From 1c7e6ec27b65b11b5cae240e1e3820eb348214f1 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sun, 20 Dec 2009 07:58:13 +0000 Subject: Don't inject the class name until that magical lbrace. Because of the rules of base-class lookup* and the restrictions on typedefs, it was actually impossible for this to cause any problems more serious than the spurious acceptance of template class A : B { ... }; instead of template class A : B > { ... }; but I'm sure we can all agree that that is a very important restriction which is well worth making another Parser->Sema call for. (*) n.b. clang++ does not implement these rules correctly; we are not ignoring non-type names llvm-svn: 91792 --- clang/lib/Sema/Sema.h | 6 +++++ clang/lib/Sema/SemaDecl.cpp | 53 +++++++++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 24 deletions(-) (limited to 'clang/lib/Sema') diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 41081f2f13b..f83e9a70bb0 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -757,6 +757,12 @@ public: /// struct, or union). virtual void ActOnTagStartDefinition(Scope *S, DeclPtrTy TagDecl); + /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a + /// C++ record definition's base-specifiers clause and are starting its + /// member declarations. + virtual void ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagDecl, + SourceLocation LBraceLoc); + /// ActOnTagFinishDefinition - Invoked once we have finished parsing /// the definition of a tag (enumeration, class, struct, or union). virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e408000fab5..c873f395797 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4962,31 +4962,36 @@ void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) { // Enter the tag context. PushDeclContext(S, Tag); +} - if (CXXRecordDecl *Record = dyn_cast(Tag)) { - FieldCollector->StartClass(); - - if (Record->getIdentifier()) { - // C++ [class]p2: - // [...] The class-name is also inserted into the scope of the - // class itself; this is known as the injected-class-name. For - // purposes of access checking, the injected-class-name is treated - // as if it were a public member name. - CXXRecordDecl *InjectedClassName - = CXXRecordDecl::Create(Context, Record->getTagKind(), - CurContext, Record->getLocation(), - Record->getIdentifier(), - Record->getTagKeywordLoc(), - Record); - InjectedClassName->setImplicit(); - InjectedClassName->setAccess(AS_public); - if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) - InjectedClassName->setDescribedClassTemplate(Template); - PushOnScopeChains(InjectedClassName, S); - assert(InjectedClassName->isInjectedClassName() && - "Broken injected-class-name"); - } - } +void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD, + SourceLocation LBraceLoc) { + AdjustDeclIfTemplate(TagD); + CXXRecordDecl *Record = cast(TagD.getAs()); + + FieldCollector->StartClass(); + + if (!Record->getIdentifier()) + return; + + // C++ [class]p2: + // [...] The class-name is also inserted into the scope of the + // class itself; this is known as the injected-class-name. For + // purposes of access checking, the injected-class-name is treated + // as if it were a public member name. + CXXRecordDecl *InjectedClassName + = CXXRecordDecl::Create(Context, Record->getTagKind(), + CurContext, Record->getLocation(), + Record->getIdentifier(), + Record->getTagKeywordLoc(), + Record); + InjectedClassName->setImplicit(); + InjectedClassName->setAccess(AS_public); + if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) + InjectedClassName->setDescribedClassTemplate(Template); + PushOnScopeChains(InjectedClassName, S); + assert(InjectedClassName->isInjectedClassName() && + "Broken injected-class-name"); } void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD, -- cgit v1.2.3