aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-01-15 05:22:14 +0000
committerChris Lattner <sabre@nondot.org>2008-01-15 05:22:14 +0000
commitb1a17ae9d339e59b81509e593907f2f924231dab (patch)
treee9fa469d9d8b73ba0cf13e7600f4693ea30008e9
parentfdc0d3c9e1c90158e1cc03be37e037690c85b6f4 (diff)
avoid pasting L + "foo" into L"foo".
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46000 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Driver/PrintPreprocessedOutput.cpp29
-rw-r--r--test/Preprocessor/output_paste_avoid.c6
2 files changed, 33 insertions, 2 deletions
diff --git a/Driver/PrintPreprocessedOutput.cpp b/Driver/PrintPreprocessedOutput.cpp
index efa2c00652..f6f7a8cf92 100644
--- a/Driver/PrintPreprocessedOutput.cpp
+++ b/Driver/PrintPreprocessedOutput.cpp
@@ -420,8 +420,8 @@ static void InitAvoidConcatTokenInfo() {
TokenInfo[tok::equal ] |= aci_avoid_equal; // ==
}
+/// StartsWithL - Return true if the spelling of this token starts with 'L'.
static bool StartsWithL(const Token &Tok, Preprocessor &PP) {
- char Buffer[256];
if (!Tok.needsCleaning()) {
SourceManager &SrcMgr = PP.getSourceManager();
return *SrcMgr.getCharacterData(SrcMgr.getPhysicalLoc(Tok.getLocation()))
@@ -429,6 +429,7 @@ static bool StartsWithL(const Token &Tok, Preprocessor &PP) {
}
if (Tok.getLength() < 256) {
+ char Buffer[256];
const char *TokPtr = Buffer;
PP.getSpelling(Tok, TokPtr);
return TokPtr[0] == 'L';
@@ -437,6 +438,28 @@ static bool StartsWithL(const Token &Tok, Preprocessor &PP) {
return PP.getSpelling(Tok)[0] == 'L';
}
+/// IsIdentifierL - Return true if the spelling of this token is literally 'L'.
+static bool IsIdentifierL(const Token &Tok, Preprocessor &PP) {
+ if (!Tok.needsCleaning()) {
+ if (Tok.getLength() != 1)
+ return false;
+ SourceManager &SrcMgr = PP.getSourceManager();
+ return *SrcMgr.getCharacterData(SrcMgr.getPhysicalLoc(Tok.getLocation()))
+ == 'L';
+ }
+
+ if (Tok.getLength() < 256) {
+ char Buffer[256];
+ const char *TokPtr = Buffer;
+ if (PP.getSpelling(Tok, TokPtr) != 1)
+ return false;
+ return TokPtr[0] == 'L';
+ }
+
+ return PP.getSpelling(Tok) == "L";
+}
+
+
/// AvoidConcat - If printing PrevTok immediately followed by Tok would cause
/// the two individual tokens to be lexed as a single token, return true (which
/// causes a space to be printed between them). This allows the output of -E
@@ -513,7 +536,9 @@ bool PrintPPOutputPPCallbacks::AvoidConcat(const Token &PrevTok,
if (StartsWithL(Tok, PP))
return true;
- return false;
+ // Otherwise, this is a narrow character or string. If the *identifier* is
+ // a literal 'L', avoid pasting L "foo" -> L"foo".
+ return IsIdentifierL(PrevTok, PP);
case tok::numeric_constant:
return isalnum(FirstChar) || Tok.is(tok::numeric_constant) ||
FirstChar == '+' || FirstChar == '-' || FirstChar == '.';
diff --git a/test/Preprocessor/output_paste_avoid.c b/test/Preprocessor/output_paste_avoid.c
index 842063a908..065c73e939 100644
--- a/test/Preprocessor/output_paste_avoid.c
+++ b/test/Preprocessor/output_paste_avoid.c
@@ -1,5 +1,6 @@
// RUN: clang -E %s | grep '+ + - - + + = = =' &&
// RUN: clang -E %s | not grep -F '...'
+// RUN: clang -E %s | not grep -F 'L"str"'
// This should print as ".. ." to avoid turning into ...
#define y(a) ..a
@@ -10,3 +11,8 @@ y(.)
#define f(x) =x=
+PLUS -EMPTY- PLUS+ f(=)
+
+// Should expand to L "str" not L"str"
+#define test(x) L#x
+test(str)
+