[llvm-branch-commits] [clang-tools-extra] fef242c - [clangd] Fix locateMacroAt() for macro definition outside preamble
Nathan Ridge via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Dec 13 15:38:33 PST 2020
Author: Nathan Ridge
Date: 2020-12-13T18:33:33-05:00
New Revision: fef242c32e833b84e8b46bd56a28c01c5f9aa65d
URL: https://github.com/llvm/llvm-project/commit/fef242c32e833b84e8b46bd56a28c01c5f9aa65d
DIFF: https://github.com/llvm/llvm-project/commit/fef242c32e833b84e8b46bd56a28c01c5f9aa65d.diff
LOG: [clangd] Fix locateMacroAt() for macro definition outside preamble
Fixes https://github.com/clangd/clangd/issues/577
Differential Revision: https://reviews.llvm.org/D91025
Added:
Modified:
clang-tools-extra/clangd/SourceCode.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp
index 54248386d7b4..c0ccf2152750 100644
--- a/clang-tools-extra/clangd/SourceCode.cpp
+++ b/clang-tools-extra/clangd/SourceCode.cpp
@@ -975,17 +975,30 @@ llvm::Optional<DefinedMacro> locateMacroAt(const syntax::Token &SpelledTok,
if (!IdentifierInfo || !IdentifierInfo->hadMacroDefinition())
return None;
- // Get the definition just before the searched location so that a macro
- // referenced in a '#undef MACRO' can still be found. Note that we only do
- // that if Loc is not pointing at start of file.
- if (SM.getLocForStartOfFile(SM.getFileID(Loc)) != Loc)
- Loc = Loc.getLocWithOffset(-1);
- MacroDefinition MacroDef = PP.getMacroDefinitionAtLoc(IdentifierInfo, Loc);
- if (auto *MI = MacroDef.getMacroInfo())
- return DefinedMacro{
- IdentifierInfo->getName(), MI,
- translatePreamblePatchLocation(MI->getDefinitionLoc(), SM)};
- return None;
+ // We need to take special case to handle #define and #undef.
+ // Preprocessor::getMacroDefinitionAtLoc() only considers a macro
+ // definition to be in scope *after* the location of the macro name in a
+ // #define that introduces it, and *before* the location of the macro name
+ // in an #undef that undefines it. To handle these cases, we check for
+ // the macro being in scope either just after or just before the location
+ // of the token. In getting the location before, we also take care to check
+ // for start-of-file.
+ FileID FID = SM.getFileID(Loc);
+ assert(Loc != SM.getLocForEndOfFile(FID));
+ SourceLocation JustAfterToken = Loc.getLocWithOffset(1);
+ auto *MacroInfo =
+ PP.getMacroDefinitionAtLoc(IdentifierInfo, JustAfterToken).getMacroInfo();
+ if (!MacroInfo && SM.getLocForStartOfFile(FID) != Loc) {
+ SourceLocation JustBeforeToken = Loc.getLocWithOffset(-1);
+ MacroInfo = PP.getMacroDefinitionAtLoc(IdentifierInfo, JustBeforeToken)
+ .getMacroInfo();
+ }
+ if (!MacroInfo) {
+ return None;
+ }
+ return DefinedMacro{
+ IdentifierInfo->getName(), MacroInfo,
+ translatePreamblePatchLocation(MacroInfo->getDefinitionLoc(), SM)};
}
llvm::Expected<std::string> Edit::apply() const {
diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
index c3c87bd628bd..5b0ceb1cc200 100644
--- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1624,6 +1624,14 @@ TEST(FindReferences, WithinAST) {
}
)cpp",
+ R"cpp(// Macro outside preamble
+ int breakPreamble;
+ #define [[MA^CRO]](X) (X+1)
+ void test() {
+ int x = [[MACRO]]([[MACRO]](1));
+ }
+ )cpp",
+
R"cpp(
int [[v^ar]] = 0;
void foo(int s = [[var]]);
More information about the llvm-branch-commits
mailing list