From a8df57a962ff5ccd340aff234215738a64c4c735 Mon Sep 17 00:00:00 2001 From: Andy Gibbs Date: Sat, 17 Nov 2012 19:16:52 +0000 Subject: [PATCH] Made the "expected string literal" diagnostic more expressive llvm-svn: 168267 --- clang/include/clang/Basic/DiagnosticCommonKinds.td | 4 +++- clang/include/clang/Lex/Preprocessor.h | 6 ++++-- clang/lib/Lex/PPMacroExpansion.cpp | 3 ++- clang/lib/Lex/Pragma.cpp | 7 +++++-- clang/lib/Lex/Preprocessor.cpp | 7 +++++-- clang/lib/Parse/ParseDecl.cpp | 3 ++- clang/lib/Parse/ParseDeclCXX.cpp | 3 ++- clang/lib/Parse/Parser.cpp | 3 ++- clang/test/Lexer/pragma-message.c | 2 ++ clang/test/Parser/attr-availability.c | 2 +- clang/test/Preprocessor/pragma_diagnostic.c | 2 +- clang/test/Preprocessor/pragma_microsoft.c | 2 +- clang/test/Preprocessor/warning_tests.c | 2 +- clang/test/Sema/static-assert.c | 2 ++ 14 files changed, 33 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index c2df5da..534531b 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -41,7 +41,9 @@ def err_expected_colon : Error<"expected ':'">; def err_expected_colon_after_setter_name : Error< "method name referenced in property setter attribute " "must end with ':'">; -def err_expected_string_literal : Error<"expected string literal">; +def err_expected_string_literal : Error<"expected string literal " + "%select{in %1|for diagnostic message in static_assert|" + "for optional message in 'availability' attribute}0">; def err_invalid_string_udl : Error< "string literal with user-defined suffix cannot be used here">; def err_invalid_character_udl : Error< diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 486dcd8..7e5c66c 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -700,17 +700,19 @@ public: /// string literals and may even come from macro expansion. /// \returns true on success, false if a error diagnostic has been generated. bool LexStringLiteral(Token &Result, std::string &String, - bool AllowMacroExpansion) { + const char *DiagnosticTag, bool AllowMacroExpansion) { if (AllowMacroExpansion) Lex(Result); else LexUnexpandedToken(Result); - return FinishLexStringLiteral(Result, String, AllowMacroExpansion); + return FinishLexStringLiteral(Result, String, DiagnosticTag, + AllowMacroExpansion); } /// \brief Complete the lexing of a string literal where the first token has /// already been lexed (see LexStringLiteral). bool FinishLexStringLiteral(Token &Result, std::string &String, + const char *DiagnosticTag, bool AllowMacroExpansion); /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 9f962b0..6baa593 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1290,7 +1290,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { LexUnexpandedToken(Tok); std::string WarningName; SourceLocation StrStartLoc = Tok.getLocation(); - if (!FinishLexStringLiteral(Tok, WarningName, /*MacroExpansion=*/false)) { + if (!FinishLexStringLiteral(Tok, WarningName, "'__has_warning'", + /*MacroExpansion=*/false)) { // Eat tokens until ')'. while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eod) diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 0c1c9db..783588e 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -503,6 +503,7 @@ void Preprocessor::HandlePragmaComment(Token &Tok) { Lex(Tok); std::string ArgumentString; if (Tok.is(tok::comma) && !LexStringLiteral(Tok, ArgumentString, + "pragma comment", /*MacroExpansion=*/true)) return; @@ -559,7 +560,8 @@ void Preprocessor::HandlePragmaMessage(Token &Tok) { } std::string MessageString; - if (!FinishLexStringLiteral(Tok, MessageString, /*MacroExpansion=*/true)) + if (!FinishLexStringLiteral(Tok, MessageString, "pragma message", + /*MacroExpansion=*/true)) return; if (ExpectClosingParen) { @@ -1039,7 +1041,8 @@ public: SourceLocation StringLoc = Tok.getLocation(); std::string WarningName; - if (!PP.FinishLexStringLiteral(Tok, WarningName, /*MacroExpansion=*/false)) + if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic", + /*MacroExpansion=*/false)) return; if (Tok.isNot(tok::eod)) { diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 52d6bb6a..9488584 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -691,10 +691,12 @@ void Preprocessor::LexAfterModuleImport(Token &Result) { } bool Preprocessor::FinishLexStringLiteral(Token &Result, std::string &String, + const char *DiagnosticTag, bool AllowMacroExpansion) { // We need at least one string literal. if (Result.isNot(tok::string_literal)) { - Diag(Result, diag::err_expected_string_literal); + Diag(Result, diag::err_expected_string_literal) + << /*Source='in...'*/0 << DiagnosticTag; return false; } @@ -720,7 +722,8 @@ bool Preprocessor::FinishLexStringLiteral(Token &Result, std::string &String, return false; if (Literal.Pascal) { - Diag(StrToks[0].getLocation(), diag::err_expected_string_literal); + Diag(StrToks[0].getLocation(), diag::err_expected_string_literal) + << /*Source='in...'*/0 << DiagnosticTag; return false; } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index d898447..7c5b153 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -735,7 +735,8 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, ConsumeToken(); if (Keyword == Ident_message) { if (!isTokenStringLiteral()) { - Diag(Tok, diag::err_expected_string_literal); + Diag(Tok, diag::err_expected_string_literal) + << /*Source='availability attribute'*/2; SkipUntil(tok::r_paren); return; } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 0d785af..b8ebd9b6 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -637,7 +637,8 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ return 0; if (!isTokenStringLiteral()) { - Diag(Tok, diag::err_expected_string_literal); + Diag(Tok, diag::err_expected_string_literal) + << /*Source='static_assert'*/1; SkipMalformedDecl(); return 0; } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index f4cdd61..dfffe81 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1263,7 +1263,8 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() { return ExprError(); } default: - Diag(Tok, diag::err_expected_string_literal); + Diag(Tok, diag::err_expected_string_literal) + << /*Source='in...'*/0 << "'asm'"; return ExprError(); } diff --git a/clang/test/Lexer/pragma-message.c b/clang/test/Lexer/pragma-message.c index 807edda..b67886f 100644 --- a/clang/test/Lexer/pragma-message.c +++ b/clang/test/Lexer/pragma-message.c @@ -12,3 +12,5 @@ #define STRING(x) STRING2(x) #pragma message(":O I'm a message! " STRING(__LINE__)) // expected-warning {{:O I'm a message! 13}} #pragma message ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 14}} + +#pragma message(invalid) // expected-error {{expected string literal in pragma message}} diff --git a/clang/test/Parser/attr-availability.c b/clang/test/Parser/attr-availability.c index b9ff31c..0ed8391 100644 --- a/clang/test/Parser/attr-availability.c +++ b/clang/test/Parser/attr-availability.c @@ -20,7 +20,7 @@ void f6() __attribute__((availability(macosx,unavailable,introduced=10.5))); // // rdar://10095131 enum E{ - gorf __attribute__((availability(macosx,introduced=8.5, message = 10.0))), // expected-error {{expected string literal}} + gorf __attribute__((availability(macosx,introduced=8.5, message = 10.0))), // expected-error {{expected string literal for optional message in 'availability' attribute}} garf __attribute__((availability(macosx,introduced=8.5, message))), // expected-error {{expected '=' after 'message'}} foo __attribute__((availability(macosx,introduced=8.5,deprecated=9.0, message="Use CTFontCopyPostScriptName()", deprecated=10.0))) // expected-error {{expected ')'}} \ diff --git a/clang/test/Preprocessor/pragma_diagnostic.c b/clang/test/Preprocessor/pragma_diagnostic.c index 5c91079..e8a67ab 100644 --- a/clang/test/Preprocessor/pragma_diagnostic.c +++ b/clang/test/Preprocessor/pragma_diagnostic.c @@ -23,7 +23,7 @@ #define foo error #pragma GCC diagnostic foo "-Wundef" // expected-warning {{pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'}} -#pragma GCC diagnostic error 42 // expected-error {{expected string literal}} +#pragma GCC diagnostic error 42 // expected-error {{expected string literal in pragma diagnostic}} #pragma GCC diagnostic error "-Wundef" 42 // expected-warning {{unexpected token in pragma diagnostic}} #pragma GCC diagnostic error "invalid-name" // expected-warning {{pragma diagnostic expected option name (e.g. "-Wundef")}} diff --git a/clang/test/Preprocessor/pragma_microsoft.c b/clang/test/Preprocessor/pragma_microsoft.c index 782f986..156d052 100644 --- a/clang/test/Preprocessor/pragma_microsoft.c +++ b/clang/test/Preprocessor/pragma_microsoft.c @@ -11,7 +11,7 @@ #pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ ) #pragma comment(foo) // expected-error {{unknown kind of pragma comment}} -#pragma comment(compiler,) // expected-error {{expected string literal}} +#pragma comment(compiler,) // expected-error {{expected string literal in pragma comment}} #define foo compiler #pragma comment(foo) // macro expand kind. #pragma comment(foo) x // expected-error {{pragma comment requires}} diff --git a/clang/test/Preprocessor/warning_tests.c b/clang/test/Preprocessor/warning_tests.c index 77b8456..c0c22ef 100644 --- a/clang/test/Preprocessor/warning_tests.c +++ b/clang/test/Preprocessor/warning_tests.c @@ -11,7 +11,7 @@ #warning Should have -Wparentheses #endif -// expected-error@+2 {{expected string literal}} +// expected-error@+2 {{expected string literal in '__has_warning'}} // expected-error@+1 {{expected value in expression}} #if __has_warning(-Wfoo) #endif diff --git a/clang/test/Sema/static-assert.c b/clang/test/Sema/static-assert.c index 13d7070..9309987 100644 --- a/clang/test/Sema/static-assert.c +++ b/clang/test/Sema/static-assert.c @@ -9,3 +9,5 @@ void foo(void) { _Static_assert(1, "1 is nonzero"); _Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}} } + +_Static_assert(1, invalid); // expected-error {{expected string literal for diagnostic message in static_assert}} -- 2.7.4