diff options
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 62d43768bff..1bbc8943372 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4373,20 +4373,18 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified) { /// type-qualifier-list: [C99 6.7.5] /// type-qualifier /// [vendor] attributes -/// [ only if VendorAttributesAllowed=true ] +/// [ only if AttrReqs & AR_VendorAttributesParsed ] /// type-qualifier-list type-qualifier /// [vendor] type-qualifier-list attributes -/// [ only if VendorAttributesAllowed=true ] +/// [ only if AttrReqs & AR_VendorAttributesParsed ] /// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq -/// [ only if CXX11AttributesAllowed=true ] -/// Note: vendor can be GNU, MS, etc. -/// -void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, - bool VendorAttributesAllowed, - bool CXX11AttributesAllowed, +/// [ only if AttReqs & AR_CXX11AttributesParsed ] +/// Note: vendor can be GNU, MS, etc and can be explicitly controlled via +/// AttrRequirements bitmask values. +void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed, bool IdentifierRequired) { - if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed && + if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrs(AttrFactory); ParseCXX11Attributes(attrs); @@ -4439,7 +4437,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, case tok::kw___uptr: // GNU libc headers in C mode use '__uptr' as an identifer which conflicts // with the MS modifier keyword. - if (VendorAttributesAllowed && !getLangOpts().CPlusPlus && + if ((AttrReqs & AR_DeclspecAttributesParsed) && !getLangOpts().CPlusPlus && IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) { if (TryKeywordIdentFallback(false)) continue; @@ -4453,19 +4451,26 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, case tok::kw___fastcall: case tok::kw___thiscall: case tok::kw___unaligned: - if (VendorAttributesAllowed) { + if (AttrReqs & AR_DeclspecAttributesParsed) { ParseMicrosoftTypeAttributes(DS.getAttributes()); continue; } goto DoneWithTypeQuals; case tok::kw___pascal: - if (VendorAttributesAllowed) { + if (AttrReqs & AR_VendorAttributesParsed) { ParseBorlandTypeAttributes(DS.getAttributes()); continue; } goto DoneWithTypeQuals; case tok::kw___attribute: - if (VendorAttributesAllowed) { + if (AttrReqs & AR_GNUAttributesParsedAndRejected) + // When GNU attributes are expressly forbidden, diagnose their usage. + Diag(Tok, diag::err_attributes_not_allowed); + + // Parse the attributes even if they are rejected to ensure that error + // recovery is graceful. + if (AttrReqs & AR_GNUAttributesParsed || + AttrReqs & AR_GNUAttributesParsedAndRejected) { ParseGNUAttributes(DS.getAttributes()); continue; // do *not* consume the next token! } @@ -4601,8 +4606,13 @@ void Parser::ParseDeclaratorInternal(Declarator &D, // Is a pointer. DeclSpec DS(AttrFactory); - // FIXME: GNU attributes are not allowed here in a new-type-id. - ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier()); + // GNU attributes are not allowed here in a new-type-id, but Declspec and + // C++11 attributes are allowed. + unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed | + ((D.getContext() != Declarator::CXXNewContext) + ? AR_GNUAttributesParsed + : AR_GNUAttributesParsedAndRejected); + ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier()); D.ExtendWithDeclSpec(DS); // Recursively parse the declarator. @@ -5149,8 +5159,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, // with the virt-specifier-seq and pure-specifier in the same way. // Parse cv-qualifier-seq[opt]. - ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false, - /*CXX11AttributesAllowed*/ false, + ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, /*AtomicAllowed*/ false); if (!DS.getSourceRange().getEnd().isInvalid()) { EndLoc = DS.getSourceRange().getEnd(); @@ -5546,7 +5555,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { // If there is a type-qualifier-list, read it now. // Type qualifiers in an array subscript are a C99 feature. DeclSpec DS(AttrFactory); - ParseTypeQualifierListOpt(DS, false /*no attributes*/); + ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed); // If we haven't already read 'static', check to see if there is one after the // type-qualifier-list. |