diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/SourceManager.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Lex/Lexer.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Lex/Pragma.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Lex/TokenLexer.cpp | 18 |
7 files changed, 67 insertions, 32 deletions
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index e023a91f2f1..71bda5b255f 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -352,7 +352,7 @@ void SourceManager::clearIDTables() { // Use up FileID #0 as an invalid instantiation. NextOffset = 0; - createInstantiationLoc(SourceLocation(), SourceLocation(), 1); + createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1); } /// getOrCreateContentCache - Create or return a cached ContentCache for the @@ -418,11 +418,11 @@ FileID SourceManager::createFileID(const ContentCache *File, /// that a token from SpellingLoc should actually be referenced from /// InstantiationLoc. SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc, - SourceLocation InstantLoc, + SourceLocation ILocStart, + SourceLocation ILocEnd, unsigned TokLength) { - SLocEntryTable.push_back(SLocEntry::get(NextOffset, - InstantiationInfo::get(InstantLoc, - SpellingLoc))); + InstantiationInfo II = InstantiationInfo::get(ILocStart,ILocEnd, SpellingLoc); + SLocEntryTable.push_back(SLocEntry::get(NextOffset, II)); assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!"); NextOffset += TokLength+1; return SourceLocation::getMacroLoc(NextOffset-(TokLength+1)); @@ -543,7 +543,8 @@ SourceLocation SourceManager:: getInstantiationLocSlowCase(SourceLocation Loc) const { do { std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); - Loc =getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc(); + Loc = getSLocEntry(LocInfo.first).getInstantiation() + .getInstantiationLocStart(); Loc = Loc.getFileLocWithOffset(LocInfo.second); } while (!Loc.isFileID()); @@ -568,7 +569,7 @@ SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, FileID FID; SourceLocation Loc; do { - Loc = E->getInstantiation().getInstantiationLoc(); + Loc = E->getInstantiation().getInstantiationLocStart(); FID = getFileID(Loc); E = &getSLocEntry(FID); @@ -596,6 +597,16 @@ SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, return std::make_pair(FID, Offset); } +/// getImmediateInstantiationRange - Loc is required to be an instantiation +/// location. Return the start/end of the instantiation information. +std::pair<SourceLocation,SourceLocation> +SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const { + assert(Loc.isMacroID() && "Not an instantiation loc!"); + const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation(); + return II.getInstantiationLocRange(); +} + + //===----------------------------------------------------------------------===// // Queries about the code at a SourceLocation. diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 72715c9eeda..5f325220206 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -151,7 +151,8 @@ Lexer::Lexer(FileID FID, const SourceManager &SM, const LangOptions &features) /// out of the critical path of the lexer! /// Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc, - SourceLocation InstantiationLoc, + SourceLocation InstantiationLocStart, + SourceLocation InstantiationLocEnd, unsigned TokLen, Preprocessor &PP) { SourceManager &SM = PP.getSourceManager(); @@ -170,7 +171,8 @@ Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc, // Set the SourceLocation with the remapping information. This ensures that // GetMappedTokenLoc will remap the tokens as they are lexed. L->FileLoc = SM.createInstantiationLoc(SM.getLocForStartOfFile(SpellingFID), - InstantiationLoc, TokLen); + InstantiationLocStart, + InstantiationLocEnd, TokLen); // Ensure that the lexer thinks it is inside a directive, so that end \n will // return an EOM token. @@ -315,16 +317,24 @@ static SourceLocation GetMappedTokenLoc(Preprocessor &PP, static SourceLocation GetMappedTokenLoc(Preprocessor &PP, SourceLocation FileLoc, unsigned CharNo, unsigned TokLen) { + assert(FileLoc.isMacroID() && "Must be an instantiation"); + // Otherwise, we're lexing "mapped tokens". This is used for things like // _Pragma handling. Combine the instantiation location of FileLoc with the // spelling location. - SourceManager &SourceMgr = PP.getSourceManager(); + SourceManager &SM = PP.getSourceManager(); // Create a new SLoc which is expanded from Instantiation(FileLoc) but whose // characters come from spelling(FileLoc)+Offset. - SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(FileLoc); + SourceLocation SpellingLoc = SM.getSpellingLoc(FileLoc); SpellingLoc = SpellingLoc.getFileLocWithOffset(CharNo); - return SourceMgr.createInstantiationLoc(SpellingLoc, FileLoc, TokLen); + + // Figure out the expansion loc range, which is the range covered by the + // original _Pragma(...) sequence. + std::pair<SourceLocation,SourceLocation> II = + SM.getImmediateInstantiationRange(FileLoc); + + return SM.createInstantiationLoc(SpellingLoc, II.first, II.second, TokLen); } /// getSourceLocation - Return a source location identifier for the specified diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index ec3447a5af9..13e6126899d 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -127,15 +127,16 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL, /// EnterMacro - Add a Macro to the top of the include stack and start lexing /// tokens from it instead of the current buffer. -void Preprocessor::EnterMacro(Token &Tok, MacroArgs *Args) { +void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd, + MacroArgs *Args) { PushIncludeMacroStack(); CurDirLookup = 0; if (NumCachedTokenLexers == 0) { - CurTokenLexer.reset(new TokenLexer(Tok, Args, *this)); + CurTokenLexer.reset(new TokenLexer(Tok, ILEnd, Args, *this)); } else { CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]); - CurTokenLexer->Init(Tok, Args); + CurTokenLexer->Init(Tok, ILEnd, Args); } } diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 776754372d3..ae686527f55 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -165,6 +165,10 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, /// invocation. MacroArgs *Args = 0; + // Remember where the end of the instantiation occurred. For an object-like + // macro, this is the identifier. For a function-like macro, this is the ')'. + SourceLocation InstantiationEnd = Identifier.getLocation(); + // If this is a function-like macro, read the arguments. if (MI->isFunctionLike()) { // C99 6.10.3p10: If the preprocessing token immediately after the the macro @@ -177,7 +181,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // Preprocessor directives used inside macro arguments are not portable, and // this enables the warning. InMacroArgs = true; - Args = ReadFunctionLikeMacroArgs(Identifier, MI); + Args = ReadFunctionLikeMacroArgs(Identifier, MI, InstantiationEnd); // Finished parsing args. InMacroArgs = false; @@ -248,7 +252,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // locations. SourceLocation Loc = SourceMgr.createInstantiationLoc(Identifier.getLocation(), InstantiateLoc, - Identifier.getLength()); + InstantiationEnd,Identifier.getLength()); Identifier.setLocation(Loc); // If this is #define X X, we must mark the result as unexpandible. @@ -263,7 +267,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, } // Start expanding the macro. - EnterMacro(Identifier, Args); + EnterMacro(Identifier, InstantiationEnd, Args); // Now that the macro is at the top of the include stack, ask the // preprocessor to read the next token from it. @@ -275,7 +279,8 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, /// invoked to read all of the actual arguments specified for the macro /// invocation. This returns null on error. MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, - MacroInfo *MI) { + MacroInfo *MI, + SourceLocation &MacroEnd) { // The number of fixed arguments to parse. unsigned NumFixedArgsLeft = MI->getNumArgs(); bool isVariadic = MI->isVariadic(); @@ -308,8 +313,10 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, return 0; } else if (Tok.is(tok::r_paren)) { // If we found the ) token, the macro arg list is done. - if (NumParens-- == 0) + if (NumParens-- == 0) { + MacroEnd = Tok.getLocation(); break; + } } else if (Tok.is(tok::l_paren)) { ++NumParens; } else if (Tok.is(tok::comma) && NumParens == 0) { @@ -357,7 +364,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, ArgTokens.push_back(EOFTok); ++NumActuals; --NumFixedArgsLeft; - }; + } // Okay, we either found the r_paren. Check to see if we parsed too few // arguments. @@ -494,6 +501,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"Mmm dd yyyy\"")); Tok.setLocation(SourceMgr.createInstantiationLoc(DATELoc, Tok.getLocation(), + Tok.getLocation(), Tok.getLength())); } else if (II == Ident__TIME__) { if (!TIMELoc.isValid()) @@ -501,6 +509,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"hh:mm:ss\"")); Tok.setLocation(SourceMgr.createInstantiationLoc(TIMELoc, Tok.getLocation(), + Tok.getLocation(), Tok.getLength())); } else if (II == Ident__INCLUDE_LEVEL__) { Diag(Tok, diag::ext_pp_include_level); diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 87410f9ff4a..73d36414ba9 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -117,7 +117,6 @@ void Preprocessor::Handle_Pragma(Token &Tok) { // Remember the string. std::string StrVal = getSpelling(Tok); - SourceLocation StrLoc = Tok.getLocation(); // Read the ')'. Lex(Tok); @@ -126,6 +125,8 @@ void Preprocessor::Handle_Pragma(Token &Tok) { return; } + SourceLocation RParenLoc = Tok.getLocation(); + // The _Pragma is lexically sound. Destringize according to C99 6.10.9.1: // "The string literal is destringized by deleting the L prefix, if present, // deleting the leading and trailing double-quotes, replacing each escape @@ -163,7 +164,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) { // Make and enter a lexer object so that we lex and expand the tokens just // like any others. - Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, StrLoc, + Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc, // do not include the null in the count. StrVal.size()-1, *this); diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index d769720634d..cf7306a41cc 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -277,7 +277,8 @@ void Preprocessor::CreateString(const char *Buf, unsigned Len, Token &Tok, SourceLocation Loc = ScratchBuf->getToken(Buf, Len, DestPtr); if (InstantiationLoc.isValid()) - Loc = SourceMgr.createInstantiationLoc(Loc, InstantiationLoc, Len); + Loc = SourceMgr.createInstantiationLoc(Loc, InstantiationLoc, + InstantiationLoc, Len); Tok.setLocation(Loc); // If this is a literal token, set the pointer data. diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index 3ca0fcfa05d..f0e2fbdfa62 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -23,7 +23,7 @@ using namespace clang; /// Create a TokenLexer for the specified macro with the specified actual /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. -void TokenLexer::Init(Token &Tok, MacroArgs *Actuals) { +void TokenLexer::Init(Token &Tok, SourceLocation ILEnd, MacroArgs *Actuals) { // If the client is reusing a TokenLexer, make sure to free any memory // associated with it. destroy(); @@ -32,7 +32,8 @@ void TokenLexer::Init(Token &Tok, MacroArgs *Actuals) { ActualArgs = Actuals; CurToken = 0; - InstantiateLoc = Tok.getLocation(); + InstantiateLocStart = Tok.getLocation(); + InstantiateLocEnd = ILEnd; AtStartOfLine = Tok.isAtStartOfLine(); HasLeadingSpace = Tok.hasLeadingSpace(); Tokens = &*Macro->tokens_begin(); @@ -68,7 +69,7 @@ void TokenLexer::Init(const Token *TokArray, unsigned NumToks, DisableMacroExpansion = disableMacroExpansion; NumTokens = NumToks; CurToken = 0; - InstantiateLoc = SourceLocation(); + InstantiateLocStart = InstantiateLocEnd = SourceLocation(); AtStartOfLine = false; HasLeadingSpace = false; @@ -313,11 +314,12 @@ void TokenLexer::Lex(Token &Tok) { // diagnostics for the expanded token should appear as if they came from // InstantiationLoc. Pull this information together into a new SourceLocation // that captures all of this. - if (InstantiateLoc.isValid()) { // Don't do this for token streams. - SourceManager &SrcMgr = PP.getSourceManager(); - Tok.setLocation(SrcMgr.createInstantiationLoc(Tok.getLocation(), - InstantiateLoc, - Tok.getLength())); + if (InstantiateLocStart.isValid()) { // Don't do this for token streams. + SourceManager &SM = PP.getSourceManager(); + Tok.setLocation(SM.createInstantiationLoc(Tok.getLocation(), + InstantiateLocStart, + InstantiateLocEnd, + Tok.getLength())); } // If this is the first token, set the lexical properties of the token to |