diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-30 18:55:50 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-30 18:55:50 +0000 |
commit | 895162da2d52f4243f61081d7436de66af4503fc (patch) | |
tree | 190cae43675e176ce9b2c08fdf16e55ab36b829a /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 25cf7b4e9198026c8872203874d04b36831af969 (diff) |
Clean up our handling of local instantiation scopes, which keep track
of the mapping from local declarations to their instantiated
counterparts during template instantiation. Previously, we tried to do
some unholy merging of local instantiation scopes that involved
storing a single hash table along with an "undo" list on the
side... which was ugly, and never handled function parameters
properly.
Now, we just keep separate hash tables for each local instantiation
scope, and "combining" two scopes means that we'll look in each of the
combined hash tables. The combined scope stack is rarely deep, and
this makes it easy to avoid the "undo" issues we were hitting. Also,
I've simplified the logic for function parameters: if we're declaring
a function and we need the function parameters to live longer, we just
push them back into the local instantiation scope where we need them.
Fixes PR6990.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102732 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index a75a80b83d..e727cdbc9e 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -532,8 +532,7 @@ bool Sema::isSFINAEContext() const { // Template Instantiation for Types //===----------------------------------------------------------------------===/ namespace { - class TemplateInstantiator - : public TreeTransform<TemplateInstantiator> { + class TemplateInstantiator : public TreeTransform<TemplateInstantiator> { const MultiLevelTemplateArgumentList &TemplateArgs; SourceLocation Loc; DeclarationName Entity; @@ -604,13 +603,9 @@ namespace { Sema::OwningExprResult TransformTemplateParmRefExpr(DeclRefExpr *E, NonTypeTemplateParmDecl *D); - /// \brief Transforms a function proto type by performing - /// substitution in the function parameters, possibly adjusting - /// their types and marking default arguments as uninstantiated. - bool TransformFunctionTypeParams(FunctionProtoTypeLoc TL, - llvm::SmallVectorImpl<QualType> &PTypes, - llvm::SmallVectorImpl<ParmVarDecl*> &PVars); - + QualType TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + QualType ObjectType); ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm); /// \brief Transforms a template type parameter type by performing @@ -825,23 +820,12 @@ Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr( E->getParam()); } - -bool -TemplateInstantiator::TransformFunctionTypeParams(FunctionProtoTypeLoc TL, - llvm::SmallVectorImpl<QualType> &PTypes, - llvm::SmallVectorImpl<ParmVarDecl*> &PVars) { - // Create a local instantiation scope for the parameters. - // 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)) - return true; - - return false; +QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + QualType ObjectType) { + // We need a local instantiation scope for this function prototype. + Sema::LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); + return inherited::TransformFunctionProtoType(TLB, TL, ObjectType); } ParmVarDecl * @@ -1600,3 +1584,29 @@ bool Sema::Subst(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output, return Instantiator.TransformTemplateArgument(Input, Output); } + +Decl *Sema::LocalInstantiationScope::getInstantiationOf(const Decl *D) { + for (LocalInstantiationScope *Current = this; Current; + Current = Current->Outer) { + // Check if we found something within this scope. + llvm::DenseMap<const Decl *, Decl *>::iterator Found + = Current->LocalDecls.find(D); + if (Found != Current->LocalDecls.end()) + return Found->second; + + // If we aren't combined with our outer scope, we're done. + if (!Current->CombineWithOuterScope) + break; + } + + assert(D->isInvalidDecl() && + "declaration was not instantiated in this scope!"); + return 0; +} + +void Sema::LocalInstantiationScope::InstantiatedLocal(const Decl *D, + Decl *Inst) { + Decl *&Stored = LocalDecls[D]; + assert((!Stored || Stored == Inst)&& "Already instantiated this local"); + Stored = Inst; +} |