aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Lex/TokenLexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/TokenLexer.cpp')
-rw-r--r--lib/Lex/TokenLexer.cpp29
1 files changed, 23 insertions, 6 deletions
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 9d03e8d30b8b..5f4705eff697 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -206,6 +206,7 @@ void TokenLexer::ExpandFunctionArguments() {
ExpansionLocStart,
ExpansionLocEnd);
}
+ Res.setFlag(Token::StringifiedInMacro);
// The stringified/charified string leading space flag gets set to match
// the #/#@ operator.
@@ -405,6 +406,14 @@ void TokenLexer::ExpandFunctionArguments() {
}
}
+/// \brief Checks if two tokens form wide string literal.
+static bool isWideStringLiteralFromMacro(const Token &FirstTok,
+ const Token &SecondTok) {
+ return FirstTok.is(tok::identifier) &&
+ FirstTok.getIdentifierInfo()->isStr("L") && SecondTok.isLiteral() &&
+ SecondTok.stringifiedInMacro();
+}
+
/// Lex - Lex and return a token from this macro stream.
///
bool TokenLexer::Lex(Token &Tok) {
@@ -435,7 +444,13 @@ bool TokenLexer::Lex(Token &Tok) {
// If this token is followed by a token paste (##) operator, paste the tokens!
// Note that ## is a normal token when not expanding a macro.
- if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash) && Macro) {
+ if (!isAtEnd() && Macro &&
+ (Tokens[CurToken].is(tok::hashhash) ||
+ // Special processing of L#x macros in -fms-compatibility mode.
+ // Microsoft compiler is able to form a wide string literal from
+ // 'L#macro_arg' construct in a function-like macro.
+ (PP.getLangOpts().MSVCCompat &&
+ isWideStringLiteralFromMacro(Tok, Tokens[CurToken])))) {
// When handling the microsoft /##/ extension, the final token is
// returned by PasteTokens, not the pasted token.
if (PasteTokens(Tok))
@@ -511,9 +526,10 @@ bool TokenLexer::PasteTokens(Token &Tok) {
SourceLocation StartLoc = Tok.getLocation();
SourceLocation PasteOpLoc;
do {
- // Consume the ## operator.
+ // Consume the ## operator if any.
PasteOpLoc = Tokens[CurToken].getLocation();
- ++CurToken;
+ if (Tokens[CurToken].is(tok::hashhash))
+ ++CurToken;
assert(!isAtEnd() && "No token on the RHS of a paste operator!");
// Get the RHS token.
@@ -531,12 +547,13 @@ bool TokenLexer::PasteTokens(Token &Tok) {
memcpy(&Buffer[0], BufPtr, LHSLen);
if (Invalid)
return true;
-
- BufPtr = &Buffer[LHSLen];
+
+ BufPtr = Buffer.data() + LHSLen;
unsigned RHSLen = PP.getSpelling(RHS, BufPtr, &Invalid);
if (Invalid)
return true;
- if (BufPtr != &Buffer[LHSLen]) // Really, we want the chars in Buffer!
+ if (RHSLen && BufPtr != &Buffer[LHSLen])
+ // Really, we want the chars in Buffer!
memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
// Trim excess space.