1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "CodeGenFunction.h" |
14 | #include "CodeGenModule.h" |
15 | #include "clang/AST/StmtVisitor.h" |
16 | #include "llvm/ADT/STLExtras.h" |
17 | #include "llvm/IR/Constants.h" |
18 | #include "llvm/IR/Instructions.h" |
19 | #include "llvm/IR/MDBuilder.h" |
20 | #include "llvm/IR/Metadata.h" |
21 | #include <algorithm> |
22 | using namespace clang; |
23 | using namespace CodeGen; |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | typedef CodeGenFunction::ComplexPairTy ComplexPairTy; |
30 | |
31 | |
32 | static const ComplexType *getComplexType(QualType type) { |
33 | type = type.getCanonicalType(); |
34 | if (const ComplexType *comp = dyn_cast<ComplexType>(type)) { |
35 | return comp; |
36 | } else { |
37 | return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); |
38 | } |
39 | } |
40 | |
41 | namespace { |
42 | class ComplexExprEmitter |
43 | : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { |
44 | CodeGenFunction &CGF; |
45 | CGBuilderTy &Builder; |
46 | bool IgnoreReal; |
47 | bool IgnoreImag; |
48 | public: |
49 | ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false) |
50 | : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) { |
51 | } |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | bool TestAndClearIgnoreReal() { |
59 | bool I = IgnoreReal; |
60 | IgnoreReal = false; |
61 | return I; |
62 | } |
63 | bool TestAndClearIgnoreImag() { |
64 | bool I = IgnoreImag; |
65 | IgnoreImag = false; |
66 | return I; |
67 | } |
68 | |
69 | |
70 | |
71 | |
72 | ComplexPairTy EmitLoadOfLValue(const Expr *E) { |
73 | return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc()); |
74 | } |
75 | |
76 | ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc); |
77 | |
78 | |
79 | |
80 | void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit); |
81 | |
82 | |
83 | ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, |
84 | QualType DestType, SourceLocation Loc); |
85 | |
86 | ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, |
87 | QualType DestType, SourceLocation Loc); |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | ComplexPairTy Visit(Expr *E) { |
94 | ApplyDebugLocation DL(CGF, E); |
95 | return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); |
96 | } |
97 | |
98 | ComplexPairTy VisitStmt(Stmt *S) { |
99 | S->dump(CGF.getContext().getSourceManager()); |
100 | llvm_unreachable("Stmt can't have complex result type!"); |
101 | } |
102 | ComplexPairTy VisitExpr(Expr *S); |
103 | ComplexPairTy VisitConstantExpr(ConstantExpr *E) { |
104 | return Visit(E->getSubExpr()); |
105 | } |
106 | ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} |
107 | ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { |
108 | return Visit(GE->getResultExpr()); |
109 | } |
110 | ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); |
111 | ComplexPairTy |
112 | VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) { |
113 | return Visit(PE->getReplacement()); |
114 | } |
115 | ComplexPairTy VisitCoawaitExpr(CoawaitExpr *S) { |
116 | return CGF.EmitCoawaitExpr(*S).getComplexVal(); |
117 | } |
118 | ComplexPairTy VisitCoyieldExpr(CoyieldExpr *S) { |
119 | return CGF.EmitCoyieldExpr(*S).getComplexVal(); |
120 | } |
121 | ComplexPairTy VisitUnaryCoawait(const UnaryOperator *E) { |
122 | return Visit(E->getSubExpr()); |
123 | } |
124 | |
125 | ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant, |
126 | Expr *E) { |
127 | (0) . __assert_fail ("Constant && \"not a constant\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 127, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Constant && "not a constant"); |
128 | if (Constant.isReference()) |
129 | return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E), |
130 | E->getExprLoc()); |
131 | |
132 | llvm::Constant *pair = Constant.getValue(); |
133 | return ComplexPairTy(pair->getAggregateElement(0U), |
134 | pair->getAggregateElement(1U)); |
135 | } |
136 | |
137 | |
138 | ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { |
139 | if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) |
140 | return emitConstant(Constant, E); |
141 | return EmitLoadOfLValue(E); |
142 | } |
143 | ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { |
144 | return EmitLoadOfLValue(E); |
145 | } |
146 | ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { |
147 | return CGF.EmitObjCMessageExpr(E).getComplexVal(); |
148 | } |
149 | ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } |
150 | ComplexPairTy VisitMemberExpr(MemberExpr *ME) { |
151 | if (CodeGenFunction::ConstantEmission Constant = |
152 | CGF.tryEmitAsConstant(ME)) { |
153 | CGF.EmitIgnoredExpr(ME->getBase()); |
154 | return emitConstant(Constant, ME); |
155 | } |
156 | return EmitLoadOfLValue(ME); |
157 | } |
158 | ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { |
159 | if (E->isGLValue()) |
160 | return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), |
161 | E->getExprLoc()); |
162 | return CGF.getOrCreateOpaqueRValueMapping(E).getComplexVal(); |
163 | } |
164 | |
165 | ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { |
166 | return CGF.EmitPseudoObjectRValue(E).getComplexVal(); |
167 | } |
168 | |
169 | |
170 | |
171 | ComplexPairTy EmitCast(CastKind CK, Expr *Op, QualType DestTy); |
172 | ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { |
173 | |
174 | |
175 | return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); |
176 | } |
177 | ComplexPairTy VisitCastExpr(CastExpr *E) { |
178 | if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E)) |
179 | CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); |
180 | return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); |
181 | } |
182 | ComplexPairTy VisitCallExpr(const CallExpr *E); |
183 | ComplexPairTy VisitStmtExpr(const StmtExpr *E); |
184 | |
185 | |
186 | ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, |
187 | bool isInc, bool isPre) { |
188 | LValue LV = CGF.EmitLValue(E->getSubExpr()); |
189 | return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); |
190 | } |
191 | ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { |
192 | return VisitPrePostIncDec(E, false, false); |
193 | } |
194 | ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { |
195 | return VisitPrePostIncDec(E, true, false); |
196 | } |
197 | ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { |
198 | return VisitPrePostIncDec(E, false, true); |
199 | } |
200 | ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { |
201 | return VisitPrePostIncDec(E, true, true); |
202 | } |
203 | ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } |
204 | ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) { |
205 | TestAndClearIgnoreReal(); |
206 | TestAndClearIgnoreImag(); |
207 | return Visit(E->getSubExpr()); |
208 | } |
209 | ComplexPairTy VisitUnaryMinus (const UnaryOperator *E); |
210 | ComplexPairTy VisitUnaryNot (const UnaryOperator *E); |
211 | |
212 | ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { |
213 | return Visit(E->getSubExpr()); |
214 | } |
215 | ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { |
216 | return Visit(DAE->getExpr()); |
217 | } |
218 | ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { |
219 | CodeGenFunction::CXXDefaultInitExprScope Scope(CGF); |
220 | return Visit(DIE->getExpr()); |
221 | } |
222 | ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) { |
223 | CGF.enterFullExpression(E); |
224 | CodeGenFunction::RunCleanupsScope Scope(CGF); |
225 | ComplexPairTy Vals = Visit(E->getSubExpr()); |
226 | |
227 | |
228 | Scope.ForceCleanup({&Vals.first, &Vals.second}); |
229 | return Vals; |
230 | } |
231 | ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { |
232 | (0) . __assert_fail ("E->getType()->isAnyComplexType() && \"Expected complex type!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 232, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E->getType()->isAnyComplexType() && "Expected complex type!"); |
233 | QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); |
234 | llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); |
235 | return ComplexPairTy(Null, Null); |
236 | } |
237 | ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { |
238 | (0) . __assert_fail ("E->getType()->isAnyComplexType() && \"Expected complex type!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 238, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E->getType()->isAnyComplexType() && "Expected complex type!"); |
239 | QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); |
240 | llvm::Constant *Null = |
241 | llvm::Constant::getNullValue(CGF.ConvertType(Elem)); |
242 | return ComplexPairTy(Null, Null); |
243 | } |
244 | |
245 | struct BinOpInfo { |
246 | ComplexPairTy LHS; |
247 | ComplexPairTy RHS; |
248 | QualType Ty; |
249 | }; |
250 | |
251 | BinOpInfo EmitBinOps(const BinaryOperator *E); |
252 | LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, |
253 | ComplexPairTy (ComplexExprEmitter::*Func) |
254 | (const BinOpInfo &), |
255 | RValue &Val); |
256 | ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, |
257 | ComplexPairTy (ComplexExprEmitter::*Func) |
258 | (const BinOpInfo &)); |
259 | |
260 | ComplexPairTy EmitBinAdd(const BinOpInfo &Op); |
261 | ComplexPairTy EmitBinSub(const BinOpInfo &Op); |
262 | ComplexPairTy EmitBinMul(const BinOpInfo &Op); |
263 | ComplexPairTy EmitBinDiv(const BinOpInfo &Op); |
264 | |
265 | ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, |
266 | const BinOpInfo &Op); |
267 | |
268 | ComplexPairTy VisitBinAdd(const BinaryOperator *E) { |
269 | return EmitBinAdd(EmitBinOps(E)); |
270 | } |
271 | ComplexPairTy VisitBinSub(const BinaryOperator *E) { |
272 | return EmitBinSub(EmitBinOps(E)); |
273 | } |
274 | ComplexPairTy VisitBinMul(const BinaryOperator *E) { |
275 | return EmitBinMul(EmitBinOps(E)); |
276 | } |
277 | ComplexPairTy VisitBinDiv(const BinaryOperator *E) { |
278 | return EmitBinDiv(EmitBinOps(E)); |
279 | } |
280 | |
281 | |
282 | ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { |
283 | return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); |
284 | } |
285 | ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { |
286 | return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); |
287 | } |
288 | ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { |
289 | return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); |
290 | } |
291 | ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { |
292 | return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); |
293 | } |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | LValue EmitBinAssignLValue(const BinaryOperator *E, |
301 | ComplexPairTy &Val); |
302 | ComplexPairTy VisitBinAssign (const BinaryOperator *E); |
303 | ComplexPairTy VisitBinComma (const BinaryOperator *E); |
304 | |
305 | |
306 | ComplexPairTy |
307 | VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); |
308 | ComplexPairTy VisitChooseExpr(ChooseExpr *CE); |
309 | |
310 | ComplexPairTy VisitInitListExpr(InitListExpr *E); |
311 | |
312 | ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { |
313 | return EmitLoadOfLValue(E); |
314 | } |
315 | |
316 | ComplexPairTy VisitVAArgExpr(VAArgExpr *E); |
317 | |
318 | ComplexPairTy VisitAtomicExpr(AtomicExpr *E) { |
319 | return CGF.EmitAtomicExpr(E).getComplexVal(); |
320 | } |
321 | }; |
322 | } |
323 | |
324 | |
325 | |
326 | |
327 | |
328 | Address CodeGenFunction::emitAddrOfRealComponent(Address addr, |
329 | QualType complexType) { |
330 | return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp"); |
331 | } |
332 | |
333 | Address CodeGenFunction::emitAddrOfImagComponent(Address addr, |
334 | QualType complexType) { |
335 | return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp"); |
336 | } |
337 | |
338 | |
339 | |
340 | ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue, |
341 | SourceLocation loc) { |
342 | (0) . __assert_fail ("lvalue.isSimple() && \"non-simple complex l-value?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 342, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(lvalue.isSimple() && "non-simple complex l-value?"); |
343 | if (lvalue.getType()->isAtomicType()) |
344 | return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal(); |
345 | |
346 | Address SrcPtr = lvalue.getAddress(); |
347 | bool isVolatile = lvalue.isVolatileQualified(); |
348 | |
349 | llvm::Value *Real = nullptr, *Imag = nullptr; |
350 | |
351 | if (!IgnoreReal || isVolatile) { |
352 | Address RealP = CGF.emitAddrOfRealComponent(SrcPtr, lvalue.getType()); |
353 | Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real"); |
354 | } |
355 | |
356 | if (!IgnoreImag || isVolatile) { |
357 | Address ImagP = CGF.emitAddrOfImagComponent(SrcPtr, lvalue.getType()); |
358 | Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag"); |
359 | } |
360 | |
361 | return ComplexPairTy(Real, Imag); |
362 | } |
363 | |
364 | |
365 | |
366 | void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue, |
367 | bool isInit) { |
368 | if (lvalue.getType()->isAtomicType() || |
369 | (!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue))) |
370 | return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit); |
371 | |
372 | Address Ptr = lvalue.getAddress(); |
373 | Address RealPtr = CGF.emitAddrOfRealComponent(Ptr, lvalue.getType()); |
374 | Address ImagPtr = CGF.emitAddrOfImagComponent(Ptr, lvalue.getType()); |
375 | |
376 | Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); |
377 | Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); |
378 | } |
379 | |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { |
387 | CGF.ErrorUnsupported(E, "complex expression"); |
388 | llvm::Type *EltTy = |
389 | CGF.ConvertType(getComplexType(E->getType())->getElementType()); |
390 | llvm::Value *U = llvm::UndefValue::get(EltTy); |
391 | return ComplexPairTy(U, U); |
392 | } |
393 | |
394 | ComplexPairTy ComplexExprEmitter:: |
395 | VisitImaginaryLiteral(const ImaginaryLiteral *IL) { |
396 | llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); |
397 | return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); |
398 | } |
399 | |
400 | |
401 | ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { |
402 | if (E->getCallReturnType(CGF.getContext())->isReferenceType()) |
403 | return EmitLoadOfLValue(E); |
404 | |
405 | return CGF.EmitCallExpr(E).getComplexVal(); |
406 | } |
407 | |
408 | ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { |
409 | CodeGenFunction::StmtExprEvaluation eval(CGF); |
410 | Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); |
411 | (0) . __assert_fail ("RetAlloca.isValid() && \"Expected complex return value\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 411, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RetAlloca.isValid() && "Expected complex return value"); |
412 | return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()), |
413 | E->getExprLoc()); |
414 | } |
415 | |
416 | |
417 | ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, |
418 | QualType SrcType, |
419 | QualType DestType, |
420 | SourceLocation Loc) { |
421 | |
422 | SrcType = SrcType->castAs<ComplexType>()->getElementType(); |
423 | DestType = DestType->castAs<ComplexType>()->getElementType(); |
424 | |
425 | |
426 | |
427 | |
428 | Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc); |
429 | Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc); |
430 | return Val; |
431 | } |
432 | |
433 | ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, |
434 | QualType SrcType, |
435 | QualType DestType, |
436 | SourceLocation Loc) { |
437 | |
438 | DestType = DestType->castAs<ComplexType>()->getElementType(); |
439 | Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc); |
440 | |
441 | |
442 | return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); |
443 | } |
444 | |
445 | ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, |
446 | QualType DestTy) { |
447 | switch (CK) { |
448 | case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); |
449 | |
450 | |
451 | |
452 | case CK_AtomicToNonAtomic: |
453 | case CK_NonAtomicToAtomic: |
454 | case CK_NoOp: |
455 | case CK_LValueToRValue: |
456 | case CK_UserDefinedConversion: |
457 | return Visit(Op); |
458 | |
459 | case CK_LValueBitCast: { |
460 | LValue origLV = CGF.EmitLValue(Op); |
461 | Address V = origLV.getAddress(); |
462 | V = Builder.CreateElementBitCast(V, CGF.ConvertType(DestTy)); |
463 | return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), Op->getExprLoc()); |
464 | } |
465 | |
466 | case CK_BitCast: |
467 | case CK_BaseToDerived: |
468 | case CK_DerivedToBase: |
469 | case CK_UncheckedDerivedToBase: |
470 | case CK_Dynamic: |
471 | case CK_ToUnion: |
472 | case CK_ArrayToPointerDecay: |
473 | case CK_FunctionToPointerDecay: |
474 | case CK_NullToPointer: |
475 | case CK_NullToMemberPointer: |
476 | case CK_BaseToDerivedMemberPointer: |
477 | case CK_DerivedToBaseMemberPointer: |
478 | case CK_MemberPointerToBoolean: |
479 | case CK_ReinterpretMemberPointer: |
480 | case CK_ConstructorConversion: |
481 | case CK_IntegralToPointer: |
482 | case CK_PointerToIntegral: |
483 | case CK_PointerToBoolean: |
484 | case CK_ToVoid: |
485 | case CK_VectorSplat: |
486 | case CK_IntegralCast: |
487 | case CK_BooleanToSignedIntegral: |
488 | case CK_IntegralToBoolean: |
489 | case CK_IntegralToFloating: |
490 | case CK_FloatingToIntegral: |
491 | case CK_FloatingToBoolean: |
492 | case CK_FloatingCast: |
493 | case CK_CPointerToObjCPointerCast: |
494 | case CK_BlockPointerToObjCPointerCast: |
495 | case CK_AnyPointerToBlockPointerCast: |
496 | case CK_ObjCObjectLValueCast: |
497 | case CK_FloatingComplexToReal: |
498 | case CK_FloatingComplexToBoolean: |
499 | case CK_IntegralComplexToReal: |
500 | case CK_IntegralComplexToBoolean: |
501 | case CK_ARCProduceObject: |
502 | case CK_ARCConsumeObject: |
503 | case CK_ARCReclaimReturnedObject: |
504 | case CK_ARCExtendBlockObject: |
505 | case CK_CopyAndAutoreleaseBlockObject: |
506 | case CK_BuiltinFnToFnPtr: |
507 | case CK_ZeroToOCLOpaqueType: |
508 | case CK_AddressSpaceConversion: |
509 | case CK_IntToOCLSampler: |
510 | case CK_FixedPointCast: |
511 | case CK_FixedPointToBoolean: |
512 | case CK_FixedPointToIntegral: |
513 | case CK_IntegralToFixedPoint: |
514 | llvm_unreachable("invalid cast kind for complex value"); |
515 | |
516 | case CK_FloatingRealToComplex: |
517 | case CK_IntegralRealToComplex: |
518 | return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(), |
519 | DestTy, Op->getExprLoc()); |
520 | |
521 | case CK_FloatingComplexCast: |
522 | case CK_FloatingComplexToIntegralComplex: |
523 | case CK_IntegralComplexCast: |
524 | case CK_IntegralComplexToFloatingComplex: |
525 | return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy, |
526 | Op->getExprLoc()); |
527 | } |
528 | |
529 | llvm_unreachable("unknown cast resulting in complex value"); |
530 | } |
531 | |
532 | ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { |
533 | TestAndClearIgnoreReal(); |
534 | TestAndClearIgnoreImag(); |
535 | ComplexPairTy Op = Visit(E->getSubExpr()); |
536 | |
537 | llvm::Value *ResR, *ResI; |
538 | if (Op.first->getType()->isFloatingPointTy()) { |
539 | ResR = Builder.CreateFNeg(Op.first, "neg.r"); |
540 | ResI = Builder.CreateFNeg(Op.second, "neg.i"); |
541 | } else { |
542 | ResR = Builder.CreateNeg(Op.first, "neg.r"); |
543 | ResI = Builder.CreateNeg(Op.second, "neg.i"); |
544 | } |
545 | return ComplexPairTy(ResR, ResI); |
546 | } |
547 | |
548 | ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { |
549 | TestAndClearIgnoreReal(); |
550 | TestAndClearIgnoreImag(); |
551 | |
552 | ComplexPairTy Op = Visit(E->getSubExpr()); |
553 | llvm::Value *ResI; |
554 | if (Op.second->getType()->isFloatingPointTy()) |
555 | ResI = Builder.CreateFNeg(Op.second, "conj.i"); |
556 | else |
557 | ResI = Builder.CreateNeg(Op.second, "conj.i"); |
558 | |
559 | return ComplexPairTy(Op.first, ResI); |
560 | } |
561 | |
562 | ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { |
563 | llvm::Value *ResR, *ResI; |
564 | |
565 | if (Op.LHS.first->getType()->isFloatingPointTy()) { |
566 | ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); |
567 | if (Op.LHS.second && Op.RHS.second) |
568 | ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); |
569 | else |
570 | ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second; |
571 | (0) . __assert_fail ("ResI && \"Only one operand may be real!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 571, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ResI && "Only one operand may be real!"); |
572 | } else { |
573 | ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); |
574 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 575, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Op.LHS.second && Op.RHS.second && |
575 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 575, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Both operands of integer complex operators must be complex!"); |
576 | ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); |
577 | } |
578 | return ComplexPairTy(ResR, ResI); |
579 | } |
580 | |
581 | ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { |
582 | llvm::Value *ResR, *ResI; |
583 | if (Op.LHS.first->getType()->isFloatingPointTy()) { |
584 | ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); |
585 | if (Op.LHS.second && Op.RHS.second) |
586 | ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); |
587 | else |
588 | ResI = Op.LHS.second ? Op.LHS.second |
589 | : Builder.CreateFNeg(Op.RHS.second, "sub.i"); |
590 | (0) . __assert_fail ("ResI && \"Only one operand may be real!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 590, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ResI && "Only one operand may be real!"); |
591 | } else { |
592 | ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); |
593 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 594, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Op.LHS.second && Op.RHS.second && |
594 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 594, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Both operands of integer complex operators must be complex!"); |
595 | ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); |
596 | } |
597 | return ComplexPairTy(ResR, ResI); |
598 | } |
599 | |
600 | |
601 | ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName, |
602 | const BinOpInfo &Op) { |
603 | CallArgList Args; |
604 | Args.add(RValue::get(Op.LHS.first), |
605 | Op.Ty->castAs<ComplexType>()->getElementType()); |
606 | Args.add(RValue::get(Op.LHS.second), |
607 | Op.Ty->castAs<ComplexType>()->getElementType()); |
608 | Args.add(RValue::get(Op.RHS.first), |
609 | Op.Ty->castAs<ComplexType>()->getElementType()); |
610 | Args.add(RValue::get(Op.RHS.second), |
611 | Op.Ty->castAs<ComplexType>()->getElementType()); |
612 | |
613 | |
614 | |
615 | |
616 | |
617 | |
618 | |
619 | FunctionProtoType::ExtProtoInfo EPI; |
620 | EPI = EPI.withExceptionSpec( |
621 | FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept)); |
622 | SmallVector<QualType, 4> ArgsQTys( |
623 | 4, Op.Ty->castAs<ComplexType>()->getElementType()); |
624 | QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI); |
625 | const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall( |
626 | Args, cast<FunctionType>(FQTy.getTypePtr()), false); |
627 | |
628 | llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo); |
629 | llvm::FunctionCallee Func = CGF.CGM.CreateRuntimeFunction( |
630 | FTy, LibCallName, llvm::AttributeList(), true); |
631 | CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>()); |
632 | |
633 | llvm::CallBase *Call; |
634 | RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call); |
635 | Call->setCallingConv(CGF.CGM.getRuntimeCC()); |
636 | return Res.getComplexVal(); |
637 | } |
638 | |
639 | |
640 | |
641 | static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) { |
642 | switch (Ty->getTypeID()) { |
643 | default: |
644 | llvm_unreachable("Unsupported floating point type!"); |
645 | case llvm::Type::HalfTyID: |
646 | return "__mulhc3"; |
647 | case llvm::Type::FloatTyID: |
648 | return "__mulsc3"; |
649 | case llvm::Type::DoubleTyID: |
650 | return "__muldc3"; |
651 | case llvm::Type::PPC_FP128TyID: |
652 | return "__multc3"; |
653 | case llvm::Type::X86_FP80TyID: |
654 | return "__mulxc3"; |
655 | case llvm::Type::FP128TyID: |
656 | return "__multc3"; |
657 | } |
658 | } |
659 | |
660 | |
661 | |
662 | ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { |
663 | using llvm::Value; |
664 | Value *ResR, *ResI; |
665 | llvm::MDBuilder MDHelper(CGF.getLLVMContext()); |
666 | |
667 | if (Op.LHS.first->getType()->isFloatingPointTy()) { |
668 | |
669 | |
670 | |
671 | |
672 | |
673 | |
674 | |
675 | |
676 | if (Op.LHS.second && Op.RHS.second) { |
677 | |
678 | |
679 | |
680 | |
681 | |
682 | |
683 | |
684 | |
685 | |
686 | |
687 | Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac"); |
688 | Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd"); |
689 | Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad"); |
690 | Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc"); |
691 | |
692 | |
693 | |
694 | ResR = Builder.CreateFSub(AC, BD, "mul_r"); |
695 | ResI = Builder.CreateFAdd(AD, BC, "mul_i"); |
696 | |
697 | |
698 | |
699 | Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp"); |
700 | llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont"); |
701 | llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan"); |
702 | llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB); |
703 | llvm::BasicBlock *OrigBB = Branch->getParent(); |
704 | |
705 | |
706 | |
707 | llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1); |
708 | Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); |
709 | |
710 | |
711 | CGF.EmitBlock(INaNBB); |
712 | Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp"); |
713 | llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall"); |
714 | Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB); |
715 | Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); |
716 | |
717 | |
718 | CGF.EmitBlock(LibCallBB); |
719 | Value *LibCallR, *LibCallI; |
720 | std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall( |
721 | getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op); |
722 | Builder.CreateBr(ContBB); |
723 | |
724 | |
725 | |
726 | CGF.EmitBlock(ContBB); |
727 | llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi"); |
728 | RealPHI->addIncoming(ResR, OrigBB); |
729 | RealPHI->addIncoming(ResR, INaNBB); |
730 | RealPHI->addIncoming(LibCallR, LibCallBB); |
731 | llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi"); |
732 | ImagPHI->addIncoming(ResI, OrigBB); |
733 | ImagPHI->addIncoming(ResI, INaNBB); |
734 | ImagPHI->addIncoming(LibCallI, LibCallBB); |
735 | return ComplexPairTy(RealPHI, ImagPHI); |
736 | } |
737 | (0) . __assert_fail ("(Op.LHS.second || Op.RHS.second) && \"At least one operand must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 738, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((Op.LHS.second || Op.RHS.second) && |
738 | (0) . __assert_fail ("(Op.LHS.second || Op.RHS.second) && \"At least one operand must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 738, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "At least one operand must be complex!"); |
739 | |
740 | |
741 | |
742 | |
743 | ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); |
744 | |
745 | ResI = Op.LHS.second |
746 | ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il") |
747 | : Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); |
748 | } else { |
749 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 750, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Op.LHS.second && Op.RHS.second && |
750 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 750, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Both operands of integer complex operators must be complex!"); |
751 | Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); |
752 | Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr"); |
753 | ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); |
754 | |
755 | Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); |
756 | Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); |
757 | ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); |
758 | } |
759 | return ComplexPairTy(ResR, ResI); |
760 | } |
761 | |
762 | |
763 | |
764 | ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { |
765 | llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; |
766 | llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; |
767 | |
768 | llvm::Value *DSTr, *DSTi; |
769 | if (LHSr->getType()->isFloatingPointTy()) { |
770 | |
771 | |
772 | |
773 | |
774 | |
775 | |
776 | |
777 | if (RHSi && !CGF.getLangOpts().FastMath) { |
778 | BinOpInfo LibCallOp = Op; |
779 | |
780 | if (!LHSi) |
781 | LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType()); |
782 | |
783 | switch (LHSr->getType()->getTypeID()) { |
784 | default: |
785 | llvm_unreachable("Unsupported floating point type!"); |
786 | case llvm::Type::HalfTyID: |
787 | return EmitComplexBinOpLibCall("__divhc3", LibCallOp); |
788 | case llvm::Type::FloatTyID: |
789 | return EmitComplexBinOpLibCall("__divsc3", LibCallOp); |
790 | case llvm::Type::DoubleTyID: |
791 | return EmitComplexBinOpLibCall("__divdc3", LibCallOp); |
792 | case llvm::Type::PPC_FP128TyID: |
793 | return EmitComplexBinOpLibCall("__divtc3", LibCallOp); |
794 | case llvm::Type::X86_FP80TyID: |
795 | return EmitComplexBinOpLibCall("__divxc3", LibCallOp); |
796 | case llvm::Type::FP128TyID: |
797 | return EmitComplexBinOpLibCall("__divtc3", LibCallOp); |
798 | } |
799 | } else if (RHSi) { |
800 | if (!LHSi) |
801 | LHSi = llvm::Constant::getNullValue(RHSi->getType()); |
802 | |
803 | |
804 | llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); |
805 | llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); |
806 | llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); |
807 | |
808 | llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); |
809 | llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); |
810 | llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); |
811 | |
812 | llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); |
813 | llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); |
814 | llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); |
815 | |
816 | DSTr = Builder.CreateFDiv(ACpBD, CCpDD); |
817 | DSTi = Builder.CreateFDiv(BCmAD, CCpDD); |
818 | } else { |
819 | (0) . __assert_fail ("LHSi && \"Can have at most one non-complex operand!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 819, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LHSi && "Can have at most one non-complex operand!"); |
820 | |
821 | DSTr = Builder.CreateFDiv(LHSr, RHSr); |
822 | DSTi = Builder.CreateFDiv(LHSi, RHSr); |
823 | } |
824 | } else { |
825 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 826, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Op.LHS.second && Op.RHS.second && |
826 | (0) . __assert_fail ("Op.LHS.second && Op.RHS.second && \"Both operands of integer complex operators must be complex!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 826, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Both operands of integer complex operators must be complex!"); |
827 | |
828 | llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); |
829 | llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); |
830 | llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); |
831 | |
832 | llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); |
833 | llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); |
834 | llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); |
835 | |
836 | llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); |
837 | llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); |
838 | llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); |
839 | |
840 | if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { |
841 | DSTr = Builder.CreateUDiv(Tmp3, Tmp6); |
842 | DSTi = Builder.CreateUDiv(Tmp9, Tmp6); |
843 | } else { |
844 | DSTr = Builder.CreateSDiv(Tmp3, Tmp6); |
845 | DSTi = Builder.CreateSDiv(Tmp9, Tmp6); |
846 | } |
847 | } |
848 | |
849 | return ComplexPairTy(DSTr, DSTi); |
850 | } |
851 | |
852 | ComplexExprEmitter::BinOpInfo |
853 | ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { |
854 | TestAndClearIgnoreReal(); |
855 | TestAndClearIgnoreImag(); |
856 | BinOpInfo Ops; |
857 | if (E->getLHS()->getType()->isRealFloatingType()) |
858 | Ops.LHS = ComplexPairTy(CGF.EmitScalarExpr(E->getLHS()), nullptr); |
859 | else |
860 | Ops.LHS = Visit(E->getLHS()); |
861 | if (E->getRHS()->getType()->isRealFloatingType()) |
862 | Ops.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); |
863 | else |
864 | Ops.RHS = Visit(E->getRHS()); |
865 | |
866 | Ops.Ty = E->getType(); |
867 | return Ops; |
868 | } |
869 | |
870 | |
871 | LValue ComplexExprEmitter:: |
872 | EmitCompoundAssignLValue(const CompoundAssignOperator *E, |
873 | ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), |
874 | RValue &Val) { |
875 | TestAndClearIgnoreReal(); |
876 | TestAndClearIgnoreImag(); |
877 | QualType LHSTy = E->getLHS()->getType(); |
878 | if (const AtomicType *AT = LHSTy->getAs<AtomicType>()) |
879 | LHSTy = AT->getValueType(); |
880 | |
881 | BinOpInfo OpInfo; |
882 | |
883 | |
884 | |
885 | |
886 | OpInfo.Ty = E->getComputationResultType(); |
887 | QualType ComplexElementTy = cast<ComplexType>(OpInfo.Ty)->getElementType(); |
888 | |
889 | |
890 | if (E->getRHS()->getType()->isRealFloatingType()) { |
891 | getRHS()->getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 893, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert( |
892 | getRHS()->getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 893, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> CGF.getContext() |
893 | getRHS()->getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 893, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> .hasSameUnqualifiedType(ComplexElementTy, E->getRHS()->getType())); |
894 | OpInfo.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); |
895 | } else { |
896 | getRHS()->getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 897, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CGF.getContext() |
897 | getRHS()->getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 897, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> .hasSameUnqualifiedType(OpInfo.Ty, E->getRHS()->getType())); |
898 | OpInfo.RHS = Visit(E->getRHS()); |
899 | } |
900 | |
901 | LValue LHS = CGF.EmitLValue(E->getLHS()); |
902 | |
903 | |
904 | SourceLocation Loc = E->getExprLoc(); |
905 | if (LHSTy->isAnyComplexType()) { |
906 | ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc); |
907 | OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); |
908 | } else { |
909 | llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc); |
910 | |
911 | |
912 | if (LHSTy->isRealFloatingType()) { |
913 | if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy)) |
914 | LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc); |
915 | OpInfo.LHS = ComplexPairTy(LHSVal, nullptr); |
916 | } else { |
917 | OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); |
918 | } |
919 | } |
920 | |
921 | |
922 | ComplexPairTy Result = (this->*Func)(OpInfo); |
923 | |
924 | |
925 | if (LHSTy->isAnyComplexType()) { |
926 | ComplexPairTy ResVal = |
927 | EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc); |
928 | EmitStoreOfComplex(ResVal, LHS, false); |
929 | Val = RValue::getComplex(ResVal); |
930 | } else { |
931 | llvm::Value *ResVal = |
932 | CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc); |
933 | CGF.EmitStoreOfScalar(ResVal, LHS, false); |
934 | Val = RValue::get(ResVal); |
935 | } |
936 | |
937 | return LHS; |
938 | } |
939 | |
940 | |
941 | ComplexPairTy ComplexExprEmitter:: |
942 | EmitCompoundAssign(const CompoundAssignOperator *E, |
943 | ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ |
944 | RValue Val; |
945 | LValue LV = EmitCompoundAssignLValue(E, Func, Val); |
946 | |
947 | |
948 | if (!CGF.getLangOpts().CPlusPlus) |
949 | return Val.getComplexVal(); |
950 | |
951 | |
952 | if (!LV.isVolatileQualified()) |
953 | return Val.getComplexVal(); |
954 | |
955 | return EmitLoadOfLValue(LV, E->getExprLoc()); |
956 | } |
957 | |
958 | LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, |
959 | ComplexPairTy &Val) { |
960 | (0) . __assert_fail ("CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), E->getRHS()->getType()) && \"Invalid assignment\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 962, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), |
961 | (0) . __assert_fail ("CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), E->getRHS()->getType()) && \"Invalid assignment\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 962, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> E->getRHS()->getType()) && |
962 | (0) . __assert_fail ("CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), E->getRHS()->getType()) && \"Invalid assignment\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 962, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid assignment"); |
963 | TestAndClearIgnoreReal(); |
964 | TestAndClearIgnoreImag(); |
965 | |
966 | |
967 | Val = Visit(E->getRHS()); |
968 | |
969 | |
970 | LValue LHS = CGF.EmitLValue(E->getLHS()); |
971 | |
972 | |
973 | EmitStoreOfComplex(Val, LHS, false); |
974 | |
975 | return LHS; |
976 | } |
977 | |
978 | ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { |
979 | ComplexPairTy Val; |
980 | LValue LV = EmitBinAssignLValue(E, Val); |
981 | |
982 | |
983 | if (!CGF.getLangOpts().CPlusPlus) |
984 | return Val; |
985 | |
986 | |
987 | if (!LV.isVolatileQualified()) |
988 | return Val; |
989 | |
990 | return EmitLoadOfLValue(LV, E->getExprLoc()); |
991 | } |
992 | |
993 | ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { |
994 | CGF.EmitIgnoredExpr(E->getLHS()); |
995 | return Visit(E->getRHS()); |
996 | } |
997 | |
998 | ComplexPairTy ComplexExprEmitter:: |
999 | VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { |
1000 | TestAndClearIgnoreReal(); |
1001 | TestAndClearIgnoreImag(); |
1002 | llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); |
1003 | llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); |
1004 | llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); |
1005 | |
1006 | |
1007 | CodeGenFunction::OpaqueValueMapping binding(CGF, E); |
1008 | |
1009 | |
1010 | CodeGenFunction::ConditionalEvaluation eval(CGF); |
1011 | CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, |
1012 | CGF.getProfileCount(E)); |
1013 | |
1014 | eval.begin(CGF); |
1015 | CGF.EmitBlock(LHSBlock); |
1016 | CGF.incrementProfileCounter(E); |
1017 | ComplexPairTy LHS = Visit(E->getTrueExpr()); |
1018 | LHSBlock = Builder.GetInsertBlock(); |
1019 | CGF.EmitBranch(ContBlock); |
1020 | eval.end(CGF); |
1021 | |
1022 | eval.begin(CGF); |
1023 | CGF.EmitBlock(RHSBlock); |
1024 | ComplexPairTy RHS = Visit(E->getFalseExpr()); |
1025 | RHSBlock = Builder.GetInsertBlock(); |
1026 | CGF.EmitBlock(ContBlock); |
1027 | eval.end(CGF); |
1028 | |
1029 | |
1030 | llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r"); |
1031 | RealPN->addIncoming(LHS.first, LHSBlock); |
1032 | RealPN->addIncoming(RHS.first, RHSBlock); |
1033 | |
1034 | |
1035 | llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i"); |
1036 | ImagPN->addIncoming(LHS.second, LHSBlock); |
1037 | ImagPN->addIncoming(RHS.second, RHSBlock); |
1038 | |
1039 | return ComplexPairTy(RealPN, ImagPN); |
1040 | } |
1041 | |
1042 | ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { |
1043 | return Visit(E->getChosenSubExpr()); |
1044 | } |
1045 | |
1046 | ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { |
1047 | bool Ignore = TestAndClearIgnoreReal(); |
1048 | (void)Ignore; |
1049 | (0) . __assert_fail ("Ignore == false && \"init list ignored\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1049, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert (Ignore == false && "init list ignored"); |
1050 | Ignore = TestAndClearIgnoreImag(); |
1051 | (void)Ignore; |
1052 | (0) . __assert_fail ("Ignore == false && \"init list ignored\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1052, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert (Ignore == false && "init list ignored"); |
1053 | |
1054 | if (E->getNumInits() == 2) { |
1055 | llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); |
1056 | llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1)); |
1057 | return ComplexPairTy(Real, Imag); |
1058 | } else if (E->getNumInits() == 1) { |
1059 | return Visit(E->getInit(0)); |
1060 | } |
1061 | |
1062 | |
1063 | (0) . __assert_fail ("E->getNumInits() == 0 && \"Unexpected number of inits\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1063, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E->getNumInits() == 0 && "Unexpected number of inits"); |
1064 | QualType Ty = E->getType()->castAs<ComplexType>()->getElementType(); |
1065 | llvm::Type* LTy = CGF.ConvertType(Ty); |
1066 | llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); |
1067 | return ComplexPairTy(zeroConstant, zeroConstant); |
1068 | } |
1069 | |
1070 | ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { |
1071 | Address ArgValue = Address::invalid(); |
1072 | Address ArgPtr = CGF.EmitVAArg(E, ArgValue); |
1073 | |
1074 | if (!ArgPtr.isValid()) { |
1075 | CGF.ErrorUnsupported(E, "complex va_arg expression"); |
1076 | llvm::Type *EltTy = |
1077 | CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); |
1078 | llvm::Value *U = llvm::UndefValue::get(EltTy); |
1079 | return ComplexPairTy(U, U); |
1080 | } |
1081 | |
1082 | return EmitLoadOfLValue(CGF.MakeAddrLValue(ArgPtr, E->getType()), |
1083 | E->getExprLoc()); |
1084 | } |
1085 | |
1086 | |
1087 | |
1088 | |
1089 | |
1090 | |
1091 | |
1092 | ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, |
1093 | bool IgnoreImag) { |
1094 | (0) . __assert_fail ("E && getComplexType(E->getType()) && \"Invalid complex expression to emit\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1095, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E && getComplexType(E->getType()) && |
1095 | (0) . __assert_fail ("E && getComplexType(E->getType()) && \"Invalid complex expression to emit\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1095, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid complex expression to emit"); |
1096 | |
1097 | return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) |
1098 | .Visit(const_cast<Expr *>(E)); |
1099 | } |
1100 | |
1101 | void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, |
1102 | bool isInit) { |
1103 | (0) . __assert_fail ("E && getComplexType(E->getType()) && \"Invalid complex expression to emit\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1104, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E && getComplexType(E->getType()) && |
1104 | (0) . __assert_fail ("E && getComplexType(E->getType()) && \"Invalid complex expression to emit\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1104, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid complex expression to emit"); |
1105 | ComplexExprEmitter Emitter(*this); |
1106 | ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); |
1107 | Emitter.EmitStoreOfComplex(Val, dest, isInit); |
1108 | } |
1109 | |
1110 | |
1111 | void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest, |
1112 | bool isInit) { |
1113 | ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit); |
1114 | } |
1115 | |
1116 | |
1117 | ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src, |
1118 | SourceLocation loc) { |
1119 | return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc); |
1120 | } |
1121 | |
1122 | LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { |
1123 | getOpcode() == BO_Assign", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGExprComplex.cpp", 1123, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E->getOpcode() == BO_Assign); |
1124 | ComplexPairTy Val; |
1125 | return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); |
1126 | } |
1127 | |
1128 | typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( |
1129 | const ComplexExprEmitter::BinOpInfo &); |
1130 | |
1131 | static CompoundFunc getComplexOp(BinaryOperatorKind Op) { |
1132 | switch (Op) { |
1133 | case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; |
1134 | case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; |
1135 | case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; |
1136 | case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd; |
1137 | default: |
1138 | llvm_unreachable("unexpected complex compound assignment"); |
1139 | } |
1140 | } |
1141 | |
1142 | LValue CodeGenFunction:: |
1143 | EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { |
1144 | CompoundFunc Op = getComplexOp(E->getOpcode()); |
1145 | RValue Val; |
1146 | return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); |
1147 | } |
1148 | |
1149 | LValue CodeGenFunction:: |
1150 | EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, |
1151 | llvm::Value *&Result) { |
1152 | CompoundFunc Op = getComplexOp(E->getOpcode()); |
1153 | RValue Val; |
1154 | LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); |
1155 | Result = Val.getScalarVal(); |
1156 | return Ret; |
1157 | } |
1158 | |