diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 111 |
1 files changed, 52 insertions, 59 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index cf8d38c095..e8bcb8be89 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Lex/Preprocessor.h" @@ -89,7 +90,7 @@ namespace { } // Helper functions for instantiating methods. - QualType SubstFunctionType(FunctionDecl *D, + TypeSourceInfo *SubstFunctionType(FunctionDecl *D, llvm::SmallVectorImpl<ParmVarDecl *> &Params); bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); @@ -797,9 +798,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); llvm::SmallVector<ParmVarDecl *, 4> Params; - QualType T = SubstFunctionType(D, Params); - if (T.isNull()) + TypeSourceInfo *TInfo = D->getTypeSourceInfo(); + TInfo = SubstFunctionType(D, Params); + if (!TInfo) return 0; + QualType T = TInfo->getType(); // If we're instantiating a local function declaration, put the result // in the owner; otherwise we need to find the instantiated context. @@ -812,7 +815,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, FunctionDecl *Function = FunctionDecl::Create(SemaRef.Context, DC, D->getLocation(), - D->getDeclName(), T, D->getTypeSourceInfo(), + D->getDeclName(), T, TInfo, D->getStorageClass(), D->isInlineSpecified(), D->hasWrittenPrototype()); Function->setLexicalDeclContext(Owner); @@ -932,9 +935,11 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); llvm::SmallVector<ParmVarDecl *, 4> Params; - QualType T = SubstFunctionType(D, Params); - if (T.isNull()) + TypeSourceInfo *TInfo = D->getTypeSourceInfo(); + TInfo = SubstFunctionType(D, Params); + if (!TInfo) return 0; + QualType T = TInfo->getType(); // Build the instantiated method declaration. CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); @@ -947,8 +952,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, SemaRef.Context.getCanonicalType(ClassTy)); Method = CXXConstructorDecl::Create(SemaRef.Context, Record, Constructor->getLocation(), - Name, T, - Constructor->getTypeSourceInfo(), + Name, T, TInfo, Constructor->isExplicit(), Constructor->isInlineSpecified(), false); } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { @@ -966,12 +970,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, ConvTy); Method = CXXConversionDecl::Create(SemaRef.Context, Record, Conversion->getLocation(), Name, - T, Conversion->getTypeSourceInfo(), + T, TInfo, Conversion->isInlineSpecified(), Conversion->isExplicit()); } else { Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(), - D->getDeclName(), T, D->getTypeSourceInfo(), + D->getDeclName(), T, TInfo, D->isStatic(), D->isInlineSpecified()); } @@ -1514,60 +1518,49 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( return false; } -/// \brief Does substitution on the type of the given function, including -/// all of the function parameters. -/// -/// \param D The function whose type will be the basis of the substitution -/// -/// \param Params the instantiated parameter declarations - -/// \returns the instantiated function's type if successful, a NULL -/// type if there was an error. -QualType -TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, - llvm::SmallVectorImpl<ParmVarDecl *> &Params) { - bool InvalidDecl = false; - - // Substitute all of the function's formal parameter types. - TemplateDeclInstantiator ParamInstantiator(SemaRef, 0, TemplateArgs); - llvm::SmallVector<QualType, 4> ParamTys; - for (FunctionDecl::param_iterator P = D->param_begin(), - PEnd = D->param_end(); - P != PEnd; ++P) { - if (ParmVarDecl *PInst = ParamInstantiator.VisitParmVarDecl(*P)) { - if (PInst->getType()->isVoidType()) { - SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type); +bool +Sema::CheckInstantiatedParams(llvm::SmallVectorImpl<ParmVarDecl*> &Params) { + bool Invalid = false; + for (unsigned i = 0, i_end = Params.size(); i != i_end; ++i) + if (ParmVarDecl *PInst = Params[i]) { + if (PInst->isInvalidDecl()) + Invalid = true; + else if (PInst->getType()->isVoidType()) { + Diag(PInst->getLocation(), diag::err_param_with_void_type); PInst->setInvalidDecl(); - } else if (SemaRef.RequireNonAbstractType(PInst->getLocation(), - PInst->getType(), - diag::err_abstract_type_in_decl, - Sema::AbstractParamType)) + Invalid = true; + } + else if (RequireNonAbstractType(PInst->getLocation(), + PInst->getType(), + diag::err_abstract_type_in_decl, + Sema::AbstractParamType)) { PInst->setInvalidDecl(); + Invalid = true; + } + } + return Invalid; +} - Params.push_back(PInst); - ParamTys.push_back(PInst->getType()); +TypeSourceInfo* +TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, + llvm::SmallVectorImpl<ParmVarDecl *> &Params) { + TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); + assert(OldTInfo && "substituting function without type source info"); + assert(Params.empty() && "parameter vector is non-empty at start"); + TypeSourceInfo *NewTInfo = SemaRef.SubstType(OldTInfo, TemplateArgs, + D->getTypeSpecStartLoc(), + D->getDeclName()); + if (!NewTInfo) + return 0; - if (PInst->isInvalidDecl()) - InvalidDecl = true; - } else - InvalidDecl = true; - } + // Get parameters from the new type info. + TypeLoc NewTL = NewTInfo->getTypeLoc(); + FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL); + assert(NewProtoLoc && "Missing prototype?"); + for (unsigned i = 0, i_end = NewProtoLoc->getNumArgs(); i != i_end; ++i) + Params.push_back(NewProtoLoc->getArg(i)); - // FIXME: Deallocate dead declarations. - if (InvalidDecl) - return QualType(); - - const FunctionProtoType *Proto = D->getType()->getAs<FunctionProtoType>(); - assert(Proto && "Missing prototype?"); - QualType ResultType - = SemaRef.SubstType(Proto->getResultType(), TemplateArgs, - D->getLocation(), D->getDeclName()); - if (ResultType.isNull()) - return QualType(); - - return SemaRef.BuildFunctionType(ResultType, ParamTys.data(), ParamTys.size(), - Proto->isVariadic(), Proto->getTypeQuals(), - D->getLocation(), D->getDeclName()); + return NewTInfo; } /// \brief Initializes the common fields of an instantiation function |