diff options
author | Sam McCall <sam.mccall@gmail.com> | 2022-09-20 22:39:47 +0300 |
---|---|---|
committer | Sam McCall <sam.mccall@gmail.com> | 2022-10-12 20:54:51 +0300 |
commit | 2eaf6f973cacd7f24691b72a9c6a3ee2a3d1a60b (patch) | |
tree | acd85f44f20df33bff5f2d778bca2c68955ba9cc /clang-tools-extra | |
parent | 20be96b19813a73137d2f5b398428a293e9f3399 (diff) |
[AST] Preserve more structure in UsingEnumDecl node.
- store NestedNameSpecifier & Loc for the qualifiers
This information was entirely missing from the AST.
- expose the location information for qualifier/identifier/typedefs as typeloc
This allows many traversals/astmatchers etc to handle these generically along
with other references. The decl vs type split can help preserve typedef
sugar when https://github.com/llvm/llvm-project/issues/57659 is resolved.
- fix the SourceRange of UsingEnumDecl to include 'using'.
Fixes https://github.com/clangd/clangd/issues/1283
Differential Revision: https://reviews.llvm.org/D134303
Diffstat (limited to 'clang-tools-extra')
4 files changed, 51 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index dea5cb7f5028..f76bedee0351 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -629,6 +629,12 @@ llvm::SmallVector<ReferenceLoc> refInDecl(const Decl *D, DeclRelation::Underlying, Resolver)}); } + void VisitUsingEnumDecl(const UsingEnumDecl *D) { + // "using enum ns::E" is a non-declaration reference. + // The reference is covered by the embedded typeloc. + // Don't use the default VisitNamedDecl, which would report a declaration. + } + void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { // For namespace alias, "namespace Foo = Target;", we add two references. // Add a declaration reference for Foo. diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index fd25e8059e81..57838eafd651 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -1267,6 +1267,15 @@ TEST_F(FindExplicitReferencesTest, All) { )cpp", "0: targets = {ns}\n" "1: targets = {ns::global}, qualifier = 'ns::'\n"}, + // Using enum declarations. + {R"cpp( + namespace ns { enum class A {}; } + void foo() { + using enum $0^ns::$1^A; + } + )cpp", + "0: targets = {ns}\n" + "1: targets = {ns::A}, qualifier = 'ns::'\n"}, // Simple types. {R"cpp( struct Struct { int a; }; diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp index 239566a35861..bd3df2404fcf 100644 --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -531,6 +531,33 @@ TEST(SelectionTest, CommonAncestor) { void func() { [[__^func__]]; } )cpp", "PredefinedExpr"}, + + // using enum + {R"cpp( + namespace ns { enum class A {}; }; + using enum ns::[[^A]]; + )cpp", + "EnumTypeLoc"}, + {R"cpp( + namespace ns { enum class A {}; using B = A; }; + using enum ns::[[^B]]; + )cpp", + "TypedefTypeLoc"}, + {R"cpp( + namespace ns { enum class A {}; }; + using enum [[^ns::]]A; + )cpp", + "NestedNameSpecifierLoc"}, + {R"cpp( + namespace ns { enum class A {}; }; + [[using ^enum ns::A]]; + )cpp", + "UsingEnumDecl"}, + {R"cpp( + namespace ns { enum class A {}; }; + [[^using enum ns::A]]; + )cpp", + "UsingEnumDecl"}, }; for (const Case &C : Cases) { @@ -541,6 +568,7 @@ TEST(SelectionTest, CommonAncestor) { TU.Code = std::string(Test.code()); TU.ExtraArgs.push_back("-xobjective-c++"); + TU.ExtraArgs.push_back("-std=c++20"); auto AST = TU.build(); auto T = makeSelectionTree(C.Code, AST); diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp index 32f0f58ade2c..e851bea5e632 100644 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -828,6 +828,14 @@ sizeof...($TemplateParameter[[Elements]]); typedef int $Primitive_decl[[MyTypedef]]; enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {}; )cpp", + // Using enum + R"cpp( + enum class $Enum_decl[[Color]] { $EnumConstant_decl_readonly[[Black]] }; + namespace $Namespace_decl[[ns]] { + using enum $Enum[[Color]]; + $Enum[[Color]] $Variable_decl[[ModelT]] = $EnumConstant[[Black]]; + } + )cpp", // Issue 1096 R"cpp( void $Function_decl[[Foo]](); |