[cfe-commits] r43493 - in /cfe/trunk: AST/Decl.cpp Driver/RewriteTest.cpp Parse/MinimalAction.cpp Parse/ParseDecl.cpp Parse/ParseObjc.cpp Parse/ParseStmt.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/DeclObjC.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

Steve Naroff snaroff at apple.com
Mon Oct 29 19:23:23 PDT 2007


Author: snaroff
Date: Mon Oct 29 21:23:23 2007
New Revision: 43493

URL: http://llvm.org/viewvc/llvm-project?rev=43493&view=rev
Log:

More support for rewriting ObjC intefaces. Still some edge cases to handle...


Modified:
    cfe/trunk/AST/Decl.cpp
    cfe/trunk/Driver/RewriteTest.cpp
    cfe/trunk/Parse/MinimalAction.cpp
    cfe/trunk/Parse/ParseDecl.cpp
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Parse/ParseStmt.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Mon Oct 29 21:23:23 2007
@@ -295,13 +295,13 @@
 ///
 void ObjcInterfaceDecl::addInstanceVariablesToClass(ObjcIvarDecl **ivars,
                                                     unsigned numIvars,
-                                                    SourceLocation RB) {
+                                                    SourceLocation RBrac) {
   NumIvars = numIvars;
   if (numIvars) {
     Ivars = new ObjcIvarDecl*[numIvars];
     memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
   }
-  RBracLoc = RB;
+  setLocEnd(RBrac);
 }
 
 /// ObjcAddInstanceVariablesToClassImpl - Checks for correctness of Instance 
@@ -335,7 +335,7 @@
     ClassMethods = new ObjcMethodDecl*[numClsMembers];
     memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
   }
-  EndLoc = endLoc;
+  AtEndLoc = endLoc;
 }
 
 /// addMethods - Insert instance and methods declarations into

Modified: cfe/trunk/Driver/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteTest.cpp?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Mon Oct 29 21:23:23 2007
@@ -264,6 +264,27 @@
 }
 
 void RewriteTest::RewriteInterfaceDecl(ObjcInterfaceDecl *ClassDecl) {
+
+  SourceLocation LocStart = ClassDecl->getLocStart();
+  SourceLocation LocEnd = ClassDecl->getLocEnd();
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+
+  // FIXME: need to consider empty class decls (no vars, methods)...
+  //   @interface NSConstantString : NSSimpleCString
+  //   @end
+
+  if (*endBuf != '>' && *endBuf != '}')
+    // we have an identifier - scan ahead until the end of token.
+    endBuf = strchr(endBuf, ' '); // FIXME: implement correctly.
+
+  std::string ResultStr;
+  SynthesizeObjcInternalStruct(ClassDecl, ResultStr);
+    
+  Rewrite.ReplaceText(LocStart, endBuf-startBuf+1, 
+                      ResultStr.c_str(), ResultStr.size());
+  
   int nInstanceMethods = ClassDecl->getNumInstanceMethods();
   ObjcMethodDecl **instanceMethods = ClassDecl->getInstanceMethods();
   

Modified: cfe/trunk/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/MinimalAction.cpp?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/Parse/MinimalAction.cpp Mon Oct 29 21:23:23 2007
@@ -72,7 +72,7 @@
                     IdentifierInfo *ClassName, SourceLocation ClassLoc,
                     IdentifierInfo *SuperName, SourceLocation SuperLoc,
                     IdentifierInfo **ProtocolNames, unsigned NumProtocols,
-                    AttributeList *AttrList) {
+                    SourceLocation EndProtoLoc, AttributeList *AttrList) {
   TypeNameInfo *TI =
     new TypeNameInfo(1, ClassName->getFETokenInfo<TypeNameInfo>());
 

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

==============================================================================
--- cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/Parse/ParseDecl.cpp Mon Oct 29 21:23:23 2007
@@ -407,8 +407,9 @@
           DS.Range.setEnd(Tok.getLocation());
           ConsumeToken(); // The identifier
           if (Tok.is(tok::less)) {
+            SourceLocation endProtoLoc;
             llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
-            ParseObjCProtocolReferences(ProtocolRefs);
+            ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc);
             llvm::SmallVector<DeclTy *, 8> *ProtocolDecl = 
                     new llvm::SmallVector<DeclTy *, 8>;
             DS.setProtocolQualifiers(ProtocolDecl);

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Mon Oct 29 21:23:23 2007
@@ -146,9 +146,10 @@
       return 0;
     }
     rparenLoc = ConsumeParen();
+    SourceLocation endProtoLoc;
     // Next, we need to check for any protocol references.
     if (Tok.is(tok::less)) {
-      if (ParseObjCProtocolReferences(ProtocolRefs))
+      if (ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc))
         return 0;
     }
     if (attrList) // categories don't support attributes.
@@ -183,14 +184,15 @@
   }
   // Next, we need to check for any protocol references.
   llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
+  SourceLocation endProtoLoc;
   if (Tok.is(tok::less)) {
-    if (ParseObjCProtocolReferences(ProtocolRefs))
+    if (ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc))
       return 0;
   }
   DeclTy *ClsType = Actions.ActOnStartClassInterface(
 		      atLoc, nameId, nameLoc, 
                       superClassId, superClassLoc, &ProtocolRefs[0], 
-                      ProtocolRefs.size(), attrList);
+                      ProtocolRefs.size(), endProtoLoc, attrList);
             
   if (Tok.is(tok::l_brace))
     ParseObjCClassInstanceVariables(ClsType, atLoc);
@@ -635,7 +637,8 @@
 ///     '<' identifier-list '>'
 ///
 bool Parser::ParseObjCProtocolReferences(
-  llvm::SmallVectorImpl<IdentifierInfo*> &ProtocolRefs) {
+  llvm::SmallVectorImpl<IdentifierInfo*> &ProtocolRefs, SourceLocation &endLoc) 
+{
   assert(Tok.is(tok::less) && "expected <");
   
   ConsumeToken(); // the "<"
@@ -661,9 +664,13 @@
   // Make protocol names unique.
   ProtocolRefs.erase(std::unique(ProtocolRefs.begin(), ProtocolRefs.end()), 
                      ProtocolRefs.end());
-
   // Consume the '>'.
-  return ExpectAndConsume(tok::greater, diag::err_expected_greater);
+  if (Tok.is(tok::greater)) {
+    endLoc = ConsumeAnyToken();
+    return false;
+  }
+  Diag(Tok, diag::err_expected_greater);
+  return true;
 }
 
 ///   objc-class-instance-variables:
@@ -811,15 +818,16 @@
                                                    &ProtocolRefs[0], 
                                                    ProtocolRefs.size());
   // Last, and definitely not least, parse a protocol declaration.
+  SourceLocation endProtoLoc;
   if (Tok.is(tok::less)) {
-    if (ParseObjCProtocolReferences(ProtocolRefs))
+    if (ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc))
       return 0;
   }
   
   DeclTy *ProtoType = Actions.ActOnStartProtocolInterface(AtLoc, 
                                 protocolName, nameLoc,
                                 &ProtocolRefs[0],
-                                ProtocolRefs.size());
+                                ProtocolRefs.size(), endProtoLoc);
   ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
 
   // The @ sign was already consumed by ParseObjCInterfaceDeclList().

Modified: cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseStmt.cpp?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/Parse/ParseStmt.cpp Mon Oct 29 21:23:23 2007
@@ -235,9 +235,10 @@
                                        IdentTok.getLocation(), PrevSpec,
                                        TypeRep);
     assert(!isInvalid && "First declspec can't be invalid!");
+    SourceLocation endProtoLoc;
     if (Tok.is(tok::less)) {
       llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
-      ParseObjCProtocolReferences(ProtocolRefs);
+      ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc);
       llvm::SmallVector<DeclTy *, 8> *ProtocolDecl = 
               new llvm::SmallVector<DeclTy *, 8>;
       DS.setProtocolQualifiers(ProtocolDecl);

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Mon Oct 29 21:23:23 2007
@@ -472,7 +472,7 @@
                     IdentifierInfo *ClassName, SourceLocation ClassLoc,
                     IdentifierInfo *SuperName, SourceLocation SuperLoc,
                     IdentifierInfo **ProtocolNames, unsigned NumProtocols,
-                    AttributeList *AttrList);
+                    SourceLocation EndProtoLoc, AttributeList *AttrList);
   
   virtual DeclTy *ActOnCompatiblityAlias(
                     SourceLocation AtCompatibilityAliasLoc,
@@ -482,7 +482,8 @@
   virtual DeclTy *ActOnStartProtocolInterface(
 		    SourceLocation AtProtoInterfaceLoc,
                     IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
-                    IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs);
+                    IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
+                    SourceLocation EndProtoLoc);
   
   virtual DeclTy *ActOnStartCategoryInterface(
 		    SourceLocation AtInterfaceLoc,

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Oct 29 21:23:23 2007
@@ -941,7 +941,7 @@
                     IdentifierInfo *ClassName, SourceLocation ClassLoc,
                     IdentifierInfo *SuperName, SourceLocation SuperLoc,
                     IdentifierInfo **ProtocolNames, unsigned NumProtocols,
-                    AttributeList *AttrList) {
+                    SourceLocation EndProtoLoc, AttributeList *AttrList) {
   assert(ClassName && "Missing class identifier");
   
   // Check for another declaration kind with the same name.
@@ -958,6 +958,7 @@
     if (!IDecl->isForwardDecl())
       Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
     else {
+      IDecl->setLocation(AtInterfaceLoc);
       IDecl->setForwardDecl(false);
       IDecl->AllocIntfRefProtocols(NumProtocols);
     }
@@ -994,18 +995,23 @@
       }
     }
     IDecl->setSuperClass(SuperClassEntry);
+    IDecl->setLocEnd(SuperLoc);
+  } else { // we have a root class.
+    IDecl->setLocEnd(ClassLoc);
   }
   
   /// Check then save referenced protocols
-  for (unsigned int i = 0; i != NumProtocols; i++) {
-    ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtocolNames[i]];
-    if (!RefPDecl || RefPDecl->isForwardDecl())
-      Diag(ClassLoc, diag::err_undef_protocolref,
-           ProtocolNames[i]->getName(),
-           ClassName->getName());
-    IDecl->setIntfRefProtocols((int)i, RefPDecl);
+  if (NumProtocols) {
+    for (unsigned int i = 0; i != NumProtocols; i++) {
+      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtocolNames[i]];
+      if (!RefPDecl || RefPDecl->isForwardDecl())
+        Diag(ClassLoc, diag::err_undef_protocolref,
+             ProtocolNames[i]->getName(),
+             ClassName->getName());
+      IDecl->setIntfRefProtocols((int)i, RefPDecl);
+    }
+    IDecl->setLocEnd(EndProtoLoc);
   }
-  
   return IDecl;
 }
 
@@ -1055,7 +1061,8 @@
 Sema::DeclTy *Sema::ActOnStartProtocolInterface(
                 SourceLocation AtProtoInterfaceLoc,
                 IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
-                IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) {
+                IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
+                SourceLocation EndProtoLoc) {
   assert(ProtocolName && "Missing protocol identifier");
   ObjcProtocolDecl *PDecl = ObjcProtocols[ProtocolName];
   if (PDecl) {

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Oct 29 21:23:23 2007
@@ -74,8 +74,8 @@
   
   bool ForwardDecl; // declared with @class.
   
-  SourceLocation RBracLoc; // marks the end of the instance variables.
-  SourceLocation EndLoc; // marks the end of the entire interface.
+  SourceLocation EndLoc; // marks the '>', '}', or identifier.
+  SourceLocation AtEndLoc; // marks the end of the entire interface.
 public:
   ObjcInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos,
                     IdentifierInfo *Id, bool FD = false)
@@ -137,14 +137,14 @@
   ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
   ObjcMethodDecl *lookupClassMethod(Selector &Sel);
 
-  // Location information, modeled after the Stmt API. For interfaces, 
-  // which are fairly course grain, the end refers to the '}' token.
+  // Location information, modeled after the Stmt API. 
   SourceLocation getLocStart() const { return getLocation(); } // '@'interface
-  SourceLocation getLocEnd() const { return RBracLoc; }
+  SourceLocation getLocEnd() const { return EndLoc; }
+  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
   
   // We also need to record the @end location.
-  SourceLocation getAtEndLoc() const { return EndLoc; }
-  
+  SourceLocation getAtEndLoc() const { return AtEndLoc; }
+
   /// ImplicitInterfaceDecl - check that this is an implicitely declared
   /// ObjcInterfaceDecl node. This is for legacy objective-c @implementation
   /// declaration without an @interface declaration.

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Oct 29 21:23:23 2007
@@ -465,6 +465,7 @@
     SourceLocation SuperLoc,
     IdentifierInfo **ProtocolNames, 
     unsigned NumProtocols,
+    SourceLocation EndProtoLoc,
     AttributeList *AttrList) {
     return 0;
   }
@@ -485,7 +486,8 @@
     IdentifierInfo *ProtocolName, 
     SourceLocation ProtocolLoc,
     IdentifierInfo **ProtoRefNames, 
-    unsigned NumProtoRefs) {
+    unsigned NumProtoRefs,
+    SourceLocation EndProtoLoc) {
     return 0;
   }
   // ActOnStartCategoryInterface - this action is called immdiately after
@@ -654,7 +656,7 @@
                     IdentifierInfo *ClassName, SourceLocation ClassLoc,
                     IdentifierInfo *SuperName, SourceLocation SuperLoc,
                     IdentifierInfo **ProtocolNames, unsigned NumProtocols,
-                    AttributeList *AttrList);
+                    SourceLocation EndProtoLoc, AttributeList *AttrList);
 };
 
 }  // end namespace clang

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=43493&r1=43492&r2=43493&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Oct 29 21:23:23 2007
@@ -260,7 +260,8 @@
                                           AttributeList *prefixAttrs = 0);
   void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, 
                                        SourceLocation atLoc);
-  bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierInfo*> &);
+  bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierInfo*> &,
+                                   SourceLocation &endProtoLoc);
   void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
 				  tok::ObjCKeywordKind contextKey);
   DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);





More information about the cfe-commits mailing list