summaryrefslogtreecommitdiffstats
path: root/clang/lib
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
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')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp11
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp22
2 files changed, 27 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 18747825537..82ff7c0ca4f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2788,9 +2788,14 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) {
isa<TemplateTemplateParmDecl>(D))
return nullptr;
- // Tag type may be referenced prior to definition, in this case it does not
- // have instantiation yet.
- if (isa<TagDecl>(D))
+ // Local types referenced prior to definition may require instantiation.
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+ if (RD->isLocalClass())
+ return nullptr;
+
+ // Enumeration types referenced prior to definition may appear as a result of
+ // error recovery.
+ if (isa<EnumDecl>(D))
return nullptr;
// If we didn't find the decl, then we either have a sema bug, or we have a
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