diseraluca created this revision.
diseraluca added a reviewer: aaron.ballman.
Herald added a subscriber: arphaman.
Herald added a project: All.
diseraluca requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The method is now wrapped by `clang_getUnqualifiedType`.

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

An implementation for `clang_getUnqualifiedType` was introduced in
`CXType.cpp` that wraps the equivalent method of the underlying
`QualType` of a `CXType`.

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

A test was added to `LibclangTest.cpp` that tests the removal of
qualifiers for some `CXType`s.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132749

Files:
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map
  clang/unittests/libclang/LibclangTest.cpp

Index: clang/unittests/libclang/LibclangTest.cpp
===================================================================
--- clang/unittests/libclang/LibclangTest.cpp
+++ clang/unittests/libclang/LibclangTest.cpp
@@ -843,6 +843,54 @@
       },
       nullptr);
 }
+
+TEST_F(LibclangParseTest, clang_getUnqualifiedTypeRemovesQualifiers) {
+  std::string Header = "header.h";
+  WriteFile(Header, "void foo1(const int);\n"
+                    "void foo2(volatile int);\n"
+                    "void foo3(const volatile int);\n"
+                    "void foo4(int* const);\n"
+                    "void foo5(int* volatile);\n"
+                    "void foo6(int* restrict);\n"
+                    "void foo7(int* const volatile);\n"
+                    "void foo8(int* volatile restrict);\n"
+                    "void foo9(int* const restrict);\n"
+                    "void foo10(int* const volatile restrict);\n");
+
+  auto is_qualified = [](CXType type) -> bool {
+    return clang_isConstQualifiedType(type) ||
+           clang_isVolatileQualifiedType(type) ||
+           clang_isRestrictQualifiedType(type);
+  };
+
+  auto from_CXString = [](CXString cx_string) -> std::string {
+    std::string string{clang_getCString(cx_string)};
+
+    clang_disposeString(cx_string);
+
+    return string;
+  };
+
+  ClangTU = clang_parseTranslationUnit(Index, Header.c_str(), nullptr, 0,
+                                       nullptr, 0, TUFlags);
+
+  Traverse([&is_qualified, &from_CXString](CXCursor cursor, CXCursor) {
+    if (clang_getCursorKind(cursor) == CXCursor_FunctionDecl) {
+      CXType arg_type = clang_getArgType(clang_getCursorType(cursor), 0);
+      EXPECT_TRUE(is_qualified(arg_type))
+          << "Input data '" << from_CXString(clang_getCursorSpelling(cursor))
+          << "' first argument does not have a qualified type.";
+
+      CXType unqualified_arg_type = clang_getUnqualifiedType(arg_type);
+      EXPECT_FALSE(is_qualified(unqualified_arg_type))
+          << "The type '" << from_CXString(clang_getTypeSpelling(arg_type))
+          << "' was not unqualified after a call to clang_getUnqualifiedType.";
+    }
+
+    return CXChildVisit_Continue;
+  });
+}
+
 class LibclangRewriteTest : public LibclangParseTest {
 public:
   CXRewriter Rew = nullptr;
Index: clang/tools/libclang/libclang.map
===================================================================
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -405,6 +405,11 @@
   local: *;
 };
 
+LLVM_16 {
+  global:
+    clang_getUnqualifiedType;
+};
+
 # Example of how to add a new symbol version entry.  If you do add a new symbol
 # version, please update the example to depend on the version you added.
 # LLVM_X {
Index: clang/tools/libclang/CXType.cpp
===================================================================
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -484,6 +484,10 @@
   return MakeCXType(T, GetTU(CT));
 }
 
+CXType clang_getUnqualifiedType(CXType CT) {
+  return MakeCXType(GetQualType(CT).getUnqualifiedType(), GetTU(CT));
+}
+
 CXCursor clang_getTypeDeclaration(CXType CT) {
   if (CT.kind == CXType_Invalid)
     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
Index: clang/include/clang-c/Index.h
===================================================================
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -3760,6 +3760,43 @@
  */
 CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
 
+/**
+ * Retrieve the unqualified variant of the given type, removing as
+ * little sugar as possible.
+ *
+ * For example, given the following series of typedefs:
+ *
+ * \code
+ * typedef int Integer;
+ * typedef const Integer CInteger;
+ * typedef CInteger DifferenceType;
+ * \endcode
+ *
+ * Executing \c clang_getUnuqalifiedType() on a \c CXType that
+ * represents \c DifferenceType, will desugar to a type representing
+ * \c Integer, that has no qualifiers.
+ *
+ * And, executing \c clang_getUnuqalifiedType() on the type of the
+ * first argument of the following function declaration:
+ *
+ * \code
+ * void foo(const int);
+ * \endcode
+ *
+ * Will return a type representing \c int, removing the \c const
+ * qualifier.
+ *
+ * Sugar over array type is not desugared.
+ *
+ * A type can be checked for qualifiers with \c
+ * clang_isConstQualifiedType(), \c clang_isVolativeQualifiedType()
+ * and \c clang_isRestrictQualifiedType().
+ *
+ * A type that resulted from a call to \c clang_getUnqualifiedType
+ * will return \c false for all of the above calls.
+ */
+CINDEX_LINKAGE CXType clang_getUnqualifiedType(CXType CT);
+
 /**
  * Return the cursor for the declaration of the given type.
  */
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to