From d0c873799614d32c9c11280878ac1a856f92f707 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 27 May 2009 17:30:49 +0000 Subject: [PATCH] Add some more tests for instantiation of declaration references. Also, improve some error recovery with explicit template instantiation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72484 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 4 +++- lib/Sema/SemaTemplate.cpp | 3 +++ test/SemaTemplate/instantiate-declref.cpp | 13 ++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 5e09851770..d592cf6178 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3358,6 +3358,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, if (PrevDecl == 0) { Diag(NameLoc, diag::err_not_tag_in_scope) << Name << SS.getRange(); Name = 0; + Invalid = true; goto CreateNewDecl; } } else if (Name) { @@ -3629,7 +3630,8 @@ CreateNewDecl: New->setLexicalDeclContext(CurContext); // Set the access specifier. - SetMemberAccessSpecifier(New, PrevDecl, AS); + if (!Invalid) + SetMemberAccessSpecifier(New, PrevDecl, AS); if (TK == TK_Definition) New->startDefinition(); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c533789458..97eca48b9f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2369,6 +2369,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, return true; } + if (Tag->isInvalidDecl()) + return true; + CXXRecordDecl *Record = cast(Tag); CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass(); if (!Pattern) { diff --git a/test/SemaTemplate/instantiate-declref.cpp b/test/SemaTemplate/instantiate-declref.cpp index cceaed00e6..3b6db38617 100644 --- a/test/SemaTemplate/instantiate-declref.cpp +++ b/test/SemaTemplate/instantiate-declref.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -fsyntax-only %s +// RUN: clang-cc -fsyntax-only -verify %s namespace N { struct Outer { @@ -10,12 +10,22 @@ namespace N { static enum K1 { K1Val = sizeof(T) } Kind1; static enum { K2Val = sizeof(T)*2 } Kind2; + enum { K3Val = sizeof(T)*2 } Kind3; void foo() { K1 k1 = K1Val; Kind1 = K1Val; Outer::Inner::InnerTemplate::VeryInner::Kind2 = K2Val; + Kind3 = K3Val; } + + struct UeberInner { + void bar() { + K1 k1 = K1Val; + Kind1 = K1Val; + Outer::Inner::InnerTemplate::VeryInner::Kind2 = K2Val; + } + }; }; }; }; @@ -24,3 +34,4 @@ namespace N { typedef int INT; template struct N::Outer::Inner::InnerTemplate::VeryInner; +template struct N::Outer::Inner::InnerTemplate::UeberInner; // expected-error{{'UeberInner' does not name a tag member}} -- 2.40.0