diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 25 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 122 |
2 files changed, 49 insertions, 98 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index af9af0ab83a..3468a3d93f6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1221,6 +1221,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs)) Invalid = true; + TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs); llvm::SmallVector<Decl*, 4> Fields; for (RecordDecl::decl_iterator Member = Pattern->decls_begin(), MemberEnd = Pattern->decls_end(); @@ -1237,7 +1238,12 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, if ((*Member)->getDeclContext() != Pattern) continue; - Decl *NewMember = SubstDecl(*Member, Instantiation, TemplateArgs); + if ((*Member)->isInvalidDecl()) { + Invalid = true; + continue; + } + + Decl *NewMember = Instantiator.Visit(*Member); if (NewMember) { if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) Fields.push_back(Field); @@ -1257,7 +1263,22 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, CheckCompletedCXXClass(Instantiation); if (Instantiation->isInvalidDecl()) Invalid = true; - + else { + // Instantiate any out-of-line class template partial + // specializations now. + for (TemplateDeclInstantiator::delayed_partial_spec_iterator + P = Instantiator.delayed_partial_spec_begin(), + PEnd = Instantiator.delayed_partial_spec_end(); + P != PEnd; ++P) { + if (!Instantiator.InstantiateClassTemplatePartialSpecialization( + P->first, + P->second)) { + Invalid = true; + break; + } + } + } + // Exit the scope of this instantiation. SavedContext.pop(); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index aea25c8dad0..5b5e1babf53 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -25,85 +25,6 @@ using namespace clang; -namespace { - class TemplateDeclInstantiator - : public DeclVisitor<TemplateDeclInstantiator, Decl *> { - Sema &SemaRef; - DeclContext *Owner; - const MultiLevelTemplateArgumentList &TemplateArgs; - - public: - TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, - const MultiLevelTemplateArgumentList &TemplateArgs) - : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { } - - // FIXME: Once we get closer to completion, replace these manually-written - // declarations with automatically-generated ones from - // clang/AST/DeclNodes.inc. - Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); - Decl *VisitNamespaceDecl(NamespaceDecl *D); - Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - Decl *VisitTypedefDecl(TypedefDecl *D); - Decl *VisitVarDecl(VarDecl *D); - Decl *VisitAccessSpecDecl(AccessSpecDecl *D); - Decl *VisitFieldDecl(FieldDecl *D); - Decl *VisitStaticAssertDecl(StaticAssertDecl *D); - Decl *VisitEnumDecl(EnumDecl *D); - Decl *VisitEnumConstantDecl(EnumConstantDecl *D); - Decl *VisitFriendDecl(FriendDecl *D); - Decl *VisitFunctionDecl(FunctionDecl *D, - TemplateParameterList *TemplateParams = 0); - Decl *VisitCXXRecordDecl(CXXRecordDecl *D); - Decl *VisitCXXMethodDecl(CXXMethodDecl *D, - TemplateParameterList *TemplateParams = 0); - Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); - Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); - Decl *VisitCXXConversionDecl(CXXConversionDecl *D); - ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D); - Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); - Decl *VisitClassTemplatePartialSpecializationDecl( - ClassTemplatePartialSpecializationDecl *D); - Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); - Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); - Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); - Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); - Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); - Decl *VisitUsingDecl(UsingDecl *D); - Decl *VisitUsingShadowDecl(UsingShadowDecl *D); - Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); - Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); - - // Base case. FIXME: Remove once we can instantiate everything. - Decl *VisitDecl(Decl *D) { - unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID( - Diagnostic::Error, - "cannot instantiate %0 yet"); - SemaRef.Diag(D->getLocation(), DiagID) - << D->getDeclKindName(); - - return 0; - } - - // Helper functions for instantiating methods. - TypeSourceInfo *SubstFunctionType(FunctionDecl *D, - llvm::SmallVectorImpl<ParmVarDecl *> &Params); - bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); - bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); - - TemplateParameterList * - SubstTemplateParams(TemplateParameterList *List); - - bool SubstQualifier(const DeclaratorDecl *OldDecl, - DeclaratorDecl *NewDecl); - bool SubstQualifier(const TagDecl *OldDecl, - TagDecl *NewDecl); - - bool InstantiateClassTemplatePartialSpecialization( - ClassTemplateDecl *ClassTemplate, - ClassTemplatePartialSpecializationDecl *PartialSpec); - }; -} - bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, DeclaratorDecl *NewDecl) { NestedNameSpecifier *OldQual = OldDecl->getQualifier(); @@ -860,14 +781,18 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { } Owner->addDecl(Inst); - - // Instantiate all of the partial specializations of this member class - // template. - llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; - D->getPartialSpecializations(PartialSpecs); - for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) - InstantiateClassTemplatePartialSpecialization(Inst, PartialSpecs[I]); - + + if (!PrevClassTemplate) { + // Queue up any out-of-line partial specializations of this member + // class template; the client will force their instantiation once + // the enclosing class has been instantiated. + llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; + D->getPartialSpecializations(PartialSpecs); + for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) + if (PartialSpecs[I]->isOutOfLine()) + OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I])); + } + return Inst; } @@ -888,7 +813,11 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( if (!InstClassTemplate) return 0; - return InstClassTemplate->findPartialSpecInstantiatedFromMember(D); + if (ClassTemplatePartialSpecializationDecl *Result + = InstClassTemplate->findPartialSpecInstantiatedFromMember(D)) + return Result; + + return InstantiateClassTemplatePartialSpecialization(InstClassTemplate, D); } Decl * @@ -1818,8 +1747,9 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { /// \param PartialSpec the (uninstantiated) class template partial /// specialization that we are instantiating. /// -/// \returns true if there was an error, false otherwise. -bool +/// \returns The instantiated partial specialization, if successful; otherwise, +/// NULL to indicate an error. +ClassTemplatePartialSpecializationDecl * TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( ClassTemplateDecl *ClassTemplate, ClassTemplatePartialSpecializationDecl *PartialSpec) { @@ -1833,7 +1763,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return true; + return 0; // Substitute into the template arguments of the class template partial // specialization. @@ -1845,7 +1775,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( for (unsigned I = 0; I != N; ++I) { TemplateArgumentLoc Loc; if (SemaRef.Subst(PartialSpecTemplateArgs[I], Loc, TemplateArgs)) - return true; + return 0; InstTemplateArgs.addArgument(Loc); } @@ -1858,7 +1788,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( InstTemplateArgs, false, Converted)) - return true; + return 0; // Figure out where to insert this class template partial specialization // in the member template's set of class template partial specializations. @@ -1905,10 +1835,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // Outer<int, int> outer; // error: the partial specializations of Inner // // have the same signature. SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared) - << WrittenTy; + << WrittenTy->getType(); SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here) << SemaRef.Context.getTypeDeclType(PrevDecl); - return true; + return 0; } @@ -1936,7 +1866,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // Add this partial specialization to the set of class template partial // specializations. ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos); - return false; + return InstPartialSpec; } TypeSourceInfo* |

