From 06c0fecd197fef21e265a41bca8dc5022de1f864 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 25 Mar 2009 22:00:53 +0000 Subject: [PATCH] Pass access specifiers through to member classes and member enums. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67710 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Action.h | 2 +- include/clang/Parse/Parser.h | 9 ++++++--- lib/Parse/ParseDecl.cpp | 11 ++++++----- lib/Parse/ParseDeclCXX.cpp | 7 ++++--- lib/Sema/Sema.h | 2 +- lib/Sema/SemaDecl.cpp | 5 ++++- lib/Sema/SemaTemplateInstantiateDecl.cpp | 1 + tools/clang-cc/PrintParserCallbacks.cpp | 2 +- 8 files changed, 24 insertions(+), 15 deletions(-) diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index bd47d9df08..288e9a2cad 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -353,7 +353,7 @@ public: virtual DeclTy *ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr) { + AttributeList *Attr, AccessSpecifier AS) { // TagType is an instance of DeclSpec::TST, indicating what kind of tag this // is (struct/union/enum/class). return 0; diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 288b03de69..f49f7bd598 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_PARSE_PARSER_H #include "clang/Lex/Preprocessor.h" +#include "clang/Parse/AccessSpecifier.h" #include "clang/Parse/Action.h" #include "clang/Parse/DeclSpec.h" #include "llvm/ADT/OwningPtr.h" @@ -809,7 +810,8 @@ private: DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D); DeclTy *ParseFunctionStatementBody(DeclTy *Decl); void ParseDeclarationSpecifiers(DeclSpec &DS, - TemplateParameterLists *TemplateParams = 0); + TemplateParameterLists *TemplateParams = 0, + AccessSpecifier AS = AS_none); bool ParseOptionalTypeSpecifier(DeclSpec &DS, int &isInvalid, const char *&PrevSpec, TemplateParameterLists *TemplateParams = 0); @@ -817,7 +819,7 @@ private: void ParseObjCTypeQualifierList(ObjCDeclSpec &DS); - void ParseEnumSpecifier(DeclSpec &DS); + void ParseEnumSpecifier(DeclSpec &DS, AccessSpecifier AS = AS_none); void ParseEnumBody(SourceLocation StartLoc, DeclTy *TagDecl); void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType, DeclTy *TagDecl); @@ -999,7 +1001,8 @@ private: TypeTy *ParseClassName(SourceLocation &EndLocation, const CXXScopeSpec *SS = 0); void ParseClassSpecifier(DeclSpec &DS, - TemplateParameterLists *TemplateParams = 0); + TemplateParameterLists *TemplateParams = 0, + AccessSpecifier AS = AS_none); void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType, DeclTy *TagDecl); DeclTy *ParseCXXClassMemberDeclaration(AccessSpecifier AS); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index a6e7d52fc1..7a92171908 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -471,7 +471,8 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { /// [C++] 'explicit' /// void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, - TemplateParameterLists *TemplateParams){ + TemplateParameterLists *TemplateParams, + AccessSpecifier AS){ DS.SetRangeStart(Tok.getLocation()); while (1) { int isInvalid = false; @@ -767,12 +768,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::kw_class: case tok::kw_struct: case tok::kw_union: - ParseClassSpecifier(DS, TemplateParams); + ParseClassSpecifier(DS, TemplateParams, AS); continue; // enum-specifier: case tok::kw_enum: - ParseEnumSpecifier(DS); + ParseEnumSpecifier(DS, AS); continue; // cv-qualifier: @@ -1228,7 +1229,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, /// [C++] elaborated-type-specifier: /// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier /// -void Parser::ParseEnumSpecifier(DeclSpec &DS) { +void Parser::ParseEnumSpecifier(DeclSpec &DS, AccessSpecifier AS) { assert(Tok.is(tok::kw_enum) && "Not an enum specifier"); SourceLocation StartLoc = ConsumeToken(); @@ -1285,7 +1286,7 @@ void Parser::ParseEnumSpecifier(DeclSpec &DS) { else TK = Action::TK_Reference; DeclTy *TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK, StartLoc, - SS, Name, NameLoc, Attr); + SS, Name, NameLoc, Attr, AS); if (Tok.is(tok::l_brace)) ParseEnumBody(StartLoc, TagDecl); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index d2d8c1eeae..1bbf411874 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -349,7 +349,8 @@ Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation, /// 'struct' /// 'union' void Parser::ParseClassSpecifier(DeclSpec &DS, - TemplateParameterLists *TemplateParams) { + TemplateParameterLists *TemplateParams, + AccessSpecifier AS) { assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_struct) || Tok.is(tok::kw_union)) && @@ -462,7 +463,7 @@ void Parser::ParseClassSpecifier(DeclSpec &DS, TemplateParams->size())); else TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, - NameLoc, Attr); + NameLoc, Attr, AS); // Parse the optional base clause (C++ only). if (getLang().CPlusPlus && Tok.is(tok::colon)) @@ -649,7 +650,7 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { // decl-specifier-seq: // Parse the common declaration-specifiers piece. DeclSpec DS; - ParseDeclarationSpecifiers(DS); + ParseDeclarationSpecifiers(DS, 0, AS); if (Tok.is(tok::semi)) { ConsumeToken(); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index ad7aa3bee9..8c1b78c918 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -390,7 +390,7 @@ public: virtual DeclTy *ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr); + AttributeList *Attr, AccessSpecifier AS); virtual void ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart, IdentifierInfo *ClassName, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cc1a5b32a7..a2ec9388d2 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3068,7 +3068,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr) { + AttributeList *Attr, AccessSpecifier AS) { // If this is not a definition, it must have a name. assert((Name != 0 || TK == TK_Definition) && "Nameless record must be a definition!"); @@ -3362,6 +3362,9 @@ CreateNewDecl: // lexical context will be different from the semantic context. New->setLexicalDeclContext(CurContext); + if (AS != AS_none) + New->setAccess(AS); + if (TK == TK_Definition) New->startDefinition(); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index d9f6902b54..ff474fab26 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -173,6 +173,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner, D->getLocation(), D->getIdentifier(), /*PrevDecl=*/0); + Enum->setAccess(D->getAccess()); Owner->addDecl(Enum); Enum->startDefinition(); diff --git a/tools/clang-cc/PrintParserCallbacks.cpp b/tools/clang-cc/PrintParserCallbacks.cpp index 6230591ffc..ba0d8efbbf 100644 --- a/tools/clang-cc/PrintParserCallbacks.cpp +++ b/tools/clang-cc/PrintParserCallbacks.cpp @@ -189,7 +189,7 @@ namespace { virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr) { + AttributeList *Attr, AccessSpecifier AS) { // TagType is an instance of DeclSpec::TST, indicating what kind of tag this // is (struct/union/enum/class). llvm::cout << __FUNCTION__ << "\n"; -- 2.40.0