// FIXME could be optimized by folding consecutive concats to one destination CharacterValueTy CharacterExprEmitter::VisitBinaryExprConcat(const BinaryExpr *E) { auto CharType = CGF.getContext().CharacterTy; CharacterValueTy Dest; if(hasDestination()) { Dest = takeDestination(); } else { // FIXME temp size overflow checking. auto CharTyLHS = E->getLHS()->getType()->asCharacterType(); auto CharTyRHS = E->getRHS()->getType()->asCharacterType(); auto Size = CharTyLHS->getLength() + CharTyRHS->getLength(); auto Storage = CGF.CreateTempAlloca(llvm::ArrayType::get(CGF.getModule().Int8Ty, Size), "concat-result"); Dest = CharacterValueTy(Builder.CreateConstInBoundsGEP2_32( llvm::ArrayType::get(CGF.getModule().Int8Ty, Size), Storage, 0, 0), llvm::ConstantInt::get(CGF.getModule().SizeTy, Size)); } // a = b // c auto Src1 = EmitExpr(E->getLHS()); auto Src2 = EmitExpr(E->getRHS()); auto Func = CGF.getModule().GetRuntimeFunction3(MANGLE_CHAR_FUNCTION("concat", CharType), CharType, CharType, CharType); CGF.EmitCall3(Func, Dest, Src1, Src2); return Dest; }
ComplexValueTy ComplexExprEmitter::VisitVarExpr(const VarExpr *E) { auto VD = E->getVarDecl(); if(CGF.IsInlinedArgument(VD)) return CGF.GetInlinedArgumentValue(VD).asComplex(); if(VD->isParameter()) return EmitExpr(VD->getInit()); auto Ptr = CGF.GetVarPtr(VD); return CGF.EmitComplexLoad(Ptr); }
RValueTy AggregateExprEmitter::VisitVarExpr(const VarExpr *E) { auto VD = E->getVarDecl(); if(CGF.IsInlinedArgument(VD)) return CGF.GetInlinedArgumentValue(VD); else if(VD->isParameter()) return EmitExpr(VD->getInit()); else if(VD->isFunctionResult()) return RValueTy::getAggregate(CGF.GetRetVarPtr()); return RValueTy::getAggregate(CGF.GetVarPtr(VD)); }
CharacterValueTy CharacterExprEmitter::VisitVarExpr(const VarExpr *E) { auto VD = E->getVarDecl(); if(CGF.IsInlinedArgument(VD)) return CGF.GetInlinedArgumentValue(VD).asCharacter(); if(VD->isArgument()) return CGF.GetCharacterArg(VD); else if(VD->isParameter()) return EmitExpr(VD->getInit()); else if(VD->isFunctionResult()) return CGF.ExtractCharacterValue(CGF.GetRetVarPtr()); return CGF.GetCharacterValueFromPtr(CGF.GetVarPtr(VD), VD->getType()); }
ComplexValueTy ComplexExprEmitter::VisitBinaryExprPow(const BinaryExpr *E) { auto LHS = EmitExpr(E->getLHS()); if(E->getRHS()->getType()->isIntegerType()) { auto RHS = CGF.EmitScalarExpr(E->getRHS()); // (a+ib) ** 1 => (a+ib) // (a+ib) ** 2 => // (a+ib) * (a+ib) => // a*a + 2iab + i**2*b*b => // a*a - b*b + 2iab // (a+ib) ** n => // ( r*cos(a) + ir*sin(a) )**n => // r ** n cos(n*a) + ir ** n sin(n*a) if(auto ConstInt = dyn_cast<llvm::ConstantInt>(RHS)) { if(ConstInt->equalsInt(1)) return LHS; else if(ConstInt->equalsInt(2)) return CGF.EmitComplexBinaryExpr(BinaryExpr::Multiply, LHS, LHS); } return CGF.EmitComplexPowi(LHS, RHS); } return CGF.EmitComplexPow(LHS, EmitExpr(E->getRHS())); }
CharacterValueTy CharacterExprEmitter::VisitSubstringExpr(const SubstringExpr *E) { auto Str = EmitExpr(E->getTarget()); if(E->getStartingPoint()) { auto Start = Builder.CreateSub(CGF.EmitSizeIntExpr(E->getStartingPoint()), llvm::ConstantInt::get(CGF.getModule().SizeTy, 1)); Str.Ptr = Builder.CreateGEP(Str.Ptr, Start); if(E->getEndPoint()) { auto End = CGF.EmitSizeIntExpr(E->getEndPoint()); Str.Len = Builder.CreateSub(End, Start); } else Str.Len = Builder.CreateSub(Str.Len, Start); } else if(E->getEndPoint()) Str.Len = CGF.EmitSizeIntExpr(E->getEndPoint()); return Str; }
ComplexValueTy ComplexExprEmitter::VisitBinaryExpr(const BinaryExpr *E) { return CGF.EmitComplexBinaryExpr(E->getOperator(), EmitExpr(E->getLHS()), EmitExpr(E->getRHS())); }
ComplexValueTy ComplexExprEmitter::VisitUnaryExprMinus(const UnaryExpr *E) { return CGF.EmitComplexUnaryMinus(EmitExpr(E->getExpression())); }
ComplexValueTy ComplexExprEmitter::VisitUnaryExprPlus(const UnaryExpr *E) { return EmitExpr(E->getExpression()); }
ComplexValueTy ComplexExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) { auto Input = E->getExpression(); if(Input->getType()->isComplexType()) return CGF.EmitComplexToComplexConversion(EmitExpr(Input), E->getType().getSelfOrArrayElementType()); return CGF.EmitScalarToComplexConversion(CGF.EmitScalarExpr(Input), E->getType().getSelfOrArrayElementType()); }
RValueTy AggregateExprEmitter::VisitMemberExpr(const MemberExpr *E) { auto Val = EmitExpr(E->getTarget()); return RValueTy::getAggregate(CGF.EmitAggregateMember(Val.getAggregateAddr(), E->getField()), Val.isVolatileQualifier()); }