diff options
author | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-06-05 05:09:32 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-06-05 05:09:32 +0000 |
commit | 6206d53f67613958ae1b023aba337ebb46f11a8b (patch) | |
tree | f662c7b35e4ee18ad916576c2e08fa016b7bd4d2 /lib | |
parent | 21d07e499e108752c9d63d7418f7d9b485f4e0e6 (diff) |
Added AccessSpecDecl node.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105525 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 1 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 27 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 7 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 9 |
10 files changed, 62 insertions, 17 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index a73d17a5ca..8f6fdbc956 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -291,6 +291,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { // Never have names. case Friend: case FriendTemplate: + case AccessSpec: case LinkageSpec: case FileScopeAsm: case StaticAssert: diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 5394924797..2fb6cb1d31 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -183,7 +183,7 @@ void DeclPrinter::Print(AccessSpecifier AS) { case AS_none: assert(0 && "No access specifier!"); break; case AS_public: Out << "public"; break; case AS_protected: Out << "protected"; break; - case AS_private: Out << " private"; break; + case AS_private: Out << "private"; break; } } @@ -195,9 +195,6 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (Indent) Indentation += Policy.Indentation; - bool PrintAccess = isa<CXXRecordDecl>(DC); - AccessSpecifier CurAS = AS_none; - llvm::SmallVector<Decl*, 2> Decls; for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); D != DEnd; ++D) { @@ -211,18 +208,6 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { continue; } - if (PrintAccess) { - AccessSpecifier AS = D->getAccess(); - - if (AS != CurAS) { - if (Indent) - this->Indent(Indentation - Policy.Indentation); - Print(AS); - Out << ":\n"; - CurAS = AS; - } - } - // The next bits of code handles stuff like "struct {int x;} a,b"; we're // forced to merge the declarations because there's no other way to // refer to the struct in question. This limited merging is safe without @@ -251,6 +236,16 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { Decls.push_back(*D); continue; } + + if (isa<AccessSpecDecl>(*D)) { + Indentation -= Policy.Indentation; + this->Indent(); + Print(D->getAccess()); + Out << ":\n"; + Indentation += Policy.Indentation; + continue; + } + this->Indent(); Visit(*D); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 5b0cc00cd7..e8b67b8864 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -59,6 +59,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::ObjCImplementation: case Decl::ObjCProperty: case Decl::ObjCCompatibleAlias: + case Decl::AccessSpec: case Decl::LinkageSpec: case Decl::ObjCPropertyImpl: case Decl::ObjCClass: diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 5056f93377..7ccf14362f 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -80,6 +80,7 @@ namespace { void VisitUsingShadow(UsingShadowDecl *D); void VisitLinkageSpecDecl(LinkageSpecDecl *D); void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD); + void VisitAccessSpecDecl(AccessSpecDecl *D); void VisitFriendTemplateDecl(FriendTemplateDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitBlockDecl(BlockDecl *BD); @@ -607,6 +608,11 @@ void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { VisitCXXMethodDecl(D); } +void PCHDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { + VisitDecl(D); + D->setColonLoc(Reader.ReadSourceLocation(Record, Idx)); +} + void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) { assert(false && "cannot read FriendTemplateDecl"); } @@ -971,6 +977,10 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { case pch::DECL_CXX_CONVERSION: D = CXXConversionDecl::Create(*Context, Decl::EmptyShell()); break; + case pch::DECL_ACCESS_SPEC: + D = AccessSpecDecl::Create(*Context, AS_none, 0, SourceLocation(), + SourceLocation()); + break; case pch::DECL_FRIEND: assert(false && "cannot read FriendDecl"); break; diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 499a16adb1..6b88dfcae4 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -81,6 +81,7 @@ namespace { void VisitUsingShadow(UsingShadowDecl *D); void VisitLinkageSpecDecl(LinkageSpecDecl *D); void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); + void VisitAccessSpecDecl(AccessSpecDecl *D); void VisitFriendTemplateDecl(FriendTemplateDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitBlockDecl(BlockDecl *D); @@ -607,6 +608,12 @@ void PCHDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) { Code = pch::DECL_CXX_CONVERSION; } +void PCHDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) { + VisitDecl(D); + Writer.AddSourceLocation(D->getColonLoc(), Record); + Code = pch::DECL_ACCESS_SPEC; +} + void PCHDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) { assert(false && "cannot write FriendTemplateDecl"); } diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 7e59170b37..eda490d918 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1570,8 +1570,13 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, if (AS != AS_none) { // Current token is a C++ access specifier. CurAS = AS; + SourceLocation ASLoc = Tok.getLocation(); + ConsumeToken(); + if (Tok.is(tok::colon)) + Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); + else + Diag(Tok, diag::err_expected_colon); ConsumeToken(); - ExpectAndConsume(tok::colon, diag::err_expected_colon); continue; } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 5d4b39e292..064d34316e 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2544,6 +2544,10 @@ public: virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS); + virtual DeclPtrTy ActOnAccessSpecifier(AccessSpecifier Access, + SourceLocation ASLoc, + SourceLocation ColonLoc); + virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 501d878f57..03b2ef5643 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1770,6 +1770,8 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, << (int)Record->isUnion(); Invalid = true; } + } else if (isa<AccessSpecDecl>(*Mem)) { + // Any access specifier is fine. } else { // We have something that isn't a non-static data // member. Complain about it. diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index a6a1943ecd..7dcda88407 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -871,6 +871,17 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) { // C++ class member Handling //===----------------------------------------------------------------------===// +/// ActOnAccessSpecifier - Parsed an access specifier followed by a colon. +Sema::DeclPtrTy +Sema::ActOnAccessSpecifier(AccessSpecifier Access, + SourceLocation ASLoc, SourceLocation ColonLoc) { + assert(Access != AS_none && "Invalid kind for syntactic access specifier!"); + AccessSpecDecl* ASDecl = AccessSpecDecl::Create(Context, Access, CurContext, + ASLoc, ColonLoc); + CurContext->addHiddenDecl(ASDecl); + return DeclPtrTy::make(ASDecl); +} + /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member /// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the /// bitfield width if there is one and 'InitExpr' specifies the initializer if diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 939f6caa96..0af3ed9095 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -48,6 +48,7 @@ namespace { Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitVarDecl(VarDecl *D); + Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitFieldDecl(FieldDecl *D); Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitEnumDecl(EnumDecl *D); @@ -437,6 +438,14 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { return Var; } +Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) { + AccessSpecDecl* AD + = AccessSpecDecl::Create(SemaRef.Context, D->getAccess(), Owner, + D->getAccessSpecifierLoc(), D->getColonLoc()); + Owner->addHiddenDecl(AD); + return AD; +} + Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { bool Invalid = false; TypeSourceInfo *DI = D->getTypeSourceInfo(); |