diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-08-07 23:02:44 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-08-07 23:02:44 +0000 | 
| commit | 51ece4aae5857052d224ce52277924c74685714e (patch) | |
| tree | ca13cf9e2e8c2499f61f1246e455efd2804abd36 /lib/Parse/ParseDecl.cpp | |
| parent | c192b3dcffd5e672a2b2e1730e2440febb4fb192 (diff) | |
Notes
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
| -rw-r--r-- | lib/Parse/ParseDecl.cpp | 66 | 
1 files changed, 48 insertions, 18 deletions
| diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d843e801b634..f46af889e25d 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -365,7 +365,8 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,    // These may refer to the function arguments, but need to be parsed early to    // participate in determining whether it's a redeclaration.    std::unique_ptr<ParseScope> PrototypeScope; -  if (AttrName->isStr("enable_if") && D && D->isFunctionDeclarator()) { +  if (normalizeAttrName(AttrName->getName()) == "enable_if" && +      D && D->isFunctionDeclarator()) {      DeclaratorChunk::FunctionTypeInfo FTI = D->getFunctionTypeInfo();      PrototypeScope.reset(new ParseScope(this, Scope::FunctionPrototypeScope |                                          Scope::FunctionDeclarationScope | @@ -2144,8 +2145,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,    if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) {      Diag(Tok, diag::err_expected_type);      DS.SetTypeSpecError(); -  } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && -             !DS.hasAttributes()) { +  } else if (Specs == DeclSpec::PQ_None && !DS.hasAttributes()) {      Diag(Tok, diag::err_typename_requires_specqual);      if (!DS.hasTypeSpecifier())        DS.SetTypeSpecError(); @@ -2602,6 +2602,7 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,  /// [C11]   alignment-specifier declaration-specifiers[opt]  /// [GNU]   attributes declaration-specifiers[opt]  /// [Clang] '__module_private__' declaration-specifiers[opt] +/// [ObjC1] '__kindof' declaration-specifiers[opt]  ///  ///       storage-class-specifier: [C99 6.7.1]  ///         'typedef' @@ -2886,12 +2887,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,        DS.SetRangeEnd(Tok.getAnnotationEndLoc());        ConsumeToken(); // The typename -      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' -      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an -      // Objective-C interface. -      if (Tok.is(tok::less) && getLangOpts().ObjC1) -        ParseObjCProtocolQualifiers(DS); -        continue;      } @@ -2997,11 +2992,19 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,        DS.SetRangeEnd(Tok.getLocation());        ConsumeToken(); // The identifier -      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' -      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an -      // Objective-C interface. -      if (Tok.is(tok::less) && getLangOpts().ObjC1) -        ParseObjCProtocolQualifiers(DS); +      // Objective-C supports type arguments and protocol references +      // following an Objective-C object or object pointer +      // type. Handle either one of them. +      if (Tok.is(tok::less) && getLangOpts().ObjC1) { +        SourceLocation NewEndLoc; +        TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers( +                                  Loc, TypeRep, /*consumeLastToken=*/true, +                                  NewEndLoc); +        if (NewTypeRep.isUsable()) { +          DS.UpdateTypeRep(NewTypeRep.get()); +          DS.SetRangeEnd(NewEndLoc); +        } +      }        // Need to support trailing type qualifiers (e.g. "id<p> const").        // If a type specifier follows, it will be diagnosed elsewhere. @@ -3082,6 +3085,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,        ParseNullabilityTypeSpecifiers(DS.getAttributes());        continue; +    // Objective-C 'kindof' types. +    case tok::kw___kindof: +      DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc, +                                nullptr, 0, AttributeList::AS_Keyword); +      (void)ConsumeToken(); +      continue; +      // storage-class-specifier      case tok::kw_typedef:        isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc, @@ -3418,10 +3428,19 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,        if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)          goto DoneWithDeclSpec; -      if (!ParseObjCProtocolQualifiers(DS)) -        Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) -          << FixItHint::CreateInsertion(Loc, "id") -          << SourceRange(Loc, DS.getSourceRange().getEnd()); +      SourceLocation StartLoc = Tok.getLocation(); +      SourceLocation EndLoc; +      TypeResult Type = parseObjCProtocolQualifierType(EndLoc); +      if (Type.isUsable()) { +        if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, StartLoc, +                               PrevSpec, DiagID, Type.get(), +                               Actions.getASTContext().getPrintingPolicy())) +          Diag(StartLoc, DiagID) << PrevSpec; +         +        DS.SetRangeEnd(EndLoc); +      } else { +        DS.SetTypeSpecError(); +      }        // Need to support trailing type qualifiers (e.g. "id<p> const").        // If a type specifier follows, it will be diagnosed elsewhere. @@ -4335,6 +4354,8 @@ bool Parser::isTypeSpecifierQualifier() {    case tok::kw__Nullable:    case tok::kw__Null_unspecified: +  case tok::kw___kindof: +    case tok::kw___private:    case tok::kw___local:    case tok::kw___global: @@ -4515,6 +4536,8 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {    case tok::kw__Nullable:    case tok::kw__Null_unspecified: +  case tok::kw___kindof: +    case tok::kw___private:    case tok::kw___local:    case tok::kw___global: @@ -4752,6 +4775,13 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,        ParseNullabilityTypeSpecifiers(DS.getAttributes());        continue; +    // Objective-C 'kindof' types. +    case tok::kw___kindof: +      DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc, +                                nullptr, 0, AttributeList::AS_Keyword); +      (void)ConsumeToken(); +      continue; +      case tok::kw___attribute:        if (AttrReqs & AR_GNUAttributesParsedAndRejected)          // When GNU attributes are expressly forbidden, diagnose their usage. | 
