Index: clangd/SourceCode.h =================================================================== --- clangd/SourceCode.h +++ clangd/SourceCode.h @@ -18,6 +18,7 @@ namespace clang { class SourceManager; +class Decl; namespace clangd { @@ -30,6 +31,13 @@ /// Turn a SourceLocation into a [line, column] pair. Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc); +/// Get the source location of the given D. +/// +/// For symbols defined inside macros: +/// * use expansion location, if the symbol is formed via macro concatenation. +/// * use spelling location, otherwise. +SourceLocation getDeclSourceLoc(const clang::Decl* D); + } // namespace clangd } // namespace clang #endif Index: clangd/SourceCode.cpp =================================================================== --- clangd/SourceCode.cpp +++ clangd/SourceCode.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "SourceCode.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" #include "clang/Basic/SourceManager.h" namespace clang { @@ -48,5 +50,25 @@ return P; } +SourceLocation getDeclSourceLoc(const clang::Decl* D) { + const auto& SM = D->getASTContext().getSourceManager(); + SourceLocation SpellingLoc = SM.getSpellingLoc(D->getLocation()); + if (D->getLocation().isMacroID()) { + std::string PrintLoc = SpellingLoc.printToString(SM); + if (llvm::StringRef(PrintLoc).startswith("")) { + // We use the expansion location for the following symbols, as spelling + // locations of these symbols are not interesting to us: + // * symbols formed via macro concatenation, the spelling location will + // be "" + // * symbols controlled and defined by a compile command-line option + // `-DName=foo`, the spelling location will be "". + SpellingLoc = SM.getExpansionRange(D->getLocation()).first; + } + } + return SpellingLoc; + +} + } // namespace clangd } // namespace clang Index: clangd/XRefs.cpp =================================================================== --- clangd/XRefs.cpp +++ clangd/XRefs.cpp @@ -189,8 +189,11 @@ std::vector MacroInfos = DeclMacrosFinder->takeMacroInfos(); std::vector Result; - for (auto Item : Decls) { - auto L = getDeclarationLocation(AST, Item->getSourceRange()); + for (auto D : Decls) { + auto Loc = getDeclSourceLoc(D); + // We use the identifier range as the definition range which matches the + // index. + auto L = getDeclarationLocation(AST, SourceRange(Loc, Loc)); if (L) Result.push_back(*L); } Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -11,6 +11,7 @@ #include "../CodeCompletionStrings.h" #include "../Logger.h" #include "../URI.h" +#include "../SourceCode.h" #include "CanonicalIncludes.h" #include "clang/AST/DeclCXX.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -178,21 +179,7 @@ llvm::Optional getSymbolLocation( const NamedDecl &D, SourceManager &SM, const SymbolCollector::Options &Opts, const clang::LangOptions &LangOpts, std::string &FileURIStorage) { - SourceLocation SpellingLoc = SM.getSpellingLoc(D.getLocation()); - if (D.getLocation().isMacroID()) { - std::string PrintLoc = SpellingLoc.printToString(SM); - if (llvm::StringRef(PrintLoc).startswith("")) { - // We use the expansion location for the following symbols, as spelling - // locations of these symbols are not interesting to us: - // * symbols formed via macro concatenation, the spelling location will - // be "" - // * symbols controlled and defined by a compile command-line option - // `-DName=foo`, the spelling location will be "". - SpellingLoc = SM.getExpansionRange(D.getLocation()).first; - } - } - + SourceLocation SpellingLoc = getDeclSourceLoc(&D); auto U = toURI(SM, SM.getFilename(SpellingLoc), Opts); if (!U) return llvm::None; Index: unittests/clangd/XRefsTests.cpp =================================================================== --- unittests/clangd/XRefsTests.cpp +++ unittests/clangd/XRefsTests.cpp @@ -119,7 +119,7 @@ const char *Tests[] = { R"cpp(// Local variable int main() { - [[int bonjour]]; + int [[bonjour]]; ^bonjour = 2; int test1 = bonjour; } @@ -127,7 +127,7 @@ R"cpp(// Struct namespace ns1 { - [[struct MyClass {}]]; + struct [[MyClass]] {}; } // namespace ns1 int main() { ns1::My^Class* Params; @@ -135,21 +135,21 @@ )cpp", R"cpp(// Function definition via pointer - [[int foo(int) {}]] + int [[foo]](int) {} int main() { auto *X = &^foo; } )cpp", R"cpp(// Function declaration via call - [[int foo(int)]]; + int [[foo]](int); int main() { return ^foo(42); } )cpp", R"cpp(// Field - struct Foo { [[int x]]; }; + struct Foo { int [[x]]; }; int main() { Foo bar; bar.^x; @@ -158,27 +158,27 @@ R"cpp(// Field, member initializer struct Foo { - [[int x]]; + int [[x]]; Foo() : ^x(0) {} }; )cpp", R"cpp(// Field, GNU old-style field designator - struct Foo { [[int x]]; }; + struct Foo { int [[x]]; }; int main() { Foo bar = { ^x : 1 }; } )cpp", R"cpp(// Field, field designator - struct Foo { [[int x]]; }; + struct Foo { int [[x]]; }; int main() { Foo bar = { .^x = 2 }; } )cpp", R"cpp(// Method call - struct Foo { [[int x()]]; }; + struct Foo { int [[x]](); }; int main() { Foo bar; bar.^x(); @@ -186,7 +186,7 @@ )cpp", R"cpp(// Typedef - [[typedef int Foo]]; + typedef int [[Foo]]; int main() { ^Foo bar; } @@ -199,9 +199,9 @@ )cpp", */ R"cpp(// Namespace - [[namespace ns { + namespace [[ns]] { struct Foo { static void bar(); } - }]] // namespace ns + } // namespace ns int main() { ^ns::Foo::bar(); } )cpp", @@ -215,14 +215,26 @@ R"cpp(// Forward class declaration class Foo; - [[class Foo {}]]; + class [[Foo]] {}; F^oo* foo(); )cpp", R"cpp(// Function declaration void foo(); void g() { f^oo(); } - [[void foo() {}]] + void [[foo]]() {} + )cpp", + + R"cpp( + #define FF(name) class name##_Test {}; + [[FF]](my); + void f() { my^_Test a; } + )cpp", + + R"cpp( + #define FF() class [[Test]] {}; + FF(); + void f() { T^est a; } )cpp", }; for (const char *Test : Tests) { @@ -236,7 +248,7 @@ TEST(GoToDefinition, RelPathsInCompileCommand) { Annotations SourceAnnotations(R"cpp( -[[int foo]]; +int [[foo]]; int baz = f^oo; )cpp");