diff options
author | John McCall <rjmccall@apple.com> | 2009-09-11 04:59:25 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-09-11 04:59:25 +0000 |
commit | c4e7019d5c9034a2d84ee4695f8e98dc025ac131 (patch) | |
tree | da8b19b3e6e6f62ddc50db7209b8dd0421fd15a8 /lib/Parse/ParseDeclCXX.cpp | |
parent | 66847a2826c97b8e09aec304a0a7b4fe1dc35969 (diff) |
Support elaborated dependent types and diagnose tag mismatches.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81504 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index fc3e6ae17f..8fa8525750 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -619,7 +619,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } // Create the tag portion of the class or class template. - Action::DeclResult TagOrTempResult; + Action::DeclResult TagOrTempResult = true; // invalid + Action::TypeResult TypeResult = true; // invalid TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; // FIXME: When TUK == TUK_Reference and we have a template-id, we need @@ -651,7 +652,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateId->RAngleLoc, Attr); } else if (TUK == Action::TUK_Reference || TUK == Action::TUK_Friend) { - Action::TypeResult Type + TypeResult = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template), TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, @@ -659,23 +660,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateId->getTemplateArgLocations(), TemplateId->RAngleLoc); - Type = Actions.ActOnTagTemplateIdType(Type, TUK, TagType, StartLoc); - - TemplateId->Destroy(); - - if (Type.isInvalid()) { - DS.SetTypeSpecError(); - return; - } - - const char *PrevSpec = 0; - unsigned DiagID; - if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, PrevSpec, - DiagID, Type.get())) - Diag(StartLoc, DiagID) << PrevSpec; - - return; - + TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK, + TagType, StartLoc); } else { // This is an explicit specialization or a class template // partial specialization. @@ -746,13 +732,21 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // FIXME: Diagnose this particular error. } + bool IsDependent = false; + // Declaration or definition of a class type TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TUK, StartLoc, SS, Name, NameLoc, Attr, AS, Action::MultiTemplateParamsArg(Actions, TemplateParams? &(*TemplateParams)[0] : 0, TemplateParams? TemplateParams->size() : 0), - Owned); + Owned, IsDependent); + + // If ActOnTag said the type was dependent, try again with the + // less common call. + if (IsDependent) + TypeResult = Actions.ActOnDependentTag(CurScope, TagType, TUK, + SS, Name, StartLoc, NameLoc); } // Parse the optional base clause (C++ only). @@ -771,15 +765,23 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, Diag(Tok, diag::err_expected_lbrace); } - if (TagOrTempResult.isInvalid()) { + void *Result; + if (!TypeResult.isInvalid()) { + TagType = DeclSpec::TST_typename; + Result = TypeResult.get(); + Owned = false; + } else if (!TagOrTempResult.isInvalid()) { + Result = TagOrTempResult.get().getAs<void>(); + } else { DS.SetTypeSpecError(); return; } const char *PrevSpec = 0; unsigned DiagID; + if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, DiagID, - TagOrTempResult.get().getAs<void>(), Owned)) + Result, Owned)) Diag(StartLoc, DiagID) << PrevSpec; } |