Expose QualType::getNonReferenceType in libclang
authorLuca Di Sera <disera.luca@gmail.com>
Fri, 2 Sep 2022 13:54:10 +0000 (09:54 -0400)
committerAaron Ballman <aaron@aaronballman.com>
Fri, 2 Sep 2022 13:54:10 +0000 (09:54 -0400)
The method is now wrapped by clang_getNonReferenceType.

A declaration for clang_getNonReferenceType was added to clang-c/Index.h
to expose it to user of the library.

An implementation for clang_getNonReferenceType was introduced in
CXType.cpp, wrapping the equivalent method of the underlying QualType of
a CXType.

An export symbol for the new function was added to libclang.map under
the LLVM_16 version entry.

A test was added to LibclangTest.cpp that tests the removal of
ref-qualifiers for some CXTypes.

The release-notes for the clang project was updated to include a
notification of the new addition under the "libclang" section.

Differential Revision: https://reviews.llvm.org/D133195

clang/docs/ReleaseNotes.rst
clang/include/clang-c/Index.h
clang/tools/libclang/CXType.cpp
clang/tools/libclang/libclang.map
clang/unittests/libclang/LibclangTest.cpp

index 2a92f65..41371fe 100644 (file)
@@ -289,6 +289,8 @@ libclang
 
 - Introduced the new function `clang_getUnqualifiedType`, which mimics
   the behavior of `QualType::getUnqualifiedType` for `CXType`.
+- Introduced the new function `clang_getNonReferenceType`, which mimics
+  the behavior of `QualType::getNonReferenceType` for `CXType`.
 
 Static Analyzer
 ---------------
index 41efc57..c0dbad8 100644 (file)
@@ -3798,6 +3798,17 @@ CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
 CINDEX_LINKAGE CXType clang_getUnqualifiedType(CXType CT);
 
 /**
+ * For reference types (e.g., "const int&"), returns the type that the
+ * reference refers to (e.g "const int").
+ *
+ * Otherwise, returns the type itself.
+ *
+ * A type that has kind \c CXType_LValueReference or
+ * \c CXType_RValueReference is a reference type.
+ */
+CINDEX_LINKAGE CXType clang_getNonReferenceType(CXType CT);
+
+/**
  * Return the cursor for the declaration of the given type.
  */
 CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
index e50a471..a62163c 100644 (file)
@@ -488,6 +488,10 @@ CXType clang_getUnqualifiedType(CXType CT) {
   return MakeCXType(GetQualType(CT).getUnqualifiedType(), GetTU(CT));
 }
 
+CXType clang_getNonReferenceType(CXType CT) {
+  return MakeCXType(GetQualType(CT).getNonReferenceType(), GetTU(CT));
+}
+
 CXCursor clang_getTypeDeclaration(CXType CT) {
   if (CT.kind == CXType_Invalid)
     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
index 9ed8172..911292a 100644 (file)
@@ -408,6 +408,7 @@ LLVM_13 {
 LLVM_16 {
   global:
     clang_getUnqualifiedType;
+    clang_getNonReferenceType;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
index e608485..d020fa9 100644 (file)
@@ -891,6 +891,46 @@ TEST_F(LibclangParseTest, clang_getUnqualifiedTypeRemovesQualifiers) {
   });
 }
 
+TEST_F(LibclangParseTest, clang_getNonReferenceTypeRemovesRefQualifiers) {
+  std::string Header = "header.h";
+  WriteFile(Header, "void foo1(int&);\n"
+                    "void foo2(int&&);\n");
+
+  auto is_ref_qualified = [](CXType type) -> bool {
+    return (type.kind == CXType_LValueReference) ||
+           (type.kind == CXType_RValueReference);
+  };
+
+  auto from_CXString = [](CXString cx_string) -> std::string {
+    std::string string{clang_getCString(cx_string)};
+
+    clang_disposeString(cx_string);
+
+    return string;
+  };
+
+  const char *Args[] = {"-xc++"};
+  ClangTU = clang_parseTranslationUnit(Index, Header.c_str(), Args, 1, nullptr,
+                                       0, TUFlags);
+
+  Traverse([&is_ref_qualified, &from_CXString](CXCursor cursor, CXCursor) {
+    if (clang_getCursorKind(cursor) == CXCursor_FunctionDecl) {
+      CXType arg_type = clang_getArgType(clang_getCursorType(cursor), 0);
+      EXPECT_TRUE(is_ref_qualified(arg_type))
+          << "Input data '" << from_CXString(clang_getCursorSpelling(cursor))
+          << "' first argument does not have a ref-qualified type.";
+
+      CXType non_reference_arg_type = clang_getNonReferenceType(arg_type);
+      EXPECT_FALSE(is_ref_qualified(non_reference_arg_type))
+          << "The type '" << from_CXString(clang_getTypeSpelling(arg_type))
+          << "' ref-qualifier was not removed after a call to "
+             "clang_getNonReferenceType.";
+    }
+
+    return CXChildVisit_Continue;
+  });
+}
+
 class LibclangRewriteTest : public LibclangParseTest {
 public:
   CXRewriter Rew = nullptr;