From 69bda4c027671df7163619f215209529eb236620 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 19 Jan 2012 15:59:08 +0000 Subject: [PATCH] For Lexer's isAt[Start/End]OfMacroExpansion add an out parameter for the macro start/end location. It is commonly needed after calling the function; with this way we avoid recalculating it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148479 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/Lexer.h | 16 ++++++++++---- include/clang/Lex/Preprocessor.h | 17 +++++++++++---- lib/ARCMigrate/Transforms.cpp | 3 +-- lib/Lex/Lexer.cpp | 36 +++++++++++++++++++------------- lib/Parse/ParseExpr.cpp | 4 ++-- unittests/Lex/LexerTest.cpp | 7 +++++-- 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 1751d22b0b..99c16d292a 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -313,15 +313,23 @@ public: /// \brief Returns true if the given MacroID location points at the first /// token of the macro expansion. + /// + /// \param MacroBegin If non-null and function returns true, it is set to + /// begin location of the macro. static bool isAtStartOfMacroExpansion(SourceLocation loc, - const SourceManager &SM, - const LangOptions &LangOpts); + const SourceManager &SM, + const LangOptions &LangOpts, + SourceLocation *MacroBegin = 0); /// \brief Returns true if the given MacroID location points at the last /// token of the macro expansion. + /// + /// \param MacroBegin If non-null and function returns true, it is set to + /// end location of the macro. static bool isAtEndOfMacroExpansion(SourceLocation loc, - const SourceManager &SM, - const LangOptions &LangOpts); + const SourceManager &SM, + const LangOptions &LangOpts, + SourceLocation *MacroEnd = 0); /// \brief Retrieve the name of the immediate macro expansion. /// diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index a83f6e26c7..c6190b0470 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -869,14 +869,23 @@ public: /// \brief Returns true if the given MacroID location points at the first /// token of the macro expansion. - bool isAtStartOfMacroExpansion(SourceLocation loc) const { - return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, Features); + /// + /// \param MacroBegin If non-null and function returns true, it is set to + /// begin location of the macro. + bool isAtStartOfMacroExpansion(SourceLocation loc, + SourceLocation *MacroBegin = 0) const { + return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, Features, + MacroBegin); } /// \brief Returns true if the given MacroID location points at the last /// token of the macro expansion. - bool isAtEndOfMacroExpansion(SourceLocation loc) const { - return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, Features); + /// + /// \param MacroBegin If non-null and function returns true, it is set to + /// end location of the macro. + bool isAtEndOfMacroExpansion(SourceLocation loc, + SourceLocation *MacroEnd = 0) const { + return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, Features, MacroEnd); } /// DumpToken - Print the token to stderr, used for debugging. diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp index 21df257872..a64124015c 100644 --- a/lib/ARCMigrate/Transforms.cpp +++ b/lib/ARCMigrate/Transforms.cpp @@ -111,9 +111,8 @@ SourceLocation trans::findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx) { SourceManager &SM = Ctx.getSourceManager(); if (loc.isMacroID()) { - if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOptions())) + if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOptions(), &loc)) return SourceLocation(); - loc = SM.getExpansionRange(loc).second; } loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOptions()); diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index bb1bbbbe7e..ddb5eccff5 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -720,11 +720,8 @@ SourceLocation Lexer::getLocForEndOfToken(SourceLocation Loc, unsigned Offset, return SourceLocation(); if (Loc.isMacroID()) { - if (Offset > 0 || !isAtEndOfMacroExpansion(Loc, SM, Features)) + if (Offset > 0 || !isAtEndOfMacroExpansion(Loc, SM, Features, &Loc)) return SourceLocation(); // Points inside the macro expansion. - - // Continue and find the location just after the macro expansion. - Loc = SM.getExpansionRange(Loc).second; } unsigned Len = Lexer::MeasureTokenLength(Loc, SM, Features); @@ -740,7 +737,8 @@ SourceLocation Lexer::getLocForEndOfToken(SourceLocation Loc, unsigned Offset, /// token of the macro expansion. bool Lexer::isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + SourceLocation *MacroBegin) { assert(loc.isValid() && loc.isMacroID() && "Expected a valid macro loc"); std::pair infoLoc = SM.getDecomposedLoc(loc); @@ -751,17 +749,22 @@ bool Lexer::isAtStartOfMacroExpansion(SourceLocation loc, SourceLocation expansionLoc = SM.getSLocEntry(infoLoc.first).getExpansion().getExpansionLocStart(); - if (expansionLoc.isFileID()) - return true; // No other macro expansions, this is the first. + if (expansionLoc.isFileID()) { + // No other macro expansions, this is the first. + if (MacroBegin) + *MacroBegin = expansionLoc; + return true; + } - return isAtStartOfMacroExpansion(expansionLoc, SM, LangOpts); + return isAtStartOfMacroExpansion(expansionLoc, SM, LangOpts, MacroBegin); } /// \brief Returns true if the given MacroID location points at the last /// token of the macro expansion. bool Lexer::isAtEndOfMacroExpansion(SourceLocation loc, - const SourceManager &SM, - const LangOptions &LangOpts) { + const SourceManager &SM, + const LangOptions &LangOpts, + SourceLocation *MacroEnd) { assert(loc.isValid() && loc.isMacroID() && "Expected a valid macro loc"); SourceLocation spellLoc = SM.getSpellingLoc(loc); @@ -779,10 +782,14 @@ bool Lexer::isAtEndOfMacroExpansion(SourceLocation loc, SourceLocation expansionLoc = SM.getSLocEntry(FID).getExpansion().getExpansionLocEnd(); - if (expansionLoc.isFileID()) - return true; // No other macro expansions. + if (expansionLoc.isFileID()) { + // No other macro expansions. + if (MacroEnd) + *MacroEnd = expansionLoc; + return true; + } - return isAtEndOfMacroExpansion(expansionLoc, SM, LangOpts); + return isAtEndOfMacroExpansion(expansionLoc, SM, LangOpts, MacroEnd); } StringRef Lexer::getImmediateMacroName(SourceLocation Loc, @@ -1108,9 +1115,8 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc, const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine) { if (Loc.isMacroID()) { - if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts)) + if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc)) return SourceLocation(); - Loc = SM.getExpansionRange(Loc).second; } Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts); diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 7eac984172..c766bad110 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -312,8 +312,8 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { SourceLocation FILoc = Tok.getLocation(); const char *FIText = ": "; const SourceManager &SM = PP.getSourceManager(); - if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc)) { - FILoc = SM.getExpansionLoc(FILoc); + if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc, &FILoc)) { + assert(FILoc.isFileID()); bool IsInvalid = false; const char *SourcePtr = SM.getCharacterData(FILoc.getLocWithOffset(-1), &IsInvalid); diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp index 17c9cf8cca..e63f31a705 100644 --- a/unittests/Lex/LexerTest.cpp +++ b/unittests/Lex/LexerTest.cpp @@ -91,10 +91,13 @@ TEST_F(LexerTest, LexAPI) { SourceLocation idLoc = toks[1].getLocation(); SourceLocation rsqrLoc = toks[2].getLocation(); - EXPECT_TRUE(Lexer::isAtStartOfMacroExpansion(lsqrLoc, SourceMgr, LangOpts)); + SourceLocation Loc; + EXPECT_TRUE(Lexer::isAtStartOfMacroExpansion(lsqrLoc, SourceMgr, LangOpts, &Loc)); + EXPECT_EQ(SourceMgr.getExpansionLoc(lsqrLoc), Loc); EXPECT_FALSE(Lexer::isAtStartOfMacroExpansion(idLoc, SourceMgr, LangOpts)); EXPECT_FALSE(Lexer::isAtEndOfMacroExpansion(idLoc, SourceMgr, LangOpts)); - EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts)); + EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts, &Loc)); + EXPECT_EQ(SourceMgr.getExpansionRange(rsqrLoc).second, Loc); } } // anonymous namespace