anderslanglands updated this revision to Diff 477399.
anderslanglands added a comment.

couple of little spaces I missed...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138377/new/

https://reviews.llvm.org/D138377

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/test/Index/print-qualified-type.cpp
  clang/tools/c-index-test/c-index-test.c
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map

Index: clang/tools/libclang/libclang.map
===================================================================
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -413,6 +413,7 @@
     clang_CXXMethod_isDeleted;
     clang_CXXMethod_isCopyAssignmentOperator;
     clang_CXXMethod_isMoveAssignmentOperator;
+    clang_Type_getFullyQualifiedName;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===================================================================
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/QualTypeNames.h"
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Frontend/ASTUnit.h"
 
@@ -309,6 +310,18 @@
   return cxstring::createDup(OS.str());
 }
 
+CXString clang_Type_getFullyQualifiedName(CXType CT) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+    return cxstring::createEmpty();
+
+  const ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext();
+  std::string QualName = clang::TypeName::getFullyQualifiedName(
+      T, Ctx, Ctx.getLangOpts());
+
+  return cxstring::createDup(QualName);
+}
+
 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
   using namespace cxcursor;
   CXTranslationUnit TU = cxcursor::getCursorTU(C);
Index: clang/tools/c-index-test/c-index-test.c
===================================================================
--- clang/tools/c-index-test/c-index-test.c
+++ clang/tools/c-index-test/c-index-test.c
@@ -373,6 +373,19 @@
   return CommentSchemaFile;
 }
 
+static int parse_print_qualified_type_names(int argc, const char **argv) {
+  const char *PrintQualifiedTypeNamesArg = "-print-qualified-type-names";
+  int PrintQualifiedTypeNames = 0;
+
+  if (argc == 0)
+    return PrintQualifiedTypeNames;
+
+  if (!strncmp(argv[0], PrintQualifiedTypeNamesArg, strlen(PrintQualifiedTypeNamesArg)))
+    PrintQualifiedTypeNames = 1;
+
+  return PrintQualifiedTypeNames;
+}
+
 /******************************************************************************/
 /* Pretty-printing.                                                           */
 /******************************************************************************/
@@ -1300,6 +1313,7 @@
   CXTranslationUnit TU;
   enum CXCursorKind *Filter;
   const char *CommentSchemaFile;
+  int PrintQualifiedTypeNames;
 } VisitorData;
 
 
@@ -1507,10 +1521,15 @@
 /* Typekind testing.                                                          */
 /******************************************************************************/
 
-static void PrintTypeAndTypeKind(CXType T, const char *Format) {
+static void PrintTypeAndTypeKind(CXType T, const char *Format,
+                                 int PrintQualifiedName) {
   CXString TypeSpelling, TypeKindSpelling;
 
-  TypeSpelling = clang_getTypeSpelling(T);
+  if (PrintQualifiedName != 0) {
+    TypeSpelling = clang_Type_getFullyQualifiedName(T);
+  } else {
+    TypeSpelling = clang_getTypeSpelling(T);
+  }
   TypeKindSpelling = clang_getTypeKindSpelling(T.kind);
   printf(Format,
          clang_getCString(TypeSpelling),
@@ -1525,7 +1544,8 @@
     return CXVisit_Continue;
 }
 
-static void PrintTypeTemplateArgs(CXType T, const char *Format) {
+static void PrintTypeTemplateArgs(CXType T, const char *Format,
+                                  int PrintQualifiedName) {
   int NumTArgs = clang_Type_getNumTemplateArguments(T);
   if (NumTArgs != -1 && NumTArgs != 0) {
     int i;
@@ -1534,7 +1554,8 @@
     for (i = 0; i < NumTArgs; ++i) {
       TArg = clang_Type_getTemplateArgumentAsType(T, i);
       if (TArg.kind != CXType_Invalid) {
-        PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]");
+        PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]",
+                             PrintQualifiedName);
       }
     }
     /* Ensure that the returned type is invalid when indexing off-by-one. */
@@ -1577,7 +1598,9 @@
     CXType PT = clang_getPointeeType(T);
     enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T);
     PrintCursor(cursor, NULL);
-    PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
+    VisitorData *Data = (VisitorData *)d;
+    PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]",
+                         Data->PrintQualifiedTypeNames);
     PrintNullabilityKind(T, " [nullability=%s]");
     if (clang_isConstQualifiedType(T))
       printf(" const");
@@ -1590,33 +1613,39 @@
     if (RQ == CXRefQualifier_RValue)
       printf(" rvalue-ref-qualifier");
     /* Print the template argument types if they exist. */
-    PrintTypeTemplateArgs(T, " [templateargs/%d=");
+    PrintTypeTemplateArgs(T,
+                          " [templateargs/%d=", Data->PrintQualifiedTypeNames);
     /* Print the canonical type if it is different. */
     {
       CXType CT = clang_getCanonicalType(T);
       if (!clang_equalTypes(T, CT)) {
-        PrintTypeAndTypeKind(CT, " [canonicaltype=%s] [canonicaltypekind=%s]");
-        PrintTypeTemplateArgs(CT, " [canonicaltemplateargs/%d=");
+        PrintTypeAndTypeKind(CT, " [canonicaltype=%s] [canonicaltypekind=%s]",
+                             Data->PrintQualifiedTypeNames);
+        PrintTypeTemplateArgs(
+            CT, " [canonicaltemplateargs/%d=", Data->PrintQualifiedTypeNames);
       }
     }
     /* Print the value type if it exists. */
     {
       CXType VT = clang_Type_getValueType(T);
       if (VT.kind != CXType_Invalid)
-        PrintTypeAndTypeKind(VT, " [valuetype=%s] [valuetypekind=%s]");
+        PrintTypeAndTypeKind(VT, " [valuetype=%s] [valuetypekind=%s]",
+                             Data->PrintQualifiedTypeNames);
     }
     /* Print the modified type if it exists. */
     {
       CXType MT = clang_Type_getModifiedType(T);
       if (MT.kind != CXType_Invalid) {
-        PrintTypeAndTypeKind(MT, " [modifiedtype=%s] [modifiedtypekind=%s]");
+        PrintTypeAndTypeKind(MT, " [modifiedtype=%s] [modifiedtypekind=%s]",
+                             Data->PrintQualifiedTypeNames);
       }
     }
     /* Print the return type if it exists. */
     {
       CXType RT = clang_getCursorResultType(cursor);
       if (RT.kind != CXType_Invalid) {
-        PrintTypeAndTypeKind(RT, " [resulttype=%s] [resulttypekind=%s]");
+        PrintTypeAndTypeKind(RT, " [resulttype=%s] [resulttypekind=%s]",
+                             Data->PrintQualifiedTypeNames);
       }
       PrintNullabilityKind(RT, " [resultnullability=%s]");
     }
@@ -1629,7 +1658,8 @@
         for (i = 0; i < NumArgs; ++i) {
           CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
           if (T.kind != CXType_Invalid) {
-            PrintTypeAndTypeKind(T, " [%s] [%s]");
+            PrintTypeAndTypeKind(T, " [%s] [%s]",
+                                 Data->PrintQualifiedTypeNames);
             PrintNullabilityKind(T, " [%s]");
           }
         }
@@ -1640,7 +1670,8 @@
     {
       CXType BT = clang_Type_getObjCObjectBaseType(PT);
       if (BT.kind != CXType_Invalid) {
-        PrintTypeAndTypeKind(BT, " [basetype=%s] [basekind=%s]");
+        PrintTypeAndTypeKind(BT, " [basetype=%s] [basekind=%s]",
+                             Data->PrintQualifiedTypeNames);
       }
     }
     {
@@ -1651,7 +1682,8 @@
         for (i = 0; i < NumTypeArgs; ++i) {
           CXType TA = clang_Type_getObjCTypeArg(PT, i);
           if (TA.kind != CXType_Invalid) {
-            PrintTypeAndTypeKind(TA, " [%s] [%s]");
+            PrintTypeAndTypeKind(TA, " [%s] [%s]",
+                                 Data->PrintQualifiedTypeNames);
           }
         }
         printf("]");
@@ -1676,7 +1708,8 @@
     /* Print the pointee type. */
     {
       if (PT.kind != CXType_Invalid) {
-        PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]");
+        PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]",
+                             Data->PrintQualifiedTypeNames);
       }
     }
     /* Print the number of fields if they exist. */
@@ -1717,8 +1750,9 @@
 
 static void PrintSingleTypeSize(CXType T, const char *TypeKindFormat,
                                 const char *SizeFormat,
-                                const char *AlignFormat) {
-  PrintTypeAndTypeKind(T, TypeKindFormat);
+                                const char *AlignFormat,
+                                int PrintQualifiedName) {
+  PrintTypeAndTypeKind(T, TypeKindFormat, PrintQualifiedName);
   /* Print the type sizeof if applicable. */
   {
     long long Size = clang_Type_getSizeOf(T);
@@ -1739,7 +1773,8 @@
     CXType RT = clang_getResultType(T);
     if (RT.kind != CXType_Invalid)
       PrintSingleTypeSize(RT, " [resulttype=%s] [resulttypekind=%s]",
-                              " [resultsizeof=%lld]", " [resultalignof=%lld]");
+                          " [resultsizeof=%lld]", " [resultalignof=%lld]",
+                          PrintQualifiedName);
   }
 }
 
@@ -1751,8 +1786,9 @@
     return CXChildVisit_Recurse;
   T = clang_getCursorType(cursor);
   PrintCursor(cursor, NULL);
+  VisitorData *Data = (VisitorData *)d;
   PrintSingleTypeSize(T, " [type=%s] [typekind=%s]", " [sizeof=%lld]",
-                      " [alignof=%lld]");
+                      " [alignof=%lld]", Data->PrintQualifiedTypeNames);
   /* Print the record field offset if applicable. */
   {
     CXString FieldSpelling = clang_getCursorSpelling(cursor);
@@ -1869,7 +1905,10 @@
 
   if (clang_isDeclaration(typeDeclaration.kind)) {
     PrintCursor(cursor, NULL);
-    PrintTypeAndTypeKind(clang_getCursorType(typeDeclaration), " [typedeclaration=%s] [typekind=%s]\n");
+    VisitorData *Data = (VisitorData *)d;
+    PrintTypeAndTypeKind(clang_getCursorType(typeDeclaration),
+                         " [typedeclaration=%s] [typekind=%s]\n",
+                         Data->PrintQualifiedTypeNames);
   }
 
   return CXChildVisit_Recurse;
@@ -1945,7 +1984,8 @@
                              const char *filter, const char *prefix,
                              CXCursorVisitor Visitor,
                              PostVisitTU PV,
-                             const char *CommentSchemaFile) {
+                             const char *CommentSchemaFile,
+                             int PrintQualifiedTypeNames) {
 
   if (prefix)
     FileCheckPrefix = prefix;
@@ -1982,6 +2022,7 @@
     Data.TU = TU;
     Data.Filter = ck;
     Data.CommentSchemaFile = CommentSchemaFile;
+    Data.PrintQualifiedTypeNames = PrintQualifiedTypeNames;
     clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
   }
 
@@ -2000,7 +2041,7 @@
 
 int perform_test_load_tu(const char *file, const char *filter,
                          const char *prefix, CXCursorVisitor Visitor,
-                         PostVisitTU PV) {
+                         PostVisitTU PV, int PrintQualifiedTypeNames) {
   CXIndex Idx;
   CXTranslationUnit TU;
   int result;
@@ -2013,7 +2054,8 @@
     return 1;
   }
 
-  result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV, NULL);
+  result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV, NULL,
+                             PrintQualifiedTypeNames);
   clang_disposeIndex(Idx);
   return result;
 }
@@ -2024,6 +2066,7 @@
   CXIndex Idx;
   CXTranslationUnit TU;
   const char *CommentSchemaFile;
+  int PrintQualifiedTypeNames = 0;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
   enum CXErrorCode Err;
@@ -2048,6 +2091,11 @@
     argv++;
   }
 
+  if ((PrintQualifiedTypeNames = parse_print_qualified_type_names(argc, argv))) {
+    argc--;
+    argv++;
+  }
+
   if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
     clang_disposeIndex(Idx);
     return -1;
@@ -2088,7 +2136,7 @@
   }
 
   result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV,
-                             CommentSchemaFile);
+                             CommentSchemaFile, PrintQualifiedTypeNames);
   free_remapped_files(unsaved_files, num_unsaved_files);
   clang_disposeIndex(Idx);
   return result;
@@ -2109,6 +2157,7 @@
   const char *execute_command = NULL;
   int remap_after_trial = 0;
   char *endptr = 0;
+  int PrintQualifiedTypeNames = 0;
   
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
                           !strcmp(filter, "local") ? 1 : 0,
@@ -2190,8 +2239,9 @@
     if (checkForErrors(TU) != 0)
       return -1;
   }
-  
-  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV, NULL);
+
+  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV, NULL,
+                             PrintQualifiedTypeNames);
 
   free_remapped_files(unsaved_files, num_unsaved_files);
   clang_disposeIndex(Idx);
@@ -2221,7 +2271,8 @@
   }
 
   result = perform_test_load(Idx, TU, /*filter=*/"all", /*prefix=*/NULL, FilteredPrintingVisitor, /*PostVisit=*/NULL,
-                             /*CommentSchemaFile=*/NULL);
+                             /*CommentSchemaFile=*/NULL,
+                             /*PrintQualifiedTypeNames*/ 0);
   clang_disposeIndex(Idx);
   return result;
 }
@@ -2249,7 +2300,8 @@
   }
 
   result = perform_test_load(Idx, TU, /*filter=*/"all", /*prefix=*/NULL, FilteredPrintingVisitor, /*PostVisit=*/NULL,
-                             /*CommentSchemaFile=*/NULL);
+                             /*CommentSchemaFile=*/NULL,
+                             /*PrintQualifiedTypeNames*/ 0);
   clang_disposeIndex(Idx);
   return result;
 }
@@ -4901,7 +4953,7 @@
     CXCursorVisitor I = GetVisitor(argv[1] + 13);
     if (I)
       return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
-                                  NULL);
+                                  NULL, 0);
   }
   else if (argc >= 5 && strncmp(argv[1], "-test-load-source-reparse", 25) == 0){
     CXCursorVisitor I = GetVisitor(argv[1] + 25);
@@ -4936,7 +4988,7 @@
                                     PrintInclusionStack);
   else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0)
     return perform_test_load_tu(argv[2], "all", NULL, NULL,
-                                PrintInclusionStack);
+                                PrintInclusionStack, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0)
     return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage,
                                     NULL);
@@ -4959,9 +5011,9 @@
     return perform_test_load_source(argc - 2, argv + 2, "all",
                                     PrintBitWidth, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-mangle") == 0)
-    return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL);
+    return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-manglings") == 0)
-    return perform_test_load_tu(argv[2], "all", NULL, PrintManglings, NULL);
+    return perform_test_load_tu(argv[2], "all", NULL, PrintManglings, NULL, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-target-info") == 0)
     return print_target_info(argc - 2, argv + 2);
   else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
Index: clang/test/Index/print-qualified-type.cpp
===================================================================
--- /dev/null
+++ clang/test/Index/print-qualified-type.cpp
@@ -0,0 +1,17 @@
+namespace A {
+  namespace B {
+    struct Foo {};
+    template <class T>
+    struct Bar {
+    };
+
+    typedef Bar<Foo> FooBar;
+    void foobar(const FooBar&);
+  } 
+
+}
+
+
+
+// RUN: c-index-test -test-print-type -print-qualified-type-names %s -std=c++14 | FileCheck %s
+// CHECK: FunctionDecl=foobar:9:10 [type=void (const FooBar &)] [typekind=FunctionProto] [canonicaltype=void (const A::B::Bar<A::B::Foo> &)] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [const A::B::FooBar &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
Index: clang/include/clang-c/Index.h
===================================================================
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2846,6 +2846,13 @@
  */
 CINDEX_LINKAGE CXString clang_getTypeSpelling(CXType CT);
 
+/**
+ * Get the fully qualified name for a type.
+ *
+ * This includes full qualification of all template parameters.
+*/
+CINDEX_LINKAGE CXString clang_Type_getFullyQualifiedName(CXType CT);
+
 /**
  * Retrieve the underlying type of a typedef declaration.
  *
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -810,6 +810,8 @@
   is a replacement for a template type parameter (previously reported a ``CXType_Unexposed``).
 - Introduced the new function ``clang_Type_getReplacementType`` which gets the type replacing
   the template type parameter when type kind is ``CXType_SubstTemplateTypeParm``.
+- Introduced the new function ``clang_Type_getFullyQualifiedName``, which gets the fully
+  qualified name of the given type, including qualification of all template parameters.
 
 Static Analyzer
 ---------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to