summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2014-12-15 04:18:11 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2014-12-15 04:18:11 +0000
commit583b0762236e4241f140d07227e73ba9e3b65918 (patch)
tree492411a19cec6873d1726eb5d04d6c1408d4a8f3 /clang/lib/Lex
parentc175dd2ea564f6e9b81d2eabc2977a94f3176ccf (diff)
downloadbcm5719-llvm-583b0762236e4241f140d07227e73ba9e3b65918.tar.gz
bcm5719-llvm-583b0762236e4241f140d07227e73ba9e3b65918.zip
MSVC: A wide string literal from L#macro_arg in a macro
Clang should form a wide string literal from L#macro_arg in a function-like macro in -fms-compatibility mode. Fix for http://llvm.org/PR9984. Differential Revision: http://reviews.llvm.org/D6604 llvm-svn: 224228
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/TokenLexer.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp
index 45c8b010b38..5f4705eff69 100644
--- a/clang/lib/Lex/TokenLexer.cpp
+++ b/clang/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.
OpenPOWER on IntegriCloud