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 {