r311053 - [index] Add indexing for unresolved-using declarations

Ben Langmuir via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 16 16:12:21 PDT 2017


Author: benlangmuir
Date: Wed Aug 16 16:12:21 2017
New Revision: 311053

URL: http://llvm.org/viewvc/llvm-project?rev=311053&view=rev
Log:
[index] Add indexing for unresolved-using declarations

In dependent contexts we end up referencing these, so make sure they
have USRs, and have their declarations indexed. For the most part they
behave like typedefs, but we also need to worry about having multiple
using declarations with the same "name".

rdar://problem/33883650

Modified:
    cfe/trunk/include/clang/Index/IndexSymbol.h
    cfe/trunk/lib/Index/IndexDecl.cpp
    cfe/trunk/lib/Index/IndexSymbol.cpp
    cfe/trunk/lib/Index/USRGeneration.cpp
    cfe/trunk/test/Index/Core/index-dependent-source.cpp
    cfe/trunk/test/Index/index-templates.cpp
    cfe/trunk/tools/libclang/CXIndexDataConsumer.cpp

Modified: cfe/trunk/include/clang/Index/IndexSymbol.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Index/IndexSymbol.h?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/include/clang/Index/IndexSymbol.h (original)
+++ cfe/trunk/include/clang/Index/IndexSymbol.h Wed Aug 16 16:12:21 2017
@@ -53,6 +53,7 @@ enum class SymbolKind : uint8_t {
   ConversionFunction,
 
   Parameter,
+  Using,
 };
 
 enum class SymbolLanguage {
@@ -69,6 +70,8 @@ enum class SymbolSubKind {
   CXXMoveConstructor,
   AccessorGetter,
   AccessorSetter,
+  UsingTypename,
+  UsingValue,
 };
 
 /// Set of properties that provide additional info about a symbol.

Modified: cfe/trunk/lib/Index/IndexDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/lib/Index/IndexDecl.cpp (original)
+++ cfe/trunk/lib/Index/IndexDecl.cpp Wed Aug 16 16:12:21 2017
@@ -611,6 +611,24 @@ public:
                                     SymbolRoleSet());
   }
 
+  bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+    TRY_DECL(D, IndexCtx.handleDecl(D));
+    const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+    const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
+    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
+                                         D->getLexicalDeclContext());
+    return true;
+  }
+
+  bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+    TRY_DECL(D, IndexCtx.handleDecl(D));
+    const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+    const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
+    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
+                                         D->getLexicalDeclContext());
+    return true;
+  }
+
   bool VisitClassTemplateSpecializationDecl(const
                                            ClassTemplateSpecializationDecl *D) {
     // FIXME: Notify subsequent callbacks if info comes from implicit

Modified: cfe/trunk/lib/Index/IndexSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexSymbol.cpp?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/lib/Index/IndexSymbol.cpp (original)
+++ cfe/trunk/lib/Index/IndexSymbol.cpp Wed Aug 16 16:12:21 2017
@@ -300,6 +300,18 @@ SymbolInfo index::getSymbolInfo(const De
       Info.Kind = SymbolKind::TypeAlias;
       Info.Lang = SymbolLanguage::CXX;
       break;
+    case Decl::UnresolvedUsingTypename:
+      Info.Kind = SymbolKind::Using;
+      Info.SubKind = SymbolSubKind::UsingTypename;
+      Info.Lang = SymbolLanguage::CXX;
+      Info.Properties |= (unsigned)SymbolProperty::Generic;
+      break;
+    case Decl::UnresolvedUsingValue:
+      Info.Kind = SymbolKind::Using;
+      Info.SubKind = SymbolSubKind::UsingValue;
+      Info.Lang = SymbolLanguage::CXX;
+      Info.Properties |= (unsigned)SymbolProperty::Generic;
+      break;
     case Decl::Binding:
       Info.Kind = SymbolKind::Variable;
       Info.Lang = SymbolLanguage::CXX;
@@ -448,6 +460,7 @@ StringRef index::getSymbolKindString(Sym
   case SymbolKind::Destructor: return "destructor";
   case SymbolKind::ConversionFunction: return "coversion-func";
   case SymbolKind::Parameter: return "param";
+  case SymbolKind::Using: return "using";
   }
   llvm_unreachable("invalid symbol kind");
 }
@@ -459,6 +472,8 @@ StringRef index::getSymbolSubKindString(
   case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
   case SymbolSubKind::AccessorGetter: return "acc-get";
   case SymbolSubKind::AccessorSetter: return "acc-set";
+  case SymbolSubKind::UsingTypename: return "using-typename";
+  case SymbolSubKind::UsingValue: return "using-value";
   }
   llvm_unreachable("invalid symbol subkind");
 }

Modified: cfe/trunk/lib/Index/USRGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/USRGeneration.cpp?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/lib/Index/USRGeneration.cpp (original)
+++ cfe/trunk/lib/Index/USRGeneration.cpp Wed Aug 16 16:12:21 2017
@@ -99,6 +99,8 @@ public:
   void VisitVarDecl(const VarDecl *D);
   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
+  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
+  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
 
   void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
     IgnoreResults = true;
@@ -112,14 +114,6 @@ public:
     IgnoreResults = true;
   }
 
-  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
-    IgnoreResults = true;
-  }
-
-  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
-    IgnoreResults = true;
-  }
-
   bool ShouldGenerateLocation(const NamedDecl *D);
 
   bool isLocal(const NamedDecl *D) {
@@ -609,6 +603,16 @@ bool USRGenerator::GenLoc(const Decl *D,
   return IgnoreResults;
 }
 
+static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) {
+  // FIXME: Encode the qualifier, don't just print it.
+  PrintingPolicy PO(Ctx.getLangOpts());
+  PO.SuppressTagKeyword = true;
+  PO.SuppressUnwrittenScope = true;
+  PO.ConstantArraySizeAsWritten = false;
+  PO.AnonymousTagLocations = false;
+  NNS->print(Out, PO);
+}
+
 void USRGenerator::VisitType(QualType T) {
   // This method mangles in USR information for types.  It can possibly
   // just reuse the naming-mangling logic used by codegen, although the
@@ -797,13 +801,7 @@ void USRGenerator::VisitType(QualType T)
     }
     if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
       Out << '^';
-      // FIXME: Encode the qualifier, don't just print it.
-      PrintingPolicy PO(Ctx.getLangOpts());
-      PO.SuppressTagKeyword = true;
-      PO.SuppressUnwrittenScope = true;
-      PO.ConstantArraySizeAsWritten = false;
-      PO.AnonymousTagLocations = false;
-      DNT->getQualifier()->print(Out, PO);
+      printQualifier(Out, Ctx, DNT->getQualifier());
       Out << ':' << DNT->getIdentifier()->getName();
       return;
     }
@@ -912,6 +910,26 @@ void USRGenerator::VisitTemplateArgument
   }
 }
 
+void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
+    return;
+  VisitDeclContext(D->getDeclContext());
+  Out << "@UUV@";
+  printQualifier(Out, D->getASTContext(), D->getQualifier());
+  EmitDeclName(D);
+}
+
+void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
+    return;
+  VisitDeclContext(D->getDeclContext());
+  Out << "@UUT@";
+  printQualifier(Out, D->getASTContext(), D->getQualifier());
+  Out << D->getName(); // Simple name.
+}
+
+
+
 //===----------------------------------------------------------------------===//
 // USR generation functions.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Index/Core/index-dependent-source.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-dependent-source.cpp?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/test/Index/Core/index-dependent-source.cpp (original)
+++ cfe/trunk/test/Index/Core/index-dependent-source.cpp Wed Aug 16 16:12:21 2017
@@ -158,3 +158,69 @@ void infiniteTraitRecursion(Trait<T> &t)
 // Shouldn't crash!
   t.lookup;
 }
+
+template <typename T>
+struct UsingA {
+// CHECK: [[@LINE+1]]:15 | type-alias/C | Type | c:index-dependent-source.cpp at ST>1#T at UsingA@T at Type | <no-cgname> | Def,RelChild | rel: 1
+  typedef int Type;
+// CHECK: [[@LINE+1]]:15 | static-method/C++ | func | c:@ST>1#T at UsingA@F at func#S | <no-cgname> | Decl,RelChild | rel: 1
+  static void func();
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator() | c:@ST>1#T at UsingA@F at operator()#I# | <no-cgname> | Decl,RelChild | rel: 1
+  void operator()(int);
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator+ | c:@ST>1#T at UsingA@F at operator+#&1>@ST>1#T at UsingA1t0.0# | <no-cgname> | Decl,RelChild | rel: 1
+  void operator+(const UsingA &);
+};
+
+template <typename T>
+struct OtherUsing {};
+
+template <typename T>
+struct UsingB : public UsingA<T> {
+// CHECK: [[@LINE+2]]:40 | type-alias/C | TypeB | c:index-dependent-source.cpp at ST>1#T at UsingB@T at TypeB | <no-cgname> | Def,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T at OtherUsing | <no-cgname> | Ref,RelCont | rel: 1
+  typedef typename OtherUsing<T>::Type TypeB;
+// CHECK: [[@LINE+2]]:29 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp at ST>1#T at UsingB@UUT at UsingA<T>::Type | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T at UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using typename UsingA<T>::Type;
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp at ST>1#T at UsingB@UUV at UsingA<T>::func | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T at UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingA<T>::func;
+
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator() | c:index-dependent-source.cpp at ST>1#T at UsingB@UUV at UsingA<T>::operator() | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T at UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingA<T>::operator();
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator+ | c:index-dependent-source.cpp at ST>1#T at UsingB@UUV at UsingA<T>::operator+ | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T at UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingA<T>::operator+;
+};
+
+template <typename T>
+struct UsingC : public UsingB<T> {
+  static void test() {
+// CHECK: [[@LINE+2]]:25 | type-alias/C | TypeB | c:index-dependent-source.cpp at ST>1#T at UsingB@T at TypeB | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T at UsingB | <no-cgname> | Ref,RelCont | rel: 1
+    typename UsingB<T>::TypeB value1;
+// CHECK: [[@LINE+2]]:25 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp at ST>1#T at UsingB@UUT at UsingA<T>::Type | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T at UsingB | <no-cgname> | Ref,RelCont | rel: 1
+    typename UsingB<T>::Type value2;
+// CHECK: [[@LINE+2]]:16 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp at ST>1#T at UsingB@UUV at UsingA<T>::func | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T at UsingB | <no-cgname> | Ref,RelCont | rel: 1
+    UsingB<T>::func();
+  }
+};
+
+template <typename T>
+struct UsingD {
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | foo | c:@ST>1#T at UsingD@F at foo#t0.0# | <no-cgname> | Decl,RelChild | rel: 1
+  void foo(T);
+};
+
+template <typename T, typename U>
+struct UsingE : public UsingD<T>, public UsingD<U> {
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp at ST>2#T#T at UsingE@UUV at UsingD<T>::foo | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T at UsingD | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingD<T>::foo;
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp at ST>2#T#T at UsingE@UUV at UsingD<U>::foo | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T at UsingD | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingD<U>::foo;
+};

Modified: cfe/trunk/test/Index/index-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-templates.cpp?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/test/Index/index-templates.cpp (original)
+++ cfe/trunk/test/Index/index-templates.cpp Wed Aug 16 16:12:21 2017
@@ -219,6 +219,6 @@ using alias = T;
 // CHECK-USRS: index-templates.cpp c:@ST>2#T#T at Y Extent=[27:1 - 31:2]
 // CHECK-USRS: index-templates.cpp c:index-templates.cpp at 443 Extent=[27:10 - 27:20]
 // CHECK-USRS: index-templates.cpp c:index-templates.cpp at 455 Extent=[27:22 - 27:32]
-// CHECK-USRS-NOT: type
+// CHECK-USRS: index-templates.cpp c:index-templates.cpp at ST>2#T#T at Y@UUT at T::type Extent=[29:3 - 29:25]
 // CHECK-USRS: index-templates.cpp c:@S at Z3 Extent=[33:1 - 33:14]
 // CHECK-USRS: index-templates.cpp c:@F at f#$@S at map>#$@S at Z4#$@S at Pair>#I#S1_#$@S at compare>#$@S at Pair>#S1_#S2_#$@S at allocator>#S4_#

Modified: cfe/trunk/tools/libclang/CXIndexDataConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXIndexDataConsumer.cpp?rev=311053&r1=311052&r2=311053&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXIndexDataConsumer.cpp (original)
+++ cfe/trunk/tools/libclang/CXIndexDataConsumer.cpp Wed Aug 16 16:12:21 2017
@@ -1258,6 +1258,7 @@ static CXIdxEntityKind getEntityKindFrom
   case SymbolKind::Module:
   case SymbolKind::Macro:
   case SymbolKind::ClassProperty:
+  case SymbolKind::Using:
     return CXIdxEntity_Unexposed;
 
   case SymbolKind::Enum: return CXIdxEntity_Enum;




More information about the cfe-commits mailing list