]> granicus.if.org Git - clang/commitdiff
Fixed a problem caused by foreward @class use
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 14 Feb 2009 20:13:28 +0000 (20:13 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 14 Feb 2009 20:13:28 +0000 (20:13 +0000)
which consequently caused a Seg fault. during meta-data
generation. It also addresses an issue related to
late binding of newly synthesize ivars (when we support it).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64563 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/CodeGen/CGObjCMac.cpp
test/CodeGenObjC/class-type.m [new file with mode: 0644]

index 3f9e6bf213c6088b98f57e14e7e54f4f53cd4d6e..c09c2573bda0ba918ed6073bb8a50308e0be3396 100644 (file)
@@ -263,6 +263,7 @@ public:
   /// specified typename decl.
   QualType getTypedefType(TypedefDecl *Decl);
   QualType getObjCInterfaceType(ObjCInterfaceDecl *Decl);
+  QualType buildObjCInterfaceType(ObjCInterfaceDecl *Decl);
 
   QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, 
                                    IdentifierInfo *Name = 0);
index d4fe26ed6782e73de0c2c1084bb8d833d3ddffbd..652fcdf8080c0f5d8d10d50dbbdf41e790949b1e 100644 (file)
@@ -1210,6 +1210,18 @@ QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
   return QualType(Decl->TypeForDecl, 0);
 }
 
+/// buildObjCInterfaceType - Returns a new type for the interface
+/// declaration, regardless. It also removes any previously built 
+/// record declaration so caller can rebuild it.
+QualType ASTContext::buildObjCInterfaceType(ObjCInterfaceDecl *Decl) {
+  const RecordDecl *&RD = ASTRecordForInterface[Decl];
+  if (RD)
+    RD = 0;
+  Decl->TypeForDecl = new(*this,8) ObjCInterfaceType(Type::ObjCInterface, Decl);
+  Types.push_back(Decl->TypeForDecl);
+  return QualType(Decl->TypeForDecl, 0);
+}
+
 /// \brief Retrieve the template type parameter type for a template
 /// parameter with the given depth, index, and (optionally) name.
 QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, 
index 360eac0535adecd2dd649d4f1707a85fd4ac198e..4ec0e7c888348db97bbe7be50880ce9e32b8cc7b 100644 (file)
@@ -1370,7 +1370,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
                      Interface->protocol_begin(),
                      Interface->protocol_end());
   const llvm::Type *InterfaceTy = 
-   CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
+   CGM.getTypes().ConvertType(CGM.getContext().buildObjCInterfaceType(Interface));
   unsigned Flags = eClassFlags_Factory;
   unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy);
 
@@ -3717,7 +3717,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
       const_cast<ObjCInterfaceDecl*>(ID->getClassInterface())) {
     // FIXME. Share this with the one in EmitIvarList.
     const llvm::Type *InterfaceTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID));
+    CGM.getTypes().ConvertType(CGM.getContext().buildObjCInterfaceType(OID));
     const llvm::StructLayout *Layout =
     CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
     
diff --git a/test/CodeGenObjC/class-type.m b/test/CodeGenObjC/class-type.m
new file mode 100644 (file)
index 0000000..12a8a31
--- /dev/null
@@ -0,0 +1,24 @@
+// RUN: clang -triple x86_64-unknown-unknown -emit-llvm -o %t %s
+
+@interface I0 {
+  struct { int a; } a;
+}
+@end 
+
+@class I2;
+
+@interface I1 {
+  I2 *_imageBrowser;
+}
+@end 
+
+@implementation I1 
+@end 
+
+@interface I2 : I0 
+@end 
+
+@implementation I2 
+@end 
+
+