clang 22.0.0git
CIRGenExprComplex.cpp
Go to the documentation of this file.
1#include "CIRGenBuilder.h"
2#include "CIRGenFunction.h"
3
5
6using namespace clang;
7using namespace clang::CIRGen;
8
9namespace {
10class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
11 CIRGenFunction &cgf;
12 CIRGenBuilderTy &builder;
13
14public:
15 explicit ComplexExprEmitter(CIRGenFunction &cgf)
16 : cgf(cgf), builder(cgf.getBuilder()) {}
17
18 //===--------------------------------------------------------------------===//
19 // Utilities
20 //===--------------------------------------------------------------------===//
21
22 LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val);
23
24 mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy);
25
26 mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant,
27 Expr *e);
28
29 /// Given an expression with complex type that represents a value l-value,
30 /// this method emits the address of the l-value, then loads and returns the
31 /// result.
32 mlir::Value emitLoadOfLValue(const Expr *e) {
33 return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc());
34 }
35
36 mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
37
38 /// Store the specified real/imag parts into the
39 /// specified value pointer.
40 void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
41 bool isInit);
42
43 /// Emit a cast from complex value Val to DestType.
44 mlir::Value emitComplexToComplexCast(mlir::Value value, QualType srcType,
45 QualType destType, SourceLocation loc);
46
47 /// Emit a cast from scalar value Val to DestType.
48 mlir::Value emitScalarToComplexCast(mlir::Value value, QualType srcType,
49 QualType destType, SourceLocation loc);
50
51 mlir::Value
52 VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
53 mlir::Value VisitArraySubscriptExpr(Expr *e);
54 mlir::Value VisitBinAssign(const BinaryOperator *e);
55 mlir::Value VisitBinComma(const BinaryOperator *e);
56 mlir::Value VisitCallExpr(const CallExpr *e);
57 mlir::Value VisitCastExpr(CastExpr *e);
58 mlir::Value VisitChooseExpr(ChooseExpr *e);
59 mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e);
60 mlir::Value VisitDeclRefExpr(DeclRefExpr *e);
61 mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *e);
62 mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e);
63 mlir::Value VisitInitListExpr(InitListExpr *e);
64
65 mlir::Value VisitMemberExpr(MemberExpr *me) {
67 cgf.emitIgnoredExpr(me->getBase());
68 return emitConstant(constant, me);
69 }
70 return emitLoadOfLValue(me);
71 }
72
73 mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
74 return emitLoadOfLValue(e);
75 }
76
77 mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il);
78 mlir::Value VisitParenExpr(ParenExpr *e);
79 mlir::Value
80 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
81
82 mlir::Value VisitPrePostIncDec(const UnaryOperator *e, cir::UnaryOpKind op,
83 bool isPre);
84
85 mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
86 return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, false);
87 }
88
89 mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
90 return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, false);
91 }
92
93 mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
94 return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, true);
95 }
96
97 mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
98 return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, true);
99 }
100
101 mlir::Value VisitUnaryDeref(const Expr *e);
102
103 mlir::Value VisitUnaryPlus(const UnaryOperator *e);
104
105 mlir::Value VisitPlusMinus(const UnaryOperator *e, cir::UnaryOpKind kind,
106 QualType promotionType);
107
108 mlir::Value VisitUnaryMinus(const UnaryOperator *e);
109
110 mlir::Value VisitUnaryNot(const UnaryOperator *e);
111
112 struct BinOpInfo {
113 mlir::Location loc;
114 mlir::Value lhs{};
115 mlir::Value rhs{};
116 QualType ty{}; // Computation Type.
117 FPOptions fpFeatures{};
118 };
119
120 BinOpInfo emitBinOps(const BinaryOperator *e,
121 QualType promotionTy = QualType());
122
123 mlir::Value emitPromoted(const Expr *e, QualType promotionTy);
124
125 mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);
126
127 LValue emitCompoundAssignLValue(
128 const CompoundAssignOperator *e,
129 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &),
130 RValue &value);
131
132 mlir::Value emitCompoundAssign(
133 const CompoundAssignOperator *e,
134 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &));
135
136 mlir::Value emitBinAdd(const BinOpInfo &op);
137 mlir::Value emitBinSub(const BinOpInfo &op);
138 mlir::Value emitBinMul(const BinOpInfo &op);
139 mlir::Value emitBinDiv(const BinOpInfo &op);
140
141 QualType getPromotionType(QualType ty, bool isDivOpCode = false) {
142 if (auto *complexTy = ty->getAs<ComplexType>()) {
143 QualType elementTy = complexTy->getElementType();
144 if (elementTy.UseExcessPrecision(cgf.getContext()))
145 return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
146 }
147
148 if (ty.UseExcessPrecision(cgf.getContext()))
149 return cgf.getContext().FloatTy;
150 return QualType();
151 }
152
153#define HANDLEBINOP(OP) \
154 mlir::Value VisitBin##OP(const BinaryOperator *e) { \
155 QualType promotionTy = getPromotionType( \
156 e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \
157 mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \
158 if (!promotionTy.isNull()) \
159 result = cgf.emitUnPromotedValue(result, e->getType()); \
160 return result; \
161 }
162
163 HANDLEBINOP(Add)
164 HANDLEBINOP(Sub)
165 HANDLEBINOP(Mul)
166 HANDLEBINOP(Div)
167#undef HANDLEBINOP
168
169 // Compound assignments.
170 mlir::Value VisitBinAddAssign(const CompoundAssignOperator *e) {
171 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinAdd);
172 }
173
174 mlir::Value VisitBinSubAssign(const CompoundAssignOperator *e) {
175 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinSub);
176 }
177
178 mlir::Value VisitBinMulAssign(const CompoundAssignOperator *e) {
179 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinMul);
180 }
181
182 mlir::Value VisitBinDivAssign(const CompoundAssignOperator *e) {
183 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);
184 }
185};
186} // namespace
187
188#ifndef NDEBUG
189// Only used in asserts
191 type = type.getCanonicalType();
192 if (const ComplexType *comp = dyn_cast<ComplexType>(type))
193 return comp;
194 return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
195}
196#endif // NDEBUG
197
198LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,
199 mlir::Value &value) {
200 assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
201 e->getRHS()->getType()) &&
202 "Invalid assignment");
203
204 // Emit the RHS. __block variables need the RHS evaluated first.
205 value = Visit(e->getRHS());
206
207 // Compute the address to store into.
208 LValue lhs = cgf.emitLValue(e->getLHS());
209
210 // Store the result value into the LHS lvalue.
211 emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs, /*isInit*/ false);
212 return lhs;
213}
214
215mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
216 QualType destTy) {
217 switch (ck) {
218 case CK_Dependent:
219 llvm_unreachable("dependent type must be resolved before the CIR codegen");
220
221 case CK_NoOp:
222 case CK_LValueToRValue:
223 return Visit(op);
224
225 case CK_AtomicToNonAtomic:
226 case CK_NonAtomicToAtomic:
227 case CK_UserDefinedConversion: {
228 cgf.cgm.errorNYI(
229 "ComplexExprEmitter::emitCast Atmoic & UserDefinedConversion");
230 return {};
231 }
232
233 case CK_LValueBitCast: {
234 LValue origLV = cgf.emitLValue(op);
235 Address addr =
236 origLV.getAddress().withElementType(builder, cgf.convertType(destTy));
237 LValue destLV = cgf.makeAddrLValue(addr, destTy);
238 return emitLoadOfLValue(destLV, op->getExprLoc());
239 }
240
241 case CK_LValueToRValueBitCast: {
242 LValue sourceLVal = cgf.emitLValue(op);
243 Address addr = sourceLVal.getAddress().withElementType(
244 builder, cgf.convertTypeForMem(destTy));
245 LValue destLV = cgf.makeAddrLValue(addr, destTy);
247 return emitLoadOfLValue(destLV, op->getExprLoc());
248 }
249
250 case CK_BitCast:
251 case CK_BaseToDerived:
252 case CK_DerivedToBase:
253 case CK_UncheckedDerivedToBase:
254 case CK_Dynamic:
255 case CK_ToUnion:
256 case CK_ArrayToPointerDecay:
257 case CK_FunctionToPointerDecay:
258 case CK_NullToPointer:
259 case CK_NullToMemberPointer:
260 case CK_BaseToDerivedMemberPointer:
261 case CK_DerivedToBaseMemberPointer:
262 case CK_MemberPointerToBoolean:
263 case CK_ReinterpretMemberPointer:
264 case CK_ConstructorConversion:
265 case CK_IntegralToPointer:
266 case CK_PointerToIntegral:
267 case CK_PointerToBoolean:
268 case CK_ToVoid:
269 case CK_VectorSplat:
270 case CK_IntegralCast:
271 case CK_BooleanToSignedIntegral:
272 case CK_IntegralToBoolean:
273 case CK_IntegralToFloating:
274 case CK_FloatingToIntegral:
275 case CK_FloatingToBoolean:
276 case CK_FloatingCast:
277 case CK_CPointerToObjCPointerCast:
278 case CK_BlockPointerToObjCPointerCast:
279 case CK_AnyPointerToBlockPointerCast:
280 case CK_ObjCObjectLValueCast:
281 case CK_FloatingComplexToReal:
282 case CK_FloatingComplexToBoolean:
283 case CK_IntegralComplexToReal:
284 case CK_IntegralComplexToBoolean:
285 case CK_ARCProduceObject:
286 case CK_ARCConsumeObject:
287 case CK_ARCReclaimReturnedObject:
288 case CK_ARCExtendBlockObject:
289 case CK_CopyAndAutoreleaseBlockObject:
290 case CK_BuiltinFnToFnPtr:
291 case CK_ZeroToOCLOpaqueType:
292 case CK_AddressSpaceConversion:
293 case CK_IntToOCLSampler:
294 case CK_FloatingToFixedPoint:
295 case CK_FixedPointToFloating:
296 case CK_FixedPointCast:
297 case CK_FixedPointToBoolean:
298 case CK_FixedPointToIntegral:
299 case CK_IntegralToFixedPoint:
300 case CK_MatrixCast:
301 case CK_HLSLVectorTruncation:
302 case CK_HLSLArrayRValue:
303 case CK_HLSLElementwiseCast:
304 case CK_HLSLAggregateSplatCast:
305 llvm_unreachable("invalid cast kind for complex value");
306
307 case CK_FloatingRealToComplex:
308 case CK_IntegralRealToComplex: {
310 return emitScalarToComplexCast(cgf.emitScalarExpr(op), op->getType(),
311 destTy, op->getExprLoc());
312 }
313
314 case CK_FloatingComplexCast:
315 case CK_FloatingComplexToIntegralComplex:
316 case CK_IntegralComplexCast:
317 case CK_IntegralComplexToFloatingComplex: {
319 return emitComplexToComplexCast(Visit(op), op->getType(), destTy,
320 op->getExprLoc());
321 }
322 }
323
324 llvm_unreachable("unknown cast resulting in complex value");
325}
326
327mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e) {
328 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());
329 mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Plus, promotionTy);
330 if (!promotionTy.isNull())
331 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());
332 return result;
333}
334
335mlir::Value ComplexExprEmitter::VisitPlusMinus(const UnaryOperator *e,
336 cir::UnaryOpKind kind,
337 QualType promotionType) {
338 assert(kind == cir::UnaryOpKind::Plus ||
339 kind == cir::UnaryOpKind::Minus &&
340 "Invalid UnaryOp kind for ComplexType Plus or Minus");
341
342 mlir::Value op;
343 if (!promotionType.isNull())
344 op = cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType);
345 else
346 op = Visit(e->getSubExpr());
347 return builder.createUnaryOp(cgf.getLoc(e->getExprLoc()), kind, op);
348}
349
350mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e) {
351 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());
352 mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Minus, promotionTy);
353 if (!promotionTy.isNull())
354 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());
355 return result;
356}
357
358mlir::Value ComplexExprEmitter::emitConstant(
359 const CIRGenFunction::ConstantEmission &constant, Expr *e) {
360 assert(constant && "not a constant");
361 if (constant.isReference())
362 return emitLoadOfLValue(constant.getReferenceLValue(cgf, e),
363 e->getExprLoc());
364
365 mlir::TypedAttr valueAttr = constant.getValue();
366 return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr);
367}
368
369mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
370 SourceLocation loc) {
371 assert(lv.isSimple() && "non-simple complex l-value?");
372 if (lv.getType()->isAtomicType())
373 cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");
374
375 const Address srcAddr = lv.getAddress();
376 return builder.createLoad(cgf.getLoc(loc), srcAddr);
377}
378
379void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
380 LValue lv, bool isInit) {
381 if (lv.getType()->isAtomicType() ||
382 (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
383 cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");
384 return;
385 }
386
387 const Address destAddr = lv.getAddress();
388 builder.createStore(loc, val, destAddr);
389}
390
391mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,
392 QualType srcType,
393 QualType destType,
394 SourceLocation loc) {
395 if (srcType == destType)
396 return val;
397
398 // Get the src/dest element type.
399 QualType srcElemTy = srcType->castAs<ComplexType>()->getElementType();
400 QualType destElemTy = destType->castAs<ComplexType>()->getElementType();
401
402 cir::CastKind castOpKind;
403 if (srcElemTy->isFloatingType() && destElemTy->isFloatingType())
404 castOpKind = cir::CastKind::float_complex;
405 else if (srcElemTy->isFloatingType() && destElemTy->isIntegerType())
406 castOpKind = cir::CastKind::float_complex_to_int_complex;
407 else if (srcElemTy->isIntegerType() && destElemTy->isFloatingType())
408 castOpKind = cir::CastKind::int_complex_to_float_complex;
409 else if (srcElemTy->isIntegerType() && destElemTy->isIntegerType())
410 castOpKind = cir::CastKind::int_complex;
411 else
412 llvm_unreachable("unexpected src type or dest type");
413
414 return builder.createCast(cgf.getLoc(loc), castOpKind, val,
415 cgf.convertType(destType));
416}
417
418mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,
419 QualType srcType,
420 QualType destType,
421 SourceLocation loc) {
422 cir::CastKind castOpKind;
423 if (srcType->isFloatingType())
424 castOpKind = cir::CastKind::float_to_complex;
425 else if (srcType->isIntegerType())
426 castOpKind = cir::CastKind::int_to_complex;
427 else
428 llvm_unreachable("unexpected src type");
429
430 return builder.createCast(cgf.getLoc(loc), castOpKind, val,
431 cgf.convertType(destType));
432}
433
434mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
436 mlir::Value condValue = Visit(e->getCond());
437 mlir::Location loc = cgf.getLoc(e->getSourceRange());
438
439 return builder
440 .create<cir::TernaryOp>(
441 loc, condValue,
442 /*thenBuilder=*/
443 [&](mlir::OpBuilder &b, mlir::Location loc) {
444 mlir::Value trueValue = Visit(e->getTrueExpr());
445 b.create<cir::YieldOp>(loc, trueValue);
446 },
447 /*elseBuilder=*/
448 [&](mlir::OpBuilder &b, mlir::Location loc) {
449 mlir::Value falseValue = Visit(e->getFalseExpr());
450 b.create<cir::YieldOp>(loc, falseValue);
451 })
452 .getResult();
453}
454
455mlir::Value ComplexExprEmitter::VisitArraySubscriptExpr(Expr *e) {
456 return emitLoadOfLValue(e);
457}
458
459mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) {
460 mlir::Value value;
461 LValue lv = emitBinAssignLValue(e, value);
462
463 // The result of an assignment in C is the assigned r-value.
464 if (!cgf.getLangOpts().CPlusPlus)
465 return value;
466
467 // If the lvalue is non-volatile, return the computed value of the
468 // assignment.
469 if (!lv.isVolatile())
470 return value;
471
472 return emitLoadOfLValue(lv, e->getExprLoc());
473}
474
475mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) {
476 cgf.emitIgnoredExpr(e->getLHS());
477 return Visit(e->getRHS());
478}
479
480mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
482 return emitLoadOfLValue(e);
483 return cgf.emitCallExpr(e).getComplexValue();
484}
485
486mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) {
487 if (const auto *ece = dyn_cast<ExplicitCastExpr>(e)) {
488 // Bind VLAs in the cast type.
489 if (ece->getType()->isVariablyModifiedType()) {
490 cgf.cgm.errorNYI("VisitCastExpr Bind VLAs in the cast type");
491 return {};
492 }
493 }
494
496 return emitLoadOfLValue(e);
497
498 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
499}
500
501mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
502 return Visit(e->getChosenSubExpr());
503}
504
505mlir::Value
506ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
507 mlir::Location loc = cgf.getLoc(e->getExprLoc());
508 mlir::Type complexTy = cgf.convertType(e->getType());
509 return builder.getNullValue(complexTy, loc);
510}
511
512mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) {
514 return emitConstant(constant, e);
515 return emitLoadOfLValue(e);
516}
517
518mlir::Value
519ComplexExprEmitter::VisitGenericSelectionExpr(GenericSelectionExpr *e) {
520 return Visit(e->getResultExpr());
521}
522
523mlir::Value ComplexExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *e) {
524 // Unlike for scalars, we don't have to worry about function->ptr demotion
525 // here.
527 return emitLoadOfLValue(e);
528 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
529}
530
531mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {
532 mlir::Location loc = cgf.getLoc(e->getExprLoc());
533 if (e->getNumInits() == 2) {
534 mlir::Value real = cgf.emitScalarExpr(e->getInit(0));
535 mlir::Value imag = cgf.emitScalarExpr(e->getInit(1));
536 return builder.createComplexCreate(loc, real, imag);
537 }
538
539 if (e->getNumInits() == 1)
540 return Visit(e->getInit(0));
541
542 assert(e->getNumInits() == 0 && "Unexpected number of inits");
543 mlir::Type complexTy = cgf.convertType(e->getType());
544 return builder.getNullValue(complexTy, loc);
545}
546
547mlir::Value
548ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
549 auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType()));
550 mlir::Type elementTy = ty.getElementType();
551 mlir::Location loc = cgf.getLoc(il->getExprLoc());
552
553 mlir::TypedAttr realValueAttr;
554 mlir::TypedAttr imagValueAttr;
555
556 if (mlir::isa<cir::IntType>(elementTy)) {
557 llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue();
558 realValueAttr = cir::IntAttr::get(elementTy, 0);
559 imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
560 } else {
561 assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
562 "Expected complex element type to be floating-point");
563
564 llvm::APFloat imagValue =
565 cast<FloatingLiteral>(il->getSubExpr())->getValue();
566 realValueAttr = cir::FPAttr::get(
567 elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
568 imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
569 }
570
571 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
572 return builder.create<cir::ConstantOp>(loc, complexAttr);
573}
574
575mlir::Value ComplexExprEmitter::VisitParenExpr(ParenExpr *e) {
576 return Visit(e->getSubExpr());
577}
578
579mlir::Value ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr(
581 return Visit(e->getReplacement());
582}
583
584mlir::Value ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *e,
585 cir::UnaryOpKind op,
586 bool isPre) {
587 LValue lv = cgf.emitLValue(e->getSubExpr());
588 return cgf.emitComplexPrePostIncDec(e, lv, op, isPre);
589}
590
591mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) {
592 return emitLoadOfLValue(e);
593}
594
595mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) {
596 mlir::Value op = Visit(e->getSubExpr());
597 return builder.createNot(op);
598}
599
600mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
601 QualType promotionTy) {
602 e = e->IgnoreParens();
603 if (const auto *bo = dyn_cast<BinaryOperator>(e)) {
604 switch (bo->getOpcode()) {
605#define HANDLE_BINOP(OP) \
606 case BO_##OP: \
607 return emitBin##OP(emitBinOps(bo, promotionTy));
608 HANDLE_BINOP(Add)
609 HANDLE_BINOP(Sub)
610 HANDLE_BINOP(Mul)
611#undef HANDLE_BINOP
612 default:
613 break;
614 }
615 } else if (const auto *unaryOp = dyn_cast<UnaryOperator>(e)) {
616 switch (unaryOp->getOpcode()) {
617 case UO_Minus:
618 case UO_Plus: {
619 auto kind = unaryOp->getOpcode() == UO_Plus ? cir::UnaryOpKind::Plus
620 : cir::UnaryOpKind::Minus;
621 return VisitPlusMinus(unaryOp, kind, promotionTy);
622 }
623 default:
624 break;
625 }
626 }
627
628 mlir::Value result = Visit(const_cast<Expr *>(e));
629 if (!promotionTy.isNull())
630 return cgf.emitPromotedValue(result, promotionTy);
631
632 return result;
633}
634
635mlir::Value
636ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e,
637 QualType promotionTy) {
638 if (e->getType()->isAnyComplexType()) {
639 if (!promotionTy.isNull())
640 return cgf.emitPromotedComplexExpr(e, promotionTy);
641 return Visit(const_cast<Expr *>(e));
642 }
643
644 if (!promotionTy.isNull()) {
645 QualType complexElementTy =
646 promotionTy->castAs<ComplexType>()->getElementType();
647 return cgf.emitPromotedScalarExpr(e, complexElementTy);
648 }
649 return cgf.emitScalarExpr(e);
650}
651
652ComplexExprEmitter::BinOpInfo
653ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {
654 BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())};
655 binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy);
656 binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy);
657 binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy;
658 binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
659 return binOpInfo;
660}
661
662LValue ComplexExprEmitter::emitCompoundAssignLValue(
663 const CompoundAssignOperator *e,
664 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &), RValue &value) {
665 QualType lhsTy = e->getLHS()->getType();
666 QualType rhsTy = e->getRHS()->getType();
667 SourceLocation exprLoc = e->getExprLoc();
668 mlir::Location loc = cgf.getLoc(exprLoc);
669
670 if (lhsTy->getAs<AtomicType>()) {
671 cgf.cgm.errorNYI("emitCompoundAssignLValue AtmoicType");
672 return {};
673 }
674
675 BinOpInfo opInfo{loc};
676 opInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
677
679
680 // Load the RHS and LHS operands.
681 // __block variables need to have the rhs evaluated first, plus this should
682 // improve codegen a little.
683 QualType promotionTypeCR = getPromotionType(e->getComputationResultType());
684 opInfo.ty = promotionTypeCR.isNull() ? e->getComputationResultType()
685 : promotionTypeCR;
686
687 QualType complexElementTy =
688 opInfo.ty->castAs<ComplexType>()->getElementType();
689 QualType promotionTypeRHS = getPromotionType(rhsTy);
690
691 // The RHS should have been converted to the computation type.
692 if (e->getRHS()->getType()->isRealFloatingType()) {
693 if (!promotionTypeRHS.isNull()) {
694 opInfo.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionTypeRHS);
695 } else {
696 assert(cgf.getContext().hasSameUnqualifiedType(complexElementTy, rhsTy));
697 opInfo.rhs = cgf.emitScalarExpr(e->getRHS());
698 }
699 } else {
700 if (!promotionTypeRHS.isNull()) {
701 opInfo.rhs = cgf.emitPromotedComplexExpr(e->getRHS(), promotionTypeRHS);
702 } else {
703 assert(cgf.getContext().hasSameUnqualifiedType(opInfo.ty, rhsTy));
704 opInfo.rhs = Visit(e->getRHS());
705 }
706 }
707
708 LValue lhs = cgf.emitLValue(e->getLHS());
709
710 // Load from the l-value and convert it.
711 QualType promotionTypeLHS = getPromotionType(e->getComputationLHSType());
712 if (lhsTy->isAnyComplexType()) {
713 mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);
714 QualType destTy = promotionTypeLHS.isNull() ? opInfo.ty : promotionTypeLHS;
715 opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);
716 } else {
717 mlir::Value lhsVal = cgf.emitLoadOfScalar(lhs, exprLoc);
718 // For floating point real operands we can directly pass the scalar form
719 // to the binary operator emission and potentially get more efficient code.
720 if (lhsTy->isRealFloatingType()) {
721 QualType promotedComplexElementTy;
722 if (!promotionTypeLHS.isNull()) {
723 promotedComplexElementTy =
724 cast<ComplexType>(promotionTypeLHS)->getElementType();
725 if (!cgf.getContext().hasSameUnqualifiedType(promotedComplexElementTy,
726 promotionTypeLHS))
727 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy,
728 promotedComplexElementTy, exprLoc);
729 } else {
730 if (!cgf.getContext().hasSameUnqualifiedType(complexElementTy, lhsTy))
731 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy, complexElementTy,
732 exprLoc);
733 }
734 opInfo.lhs = lhsVal;
735 } else {
736 opInfo.lhs = emitScalarToComplexCast(lhsVal, lhsTy, opInfo.ty, exprLoc);
737 }
738 }
739
740 // Expand the binary operator.
741 mlir::Value result = (this->*func)(opInfo);
742
743 // Truncate the result and store it into the LHS lvalue.
744 if (lhsTy->isAnyComplexType()) {
745 mlir::Value resultValue =
746 emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);
747 emitStoreOfComplex(loc, resultValue, lhs, /*isInit*/ false);
748 value = RValue::getComplex(resultValue);
749 } else {
750 mlir::Value resultValue =
751 cgf.emitComplexToScalarConversion(result, opInfo.ty, lhsTy, exprLoc);
752 cgf.emitStoreOfScalar(resultValue, lhs, /*isInit*/ false);
753 value = RValue::get(resultValue);
754 }
755
756 return lhs;
757}
758
759mlir::Value ComplexExprEmitter::emitCompoundAssign(
760 const CompoundAssignOperator *e,
761 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &)) {
762 RValue val;
763 LValue lv = emitCompoundAssignLValue(e, func, val);
764
765 // The result of an assignment in C is the assigned r-value.
766 if (!cgf.getLangOpts().CPlusPlus)
767 return val.getComplexValue();
768
769 // If the lvalue is non-volatile, return the computed value of the assignment.
770 if (!lv.isVolatileQualified())
771 return val.getComplexValue();
772
773 return emitLoadOfLValue(lv, e->getExprLoc());
774}
775
776mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {
779
780 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
781 mlir::isa<cir::ComplexType>(op.rhs.getType()))
782 return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs);
783
784 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
785 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
786 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
787 mlir::Value newReal = builder.createAdd(op.loc, real, op.rhs);
788 return builder.createComplexCreate(op.loc, newReal, imag);
789 }
790
791 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
792 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
793 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
794 mlir::Value newReal = builder.createAdd(op.loc, op.lhs, real);
795 return builder.createComplexCreate(op.loc, newReal, imag);
796}
797
798mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {
801
802 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
803 mlir::isa<cir::ComplexType>(op.rhs.getType()))
804 return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs);
805
806 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
807 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
808 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
809 mlir::Value newReal = builder.createSub(op.loc, real, op.rhs);
810 return builder.createComplexCreate(op.loc, newReal, imag);
811 }
812
813 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
814 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
815 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
816 mlir::Value newReal = builder.createSub(op.loc, op.lhs, real);
817 return builder.createComplexCreate(op.loc, newReal, imag);
818}
819
820static cir::ComplexRangeKind
822 switch (range) {
823 case LangOptions::CX_Full:
824 return cir::ComplexRangeKind::Full;
825 case LangOptions::CX_Improved:
826 return cir::ComplexRangeKind::Improved;
827 case LangOptions::CX_Promoted:
828 return cir::ComplexRangeKind::Promoted;
829 case LangOptions::CX_Basic:
830 return cir::ComplexRangeKind::Basic;
831 case LangOptions::CX_None:
832 // The default value for ComplexRangeKind is Full if no option is selected
833 return cir::ComplexRangeKind::Full;
834 }
835}
836
837mlir::Value ComplexExprEmitter::emitBinMul(const BinOpInfo &op) {
840
841 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
842 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
843 cir::ComplexRangeKind rangeKind =
844 getComplexRangeAttr(op.fpFeatures.getComplexRange());
845 return builder.create<cir::ComplexMulOp>(op.loc, op.lhs, op.rhs, rangeKind);
846 }
847
848 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
849 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
850 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
851 mlir::Value newReal = builder.createMul(op.loc, real, op.rhs);
852 mlir::Value newImag = builder.createMul(op.loc, imag, op.rhs);
853 return builder.createComplexCreate(op.loc, newReal, newImag);
854 }
855
856 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
857 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
858 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
859 mlir::Value newReal = builder.createMul(op.loc, op.lhs, real);
860 mlir::Value newImag = builder.createMul(op.loc, op.lhs, imag);
861 return builder.createComplexCreate(op.loc, newReal, newImag);
862}
863
864mlir::Value ComplexExprEmitter::emitBinDiv(const BinOpInfo &op) {
867
868 // Handle division between two complex values. In the case of complex integer
869 // types mixed with scalar integers, the scalar integer type will always be
870 // promoted to a complex integer value with a zero imaginary component when
871 // the AST is formed.
872 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
873 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
874 cir::ComplexRangeKind rangeKind =
875 getComplexRangeAttr(op.fpFeatures.getComplexRange());
876 return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs,
877 rangeKind);
878 }
879
880 // The C99 standard (G.5.1) defines division of a complex value by a real
881 // value in the following simplified form.
882 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
883 assert(mlir::cast<cir::ComplexType>(op.lhs.getType()).getElementType() ==
884 op.rhs.getType());
885 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
886 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
887 mlir::Value newReal = builder.createFDiv(op.loc, real, op.rhs);
888 mlir::Value newImag = builder.createFDiv(op.loc, imag, op.rhs);
889 return builder.createComplexCreate(op.loc, newReal, newImag);
890 }
891
892 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
893 cir::ConstantOp nullValue = builder.getNullValue(op.lhs.getType(), op.loc);
894 mlir::Value lhs = builder.createComplexCreate(op.loc, op.lhs, nullValue);
895 cir::ComplexRangeKind rangeKind =
896 getComplexRangeAttr(op.fpFeatures.getComplexRange());
897 return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind);
898}
899
901 assert(e->getOpcode() == BO_Assign && "Expected assign op");
902
903 mlir::Value value; // ignored
904 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
905 if (getLangOpts().OpenMP)
906 cgm.errorNYI("emitComplexAssignmentLValue OpenMP");
907
908 return lvalue;
909}
910
912 assert(e && getComplexType(e->getType()) &&
913 "Invalid complex expression to emit");
914
915 return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));
916}
917
919 mlir::Value (ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &);
920
922 switch (op) {
923 case BO_MulAssign:
924 return &ComplexExprEmitter::emitBinMul;
925 case BO_DivAssign:
926 return &ComplexExprEmitter::emitBinDiv;
927 case BO_SubAssign:
928 return &ComplexExprEmitter::emitBinSub;
929 case BO_AddAssign:
930 return &ComplexExprEmitter::emitBinAdd;
931 default:
932 llvm_unreachable("unexpected complex compound assignment");
933 }
934}
935
937 const CompoundAssignOperator *e) {
939 RValue val;
940 return ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, val);
941}
942
944 LValue lv,
945 cir::UnaryOpKind op,
946 bool isPre) {
947 assert(op == cir::UnaryOpKind::Inc ||
948 op == cir::UnaryOpKind::Dec && "Invalid UnaryOp kind for ComplexType");
949
950 mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
951 mlir::Location loc = getLoc(e->getExprLoc());
952 mlir::Value incVal = builder.createUnaryOp(loc, op, inVal);
953
954 // Store the updated result through the lvalue.
955 emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
956
957 if (getLangOpts().OpenMP)
958 cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
959
960 // If this is a postinc, return the value read from memory, otherwise use the
961 // updated value.
962 return isPre ? incVal : inVal;
963}
964
966 bool isInit) {
967 assert(e && getComplexType(e->getType()) &&
968 "Invalid complex expression to emit");
969 ComplexExprEmitter emitter(*this);
970 mlir::Value value = emitter.Visit(const_cast<Expr *>(e));
971 emitter.emitStoreOfComplex(getLoc(e->getExprLoc()), value, dest, isInit);
972}
973
975 return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
976}
977
978void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
979 LValue dest, bool isInit) {
980 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
981}
982
984 QualType promotionType) {
985 return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
986}
987
988mlir::Value CIRGenFunction::emitPromotedValue(mlir::Value result,
989 QualType promotionType) {
990 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
991 "integral complex will never be promoted");
992 return builder.createCast(cir::CastKind::float_complex, result,
993 convertType(promotionType));
994}
995
996mlir::Value CIRGenFunction::emitUnPromotedValue(mlir::Value result,
997 QualType unPromotionType) {
998 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
999 "integral complex will never be promoted");
1000 return builder.createCast(cir::CastKind::float_complex, result,
1001 convertType(unPromotionType));
1002}
1003
1005 const CompoundAssignOperator *e, mlir::Value &result) {
1007 RValue value;
1008 LValue ret = ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, value);
1009 result = value.getValue();
1010 return ret;
1011}
#define HANDLEBINOP(OP)
static CompoundFunc getComplexOp(BinaryOperatorKind op)
static const ComplexType * getComplexType(QualType type)
static cir::ComplexRangeKind getComplexRangeAttr(LangOptions::ComplexRangeKind range)
mlir::Value(ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &) CompoundFunc
#define HANDLE_BINOP(OP)
__device__ __2f16 b
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
mlir::Value createCast(mlir::Location loc, cir::CastKind kind, mlir::Value src, mlir::Type newTy)
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createNot(mlir::Value value)
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand)
mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::Saturated)
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real, mlir::Value imag)
mlir::Value createUnaryOp(mlir::Location loc, cir::UnaryOpKind kind, mlir::Value operand)
mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand)
CanQualType FloatTy
Definition: ASTContext.h:1234
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2898
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:4289
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Definition: Expr.h:4467
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition: Expr.h:4473
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition: Expr.h:4479
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3974
Expr * getLHS() const
Definition: Expr.h:4024
SourceLocation getExprLoc() const
Definition: Expr.h:4015
Expr * getRHS() const
Definition: Expr.h:4026
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Definition: Expr.h:4187
Opcode getOpcode() const
Definition: Expr.h:4019
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
LValue getReferenceLValue(CIRGenFunction &cgf, Expr *refExpr) const
mlir::Value emitComplexToScalarConversion(mlir::Value src, QualType srcTy, QualType dstTy, SourceLocation loc)
Emit a conversion from the specified complex type to the specified destination type,...
mlir::Type convertType(clang::QualType t)
mlir::Value emitPromotedValue(mlir::Value result, QualType promotionType)
const clang::LangOptions & getLangOpts() const
LValue emitScalarCompoundAssignWithComplex(const CompoundAssignOperator *e, mlir::Value &result)
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, bool isInit=false, bool isNontemporal=false)
Definition: CIRGenExpr.cpp:312
LValue emitComplexCompoundAssignmentLValue(const CompoundAssignOperator *e)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, clang::QualType dstType, clang::SourceLocation loc)
Emit a conversion from the specified type to the specified destination type, both of which are CIR sc...
mlir::Value emitPromotedComplexExpr(const Expr *e, QualType promotionType)
mlir::Value emitUnPromotedValue(mlir::Value result, QualType unPromotionType)
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv, cir::UnaryOpKind op, bool isPre)
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
LValue emitComplexAssignmentLValue(const BinaryOperator *e)
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType)
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
Definition: CIRGenExpr.cpp:546
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
clang::ASTContext & getContext() const
bool isLValueSuitableForInlineAtomic(LValue lv)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
Address getAddress() const
Definition: CIRGenValue.h:211
clang::QualType getType() const
Definition: CIRGenValue.h:202
bool isVolatileQualified() const
Definition: CIRGenValue.h:196
bool isVolatile() const
Definition: CIRGenValue.h:194
bool isSimple() const
Definition: CIRGenValue.h:190
This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CIRGenValue.h:33
static RValue get(mlir::Value v)
Definition: CIRGenValue.h:82
static RValue getComplex(mlir::Value v)
Definition: CIRGenValue.h:90
mlir::Value getValue() const
Return the value of this scalar value.
Definition: CIRGenValue.h:56
mlir::Value getComplexValue() const
Return the value of this complex value.
Definition: CIRGenValue.h:62
An expression "T()" which creates an rvalue of a non-class type T.
Definition: ExprCXX.h:2198
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1599
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3612
CastKind getCastKind() const
Definition: Expr.h:3656
bool changesVolatileQualification() const
Return.
Definition: Expr.h:3746
Expr * getSubExpr()
Definition: Expr.h:3662
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4784
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition: Expr.h:4820
Complex values, per C99 6.2.5p11.
Definition: TypeBase.h:3293
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4236
QualType getComputationLHSType() const
Definition: Expr.h:4270
QualType getComputationResultType() const
Definition: Expr.h:4273
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3541
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
This represents one expression.
Definition: Expr.h:112
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3069
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:273
QualType getType() const
Definition: Expr.h:144
Represents a C11 generic selection.
Definition: Expr.h:6114
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition: Expr.h:6398
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1733
const Expr * getSubExpr() const
Definition: Expr.h:1745
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3789
Describes an C or C++ initializer list.
Definition: Expr.h:5235
unsigned getNumInits() const
Definition: Expr.h:5265
const Expr * getInit(unsigned Init) const
Definition: Expr.h:5289
ComplexRangeKind
Controls the various implementations for complex multiplication and.
Definition: LangOptions.h:375
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3300
Expr * getBase() const
Definition: Expr.h:3377
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2184
const Expr * getSubExpr() const
Definition: Expr.h:2201
A (possibly-)qualified type.
Definition: TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: TypeBase.h:1004
bool UseExcessPrecision(const ASTContext &Ctx)
Definition: Type.cpp:1612
Encodes a location in the source.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:186
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4658
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: TypeBase.h:8980
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isAnyComplexType() const
Definition: TypeBase.h:8715
bool isAtomicType() const
Definition: TypeBase.h:8762
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2324
bool isFloatingType() const
Definition: Type.cpp:2308
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2246
SourceLocation getExprLoc() const
Definition: Expr.h:2370
Expr * getSubExpr() const
Definition: Expr.h:2287
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:76
The JSON file list parser is used to communicate input to InstallAPI.
BinaryOperatorKind
CastKind
CastKind - The kind of operation required for a conversion.
static bool cgFPOptionsRAII()
static bool fastMathFlags()