objective-c modern rewriter. More fixes related to rewriting
ivars in the modern rewriter.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152451 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index fdaf44d..111de2e 100644
--- a/lib/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Rewrite/RewriteModernObjC.cpp
@@ -336,6 +336,8 @@
     
     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 @@
   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 @@
         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 @@
       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 @@
         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";
 }