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