From 36c49e3f258dced101949edabd72e9bc3f1dedc4 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Fri, 17 Sep 2010 15:54:40 +0000
Subject: Vendor import of clang r114020 (from the release_28 branch):
 http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020

Approved by:	rpaulo (mentor)
---
 lib/CodeGen/CGRecordLayoutBuilder.cpp | 81 +++++++++++++++++++----------------
 1 file changed, 44 insertions(+), 37 deletions(-)

(limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')

diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 9f16875..77a319f 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "CodeGenTypes.h"
+#include "CGCXXABI.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Type.h"
 #include "llvm/Support/Debug.h"
@@ -45,10 +46,9 @@ public:
   typedef std::pair<const CXXRecordDecl *, unsigned> LLVMBaseInfo;
   llvm::SmallVector<LLVMBaseInfo, 16> LLVMNonVirtualBases;
   
-  /// ContainsPointerToDataMember - Whether one of the fields in this record
-  /// layout is a pointer to data member, or a struct that contains pointer to
-  /// data member.
-  bool ContainsPointerToDataMember;
+  /// IsZeroInitializable - Whether this struct can be C++
+  /// zero-initialized with an LLVM zeroinitializer.
+  bool IsZeroInitializable;
 
   /// Packed - Whether the resulting LLVM struct will be packed or not.
   bool Packed;
@@ -115,14 +115,14 @@ private:
 
   unsigned getTypeAlignment(const llvm::Type *Ty) const;
 
-  /// CheckForPointerToDataMember - Check if the given type contains a pointer
+  /// CheckZeroInitializable - Check if the given type contains a pointer
   /// to data member.
-  void CheckForPointerToDataMember(QualType T);
-  void CheckForPointerToDataMember(const CXXRecordDecl *RD);
+  void CheckZeroInitializable(QualType T);
+  void CheckZeroInitializable(const CXXRecordDecl *RD);
 
 public:
   CGRecordLayoutBuilder(CodeGenTypes &Types)
-    : ContainsPointerToDataMember(false), Packed(false), Types(Types),
+    : IsZeroInitializable(true), Packed(false), Types(Types),
       Alignment(0), AlignmentAsLLVMStruct(1),
       BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
 
@@ -157,15 +157,12 @@ void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
   LayoutFields(D);
 }
 
-static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types,
-                                          const FieldDecl *FD,
-                                          uint64_t FieldOffset,
-                                          uint64_t FieldSize) {
-  const RecordDecl *RD = FD->getParent();
-  const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD);
-  uint64_t ContainingTypeSizeInBits = RL.getSize();
-  unsigned ContainingTypeAlign = RL.getAlignment();
-
+CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
+                               const FieldDecl *FD,
+                               uint64_t FieldOffset,
+                               uint64_t FieldSize,
+                               uint64_t ContainingTypeSizeInBits,
+                               unsigned ContainingTypeAlign) {
   const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(FD->getType());
   uint64_t TypeSizeInBytes = Types.getTargetData().getTypeAllocSize(Ty);
   uint64_t TypeSizeInBits = TypeSizeInBytes * 8;
@@ -255,6 +252,19 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types,
   return CGBitFieldInfo(FieldSize, NumComponents, Components, IsSigned);
 }
 
+CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
+                                        const FieldDecl *FD,
+                                        uint64_t FieldOffset,
+                                        uint64_t FieldSize) {
+  const RecordDecl *RD = FD->getParent();
+  const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD);
+  uint64_t ContainingTypeSizeInBits = RL.getSize();
+  unsigned ContainingTypeAlign = RL.getAlignment();
+
+  return MakeInfo(Types, FD, FieldOffset, FieldSize, ContainingTypeSizeInBits,
+                  ContainingTypeAlign);
+}
+
 void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
                                            uint64_t FieldOffset) {
   uint64_t FieldSize =
@@ -287,7 +297,8 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
 
   // Add the bit field info.
   LLVMBitFields.push_back(
-    LLVMBitFieldInfo(D, ComputeBitFieldInfo(Types, D, FieldOffset, FieldSize)));
+    LLVMBitFieldInfo(D, CGBitFieldInfo::MakeInfo(Types, D, FieldOffset,
+                                                 FieldSize)));
 
   AppendBytes(NumBytesToAppend);
 
@@ -311,8 +322,7 @@ bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
     return true;
   }
 
-  // Check if we have a pointer to data member in this field.
-  CheckForPointerToDataMember(D->getType());
+  CheckZeroInitializable(D->getType());
 
   assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!");
   uint64_t FieldOffsetInBytes = FieldOffset / 8;
@@ -380,7 +390,8 @@ CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
 
     // Add the bit field info.
     LLVMBitFields.push_back(
-      LLVMBitFieldInfo(Field, ComputeBitFieldInfo(Types, Field, 0, FieldSize)));
+      LLVMBitFieldInfo(Field, CGBitFieldInfo::MakeInfo(Types, Field,
+                                                       0, FieldSize)));
     return FieldTy;
   }
 
@@ -458,7 +469,7 @@ void CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
     return;
   }
 
-  CheckForPointerToDataMember(BaseDecl);
+  CheckZeroInitializable(BaseDecl);
 
   // FIXME: Actually use a better type than [sizeof(BaseDecl) x i8] when we can.
   AppendPadding(BaseOffset / 8, 1);
@@ -603,9 +614,9 @@ unsigned CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const {
   return Types.getTargetData().getABITypeAlignment(Ty);
 }
 
-void CGRecordLayoutBuilder::CheckForPointerToDataMember(QualType T) {
+void CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) {
   // This record already contains a member pointer.
-  if (ContainsPointerToDataMember)
+  if (!IsZeroInitializable)
     return;
 
   // Can only have member pointers if we're compiling C++.
@@ -615,21 +626,17 @@ void CGRecordLayoutBuilder::CheckForPointerToDataMember(QualType T) {
   T = Types.getContext().getBaseElementType(T);
 
   if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
-    if (!MPT->getPointeeType()->isFunctionType()) {
-      // We have a pointer to data member.
-      ContainsPointerToDataMember = true;
-    }
+    if (!Types.getCXXABI().isZeroInitializable(MPT))
+      IsZeroInitializable = false;
   } else if (const RecordType *RT = T->getAs<RecordType>()) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-
-    return CheckForPointerToDataMember(RD);
+    CheckZeroInitializable(RD);
   }
 }
 
-void
-CGRecordLayoutBuilder::CheckForPointerToDataMember(const CXXRecordDecl *RD) {
+void CGRecordLayoutBuilder::CheckZeroInitializable(const CXXRecordDecl *RD) {
   // This record already contains a member pointer.
-  if (ContainsPointerToDataMember)
+  if (!IsZeroInitializable)
     return;
 
   // FIXME: It would be better if there was a way to explicitly compute the
@@ -638,8 +645,8 @@ CGRecordLayoutBuilder::CheckForPointerToDataMember(const CXXRecordDecl *RD) {
   
   const CGRecordLayout &Layout = Types.getCGRecordLayout(RD);
   
-  if (Layout.containsPointerToDataMember())
-    ContainsPointerToDataMember = true;
+  if (!Layout.isZeroInitializable())
+    IsZeroInitializable = false;
 }
 
 CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
@@ -652,7 +659,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
                                                Builder.Packed);
 
   CGRecordLayout *RL =
-    new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);
+    new CGRecordLayout(Ty, Builder.IsZeroInitializable);
 
   // Add all the non-virtual base field numbers.
   RL->NonVirtualBaseFields.insert(Builder.LLVMNonVirtualBases.begin(),
@@ -723,7 +730,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
 void CGRecordLayout::print(llvm::raw_ostream &OS) const {
   OS << "<CGRecordLayout\n";
   OS << "  LLVMType:" << *LLVMType << "\n";
-  OS << "  ContainsPointerToDataMember:" << ContainsPointerToDataMember << "\n";
+  OS << "  IsZeroInitializable:" << IsZeroInitializable << "\n";
   OS << "  BitFields:[\n";
 
   // Print bit-field infos in declaration order.
-- 
cgit v1.1