1*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // This contains code to emit Constant Expr nodes as LLVM code.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric
13*700637cbSDimitry Andric #include "Address.h"
14*700637cbSDimitry Andric #include "CIRGenConstantEmitter.h"
15*700637cbSDimitry Andric #include "CIRGenFunction.h"
16*700637cbSDimitry Andric #include "CIRGenModule.h"
17*700637cbSDimitry Andric #include "CIRGenRecordLayout.h"
18*700637cbSDimitry Andric #include "mlir/IR/Attributes.h"
19*700637cbSDimitry Andric #include "mlir/IR/BuiltinAttributeInterfaces.h"
20*700637cbSDimitry Andric #include "mlir/IR/BuiltinAttributes.h"
21*700637cbSDimitry Andric #include "clang/AST/APValue.h"
22*700637cbSDimitry Andric #include "clang/AST/ASTContext.h"
23*700637cbSDimitry Andric #include "clang/AST/Attr.h"
24*700637cbSDimitry Andric #include "clang/AST/OperationKinds.h"
25*700637cbSDimitry Andric #include "clang/AST/RecordLayout.h"
26*700637cbSDimitry Andric #include "clang/AST/StmtVisitor.h"
27*700637cbSDimitry Andric #include "clang/Basic/Builtins.h"
28*700637cbSDimitry Andric #include "clang/Basic/Specifiers.h"
29*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRAttrs.h"
30*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRTypes.h"
31*700637cbSDimitry Andric #include "llvm/ADT/STLExtras.h"
32*700637cbSDimitry Andric #include "llvm/ADT/Sequence.h"
33*700637cbSDimitry Andric #include "llvm/Support/ErrorHandling.h"
34*700637cbSDimitry Andric
35*700637cbSDimitry Andric using namespace clang;
36*700637cbSDimitry Andric using namespace clang::CIRGen;
37*700637cbSDimitry Andric
38*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
39*700637cbSDimitry Andric // ConstExprEmitter
40*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
41*700637cbSDimitry Andric
42*700637cbSDimitry Andric // This class only needs to handle arrays, structs and unions.
43*700637cbSDimitry Andric //
44*700637cbSDimitry Andric // In LLVM codegen, when outside C++11 mode, those types are not constant
45*700637cbSDimitry Andric // folded, while all other types are handled by constant folding.
46*700637cbSDimitry Andric //
47*700637cbSDimitry Andric // In CIR codegen, instead of folding things here, we should defer that work
48*700637cbSDimitry Andric // to MLIR: do not attempt to do much here.
49*700637cbSDimitry Andric class ConstExprEmitter
50*700637cbSDimitry Andric : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
51*700637cbSDimitry Andric CIRGenModule &cgm;
52*700637cbSDimitry Andric LLVM_ATTRIBUTE_UNUSED ConstantEmitter &emitter;
53*700637cbSDimitry Andric
54*700637cbSDimitry Andric public:
ConstExprEmitter(ConstantEmitter & emitter)55*700637cbSDimitry Andric ConstExprEmitter(ConstantEmitter &emitter)
56*700637cbSDimitry Andric : cgm(emitter.cgm), emitter(emitter) {}
57*700637cbSDimitry Andric
58*700637cbSDimitry Andric //===--------------------------------------------------------------------===//
59*700637cbSDimitry Andric // Visitor Methods
60*700637cbSDimitry Andric //===--------------------------------------------------------------------===//
61*700637cbSDimitry Andric
VisitStmt(Stmt * S,QualType T)62*700637cbSDimitry Andric mlir::Attribute VisitStmt(Stmt *S, QualType T) { return {}; }
63*700637cbSDimitry Andric
VisitConstantExpr(ConstantExpr * ce,QualType t)64*700637cbSDimitry Andric mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {
65*700637cbSDimitry Andric if (mlir::Attribute result = emitter.tryEmitConstantExpr(ce))
66*700637cbSDimitry Andric return result;
67*700637cbSDimitry Andric return Visit(ce->getSubExpr(), t);
68*700637cbSDimitry Andric }
69*700637cbSDimitry Andric
VisitParenExpr(ParenExpr * pe,QualType t)70*700637cbSDimitry Andric mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {
71*700637cbSDimitry Andric return Visit(pe->getSubExpr(), t);
72*700637cbSDimitry Andric }
73*700637cbSDimitry Andric
74*700637cbSDimitry Andric mlir::Attribute
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * pe,QualType t)75*700637cbSDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe,
76*700637cbSDimitry Andric QualType t) {
77*700637cbSDimitry Andric return Visit(pe->getReplacement(), t);
78*700637cbSDimitry Andric }
79*700637cbSDimitry Andric
VisitGenericSelectionExpr(GenericSelectionExpr * ge,QualType t)80*700637cbSDimitry Andric mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge,
81*700637cbSDimitry Andric QualType t) {
82*700637cbSDimitry Andric return Visit(ge->getResultExpr(), t);
83*700637cbSDimitry Andric }
84*700637cbSDimitry Andric
VisitChooseExpr(ChooseExpr * ce,QualType t)85*700637cbSDimitry Andric mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {
86*700637cbSDimitry Andric return Visit(ce->getChosenSubExpr(), t);
87*700637cbSDimitry Andric }
88*700637cbSDimitry Andric
VisitCompoundLiteralExpr(CompoundLiteralExpr * e,QualType t)89*700637cbSDimitry Andric mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t) {
90*700637cbSDimitry Andric return Visit(e->getInitializer(), t);
91*700637cbSDimitry Andric }
92*700637cbSDimitry Andric
VisitCastExpr(CastExpr * e,QualType destType)93*700637cbSDimitry Andric mlir::Attribute VisitCastExpr(CastExpr *e, QualType destType) {
94*700637cbSDimitry Andric if (isa<ExplicitCastExpr>(e))
95*700637cbSDimitry Andric cgm.errorNYI(e->getBeginLoc(),
96*700637cbSDimitry Andric "ConstExprEmitter::VisitCastExpr explicit cast");
97*700637cbSDimitry Andric
98*700637cbSDimitry Andric Expr *subExpr = e->getSubExpr();
99*700637cbSDimitry Andric
100*700637cbSDimitry Andric switch (e->getCastKind()) {
101*700637cbSDimitry Andric case CK_ToUnion:
102*700637cbSDimitry Andric case CK_AddressSpaceConversion:
103*700637cbSDimitry Andric case CK_ReinterpretMemberPointer:
104*700637cbSDimitry Andric case CK_DerivedToBaseMemberPointer:
105*700637cbSDimitry Andric case CK_BaseToDerivedMemberPointer:
106*700637cbSDimitry Andric cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCastExpr");
107*700637cbSDimitry Andric return {};
108*700637cbSDimitry Andric
109*700637cbSDimitry Andric case CK_LValueToRValue:
110*700637cbSDimitry Andric case CK_AtomicToNonAtomic:
111*700637cbSDimitry Andric case CK_NonAtomicToAtomic:
112*700637cbSDimitry Andric case CK_NoOp:
113*700637cbSDimitry Andric case CK_ConstructorConversion:
114*700637cbSDimitry Andric return Visit(subExpr, destType);
115*700637cbSDimitry Andric
116*700637cbSDimitry Andric case CK_IntToOCLSampler:
117*700637cbSDimitry Andric llvm_unreachable("global sampler variables are not generated");
118*700637cbSDimitry Andric
119*700637cbSDimitry Andric case CK_Dependent:
120*700637cbSDimitry Andric llvm_unreachable("saw dependent cast!");
121*700637cbSDimitry Andric
122*700637cbSDimitry Andric case CK_BuiltinFnToFnPtr:
123*700637cbSDimitry Andric llvm_unreachable("builtin functions are handled elsewhere");
124*700637cbSDimitry Andric
125*700637cbSDimitry Andric // These will never be supported.
126*700637cbSDimitry Andric case CK_ObjCObjectLValueCast:
127*700637cbSDimitry Andric case CK_ARCProduceObject:
128*700637cbSDimitry Andric case CK_ARCConsumeObject:
129*700637cbSDimitry Andric case CK_ARCReclaimReturnedObject:
130*700637cbSDimitry Andric case CK_ARCExtendBlockObject:
131*700637cbSDimitry Andric case CK_CopyAndAutoreleaseBlockObject:
132*700637cbSDimitry Andric return {};
133*700637cbSDimitry Andric
134*700637cbSDimitry Andric // These don't need to be handled here because Evaluate knows how to
135*700637cbSDimitry Andric // evaluate them in the cases where they can be folded.
136*700637cbSDimitry Andric case CK_BitCast:
137*700637cbSDimitry Andric case CK_ToVoid:
138*700637cbSDimitry Andric case CK_Dynamic:
139*700637cbSDimitry Andric case CK_LValueBitCast:
140*700637cbSDimitry Andric case CK_LValueToRValueBitCast:
141*700637cbSDimitry Andric case CK_NullToMemberPointer:
142*700637cbSDimitry Andric case CK_UserDefinedConversion:
143*700637cbSDimitry Andric case CK_CPointerToObjCPointerCast:
144*700637cbSDimitry Andric case CK_BlockPointerToObjCPointerCast:
145*700637cbSDimitry Andric case CK_AnyPointerToBlockPointerCast:
146*700637cbSDimitry Andric case CK_ArrayToPointerDecay:
147*700637cbSDimitry Andric case CK_FunctionToPointerDecay:
148*700637cbSDimitry Andric case CK_BaseToDerived:
149*700637cbSDimitry Andric case CK_DerivedToBase:
150*700637cbSDimitry Andric case CK_UncheckedDerivedToBase:
151*700637cbSDimitry Andric case CK_MemberPointerToBoolean:
152*700637cbSDimitry Andric case CK_VectorSplat:
153*700637cbSDimitry Andric case CK_FloatingRealToComplex:
154*700637cbSDimitry Andric case CK_FloatingComplexToReal:
155*700637cbSDimitry Andric case CK_FloatingComplexToBoolean:
156*700637cbSDimitry Andric case CK_FloatingComplexCast:
157*700637cbSDimitry Andric case CK_FloatingComplexToIntegralComplex:
158*700637cbSDimitry Andric case CK_IntegralRealToComplex:
159*700637cbSDimitry Andric case CK_IntegralComplexToReal:
160*700637cbSDimitry Andric case CK_IntegralComplexToBoolean:
161*700637cbSDimitry Andric case CK_IntegralComplexCast:
162*700637cbSDimitry Andric case CK_IntegralComplexToFloatingComplex:
163*700637cbSDimitry Andric case CK_PointerToIntegral:
164*700637cbSDimitry Andric case CK_PointerToBoolean:
165*700637cbSDimitry Andric case CK_NullToPointer:
166*700637cbSDimitry Andric case CK_IntegralCast:
167*700637cbSDimitry Andric case CK_BooleanToSignedIntegral:
168*700637cbSDimitry Andric case CK_IntegralToPointer:
169*700637cbSDimitry Andric case CK_IntegralToBoolean:
170*700637cbSDimitry Andric case CK_IntegralToFloating:
171*700637cbSDimitry Andric case CK_FloatingToIntegral:
172*700637cbSDimitry Andric case CK_FloatingToBoolean:
173*700637cbSDimitry Andric case CK_FloatingCast:
174*700637cbSDimitry Andric case CK_FloatingToFixedPoint:
175*700637cbSDimitry Andric case CK_FixedPointToFloating:
176*700637cbSDimitry Andric case CK_FixedPointCast:
177*700637cbSDimitry Andric case CK_FixedPointToBoolean:
178*700637cbSDimitry Andric case CK_FixedPointToIntegral:
179*700637cbSDimitry Andric case CK_IntegralToFixedPoint:
180*700637cbSDimitry Andric case CK_ZeroToOCLOpaqueType:
181*700637cbSDimitry Andric case CK_MatrixCast:
182*700637cbSDimitry Andric case CK_HLSLArrayRValue:
183*700637cbSDimitry Andric case CK_HLSLVectorTruncation:
184*700637cbSDimitry Andric case CK_HLSLElementwiseCast:
185*700637cbSDimitry Andric case CK_HLSLAggregateSplatCast:
186*700637cbSDimitry Andric return {};
187*700637cbSDimitry Andric }
188*700637cbSDimitry Andric llvm_unreachable("Invalid CastKind");
189*700637cbSDimitry Andric }
190*700637cbSDimitry Andric
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * die,QualType t)191*700637cbSDimitry Andric mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) {
192*700637cbSDimitry Andric cgm.errorNYI(die->getBeginLoc(),
193*700637cbSDimitry Andric "ConstExprEmitter::VisitCXXDefaultInitExpr");
194*700637cbSDimitry Andric return {};
195*700637cbSDimitry Andric }
196*700637cbSDimitry Andric
VisitExprWithCleanups(ExprWithCleanups * e,QualType t)197*700637cbSDimitry Andric mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) {
198*700637cbSDimitry Andric // Since this about constant emission no need to wrap this under a scope.
199*700637cbSDimitry Andric return Visit(e->getSubExpr(), t);
200*700637cbSDimitry Andric }
201*700637cbSDimitry Andric
VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr * e,QualType t)202*700637cbSDimitry Andric mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e,
203*700637cbSDimitry Andric QualType t) {
204*700637cbSDimitry Andric return Visit(e->getSubExpr(), t);
205*700637cbSDimitry Andric }
206*700637cbSDimitry Andric
VisitImplicitValueInitExpr(ImplicitValueInitExpr * E,QualType T)207*700637cbSDimitry Andric mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *E,
208*700637cbSDimitry Andric QualType T) {
209*700637cbSDimitry Andric cgm.errorNYI(E->getBeginLoc(),
210*700637cbSDimitry Andric "ConstExprEmitter::VisitImplicitValueInitExpr");
211*700637cbSDimitry Andric return {};
212*700637cbSDimitry Andric }
213*700637cbSDimitry Andric
VisitInitListExpr(InitListExpr * ile,QualType t)214*700637cbSDimitry Andric mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {
215*700637cbSDimitry Andric if (ile->isTransparent())
216*700637cbSDimitry Andric return Visit(ile->getInit(0), t);
217*700637cbSDimitry Andric
218*700637cbSDimitry Andric if (ile->getType()->isArrayType()) {
219*700637cbSDimitry Andric // If we return null here, the non-constant initializer will take care of
220*700637cbSDimitry Andric // it, but we would prefer to handle it here.
221*700637cbSDimitry Andric assert(!cir::MissingFeatures::constEmitterArrayILE());
222*700637cbSDimitry Andric return {};
223*700637cbSDimitry Andric }
224*700637cbSDimitry Andric
225*700637cbSDimitry Andric if (ile->getType()->isRecordType()) {
226*700637cbSDimitry Andric cgm.errorNYI(ile->getBeginLoc(), "ConstExprEmitter: record ILE");
227*700637cbSDimitry Andric return {};
228*700637cbSDimitry Andric }
229*700637cbSDimitry Andric
230*700637cbSDimitry Andric if (ile->getType()->isVectorType()) {
231*700637cbSDimitry Andric // If we return null here, the non-constant initializer will take care of
232*700637cbSDimitry Andric // it, but we would prefer to handle it here.
233*700637cbSDimitry Andric assert(!cir::MissingFeatures::constEmitterVectorILE());
234*700637cbSDimitry Andric return {};
235*700637cbSDimitry Andric }
236*700637cbSDimitry Andric
237*700637cbSDimitry Andric return {};
238*700637cbSDimitry Andric }
239*700637cbSDimitry Andric
VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr * e,QualType destType)240*700637cbSDimitry Andric mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e,
241*700637cbSDimitry Andric QualType destType) {
242*700637cbSDimitry Andric mlir::Attribute c = Visit(e->getBase(), destType);
243*700637cbSDimitry Andric if (!c)
244*700637cbSDimitry Andric return {};
245*700637cbSDimitry Andric
246*700637cbSDimitry Andric cgm.errorNYI(e->getBeginLoc(),
247*700637cbSDimitry Andric "ConstExprEmitter::VisitDesignatedInitUpdateExpr");
248*700637cbSDimitry Andric return {};
249*700637cbSDimitry Andric }
250*700637cbSDimitry Andric
VisitCXXConstructExpr(CXXConstructExpr * e,QualType ty)251*700637cbSDimitry Andric mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty) {
252*700637cbSDimitry Andric cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCXXConstructExpr");
253*700637cbSDimitry Andric return {};
254*700637cbSDimitry Andric }
255*700637cbSDimitry Andric
VisitStringLiteral(StringLiteral * e,QualType t)256*700637cbSDimitry Andric mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) {
257*700637cbSDimitry Andric // This is a string literal initializing an array in an initializer.
258*700637cbSDimitry Andric return cgm.getConstantArrayFromStringLiteral(e);
259*700637cbSDimitry Andric }
260*700637cbSDimitry Andric
VisitObjCEncodeExpr(ObjCEncodeExpr * e,QualType t)261*700637cbSDimitry Andric mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) {
262*700637cbSDimitry Andric cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitObjCEncodeExpr");
263*700637cbSDimitry Andric return {};
264*700637cbSDimitry Andric }
265*700637cbSDimitry Andric
VisitUnaryExtension(const UnaryOperator * e,QualType t)266*700637cbSDimitry Andric mlir::Attribute VisitUnaryExtension(const UnaryOperator *e, QualType t) {
267*700637cbSDimitry Andric return Visit(e->getSubExpr(), t);
268*700637cbSDimitry Andric }
269*700637cbSDimitry Andric
270*700637cbSDimitry Andric // Utility methods
convertType(QualType t)271*700637cbSDimitry Andric mlir::Type convertType(QualType t) { return cgm.convertType(t); }
272*700637cbSDimitry Andric };
273*700637cbSDimitry Andric
274*700637cbSDimitry Andric // TODO(cir): this can be shared with LLVM's codegen
getNonMemoryType(CIRGenModule & cgm,QualType type)275*700637cbSDimitry Andric static QualType getNonMemoryType(CIRGenModule &cgm, QualType type) {
276*700637cbSDimitry Andric if (const auto *at = type->getAs<AtomicType>()) {
277*700637cbSDimitry Andric return cgm.getASTContext().getQualifiedType(at->getValueType(),
278*700637cbSDimitry Andric type.getQualifiers());
279*700637cbSDimitry Andric }
280*700637cbSDimitry Andric return type;
281*700637cbSDimitry Andric }
282*700637cbSDimitry Andric
283*700637cbSDimitry Andric static mlir::Attribute
emitArrayConstant(CIRGenModule & cgm,mlir::Type desiredType,mlir::Type commonElementType,unsigned arrayBound,SmallVectorImpl<mlir::TypedAttr> & elements,mlir::TypedAttr filler)284*700637cbSDimitry Andric emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
285*700637cbSDimitry Andric mlir::Type commonElementType, unsigned arrayBound,
286*700637cbSDimitry Andric SmallVectorImpl<mlir::TypedAttr> &elements,
287*700637cbSDimitry Andric mlir::TypedAttr filler) {
288*700637cbSDimitry Andric const CIRGenBuilderTy &builder = cgm.getBuilder();
289*700637cbSDimitry Andric
290*700637cbSDimitry Andric unsigned nonzeroLength = arrayBound;
291*700637cbSDimitry Andric if (elements.size() < nonzeroLength && builder.isNullValue(filler))
292*700637cbSDimitry Andric nonzeroLength = elements.size();
293*700637cbSDimitry Andric
294*700637cbSDimitry Andric if (nonzeroLength == elements.size()) {
295*700637cbSDimitry Andric while (nonzeroLength > 0 &&
296*700637cbSDimitry Andric builder.isNullValue(elements[nonzeroLength - 1]))
297*700637cbSDimitry Andric --nonzeroLength;
298*700637cbSDimitry Andric }
299*700637cbSDimitry Andric
300*700637cbSDimitry Andric if (nonzeroLength == 0)
301*700637cbSDimitry Andric return cir::ZeroAttr::get(desiredType);
302*700637cbSDimitry Andric
303*700637cbSDimitry Andric const unsigned trailingZeroes = arrayBound - nonzeroLength;
304*700637cbSDimitry Andric
305*700637cbSDimitry Andric // Add a zeroinitializer array filler if we have lots of trailing zeroes.
306*700637cbSDimitry Andric if (trailingZeroes >= 8) {
307*700637cbSDimitry Andric assert(elements.size() >= nonzeroLength &&
308*700637cbSDimitry Andric "missing initializer for non-zero element");
309*700637cbSDimitry Andric } else if (elements.size() != arrayBound) {
310*700637cbSDimitry Andric elements.resize(arrayBound, filler);
311*700637cbSDimitry Andric
312*700637cbSDimitry Andric if (filler.getType() != commonElementType)
313*700637cbSDimitry Andric commonElementType = {};
314*700637cbSDimitry Andric }
315*700637cbSDimitry Andric
316*700637cbSDimitry Andric if (commonElementType) {
317*700637cbSDimitry Andric SmallVector<mlir::Attribute, 4> eles;
318*700637cbSDimitry Andric eles.reserve(elements.size());
319*700637cbSDimitry Andric
320*700637cbSDimitry Andric for (const auto &element : elements)
321*700637cbSDimitry Andric eles.push_back(element);
322*700637cbSDimitry Andric
323*700637cbSDimitry Andric return cir::ConstArrayAttr::get(
324*700637cbSDimitry Andric cir::ArrayType::get(commonElementType, arrayBound),
325*700637cbSDimitry Andric mlir::ArrayAttr::get(builder.getContext(), eles));
326*700637cbSDimitry Andric }
327*700637cbSDimitry Andric
328*700637cbSDimitry Andric cgm.errorNYI("array with different type elements");
329*700637cbSDimitry Andric return {};
330*700637cbSDimitry Andric }
331*700637cbSDimitry Andric
332*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
333*700637cbSDimitry Andric // ConstantLValueEmitter
334*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
335*700637cbSDimitry Andric
336*700637cbSDimitry Andric namespace {
337*700637cbSDimitry Andric /// A struct which can be used to peephole certain kinds of finalization
338*700637cbSDimitry Andric /// that normally happen during l-value emission.
339*700637cbSDimitry Andric struct ConstantLValue {
340*700637cbSDimitry Andric llvm::PointerUnion<mlir::Value, mlir::Attribute> value;
341*700637cbSDimitry Andric bool hasOffsetApplied;
342*700637cbSDimitry Andric
ConstantLValue__anon56f2e7ec0111::ConstantLValue343*700637cbSDimitry Andric ConstantLValue(std::nullptr_t) : value(nullptr), hasOffsetApplied(false) {}
ConstantLValue__anon56f2e7ec0111::ConstantLValue344*700637cbSDimitry Andric ConstantLValue() : value(nullptr), hasOffsetApplied(false) {}
345*700637cbSDimitry Andric };
346*700637cbSDimitry Andric
347*700637cbSDimitry Andric /// A helper class for emitting constant l-values.
348*700637cbSDimitry Andric class ConstantLValueEmitter
349*700637cbSDimitry Andric : public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> {
350*700637cbSDimitry Andric CIRGenModule &cgm;
351*700637cbSDimitry Andric ConstantEmitter &emitter;
352*700637cbSDimitry Andric const APValue &value;
353*700637cbSDimitry Andric QualType destType;
354*700637cbSDimitry Andric
355*700637cbSDimitry Andric // Befriend StmtVisitorBase so that we don't have to expose Visit*.
356*700637cbSDimitry Andric friend StmtVisitorBase;
357*700637cbSDimitry Andric
358*700637cbSDimitry Andric public:
ConstantLValueEmitter(ConstantEmitter & emitter,const APValue & value,QualType destType)359*700637cbSDimitry Andric ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,
360*700637cbSDimitry Andric QualType destType)
361*700637cbSDimitry Andric : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}
362*700637cbSDimitry Andric
363*700637cbSDimitry Andric mlir::Attribute tryEmit();
364*700637cbSDimitry Andric
365*700637cbSDimitry Andric private:
366*700637cbSDimitry Andric mlir::Attribute tryEmitAbsolute(mlir::Type destTy);
367*700637cbSDimitry Andric ConstantLValue tryEmitBase(const APValue::LValueBase &base);
368*700637cbSDimitry Andric
VisitStmt(const Stmt * s)369*700637cbSDimitry Andric ConstantLValue VisitStmt(const Stmt *s) { return nullptr; }
370*700637cbSDimitry Andric ConstantLValue VisitConstantExpr(const ConstantExpr *e);
371*700637cbSDimitry Andric ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e);
372*700637cbSDimitry Andric ConstantLValue VisitStringLiteral(const StringLiteral *e);
373*700637cbSDimitry Andric ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e);
374*700637cbSDimitry Andric ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e);
375*700637cbSDimitry Andric ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e);
376*700637cbSDimitry Andric ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e);
377*700637cbSDimitry Andric ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e);
378*700637cbSDimitry Andric ConstantLValue VisitCallExpr(const CallExpr *e);
379*700637cbSDimitry Andric ConstantLValue VisitBlockExpr(const BlockExpr *e);
380*700637cbSDimitry Andric ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e);
381*700637cbSDimitry Andric ConstantLValue
382*700637cbSDimitry Andric VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e);
383*700637cbSDimitry Andric };
384*700637cbSDimitry Andric
385*700637cbSDimitry Andric } // namespace
386*700637cbSDimitry Andric
tryEmit()387*700637cbSDimitry Andric mlir::Attribute ConstantLValueEmitter::tryEmit() {
388*700637cbSDimitry Andric const APValue::LValueBase &base = value.getLValueBase();
389*700637cbSDimitry Andric
390*700637cbSDimitry Andric // The destination type should be a pointer or reference
391*700637cbSDimitry Andric // type, but it might also be a cast thereof.
392*700637cbSDimitry Andric //
393*700637cbSDimitry Andric // FIXME: the chain of casts required should be reflected in the APValue.
394*700637cbSDimitry Andric // We need this in order to correctly handle things like a ptrtoint of a
395*700637cbSDimitry Andric // non-zero null pointer and addrspace casts that aren't trivially
396*700637cbSDimitry Andric // represented in LLVM IR.
397*700637cbSDimitry Andric mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
398*700637cbSDimitry Andric assert(mlir::isa<cir::PointerType>(destTy));
399*700637cbSDimitry Andric
400*700637cbSDimitry Andric // If there's no base at all, this is a null or absolute pointer,
401*700637cbSDimitry Andric // possibly cast back to an integer type.
402*700637cbSDimitry Andric if (!base)
403*700637cbSDimitry Andric return tryEmitAbsolute(destTy);
404*700637cbSDimitry Andric
405*700637cbSDimitry Andric // Otherwise, try to emit the base.
406*700637cbSDimitry Andric ConstantLValue result = tryEmitBase(base);
407*700637cbSDimitry Andric
408*700637cbSDimitry Andric // If that failed, we're done.
409*700637cbSDimitry Andric llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;
410*700637cbSDimitry Andric if (!value)
411*700637cbSDimitry Andric return {};
412*700637cbSDimitry Andric
413*700637cbSDimitry Andric // Apply the offset if necessary and not already done.
414*700637cbSDimitry Andric if (!result.hasOffsetApplied) {
415*700637cbSDimitry Andric cgm.errorNYI("ConstantLValueEmitter: apply offset");
416*700637cbSDimitry Andric return {};
417*700637cbSDimitry Andric }
418*700637cbSDimitry Andric
419*700637cbSDimitry Andric // Convert to the appropriate type; this could be an lvalue for
420*700637cbSDimitry Andric // an integer. FIXME: performAddrSpaceCast
421*700637cbSDimitry Andric if (mlir::isa<cir::PointerType>(destTy)) {
422*700637cbSDimitry Andric if (auto attr = mlir::dyn_cast<mlir::Attribute>(value))
423*700637cbSDimitry Andric return attr;
424*700637cbSDimitry Andric cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer");
425*700637cbSDimitry Andric return {};
426*700637cbSDimitry Andric }
427*700637cbSDimitry Andric
428*700637cbSDimitry Andric cgm.errorNYI("ConstantLValueEmitter: other?");
429*700637cbSDimitry Andric return {};
430*700637cbSDimitry Andric }
431*700637cbSDimitry Andric
432*700637cbSDimitry Andric /// Try to emit an absolute l-value, such as a null pointer or an integer
433*700637cbSDimitry Andric /// bitcast to pointer type.
tryEmitAbsolute(mlir::Type destTy)434*700637cbSDimitry Andric mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {
435*700637cbSDimitry Andric // If we're producing a pointer, this is easy.
436*700637cbSDimitry Andric auto destPtrTy = mlir::cast<cir::PointerType>(destTy);
437*700637cbSDimitry Andric return cgm.getBuilder().getConstPtrAttr(
438*700637cbSDimitry Andric destPtrTy, value.getLValueOffset().getQuantity());
439*700637cbSDimitry Andric }
440*700637cbSDimitry Andric
441*700637cbSDimitry Andric ConstantLValue
tryEmitBase(const APValue::LValueBase & base)442*700637cbSDimitry Andric ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
443*700637cbSDimitry Andric // Handle values.
444*700637cbSDimitry Andric if (const ValueDecl *d = base.dyn_cast<const ValueDecl *>()) {
445*700637cbSDimitry Andric // The constant always points to the canonical declaration. We want to look
446*700637cbSDimitry Andric // at properties of the most recent declaration at the point of emission.
447*700637cbSDimitry Andric d = cast<ValueDecl>(d->getMostRecentDecl());
448*700637cbSDimitry Andric
449*700637cbSDimitry Andric if (d->hasAttr<WeakRefAttr>()) {
450*700637cbSDimitry Andric cgm.errorNYI(d->getSourceRange(),
451*700637cbSDimitry Andric "ConstantLValueEmitter: emit pointer base for weakref");
452*700637cbSDimitry Andric return {};
453*700637cbSDimitry Andric }
454*700637cbSDimitry Andric
455*700637cbSDimitry Andric if (auto *fd = dyn_cast<FunctionDecl>(d)) {
456*700637cbSDimitry Andric cgm.errorNYI(fd->getSourceRange(),
457*700637cbSDimitry Andric "ConstantLValueEmitter: function decl");
458*700637cbSDimitry Andric return {};
459*700637cbSDimitry Andric }
460*700637cbSDimitry Andric
461*700637cbSDimitry Andric if (auto *vd = dyn_cast<VarDecl>(d)) {
462*700637cbSDimitry Andric cgm.errorNYI(vd->getSourceRange(), "ConstantLValueEmitter: var decl");
463*700637cbSDimitry Andric return {};
464*700637cbSDimitry Andric }
465*700637cbSDimitry Andric }
466*700637cbSDimitry Andric
467*700637cbSDimitry Andric // Handle typeid(T).
468*700637cbSDimitry Andric if (base.dyn_cast<TypeInfoLValue>()) {
469*700637cbSDimitry Andric cgm.errorNYI("ConstantLValueEmitter: typeid");
470*700637cbSDimitry Andric return {};
471*700637cbSDimitry Andric }
472*700637cbSDimitry Andric
473*700637cbSDimitry Andric // Otherwise, it must be an expression.
474*700637cbSDimitry Andric return Visit(base.get<const Expr *>());
475*700637cbSDimitry Andric }
476*700637cbSDimitry Andric
VisitConstantExpr(const ConstantExpr * e)477*700637cbSDimitry Andric ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) {
478*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr");
479*700637cbSDimitry Andric return {};
480*700637cbSDimitry Andric }
481*700637cbSDimitry Andric
482*700637cbSDimitry Andric ConstantLValue
VisitCompoundLiteralExpr(const CompoundLiteralExpr * e)483*700637cbSDimitry Andric ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {
484*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: compound literal");
485*700637cbSDimitry Andric return {};
486*700637cbSDimitry Andric }
487*700637cbSDimitry Andric
488*700637cbSDimitry Andric ConstantLValue
VisitStringLiteral(const StringLiteral * e)489*700637cbSDimitry Andric ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {
490*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: string literal");
491*700637cbSDimitry Andric return {};
492*700637cbSDimitry Andric }
493*700637cbSDimitry Andric
494*700637cbSDimitry Andric ConstantLValue
VisitObjCEncodeExpr(const ObjCEncodeExpr * e)495*700637cbSDimitry Andric ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) {
496*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr");
497*700637cbSDimitry Andric return {};
498*700637cbSDimitry Andric }
499*700637cbSDimitry Andric
500*700637cbSDimitry Andric ConstantLValue
VisitObjCStringLiteral(const ObjCStringLiteral * e)501*700637cbSDimitry Andric ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) {
502*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(),
503*700637cbSDimitry Andric "ConstantLValueEmitter: objc string literal");
504*700637cbSDimitry Andric return {};
505*700637cbSDimitry Andric }
506*700637cbSDimitry Andric
507*700637cbSDimitry Andric ConstantLValue
VisitObjCBoxedExpr(const ObjCBoxedExpr * e)508*700637cbSDimitry Andric ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) {
509*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr");
510*700637cbSDimitry Andric return {};
511*700637cbSDimitry Andric }
512*700637cbSDimitry Andric
513*700637cbSDimitry Andric ConstantLValue
VisitPredefinedExpr(const PredefinedExpr * e)514*700637cbSDimitry Andric ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) {
515*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: predefined expr");
516*700637cbSDimitry Andric return {};
517*700637cbSDimitry Andric }
518*700637cbSDimitry Andric
519*700637cbSDimitry Andric ConstantLValue
VisitAddrLabelExpr(const AddrLabelExpr * e)520*700637cbSDimitry Andric ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) {
521*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: addr label expr");
522*700637cbSDimitry Andric return {};
523*700637cbSDimitry Andric }
524*700637cbSDimitry Andric
VisitCallExpr(const CallExpr * e)525*700637cbSDimitry Andric ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) {
526*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr");
527*700637cbSDimitry Andric return {};
528*700637cbSDimitry Andric }
529*700637cbSDimitry Andric
VisitBlockExpr(const BlockExpr * e)530*700637cbSDimitry Andric ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) {
531*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr");
532*700637cbSDimitry Andric return {};
533*700637cbSDimitry Andric }
534*700637cbSDimitry Andric
535*700637cbSDimitry Andric ConstantLValue
VisitCXXTypeidExpr(const CXXTypeidExpr * e)536*700637cbSDimitry Andric ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) {
537*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: cxx typeid expr");
538*700637cbSDimitry Andric return {};
539*700637cbSDimitry Andric }
540*700637cbSDimitry Andric
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * e)541*700637cbSDimitry Andric ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
542*700637cbSDimitry Andric const MaterializeTemporaryExpr *e) {
543*700637cbSDimitry Andric cgm.errorNYI(e->getSourceRange(),
544*700637cbSDimitry Andric "ConstantLValueEmitter: materialize temporary expr");
545*700637cbSDimitry Andric return {};
546*700637cbSDimitry Andric }
547*700637cbSDimitry Andric
548*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
549*700637cbSDimitry Andric // ConstantEmitter
550*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
551*700637cbSDimitry Andric
tryEmitForInitializer(const VarDecl & d)552*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::tryEmitForInitializer(const VarDecl &d) {
553*700637cbSDimitry Andric initializeNonAbstract();
554*700637cbSDimitry Andric return markIfFailed(tryEmitPrivateForVarInit(d));
555*700637cbSDimitry Andric }
556*700637cbSDimitry Andric
finalize(cir::GlobalOp gv)557*700637cbSDimitry Andric void ConstantEmitter::finalize(cir::GlobalOp gv) {
558*700637cbSDimitry Andric assert(initializedNonAbstract &&
559*700637cbSDimitry Andric "finalizing emitter that was used for abstract emission?");
560*700637cbSDimitry Andric assert(!finalized && "finalizing emitter multiple times");
561*700637cbSDimitry Andric assert(!gv.isDeclaration());
562*700637cbSDimitry Andric #ifndef NDEBUG
563*700637cbSDimitry Andric // Note that we might also be Failed.
564*700637cbSDimitry Andric finalized = true;
565*700637cbSDimitry Andric #endif // NDEBUG
566*700637cbSDimitry Andric }
567*700637cbSDimitry Andric
568*700637cbSDimitry Andric mlir::Attribute
tryEmitAbstractForInitializer(const VarDecl & d)569*700637cbSDimitry Andric ConstantEmitter::tryEmitAbstractForInitializer(const VarDecl &d) {
570*700637cbSDimitry Andric AbstractStateRAII state(*this, true);
571*700637cbSDimitry Andric return tryEmitPrivateForVarInit(d);
572*700637cbSDimitry Andric }
573*700637cbSDimitry Andric
~ConstantEmitter()574*700637cbSDimitry Andric ConstantEmitter::~ConstantEmitter() {
575*700637cbSDimitry Andric assert((!initializedNonAbstract || finalized || failed) &&
576*700637cbSDimitry Andric "not finalized after being initialized for non-abstract emission");
577*700637cbSDimitry Andric }
578*700637cbSDimitry Andric
tryEmitPrivateForVarInit(const VarDecl & d)579*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) {
580*700637cbSDimitry Andric // Make a quick check if variable can be default NULL initialized
581*700637cbSDimitry Andric // and avoid going through rest of code which may do, for c++11,
582*700637cbSDimitry Andric // initialization of memory to all NULLs.
583*700637cbSDimitry Andric if (!d.hasLocalStorage()) {
584*700637cbSDimitry Andric QualType ty = cgm.getASTContext().getBaseElementType(d.getType());
585*700637cbSDimitry Andric if (ty->isRecordType()) {
586*700637cbSDimitry Andric if (const auto *e = dyn_cast_or_null<CXXConstructExpr>(d.getInit())) {
587*700637cbSDimitry Andric const CXXConstructorDecl *cd = e->getConstructor();
588*700637cbSDimitry Andric // FIXME: we should probably model this more closely to C++ than
589*700637cbSDimitry Andric // just emitting a global with zero init (mimic what we do for trivial
590*700637cbSDimitry Andric // assignments and whatnots). Since this is for globals shouldn't
591*700637cbSDimitry Andric // be a problem for the near future.
592*700637cbSDimitry Andric if (cd->isTrivial() && cd->isDefaultConstructor()) {
593*700637cbSDimitry Andric const auto *cxxrd =
594*700637cbSDimitry Andric cast<CXXRecordDecl>(ty->getAs<RecordType>()->getDecl());
595*700637cbSDimitry Andric if (cxxrd->getNumBases() != 0) {
596*700637cbSDimitry Andric // There may not be anything additional to do here, but this will
597*700637cbSDimitry Andric // force us to pause and test this path when it is supported.
598*700637cbSDimitry Andric cgm.errorNYI("tryEmitPrivateForVarInit: cxx record with bases");
599*700637cbSDimitry Andric return {};
600*700637cbSDimitry Andric }
601*700637cbSDimitry Andric if (!cgm.getTypes().isZeroInitializable(cxxrd)) {
602*700637cbSDimitry Andric // To handle this case, we really need to go through
603*700637cbSDimitry Andric // emitNullConstant, but we need an attribute, not a value
604*700637cbSDimitry Andric cgm.errorNYI(
605*700637cbSDimitry Andric "tryEmitPrivateForVarInit: non-zero-initializable cxx record");
606*700637cbSDimitry Andric return {};
607*700637cbSDimitry Andric }
608*700637cbSDimitry Andric return cir::ZeroAttr::get(cgm.convertType(d.getType()));
609*700637cbSDimitry Andric }
610*700637cbSDimitry Andric }
611*700637cbSDimitry Andric }
612*700637cbSDimitry Andric }
613*700637cbSDimitry Andric inConstantContext = d.hasConstantInitialization();
614*700637cbSDimitry Andric
615*700637cbSDimitry Andric const Expr *e = d.getInit();
616*700637cbSDimitry Andric assert(e && "No initializer to emit");
617*700637cbSDimitry Andric
618*700637cbSDimitry Andric QualType destType = d.getType();
619*700637cbSDimitry Andric
620*700637cbSDimitry Andric if (!destType->isReferenceType()) {
621*700637cbSDimitry Andric QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
622*700637cbSDimitry Andric if (mlir::Attribute c = ConstExprEmitter(*this).Visit(const_cast<Expr *>(e),
623*700637cbSDimitry Andric nonMemoryDestType))
624*700637cbSDimitry Andric return emitForMemory(c, destType);
625*700637cbSDimitry Andric }
626*700637cbSDimitry Andric
627*700637cbSDimitry Andric // Try to emit the initializer. Note that this can allow some things that
628*700637cbSDimitry Andric // are not allowed by tryEmitPrivateForMemory alone.
629*700637cbSDimitry Andric if (APValue *value = d.evaluateValue())
630*700637cbSDimitry Andric return tryEmitPrivateForMemory(*value, destType);
631*700637cbSDimitry Andric
632*700637cbSDimitry Andric return {};
633*700637cbSDimitry Andric }
634*700637cbSDimitry Andric
tryEmitConstantExpr(const ConstantExpr * ce)635*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *ce) {
636*700637cbSDimitry Andric if (!ce->hasAPValueResult())
637*700637cbSDimitry Andric return {};
638*700637cbSDimitry Andric
639*700637cbSDimitry Andric QualType retType = ce->getType();
640*700637cbSDimitry Andric if (ce->isGLValue())
641*700637cbSDimitry Andric retType = cgm.getASTContext().getLValueReferenceType(retType);
642*700637cbSDimitry Andric
643*700637cbSDimitry Andric return emitAbstract(ce->getBeginLoc(), ce->getAPValueResult(), retType);
644*700637cbSDimitry Andric }
645*700637cbSDimitry Andric
tryEmitPrivateForMemory(const APValue & value,QualType destType)646*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::tryEmitPrivateForMemory(const APValue &value,
647*700637cbSDimitry Andric QualType destType) {
648*700637cbSDimitry Andric QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
649*700637cbSDimitry Andric mlir::Attribute c = tryEmitPrivate(value, nonMemoryDestType);
650*700637cbSDimitry Andric return (c ? emitForMemory(c, destType) : nullptr);
651*700637cbSDimitry Andric }
652*700637cbSDimitry Andric
emitAbstract(SourceLocation loc,const APValue & value,QualType destType)653*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::emitAbstract(SourceLocation loc,
654*700637cbSDimitry Andric const APValue &value,
655*700637cbSDimitry Andric QualType destType) {
656*700637cbSDimitry Andric AbstractStateRAII state(*this, true);
657*700637cbSDimitry Andric mlir::Attribute c = tryEmitPrivate(value, destType);
658*700637cbSDimitry Andric if (!c)
659*700637cbSDimitry Andric cgm.errorNYI(loc, "emitAbstract failed, emit null constaant");
660*700637cbSDimitry Andric return c;
661*700637cbSDimitry Andric }
662*700637cbSDimitry Andric
emitForMemory(mlir::Attribute c,QualType destType)663*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::emitForMemory(mlir::Attribute c,
664*700637cbSDimitry Andric QualType destType) {
665*700637cbSDimitry Andric // For an _Atomic-qualified constant, we may need to add tail padding.
666*700637cbSDimitry Andric if (destType->getAs<AtomicType>()) {
667*700637cbSDimitry Andric cgm.errorNYI("emitForMemory: atomic type");
668*700637cbSDimitry Andric return {};
669*700637cbSDimitry Andric }
670*700637cbSDimitry Andric
671*700637cbSDimitry Andric return c;
672*700637cbSDimitry Andric }
673*700637cbSDimitry Andric
tryEmitPrivate(const APValue & value,QualType destType)674*700637cbSDimitry Andric mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
675*700637cbSDimitry Andric QualType destType) {
676*700637cbSDimitry Andric auto &builder = cgm.getBuilder();
677*700637cbSDimitry Andric switch (value.getKind()) {
678*700637cbSDimitry Andric case APValue::None:
679*700637cbSDimitry Andric case APValue::Indeterminate:
680*700637cbSDimitry Andric cgm.errorNYI("ConstExprEmitter::tryEmitPrivate none or indeterminate");
681*700637cbSDimitry Andric return {};
682*700637cbSDimitry Andric case APValue::Int: {
683*700637cbSDimitry Andric mlir::Type ty = cgm.convertType(destType);
684*700637cbSDimitry Andric if (mlir::isa<cir::BoolType>(ty))
685*700637cbSDimitry Andric return builder.getCIRBoolAttr(value.getInt().getZExtValue());
686*700637cbSDimitry Andric assert(mlir::isa<cir::IntType>(ty) && "expected integral type");
687*700637cbSDimitry Andric return cir::IntAttr::get(ty, value.getInt());
688*700637cbSDimitry Andric }
689*700637cbSDimitry Andric case APValue::Float: {
690*700637cbSDimitry Andric const llvm::APFloat &init = value.getFloat();
691*700637cbSDimitry Andric if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
692*700637cbSDimitry Andric !cgm.getASTContext().getLangOpts().NativeHalfType &&
693*700637cbSDimitry Andric cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {
694*700637cbSDimitry Andric cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half");
695*700637cbSDimitry Andric return {};
696*700637cbSDimitry Andric }
697*700637cbSDimitry Andric
698*700637cbSDimitry Andric mlir::Type ty = cgm.convertType(destType);
699*700637cbSDimitry Andric assert(mlir::isa<cir::FPTypeInterface>(ty) &&
700*700637cbSDimitry Andric "expected floating-point type");
701*700637cbSDimitry Andric return cir::FPAttr::get(ty, init);
702*700637cbSDimitry Andric }
703*700637cbSDimitry Andric case APValue::Array: {
704*700637cbSDimitry Andric const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType);
705*700637cbSDimitry Andric const QualType arrayElementTy = arrayTy->getElementType();
706*700637cbSDimitry Andric const unsigned numElements = value.getArraySize();
707*700637cbSDimitry Andric const unsigned numInitElts = value.getArrayInitializedElts();
708*700637cbSDimitry Andric
709*700637cbSDimitry Andric mlir::Attribute filler;
710*700637cbSDimitry Andric if (value.hasArrayFiller()) {
711*700637cbSDimitry Andric filler = tryEmitPrivate(value.getArrayFiller(), arrayElementTy);
712*700637cbSDimitry Andric if (!filler)
713*700637cbSDimitry Andric return {};
714*700637cbSDimitry Andric }
715*700637cbSDimitry Andric
716*700637cbSDimitry Andric SmallVector<mlir::TypedAttr, 16> elements;
717*700637cbSDimitry Andric if (filler && builder.isNullValue(filler))
718*700637cbSDimitry Andric elements.reserve(numInitElts + 1);
719*700637cbSDimitry Andric else
720*700637cbSDimitry Andric elements.reserve(numInitElts);
721*700637cbSDimitry Andric
722*700637cbSDimitry Andric mlir::Type commonElementType;
723*700637cbSDimitry Andric for (unsigned i = 0; i < numInitElts; ++i) {
724*700637cbSDimitry Andric const APValue &arrayElement = value.getArrayInitializedElt(i);
725*700637cbSDimitry Andric const mlir::Attribute element =
726*700637cbSDimitry Andric tryEmitPrivateForMemory(arrayElement, arrayElementTy);
727*700637cbSDimitry Andric if (!element)
728*700637cbSDimitry Andric return {};
729*700637cbSDimitry Andric
730*700637cbSDimitry Andric const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);
731*700637cbSDimitry Andric if (i == 0)
732*700637cbSDimitry Andric commonElementType = elementTyped.getType();
733*700637cbSDimitry Andric else if (elementTyped.getType() != commonElementType) {
734*700637cbSDimitry Andric commonElementType = {};
735*700637cbSDimitry Andric }
736*700637cbSDimitry Andric
737*700637cbSDimitry Andric elements.push_back(elementTyped);
738*700637cbSDimitry Andric }
739*700637cbSDimitry Andric
740*700637cbSDimitry Andric mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler);
741*700637cbSDimitry Andric if (filler && !typedFiller)
742*700637cbSDimitry Andric cgm.errorNYI("array filler should always be typed");
743*700637cbSDimitry Andric
744*700637cbSDimitry Andric mlir::Type desiredType = cgm.convertType(destType);
745*700637cbSDimitry Andric return emitArrayConstant(cgm, desiredType, commonElementType, numElements,
746*700637cbSDimitry Andric elements, typedFiller);
747*700637cbSDimitry Andric }
748*700637cbSDimitry Andric case APValue::Vector: {
749*700637cbSDimitry Andric const QualType elementType =
750*700637cbSDimitry Andric destType->castAs<VectorType>()->getElementType();
751*700637cbSDimitry Andric const unsigned numElements = value.getVectorLength();
752*700637cbSDimitry Andric
753*700637cbSDimitry Andric SmallVector<mlir::Attribute, 16> elements;
754*700637cbSDimitry Andric elements.reserve(numElements);
755*700637cbSDimitry Andric
756*700637cbSDimitry Andric for (unsigned i = 0; i < numElements; ++i) {
757*700637cbSDimitry Andric const mlir::Attribute element =
758*700637cbSDimitry Andric tryEmitPrivateForMemory(value.getVectorElt(i), elementType);
759*700637cbSDimitry Andric if (!element)
760*700637cbSDimitry Andric return {};
761*700637cbSDimitry Andric elements.push_back(element);
762*700637cbSDimitry Andric }
763*700637cbSDimitry Andric
764*700637cbSDimitry Andric const auto desiredVecTy =
765*700637cbSDimitry Andric mlir::cast<cir::VectorType>(cgm.convertType(destType));
766*700637cbSDimitry Andric
767*700637cbSDimitry Andric return cir::ConstVectorAttr::get(
768*700637cbSDimitry Andric desiredVecTy,
769*700637cbSDimitry Andric mlir::ArrayAttr::get(cgm.getBuilder().getContext(), elements));
770*700637cbSDimitry Andric }
771*700637cbSDimitry Andric case APValue::MemberPointer: {
772*700637cbSDimitry Andric cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer");
773*700637cbSDimitry Andric return {};
774*700637cbSDimitry Andric }
775*700637cbSDimitry Andric case APValue::LValue:
776*700637cbSDimitry Andric return ConstantLValueEmitter(*this, value, destType).tryEmit();
777*700637cbSDimitry Andric case APValue::Struct:
778*700637cbSDimitry Andric case APValue::Union:
779*700637cbSDimitry Andric cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union");
780*700637cbSDimitry Andric return {};
781*700637cbSDimitry Andric case APValue::ComplexInt:
782*700637cbSDimitry Andric case APValue::ComplexFloat: {
783*700637cbSDimitry Andric mlir::Type desiredType = cgm.convertType(destType);
784*700637cbSDimitry Andric cir::ComplexType complexType =
785*700637cbSDimitry Andric mlir::dyn_cast<cir::ComplexType>(desiredType);
786*700637cbSDimitry Andric
787*700637cbSDimitry Andric mlir::Type complexElemTy = complexType.getElementType();
788*700637cbSDimitry Andric if (isa<cir::IntType>(complexElemTy)) {
789*700637cbSDimitry Andric llvm::APSInt real = value.getComplexIntReal();
790*700637cbSDimitry Andric llvm::APSInt imag = value.getComplexIntImag();
791*700637cbSDimitry Andric return builder.getAttr<cir::ConstComplexAttr>(
792*700637cbSDimitry Andric complexType, cir::IntAttr::get(complexElemTy, real),
793*700637cbSDimitry Andric cir::IntAttr::get(complexElemTy, imag));
794*700637cbSDimitry Andric }
795*700637cbSDimitry Andric
796*700637cbSDimitry Andric assert(isa<cir::FPTypeInterface>(complexElemTy) &&
797*700637cbSDimitry Andric "expected floating-point type");
798*700637cbSDimitry Andric llvm::APFloat real = value.getComplexFloatReal();
799*700637cbSDimitry Andric llvm::APFloat imag = value.getComplexFloatImag();
800*700637cbSDimitry Andric return builder.getAttr<cir::ConstComplexAttr>(
801*700637cbSDimitry Andric complexType, cir::FPAttr::get(complexElemTy, real),
802*700637cbSDimitry Andric cir::FPAttr::get(complexElemTy, imag));
803*700637cbSDimitry Andric }
804*700637cbSDimitry Andric case APValue::FixedPoint:
805*700637cbSDimitry Andric case APValue::AddrLabelDiff:
806*700637cbSDimitry Andric cgm.errorNYI(
807*700637cbSDimitry Andric "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
808*700637cbSDimitry Andric return {};
809*700637cbSDimitry Andric }
810*700637cbSDimitry Andric llvm_unreachable("Unknown APValue kind");
811*700637cbSDimitry Andric }
812*700637cbSDimitry Andric
emitNullConstant(QualType t,mlir::Location loc)813*700637cbSDimitry Andric mlir::Value CIRGenModule::emitNullConstant(QualType t, mlir::Location loc) {
814*700637cbSDimitry Andric if (t->getAs<PointerType>()) {
815*700637cbSDimitry Andric return builder.getNullPtr(getTypes().convertTypeForMem(t), loc);
816*700637cbSDimitry Andric }
817*700637cbSDimitry Andric
818*700637cbSDimitry Andric if (getTypes().isZeroInitializable(t))
819*700637cbSDimitry Andric return builder.getNullValue(getTypes().convertTypeForMem(t), loc);
820*700637cbSDimitry Andric
821*700637cbSDimitry Andric if (getASTContext().getAsConstantArrayType(t)) {
822*700637cbSDimitry Andric errorNYI("CIRGenModule::emitNullConstant ConstantArrayType");
823*700637cbSDimitry Andric }
824*700637cbSDimitry Andric
825*700637cbSDimitry Andric if (t->getAs<RecordType>())
826*700637cbSDimitry Andric errorNYI("CIRGenModule::emitNullConstant RecordType");
827*700637cbSDimitry Andric
828*700637cbSDimitry Andric assert(t->isMemberDataPointerType() &&
829*700637cbSDimitry Andric "Should only see pointers to data members here!");
830*700637cbSDimitry Andric
831*700637cbSDimitry Andric errorNYI("CIRGenModule::emitNullConstant unsupported type");
832*700637cbSDimitry Andric return {};
833*700637cbSDimitry Andric }
834