@@ -1733,20 +1733,21 @@ static mlir::TypedAttr emitNullConstant(CIRGenModule &CGM, const RecordDecl *rd,
1733
1733
}
1734
1734
1735
1735
// Fill in all the fields.
1736
- for (const auto *Field : rd->fields ()) {
1736
+ for (const auto *field : rd->fields ()) {
1737
1737
// Fill in non-bitfields. (Bitfields always use a zero pattern, which we
1738
1738
// will fill in later.)
1739
- if (!Field->isBitField () &&
1740
- !isEmptyFieldForLayout (CGM.getASTContext (), Field)) {
1741
- llvm_unreachable (" NYI" );
1739
+ if (!field->isBitField () &&
1740
+ !isEmptyFieldForLayout (CGM.getASTContext (), field)) {
1741
+ unsigned fieldIndex = layout.getCIRFieldNo (field);
1742
+ elements[fieldIndex] = CGM.emitNullConstant (field->getType ());
1742
1743
}
1743
1744
1744
1745
// For unions, stop after the first named field.
1745
1746
if (rd->isUnion ()) {
1746
- if (Field ->getIdentifier ())
1747
+ if (field ->getIdentifier ())
1747
1748
break ;
1748
- if (const auto *FieldRD = Field ->getType ()->getAsRecordDecl ())
1749
- if (FieldRD ->findFirstNamedDataMember ())
1749
+ if (const auto *fieldRD = field ->getType ()->getAsRecordDecl ())
1750
+ if (fieldRD ->findFirstNamedDataMember ())
1750
1751
break ;
1751
1752
}
1752
1753
}
@@ -1780,27 +1781,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
1780
1781
if (const CXXConstructExpr *E =
1781
1782
dyn_cast_or_null<CXXConstructExpr>(D.getInit ())) {
1782
1783
const CXXConstructorDecl *CD = E->getConstructor ();
1783
- // FIXME: we should probably model this more closely to C++ than
1784
- // just emitting a global with zero init (mimic what we do for trivial
1785
- // assignments and whatnots). Since this is for globals shouldn't
1786
- // be a problem for the near future.
1787
- if (CD->isTrivial () && CD->isDefaultConstructor ()) {
1788
- const auto *cxxrd =
1789
- cast<CXXRecordDecl>(Ty->getAs <RecordType>()->getDecl ());
1790
- // Some cases, such as member pointer members, can't be zero
1791
- // initialized. These are "zero-initialized" in the language standard
1792
- // sense, but the target ABI may require that a literal value other
1793
- // than zero be used in the initializer to make clear that a pointer
1794
- // with the value zero is not what is intended. The classic codegen
1795
- // goes through emitNullConstant for those cases but generates a
1796
- // non-zero constant. We can't quite do that here because we need an
1797
- // attribute and not a value, but something like that can be
1798
- // implemented.
1799
- if (!CGM.getTypes ().isZeroInitializable (cxxrd)) {
1800
- llvm_unreachable (" NYI" );
1801
- }
1802
- return cir::ZeroAttr::get (CGM.convertType (D.getType ()));
1803
- }
1784
+ if (CD->isTrivial () && CD->isDefaultConstructor ())
1785
+ return CGM.emitNullConstant (D.getType ());
1804
1786
}
1805
1787
}
1806
1788
}
@@ -1820,8 +1802,11 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
1820
1802
1821
1803
// Try to emit the initializer. Note that this can allow some things that
1822
1804
// are not allowed by tryEmitPrivateForMemory alone.
1823
- if (auto value = D.evaluateValue ())
1805
+ if (auto value = D.evaluateValue ()) {
1806
+ assert (!value->allowConstexprUnknown () &&
1807
+ " Constexpr unknown values are not allowed in CodeGen" );
1824
1808
return tryEmitPrivateForMemory (*value, destType);
1809
+ }
1825
1810
1826
1811
return nullptr ;
1827
1812
}
@@ -2109,14 +2094,14 @@ mlir::TypedAttr CIRGenModule::emitNullConstant(QualType T) {
2109
2094
llvm_unreachable (" NYI" );
2110
2095
}
2111
2096
2112
- if (T->getAs <clang::RecordType>())
2113
- llvm_unreachable (" NYI" );
2097
+ if (const RecordType *rt = T->getAs <RecordType>())
2098
+ return ::emitNullConstant (*this , rt->getDecl (), /* complete object*/
2099
+ true );
2114
2100
2115
2101
assert (T->isMemberDataPointerType () &&
2116
2102
" Should only see pointers to data members here!" );
2117
2103
2118
- llvm_unreachable (" NYI" );
2119
- return {};
2104
+ return getCXXABI ().emitNullMemberPointer (T);
2120
2105
}
2121
2106
2122
2107
mlir::Value CIRGenModule::emitMemberPointerConstant (const UnaryOperator *E) {
0 commit comments