summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h27
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp12
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp7
3 files changed, 33 insertions, 13 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index ba6d38f849a..7e2e6143965 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -3487,15 +3487,27 @@ public:
/// \brief Whether we have already exited this scope.
bool Exited;
+ /// \brief Whether this scope is temporary, meaning that we should
+ /// remove any additions we make once we exit this
+ /// scope. Temporary scopes are always combined with their outer
+ /// scopes.
+ bool Temporary;
+
+ /// \brief List of the declarations that we have added into this
+ /// temporary scope. They will be removed when we exit the
+ /// temporary scope.
+ llvm::SmallVector<const Decl *, 4> AddedTemporaryDecls;
+
// This class is non-copyable
LocalInstantiationScope(const LocalInstantiationScope &);
LocalInstantiationScope &operator=(const LocalInstantiationScope &);
public:
- LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
+ LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
+ bool Temporary = false)
: SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
- Exited(false) {
- if (!CombineWithOuterScope)
+ Exited(false), Temporary(Temporary) {
+ if (!CombineWithOuterScope && !Temporary)
SemaRef.CurrentInstantiationScope = this;
else
assert(SemaRef.CurrentInstantiationScope &&
@@ -3503,8 +3515,11 @@ public:
}
~LocalInstantiationScope() {
- if (!Exited)
+ if (!Exited) {
SemaRef.CurrentInstantiationScope = Outer;
+ for (unsigned I = 0, N = AddedTemporaryDecls.size(); I != N; ++I)
+ LocalDecls.erase(AddedTemporaryDecls[I]);
+ }
}
/// \brief Exit this local instantiation scope early.
@@ -3537,6 +3552,10 @@ public:
void InstantiatedLocal(const Decl *D, Decl *Inst) {
Decl *&Stored = LocalDecls[D];
assert((!Stored || Stored == Inst) && "Already instantiated this local");
+
+ if (Temporary && !Stored)
+ AddedTemporaryDecls.push_back(D);
+
Stored = Inst;
}
};
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 326519d3a37..3a8ed508942 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -987,13 +987,7 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
Decl *Param
= const_cast<NamedDecl *>(
Partial->getTemplateParameters()->getParam(I));
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
- Info.Param = TTP;
- else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(Param))
- Info.Param = NTTP;
- else
- Info.Param = cast<TemplateTemplateParmDecl>(Param);
+ Info.Param = makeTemplateParameter(Param);
return TDK_Incomplete;
}
@@ -1010,6 +1004,7 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
// verify that the instantiated template arguments are both valid
// and are equivalent to the template arguments originally provided
// to the class template.
+ Sema::LocalInstantiationScope InstScope(*this);
ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
const TemplateArgumentLoc *PartialTemplateArgs
= Partial->getTemplateArgsAsWritten();
@@ -1458,6 +1453,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// The types of the parameters from which we will perform template argument
// deduction.
+ Sema::LocalInstantiationScope InstScope(*this);
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
llvm::SmallVector<TemplateArgument, 4> Deduced;
@@ -1612,6 +1608,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
QualType FunctionType = Function->getType();
// Substitute any explicit template arguments.
+ Sema::LocalInstantiationScope InstScope(*this);
llvm::SmallVector<TemplateArgument, 4> Deduced;
llvm::SmallVector<QualType, 4> ParamTypes;
if (ExplicitTemplateArgs) {
@@ -1739,6 +1736,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// modulo the various allowed differences.
// Finish template argument deduction.
+ Sema::LocalInstantiationScope InstScope(*this);
FunctionDecl *Spec = 0;
TemplateDeductionResult Result
= FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, Spec, Info);
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index ac1bf7219c5..89a660c79f9 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -873,8 +873,11 @@ TemplateInstantiator::TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
llvm::SmallVectorImpl<QualType> &PTypes,
llvm::SmallVectorImpl<ParmVarDecl*> &PVars) {
// Create a local instantiation scope for the parameters.
- Sema::LocalInstantiationScope
- Scope(SemaRef, SemaRef.CurrentInstantiationScope != 0);
+ // FIXME: When we implement the C++0x late-specified return type,
+ // we will need to move this scope out to the function type itself.
+ bool IsTemporaryScope = (SemaRef.CurrentInstantiationScope != 0);
+ Sema::LocalInstantiationScope Scope(SemaRef, IsTemporaryScope,
+ IsTemporaryScope);
if (TreeTransform<TemplateInstantiator>::
TransformFunctionTypeParams(TL, PTypes, PVars))
OpenPOWER on IntegriCloud