[cfe-commits] r119980 - /cfe/trunk/lib/CodeGen/CGExprConstant.cpp

Anders Carlsson andersca at mac.com
Mon Nov 22 10:42:14 PST 2010


Author: andersca
Date: Mon Nov 22 12:42:14 2010
New Revision: 119980

URL: http://llvm.org/viewvc/llvm-project?rev=119980&view=rev
Log:
Refactor the null-initialization for record types and make it handle bases that aren't i8 arrays.

Modified:
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=119980&r1=119979&r2=119980&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Mon Nov 22 12:42:14 2010
@@ -964,8 +964,7 @@
     for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
          E = RD->bases_end(); I != E; ++I) {
       if (I->isVirtual()) {
-        // FIXME: We should initialize null pointer to data members in virtual
-        // bases here.
+        // Ignore virtual bases.
         continue;
       }
       
@@ -1015,6 +1014,89 @@
   }
 }
 
+static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
+                                        const CXXRecordDecl *RD) {
+  QualType T = CGM.getContext().getTagDeclType(RD);
+
+  const llvm::StructType *STy =
+    cast<llvm::StructType>(CGM.getTypes().ConvertTypeForMem(T));
+  unsigned NumElements = STy->getNumElements();
+  std::vector<llvm::Constant *> Elements(NumElements);
+
+  const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD);
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    if (I->isVirtual()) {
+      // Ignore virtual bases.
+      continue;
+    }
+
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Ignore empty bases.
+    if (BaseDecl->isEmpty())
+      continue;
+    
+    // Ignore bases that don't have any pointer to data members.
+    if (CGM.getTypes().isZeroInitializable(BaseDecl))
+      continue;
+
+    unsigned BaseFieldNo = Layout.getNonVirtualBaseLLVMFieldNo(BaseDecl);
+    const llvm::Type *BaseTy = STy->getElementType(BaseFieldNo);
+
+    if (isa<llvm::StructType>(BaseTy)) {
+      // We can just emit the base as a null constant.
+      Elements[BaseFieldNo] = EmitNullConstant(CGM, BaseDecl);
+      continue;
+    }
+
+    // Some bases are represented as arrays of i8 if the size of the
+    // base is smaller than its corresponding LLVM type.
+    // Figure out how many elements this base array has.
+    const llvm::ArrayType *BaseArrayTy =  cast<llvm::ArrayType>(BaseTy);
+    unsigned NumBaseElements = BaseArrayTy->getNumElements();
+
+    // Fill in null data member pointers.
+    std::vector<llvm::Constant *> BaseElements(NumBaseElements);
+    FillInNullDataMemberPointers(CGM, I->getType(), BaseElements, 0);
+
+    // Now go through all other elements and zero them out.
+    if (NumBaseElements) {
+      const llvm::Type* Int8Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+      llvm::Constant *Zero = llvm::Constant::getNullValue(Int8Ty);
+      for (unsigned I = 0; I != NumBaseElements; ++I) {
+        if (!BaseElements[I])
+          BaseElements[I] = Zero;
+      }
+    }
+      
+    Elements[BaseFieldNo] = llvm::ConstantArray::get(BaseArrayTy, BaseElements);
+  }
+
+  // Visit all fields.
+  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+       I != E; ++I) {
+    const FieldDecl *FD = *I;
+    
+    // Ignore bit fields.
+    if (FD->isBitField())
+      continue;
+    
+    unsigned FieldNo = Layout.getLLVMFieldNo(FD);
+    Elements[FieldNo] = CGM.EmitNullConstant(FD->getType());
+  }
+
+  // Now go through all other fields and zero them out.
+  for (unsigned i = 0; i != NumElements; ++i) {
+    if (!Elements[i])
+      Elements[i] = llvm::Constant::getNullValue(STy->getElementType(i));
+  }
+  
+  return llvm::ConstantStruct::get(STy, Elements);
+}
+
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
   if (getTypes().isZeroInitializable(T))
     return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
@@ -1036,79 +1118,7 @@
 
   if (const RecordType *RT = T->getAs<RecordType>()) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-    const llvm::StructType *STy =
-      cast<llvm::StructType>(getTypes().ConvertTypeForMem(T));
-    unsigned NumElements = STy->getNumElements();
-    std::vector<llvm::Constant *> Elements(NumElements);
-
-    const CGRecordLayout &Layout = getTypes().getCGRecordLayout(RD);
-    
-    // Go through all bases and fill in any null pointer to data members.
-    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-      if (I->isVirtual()) {
-        // FIXME: We should initialize null pointer to data members in virtual
-        // bases here.
-        continue;
-      }
-
-      const CXXRecordDecl *BaseDecl = 
-        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
-      // Ignore empty bases.
-      if (BaseDecl->isEmpty())
-        continue;
-
-      // Ignore bases that don't have any pointer to data members.
-      if (getTypes().isZeroInitializable(BaseDecl))
-        continue;
-
-      // Currently, all bases are arrays of i8. Figure out how many elements
-      // this base array has.
-      unsigned BaseFieldNo = Layout.getNonVirtualBaseLLVMFieldNo(BaseDecl);
-      const llvm::ArrayType *BaseArrayTy =
-        cast<llvm::ArrayType>(STy->getElementType(BaseFieldNo));
-      
-      unsigned NumBaseElements = BaseArrayTy->getNumElements();
-      std::vector<llvm::Constant *> BaseElements(NumBaseElements);
-      
-      // Now fill in null data member pointers.
-      FillInNullDataMemberPointers(*this, I->getType(), BaseElements, 0);
-      
-      // Now go through all other elements and zero them out.
-      if (NumBaseElements) {
-        llvm::Constant *Zero =
-          llvm::ConstantInt::get(llvm::Type::getInt8Ty(getLLVMContext()), 0);
-        
-        for (unsigned I = 0; I != NumBaseElements; ++I) {
-          if (!BaseElements[I])
-            BaseElements[I] = Zero;
-        }
-      }
-      
-      Elements[BaseFieldNo] = llvm::ConstantArray::get(BaseArrayTy, 
-                                                       BaseElements);
-    }
-      
-    for (RecordDecl::field_iterator I = RD->field_begin(),
-         E = RD->field_end(); I != E; ++I) {
-      const FieldDecl *FD = *I;
-      
-      // Ignore bit fields.
-      if (FD->isBitField())
-        continue;
-
-      unsigned FieldNo = Layout.getLLVMFieldNo(FD);
-      Elements[FieldNo] = EmitNullConstant(FD->getType());
-    }
-    
-    // Now go through all other fields and zero them out.
-    for (unsigned i = 0; i != NumElements; ++i) {
-      if (!Elements[i])
-        Elements[i] = llvm::Constant::getNullValue(STy->getElementType(i));
-    }
-    
-    return llvm::ConstantStruct::get(STy, Elements);
+    return ::EmitNullConstant(*this, RD);
   }
 
   assert(T->isMemberPointerType() && "Should only see member pointers here!");





More information about the cfe-commits mailing list