diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2015-05-15 10:10:28 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2015-05-15 10:10:28 +0000 |
commit | e7ad831241e752f32f5f65e94ae3f1d0d8ad8894 (patch) | |
tree | 9f51f2de7544174f9d8b1d4fe5f43279ba670824 /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 6f48e0fd2b4bd186a4ddab4456290501258bb98f (diff) | |
download | bcm5719-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.cpp | 22 |
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); |