[clang] 5d859a1 - [libclang] CIndex: Visit UsingTypeLoc as TypeRef

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 11 06:01:44 PDT 2022


Author: Kai Stierand
Date: 2022-10-11T15:01:31+02:00
New Revision: 5d859a1cdee3c15dce692767ee3e9ad03a8c4c1b

URL: https://github.com/llvm/llvm-project/commit/5d859a1cdee3c15dce692767ee3e9ad03a8c4c1b
DIFF: https://github.com/llvm/llvm-project/commit/5d859a1cdee3c15dce692767ee3e9ad03a8c4c1b.diff

LOG: [libclang] CIndex: Visit UsingTypeLoc as TypeRef

Reviewed By: sammccall

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

Added: 
    

Modified: 
    clang/tools/libclang/CIndex.cpp
    clang/unittests/libclang/LibclangTest.cpp
    clang/unittests/libclang/TestUtils.h

Removed: 
    


################################################################################
diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 4c7c018a231ce..69d34646ca937 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1747,7 +1747,13 @@ bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
   return Visit(TL.getPointeeLoc());
 }
 
-bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL) { return false; }
+bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL) {
+  auto *underlyingDecl = TL.getUnderlyingType()->getAsTagDecl();
+  if (underlyingDecl) {
+    return Visit(MakeCursorTypeRef(underlyingDecl, TL.getNameLoc(), TU));
+  }
+  return false;
+}
 
 bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
   return Visit(TL.getModifiedLoc());

diff  --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp
index d020fa9af61c5..a2a17646a871b 100644
--- a/clang/unittests/libclang/LibclangTest.cpp
+++ b/clang/unittests/libclang/LibclangTest.cpp
@@ -863,27 +863,19 @@ TEST_F(LibclangParseTest, clang_getUnqualifiedTypeRemovesQualifiers) {
            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) {
+  Traverse([&is_qualified](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))
+          << "Input data '" << fromCXString(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))
+          << "The type '" << fromCXString(clang_getTypeSpelling(arg_type))
           << "' was not unqualified after a call to clang_getUnqualifiedType.";
     }
 
@@ -901,28 +893,20 @@ TEST_F(LibclangParseTest, clang_getNonReferenceTypeRemovesRefQualifiers) {
            (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) {
+  Traverse([&is_ref_qualified](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))
+          << "Input data '" << fromCXString(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))
+          << "The type '" << fromCXString(clang_getTypeSpelling(arg_type))
           << "' ref-qualifier was not removed after a call to "
              "clang_getNonReferenceType.";
     }
@@ -931,6 +915,37 @@ TEST_F(LibclangParseTest, clang_getNonReferenceTypeRemovesRefQualifiers) {
   });
 }
 
+TEST_F(LibclangParseTest, VisitUsingTypeLoc) {
+  const char testSource[] = R"cpp(
+namespace ns1 {
+class Class1
+{
+    void fun();
+};
+}
+
+using ns1::Class1;
+
+void Class1::fun() {}
+)cpp";
+  std::string fileName = "main.cpp";
+  WriteFile(fileName, testSource);
+  const char *Args[] = {"-xc++"};
+  ClangTU = clang_parseTranslationUnit(Index, fileName.c_str(), Args, 1,
+                                       nullptr, 0, TUFlags);
+
+  llvm::Optional<CXCursor> typeRefCsr;
+  Traverse([&](CXCursor cursor, CXCursor parent) -> CXChildVisitResult {
+    if (cursor.kind == CXCursor_TypeRef) {
+      typeRefCsr.emplace(cursor);
+    }
+    return CXChildVisit_Recurse;
+  });
+  ASSERT_TRUE(typeRefCsr.has_value());
+  EXPECT_EQ(fromCXString(clang_getCursorSpelling(*typeRefCsr)),
+            "class ns1::Class1");
+}
+
 class LibclangRewriteTest : public LibclangParseTest {
 public:
   CXRewriter Rew = nullptr;

diff  --git a/clang/unittests/libclang/TestUtils.h b/clang/unittests/libclang/TestUtils.h
index 347fa4608664f..8900d79ea5ee6 100644
--- a/clang/unittests/libclang/TestUtils.h
+++ b/clang/unittests/libclang/TestUtils.h
@@ -82,6 +82,12 @@ class LibclangParseTest : public ::testing::Test {
         &TraverseStateless<std::reference_wrapper<const F>>,
         &FunctorRef);
   }
+  static std::string fromCXString(CXString cx_string) {
+    std::string string{clang_getCString(cx_string)};
+    clang_disposeString(cx_string);
+    return string;
+  };
+
 private:
   template<typename TState>
   static CXChildVisitResult TraverseStateless(CXCursor cx, CXCursor parent,
@@ -91,4 +97,4 @@ class LibclangParseTest : public ::testing::Test {
   }
 };
 
-#endif // LLVM_CLANG_TEST_TESTUTILS_H
\ No newline at end of file
+#endif // LLVM_CLANG_TEST_TESTUTILS_H


        


More information about the cfe-commits mailing list