diff options
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index f20c72e61c..46246e64ba 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -323,7 +323,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { // Validate declspec for type-name. unsigned Specs = DS.getParsedSpecifiers(); - if (Specs == DeclSpec::PQ_None) + if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers()) Diag(Tok, diag::err_typename_requires_specqual); // Issue diagnostic and remove storage class if present. @@ -548,6 +548,21 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { case tok::kw_inline: isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec); break; + + // Gross GCC-ism that we are forced support. FIXME: make an extension? + case tok::less: + if (!DS.hasTypeSpecifier()) { + SourceLocation endProtoLoc; + llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs; + ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc); + llvm::SmallVector<DeclTy *, 8> *ProtocolDecl = + new llvm::SmallVector<DeclTy *, 8>; + DS.setProtocolQualifiers(ProtocolDecl); + Actions.FindProtocolDeclaration(Loc, + &ProtocolRefs[0], ProtocolRefs.size(), + *ProtocolDecl); + } + continue; } // If the specifier combination wasn't legal, issue a diagnostic. if (isInvalid) { @@ -872,6 +887,8 @@ bool Parser::isTypeSpecifierQualifier() const { case tok::kw___attribute: // GNU typeof support. case tok::kw_typeof: + // GNU bizarre protocol extension. FIXME: make an extension? + case tok::less: // type-specifiers case tok::kw_short: @@ -962,6 +979,9 @@ bool Parser::isDeclarationSpecifier() const { // GNU attributes. case tok::kw___attribute: + + // GNU bizarre protocol extension. FIXME: make an extension? + case tok::less: return true; // typedef-name |