diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 25 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 9 |
5 files changed, 57 insertions, 16 deletions
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 35c181c94f..b387e9e551 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -21,7 +21,9 @@ using namespace clang; /// ParseCXXInlineMethodDef - We parsed and verified that the specified /// Declarator is a well formed C++ inline method definition. Now lex its body /// and store its tokens for parsing after the C++ class is complete. -Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, +Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, + AttributeList *AccessAttrs, + ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, const VirtSpecifiers& VS, ExprResult& Init) { assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); @@ -43,6 +45,8 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, move(TemplateParams), 0, VS, /*HasInit=*/false); if (FnD) { + Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs, + false, true); bool TypeSpecContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; if (Init.get()) diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index decb7f9ec5..607cb88260 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1577,6 +1577,7 @@ bool Parser::isCXX0XFinalKeyword() const { /// '=' constant-expression /// void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, + AttributeList *AccessAttrs, const ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject *TemplateDiags) { if (Tok.is(tok::at)) { @@ -1643,7 +1644,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, "Nested template improperly parsed?"); SourceLocation DeclEnd; ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd, - AS); + AS, AccessAttrs); return; } @@ -1652,7 +1653,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // __extension__ silences extension warnings in the subexpression. ExtensionRAIIObject O(Diags); // Use RAII to do this. ConsumeToken(); - return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags); + return ParseCXXClassMemberDeclaration(AS, AccessAttrs, + TemplateInfo, TemplateDiags); } // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it @@ -1783,7 +1785,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } Decl *FunDecl = - ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init); + ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo, + VS, Init); for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { LateParsedAttrs[i]->setDecl(FunDecl); @@ -1867,6 +1870,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, move(TemplateParams), BitfieldSize.release(), VS, HasDeferredInitializer); + if (AccessAttrs) + Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs, + false, true); } // Set the Decl for any late parsed attributes @@ -2109,6 +2115,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, CurAS = AS_private; else CurAS = AS_public; + ParsedAttributes AccessAttrs(AttrFactory); if (TagDecl) { // While we still have something to read, read the member-declarations. @@ -2137,9 +2144,17 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, SourceLocation ASLoc = Tok.getLocation(); unsigned TokLength = Tok.getLength(); ConsumeToken(); + AccessAttrs.clear(); + MaybeParseGNUAttributes(AccessAttrs); + SourceLocation EndLoc; if (Tok.is(tok::colon)) { EndLoc = Tok.getLocation(); + if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc, + AccessAttrs.getList())) { + // found another attribute than only annotations + AccessAttrs.clear(); + } ConsumeToken(); } else if (Tok.is(tok::semi)) { EndLoc = Tok.getLocation(); @@ -2158,7 +2173,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // FIXME: Make sure we don't have a template here. // Parse all the comma separated declarators. - ParseCXXClassMemberDeclaration(CurAS); + ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList()); } T.consumeClose(); @@ -2779,7 +2794,7 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, } // Parse all the comma separated declarators. - ParseCXXClassMemberDeclaration(CurAS); + ParseCXXClassMemberDeclaration(CurAS, 0); } if (Tok.isNot(tok::r_brace)) { diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 4509662c65..92fe4a5f33 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -26,14 +26,16 @@ using namespace clang; Decl * Parser::ParseDeclarationStartingWithTemplate(unsigned Context, SourceLocation &DeclEnd, - AccessSpecifier AS) { + AccessSpecifier AS, + AttributeList *AccessAttrs) { ObjCDeclContextSwitch ObjCDC(*this); if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) { return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(), DeclEnd); } - return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS); + return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS, + AccessAttrs); } /// \brief RAII class that manages the template parameter depth. @@ -77,7 +79,8 @@ namespace { Decl * Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, SourceLocation &DeclEnd, - AccessSpecifier AS) { + AccessSpecifier AS, + AttributeList *AccessAttrs) { assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) && "Token does not start a template declaration."); @@ -161,7 +164,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, isSpecialization, LastParamListWasEmpty), ParsingTemplateParams, - DeclEnd, AS); + DeclEnd, AS, AccessAttrs); } /// \brief Parse a single declaration that declares a template, @@ -190,13 +193,15 @@ Parser::ParseSingleDeclarationAfterTemplate( const ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd, - AccessSpecifier AS) { + AccessSpecifier AS, + AttributeList *AccessAttrs) { assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && "Template information required"); if (Context == Declarator::MemberContext) { // We are parsing a member template. - ParseCXXClassMemberDeclaration(AS, TemplateInfo, &DiagsFromTParams); + ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo, + &DiagsFromTParams); return 0; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index f76bb5879a..69baf79ad0 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3743,6 +3743,22 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, } } +// Annotation attributes are the only attributes allowed after an access +// specifier. +bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, + const AttributeList *AttrList) { + for (const AttributeList* l = AttrList; l; l = l->getNext()) { + if (l->getKind() == AttributeList::AT_annotate) { + handleAnnotateAttr(*this, ASDecl, *l); + } else { + Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); + return true; + } + } + + return false; +} + /// checkUnusedDeclAttributes - Check a list of attributes to see if it /// contains any decl attributes that we should warn about. static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 32da8cbb10..a39584a107 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1376,14 +1376,15 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) { //===----------------------------------------------------------------------===// /// ActOnAccessSpecifier - Parsed an access specifier followed by a colon. -Decl *Sema::ActOnAccessSpecifier(AccessSpecifier Access, - SourceLocation ASLoc, - SourceLocation ColonLoc) { +bool Sema::ActOnAccessSpecifier(AccessSpecifier Access, + SourceLocation ASLoc, + SourceLocation ColonLoc, + AttributeList *Attrs) { assert(Access != AS_none && "Invalid kind for syntactic access specifier!"); AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext, ASLoc, ColonLoc); CurContext->addHiddenDecl(ASDecl); - return ASDecl; + return ProcessAccessDeclAttributeList(ASDecl, Attrs); } /// CheckOverrideControl - Check C++0x override control semantics. |