diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2014-03-31 17:32:39 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2014-03-31 17:32:39 +0000 |
commit | b8e203939e19618ebf73ee5c85901914e3060af1 (patch) | |
tree | f80ac9cdcfd1690f51ac4254e6616495ebb8d23b /clang/lib/Parse/ParseDeclCXX.cpp | |
parent | 4b293ebbaa96e75ea5f819e82be284d59ce436ad (diff) | |
download | bcm5719-llvm-b8e203939e19618ebf73ee5c85901914e3060af1.tar.gz bcm5719-llvm-b8e203939e19618ebf73ee5c85901914e3060af1.zip |
Introduced an attribute syntax-neutral method for parsing attribute arguments that is currently being used by GNU and C++-style attributes. This allows C++11 attributes with argument lists to be handled properly, fixing the "deprecated", "type_visibility", and capability-related attributes with arguments.
llvm-svn: 205226
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index c7c8625f2c0..c84bdcbf35b 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -15,7 +15,9 @@ #include "RAIIObjectsForParser.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" +#include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/DeclSpec.h" @@ -3197,8 +3199,50 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, } } -/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently -/// only parses standard attributes. +/// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause. +/// +/// [C++11] attribute-argument-clause: +/// '(' balanced-token-seq ')' +/// +/// [C++11] balanced-token-seq: +/// balanced-token +/// balanced-token-seq balanced-token +/// +/// [C++11] balanced-token: +/// '(' balanced-token-seq ')' +/// '[' balanced-token-seq ']' +/// '{' balanced-token-seq '}' +/// any token but '(', ')', '[', ']', '{', or '}' +bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, + SourceLocation *EndLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc) { + assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); + + // If the attribute isn't known, we will not attempt to parse any + // arguments. + if (!hasAttribute(AttrSyntax::CXX, ScopeName, AttrName, + getTargetInfo().getTriple(), getLangOpts())) { + // Eat the left paren, then skip to the ending right paren. + ConsumeParen(); + SkipUntil(tok::r_paren); + return false; + } + + if (ScopeName && ScopeName->getName() == "gnu") + // GNU-scoped attributes have some special cases to handle GNU-specific + // behaviors. + ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, + ScopeLoc, AttributeList::AS_CXX11, 0); + else + ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, + ScopeLoc, AttributeList::AS_CXX11); + return true; +} + +/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. /// /// [C++11] attribute-specifier: /// '[' '[' attribute-list ']' ']' @@ -3222,19 +3266,6 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, /// /// [C++11] attribute-namespace: /// identifier -/// -/// [C++11] attribute-argument-clause: -/// '(' balanced-token-seq ')' -/// -/// [C++11] balanced-token-seq: -/// balanced-token -/// balanced-token-seq balanced-token -/// -/// [C++11] balanced-token: -/// '(' balanced-token-seq ')' -/// '[' balanced-token-seq ']' -/// '{' balanced-token-seq '}' -/// any token but '(', ')', '[', ']', '{', or '}' void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, SourceLocation *endLoc) { if (Tok.is(tok::kw_alignas)) { @@ -3279,29 +3310,22 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, } } - bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName); + bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName); bool AttrParsed = false; if (StandardAttr && !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second) Diag(AttrLoc, diag::err_cxx11_attribute_repeated) - << AttrName << SourceRange(SeenAttrs[AttrName]); + << AttrName << SourceRange(SeenAttrs[AttrName]); // Parse attribute arguments if (Tok.is(tok::l_paren)) { - if (ScopeName && ScopeName->getName() == "gnu") { - ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc, - ScopeName, ScopeLoc, AttributeList::AS_CXX11, 0); - AttrParsed = true; - } else { - if (StandardAttr) - Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments) + if (StandardAttr) + Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments) << AttrName->getName(); - // FIXME: handle other formats of c++11 attribute arguments - ConsumeParen(); - SkipUntil(tok::r_paren); - } + AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, attrs, endLoc, + ScopeName, ScopeLoc); } if (!AttrParsed) |