[cfe-commits] r53846 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/Sema/Sema.cpp lib/Sema/SemaDeclObjC.cpp test/Sema/objc-interface-1.m

Chris Lattner sabre at nondot.org
Mon Jul 21 00:06:49 PDT 2008


Author: lattner
Date: Mon Jul 21 02:06:49 2008
New Revision: 53846

URL: http://llvm.org/viewvc/llvm-project?rev=53846&view=rev
Log:
Switch initialization of the protocol list for an interface decl to use
the standard "set these as the list of protocols" interface instead of a 
strange "set this as the size and then set each one to the value" interface.
The problem with the later is that it a) is completely different from 
everything else, b) is awkward, and c) doesn't handle the case when a
referenced protocol is invalid: it set it to null.

This meant that all clients downstream would have to handle null protocols
in the protocol list, and empirically they didn't.  Fix this by not setting
invalid protocols in the referenced protocol list, fixing the crash on 
test/Sema/objc-interface-1.m

While I'm at it, clean up some locations so that we produce:

t.m:1:25: error: cannot find interface declaration for 'NSObject', superclass of 'NSWhatever'
@interface NSWhatever : NSObject <NSCopying>
~~~~~~~~~~~~~~~~~~~~~   ^

instead of:

t.m:1:1: error: cannot find interface declaration for 'NSObject', superclass of 'NSWhatever'
@interface NSWhatever : NSObject <NSCopying>
^



Added:
    cfe/trunk/test/Sema/objc-interface-1.m
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Jul 21 02:06:49 2008
@@ -257,10 +257,8 @@
   SourceLocation EndLoc; // marks the '>', '}', or identifier.
   SourceLocation AtEndLoc; // marks the end of the entire interface.
 
-  ObjCInterfaceDecl(SourceLocation atLoc,
-                    unsigned numRefProtos,
-                    IdentifierInfo *Id, SourceLocation CLoc,
-                    bool FD, bool isInternal)
+  ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
+                    SourceLocation CLoc, bool FD, bool isInternal)
     : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
       TypeForDecl(0), SuperClass(0),
       ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0), 
@@ -270,7 +268,6 @@
       CategoryList(0), PropertyDecl(0), NumPropertyDecl(0),
       ForwardDecl(FD), InternalInterface(isInternal),
       ClassLoc(CLoc) {
-        AllocIntfRefProtocols(numRefProtos);
       }
   
   virtual ~ObjCInterfaceDecl();
@@ -282,22 +279,11 @@
 
   static ObjCInterfaceDecl *Create(ASTContext &C,
                                    SourceLocation atLoc,
-                                   unsigned numRefProtos, 
                                    IdentifierInfo *Id, 
                                    SourceLocation ClassLoc = SourceLocation(),
                                    bool ForwardDecl = false,
                                    bool isInternal = false);
   
-  // This is necessary when converting a forward declaration to a definition.
-  void AllocIntfRefProtocols(unsigned numRefProtos) {
-    if (numRefProtos) {
-      ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
-      memset(ReferencedProtocols, '\0',
-             numRefProtos*sizeof(ObjCProtocolDecl*));
-      NumReferencedProtocols = numRefProtos;
-    }
-  }
-  
   ObjCProtocolDecl **getReferencedProtocols() const { 
     return ReferencedProtocols; 
   }
@@ -333,7 +319,12 @@
   classmeth_iterator classmeth_end() const {
     return ClassMethods+NumClassMethods;
   }
+
   
+  /// addReferencedProtocols - Set the list of protocols that this interface
+  /// implements.
+  void addReferencedProtocols(ObjCProtocolDecl **OID, unsigned numRefProtos);
+   
   void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
                                    SourceLocation RBracLoc);
 
@@ -358,11 +349,6 @@
   bool isForwardDecl() const { return ForwardDecl; }
   void setForwardDecl(bool val) { ForwardDecl = val; }
   
-  void setIntfRefProtocols(unsigned idx, ObjCProtocolDecl *OID) {
-    assert((idx < NumReferencedProtocols) && "index out of range");
-    ReferencedProtocols[idx] = OID;
-  }
-  
   ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
   void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
   

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=53846&r1=53845&r2=53846&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Mon Jul 21 02:06:49 2008
@@ -52,13 +52,11 @@
 
 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
                                              SourceLocation atLoc,
-                                             unsigned numRefProtos,
                                              IdentifierInfo *Id, 
                                              SourceLocation ClassLoc,
                                              bool ForwardDecl, bool isInternal){
   void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
-  return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
-                                     Id, ClassLoc, ForwardDecl,
+  return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
                                      isInternal);
 }
 
@@ -282,6 +280,18 @@
   return 0;
 }
 
+/// addReferencedProtocols - Set the list of protocols that this interface
+/// implements.
+void ObjCInterfaceDecl::addReferencedProtocols(ObjCProtocolDecl **OID, 
+                                               unsigned numRefProtos) {
+  assert(NumReferencedProtocols == 0 && "refproto already set!");
+  NumReferencedProtocols = numRefProtos;
+  if (numRefProtos) {
+    ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
+    memcpy(ReferencedProtocols, OID, numRefProtos*sizeof(ObjCProtocolDecl*));
+  }
+}
+
 /// ObjCAddInstanceVariablesToClass - Inserts instance variables
 /// into ObjCInterfaceDecl's fields.
 ///

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=53846&r1=53845&r2=53846&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Jul 21 02:06:49 2008
@@ -53,7 +53,8 @@
   if (!PP.getLangOptions().ObjC1) return;
   
   // Synthesize "typedef struct objc_selector *SEL;"
-  RecordDecl *SelTag = RecordDecl::Create(Context, TagDecl::TK_struct, CurContext,
+  RecordDecl *SelTag = RecordDecl::Create(Context, TagDecl::TK_struct,
+                                          CurContext,
                                           SourceLocation(), 
                                           &Context.Idents.get("objc_selector"),
                                           0);
@@ -82,7 +83,7 @@
   Context.setObjCClassType(ClassTypedef);
   // Synthesize "@class Protocol;
   ObjCInterfaceDecl *ProtocolDecl =
-    ObjCInterfaceDecl::Create(Context, SourceLocation(), 0, 
+    ObjCInterfaceDecl::Create(Context, SourceLocation(),
                               &Context.Idents.get("Protocol"), 
                               SourceLocation(), true);
   Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=53846&r1=53845&r2=53846&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Jul 21 02:06:49 2008
@@ -92,11 +92,9 @@
     else {
       IDecl->setLocation(AtInterfaceLoc);
       IDecl->setForwardDecl(false);
-      IDecl->AllocIntfRefProtocols(NumProtocols);
     }
-  }
-  else {
-    IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc, NumProtocols,
+  } else {
+    IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc,
                                       ClassName, ClassLoc);
   
     ObjCInterfaceDecls[ClassName] = IDecl;
@@ -118,10 +116,10 @@
       SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 
                               
       if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
-        Diag(AtInterfaceLoc, diag::err_undef_superclass, 
+        Diag(SuperLoc, diag::err_undef_superclass, 
              SuperClassEntry ? SuperClassEntry->getName() 
                              : SuperName->getName(),
-             ClassName->getName()); 
+             ClassName->getName(), SourceRange(AtInterfaceLoc, ClassLoc));
       }
     }
     IDecl->setSuperClass(SuperClassEntry);
@@ -133,14 +131,18 @@
   
   /// Check then save referenced protocols
   if (NumProtocols) {
+    llvm::SmallVector<ObjCProtocolDecl*, 8> RefProtos;
     for (unsigned int i = 0; i != NumProtocols; i++) {
       ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtocolNames[i]];
       if (!RefPDecl || RefPDecl->isForwardDecl())
-        Diag(ClassLoc, diag::warn_undef_protocolref,
+        Diag(EndProtoLoc, diag::warn_undef_protocolref,
              ProtocolNames[i]->getName(),
              ClassName->getName());
-      IDecl->setIntfRefProtocols(i, RefPDecl);
+      else
+        RefProtos.push_back(RefPDecl);
     }
+    if (!RefProtos.empty())
+      IDecl->addReferencedProtocols(&RefProtos[0], RefProtos.size());
     IDecl->setLocEnd(EndProtoLoc);
   }
   return IDecl;
@@ -350,26 +352,23 @@
 Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
                                        DeclTy *MergeItsProtocols) {
   Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols);
-  if (ObjCInterfaceDecl *MDecl = 
-      dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
+  if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
     for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
          E = MDecl->protocol_end(); P != E; ++P)
-      MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
       // Merge properties of class (*P) into IDECL's
-      ;
+      MergeOneProtocolPropertiesIntoClass(IDecl, *P);
+    
     // Go thru the list of protocols for this class and recursively merge
     // their properties into this class as well.
     for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
          E = IDecl->protocol_end(); P != E; ++P)
-      MergeProtocolPropertiesIntoClass(IDecl, (*P));
-  }
-  else if (ObjCProtocolDecl *MDecl = 
-           dyn_cast<ObjCProtocolDecl>(ClassDecl))
+      MergeProtocolPropertiesIntoClass(IDecl, *P);
+  } else {
+    ObjCProtocolDecl *MDecl = cast<ObjCProtocolDecl>(ClassDecl);
     for (ObjCProtocolDecl::protocol_iterator P = MDecl->protocol_begin(),
          E = MDecl->protocol_end(); P != E; ++P)
       MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
-  else
-    assert(false && "MergeProtocolPropertiesIntoClass - bad object kind");
+  }
 }
 
 /// ActOnForwardProtocolDeclaration - 
@@ -509,7 +508,7 @@
   if (!IDecl) {
     // Legacy case of @implementation with no corresponding @interface.
     // Build, chain & install the interface decl into the identifier.
-    IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, 0, ClassName, 
+    IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, ClassName, 
                                       ClassLoc, false, true);
     ObjCInterfaceDecls[ClassName] = IDecl;
     IDecl->setSuperClass(SDecl);
@@ -726,7 +725,7 @@
     }
     ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 
     if (!IDecl) {  // Not already seen?  Make a forward decl.
-      IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, 0, IdentList[i],
+      IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, IdentList[i],
                                         SourceLocation(), true);
       ObjCInterfaceDecls[IdentList[i]] = IDecl;
 

Added: cfe/trunk/test/Sema/objc-interface-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-interface-1.m?rev=53846&view=auto

==============================================================================
--- cfe/trunk/test/Sema/objc-interface-1.m (added)
+++ cfe/trunk/test/Sema/objc-interface-1.m Mon Jul 21 02:06:49 2008
@@ -0,0 +1,8 @@
+// RUN: clang %s -fsyntax-only -verify
+// rdar://5957506
+
+ at interface NSWhatever :
+NSObject     // expected-error {{cannot find interface declaration for 'NSObject'}}
+<NSCopying>  // expected-error {{cannot find protocol definition for 'NSCopying'}}
+ at end
+





More information about the cfe-commits mailing list