]> granicus.if.org Git - clang/commitdiff
[index] C++: Improve handling of typedefs as base names in C++ class declarations
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 4 Mar 2017 17:54:56 +0000 (17:54 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 4 Mar 2017 17:54:56 +0000 (17:54 +0000)
Report the typedef as reference, and desugar it to report the underlying class as an
implicit 'base' reference.
Reporting the underlying base class for 'base' relations matches the ObjC handling and
leads to a simpler model.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@296975 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Index/IndexTypeSourceInfo.cpp
test/Index/Core/index-source.cpp

index cf323258f9442b1cc32eef08e73d04c414962c1d..33848da0cb38398fe02399056ff8aace7a9d7eec 100644 (file)
@@ -40,18 +40,30 @@ public:
   
   bool shouldWalkTypesOfTypeLocs() const { return false; }
 
-  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-    return IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
-                                    Parent, ParentDC, SymbolRoleSet(),
-                                    Relations);
-  }
-
 #define TRY_TO(CALL_EXPR)                                                      \
   do {                                                                         \
     if (!CALL_EXPR)                                                            \
       return false;                                                            \
   } while (0)
 
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+    if (IsBase) {
+      SourceLocation Loc = TL.getNameLoc();
+      TRY_TO(IndexCtx.handleReference(TL.getTypedefNameDecl(), Loc,
+                                      Parent, ParentDC, SymbolRoleSet()));
+      if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
+        TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC,
+                                        (unsigned)SymbolRole::Implicit,
+                                        Relations));
+      }
+    } else {
+      TRY_TO(IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
+                                      Parent, ParentDC, SymbolRoleSet(),
+                                      Relations));
+    }
+    return true;
+  }
+
   bool traverseParamVarHelper(ParmVarDecl *D) {
     TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
     if (D->getTypeSourceInfo())
index 2a4c1efa960d1dce7cde5757c3fd5f0af67a97e8..ab7c6f4c063dfbc8b34f298794b3e8ee8b5417e8 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
 
-// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | <no-cgname> | Def | rel: 0
 class Cls {
   // CHECK: [[@LINE+2]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
   // CHECK-NEXT: RelChild | Cls | c:@S@Cls
@@ -11,6 +11,19 @@ class Cls {
   Cls(Cls &&);
 };
 
+// CHECK: [[@LINE+3]]:7 | class/C++ | SubCls1 | [[SubCls1_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls1 | [[SubCls1_USR]]
+class SubCls1 : public Cls {};
+// CHECK: [[@LINE+1]]:13 | type-alias/C | ClsAlias | [[ClsAlias_USR:.*]] | <no-cgname> | Def | rel: 0
+typedef Cls ClsAlias;
+// CHECK: [[@LINE+5]]:7 | class/C++ | SubCls2 | [[SubCls2_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+4]]:24 | type-alias/C | ClsAlias | [[ClsAlias_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | SubCls2 | [[SubCls2_USR]]
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls2 | [[SubCls2_USR]]
+class SubCls2 : public ClsAlias {};
+
 template <typename TemplArg>
 class TemplCls {
 // CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Def | rel: 0