aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-09-11 04:59:25 +0000
committerJohn McCall <rjmccall@apple.com>2009-09-11 04:59:25 +0000
commitc4e7019d5c9034a2d84ee4695f8e98dc025ac131 (patch)
treeda8b19b3e6e6f62ddc50db7209b8dd0421fd15a8 /lib/Parse/ParseDeclCXX.cpp
parent66847a2826c97b8e09aec304a0a7b4fe1dc35969 (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.cpp46
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;
}