diff options
| author | Chris Lattner <sabre@nondot.org> | 2008-07-26 01:18:38 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2008-07-26 01:18:38 +0000 | 
| commit | 16fac4f2adb5b08f3f2f7c400f64789fc19406ae (patch) | |
| tree | bcefe284b526b5d535c0dba4a76e4e4a3b1147cf /clang/lib/Parse/ParseDecl.cpp | |
| parent | 31236f87444b39db2857c82e22cfdb15f1fd9a16 (diff) | |
| download | bcm5719-llvm-16fac4f2adb5b08f3f2f7c400f64789fc19406ae.tar.gz bcm5719-llvm-16fac4f2adb5b08f3f2f7c400f64789fc19406ae.zip | |
Fix hte next wave of problems with protocol qualified ID:
1) reject stuff like "id<foo> short" and "<foo> short".  2) set
the declspec range correctly 3) only parse protocol qualifiers
when in objc mode.
llvm-svn: 54086
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 92 | 
1 files changed, 54 insertions, 38 deletions
| diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c9e64f4c224..98c2d897d5d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -395,47 +395,59 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {      SourceLocation Loc = Tok.getLocation();      switch (Tok.getKind()) { -      // typedef-name -    case tok::identifier: -      // This identifier can only be a typedef name if we haven't already seen -      // a type-specifier.  Without this check we misparse: -      //  typedef int X; struct Y { short X; };  as 'short int'. -      if (!DS.hasTypeSpecifier()) { -        // It has to be available as a typedef too! -        if (void *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), -                                               CurScope)) { -          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, -                                         TypeRep); -          if (isInvalid) -            break; -          // FIXME: restrict this to "id" and ObjC classnames. -          DS.SetRangeEnd(Tok.getLocation()); -          ConsumeToken(); // The identifier -          if (Tok.is(tok::less)) { -            SourceLocation endProtoLoc; -            llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs; -            ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc); -             -            // FIXME: New'ing this here seems wrong, why not have the action do -            // it? -            llvm::SmallVector<DeclTy *, 8> *ProtocolDecl =  -                    new llvm::SmallVector<DeclTy *, 8>; -            DS.setProtocolQualifiers(ProtocolDecl); -            Actions.FindProtocolDeclaration(Loc,  -                      &ProtocolRefs[0], ProtocolRefs.size(), -                      *ProtocolDecl); -          } -          continue; -        } -      } -      // FALL THROUGH.      default:      DoneWithDeclSpec:        // If this is not a declaration specifier token, we're done reading decl        // specifiers.  First verify that DeclSpec's are consistent.        DS.Finish(Diags, PP.getSourceManager(), getLang());        return; -     +         +      // typedef-name +    case tok::identifier: { +      // This identifier can only be a typedef name if we haven't already seen +      // a type-specifier.  Without this check we misparse: +      //  typedef int X; struct Y { short X; };  as 'short int'. +      if (DS.hasTypeSpecifier()) +        goto DoneWithDeclSpec; +       +      // It has to be available as a typedef too! +      void *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope); +      if (TypeRep == 0) +        goto DoneWithDeclSpec; +       +      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, +                                     TypeRep); +      if (isInvalid) +        break; +       +      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 we don't have Objective-C or a '<', this is +      // just a normal reference to a typedef name. +      if (!Tok.is(tok::less) || !getLang().ObjC1) +        continue; +       +      SourceLocation EndProtoLoc; +      llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs; +      ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc); +       +      // FIXME: New'ing this here seems wrong, why not have the action do it? +      llvm::SmallVector<DeclTy *, 8> *ProtocolDecl =  +              new llvm::SmallVector<DeclTy *, 8>; +      DS.setProtocolQualifiers(ProtocolDecl); +      Actions.FindProtocolDeclaration(Loc,  +                                      &ProtocolRefs[0], ProtocolRefs.size(), +                                      *ProtocolDecl); +       +      DS.SetRangeEnd(EndProtoLoc); + +      // Do not allow any other declspecs after the protocol qualifier list +      // "<foo,bar>short" is not allowed. +      goto DoneWithDeclSpec; +    }      // GNU attributes support.      case tok::kw___attribute:        DS.AddAttributes(ParseAttributes()); @@ -554,10 +566,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {        break;      case tok::less: -      // GCC supports types like "<SomeProtocol>" as a synonym for +      // GCC ObjC supports types like "<SomeProtocol>" as a synonym for        // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,        // but we support it. -      if (DS.hasTypeSpecifier()) +      if (DS.hasTypeSpecifier() || !getLang().ObjC1)          goto DoneWithDeclSpec;        { @@ -570,9 +582,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {          Actions.FindProtocolDeclaration(Loc,                                           &ProtocolRefs[0], ProtocolRefs.size(),                                          *ProtocolDecl); +        DS.SetRangeEnd(EndProtoLoc); +          Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id,               SourceRange(Loc, EndProtoLoc)); -        continue; +        // Do not allow any other declspecs after the protocol qualifier list +        // "<foo,bar>short" is not allowed. +        goto DoneWithDeclSpec;        }      }      // If the specifier combination wasn't legal, issue a diagnostic. | 

