summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2015-05-15 10:10:28 +0000
committerSerge Pavlov <sepavloff@gmail.com>2015-05-15 10:10:28 +0000
commite7ad831241e752f32f5f65e94ae3f1d0d8ad8894 (patch)
tree9f51f2de7544174f9d8b1d4fe5f43279ba670824 /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
parent6f48e0fd2b4bd186a4ddab4456290501258bb98f (diff)
downloadbcm5719-llvm-e7ad831241e752f32f5f65e94ae3f1d0d8ad8894.tar.gz
bcm5719-llvm-e7ad831241e752f32f5f65e94ae3f1d0d8ad8894.zip
Limit set of types instantiated in FindInstantiatedDecl.
Starting from r236426 FindInstantiatedDecl may instantiate types that are referenced before definition. This change limit the set of types that can be instantiated by this function. llvm-svn: 237434
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 4a92efdaae2..5c994f86bd2 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4442,9 +4442,25 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
if (D->isInvalidDecl())
return nullptr;
- // Tag type may be referenced prior to definition, in this case it must be
- // instantiated now.
- if (isa<TagDecl>(D)) {
+ // Normally this function only searches for already instantiated declaration
+ // however we have to make an exclusion for local types used before
+ // definition as in the code:
+ //
+ // template<typename T> void f1() {
+ // void g1(struct x1);
+ // struct x1 {};
+ // }
+ //
+ // In this case instantiation of the type of 'g1' requires definition of
+ // 'x1', which is defined later. Error recovery may produce an enum used
+ // before definition. In these cases we need to instantiate relevant
+ // declarations here.
+ bool NeedInstantiate = false;
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+ NeedInstantiate = RD->isLocalClass();
+ else
+ NeedInstantiate = isa<EnumDecl>(D);
+ if (NeedInstantiate) {
Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
CurrentInstantiationScope->InstantiatedLocal(D, Inst);
return cast<TypeDecl>(Inst);
OpenPOWER on IntegriCloud