[cfe-commits] r54086 - /cfe/trunk/lib/Parse/ParseDecl.cpp

Chris Lattner sabre at nondot.org
Fri Jul 25 18:18:38 PDT 2008


Author: lattner
Date: Fri Jul 25 20:18:38 2008
New Revision: 54086

URL: http://llvm.org/viewvc/llvm-project?rev=54086&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Parse/ParseDecl.cpp

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=54086&r1=54085&r2=54086&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Jul 25 20:18:38 2008
@@ -395,47 +395,59 @@
     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 @@
       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 @@
         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.





More information about the cfe-commits mailing list