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
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index fc3e6ae..8fa8525 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -619,7 +619,8 @@
}
// 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 @@
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 @@
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 @@
// 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 @@
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;
}