diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-03-18 03:32:24 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-03-18 03:32:24 +0000 |
commit | 99c7622d1f673e8929196cc6eec7825a42622d5f (patch) | |
tree | 1e437c5964fe3f25063c8bece58c97287f49b264 /lib/Lex/TokenConcatenation.cpp | |
parent | 10ffa9a4887d9376e3eb3598e40523d1b58773c9 (diff) |
Fix -E mismatch; an identifier followed by a numeric constant does not
require a space (to avoid concatenation) if the numeric constant had a
leading period.
- PR3819.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67163 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/TokenConcatenation.cpp')
-rw-r--r-- | lib/Lex/TokenConcatenation.cpp | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp index 549fb8d088..92edca7be4 100644 --- a/lib/Lex/TokenConcatenation.cpp +++ b/lib/Lex/TokenConcatenation.cpp @@ -90,6 +90,29 @@ TokenConcatenation::TokenConcatenation(Preprocessor &pp) : PP(pp) { TokenInfo[tok::equal ] |= aci_avoid_equal; // == } +/// GetFirstChar - Get the first character of the token \arg Tok, +/// avoiding calls to getSpelling where possible. +static char GetFirstChar(Preprocessor &PP, const Token &Tok) { + if (IdentifierInfo *II = Tok.getIdentifierInfo()) { + // Avoid spelling identifiers, the most common form of token. + return II->getName()[0]; + } else if (!Tok.needsCleaning()) { + if (Tok.isLiteral() && Tok.getLiteralData()) { + return *Tok.getLiteralData(); + } else { + SourceManager &SM = PP.getSourceManager(); + return *SM.getCharacterData(SM.getSpellingLoc(Tok.getLocation())); + } + } else if (Tok.getLength() < 256) { + char Buffer[256]; + const char *TokPtr = Buffer; + PP.getSpelling(Tok, TokPtr); + return TokPtr[0]; + } else { + return PP.getSpelling(Tok)[0]; + } +} + /// 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 @@ -103,8 +126,6 @@ TokenConcatenation::TokenConcatenation(Preprocessor &pp) : PP(pp) { /// don't want to track enough to tell "x.." from "...". bool TokenConcatenation::AvoidConcat(const Token &PrevTok, const Token &Tok) const { - char Buffer[256]; - tok::TokenKind PrevKind = PrevTok.getKind(); if (PrevTok.getIdentifierInfo()) // Language keyword or named operator. PrevKind = tok::identifier; @@ -130,30 +151,18 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevTok, char FirstChar = 0; if (ConcatInfo & aci_custom) { // If the token does not need to know the first character, don't get it. - } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) { - // Avoid spelling identifiers, the most common form of token. - FirstChar = II->getName()[0]; - } else if (!Tok.needsCleaning()) { - if (Tok.isLiteral() && Tok.getLiteralData()) { - FirstChar = *Tok.getLiteralData(); - } else { - SourceManager &SrcMgr = PP.getSourceManager(); - FirstChar = - *SrcMgr.getCharacterData(SrcMgr.getSpellingLoc(Tok.getLocation())); - } - } else if (Tok.getLength() < 256) { - const char *TokPtr = Buffer; - PP.getSpelling(Tok, TokPtr); - FirstChar = TokPtr[0]; } else { - FirstChar = PP.getSpelling(Tok)[0]; + FirstChar = GetFirstChar(PP, Tok); } - + switch (PrevKind) { default: assert(0 && "InitAvoidConcatTokenInfo built wrong"); - case tok::identifier: // id+id or id+number or id+L"foo". - if (Tok.is(tok::numeric_constant) || Tok.getIdentifierInfo() || - Tok.is(tok::wide_string_literal) /* || + case tok::identifier: // id+id or id+number or id+L"foo". + // id+'.'... will not append. + if (Tok.is(tok::numeric_constant)) + return GetFirstChar(PP, Tok) != '.'; + + if (Tok.getIdentifierInfo() || Tok.is(tok::wide_string_literal) /* || Tok.is(tok::wide_char_literal)*/) return true; |