/// CreateString - Plop the specified string into a scratch buffer and set the
/// specified token's location and length to it. If specified, the source
/// location provides a location of the expansion point of the token.
- void CreateString(const char *Buf, unsigned Len,
- Token &Tok, SourceLocation SourceLoc = SourceLocation());
+ void CreateString(const char *Buf, unsigned Len, Token &Tok,
+ SourceLocation ExpansionLocStart = SourceLocation(),
+ SourceLocation ExpansionLocEnd = SourceLocation());
/// \brief Computes the source location just past the end of the
/// token at this source location.
Result.setKind(tok::comment);
PP->CreateString(&Spelling[0], Spelling.size(), Result,
- Result.getLocation());
+ Result.getLocation(), Result.getLocation());
return true;
}
///
Token MacroArgs::StringifyArgument(const Token *ArgToks,
Preprocessor &PP, bool Charify,
- SourceLocation hashInstLoc) {
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd) {
Token Tok;
Tok.startToken();
Tok.setKind(Charify ? tok::char_constant : tok::string_literal);
}
}
- PP.CreateString(&Result[0], Result.size(), Tok, hashInstLoc);
+ PP.CreateString(&Result[0], Result.size(), Tok,
+ ExpansionLocStart, ExpansionLocEnd);
return Tok;
}
/// that has been 'stringified' as required by the # operator.
const Token &MacroArgs::getStringifiedArgument(unsigned ArgNo,
Preprocessor &PP,
- SourceLocation hashInstLoc) {
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd) {
assert(ArgNo < NumUnexpArgTokens && "Invalid argument number!");
if (StringifiedArgs.empty()) {
StringifiedArgs.resize(getNumArguments());
}
if (StringifiedArgs[ArgNo].isNot(tok::string_literal))
StringifiedArgs[ArgNo] = StringifyArgument(getUnexpArgument(ArgNo), PP,
- /*Charify=*/false, hashInstLoc);
+ /*Charify=*/false,
+ ExpansionLocStart,
+ ExpansionLocEnd);
return StringifiedArgs[ArgNo];
}
/// getStringifiedArgument - Compute, cache, and return the specified argument
/// that has been 'stringified' as required by the # operator.
const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP,
- SourceLocation hashInstLoc);
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd);
/// getNumArguments - Return the number of arguments passed into this macro
/// invocation.
///
static Token StringifyArgument(const Token *ArgToks,
Preprocessor &PP, bool Charify,
- SourceLocation hashInstLoc);
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd);
/// deallocate - This should only be called by the Preprocessor when managing
} else {
llvm_unreachable("Unknown identifier!");
}
- CreateString(OS.str().data(), OS.str().size(), Tok, Tok.getLocation());
+ CreateString(OS.str().data(), OS.str().size(), Tok,
+ Tok.getLocation(), Tok.getLocation());
}
void Preprocessor::markMacroAsUsed(MacroInfo *MI) {
/// location for it. If specified, the source location provides a source
/// location for the token.
void Preprocessor::CreateString(const char *Buf, unsigned Len, Token &Tok,
- SourceLocation ExpansionLoc) {
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd) {
Tok.setLength(Len);
const char *DestPtr;
SourceLocation Loc = ScratchBuf->getToken(Buf, Len, DestPtr);
- if (ExpansionLoc.isValid())
- Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLoc, ExpansionLoc, Len);
+ if (ExpansionLocStart.isValid())
+ Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLocStart,
+ ExpansionLocEnd, Len);
Tok.setLocation(Loc);
// If this is a raw identifier or a literal token, set the pointer data.
int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
assert(ArgNo != -1 && "Token following # is not an argument?");
- SourceLocation hashInstLoc =
+ SourceLocation ExpansionLocStart =
getExpansionLocForMacroDefLoc(CurTok.getLocation());
+ SourceLocation ExpansionLocEnd =
+ getExpansionLocForMacroDefLoc(Tokens[i+1].getLocation());
Token Res;
if (CurTok.is(tok::hash)) // Stringify
- Res = ActualArgs->getStringifiedArgument(ArgNo, PP, hashInstLoc);
+ Res = ActualArgs->getStringifiedArgument(ArgNo, PP,
+ ExpansionLocStart,
+ ExpansionLocEnd);
else {
// 'charify': don't bother caching these.
Res = MacroArgs::StringifyArgument(ActualArgs->getUnexpArgument(ArgNo),
- PP, true, hashInstLoc);
+ PP, true,
+ ExpansionLocStart,
+ ExpansionLocEnd);
}
// The stringified/charified string leading space flag gets set to match
bool TokenLexer::PasteTokens(Token &Tok) {
llvm::SmallString<128> Buffer;
const char *ResultTokStrPtr = 0;
+ SourceLocation StartLoc = Tok.getLocation();
SourceLocation PasteOpLoc;
do {
// Consume the ## operator.
Tok = Result;
} while (!isAtEnd() && Tokens[CurToken].is(tok::hashhash));
+ SourceLocation EndLoc = Tokens[CurToken - 1].getLocation();
+
// The token's current location indicate where the token was lexed from. We
// need this information to compute the spelling of the token, but any
// diagnostics for the expanded token should appear as if the token was
- // expanded from the (##) operator. Pull this information together into
+ // expanded from the full ## expression. Pull this information together into
// a new SourceLocation that captures all of this.
SourceManager &SM = PP.getSourceManager();
- SourceLocation pasteLocInst = getExpansionLocForMacroDefLoc(PasteOpLoc);
- Tok.setLocation(SM.createExpansionLoc(Tok.getLocation(),
- pasteLocInst,
- pasteLocInst,
+ if (StartLoc.isFileID())
+ StartLoc = getExpansionLocForMacroDefLoc(StartLoc);
+ if (EndLoc.isFileID())
+ EndLoc = getExpansionLocForMacroDefLoc(EndLoc);
+ Tok.setLocation(SM.createExpansionLoc(Tok.getLocation(), StartLoc, EndLoc,
Tok.getLength()));
// Now that we got the result token, it will be subject to expansion. Since
// CHECK: {{.*}}:102:41: note: expanded from:
variadic_pasting_args3a(1, 2, 3, 4);
- // FIXME: It'd be really nice to retain the start location of the first token
- // involved in the token paste instead of falling back on the full macro
- // location in the first two locations here.
- // CHECK: {{.*}}:115:3: warning: expression result unused
- // CHECK: {{.*}}:106:44: note: expanded from:
- // CHECK: {{.*}}:104:72: note: expanded from:
+ // CHECK: {{.*}}:115:30: warning: expression result unused
+ // CHECK: {{.*}}:106:71: note: expanded from:
+ // CHECK: {{.*}}:104:70: note: expanded from:
// CHECK: {{.*}}:102:41: note: expanded from:
}