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@ST>1#T@UsingA@T@Type | <no-cgname> | Def,RelChild 
| rel: 1
+  typedef int Type;
+// CHECK: [[@LINE+1]]:15 | static-method/C++ | func | 
c:@ST>1#T@UsingA@F@func#S | <no-cgname> | Decl,RelChild | rel: 1
+  static void func();
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator() | 
c:@ST>1#T@UsingA@F@operator()#I# | <no-cgname> | Decl,RelChild | rel: 1
+  void operator()(int);
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator+ | 
c:@ST>1#T@UsingA@F@operator+#&1>@ST>1#T@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@ST>1#T@UsingB@T@TypeB | <no-cgname> | Def,RelChild 
| rel: 1
+// CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T@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@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | 
Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T@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@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | 
Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@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@ST>1#T@UsingB@UUV@UsingA<T>::operator() | 
<no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@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@ST>1#T@UsingB@UUV@UsingA<T>::operator+ | 
<no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@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@ST>1#T@UsingB@T@TypeB | <no-cgname> | Ref,RelCont 
| rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@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@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | 
Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@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@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | 
Ref,Call,RelCall,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T@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@UsingD@F@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@ST>2#T#T@UsingE@UUV@UsingD<T>::foo | <no-cgname> | 
Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@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@ST>2#T#T@UsingE@UUV@UsingD<U>::foo | <no-cgname> | 
Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@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@Y Extent=[27:1 - 31:2]
 // CHECK-USRS: index-templates.cpp c:index-templates.cpp@443 Extent=[27:10 - 
27:20]
 // CHECK-USRS: index-templates.cpp c:index-templates.cpp@455 Extent=[27:22 - 
27:32]
-// CHECK-USRS-NOT: type
+// CHECK-USRS: index-templates.cpp 
c:index-templates.cpp@ST>2#T#T@Y@UUT@T::type Extent=[29:3 - 29:25]
 // CHECK-USRS: index-templates.cpp c:@S@Z3 Extent=[33:1 - 33:14]
 // CHECK-USRS: index-templates.cpp 
c:@F@f#$@S@map>#$@S@Z4#$@S@Pair>#I#S1_#$@S@compare>#$@S@Pair>#S1_#S2_#$@S@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;


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to