зеркало из https://github.com/microsoft/clang-1.git
Add code modification hints to various parsing-related diagnostics.
Plus, reword a extension warnings to avoid talking about "ISO C" when the extension might also be available in C++ or C++0x. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68257 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
31a19b6989
Коммит
9b3064b55f
|
@ -17,15 +17,15 @@ def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">;
|
|||
|
||||
def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
|
||||
def ext_top_level_semi : Extension<
|
||||
"ISO C does not allow an extra ';' outside of a function">;
|
||||
"extra ';' outside of a function">;
|
||||
def ext_extra_struct_semi : Extension<
|
||||
"ISO C does not allow an extra ';' inside a struct or union">;
|
||||
"extra ';' inside a struct or union">;
|
||||
|
||||
def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
|
||||
def ext_plain_complex : Extension<
|
||||
"ISO C does not support plain '_Complex' meaning '_Complex double'">;
|
||||
def ext_plain_complex : ExtWarn<
|
||||
"plain '_Complex' requires a type specifier; assuming '_Complex double'">;
|
||||
def ext_integer_complex : Extension<
|
||||
"ISO C does not support complex integer types">;
|
||||
"complex integer types are an extension">;
|
||||
def ext_thread_before : Extension<"'__thread' before 'static'">;
|
||||
|
||||
def ext_empty_struct_union_enum : Extension<"use of empty %0 extension">;
|
||||
|
@ -43,8 +43,8 @@ def ext_c99_variable_decl_in_for_loop : Extension<
|
|||
"variable declaration in for loop is a C99-specific feature">;
|
||||
def ext_c99_compound_literal : Extension<
|
||||
"compound literals are a C99-specific feature">;
|
||||
def ext_c99_enumerator_list_comma : Extension<
|
||||
"commas at the end of enumerator lists are a C99-specific feature">;
|
||||
def ext_enumerator_list_comma : Extension<
|
||||
"commas at the end of enumerator lists are a %select{C99|C++0x}0-specific feature">;
|
||||
|
||||
def ext_gnu_indirect_goto : Extension<
|
||||
"use of GNU indirect-goto extension">;
|
||||
|
|
|
@ -324,7 +324,7 @@ public:
|
|||
/// Finish - This does final analysis of the declspec, issuing diagnostics for
|
||||
/// things like "_Imaginary" (lacking an FP type). After calling this method,
|
||||
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
|
||||
void Finish(Diagnostic &D, SourceManager& SrcMgr, const LangOptions &Lang);
|
||||
void Finish(Diagnostic &D, Preprocessor &PP);
|
||||
|
||||
/// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone,
|
||||
/// without a Declarator. Only tag declspecs can stand alone.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <cstring>
|
||||
|
@ -283,9 +284,9 @@ bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec
|
|||
/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
|
||||
/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
|
||||
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
|
||||
void DeclSpec::Finish(Diagnostic &D, SourceManager& SrcMgr,
|
||||
const LangOptions &Lang) {
|
||||
void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
|
||||
// Check the type specifier components first.
|
||||
SourceManager &SrcMgr = PP.getSourceManager();
|
||||
|
||||
// signed/unsigned are only valid with int/char/wchar_t.
|
||||
if (TypeSpecSign != TSS_unspecified) {
|
||||
|
@ -330,7 +331,10 @@ void DeclSpec::Finish(Diagnostic &D, SourceManager& SrcMgr,
|
|||
// disallow their use. Need information about the backend.
|
||||
if (TypeSpecComplex != TSC_unspecified) {
|
||||
if (TypeSpecType == TST_unspecified) {
|
||||
Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex);
|
||||
Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
|
||||
<< CodeModificationHint::CreateInsertion(
|
||||
PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
|
||||
" double");
|
||||
TypeSpecType = TST_double; // _Complex -> _Complex double.
|
||||
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
|
||||
// Note that this intentionally doesn't include _Complex _Bool.
|
||||
|
|
|
@ -496,7 +496,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
DoneWithDeclSpec:
|
||||
// If this is not a declaration specifier token, we're done reading decl
|
||||
// specifiers. First verify that DeclSpec's are consistent.
|
||||
DS.Finish(Diags, PP.getSourceManager(), getLang());
|
||||
DS.Finish(Diags, PP);
|
||||
return;
|
||||
|
||||
case tok::coloncolon: // ::foo::bar
|
||||
|
@ -1169,7 +1169,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
|||
|
||||
// Check for extraneous top-level semicolon.
|
||||
if (Tok.is(tok::semi)) {
|
||||
Diag(Tok, diag::ext_extra_struct_semi);
|
||||
Diag(Tok, diag::ext_extra_struct_semi)
|
||||
<< CodeModificationHint::CreateRemoval(SourceRange(Tok.getLocation()));
|
||||
ConsumeToken();
|
||||
continue;
|
||||
}
|
||||
|
@ -1372,8 +1373,11 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
|
|||
break;
|
||||
SourceLocation CommaLoc = ConsumeToken();
|
||||
|
||||
if (Tok.isNot(tok::identifier) && !getLang().C99)
|
||||
Diag(CommaLoc, diag::ext_c99_enumerator_list_comma);
|
||||
if (Tok.isNot(tok::identifier) &&
|
||||
!(getLang().C99 || getLang().CPlusPlus0x))
|
||||
Diag(CommaLoc, diag::ext_enumerator_list_comma)
|
||||
<< getLang().CPlusPlus
|
||||
<< CodeModificationHint::CreateRemoval((SourceRange(CommaLoc)));
|
||||
}
|
||||
|
||||
// Eat the }.
|
||||
|
@ -1625,7 +1629,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
|
|||
DoneWithTypeQuals:
|
||||
// If this is not a type-qualifier token, we're done reading type
|
||||
// qualifiers. First verify that DeclSpec's are consistent.
|
||||
DS.Finish(Diags, PP.getSourceManager(), getLang());
|
||||
DS.Finish(Diags, PP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -608,7 +608,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
|||
// GNU typeof support.
|
||||
case tok::kw_typeof:
|
||||
ParseTypeofSpecifier(DS);
|
||||
DS.Finish(Diags, PP.getSourceManager(), getLang());
|
||||
DS.Finish(Diags, PP);
|
||||
return;
|
||||
}
|
||||
if (Tok.is(tok::annot_typename))
|
||||
|
@ -616,7 +616,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
|||
else
|
||||
DS.SetRangeEnd(Tok.getLocation());
|
||||
ConsumeToken();
|
||||
DS.Finish(Diags, PP.getSourceManager(), getLang());
|
||||
DS.Finish(Diags, PP);
|
||||
}
|
||||
|
||||
/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
|
||||
|
|
|
@ -372,7 +372,8 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() {
|
|||
DeclPtrTy SingleDecl;
|
||||
switch (Tok.getKind()) {
|
||||
case tok::semi:
|
||||
Diag(Tok, diag::ext_top_level_semi);
|
||||
Diag(Tok, diag::ext_top_level_semi)
|
||||
<< CodeModificationHint::CreateRemoval(SourceRange(Tok.getLocation()));
|
||||
ConsumeToken();
|
||||
// TODO: Invoke action for top-level semicolon.
|
||||
return DeclGroupPtrTy();
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/* RUN: clang -fsyntax-only -std=c90 -pedantic %s
|
||||
*/
|
||||
/* This is a test of the various code modification hints that are
|
||||
provided as part of warning or extension diagnostics. Eventually,
|
||||
we would like to actually try to perform the suggested
|
||||
modifications and compile the result to test that no warnings
|
||||
remain. */
|
||||
|
||||
enum e0 {
|
||||
e1,
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: clang -fsyntax-only -pedantic %s
|
||||
|
||||
/* This is a test of the various code modification hints that are
|
||||
provided as part of warning or extension diagnostics. Eventually,
|
||||
we would like to actually try to perform the suggested
|
||||
modifications and compile the result to test that no warnings
|
||||
remain. */
|
||||
|
||||
void f0(void) { };
|
||||
|
||||
struct s {
|
||||
int x, y;;
|
||||
};
|
||||
|
||||
_Complex cd;
|
||||
|
||||
struct s s0 = { y: 5 };
|
||||
int array0[5] = { [3] 3 };
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: clang-cc -fsyntax-only -pedantic -verify %s
|
||||
|
||||
/* This is a test of the various code modification hints that are
|
||||
provided as part of warning or extension diagnostics. Eventually,
|
||||
we would like to actually try to perform the suggested
|
||||
modifications and compile the result to test that no warnings
|
||||
remain. */
|
||||
|
||||
struct C1 { };
|
||||
struct C2 : virtual public virtual C1 { }; // expected-error{{duplicate}}
|
||||
|
||||
template<int Value> struct CT { };
|
||||
|
||||
CT<10 >> 2> ct; // expected-warning{{require parentheses}}
|
Загрузка…
Ссылка в новой задаче