summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/FindTarget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/FindTarget.cpp')
-rw-r--r--clang-tools-extra/clangd/FindTarget.cpp127
1 files changed, 80 insertions, 47 deletions
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index ffe808d5796..4919105335d 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -412,63 +412,86 @@ explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask = {}) {
return Targets;
}
-Optional<ReferenceLoc> refInDecl(const Decl *D) {
+llvm::SmallVector<ReferenceLoc, 2> refInDecl(const Decl *D) {
struct Visitor : ConstDeclVisitor<Visitor> {
- llvm::Optional<ReferenceLoc> Ref;
+ llvm::SmallVector<ReferenceLoc, 2> Refs;
void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
- Ref = ReferenceLoc{D->getQualifierLoc(),
- D->getIdentLocation(),
- {D->getNominatedNamespaceAsWritten()}};
+ // We want to keep it as non-declaration references, as the
+ // "using namespace" declaration doesn't have a name.
+ Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
+ D->getIdentLocation(),
+ /*IsDecl=*/false,
+ {D->getNominatedNamespaceAsWritten()}});
}
void VisitUsingDecl(const UsingDecl *D) {
- Ref = ReferenceLoc{D->getQualifierLoc(), D->getLocation(),
- explicitReferenceTargets(DynTypedNode::create(*D),
- DeclRelation::Underlying)};
+ // "using ns::identifer;" is a non-declaration reference.
+ Refs.push_back(
+ ReferenceLoc{D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
+ explicitReferenceTargets(DynTypedNode::create(*D),
+ DeclRelation::Underlying)});
}
void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
- Ref = ReferenceLoc{D->getQualifierLoc(),
- D->getTargetNameLoc(),
- {D->getAliasedNamespace()}};
+ // For namespace alias, "namespace Foo = Target;", we add two references.
+ // Add a declaration reference for Foo.
+ VisitNamedDecl(D);
+ // Add a non-declaration reference for Target.
+ Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
+ D->getTargetNameLoc(),
+ /*IsDecl=*/false,
+ {D->getAliasedNamespace()}});
+ }
+
+ void VisitNamedDecl(const NamedDecl *ND) {
+ // FIXME: decide on how to surface destructors when we need them.
+ if (llvm::isa<CXXDestructorDecl>(ND))
+ return;
+ Refs.push_back(ReferenceLoc{
+ getQualifierLoc(*ND), ND->getLocation(), /*IsDecl=*/true, {ND}});
}
};
Visitor V;
V.Visit(D);
- return V.Ref;
+ return V.Refs;
}
-Optional<ReferenceLoc> refInExpr(const Expr *E) {
+llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) {
struct Visitor : ConstStmtVisitor<Visitor> {
// FIXME: handle more complicated cases, e.g. ObjC, designated initializers.
- llvm::Optional<ReferenceLoc> Ref;
+ llvm::SmallVector<ReferenceLoc, 2> Refs;
void VisitDeclRefExpr(const DeclRefExpr *E) {
- Ref = ReferenceLoc{
- E->getQualifierLoc(), E->getNameInfo().getLoc(), {E->getFoundDecl()}};
+ Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
+ E->getNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ {E->getFoundDecl()}});
}
void VisitMemberExpr(const MemberExpr *E) {
- Ref = ReferenceLoc{E->getQualifierLoc(),
- E->getMemberNameInfo().getLoc(),
- {E->getFoundDecl()}};
+ Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
+ E->getMemberNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ {E->getFoundDecl()}});
}
void VisitOverloadExpr(const OverloadExpr *E) {
- Ref = ReferenceLoc{E->getQualifierLoc(), E->getNameInfo().getLoc(),
- llvm::SmallVector<const NamedDecl *, 1>(
- E->decls().begin(), E->decls().end())};
+ Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
+ E->getNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ llvm::SmallVector<const NamedDecl *, 1>(
+ E->decls().begin(), E->decls().end())});
}
};
Visitor V;
V.Visit(E);
- return V.Ref;
+ return V.Refs;
}
-Optional<ReferenceLoc> refInTypeLoc(TypeLoc L) {
+llvm::SmallVector<ReferenceLoc, 2> refInTypeLoc(TypeLoc L) {
struct Visitor : TypeLocVisitor<Visitor> {
llvm::Optional<ReferenceLoc> Ref;
@@ -483,13 +506,17 @@ Optional<ReferenceLoc> refInTypeLoc(TypeLoc L) {
}
void VisitTagTypeLoc(TagTypeLoc L) {
- Ref =
- ReferenceLoc{NestedNameSpecifierLoc(), L.getNameLoc(), {L.getDecl()}};
+ Ref = ReferenceLoc{NestedNameSpecifierLoc(),
+ L.getNameLoc(),
+ /*IsDecl=*/false,
+ {L.getDecl()}};
}
void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
- Ref =
- ReferenceLoc{NestedNameSpecifierLoc(), L.getNameLoc(), {L.getDecl()}};
+ Ref = ReferenceLoc{NestedNameSpecifierLoc(),
+ L.getNameLoc(),
+ /*IsDecl=*/false,
+ {L.getDecl()}};
}
void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
@@ -502,14 +529,14 @@ Optional<ReferenceLoc> refInTypeLoc(TypeLoc L) {
// 2. 'vector<int>' with mask 'Underlying'.
// we want to return only #1 in this case.
Ref = ReferenceLoc{
- NestedNameSpecifierLoc(), L.getTemplateNameLoc(),
+ NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()),
DeclRelation::Alias)};
}
void VisitDeducedTemplateSpecializationTypeLoc(
DeducedTemplateSpecializationTypeLoc L) {
Ref = ReferenceLoc{
- NestedNameSpecifierLoc(), L.getNameLoc(),
+ NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()),
DeclRelation::Alias)};
}
@@ -517,25 +544,29 @@ Optional<ReferenceLoc> refInTypeLoc(TypeLoc L) {
void VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc L) {
Ref = ReferenceLoc{
- L.getQualifierLoc(), L.getTemplateNameLoc(),
+ L.getQualifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()))};
}
void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
Ref = ReferenceLoc{
- L.getQualifierLoc(), L.getNameLoc(),
+ L.getQualifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()))};
}
void VisitTypedefTypeLoc(TypedefTypeLoc L) {
- Ref = ReferenceLoc{
- NestedNameSpecifierLoc(), L.getNameLoc(), {L.getTypedefNameDecl()}};
+ Ref = ReferenceLoc{NestedNameSpecifierLoc(),
+ L.getNameLoc(),
+ /*IsDecl=*/false,
+ {L.getTypedefNameDecl()}};
}
};
Visitor V;
V.Visit(L.getUnqualifiedLoc());
- return V.Ref;
+ if (!V.Ref)
+ return {};
+ return {*V.Ref};
}
class ExplicitReferenceColletor
@@ -575,6 +606,7 @@ public:
case TemplateArgument::TemplateExpansion:
reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
A.getTemplateNameLoc(),
+ /*IsDecl=*/false,
{A.getArgument()
.getAsTemplateOrTemplatePattern()
.getAsTemplateDecl()}},
@@ -625,34 +657,33 @@ private:
/// be references. However, declarations can have references inside them,
/// e.g. 'namespace foo = std' references namespace 'std' and this
/// function will return the corresponding reference.
- llvm::Optional<ReferenceLoc> explicitReference(DynTypedNode N) {
+ llvm::SmallVector<ReferenceLoc, 2> explicitReference(DynTypedNode N) {
if (auto *D = N.get<Decl>())
return refInDecl(D);
if (auto *E = N.get<Expr>())
return refInExpr(E);
if (auto *NNSL = N.get<NestedNameSpecifierLoc>())
- return ReferenceLoc{NNSL->getPrefix(), NNSL->getLocalBeginLoc(),
- explicitReferenceTargets(DynTypedNode::create(
- *NNSL->getNestedNameSpecifier()))};
+ return {ReferenceLoc{NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false,
+ explicitReferenceTargets(DynTypedNode::create(
+ *NNSL->getNestedNameSpecifier()))}};
if (const TypeLoc *TL = N.get<TypeLoc>())
return refInTypeLoc(*TL);
if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {
if (CCI->isBaseInitializer())
return refInTypeLoc(CCI->getBaseClassLoc());
assert(CCI->isAnyMemberInitializer());
- return ReferenceLoc{NestedNameSpecifierLoc(),
- CCI->getMemberLocation(),
- {CCI->getAnyMember()}};
+ return {ReferenceLoc{NestedNameSpecifierLoc(),
+ CCI->getMemberLocation(),
+ /*IsDecl=*/false,
+ {CCI->getAnyMember()}}};
}
// We do not have location information for other nodes (QualType, etc)
- return llvm::None;
+ return {};
}
void visitNode(DynTypedNode N) {
- auto Ref = explicitReference(N);
- if (!Ref)
- return;
- reportReference(*Ref, N);
+ for (const auto &R : explicitReference(N))
+ reportReference(R, N);
}
void reportReference(const ReferenceLoc &Ref, DynTypedNode N) {
@@ -727,6 +758,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceLoc R) {
PrintingPolicy(LangOptions()));
OS << "'";
}
+ if (R.IsDecl)
+ OS << ", decl";
return OS;
}
OpenPOWER on IntegriCloud