[cfe-commits] r46736 - in /cfe/trunk: CodeGen/CGExprConstant.cpp CodeGen/CodeGenTypes.cpp CodeGen/CodeGenTypes.h test/CodeGen/struct.c
Devang Patel
dpatel at apple.com
Mon Feb 4 18:39:51 PST 2008
Author: dpatel
Date: Mon Feb 4 20:39:50 2008
New Revision: 46736
URL: http://llvm.org/viewvc/llvm-project?rev=46736&view=rev
Log:
Cleanup InitListExpr code generation code.
Handle padding fields while initializing struct (fix PR 1962)
Modified:
cfe/trunk/CodeGen/CGExprConstant.cpp
cfe/trunk/CodeGen/CodeGenTypes.cpp
cfe/trunk/CodeGen/CodeGenTypes.h
cfe/trunk/test/CodeGen/struct.c
Modified: cfe/trunk/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprConstant.cpp?rev=46736&r1=46735&r2=46736&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/CodeGen/CGExprConstant.cpp Mon Feb 4 20:39:50 2008
@@ -66,75 +66,136 @@
return EmitConversion(C, E->getSubExpr()->getType(), E->getType());
}
-
- llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
- const llvm::CompositeType *CType =
- dyn_cast<llvm::CompositeType>(ConvertType(ILE->getType()));
- if (!CType) {
- // We have a scalar in braces. Just use the first element.
- return Visit(ILE->getInit(0));
- }
-
- unsigned NumInitElements = ILE->getNumInits();
- unsigned NumInitableElts = NumInitElements;
+ llvm::Constant *EmitArrayInitialization(InitListExpr *ILE,
+ const llvm::ArrayType *AType) {
+
std::vector<llvm::Constant*> Elts;
-
- // Initialising an array or structure requires us to automatically
+ unsigned NumInitElements = ILE->getNumInits();
+ const llvm::Type *ElemTy = AType->getElementType();
+ unsigned NumElements = AType->getNumElements();
+
+ // Initialising an array requires us to automatically
// initialise any elements that have not been initialised explicitly
- const llvm::ArrayType *AType = 0;
- const llvm::StructType *SType = 0;
- const llvm::Type *ElemTy = 0;
- unsigned NumElements = 0;
-
- // If this is an array, we may have to truncate the initializer
- if ((AType = dyn_cast<llvm::ArrayType>(CType))) {
- NumElements = AType->getNumElements();
- ElemTy = AType->getElementType();
- NumInitableElts = std::min(NumInitableElts, NumElements);
- }
-
- // If this is a structure, we may have to truncate the initializer
- if ((SType = dyn_cast<llvm::StructType>(CType))) {
- NumElements = SType->getNumElements();
- NumInitableElts = std::min(NumInitableElts, NumElements);
- }
+ unsigned NumInitableElts = std::min(NumInitElements, NumElements);
// Copy initializer elements.
unsigned i = 0;
- for (i = 0; i < NumInitableElts; ++i) {
+ for (; i < NumInitableElts; ++i) {
+
llvm::Constant *C = Visit(ILE->getInit(i));
// FIXME: Remove this when sema of initializers is finished (and the code
// above).
if (C == 0 && ILE->getInit(i)->getType()->isVoidType()) {
if (ILE->getType()->isVoidType()) return 0;
- return llvm::UndefValue::get(CType);
+ return llvm::UndefValue::get(AType);
}
assert (C && "Failed to create initializer expression");
Elts.push_back(C);
}
- if (SType) {
- // Initialize remaining structure elements.
- for (; i < NumElements; ++i) {
- ElemTy = SType->getElementType(i);
- Elts.push_back(llvm::Constant::getNullValue(ElemTy));
- }
- return llvm::ConstantStruct::get(SType, Elts);
- }
-
- if (ILE->getType()->isVectorType())
- return llvm::ConstantVector::get(cast<llvm::VectorType>(CType), Elts);
-
- // Make sure we have an array at this point
- assert(AType);
-
// Initialize remaining array elements.
for (; i < NumElements; ++i)
Elts.push_back(llvm::Constant::getNullValue(ElemTy));
return llvm::ConstantArray::get(AType, Elts);
}
+
+ llvm::Constant *EmitStructInitialization(InitListExpr *ILE,
+ const llvm::StructType *SType) {
+
+ std::vector<llvm::Constant*> Elts;
+ const CGRecordLayout *CGR = CGM.getTypes().getCGRecordLayout(SType);
+ unsigned NumInitElements = ILE->getNumInits();
+ unsigned NumElements = SType->getNumElements();
+
+ // Initialising an structure requires us to automatically
+ // initialise any elements that have not been initialised explicitly
+ unsigned NumInitableElts = std::min(NumInitElements, NumElements);
+
+ // Copy initializer elements. Skip padding fields.
+ unsigned EltNo = 0; // Element no in ILE
+ unsigned FieldNo = 0; // Field no in SType
+ while (EltNo < NumInitableElts) {
+
+ // Zero initialize padding field.
+ if (CGR->isPaddingField(FieldNo)) {
+ const llvm::Type *FieldTy = SType->getElementType(FieldNo);
+ Elts.push_back(llvm::Constant::getNullValue(FieldTy));
+ FieldNo++;
+ continue;
+ }
+
+ llvm::Constant *C = Visit(ILE->getInit(EltNo));
+ // FIXME: Remove this when sema of initializers is finished (and the code
+ // above).
+ if (C == 0 && ILE->getInit(EltNo)->getType()->isVoidType()) {
+ if (ILE->getType()->isVoidType()) return 0;
+ return llvm::UndefValue::get(SType);
+ }
+ assert (C && "Failed to create initializer expression");
+ Elts.push_back(C);
+ EltNo++;
+ FieldNo++;
+ }
+
+ // Initialize remaining structure elements.
+ for (unsigned i = Elts.size(); i < NumElements; ++i) {
+ const llvm::Type *FieldTy = SType->getElementType(i);
+ Elts.push_back(llvm::Constant::getNullValue(FieldTy));
+ }
+
+ return llvm::ConstantStruct::get(SType, Elts);
+ }
+
+ llvm::Constant *EmitVectorInitialization(InitListExpr *ILE,
+ const llvm::VectorType *VType) {
+
+ std::vector<llvm::Constant*> Elts;
+ unsigned NumInitElements = ILE->getNumInits();
+ unsigned NumElements = VType->getNumElements();
+
+ assert (NumInitElements == NumElements
+ && "Unsufficient vector init elelments");
+ // Copy initializer elements.
+ unsigned i = 0;
+ for (; i < NumElements; ++i) {
+
+ llvm::Constant *C = Visit(ILE->getInit(i));
+ // FIXME: Remove this when sema of initializers is finished (and the code
+ // above).
+ if (C == 0 && ILE->getInit(i)->getType()->isVoidType()) {
+ if (ILE->getType()->isVoidType()) return 0;
+ return llvm::UndefValue::get(VType);
+ }
+ assert (C && "Failed to create initializer expression");
+ Elts.push_back(C);
+ }
+
+ return llvm::ConstantVector::get(VType, Elts);
+ }
+
+ llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
+ const llvm::CompositeType *CType =
+ dyn_cast<llvm::CompositeType>(ConvertType(ILE->getType()));
+
+ if (!CType) {
+ // We have a scalar in braces. Just use the first element.
+ return Visit(ILE->getInit(0));
+ }
+
+ if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(CType))
+ return EmitArrayInitialization(ILE, AType);
+
+ if (const llvm::StructType *SType = dyn_cast<llvm::StructType>(CType))
+ return EmitStructInitialization(ILE, SType);
+
+ if (const llvm::VectorType *VType = dyn_cast<llvm::VectorType>(CType))
+ return EmitVectorInitialization(ILE, VType);
+
+ // Make sure we have an array at this point
+ assert(0 && "Unable to handle InitListExpr");
+ }
llvm::Constant *VisitImplicitCastExpr(ImplicitCastExpr *ICExpr) {
// If this is due to array->pointer conversion, emit the array expression as
Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=46736&r1=46735&r2=46736&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Mon Feb 4 20:39:50 2008
@@ -66,7 +66,7 @@
/// placeBitField - Find a place for FD, which is a bit-field.
void placeBitField(const FieldDecl *FD);
- llvm::SmallVector<unsigned, 8> &getPaddingFields() {
+ llvm::SmallSet<unsigned, 8> &getPaddingFields() {
return PaddingFields;
}
@@ -79,7 +79,7 @@
llvm::SmallVector<const FieldDecl *, 8> FieldDecls;
std::vector<const llvm::Type*> LLVMFields;
llvm::SmallVector<uint64_t, 8> Offsets;
- llvm::SmallVector<unsigned, 8> PaddingFields;
+ llvm::SmallSet<unsigned, 8> PaddingFields;
};
}
@@ -334,7 +334,8 @@
RO.layoutStructFields(RL);
// Get llvm::StructType.
- CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType());
+ CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(),
+ RO.getPaddingFields());
ResultType = TagDeclTypes[TD] = RLI->getLLVMType();
CGRecordLayouts[ResultType] = RLI;
@@ -357,7 +358,8 @@
RO.layoutUnionFields();
// Get llvm::StructType.
- CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType());
+ CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(),
+ RO.getPaddingFields());
ResultType = TagDeclTypes[TD] = RLI->getLLVMType();
CGRecordLayouts[ResultType] = RLI;
} else {
@@ -520,7 +522,7 @@
Offsets.push_back(llvmSize);
llvmSize += TySize;
if (isPaddingField)
- PaddingFields.push_back(llvmFieldNo);
+ PaddingFields.insert(llvmFieldNo);
LLVMFields.push_back(Ty);
++llvmFieldNo;
}
Modified: cfe/trunk/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.h?rev=46736&r1=46735&r2=46736&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.h Mon Feb 4 20:39:50 2008
@@ -15,6 +15,7 @@
#define CODEGEN_CODEGENTYPES_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
#include <vector>
namespace llvm {
@@ -42,7 +43,8 @@
class CGRecordLayout {
CGRecordLayout(); // DO NOT IMPLEMENT
public:
- CGRecordLayout(llvm::Type *T) : STy(T) {
+ CGRecordLayout(llvm::Type *T, llvm::SmallSet<unsigned, 8> &PF)
+ : STy(T), PaddingFields(PF) {
// FIXME : Collect info about fields that requires adjustments
// (i.e. fields that do not directly map to llvm struct fields.)
}
@@ -52,8 +54,17 @@
return STy;
}
+ bool isPaddingField(unsigned No) const {
+ return PaddingFields.count(No) != 0;
+ }
+
+ unsigned getNumPaddingFields() {
+ return PaddingFields.size();
+ }
+
private:
llvm::Type *STy;
+ llvm::SmallSet<unsigned, 8> PaddingFields;
};
/// CodeGenTypes - This class organizes the cross-module state that is used
Modified: cfe/trunk/test/CodeGen/struct.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/struct.c?rev=46736&r1=46735&r2=46736&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/struct.c (original)
+++ cfe/trunk/test/CodeGen/struct.c Mon Feb 4 20:39:50 2008
@@ -140,3 +140,4 @@
/* struct initialization */
struct a13 {int b; int c};
struct a13 c13 = {5};
+struct a14 { short a; int b; } x = {1, 1};
More information about the cfe-commits
mailing list