aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp111
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