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">;
"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">;
/// 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.
#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>
/// "_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) {
// 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.
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
// 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;
}
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 }.
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;
}
// 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))
else
DS.SetRangeEnd(Tok.getLocation());
ConsumeToken();
- DS.Finish(Diags, PP.getSourceManager(), getLang());
+ DS.Finish(Diags, PP);
}
/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
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();
--- /dev/null
+/* 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,
+};
--- /dev/null
+// 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 };
--- /dev/null
+// 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}}