diff options
author | Chris Lattner <sabre@nondot.org> | 2008-01-15 05:22:14 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-01-15 05:22:14 +0000 |
commit | b1a17ae9d339e59b81509e593907f2f924231dab (patch) | |
tree | e9fa469d9d8b73ba0cf13e7600f4693ea30008e9 | |
parent | fdc0d3c9e1c90158e1cc03be37e037690c85b6f4 (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.cpp | 29 | ||||
-rw-r--r-- | test/Preprocessor/output_paste_avoid.c | 6 |
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) + |