]> granicus.if.org Git - clang/commitdiff
objective-c modern rewriter. More fixes related to rewriting
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 9 Mar 2012 23:46:23 +0000 (23:46 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 9 Mar 2012 23:46:23 +0000 (23:46 +0000)
ivars in the modern rewriter.

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

lib/Rewrite/RewriteModernObjC.cpp
test/Rewriter/rewrite-modern-ivars-2.mm [new file with mode: 0644]

index fdaf44dd3300a2eeb43c5db9ad990fb06f7c18f0..111de2e49587fcfa62bc0ba1ee9b69ad53975424 100644 (file)
@@ -336,6 +336,8 @@ namespace {
     
     void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
     
+    bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
+    
     void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
                                   std::string &Result);
     
@@ -3168,14 +3170,15 @@ bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf,
   return false;
 }
 
-/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
+/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
 /// It handles elaborated types, as well as enum types in the process.
-void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
-                                             std::string &Result) {
-  QualType Type = fieldDecl->getType();
-  std::string Name = fieldDecl->getNameAsString();
-
-  if (Type->isRecordType()) {
+bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 
+                                                 std::string &Result) {
+  if (Type->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(Type);
+    return RewriteObjCFieldDeclType(ElemTy, Result);
+  }
+  else if (Type->isRecordType()) {
     RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
     if (RD->isCompleteDefinition()) {
       if (RD->isStruct())
@@ -3184,23 +3187,22 @@ void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
         Result += "\n\tunion ";
       else
         assert(false && "class not allowed as an ivar type");
-  
+      
       Result += RD->getName();
       if (TagsDefinedInIvarDecls.count(RD)) {
         // This struct is already defined. Do not write its definition again.
-        Result += " "; Result += Name; Result += ";\n";
-        return;
+        Result += " ";
+        return true;
       }
       TagsDefinedInIvarDecls.insert(RD);
       Result += " {\n";
       for (RecordDecl::field_iterator i = RD->field_begin(), 
-          e = RD->field_end(); i != e; ++i) {
+           e = RD->field_end(); i != e; ++i) {
         FieldDecl *FD = *i;
         RewriteObjCFieldDecl(FD, Result);
       }
       Result += "\t} "; 
-      Result += Name; Result += ";\n";
-      return;
+      return true;
     }
   }
   else if (Type->isEnumeralType()) {
@@ -3210,8 +3212,8 @@ void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
       Result += ED->getName();
       if (TagsDefinedInIvarDecls.count(ED)) {
         // This enum is already defined. Do not write its definition again.
-        Result += " "; Result += Name; Result += ";\n";
-        return;
+        Result += " ";
+        return true;
       }
       TagsDefinedInIvarDecls.insert(ED);
       
@@ -3224,19 +3226,43 @@ void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
         Result += ",\n";
       }
       Result += "\t} "; 
-      Result += Name; Result += ";\n";
-      return;
+      return true;
     }
   }
   
   Result += "\t";
   convertObjCTypeToCStyleType(Type);
+  return false;
+}
+
+
+/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
+/// It handles elaborated types, as well as enum types in the process.
+void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
+                                             std::string &Result) {
+  QualType Type = fieldDecl->getType();
+  std::string Name = fieldDecl->getNameAsString();
   
-  Type.getAsStringInternal(Name, Context->getPrintingPolicy());
+  bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 
+  if (!EleboratedType)
+    Type.getAsStringInternal(Name, Context->getPrintingPolicy());
   Result += Name;
   if (fieldDecl->isBitField()) {
     Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
   }
+  else if (EleboratedType && Type->isArrayType()) {
+    CanQualType CType = Context->getCanonicalType(Type);
+    while (isa<ArrayType>(CType)) {
+      if (const ConstantArrayType *CAT = Context->getAsConstantArrayType(CType)) {
+        Result += "[";
+        llvm::APInt Dim = CAT->getSize();
+        Result += utostr(Dim.getZExtValue());
+        Result += "]";
+      }
+      CType = CType->getAs<ArrayType>()->getElementType();
+    }
+  }
+  
   Result += ";\n";
 }
 
diff --git a/test/Rewriter/rewrite-modern-ivars-2.mm b/test/Rewriter/rewrite-modern-ivars-2.mm
new file mode 100644 (file)
index 0000000..ead8e8f
--- /dev/null
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+
+@interface B @end
+
+@interface A {
+  struct s0 {
+    int f0;
+    int f1;
+  } f0;
+  id f1;
+__weak B *f2;
+  int f3 : 5;
+  struct s1 {
+    int *f0;
+    int *f1;
+  } f4[2][1];
+}
+@end
+
+@interface C : A
+@property int p3;
+@end
+
+@implementation C
+@synthesize p3 = _p3;
+@end
+
+@interface A()
+@property int p0;
+@property (assign) __strong id p1;
+@property (assign) __weak id p2;
+@end
+
+// FIXME: Check layout for this class, once it is clear what the right
+// answer is.
+@implementation A
+@synthesize p0 = _p0;
+@synthesize p1 = _p1;
+@synthesize p2 = _p2;
+@end
+
+@interface D : A
+@property int p3;
+@end
+
+// FIXME: Check layout for this class, once it is clear what the right
+// answer is.
+@implementation D
+@synthesize p3 = _p3;
+@end
+
+typedef unsigned short UInt16;
+
+
+typedef signed char BOOL;
+typedef unsigned int FSCatalogInfoBitmap;
+
+@interface NSFileLocationComponent {
+    @private
+
+    id _specifierOrStandardizedPath;
+    BOOL _carbonCatalogInfoAndNameAreValid;
+    FSCatalogInfoBitmap _carbonCatalogInfoMask;
+    id _name;
+    id _containerComponent;
+    id _presentableName;
+    id _iconAsAttributedString;
+}
+@end
+
+@implementation NSFileLocationComponent @end
+