summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2017-03-04 17:54:56 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2017-03-04 17:54:56 +0000
commit898c241b26d166e7981875a71eb925468d393d5c (patch)
tree1bcdee634622aa8ecadb7c4307fc32cd1074fc66
parent266cfa30dc1435ab93cac91706f742600d11404f (diff)
downloadbcm5719-llvm-898c241b26d166e7981875a71eb925468d393d5c.tar.gz
bcm5719-llvm-898c241b26d166e7981875a71eb925468d393d5c.zip
[index] C++: Improve handling of typedefs as base names in C++ class declarations
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. llvm-svn: 296975
-rw-r--r--clang/lib/Index/IndexTypeSourceInfo.cpp24
-rw-r--r--clang/test/Index/Core/index-source.cpp15
2 files changed, 32 insertions, 7 deletions
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index cf323258f94..33848da0cb3 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -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())
diff --git a/clang/test/Index/Core/index-source.cpp b/clang/test/Index/Core/index-source.cpp
index 2a4c1efa960..ab7c6f4c063 100644
--- a/clang/test/Index/Core/index-source.cpp
+++ b/clang/test/Index/Core/index-source.cpp
@@ -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
OpenPOWER on IntegriCloud