зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
19d5aea478
Коммит
69bda4c027
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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<FileID, unsigned> 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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче