forked from OSchip/llvm-project
Patch to implement template types in ctor-initializer list.
Also has fix for bugzilla-4469. llvm-svn: 74631
This commit is contained in:
parent
39e64d452a
commit
c1fc3ec878
|
@ -1205,6 +1205,7 @@ public:
|
|||
Scope *S,
|
||||
const CXXScopeSpec &SS,
|
||||
IdentifierInfo *MemberOrBase,
|
||||
TypeTy *TemplateTypeTy,
|
||||
SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
ExprTy **Args, unsigned NumArgs,
|
||||
|
|
|
@ -1280,15 +1280,25 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
|
|||
// parse '::'[opt] nested-name-specifier[opt]
|
||||
CXXScopeSpec SS;
|
||||
ParseOptionalCXXScopeSpecifier(SS);
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
TypeTy *TemplateTypeTy = 0;
|
||||
if (Tok.is(tok::annot_template_id)) {
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
|
||||
if (TemplateId->Kind == TNK_Type_template) {
|
||||
AnnotateTemplateIdTokenAsType(&SS);
|
||||
assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
|
||||
TemplateTypeTy = Tok.getAnnotationValue();
|
||||
}
|
||||
// FIXME. May need to check for TNK_Dependent_template as well.
|
||||
}
|
||||
if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_member_or_base_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Get the identifier. This may be a member name or a class name,
|
||||
// but we'll let the semantic analysis determine which it is.
|
||||
IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
|
||||
SourceLocation IdLoc = ConsumeToken();
|
||||
|
||||
// Parse the '('.
|
||||
|
@ -1308,7 +1318,8 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
|
|||
|
||||
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||
|
||||
return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II, IdLoc,
|
||||
return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
|
||||
TemplateTypeTy, IdLoc,
|
||||
LParenLoc, ArgExprs.take(),
|
||||
ArgExprs.size(), CommaLocs.data(),
|
||||
RParenLoc);
|
||||
|
|
|
@ -1899,6 +1899,7 @@ public:
|
|||
Scope *S,
|
||||
const CXXScopeSpec &SS,
|
||||
IdentifierInfo *MemberOrBase,
|
||||
TypeTy *TemplateTypeTy,
|
||||
SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
ExprTy **Args, unsigned NumArgs,
|
||||
|
|
|
@ -648,6 +648,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
|||
Scope *S,
|
||||
const CXXScopeSpec &SS,
|
||||
IdentifierInfo *MemberOrBase,
|
||||
TypeTy *TemplateTypeTy,
|
||||
SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
ExprTy **Args, unsigned NumArgs,
|
||||
|
@ -678,7 +679,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
|||
// composed of a single identifier refers to the class member. A
|
||||
// mem-initializer-id for the hidden base class may be specified
|
||||
// using a qualified name. ]
|
||||
if (!SS.getScopeRep()) {
|
||||
if (!SS.getScopeRep() && !TemplateTypeTy) {
|
||||
// Look for a member, first.
|
||||
FieldDecl *Member = 0;
|
||||
DeclContext::lookup_result Result
|
||||
|
@ -695,13 +696,14 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
|||
}
|
||||
}
|
||||
// It didn't name a member, so see if it names a class.
|
||||
TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, &SS);
|
||||
TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy
|
||||
: getTypeName(*MemberOrBase, IdLoc, S, &SS);
|
||||
if (!BaseTy)
|
||||
return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
|
||||
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
|
||||
|
||||
QualType BaseType = QualType::getFromOpaquePtr(BaseTy);
|
||||
if (!BaseType->isRecordType())
|
||||
if (!BaseType->isRecordType() && !BaseType->isDependentType())
|
||||
return Diag(IdLoc, diag::err_base_init_does_not_name_class)
|
||||
<< BaseType << SourceRange(IdLoc, RParenLoc);
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
template<class X> struct A {};
|
||||
|
||||
template<class X> struct B : A<X> {
|
||||
B() : A<X>() {}
|
||||
};
|
||||
B<int> x;
|
||||
|
||||
template<class X> struct B1 : A<X> {
|
||||
typedef A<X> Base;
|
||||
B1() : Base() {}
|
||||
};
|
||||
B1<int> x1;
|
||||
|
||||
|
||||
template<typename T> struct Tmpl { };
|
||||
|
||||
template<typename T> struct TmplB { };
|
||||
|
||||
struct TmplC : Tmpl<int> {
|
||||
TmplC() :
|
||||
Tmpl<int>(),
|
||||
TmplB<int>() { } // expected-error {{type 'TmplB<int>' is not a direct or virtual base of 'TmplC'}}
|
||||
};
|
||||
|
||||
|
||||
struct TmplD : Tmpl<char>, TmplB<char> {
|
||||
TmplD():
|
||||
Tmpl<int>(), // expected-error {{type 'Tmpl<int>' is not a direct or virtual base of 'TmplD'}}
|
||||
TmplB<char>() {}
|
||||
};
|
||||
|
Loading…
Reference in New Issue