29#include "llvm/ADT/ScopeExit.h"
30#include "llvm/ADT/StringExtras.h"
31#include "llvm/ADT/StringRef.h"
43 case Stmt::IntegerLiteralClass:
45 case Stmt::StringLiteralClass: {
46 std::string ret(
"\"");
51 case Stmt::CharacterLiteralClass:
52 case Stmt::CXXNullPtrLiteralExprClass:
53 case Stmt::GNUNullExprClass:
54 case Stmt::CXXBoolLiteralExprClass:
55 case Stmt::FloatingLiteralClass:
56 case Stmt::ImaginaryLiteralClass:
57 case Stmt::ObjCStringLiteralClass:
65 if (
const auto *Ph = dyn_cast<til::Phi>(E))
76 if (
const auto *CA = TD.
getAttr<CapabilityAttr>())
77 return {CA->getName(), TD.
hasAttr<ReentrantCapabilityAttr>()};
121 while (
const auto *UO = dyn_cast<UnaryOperator>(Callee)) {
122 if (UO->getOpcode() != UO_Deref && UO->getOpcode() != UO_AddrOf &&
123 UO->getOpcode() != UO_Plus)
125 Callee = UO->getSubExpr()->IgnoreParenCasts();
127 return dyn_cast<MemberExpr>(Callee);
144 if (!DeclExp && !
Self)
153 else if (
const auto *ME = dyn_cast<MemberExpr>(DeclExp)) {
155 }
else if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
156 Ctx.
SelfArg = CE->getImplicitObjectArgument();
157 Ctx.
NumArgs = CE->getNumArgs();
159 }
else if (
const auto *CE = dyn_cast<CallExpr>(DeclExp)) {
163 Ctx.
NumArgs = CE->getNumArgs() - 1;
164 Ctx.
FunArgs = CE->getArgs() + 1;
168 Ctx.
NumArgs = CE->getNumArgs();
171 }
else if (
const auto *CE = dyn_cast<CXXConstructExpr>(DeclExp)) {
173 Ctx.
NumArgs = CE->getNumArgs();
181 if (
const auto *CMD = dyn_cast<CXXMethodDecl>(D))
182 if (CMD->getParent()->isLambda())
186 assert(!Ctx.
SelfArg &&
"Ambiguous self argument");
221 if (
const auto* SLit = dyn_cast<StringLiteral>(AttrExp)) {
222 if (SLit->getString() ==
"*")
233 if (
const auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) {
234 if (OE->getOperator() == OO_Exclaim) {
236 AttrExp = OE->getArg(0);
239 else if (
const auto *UO = dyn_cast<UnaryOperator>(AttrExp)) {
240 if (UO->getOpcode() == UO_LNot) {
254 if (
const auto *CE = dyn_cast<til::Cast>(E)) {
272 llvm::scope_exit Cleanup([&, RestoreClosure = VarsBeingTranslated.empty()
275 VarsBeingTranslated.erase(VD->getCanonicalDecl());
276 if (VarsBeingTranslated.empty())
277 LookupLocalVarExpr = RestoreClosure;
284 if (LookupLocalVarExpr) {
288 if (
const Expr *E = LookupLocalVarExpr(VD)) {
315 case Stmt::DeclRefExprClass:
317 case Stmt::CXXThisExprClass:
319 case Stmt::MemberExprClass:
321 case Stmt::ObjCIvarRefExprClass:
323 case Stmt::CallExprClass:
325 case Stmt::CXXMemberCallExprClass:
327 case Stmt::CXXOperatorCallExprClass:
329 case Stmt::UnaryOperatorClass:
331 case Stmt::BinaryOperatorClass:
332 case Stmt::CompoundAssignOperatorClass:
335 case Stmt::ArraySubscriptExprClass:
337 case Stmt::ConditionalOperatorClass:
338 return translateAbstractConditionalOperator(
340 case Stmt::BinaryConditionalOperatorClass:
341 return translateAbstractConditionalOperator(
345 case Stmt::ConstantExprClass:
347 case Stmt::ParenExprClass:
349 case Stmt::ExprWithCleanupsClass:
351 case Stmt::CXXBindTemporaryExprClass:
353 case Stmt::MaterializeTemporaryExprClass:
357 case Stmt::CharacterLiteralClass:
360 case Stmt::CXXNullPtrLiteralExprClass:
361 case Stmt::GNUNullExprClass:
363 case Stmt::CXXBoolLiteralExprClass:
365 case Stmt::IntegerLiteralClass: {
368 const llvm::APInt &
Value = IL->getValue();
369 if (BT->isSignedInteger())
371 else if (BT->isUnsignedInteger())
374 llvm_unreachable(
"Invalid integer type");
376 case Stmt::StringLiteralClass:
378 case Stmt::ObjCStringLiteralClass:
382 case Stmt::DeclStmtClass:
384 case Stmt::StmtExprClass:
389 if (
const auto *CE = dyn_cast<CastExpr>(S))
390 return translateCastExpr(CE, Ctx);
399 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
401 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D))
403 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
404 if (
auto *TSI = DD->getTypeSourceInfo()) {
405 TypeLoc TL = TSI->getTypeLoc();
407 TL = RTL.getPointeeLoc();
410 TL = PTL.getPointeeLoc();
412 if (I < FPTL.getNumParams())
413 return FPTL.getParam(I);
420 if (
const auto *
V = dyn_cast<til::Variable>(E))
421 return V->clangDecl();
422 if (
const auto *Ph = dyn_cast<til::Phi>(E))
423 return Ph->clangDecl();
424 if (
const auto *P = dyn_cast<til::Project>(E))
425 return P->clangDecl();
426 if (
const auto *L = dyn_cast<til::LiteralPtr>(E))
427 return L->clangDecl();
433 if (VD && VD->getType()->isAnyPointerType())
435 if (
const auto *
C = dyn_cast<til::Cast>(E))
441til::SExpr *SExprBuilder::translateDeclRefExpr(
const DeclRefExpr *DRE,
446 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
447 unsigned I = PV->getFunctionScopeIndex();
448 const DeclContext *D = PV->getDeclContext();
452 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
453 Match = (FD->getCanonicalDecl() == Canonical);
454 else if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D))
455 Match = (MD->getCanonicalDecl() == Canonical);
459 llvm_unreachable(
"ParmVarDecl does not belong to current declaration");
463 if (
const Expr *
const *FunArgs =
464 dyn_cast<const Expr *const *>(Ctx->
FunArgs)) {
465 assert(I < Ctx->NumArgs);
479 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
487 if (
const auto *FD = dyn_cast<FieldDecl>(VD); FD && Ctx && Ctx->
SelfArg) {
488 til::SExpr *BE = translateCXXThisExpr(
nullptr, Ctx);
489 til::SExpr *E =
new (Arena) til::SApply(BE);
490 til::Project *P =
new (Arena) til::Project(E, FD);
497 return new (Arena) til::LiteralPtr(VD);
500til::SExpr *SExprBuilder::translateCXXThisExpr(
const CXXThisExpr *TE,
504 if (
const auto *SelfArg = dyn_cast<const Expr *>(Ctx->
SelfArg))
509 assert(SelfVar &&
"We have no variable for 'this'!");
518 if (OverriddenMethods.begin() == OverriddenMethods.end())
521 D = *OverriddenMethods.begin();
526til::SExpr *SExprBuilder::translateMemberExpr(
const MemberExpr *ME,
529 til::SExpr *E =
new (Arena) til::SApply(BE);
532 if (
const auto *VD = dyn_cast<CXXMethodDecl>(D))
535 til::Project *P =
new (Arena) til::Project(E, D);
541til::SExpr *SExprBuilder::translateObjCIVarRefExpr(
const ObjCIvarRefExpr *IVRE,
544 til::SExpr *E =
new (Arena) til::SApply(BE);
548 til::Project *P =
new (Arena) til::Project(E, D);
554til::SExpr *SExprBuilder::translateCallExpr(
const CallExpr *CE,
557 if (CapabilityExprMode) {
559 if (
const auto *D = dyn_cast_or_null<NamedDecl>(CE->
getCalleeDecl())) {
560 const NamedDecl *AttrD = D;
561 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
563 if (
const auto *At = AttrD->
getAttr<LockReturnedAttr>()) {
565 LRCallCtx.AttrDecl = D;
566 LRCallCtx.SelfArg = SelfE;
569 LRCallCtx.SelfArg = ME->
getBase();
571 LRCallCtx.FunArgs = CE->
getArgs();
572 return const_cast<til::SExpr *
>(
582 for (
const auto *Arg : CE->
arguments()) {
584 E =
new (Arena) til::Apply(E, A);
586 return new (Arena) til::Call(E, CE);
589til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
591 if (CapabilityExprMode) {
606til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
608 if (CapabilityExprMode) {
611 if (k == OO_Star || k == OO_Arrow) {
620til::SExpr *SExprBuilder::translateUnaryOperator(
const UnaryOperator *UO,
627 return new (Arena) til::Undefined(UO);
630 if (CapabilityExprMode) {
632 if (
const auto *DRE = dyn_cast<DeclRefExpr>(UO->
getSubExpr())) {
636 auto *W =
new (Arena) til::Wildcard();
637 return new (Arena) til::Project(W, DRE->
getDecl());
664 return new (Arena) til::Undefined(UO);
666 return new (Arena) til::Undefined(UO);
670 const BinaryOperator *BO,
675 return new (Arena) til::BinaryOp(Op, E1, E0);
677 return new (Arena) til::BinaryOp(Op, E0, E1);
681 const BinaryOperator *BO,
684 const Expr *LHS = BO->
getLHS();
685 const Expr *RHS = BO->
getRHS();
689 const ValueDecl *VD =
nullptr;
690 til::SExpr *CV =
nullptr;
691 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
693 CV = lookupVarDecl(VD);
697 til::SExpr *Arg = CV ? CV :
new (Arena) til::Load(E0);
698 E1 =
new (Arena) til::BinaryOp(Op, Arg, E1);
699 E1 = addStatement(E1,
nullptr, VD);
702 return updateVarDecl(VD, E1);
703 return new (Arena) til::Store(E0, E1);
706til::SExpr *SExprBuilder::translateBinaryOperator(
const BinaryOperator *BO,
711 return new (Arena) til::Undefined(BO);
713 case BO_Mul:
return translateBinOp(
til::BOP_Mul, BO, Ctx);
714 case BO_Div:
return translateBinOp(
til::BOP_Div, BO, Ctx);
715 case BO_Rem:
return translateBinOp(
til::BOP_Rem, BO, Ctx);
716 case BO_Add:
return translateBinOp(
til::BOP_Add, BO, Ctx);
717 case BO_Sub:
return translateBinOp(
til::BOP_Sub, BO, Ctx);
718 case BO_Shl:
return translateBinOp(
til::BOP_Shl, BO, Ctx);
719 case BO_Shr:
return translateBinOp(
til::BOP_Shr, BO, Ctx);
720 case BO_LT:
return translateBinOp(
til::BOP_Lt, BO, Ctx);
721 case BO_GT:
return translateBinOp(
til::BOP_Lt, BO, Ctx,
true);
722 case BO_LE:
return translateBinOp(
til::BOP_Leq, BO, Ctx);
723 case BO_GE:
return translateBinOp(
til::BOP_Leq, BO, Ctx,
true);
724 case BO_EQ:
return translateBinOp(
til::BOP_Eq, BO, Ctx);
725 case BO_NE:
return translateBinOp(
til::BOP_Neq, BO, Ctx);
726 case BO_Cmp:
return translateBinOp(
til::BOP_Cmp, BO, Ctx);
733 case BO_Assign:
return translateBinAssign(
til::BOP_Eq, BO, Ctx,
true);
734 case BO_MulAssign:
return translateBinAssign(
til::BOP_Mul, BO, Ctx);
735 case BO_DivAssign:
return translateBinAssign(
til::BOP_Div, BO, Ctx);
736 case BO_RemAssign:
return translateBinAssign(
til::BOP_Rem, BO, Ctx);
737 case BO_AddAssign:
return translateBinAssign(
til::BOP_Add, BO, Ctx);
738 case BO_SubAssign:
return translateBinAssign(
til::BOP_Sub, BO, Ctx);
739 case BO_ShlAssign:
return translateBinAssign(
til::BOP_Shl, BO, Ctx);
740 case BO_ShrAssign:
return translateBinAssign(
til::BOP_Shr, BO, Ctx);
741 case BO_AndAssign:
return translateBinAssign(
til::BOP_BitAnd, BO, Ctx);
742 case BO_XorAssign:
return translateBinAssign(
til::BOP_BitXor, BO, Ctx);
743 case BO_OrAssign:
return translateBinAssign(
til::BOP_BitOr, BO, Ctx);
749 return new (Arena) til::Undefined(BO);
756 case CK_LValueToRValue: {
757 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CE->
getSubExpr())) {
758 til::SExpr *E0 = lookupVarDecl(DRE->
getDecl());
768 case CK_DerivedToBase:
769 case CK_UncheckedDerivedToBase:
770 case CK_ArrayToPointerDecay:
771 case CK_FunctionToPointerDecay: {
778 if (CapabilityExprMode)
786SExprBuilder::translateArraySubscriptExpr(
const ArraySubscriptExpr *E,
790 return new (Arena) til::ArrayIndex(E0, E1);
794SExprBuilder::translateAbstractConditionalOperator(
799 return new (Arena) til::IfThenElse(
C,
T, E);
803SExprBuilder::translateDeclStmt(
const DeclStmt *S,
CallingContext *Ctx) {
805 for (
auto *I : DGrp) {
806 if (
auto *VD = dyn_cast_or_null<VarDecl>(I)) {
807 Expr *E = VD->getInit();
813 return addVarDecl(VD, SE);
822til::SExpr *SExprBuilder::translateStmtExpr(
const StmtExpr *SE,
827 return CS->
body_empty() ?
new (Arena) til::Undefined(SE)
836 const ValueDecl *VD) {
840 E =
new (Arena) til::Variable(E, VD);
841 CurrentInstructions.push_back(E);
848til::SExpr *SExprBuilder::lookupVarDecl(
const ValueDecl *VD) {
849 auto It = LVarIdxMap.find(VD);
850 if (It != LVarIdxMap.end()) {
851 assert(CurrentLVarMap[It->second].first == VD);
852 return CurrentLVarMap[It->second].second;
861 if (
auto *
V = dyn_cast<til::Variable>(E)) {
870 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));
871 CurrentLVarMap.makeWritable();
872 CurrentLVarMap.push_back(std::make_pair(VD, E));
879 auto It = LVarIdxMap.find(VD);
880 if (It == LVarIdxMap.end()) {
881 til::SExpr *
Ptr =
new (Arena) til::LiteralPtr(VD);
882 til::SExpr *St =
new (Arena) til::Store(Ptr, E);
885 CurrentLVarMap.makeWritable();
886 CurrentLVarMap.elem(It->second).second = E;
893void SExprBuilder::makePhiNodeVar(
unsigned i,
unsigned NPreds,
til::SExpr *E) {
894 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
895 assert(ArgIndex > 0 && ArgIndex < NPreds);
897 til::SExpr *CurrE = CurrentLVarMap[i].second;
898 if (CurrE->
block() == CurrentBB) {
901 auto *Ph = dyn_cast<til::Phi>(CurrE);
902 assert(Ph &&
"Expecting Phi node.");
904 Ph->values()[ArgIndex] = E;
910 til::Phi *Ph =
new (Arena) til::Phi(Arena, NPreds);
912 for (
unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
913 Ph->
values()[PIdx] = CurrE;
915 Ph->
values()[ArgIndex] = E;
923 CurrentArguments.push_back(Ph);
925 IncompleteArgs.push_back(Ph);
927 CurrentLVarMap.makeWritable();
928 CurrentLVarMap.elem(i).second = Ph;
933void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
934 assert(CurrentBlockInfo &&
"Not processing a block!");
936 if (!CurrentLVarMap.valid()) {
938 CurrentLVarMap = std::move(Map);
941 if (CurrentLVarMap.sameAs(Map))
944 unsigned NPreds = CurrentBB->numPredecessors();
945 unsigned ESz = CurrentLVarMap.size();
946 unsigned MSz = Map.size();
947 unsigned Sz = std::min(ESz, MSz);
949 for (
unsigned i = 0; i < Sz; ++i) {
950 if (CurrentLVarMap[i].first != Map[i].first) {
952 CurrentLVarMap.makeWritable();
953 CurrentLVarMap.downsize(i);
956 if (CurrentLVarMap[i].second != Map[i].second)
957 makePhiNodeVar(i, NPreds, Map[i].second);
960 CurrentLVarMap.makeWritable();
961 CurrentLVarMap.downsize(Map.size());
967void SExprBuilder::mergeEntryMapBackEdge() {
976 assert(CurrentBlockInfo &&
"Not processing a block!");
978 if (CurrentBlockInfo->HasBackEdges)
980 CurrentBlockInfo->HasBackEdges =
true;
982 CurrentLVarMap.makeWritable();
983 unsigned Sz = CurrentLVarMap.size();
984 unsigned NPreds = CurrentBB->numPredecessors();
986 for (
unsigned i = 0; i < Sz; ++i)
987 makePhiNodeVar(i, NPreds,
nullptr);
993void SExprBuilder::mergePhiNodesBackEdge(
const CFGBlock *Blk) {
995 unsigned ArgIndex = BBInfo[Blk->
getBlockID()].ProcessedPredecessors;
996 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
999 auto *Ph = dyn_cast_or_null<til::Phi>(PE);
1000 assert(Ph &&
"Expecting Phi Node.");
1001 assert(Ph->
values()[ArgIndex] ==
nullptr &&
"Wrong index for back edge.");
1003 til::SExpr *E = lookupVarDecl(Ph->
clangDecl());
1004 assert(E &&
"Couldn't find local variable for Phi node.");
1005 Ph->
values()[ArgIndex] = E;
1009void SExprBuilder::enterCFG(CFG *Cfg,
const NamedDecl *D,
1010 const CFGBlock *
First) {
1013 Scfg =
new (Arena) til::SCFG(Arena, NBlocks);
1016 BBInfo.resize(NBlocks);
1017 BlockMap.resize(NBlocks,
nullptr);
1019 for (
auto *B : *Cfg) {
1020 auto *BB =
new (Arena) til::BasicBlock(Arena);
1022 BlockMap[B->getBlockID()] = BB;
1028 for (
auto *Pm : Parms) {
1029 QualType
T = Pm->getType();
1030 if (!
T.isTrivialType(Pm->getASTContext()))
1035 til::SExpr *Lp =
new (Arena) til::LiteralPtr(Pm);
1036 til::SExpr *Ld =
new (Arena) til::Load(Lp);
1037 til::SExpr *
V = addStatement(Ld,
nullptr, Pm);
1042void SExprBuilder::enterCFGBlock(
const CFGBlock *B) {
1045 CurrentBB->reservePredecessors(B->
pred_size());
1046 Scfg->add(CurrentBB);
1055void SExprBuilder::handlePredecessor(
const CFGBlock *Pred) {
1058 CurrentBB->addPredecessor(BlockMap[Pred->
getBlockID()]);
1059 BlockInfo *PredInfo = &BBInfo[Pred->
getBlockID()];
1060 assert(PredInfo->UnprocessedSuccessors > 0);
1062 if (--PredInfo->UnprocessedSuccessors == 0)
1063 mergeEntryMap(std::move(PredInfo->ExitMap));
1065 mergeEntryMap(PredInfo->ExitMap.clone());
1067 ++CurrentBlockInfo->ProcessedPredecessors;
1070void SExprBuilder::handlePredecessorBackEdge(
const CFGBlock *Pred) {
1071 mergeEntryMapBackEdge();
1074void SExprBuilder::enterCFGBlockBody(
const CFGBlock *B) {
1077 CurrentBB->arguments().reserve(
1078 static_cast<unsigned>(CurrentArguments.size()), Arena);
1079 for (
auto *A : CurrentArguments)
1080 CurrentBB->addArgument(A);
1083void SExprBuilder::handleStatement(
const Stmt *S) {
1088void SExprBuilder::handleDestructorCall(
const VarDecl *VD,
1089 const CXXDestructorDecl *DD) {
1090 til::SExpr *Sf =
new (Arena) til::LiteralPtr(VD);
1091 til::SExpr *Dr =
new (Arena) til::LiteralPtr(DD);
1092 til::SExpr *Ap =
new (Arena) til::Apply(Dr, Sf);
1093 til::SExpr *E =
new (Arena) til::Call(Ap);
1094 addStatement(E,
nullptr);
1097void SExprBuilder::exitCFGBlockBody(
const CFGBlock *B) {
1098 CurrentBB->instructions().reserve(
1099 static_cast<unsigned>(CurrentInstructions.size()), Arena);
1100 for (
auto *
V : CurrentInstructions)
1101 CurrentBB->addInstruction(
V);
1110 auto *Tm =
new (Arena) til::Goto(BB, Idx);
1111 CurrentBB->setTerminator(Tm);
1119 auto *Tm =
new (Arena) til::Branch(
C, BB1, BB2);
1120 CurrentBB->setTerminator(Tm);
1124void SExprBuilder::handleSuccessor(
const CFGBlock *Succ) {
1125 ++CurrentBlockInfo->UnprocessedSuccessors;
1128void SExprBuilder::handleSuccessorBackEdge(
const CFGBlock *Succ) {
1129 mergePhiNodesBackEdge(Succ);
1130 ++BBInfo[Succ->
getBlockID()].ProcessedPredecessors;
1133void SExprBuilder::exitCFGBlock(
const CFGBlock *B) {
1134 CurrentArguments.clear();
1135 CurrentInstructions.clear();
1136 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
1137 CurrentBB =
nullptr;
1138 CurrentBlockInfo =
nullptr;
1141void SExprBuilder::exitCFG(
const CFGBlock *
Last) {
1142 for (
auto *Ph : IncompleteArgs) {
1147 CurrentArguments.clear();
1148 CurrentInstructions.clear();
1149 IncompleteArgs.clear();
1164 llvm::BumpPtrAllocator Bpa;
1168 TILPrinter::print(Scfg, llvm::errs());
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines an enumeration for C++ overloaded operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines various enumerations that describe declaration and type specifiers.
static bool isIncompletePhi(const til::SExpr *E)
static const MemberExpr * getFunPtrFieldCallee(const CallExpr *CE, const NamedDecl *D)
If CE calls through a function pointer field D, return the member access through which the field was ...
SExprBuilder::CallingContext CallingContext
static const ParmVarDecl * getCanonicalParamDecl(const Decl *D, unsigned I)
Helper to extract the canonical parameter declaration from a function or function pointer.
static const ValueDecl * getValueDeclFromSExpr(const til::SExpr *E)
static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD)
static bool hasAnyPointerType(const til::SExpr *E)
static const CXXMethodDecl * getFirstVirtualDecl(const CXXMethodDecl *D)
static std::pair< StringRef, bool > classifyCapability(const TypeDecl &TD)
static constexpr std::pair< StringRef, bool > ClassifyCapabilityFallback
C Language Family Type Representation.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
succ_iterator succ_begin()
unsigned pred_size() const
const Stmt * getTerminatorCondition(bool StripParens=true) const
unsigned getBlockID() const
unsigned succ_size() const
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Represents a static or instance method of a struct/union/class.
overridden_method_range overridden_methods() const
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr ** getArgs()
Retrieve the call arguments.
CastKind getCastKind() const
const DeclGroupRef getDeclGroup() const
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
NamedDecl * getMostRecentDecl()
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
ObjCIvarDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
const Expr * getBase() const
Represents a parameter to a function.
Wrapper for source info for pointers.
A (possibly-)qualified type.
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
Represents a declaration of a type.
Base wrapper for a particular "section" of type source info.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isPointerOrReferenceType() const
const T * getAs() const
Member-template getAs<specific type>'.
Expr * getSubExpr() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const til::SExpr * sexpr() const
CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D, const Expr *DeclExp, til::SExpr *Self=nullptr)
Translate a clang expression in an attribute to a til::SExpr.
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
til::SExpr * lookupStmt(const Stmt *S)
til::SCFG * buildCFG(CFGWalker &Walker)
til::SExpr * translateVariable(const VarDecl *VD, CallingContext *Ctx)
til::BasicBlock * lookupBlock(const CFGBlock *B)
const InstrArray & arguments() const
void reserveInstructions(unsigned Nins)
unsigned findPredecessorIndex(const BasicBlock *BB) const
Return the index of BB, or Predecessors.size if BB is not a predecessor.
A Literal pointer to an object allocated in memory.
const ValueDecl * clangDecl() const
Return the clang declaration of the variable for this Phi node, if any.
void setClangDecl(const ValueDecl *Cvd)
Set the clang variable associated with this Phi node.
const ValArray & values() const
An SCFG is a control-flow graph.
Base class for AST nodes in the typed intermediate language.
BasicBlock * block() const
Returns the block, if this is an instruction in a basic block, otherwise returns null.
void setValues(unsigned Sz, const T &C)
Placeholder for expressions that cannot be represented in the TIL.
Placeholder for a wildcard that matches any other expression.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
bool isTrivial(const SExpr *E)
void simplifyIncompleteArg(til::Phi *Ph)
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void printSCFG(CFGWalker &Walker)
std::string getSourceLiteralString(const Expr *CE)
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
const FunctionProtoType * T
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Encapsulates the lexical context of a function call.
llvm::PointerUnion< const Expr *const *, til::SExpr * > FunArgs
const NamedDecl * AttrDecl
llvm::PointerUnion< const Expr *, til::SExpr * > SelfArg