diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-01 19:21:19 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-01 19:21:19 +0000 |
commit | 961743326fd18776f897bf4461345dba680ef637 (patch) | |
tree | c11f0b61cc7521cb153420d1afca44a4cf64f760 | |
parent | 31c11ebdaab0acfa10e231730ae95e32c0e39e1f (diff) |
Patch to implement template types in ctor-initializer list.
Also has fix for bugzilla-4469.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74631 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Action.h | 1 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 8 | ||||
-rw-r--r-- | test/SemaTemplate/class-template-ctor-initializer.cpp | 33 |
5 files changed, 56 insertions, 8 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index a8e52b2a86..24262a1126 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1205,6 +1205,7 @@ public: Scope *S, const CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, + TypeTy *TemplateTypeTy, SourceLocation IdLoc, SourceLocation LParenLoc, ExprTy **Args, unsigned NumArgs, diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 44cd5e6bc0..373d22fd9f 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 7576be8af1..338221e4d4 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1899,6 +1899,7 @@ public: Scope *S, const CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, + TypeTy *TemplateTypeTy, SourceLocation IdLoc, SourceLocation LParenLoc, ExprTy **Args, unsigned NumArgs, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index a0bc94808b..bbb173a02a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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); diff --git a/test/SemaTemplate/class-template-ctor-initializer.cpp b/test/SemaTemplate/class-template-ctor-initializer.cpp new file mode 100644 index 0000000000..d7649f5268 --- /dev/null +++ b/test/SemaTemplate/class-template-ctor-initializer.cpp @@ -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>() {} +}; + |