aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/Preprocessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/Preprocessor.cpp')
-rw-r--r--lib/Lex/Preprocessor.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 872cda390a..a0fc265b6b 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -285,6 +285,39 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const {
return Macros.end();
}
+/// \brief Compares macro tokens with a specified token value sequence.
+static bool MacroDefinitionEquals(const MacroInfo *MI,
+ llvm::ArrayRef<TokenValue> Tokens) {
+ return Tokens.size() == MI->getNumTokens() &&
+ std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin());
+}
+
+StringRef Preprocessor::getLastMacroWithSpelling(
+ SourceLocation Loc,
+ ArrayRef<TokenValue> Tokens) const {
+ SourceLocation BestLocation;
+ StringRef BestSpelling;
+ for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
+ I != E; ++I) {
+ if (!I->second->isObjectLike())
+ continue;
+ const MacroInfo *MI = I->second->findDefinitionAtLoc(Loc, SourceMgr);
+ if (!MI)
+ continue;
+ if (!MacroDefinitionEquals(MI, Tokens))
+ continue;
+ SourceLocation Location = I->second->getDefinitionLoc();
+ // Choose the macro defined latest.
+ if (BestLocation.isInvalid() ||
+ (Location.isValid() &&
+ SourceMgr.isBeforeInTranslationUnit(BestLocation, Location))) {
+ BestLocation = Location;
+ BestSpelling = I->first->getName();
+ }
+ }
+ return BestSpelling;
+}
+
void Preprocessor::recomputeCurLexerKind() {
if (CurLexer)
CurLexerKind = CLK_Lexer;