]> granicus.if.org Git - clang/commitdiff
avoid pasting L + "foo" into L"foo".
authorChris Lattner <sabre@nondot.org>
Tue, 15 Jan 2008 05:22:14 +0000 (05:22 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 15 Jan 2008 05:22:14 +0000 (05:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46000 91177308-0d34-0410-b5e6-96231b3b80d8

Driver/PrintPreprocessedOutput.cpp
test/Preprocessor/output_paste_avoid.c

index efa2c00652532a8f67875de3c8959f2ce9a8a76d..f6f7a8cf92d171243d73365c03ffc39e670049cd 100644 (file)
@@ -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 == '.';
index 842063a90846c142e0a4543877eadc6df9825e86..065c73e93908d97215abda24aba1ac77f768be80 100644 (file)
@@ -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)
+