This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGfef242c32e83: [clangd] Fix locateMacroAt() for macro definition outside preamble (authored by nridge).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D91025/new/ https://reviews.llvm.org/D91025 Files: clang-tools-extra/clangd/SourceCode.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 @@ -1624,6 +1624,14 @@ } )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]]); Index: clang-tools-extra/clangd/SourceCode.cpp =================================================================== --- clang-tools-extra/clangd/SourceCode.cpp +++ clang-tools-extra/clangd/SourceCode.cpp @@ -975,17 +975,30 @@ 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 {
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1624,6 +1624,14 @@ } )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]]); Index: clang-tools-extra/clangd/SourceCode.cpp =================================================================== --- clang-tools-extra/clangd/SourceCode.cpp +++ clang-tools-extra/clangd/SourceCode.cpp @@ -975,17 +975,30 @@ 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 {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits