static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M, const ParmVarDecl *Callback, ArrayRef<Expr *> CallArgs) { QualType Ty = Callback->getType(); DeclRefExpr *Call = M.makeDeclRefExpr(Callback); Expr *SubExpr; if (Ty->isRValueReferenceType()) { SubExpr = M.makeImplicitCast( Call, Ty.getNonReferenceType(), CK_LValueToRValue); } else if (Ty->isLValueReferenceType() && Call->getType()->isFunctionType()) { Ty = C.getPointerType(Ty.getNonReferenceType()); SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay); } else if (Ty->isLValueReferenceType() && Call->getType()->isPointerType() && Call->getType()->getPointeeType()->isFunctionType()){ SubExpr = Call; } else { llvm_unreachable("Unexpected state"); } return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue, SourceLocation()); }
Stmt *TransformWCR::VisitWhileStmt(WhileStmt *S) { StmtVector OuterBody; StmtVector BodyStmts; StmtVector WCRBody; // Declaration of condition variable VarDecl *CondVD = NewCondVarDecl(S->getCond()->getType()); CondDecls.push_back(NewDeclStmt(CondVD)); // Computation of condition DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD, CondVD->getType(), VK_RValue, SourceLocation()); BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator( LHS, S->getCond(), BO_Assign, LHS->getType(), VK_RValue, OK_Ordinary, SourceLocation()); // Cond WCR MergeBodyAndCond(BodyStmts, CondBinOp); // Exit condition DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD, CondVD->getType(), VK_RValue, SourceLocation()); UnaryOperator *NotCond = new (ASTCtx) UnaryOperator( CondRef, UO_LNot, CondVD->getType(), VK_RValue, OK_Ordinary, SourceLocation()); BreakStmt *ThenStmt = new (ASTCtx) BreakStmt(SourceLocation()); IfStmt *ExitStmt = new (ASTCtx) IfStmt(ASTCtx, SourceLocation(), NULL, NotCond, ThenStmt); BodyStmts.push_back(ExitStmt); // Body Stmt *Body = S->getBody(); CompoundStmt *CS = dyn_cast<CompoundStmt>(Body); assert(CS && "Not a CompoundStmt"); // Identify each WCR VisitRawCompoundStmt(CS, BodyStmts, WCRBody); MergeBodyAndWCR(BodyStmts, WCRBody); ASTCtx.Deallocate(S); ASTCtx.Deallocate(CS); // Outer WhileStmt Expr *Cond = CLExprs.getExpr(CLExpressions::ONE); Body = MergeWCRsAndMakeCompoundStmt(BodyStmts); WhileStmt *WS = new (ASTCtx) WhileStmt(ASTCtx, NULL, Cond, Body, SourceLocation()); OuterBody.push_back(WS); // Landing pad - empty WCR OuterBody.push_back(NewLandingPad(WS)); return NewStmtList(OuterBody); }
//--------------------------------------------------------- VarDecl* isFortranLoop(ForStmt* Node, const char*& errMsg) { // cond must be of form "x >/</!=/ expr": BinaryOperator* condCmp = dyn_cast_or_null<BinaryOperator>(Node->getCond()); if (condCmp == 0 || ((!condCmp->isRelationalOp()) && condCmp->getOpcode() != BO_NE)) { errMsg = "for-cond not fortran-like (must be x rel expr)"; return 0; } DeclRefExpr* condVar = dyn_cast<DeclRefExpr>(stripParenCasts(condCmp->getLHS())); if (condVar == 0 || !condVar->getType()->isIntegerType()) { errMsg = "no integer for-init variable"; return 0; } VarDecl* VD = dyn_cast<VarDecl>(condVar->getDecl()); if (VD == 0) { errMsg = "strange unrecognized lhs in for-condition"; return 0; } // inc must be of form "++x/x++": UnaryOperator* incStmt = dyn_cast_or_null<UnaryOperator>(Node->getInc()); if (incStmt == 0 || (!incStmt->isIncrementOp())) { errMsg = "for-inc not fortran-like (must be ++x/x++)"; return 0; } DeclRefExpr* incVar = dyn_cast<DeclRefExpr>(incStmt->getSubExpr()); if (incVar == 0 || incVar->getDecl() != VD) { errMsg = "for-inc doesn't refer to for-cond variable"; return 0; } return VD; }
Stmt *TransformWCR::VisitIfStmt(IfStmt *S) { StmtVector OuterBody; // Declaration of the condition variable VarDecl *CondVD = NewCondVarDecl(S->getCond()->getType()); CondDecls.push_back(NewDeclStmt(CondVD)); // Computation of the condition DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD, CondVD->getType(), VK_RValue, SourceLocation()); BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator( LHS, S->getCond(), BO_Assign, LHS->getType(), VK_RValue, OK_Ordinary, SourceLocation()); MergeBodyAndCond(OuterBody, CondBinOp); // Cond DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD, CondVD->getType(), VK_RValue, SourceLocation()); S->setCond(CondRef); // Then Stmt *Then = S->getThen(); CompoundStmt *ThenCS = dyn_cast<CompoundStmt>(Then); assert(ThenCS && "Not a CompoundStmt"); S->setThen(VisitCompoundStmt(ThenCS)); // Else if (Stmt *Else = S->getElse()) { CompoundStmt *ElseCS = dyn_cast<CompoundStmt>(Else); assert(ElseCS && "Not a CompoundStmt"); S->setElse(VisitCompoundStmt(ElseCS)); } OuterBody.push_back(S); return NewStmtList(OuterBody); }
Stmt *TransformWCR::VisitForStmt(ForStmt *S) { StmtVector OuterBody; StmtVector BodyStmts; StmtVector WCRBody; // If Init of ForStmt has a DeclStmt, we make a CompoundStmt that encloses // an Init stmt and WhileStmt made from orginal ForStmt. bool HasDecl = false; // Init if (Stmt *Init = S->getInit()) { if (DeclStmt *DS = dyn_cast<DeclStmt>(Init)) { HasDecl = true; StmtVector tmpWCR; VisitRawDeclStmt(DS, OuterBody, tmpWCR); MergeBodyAndWCR(OuterBody, tmpWCR); } else { MergeBodyAndCond(OuterBody, Init); } } // Declaration of condition variable VarDecl *CondVD = NewCondVarDecl(ASTCtx.IntTy); CondDecls.push_back(NewDeclStmt(CondVD)); // Computation of condition DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD, CondVD->getType(), VK_RValue, SourceLocation()); Expr *Cond = S->getCond(); if (!Cond) Cond = CLExprs.getExpr(CLExpressions::ONE); BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator( LHS, Cond, BO_Assign, LHS->getType(), VK_RValue, OK_Ordinary, SourceLocation()); // Cond WCR MergeBodyAndCond(BodyStmts, CondBinOp); // Exit condition DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD, CondVD->getType(), VK_RValue, SourceLocation()); UnaryOperator *NotCond = new (ASTCtx) UnaryOperator( CondRef, UO_LNot, CondVD->getType(), VK_RValue, OK_Ordinary, SourceLocation()); BreakStmt *ThenStmt = new (ASTCtx) BreakStmt(SourceLocation()); IfStmt *ExitStmt = new (ASTCtx) IfStmt(ASTCtx, SourceLocation(), NULL, NotCond, ThenStmt); BodyStmts.push_back(ExitStmt); // Body Stmt *Body = S->getBody(); CompoundStmt *CS = dyn_cast<CompoundStmt>(Body); assert(CS && "Not a CompoundStmt"); // Identify each WCR VisitRawCompoundStmt(CS, BodyStmts, WCRBody); MergeBodyAndWCR(BodyStmts, WCRBody); // Inc if (Expr *Inc = S->getInc()) MergeBodyAndCond(BodyStmts, Inc); ASTCtx.Deallocate(S); ASTCtx.Deallocate(CS); // Outer WhileStmt Cond = CLExprs.getExpr(CLExpressions::ONE); Body = MergeWCRsAndMakeCompoundStmt(BodyStmts); WhileStmt *WS = new (ASTCtx) WhileStmt(ASTCtx, NULL, Cond, Body, SourceLocation()); OuterBody.push_back(WS); // Landing pad - empty WCR OuterBody.push_back(NewLandingPad(WS)); CompoundStmt *Out = NewCompoundStmt(OuterBody); if (!HasDecl) Out->setIsStmtList(true); return Out; }