From 25e690273ac15efd5b2afa3ee5b3bde36913ca33 Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Sun, 24 Feb 2019 23:47:03 +0000 Subject: [PATCH] [clangd] Enhance macro hover to see full definition Summary: Signed-off-by: Marc-Andre Laperle Reviewers: simark, ilya-biryukov, sammccall, ioeric, hokein Reviewed By: ilya-biryukov Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D55250 llvm-svn: 354761 --- clang-tools-extra/clangd/XRefs.cpp | 31 ++++++++++++++++++----- clang-tools-extra/unittests/clangd/XRefsTests.cpp | 20 ++++++++++++++- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index 216d78d..edb1f7c 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -558,13 +558,30 @@ static Hover getHoverContents(QualType T, ASTContext &ASTCtx) { return H; } -/// Generate a \p Hover object given the macro \p MacroInf. -static Hover getHoverContents(llvm::StringRef MacroName) { - Hover H; - - H.contents.value = "#define "; - H.contents.value += MacroName; +/// Generate a \p Hover object given the macro \p MacroDecl. +static Hover getHoverContents(MacroDecl Decl, ParsedAST &AST) { + SourceManager &SM = AST.getASTContext().getSourceManager(); + std::string Definition = Decl.Name; + + // Try to get the full definition, not just the name + SourceLocation StartLoc = Decl.Info->getDefinitionLoc(); + SourceLocation EndLoc = Decl.Info->getDefinitionEndLoc(); + if (EndLoc.isValid()) { + EndLoc = Lexer::getLocForEndOfToken(EndLoc, 0, SM, + AST.getASTContext().getLangOpts()); + bool Invalid; + StringRef Buffer = SM.getBufferData(SM.getFileID(StartLoc), &Invalid); + if (!Invalid) { + unsigned StartOffset = SM.getFileOffset(StartLoc); + unsigned EndOffset = SM.getFileOffset(EndLoc); + if (EndOffset <= Buffer.size() && StartOffset < EndOffset) + Definition = Buffer.substr(StartOffset, EndOffset - StartOffset).str(); + } + } + Hover H; + H.contents.kind = MarkupKind::PlainText; + H.contents.value = "#define " + Definition; return H; } @@ -688,7 +705,7 @@ llvm::Optional getHover(ParsedAST &AST, Position Pos) { auto Symbols = getSymbolAtPosition(AST, SourceLocationBeg); if (!Symbols.Macros.empty()) - return getHoverContents(Symbols.Macros[0].Name); + return getHoverContents(Symbols.Macros[0], AST); if (!Symbols.Decls.empty()) return getHoverContents(Symbols.Decls[0]); diff --git a/clang-tools-extra/unittests/clangd/XRefsTests.cpp b/clang-tools-extra/unittests/clangd/XRefsTests.cpp index c1a253c..df795b1 100644 --- a/clang-tools-extra/unittests/clangd/XRefsTests.cpp +++ b/clang-tools-extra/unittests/clangd/XRefsTests.cpp @@ -743,7 +743,25 @@ TEST(Hover, All) { #define MACRO 2 #undef macro )cpp", - "#define MACRO", + "#define MACRO 1", + }, + { + R"cpp(// Macro + #define MACRO 0 + #define MACRO2 ^MACRO + )cpp", + "#define MACRO 0", + }, + { + R"cpp(// Macro + #define MACRO {\ + return 0;\ + } + int main() ^MACRO + )cpp", + R"cpp(#define MACRO {\ + return 0;\ + })cpp", }, { R"cpp(// Forward class declaration -- 2.7.4