Skip to content

Commit d09cce1

Browse files
[clang][Index] Use HeuristicResolver in libIndex (#125153)
The uses replace hand-rolled code that did a subset of what HeuristicResolver does.
1 parent 0b719d3 commit d09cce1

File tree

5 files changed

+45
-47
lines changed

5 files changed

+45
-47
lines changed

clang/lib/Index/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_clang_library(clangIndex
2323
clangFormat
2424
clangFrontend
2525
clangLex
26+
clangSema
2627
clangSerialization
2728
clangToolingCore
2829

clang/lib/Index/IndexBody.cpp

+14-33
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/AST/ExprConcepts.h"
1414
#include "clang/AST/RecursiveASTVisitor.h"
1515
#include "clang/AST/Type.h"
16+
#include "clang/Sema/HeuristicResolver.h"
1617

1718
using namespace clang;
1819
using namespace clang::index;
@@ -168,51 +169,31 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
168169
Parent, ParentDC, Roles, Relations, E);
169170
}
170171

171-
bool indexDependentReference(
172-
const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
173-
llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
174-
if (!T)
175-
return true;
176-
const TemplateSpecializationType *TST =
177-
T->getAs<TemplateSpecializationType>();
178-
if (!TST)
179-
return true;
180-
TemplateName TN = TST->getTemplateName();
181-
const ClassTemplateDecl *TD =
182-
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
183-
if (!TD)
184-
return true;
185-
CXXRecordDecl *RD = TD->getTemplatedDecl();
186-
if (!RD->hasDefinition())
187-
return true;
188-
RD = RD->getDefinition();
189-
std::vector<const NamedDecl *> Symbols =
190-
RD->lookupDependentName(NameInfo.getName(), Filter);
172+
bool indexDependentReference(const Expr *E, SourceLocation Loc,
173+
std::vector<const NamedDecl *> TargetSymbols) {
191174
// FIXME: Improve overload handling.
192-
if (Symbols.size() != 1)
175+
if (TargetSymbols.size() != 1)
193176
return true;
194-
SourceLocation Loc = NameInfo.getLoc();
195177
if (Loc.isInvalid())
196178
Loc = E->getBeginLoc();
197179
SmallVector<SymbolRelation, 4> Relations;
198180
SymbolRoleSet Roles = getRolesForRef(E, Relations);
199-
return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
200-
Relations, E);
181+
return IndexCtx.handleReference(TargetSymbols[0], Loc, Parent, ParentDC,
182+
Roles, Relations, E);
201183
}
202184

203185
bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
204-
const DeclarationNameInfo &Info = E->getMemberNameInfo();
205-
return indexDependentReference(
206-
E, E->getBaseType().getTypePtrOrNull(), Info,
207-
[](const NamedDecl *D) { return D->isCXXInstanceMember(); });
186+
auto *Resolver = IndexCtx.getResolver();
187+
assert(Resolver);
188+
return indexDependentReference(E, E->getMemberNameInfo().getLoc(),
189+
Resolver->resolveMemberExpr(E));
208190
}
209191

210192
bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
211-
const DeclarationNameInfo &Info = E->getNameInfo();
212-
const NestedNameSpecifier *NNS = E->getQualifier();
213-
return indexDependentReference(
214-
E, NNS->getAsType(), Info,
215-
[](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
193+
auto *Resolver = IndexCtx.getResolver();
194+
assert(Resolver);
195+
return indexDependentReference(E, E->getNameInfo().getLoc(),
196+
Resolver->resolveDeclRefExpr(E));
216197
}
217198

218199
bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {

clang/lib/Index/IndexingContext.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/Basic/SourceLocation.h"
1515
#include "clang/Basic/SourceManager.h"
1616
#include "clang/Index/IndexDataConsumer.h"
17+
#include "clang/Sema/HeuristicResolver.h"
1718

1819
using namespace clang;
1920
using namespace index;
@@ -25,6 +26,17 @@ static bool isGeneratedDecl(const Decl *D) {
2526
return false;
2627
}
2728

29+
IndexingContext::IndexingContext(IndexingOptions IndexOpts,
30+
IndexDataConsumer &DataConsumer)
31+
: IndexOpts(IndexOpts), DataConsumer(DataConsumer) {}
32+
33+
IndexingContext::~IndexingContext() = default;
34+
35+
void IndexingContext::setASTContext(ASTContext &ctx) {
36+
Ctx = &ctx;
37+
Resolver = Ctx ? std::make_unique<HeuristicResolver>(*Ctx) : nullptr;
38+
}
39+
2840
bool IndexingContext::shouldIndex(const Decl *D) {
2941
return !isGeneratedDecl(D);
3042
}

clang/lib/Index/IndexingContext.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace clang {
2121
class Decl;
2222
class DeclGroupRef;
2323
class ImportDecl;
24+
class HeuristicResolver;
2425
class TagDecl;
2526
class TypeSourceInfo;
2627
class NamedDecl;
@@ -39,15 +40,18 @@ class IndexingContext {
3940
IndexingOptions IndexOpts;
4041
IndexDataConsumer &DataConsumer;
4142
ASTContext *Ctx = nullptr;
43+
std::unique_ptr<HeuristicResolver> Resolver;
4244

4345
public:
44-
IndexingContext(IndexingOptions IndexOpts, IndexDataConsumer &DataConsumer)
45-
: IndexOpts(IndexOpts), DataConsumer(DataConsumer) {}
46+
IndexingContext(IndexingOptions IndexOpts, IndexDataConsumer &DataConsumer);
47+
~IndexingContext();
4648

4749
const IndexingOptions &getIndexOpts() const { return IndexOpts; }
4850
IndexDataConsumer &getDataConsumer() { return DataConsumer; }
4951

50-
void setASTContext(ASTContext &ctx) { Ctx = &ctx; }
52+
void setASTContext(ASTContext &ctx);
53+
54+
HeuristicResolver *getResolver() const { return Resolver.get(); }
5155

5256
bool shouldIndex(const Decl *D);
5357

clang/test/Index/Core/index-dependent-source.cpp

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
int invalid;
44

55
class Base {
6-
void baseFunction();
6+
void baseFunction() const;
77

88
int baseField;
99

@@ -13,7 +13,7 @@ class Base {
1313
template<typename T>
1414
class BaseTemplate {
1515
public:
16-
T baseTemplateFunction();
16+
T baseTemplateFunction() const;
1717

1818
T baseTemplateField;
1919

@@ -25,7 +25,7 @@ class TemplateClass: public Base , public BaseTemplate<T> {
2525
public:
2626
~TemplateClass();
2727

28-
T function() { }
28+
T function() const { }
2929

3030
static void staticFunction() { }
3131

@@ -48,27 +48,27 @@ template<typename T, typename S>
4848
void indexSimpleDependentDeclarations(const TemplateClass<T, S> &object) {
4949
// Valid instance members:
5050
object.function();
51-
// CHECK: [[@LINE-1]]:10 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
51+
// CHECK: [[@LINE-1]]:10 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function#1 | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
5252
object.field;
5353
// CHECK: [[@LINE-1]]:10 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
5454
object.baseFunction();
55-
// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction# | __ZN4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
55+
// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction#1 | __ZNK4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
5656
object.baseField;
5757
// CHECK: [[@LINE-1]]:10 | field/C++ | baseField | c:@S@Base@FI@baseField | <no-cgname> | Ref,RelCont | rel: 1
5858
object.baseTemplateFunction();
59-
// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
59+
// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction#1 | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
6060
object.baseTemplateField;
6161
// CHECK: [[@LINE-1]]:10 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
6262

63-
// Invalid instance members:
63+
// Static members (these are still valid to access via an instance):
6464
object.variable;
65-
// CHECK-NOT: [[@LINE-1]]:10
65+
// CHECK: [[@LINE-1]]:10 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 1
6666
object.staticFunction();
67-
// CHECK-NOT: [[@LINE-1]]:10
67+
// CHECK: [[@LINE-1]]:10 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
6868
object.Struct;
69-
// CHECK-NOT: [[@LINE-1]]:10
69+
// CHECK: [[@LINE-1]]:10 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,RelCont | rel: 1
7070
object.EnumValue;
71-
// CHECK-NOT: [[@LINE-1]]:10
71+
// CHECK: [[@LINE-1]]:10 | enumerator/C | EnumValue | c:@ST>2#T#T@TemplateClass@E@Enum@EnumValue | <no-cgname> | Ref,RelCont | rel: 1
7272

7373
// Valid static members:
7474
TemplateClass<T, S>::staticFunction();

0 commit comments

Comments
 (0)