summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-04-10 01:32:12 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-04-10 01:32:12 +0000
commit7bdcc4a9da8ccbafb15872083f551366cdaf3b51 (patch)
treebb52354737aeaa0e413fe20cb96e321ba9e47aac /clang/lib/Parse/ParseDeclCXX.cpp
parent076b3041c0706a957766f7e5e885f05b2eaf255e (diff)
downloadbcm5719-llvm-7bdcc4a9da8ccbafb15872083f551366cdaf3b51.tar.gz
bcm5719-llvm-7bdcc4a9da8ccbafb15872083f551366cdaf3b51.zip
Disambiguation of '[[':
* In C++11, '[[' is ill-formed unless it starts an attribute-specifier. Reject array sizes and array indexes which begin with a lambda-expression. Recover by parsing the lambda as a lambda. * In Objective-C++11, either '[' could be the start of a message-send. Fully disambiguate this case: it turns out that the grammars of message-sends, lambdas and attributes do not actually overlap. Accept any occurrence of '[[' where either '[' starts a message send, but reject a lambda in an array index just like in C++11 mode. Implement a couple of changes to the attribute wording which occurred after our attributes implementation landed: * In a function-declaration, the attributes go after the exception specification, not after the right paren. * A reference type can have attributes applied. * An 'identifier' in an attribute can also be a keyword. Support for alternative tokens (iso646 keywords) in attributes to follow. And some bug fixes: * Parse attributes after declarator-ids, even if they are not simple identifiers. * Do not accept attributes after a parenthesized declarator. * Accept attributes after an array size in a new-type-id. * Partially disamiguate 'delete' followed by a lambda. More work is required here for the case where the lambda-introducer is '[]'. llvm-svn: 154369
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp39
1 files changed, 23 insertions, 16 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 9321c137fba..10ed3b1516e 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2736,38 +2736,38 @@ void Parser::PopParsingClass(Sema::ParsingClassState state) {
Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
}
-/// ParseCXX0XAttributeSpecifier - Parse a C++0x attribute-specifier. Currently
+/// ParseCXX0XAttributeSpecifier - Parse a C++11 attribute-specifier. Currently
/// only parses standard attributes.
///
-/// [C++0x] attribute-specifier:
+/// [C++11] attribute-specifier:
/// '[' '[' attribute-list ']' ']'
/// alignment-specifier
///
-/// [C++0x] attribute-list:
+/// [C++11] attribute-list:
/// attribute[opt]
/// attribute-list ',' attribute[opt]
///
-/// [C++0x] attribute:
+/// [C++11] attribute:
/// attribute-token attribute-argument-clause[opt]
///
-/// [C++0x] attribute-token:
+/// [C++11] attribute-token:
/// identifier
/// attribute-scoped-token
///
-/// [C++0x] attribute-scoped-token:
+/// [C++11] attribute-scoped-token:
/// attribute-namespace '::' identifier
///
-/// [C++0x] attribute-namespace:
+/// [C++11] attribute-namespace:
/// identifier
///
-/// [C++0x] attribute-argument-clause:
+/// [C++11] attribute-argument-clause:
/// '(' balanced-token-seq ')'
///
-/// [C++0x] balanced-token-seq:
+/// [C++11] balanced-token-seq:
/// balanced-token
/// balanced-token-seq balanced-token
///
-/// [C++0x] balanced-token:
+/// [C++11] balanced-token:
/// '(' balanced-token-seq ')'
/// '[' balanced-token-seq ']'
/// '{' balanced-token-seq '}'
@@ -2781,7 +2781,7 @@ void Parser::ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs,
}
assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
- && "Not a C++0x attribute list");
+ && "Not a C++11 attribute list");
Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute);
@@ -2793,7 +2793,11 @@ void Parser::ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs,
ConsumeToken();
}
- while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
+ // C++11 [dcl.attr.grammar]p3: If a keyword or an alternative token that
+ // satisfies the syntactic requirements of an identifier is contained in an
+ // attribute-token, it is considered an identifier.
+ // FIXME: Support alternative tokens here.
+ while (Tok.getIdentifierInfo() || Tok.is(tok::comma)) {
// attribute not present
if (Tok.is(tok::comma)) {
ConsumeToken();
@@ -2807,7 +2811,7 @@ void Parser::ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs,
if (Tok.is(tok::coloncolon)) {
ConsumeToken();
- if (!Tok.is(tok::identifier)) {
+ if (!Tok.getIdentifierInfo()) {
Diag(Tok.getLocation(), diag::err_expected_ident);
SkipUntil(tok::r_square, tok::comma, true, true);
continue;
@@ -2824,8 +2828,7 @@ void Parser::ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs,
// No scoped names are supported; ideally we could put all non-standard
// attributes into namespaces.
if (!ScopeName) {
- switch(AttributeList::getKind(AttrName))
- {
+ switch (AttributeList::getKind(AttrName)) {
// No arguments
case AttributeList::AT_carries_dependency:
case AttributeList::AT_noreturn: {
@@ -2852,6 +2855,9 @@ void Parser::ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs,
// SkipUntil maintains the balancedness of tokens.
SkipUntil(tok::r_paren, false);
}
+
+ if (Tok.is(tok::ellipsis))
+ ConsumeToken();
}
if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
@@ -2874,7 +2880,7 @@ void Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
do {
ParseCXX0XAttributeSpecifier(attrs, endLoc);
- } while (isCXX0XAttributeSpecifier());
+ } while (isCXX11AttributeSpecifier());
attrs.Range = SourceRange(StartLoc, *endLoc);
}
@@ -2892,6 +2898,7 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
while (Tok.is(tok::l_square)) {
+ // FIXME: If this is actually a C++11 attribute, parse it as one.
ConsumeBracket();
SkipUntil(tok::r_square, true, true);
if (endLoc) *endLoc = Tok.getLocation();
OpenPOWER on IntegriCloud