diff options
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/Lexer.cpp | 1 | ||||
-rw-r--r-- | lib/Lex/ModuleMap.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 14 | ||||
-rw-r--r-- | lib/Lex/PPExpressions.cpp | 4 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 29 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 23 | ||||
-rw-r--r-- | lib/Lex/TokenConcatenation.cpp | 39 |
7 files changed, 99 insertions, 17 deletions
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 2b24d1cc75..a7fba8019d 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1582,6 +1582,7 @@ const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr) { unsigned Size; char C = getCharAndSize(CurPtr, Size); if (isIdentifierHead(C)) { + Result.setFlag(Token::HasUDSuffix); do { CurPtr = ConsumeChar(CurPtr, Size, Result); C = getCharAndSize(CurPtr, Size); diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index 28043d1198..e6851afada 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -617,6 +617,12 @@ retry: break; case tok::string_literal: { + if (LToken.hasUDSuffix()) { + Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); + HadError = true; + goto retry; + } + // Parse the string literal. LangOptions LangOpts; StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 1e8f59023b..7345ef2197 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -822,8 +822,10 @@ void Preprocessor::HandleLineDirective(Token &Tok) { ; // ok else if (StrTok.isNot(tok::string_literal)) { Diag(StrTok, diag::err_pp_line_invalid_filename); - DiscardUntilEndOfDirective(); - return; + return DiscardUntilEndOfDirective(); + } else if (StrTok.hasUDSuffix()) { + Diag(StrTok, diag::err_invalid_string_udl); + return DiscardUntilEndOfDirective(); } else { // Parse and validate the string, converting it into a unique ID. StringLiteralParser Literal(&StrTok, 1, *this); @@ -957,6 +959,9 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { else if (StrTok.isNot(tok::string_literal)) { Diag(StrTok, diag::err_pp_linemarker_invalid_filename); return DiscardUntilEndOfDirective(); + } else if (StrTok.hasUDSuffix()) { + Diag(StrTok, diag::err_invalid_string_udl); + return DiscardUntilEndOfDirective(); } else { // Parse and validate the string, converting it into a unique ID. StringLiteralParser Literal(&StrTok, 1, *this); @@ -1047,6 +1052,11 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) { return; } + if (StrTok.hasUDSuffix()) { + Diag(StrTok, diag::err_invalid_string_udl); + return DiscardUntilEndOfDirective(); + } + // Verify that there is nothing after the string, other than EOD. CheckEndOfDirective("ident"); diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp index c4ab143aaa..8d8fe316e7 100644 --- a/lib/Lex/PPExpressions.cpp +++ b/lib/Lex/PPExpressions.cpp @@ -251,6 +251,10 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, case tok::wide_char_constant: { // L'x' case tok::utf16_char_constant: // u'x' case tok::utf32_char_constant: // U'x' + // Complain about, and drop, any ud-suffix. + if (PeekTok.hasUDSuffix()) + PP.Diag(PeekTok, diag::err_pp_invalid_char_udl); + SmallString<32> CharBuffer; bool CharInvalid = false; StringRef ThisTok = PP.getSpelling(PeekTok, CharBuffer, &CharInvalid); diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 99f2b23dff..777e0db026 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -825,6 +825,16 @@ static bool EvaluateHasIncludeCommon(Token &Tok, return false; } + // Get ')'. + PP.LexNonComment(Tok); + + // Ensure we have a trailing ). + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName(); + PP.Diag(LParenLoc, diag::note_matching) << "("; + return false; + } + bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename); // If GetIncludeFilenameSpelling set the start ptr to null, there was an // error. @@ -836,20 +846,8 @@ static bool EvaluateHasIncludeCommon(Token &Tok, const FileEntry *File = PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL, NULL); - // Get the result value. Result = true means the file exists. - bool Result = File != 0; - - // Get ')'. - PP.LexNonComment(Tok); - - // Ensure we have a trailing ). - if (Tok.isNot(tok::r_paren)) { - PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName(); - PP.Diag(LParenLoc, diag::note_matching) << "("; - return false; - } - - return Result; + // Get the result value. A result of true means the file exists. + return File != 0; } /// EvaluateHasInclude - Process a '__has_include("path")' expression. @@ -1091,6 +1089,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // from macro expansion. SmallVector<Token, 4> StrToks; while (Tok.is(tok::string_literal)) { + // Complain about, and drop, any ud-suffix. + if (Tok.hasUDSuffix()) + Diag(Tok, diag::err_invalid_string_udl); StrToks.push_back(Tok); LexUnexpandedToken(Tok); } diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 046a4d02f0..404feaab46 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -133,6 +133,20 @@ void Preprocessor::Handle_Pragma(Token &Tok) { Lex(Tok); if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal)) { Diag(PragmaLoc, diag::err__Pragma_malformed); + // Skip this token, and the ')', if present. + if (Tok.isNot(tok::r_paren)) + Lex(Tok); + if (Tok.is(tok::r_paren)) + Lex(Tok); + return; + } + + if (Tok.hasUDSuffix()) { + Diag(Tok, diag::err_invalid_string_udl); + // Skip this token, and the ')', if present. + Lex(Tok); + if (Tok.is(tok::r_paren)) + Lex(Tok); return; } @@ -442,6 +456,8 @@ void Preprocessor::HandlePragmaComment(Token &Tok) { // "foo " "bar" "Baz" SmallVector<Token, 4> StrToks; while (Tok.is(tok::string_literal)) { + if (Tok.hasUDSuffix()) + Diag(Tok, diag::err_invalid_string_udl); StrToks.push_back(Tok); Lex(Tok); } @@ -518,6 +534,8 @@ void Preprocessor::HandlePragmaMessage(Token &Tok) { // "foo " "bar" "Baz" SmallVector<Token, 4> StrToks; while (Tok.is(tok::string_literal)) { + if (Tok.hasUDSuffix()) + Diag(Tok, diag::err_invalid_string_udl); StrToks.push_back(Tok); Lex(Tok); } @@ -577,6 +595,11 @@ IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) { return 0; } + if (Tok.hasUDSuffix()) { + Diag(Tok, diag::err_invalid_string_udl); + return 0; + } + // Remember the macro string. std::string StrVal = getSpelling(Tok); diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp index 335d864f3f..ca7e55d863 100644 --- a/lib/Lex/TokenConcatenation.cpp +++ b/lib/Lex/TokenConcatenation.cpp @@ -85,6 +85,19 @@ TokenConcatenation::TokenConcatenation(Preprocessor &pp) : PP(pp) { TokenInfo[tok::hash ] |= aci_custom_firstchar; TokenInfo[tok::arrow ] |= aci_custom_firstchar; + // These tokens have custom code in C++11 mode. + if (PP.getLangOptions().CPlusPlus0x) { + TokenInfo[tok::string_literal ] |= aci_custom; + TokenInfo[tok::wide_string_literal ] |= aci_custom; + TokenInfo[tok::utf8_string_literal ] |= aci_custom; + TokenInfo[tok::utf16_string_literal] |= aci_custom; + TokenInfo[tok::utf32_string_literal] |= aci_custom; + TokenInfo[tok::char_constant ] |= aci_custom; + TokenInfo[tok::wide_char_constant ] |= aci_custom; + TokenInfo[tok::utf16_char_constant ] |= aci_custom; + TokenInfo[tok::utf32_char_constant ] |= aci_custom; + } + // These tokens change behavior if followed by an '='. TokenInfo[tok::amp ] |= aci_avoid_equal; // &= TokenInfo[tok::plus ] |= aci_avoid_equal; // += @@ -183,6 +196,28 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok, case tok::raw_identifier: llvm_unreachable("tok::raw_identifier in non-raw lexing mode!"); + case tok::string_literal: + case tok::wide_string_literal: + case tok::utf8_string_literal: + case tok::utf16_string_literal: + case tok::utf32_string_literal: + case tok::char_constant: + case tok::wide_char_constant: + case tok::utf16_char_constant: + case tok::utf32_char_constant: + if (!PP.getLangOptions().CPlusPlus0x) + return false; + + // In C++11, a string or character literal followed by an identifier is a + // single token. + if (Tok.getIdentifierInfo()) + return true; + + // A ud-suffix is an identifier. If the previous token ends with one, treat + // it as an identifier. + if (!PrevTok.hasUDSuffix()) + return false; + // FALL THROUGH. case tok::identifier: // id+id or id+number or id+L"foo". // id+'.'... will not append. if (Tok.is(tok::numeric_constant)) @@ -201,9 +236,11 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok, // Otherwise, this is a narrow character or string. If the *identifier* // is a literal 'L', 'u8', 'u' or 'U', avoid pasting L "foo" -> L"foo". return IsIdentifierStringPrefix(PrevTok); + case tok::numeric_constant: return isalnum(FirstChar) || Tok.is(tok::numeric_constant) || - FirstChar == '+' || FirstChar == '-' || FirstChar == '.'; + FirstChar == '+' || FirstChar == '-' || FirstChar == '.' || + (PP.getLangOptions().CPlusPlus0x && FirstChar == '_'); case tok::period: // ..., .*, .1234 return (FirstChar == '.' && PrevPrevTok.is(tok::period)) || isdigit(FirstChar) || |