summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r--lib/CodeGen/CGExprConstant.cpp95
1 files changed, 27 insertions, 68 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index f5c8187..f4d6861 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -53,9 +53,6 @@ private:
NextFieldOffsetInChars(CharUnits::Zero()),
LLVMStructAlignment(CharUnits::One()) { }
- void AppendVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
- const CXXRecordDecl *VTableClass);
-
void AppendField(const FieldDecl *Field, uint64_t FieldOffset,
llvm::Constant *InitExpr);
@@ -72,8 +69,7 @@ private:
bool Build(InitListExpr *ILE);
void Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
- llvm::Constant *VTable, const CXXRecordDecl *VTableClass,
- CharUnits BaseOffset);
+ const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
llvm::Constant *Finalize(QualType Ty);
CharUnits getAlignment(const llvm::Constant *C) const {
@@ -88,23 +84,6 @@ private:
}
};
-void ConstStructBuilder::AppendVTablePointer(BaseSubobject Base,
- llvm::Constant *VTable,
- const CXXRecordDecl *VTableClass) {
- // Find the appropriate vtable within the vtable group.
- uint64_t AddressPoint =
- CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);
- llvm::Value *Indices[] = {
- llvm::ConstantInt::get(CGM.Int64Ty, 0),
- llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)
- };
- llvm::Constant *VTableAddressPoint =
- llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices);
-
- // Add the vtable at the start of the object.
- AppendBytes(Base.getBaseOffset(), VTableAddressPoint);
-}
-
void ConstStructBuilder::
AppendField(const FieldDecl *Field, uint64_t FieldOffset,
llvm::Constant *InitCst) {
@@ -368,40 +347,21 @@ void ConstStructBuilder::ConvertStructToPacked() {
}
bool ConstStructBuilder::Build(InitListExpr *ILE) {
- if (ILE->initializesStdInitializerList()) {
- //CGM.ErrorUnsupported(ILE, "global std::initializer_list");
- return false;
- }
-
RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
unsigned FieldNo = 0;
unsigned ElementNo = 0;
- const FieldDecl *LastFD = 0;
- bool IsMsStruct = RD->isMsStruct(CGM.getContext());
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
- if (IsMsStruct) {
- // Zero-length bitfields following non-bitfield members are
- // ignored:
- if (CGM.getContext().ZeroBitfieldFollowsNonBitfield(*Field, LastFD)) {
- --FieldNo;
- continue;
- }
- LastFD = *Field;
- }
-
// If this is a union, skip all the fields that aren't being initialized.
if (RD->isUnion() && ILE->getInitializedFieldInUnion() != *Field)
continue;
// Don't emit anonymous bitfields, they just affect layout.
- if (Field->isUnnamedBitfield()) {
- LastFD = *Field;
+ if (Field->isUnnamedBitfield())
continue;
- }
// Get the initializer. A struct can include fields without initializers,
// we just use explicit null values for them.
@@ -443,15 +403,19 @@ struct BaseInfo {
}
void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
- bool IsPrimaryBase, llvm::Constant *VTable,
+ bool IsPrimaryBase,
const CXXRecordDecl *VTableClass,
CharUnits Offset) {
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
// Add a vtable pointer, if we need one and it hasn't already been added.
- if (CD->isDynamicClass() && !IsPrimaryBase)
- AppendVTablePointer(BaseSubobject(CD, Offset), VTable, VTableClass);
+ if (CD->isDynamicClass() && !IsPrimaryBase) {
+ llvm::Constant *VTableAddressPoint =
+ CGM.getCXXABI().getVTableAddressPointForConstExpr(
+ BaseSubobject(CD, Offset), VTableClass);
+ AppendBytes(Offset, VTableAddressPoint);
+ }
// Accumulate and sort bases, in order to visit them in address order, which
// may not be the same as declaration order.
@@ -472,36 +436,22 @@ void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl;
Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase,
- VTable, VTableClass, Offset + Base.Offset);
+ VTableClass, Offset + Base.Offset);
}
}
unsigned FieldNo = 0;
- const FieldDecl *LastFD = 0;
- bool IsMsStruct = RD->isMsStruct(CGM.getContext());
uint64_t OffsetBits = CGM.getContext().toBits(Offset);
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
- if (IsMsStruct) {
- // Zero-length bitfields following non-bitfield members are
- // ignored:
- if (CGM.getContext().ZeroBitfieldFollowsNonBitfield(*Field, LastFD)) {
- --FieldNo;
- continue;
- }
- LastFD = *Field;
- }
-
// If this is a union, skip all the fields that aren't being initialized.
if (RD->isUnion() && Val.getUnionField() != *Field)
continue;
// Don't emit anonymous bitfields, they just affect layout.
- if (Field->isUnnamedBitfield()) {
- LastFD = *Field;
+ if (Field->isUnnamedBitfield())
continue;
- }
// Emit the value of the initializer.
const APValue &FieldValue =
@@ -593,11 +543,7 @@ llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
- llvm::Constant *VTable = 0;
- if (CD && CD->isDynamicClass())
- VTable = CGM.getVTables().GetAddrOfVTable(CD);
-
- Builder.Build(Val, RD, false, VTable, CD, CharUnits::Zero());
+ Builder.Build(Val, RD, false, CD, CharUnits::Zero());
return Builder.Finalize(ValTy);
}
@@ -642,6 +588,10 @@ public:
return Visit(GE->getResultExpr());
}
+ llvm::Constant *VisitChooseExpr(ChooseExpr *CE) {
+ return Visit(CE->getChosenSubExpr());
+ }
+
llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
return Visit(E->getInitializer());
}
@@ -687,6 +637,7 @@ public:
case CK_AtomicToNonAtomic:
case CK_NonAtomicToAtomic:
case CK_NoOp:
+ case CK_ConstructorConversion:
return C;
case CK_Dependent: llvm_unreachable("saw dependent cast!");
@@ -716,7 +667,6 @@ public:
case CK_LValueBitCast:
case CK_NullToMemberPointer:
case CK_UserDefinedConversion:
- case CK_ConstructorConversion:
case CK_CPointerToObjCPointerCast:
case CK_BlockPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
@@ -995,7 +945,7 @@ public:
CXXTypeidExpr *Typeid = cast<CXXTypeidExpr>(E);
QualType T;
if (Typeid->isTypeOperand())
- T = Typeid->getTypeOperand();
+ T = Typeid->getTypeOperand(CGM.getContext());
else
T = Typeid->getExprOperand()->getType();
return CGM.GetAddrOfRTTIDescriptor(T);
@@ -1003,6 +953,15 @@ public:
case Expr::CXXUuidofExprClass: {
return CGM.GetAddrOfUuidDescriptor(cast<CXXUuidofExpr>(E));
}
+ case Expr::MaterializeTemporaryExprClass: {
+ MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(E);
+ assert(MTE->getStorageDuration() == SD_Static);
+ SmallVector<const Expr *, 2> CommaLHSs;
+ SmallVector<SubobjectAdjustment, 2> Adjustments;
+ const Expr *Inner = MTE->GetTemporaryExpr()
+ ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+ return CGM.GetAddrOfGlobalTemporary(MTE, Inner);
+ }
}
return 0;
OpenPOWER on IntegriCloud