More of Sema to implement initialization of
ivar of c++ object types.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102500 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index f22c1ad..fb65862 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1592,10 +1592,9 @@
   void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
   
   /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
-  /// construction (construct=true) or destruction (construct=false)
+  /// initialization.
   void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
-                                    llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
-                                    bool construct=true);
+                                  llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.
 public:
@@ -2510,6 +2509,9 @@
   bool SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
                                    CXXBaseOrMemberInitializer **Initializers,
                                    unsigned NumInitializers, bool AnyErrors);
+  
+  void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
+                           
 
   /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
   /// mark all the non-trivial destructors of its members and bases as
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index f6ff400..854f204 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5699,3 +5699,44 @@
     MarkVirtualMembersReferenced(Loc, Base);
   }
 }
+
+/// SetIvarInitializers - This routine builds initialization ASTs for the
+/// Objective-C implementation whose ivars need be initialized.
+void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
+  if (!getLangOptions().CPlusPlus)
+    return;
+  if (const ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
+    llvm::SmallVector<ObjCIvarDecl*, 8> ivars;
+    CollectIvarsToConstructOrDestruct(OID, ivars);
+    if (ivars.empty())
+      return;
+    llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
+    for (unsigned i = 0; i < ivars.size(); i++) {
+      FieldDecl *Field = ivars[i];
+      CXXBaseOrMemberInitializer *Member;
+      InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field);
+      InitializationKind InitKind = 
+        InitializationKind::CreateDefault(ObjCImplementation->getLocation());
+      
+      InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0);
+      Sema::OwningExprResult MemberInit = 
+        InitSeq.Perform(*this, InitEntity, InitKind, 
+                        Sema::MultiExprArg(*this, 0, 0));
+      MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+      // Note, MemberInit could actually come back empty if no initialization 
+      // is required (e.g., because it would call a trivial default constructor)
+      if (!MemberInit.get() || MemberInit.isInvalid())
+        continue;
+      
+      Member =
+        new (Context) CXXBaseOrMemberInitializer(Context,
+                                                 Field, SourceLocation(),
+                                                 SourceLocation(),
+                                                 MemberInit.takeAs<Expr>(),
+                                                 SourceLocation());
+      AllToInit.push_back(Member);
+    }
+    ObjCImplementation->setIvarInitializers(Context, 
+                                            AllToInit.data(), AllToInit.size());
+  }
+}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 1324e05..8032030 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1441,6 +1441,7 @@
           IDecl = IDecl->getSuperClass();
         }
     }
+    SetIvarInitializers(IC);
   } else if (ObjCCategoryImplDecl* CatImplClass =
                                    dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
     CatImplClass->setAtEndRange(AtEnd);
@@ -1800,23 +1801,15 @@
 }
 
 /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
-/// construction (construct=true) or destruction (construct=false)
-///
+/// initialization.
 void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
-                                    llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
-                                    bool construct) {
-  if (!getLangOptions().CPlusPlus)
-    return;
+                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
   for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
        E = OI->ivar_end(); I != E; ++I) {
     ObjCIvarDecl *Iv = (*I);
     QualType QT = Context.getBaseElementType(Iv->getType());
-    if (const RecordType *RT = QT->getAs<RecordType>()) {
-      if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
-        if (construct && !RD->hasTrivialConstructor() ||
-            !construct && !RD->hasTrivialDestructor())
-          Ivars.push_back(*I);
-    }
+    if (isa<RecordType>(QT))
+      Ivars.push_back(*I);
   }
   
   // Find ivars to construct/destruct in class extension.
@@ -1825,12 +1818,8 @@
          E = CDecl->ivar_end(); I != E; ++I) {
       ObjCIvarDecl *Iv = (*I);
       QualType QT = Context.getBaseElementType(Iv->getType());
-      if (const RecordType *RT = QT->getAs<RecordType>()) {
-        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
-          if (construct && !RD->hasTrivialConstructor() ||
-              !construct && !RD->hasTrivialDestructor())
-            Ivars.push_back(*I);
-      }
+      if (isa<RecordType>(QT))
+        Ivars.push_back(*I);
     }
   }
   
@@ -1841,12 +1830,22 @@
          E = ImplDecl->ivar_end(); I != E; ++I) {
       ObjCIvarDecl *Iv = (*I);
       QualType QT = Context.getBaseElementType(Iv->getType());
-      if (const RecordType *RT = QT->getAs<RecordType>()) {
-        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
-          if (construct && !RD->hasTrivialConstructor() ||
-              !construct && !RD->hasTrivialDestructor())
-            Ivars.push_back(*I);
-      }
+      if (isa<RecordType>(QT))
+        Ivars.push_back(*I);
     }
   }
 }
+
+void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
+                                    CXXBaseOrMemberInitializer ** initializers,
+                                                 unsigned numInitializers) {
+  if (numInitializers > 0) {
+    NumIvarInitializers = numInitializers;
+    CXXBaseOrMemberInitializer **ivarInitializers =
+    new (C) CXXBaseOrMemberInitializer*[NumIvarInitializers];
+    memcpy(ivarInitializers, initializers,
+           numInitializers * sizeof(CXXBaseOrMemberInitializer*));
+    IvarInitializers = ivarInitializers;
+  }
+}
+