hokein created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman.
Herald added a project: clang.
hokein requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.
Extend the TargetDecl API to fix the workaround in
https://reviews.llvm.org/D87225 and
https://reviews.llvm.org/D74054.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D88472
Files:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/FindTarget.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1090,7 +1090,6 @@
R"cpp(
template <class T> struct function {};
template <class T> using [[callback]] = function<T()>;
-
c^allback<int> foo;
)cpp",
@@ -1118,17 +1117,17 @@
// decls.
R"cpp(
namespace ns { class [[Foo]] {}; }
- using ns::F^oo;
+ using ns::[[F^oo]];
)cpp",
R"cpp(
namespace ns { int [[x]](char); int [[x]](double); }
- using ns::^x;
+ using ns::[[^x]];
)cpp",
R"cpp(
namespace ns { int [[x]](char); int x(double); }
- using ns::x;
+ using ns::[[x]];
int y = ^x('a');
)cpp",
@@ -1156,7 +1155,7 @@
};
template <typename T>
struct Derived : Base<T> {
- using Base<T>::w^aldo;
+ using Base<T>::[[w^aldo]];
};
)cpp",
};
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -182,7 +182,7 @@
)cpp";
// f(char) is not referenced!
EXPECT_DECLS("DeclRefExpr", {"using foo::f", Rel::Alias},
- {"int f(int)", Rel::Underlying});
+ {"int f(int)", Rel::NonAliasUnderlying});
Code = R"cpp(
namespace foo {
@@ -193,8 +193,8 @@
)cpp";
// All overloads are referenced.
EXPECT_DECLS("UsingDecl", {"using foo::f", Rel::Alias},
- {"int f(int)", Rel::Underlying},
- {"int f(char)", Rel::Underlying});
+ {"int f(int)", Rel::NonAliasUnderlying},
+ {"int f(char)", Rel::NonAliasUnderlying});
Code = R"cpp(
struct X {
@@ -206,7 +206,7 @@
int x = Y().[[foo]]();
)cpp";
EXPECT_DECLS("MemberExpr", {"using X::foo", Rel::Alias},
- {"int foo()", Rel::Underlying});
+ {"int foo()", Rel::NonAliasUnderlying});
Code = R"cpp(
template <typename T>
@@ -219,7 +219,7 @@
};
)cpp";
EXPECT_DECLS("UnresolvedUsingValueDecl", {"using Base<T>::waldo", Rel::Alias},
- {"void waldo()", Rel::Underlying});
+ {"void waldo()", Rel::NonAliasUnderlying});
}
TEST_F(TargetDeclTest, ConstructorInitList) {
@@ -275,7 +275,7 @@
int y = [[b]]::x;
)cpp";
EXPECT_DECLS("NestedNameSpecifierLoc", {"namespace b = a", Rel::Alias},
- {"namespace a", Rel::Underlying});
+ {"namespace a", Rel::AliasUnderlying});
}
TEST_F(TargetDeclTest, Types) {
@@ -291,14 +291,14 @@
[[X]] x;
)cpp";
EXPECT_DECLS("TypedefTypeLoc", {"typedef S X", Rel::Alias},
- {"struct S", Rel::Underlying});
+ {"struct S", Rel::AliasUnderlying});
Code = R"cpp(
namespace ns { struct S{}; }
typedef ns::S X;
[[X]] x;
)cpp";
EXPECT_DECLS("TypedefTypeLoc", {"typedef ns::S X", Rel::Alias},
- {"struct S", Rel::Underlying});
+ {"struct S", Rel::AliasUnderlying});
// FIXME: Auto-completion in a template requires disabling delayed template
// parsing.
@@ -325,7 +325,7 @@
S X;
[[decltype]](X) Y;
)cpp";
- EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::Underlying});
+ EXPECT_DECLS("DecltypeTypeLoc", {"struct S", Rel::NonAliasUnderlying});
Code = R"cpp(
struct S{};
@@ -534,8 +534,9 @@
)cpp";
EXPECT_DECLS("TemplateSpecializationTypeLoc",
{"template<> class SmallVector<int, 1>",
- Rel::TemplateInstantiation | Rel::Underlying},
- {"class SmallVector", Rel::TemplatePattern | Rel::Underlying},
+ Rel::TemplateInstantiation | DeclRelation::AliasUnderlying},
+ {"class SmallVector",
+ Rel::TemplatePattern | DeclRelation::AliasUnderlying},
{"using TinyVector = SmallVector<U, 1>",
Rel::Alias | Rel::TemplatePattern});
}
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -314,8 +314,9 @@
};
// Emit all symbol locations (declaration or definition) from AST.
- DeclRelationSet Relations =
- DeclRelation::TemplatePattern | DeclRelation::Alias;
+ DeclRelationSet Relations = DeclRelation::TemplatePattern |
+ DeclRelation::Alias |
+ DeclRelation::NonAliasUnderlying;
for (const NamedDecl *D :
getDeclAtPosition(AST, CurLoc, Relations, NodeKind)) {
// Special case: void foo() ^override: jump to the overridden method.
@@ -343,18 +344,6 @@
}
}
- // Give the underlying decl if navigation is triggered on a non-renaming
- // alias.
- if (llvm::isa<UsingDecl>(D) || llvm::isa<UnresolvedUsingValueDecl>(D)) {
- // FIXME: address more complicated cases. TargetDecl(... Underlying) gives
- // all overload candidates, we only want the targeted one if the cursor is
- // on an using-alias usage, workround it with getDeclAtPosition.
- llvm::for_each(
- getDeclAtPosition(AST, CurLoc, DeclRelation::Underlying, NodeKind),
- [&](const NamedDecl *UD) { AddResultDecl(UD); });
- continue;
- }
-
// Special case: if the class name is selected, also map Objective-C
// categories and category implementations back to their class interface.
//
@@ -1140,21 +1129,10 @@
} else {
// Handle references to Decls.
- DeclRelationSet Relations =
- DeclRelation::TemplatePattern | DeclRelation::Alias;
- std::vector<const NamedDecl *> Decls =
- getDeclAtPosition(AST, *CurLoc, Relations);
- std::vector<const NamedDecl *> NonrenamingAliasUnderlyingDecls;
- // If the results include a *non-renaming* alias, get its
- // underlying decls as well. (See similar logic in locateASTReferent()).
- for (const NamedDecl *D : Decls) {
- if (llvm::isa<UsingDecl>(D) || llvm::isa<UnresolvedUsingValueDecl>(D)) {
- for (const NamedDecl *AD :
- getDeclAtPosition(AST, *CurLoc, DeclRelation::Underlying))
- NonrenamingAliasUnderlyingDecls.push_back(AD);
- }
- }
- llvm::copy(NonrenamingAliasUnderlyingDecls, std::back_inserter(Decls));
+ DeclRelationSet Relations = DeclRelation::TemplatePattern |
+ DeclRelation::Alias |
+ DeclRelation::NonAliasUnderlying;
+ auto Decls = getDeclAtPosition(AST, *CurLoc, Relations);
// We traverse the AST to find references in the main file.
auto MainFileRefs = findRefs(Decls, AST);
@@ -1221,8 +1199,9 @@
// We also want the targets of using-decls, so we include
// DeclRelation::Underlying.
- DeclRelationSet Relations = DeclRelation::TemplatePattern |
- DeclRelation::Alias | DeclRelation::Underlying;
+ DeclRelationSet Relations =
+ DeclRelation::TemplatePattern | DeclRelation::Alias |
+ DeclRelation::NonAliasUnderlying | DeclRelation::AliasUnderlying;
for (const NamedDecl *D : getDeclAtPosition(AST, *CurLoc, Relations)) {
SymbolDetails NewSymbol;
std::string QName = printQualifiedName(*D);
@@ -1406,7 +1385,9 @@
// instantiations and template patterns, and prefer the former if available
// (generally, one will be available for non-dependent specializations of a
// class template).
- auto Decls = explicitReferenceTargets(N->ASTNode, DeclRelation::Underlying);
+ auto Decls =
+ explicitReferenceTargets(N->ASTNode, DeclRelation::NonAliasUnderlying |
+ DeclRelation::AliasUnderlying);
if (Decls.empty())
return nullptr;
Index: clang-tools-extra/clangd/FindTarget.h
===================================================================
--- clang-tools-extra/clangd/FindTarget.h
+++ clang-tools-extra/clangd/FindTarget.h
@@ -107,9 +107,14 @@
/// This declaration is an alias that was referred to.
/// e.g. using llvm::StringRef (the UsingDecl directly referenced).
Alias,
- /// This is the underlying declaration for an alias, decltype etc.
+
+ /// Underlying declarations for renaming alias (typedef decl, type alias decl)
+ AliasUnderlying,
+ /// Underlying declarations for non-renaming alias, decltype, etc.
/// e.g. class llvm::StringRef (the underlying declaration referenced).
- Underlying,
+ NonAliasUnderlying,
+
+ LastKind = NonAliasUnderlying,
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &, DeclRelation);
@@ -161,7 +166,7 @@
// Boring implementation details of bitfield.
class DeclRelationSet {
- using Set = std::bitset<static_cast<unsigned>(DeclRelation::Underlying) + 1>;
+ using Set = std::bitset<static_cast<unsigned>(DeclRelation::LastKind) + 1>;
Set S;
DeclRelationSet(Set S) : S(S) {}
Index: clang-tools-extra/clangd/FindTarget.cpp
===================================================================
--- clang-tools-extra/clangd/FindTarget.cpp
+++ clang-tools-extra/clangd/FindTarget.cpp
@@ -339,14 +339,14 @@
D = UDD->getNominatedNamespaceAsWritten();
if (const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) {
- add(TND->getUnderlyingType(), Flags | Rel::Underlying);
+ add(TND->getUnderlyingType(), Flags | Rel::AliasUnderlying);
Flags |= Rel::Alias; // continue with the alias.
} else if (const UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
for (const UsingShadowDecl *S : UD->shadows())
- add(S->getUnderlyingDecl(), Flags | Rel::Underlying);
+ add(S->getUnderlyingDecl(), Flags | Rel::NonAliasUnderlying);
Flags |= Rel::Alias; // continue with the alias.
} else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {
- add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying);
+ add(NAD->getUnderlyingDecl(), Flags | Rel::AliasUnderlying);
Flags |= Rel::Alias; // continue with the alias
} else if (const UnresolvedUsingValueDecl *UUVD =
dyn_cast<UnresolvedUsingValueDecl>(D)) {
@@ -354,7 +354,7 @@
UUVD->getQualifier()->getAsType(),
[UUVD](ASTContext &) { return UUVD->getNameInfo().getName(); },
ValueFilter)) {
- add(Target, Flags | Rel::Underlying);
+ add(Target, Flags | Rel::NonAliasUnderlying);
}
Flags |= Rel::Alias; // continue with the alias
} else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
@@ -364,7 +364,7 @@
// Shadow decls are synthetic and not themselves interesting.
// Record the underlying decl instead, if allowed.
D = USD->getTargetDecl();
- Flags |= Rel::Underlying; // continue with the underlying decl.
+ Flags |= Rel::NonAliasUnderlying; // continue with the underlying decl.
} else if (const auto *DG = dyn_cast<CXXDeductionGuideDecl>(D)) {
D = DG->getDeducedTemplate();
} else if (const ObjCImplementationDecl *IID =
@@ -518,12 +518,12 @@
}
void VisitDecltypeType(const DecltypeType *DTT) {
- Outer.add(DTT->getUnderlyingType(), Flags | Rel::Underlying);
+ Outer.add(DTT->getUnderlyingType(), Flags | Rel::NonAliasUnderlying);
}
void VisitDeducedType(const DeducedType *DT) {
// FIXME: In practice this doesn't work: the AutoType you find inside
// TypeLoc never has a deduced type. https://llvm.org/PR42914
- Outer.add(DT->getDeducedType(), Flags | Rel::Underlying);
+ Outer.add(DT->getDeducedType(), Flags | Rel::NonAliasUnderlying);
}
void VisitDeducedTemplateSpecializationType(
const DeducedTemplateSpecializationType *DTST) {
@@ -548,7 +548,7 @@
// (after substitution), and failing that point to the (templated) using
// decl.
if (TST->isTypeAlias()) {
- Outer.add(TST->getAliasedType(), Flags | Rel::Underlying);
+ Outer.add(TST->getAliasedType(), Flags | Rel::AliasUnderlying);
// Don't *traverse* the alias, which would result in traversing the
// template of the underlying type.
Outer.report(
@@ -721,10 +721,10 @@
void VisitUsingDecl(const UsingDecl *D) {
// "using ns::identifier;" is a non-declaration reference.
- Refs.push_back(
- ReferenceLoc{D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
- explicitReferenceTargets(DynTypedNode::create(*D),
- DeclRelation::Underlying)});
+ Refs.push_back(ReferenceLoc{
+ D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
+ explicitReferenceTargets(DynTypedNode::create(*D),
+ DeclRelation::NonAliasUnderlying)});
}
void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
@@ -1144,7 +1144,8 @@
case DeclRelation::X: \
return OS << #X;
REL_CASE(Alias);
- REL_CASE(Underlying);
+ REL_CASE(NonAliasUnderlying);
+ REL_CASE(AliasUnderlying);
REL_CASE(TemplateInstantiation);
REL_CASE(TemplatePattern);
#undef REL_CASE
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits