summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-03-08 22:17:41 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-03-08 22:17:41 +0000
commit872307e2ac6f9a1e8a83e23a5dc0db88538fa860 (patch)
treeab727fb967e4d216dc5456c84842a0850eb21f1a /clang/lib/CodeGen
parenta99000dd311b972e35f889c61bbdbc22a1680abd (diff)
downloadbcm5719-llvm-872307e2ac6f9a1e8a83e23a5dc0db88538fa860.tar.gz
bcm5719-llvm-872307e2ac6f9a1e8a83e23a5dc0db88538fa860.zip
P0017R1: In C++1z, an aggregate class can have (public non-virtual) base classes; these are initialized as if they were data members.
llvm-svn: 262963
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp42
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp13
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp16
3 files changed, 59 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 947b3d5b858..53131f7557f 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1171,6 +1171,38 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
unsigned NumInitElements = E->getNumInits();
RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl();
+ // We'll need to enter cleanup scopes in case any of the element
+ // initializers throws an exception.
+ SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
+ llvm::Instruction *cleanupDominator = nullptr;
+
+ unsigned curInitIndex = 0;
+
+ // Emit initialization of base classes.
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
+ assert(E->getNumInits() >= CXXRD->getNumBases() &&
+ "missing initializer for base class");
+ for (auto &Base : CXXRD->bases()) {
+ assert(!Base.isVirtual() && "should not see vbases here");
+ auto *BaseRD = Base.getType()->getAsCXXRecordDecl();
+ Address V = CGF.GetAddressOfDirectBaseInCompleteClass(
+ Dest.getAddress(), CXXRD, BaseRD,
+ /*isBaseVirtual*/ false);
+ AggValueSlot AggSlot =
+ AggValueSlot::forAddr(V, Qualifiers(),
+ AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers,
+ AggValueSlot::IsNotAliased);
+ CGF.EmitAggExpr(E->getInit(curInitIndex++), AggSlot);
+
+ if (QualType::DestructionKind dtorKind =
+ Base.getType().isDestructedType()) {
+ CGF.pushDestroy(dtorKind, V, Base.getType());
+ cleanups.push_back(CGF.EHStack.stable_begin());
+ }
+ }
+ }
+
// Prepare a 'this' for CXXDefaultInitExprs.
CodeGenFunction::FieldConstructionScope FCS(CGF, Dest.getAddress());
@@ -1204,14 +1236,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
return;
}
- // We'll need to enter cleanup scopes in case any of the member
- // initializers throw an exception.
- SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
- llvm::Instruction *cleanupDominator = nullptr;
-
// Here we iterate over the fields; this makes it simpler to both
// default-initialize fields and skip over unnamed fields.
- unsigned curInitIndex = 0;
for (const auto *field : record->fields()) {
// We're done once we hit the flexible array member.
if (field->getType()->isIncompleteArrayType())
@@ -1317,6 +1343,10 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
CharUnits NumNonZeroBytes = CharUnits::Zero();
unsigned ILEElement = 0;
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(SD))
+ for (auto &Base : CXXRD->bases())
+ NumNonZeroBytes +=
+ GetNumNonZeroBytesInInit(ILE->getInit(ILEElement++), CGF);
for (const auto *Field : SD->fields()) {
// We're done once we hit the flexible array member or run out of
// InitListExpr elements.
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 614b0769231..af370972491 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1011,15 +1011,18 @@ void CodeGenFunction::EmitNewArrayInitializer(
if (auto *ILE = dyn_cast<InitListExpr>(Init)) {
if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
if (RType->getDecl()->isStruct()) {
- unsigned NumFields = 0;
+ unsigned NumElements = 0;
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RType->getDecl()))
+ NumElements = CXXRD->getNumBases();
for (auto *Field : RType->getDecl()->fields())
if (!Field->isUnnamedBitfield())
- ++NumFields;
- if (ILE->getNumInits() == NumFields)
+ ++NumElements;
+ // FIXME: Recurse into nested InitListExprs.
+ if (ILE->getNumInits() == NumElements)
for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
if (!isa<ImplicitValueInitExpr>(ILE->getInit(i)))
- --NumFields;
- if (ILE->getNumInits() == NumFields && TryMemsetInitialization())
+ --NumElements;
+ if (ILE->getNumInits() == NumElements && TryMemsetInitialization())
return;
}
}
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 2aed3bb06d9..d64c5876ee2 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -368,7 +368,14 @@ bool ConstStructBuilder::Build(InitListExpr *ILE) {
unsigned FieldNo = 0;
unsigned ElementNo = 0;
-
+
+ // Bail out if we have base classes. We could support these, but they only
+ // arise in C++1z where we will have already constant folded most interesting
+ // cases. FIXME: There are still a few more cases we can handle this way.
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ if (CXXRD->getNumBases())
+ return false;
+
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
// If this is a union, skip all the fields that aren't being initialized.
@@ -1124,6 +1131,13 @@ bool ConstStructBuilder::Build(ConstExprEmitter *Emitter,
unsigned FieldNo = -1;
unsigned ElementNo = 0;
+ // Bail out if we have base classes. We could support these, but they only
+ // arise in C++1z where we will have already constant folded most interesting
+ // cases. FIXME: There are still a few more cases we can handle this way.
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ if (CXXRD->getNumBases())
+ return false;
+
for (FieldDecl *Field : RD->fields()) {
++FieldNo;
OpenPOWER on IntegriCloud