When recovering from an invalid forward reference to an enum type in C++,

create the enum type in the same scope as you would a record type.

llvm-svn: 90500
This commit is contained in:
John McCall 2009-12-04 00:07:04 +00:00
parent 0ecd4c7d70
commit 9f545181f7
2 changed files with 8 additions and 4 deletions
clang
lib/Sema
test/SemaCXX

View File

@ -4617,8 +4617,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Previous.clear(); Previous.clear();
} }
} }
} else if (TUK == TUK_Reference && SS.isEmpty() && Name && } else if (TUK == TUK_Reference && SS.isEmpty() && Name) {
(Kind != TagDecl::TK_enum || !getLangOptions().CPlusPlus)) {
// C++ [basic.scope.pdecl]p5: // C++ [basic.scope.pdecl]p5:
// -- for an elaborated-type-specifier of the form // -- for an elaborated-type-specifier of the form
// //
@ -4636,6 +4635,11 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// C99 6.7.2.3p8 has a similar (but not identical!) provision for // C99 6.7.2.3p8 has a similar (but not identical!) provision for
// C structs and unions. // C structs and unions.
// //
// It is an error in C++ to declare (rather than define) an enum
// type, including via an elaborated type specifier. We'll
// diagnose that later; for now, declare the enum in the same
// scope as we would have picked for any other tag type.
//
// GNU C also supports this behavior as part of its incomplete // GNU C also supports this behavior as part of its incomplete
// enum types extension, while GNU C++ does not. // enum types extension, while GNU C++ does not.
// //

View File

@ -25,13 +25,13 @@ void bar() {
/// PR3688 /// PR3688
struct s1 { struct s1 {
enum e1 (*bar)(void); // expected-error{{ISO C++ forbids forward references to 'enum' types}} expected-note{{forward declaration of 'enum s1::e1'}} enum e1 (*bar)(void); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
}; };
enum e1 { YES, NO }; enum e1 { YES, NO };
static enum e1 badfunc(struct s1 *q) { static enum e1 badfunc(struct s1 *q) {
return q->bar(); // expected-error{{calling function with incomplete return type 'enum s1::e1'}} return q->bar();
} }
enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}}