/// 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);
+
+ /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone,
+ /// without a Declarator. Only tag declspecs can stand alone.
+ bool isMissingDeclaratorOk();
};
/// ObjCDeclSpec - This class captures information about
// 'data definition has no type or storage class'?
}
+bool DeclSpec::isMissingDeclaratorOk() {
+ TST tst = getTypeSpecType();
+ return (tst == TST_union
+ || tst == TST_struct
+ || tst == TST_class
+ || tst == TST_enum
+ ) && getTypeRep() != 0;
+}
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
- virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
+ virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, const CXXScopeSpec &SS,
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
- // TODO: emit error on 'int;' or 'const enum foo;'.
- // TODO: emit error on 'typedef int;'
- // if (!DS.isMissingDeclaratorOk()) Diag(...);
-
+ // FIXME: Isn't that more of a parser diagnostic than a sema diagnostic?
+ if (!DS.isMissingDeclaratorOk()) {
+ // FIXME: This diagnostic is emitted even when various previous
+ // errors occurred (see e.g. test/Sema/decl-invalid.c). However,
+ // DeclSpec has no means of communicating this information, and the
+ // responsible parser functions are quite far apart.
+ Diag(DS.getSourceRange().getBegin(), diag::err_no_declarators)
+ << DS.getSourceRange();
+ return 0;
+ }
+
return dyn_cast_or_null<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
}
template x; // expected-error {{expected '<' after 'template'}}
export template x; // expected-error {{expected '<' after 'template'}} \
// expected-note {{exported templates are unsupported}}
-template < ; // expected-error {{parse error}}
-template <template X> ; // expected-error {{expected '<' after 'template'}}
-template <template <typename> > ; // expected-error {{expected 'class' before '>'}}
-template <template <typename> Foo> ; // expected-error {{expected 'class' before 'Foo'}}
+// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic. This is
+// because ParseNonTypeTemplateParameter starts parsing a DeclSpec.
+template < ; // expected-error {{parse error}} expected-error {{declaration does not declare anything}}
+template <template X> struct Err1; // expected-error {{expected '<' after 'template'}}
+template <template <typename> > struct Err2; // expected-error {{expected 'class' before '>'}}
+template <template <typename> Foo> struct Err3; // expected-error {{expected 'class' before 'Foo'}}
// Template function declarations
template <typename T> void foo();
// RUN: clang %s -fsyntax-only -verify
-typedef union <anonymous> __mbstate_t; // expected-error {{declaration of anonymous union must be a definition}}
+// See Sema::ParsedFreeStandingDeclSpec about the double diagnostic
+typedef union <anonymous> __mbstate_t; // expected-error {{declaration of anonymous union must be a definition}} expected-error {{declaration does not declare anything}}
// PR2017
int r[x()]; // expected-error {{size of array has non-integer type 'void'}}
}
+int; // expected-error {{declaration does not declare anything}}
+typedef int; // expected-error {{declaration does not declare anything}}
+const int; // expected-error {{declaration does not declare anything}}
+struct; // expected-error {{declaration of anonymous struct must be a definition}} // expected-error {{declaration does not declare anything}}
+typedef int I;
+I; // expected-error {{declaration does not declare anything}}
void ogfn()
{
mutable int ml; // expected-error {{error: 'mutable' can only be applied to member variables}}
+
+ // PR3020: This used to crash due to double ownership of C4.
+ struct C4;
+ C4; // expected-error {{declaration does not declare anything}}
}