clang: lib/Analysis/ThreadSafetyCommon.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

29#include "llvm/ADT/StringExtras.h"

30#include "llvm/ADT/StringRef.h"

31#include "llvm/Support/Casting.h"

32#include

33#include

34#include

35#include

36

37using namespace clang;

38using namespace threadSafety;

39

40

43 case Stmt::IntegerLiteralClass:

44 return toString(cast(CE)->getValue(), 10, true);

45 case Stmt::StringLiteralClass: {

46 std::string ret("\"");

47 ret += cast(CE)->getString();

48 ret += "\"";

49 return ret;

50 }

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:

58 default:

59 return "#lit";

60 }

61}

62

63

65 if (const auto *Ph = dyn_casttil::Phi(E))

67 return false;

68}

69

71

73

75 Walker.walk(*this);

76 return Scfg;

77}

78

81 return ME ? ME->isArrow() : false;

82}

83

85 return A->getName();

86}

87

89

90

91

93 if (const auto *RD = RT->getDecl())

94 if (const auto *CA = RD->getAttr())

97 if (const auto *TD = TT->getDecl())

98 if (const auto *CA = TD->getAttr())

102

103 return "mutex";

104}

105

106

107

108

109

110

111

112

113

114

117 const Expr *DeclExp,

119

120 if (!DeclExp && Self)

122

124

125

126

127 if (!DeclExp)

128 ;

129 else if (const auto *ME = dyn_cast(DeclExp)) {

130 Ctx.SelfArg = ME->getBase();

132 } else if (const auto *CE = dyn_cast(DeclExp)) {

133 Ctx.SelfArg = CE->getImplicitObjectArgument();

135 Ctx.NumArgs = CE->getNumArgs();

136 Ctx.FunArgs = CE->getArgs();

137 } else if (const auto *CE = dyn_cast(DeclExp)) {

138

139 if (isa(CE) && isa(D)) {

140 Ctx.SelfArg = CE->getArg(0);

142 Ctx.NumArgs = CE->getNumArgs() - 1;

143 Ctx.FunArgs = CE->getArgs() + 1;

144 } else {

145 Ctx.NumArgs = CE->getNumArgs();

146 Ctx.FunArgs = CE->getArgs();

147 }

148 } else if (const auto *CE = dyn_cast(DeclExp)) {

149 Ctx.SelfArg = nullptr;

150 Ctx.NumArgs = CE->getNumArgs();

151 Ctx.FunArgs = CE->getArgs();

152 }

153

154

155

156

157

158 if (const auto *CMD = dyn_cast(D))

159 if (CMD->getParent()->isLambda())

161

163 assert(!Ctx.SelfArg && "Ambiguous self argument");

164 assert(isa(D) && "Self argument requires function");

165 if (isa(D))

167 else

169

170

171 if (!AttrExp)

175 cast(D)->getFunctionObjectParameterType()),

176 false);

177 else

179 }

180

181

182 if (!AttrExp)

184 else

186}

187

188

189

192 if (!AttrExp)

194

195 if (const auto* SLit = dyn_cast(AttrExp)) {

196 if (SLit->getString() == "*")

197

198

200 false);

201 else

202

204 }

205

206 bool Neg = false;

207 if (const auto *OE = dyn_cast(AttrExp)) {

208 if (OE->getOperator() == OO_Exclaim) {

209 Neg = true;

210 AttrExp = OE->getArg(0);

211 }

212 }

213 else if (const auto *UO = dyn_cast(AttrExp)) {

214 if (UO->getOpcode() == UO_LNot) {

215 Neg = true;

217 }

218 }

219

221

222

223

224 if (E || isatil::Literal(E))

226

228

229

230 if (const auto *CE = dyn_casttil::Cast(E)) {

233 }

235}

236

239}

240

241std::pair<til::LiteralPtr *, StringRef>

245}

246

247

248

249

251 if (!S)

252 return nullptr;

253

254

255

257 return E;

258

259 switch (S->getStmtClass()) {

260 case Stmt::DeclRefExprClass:

261 return translateDeclRefExpr(cast(S), Ctx);

262 case Stmt::CXXThisExprClass:

263 return translateCXXThisExpr(cast(S), Ctx);

264 case Stmt::MemberExprClass:

265 return translateMemberExpr(cast(S), Ctx);

266 case Stmt::ObjCIvarRefExprClass:

267 return translateObjCIVarRefExpr(cast(S), Ctx);

268 case Stmt::CallExprClass:

269 return translateCallExpr(cast(S), Ctx);

270 case Stmt::CXXMemberCallExprClass:

271 return translateCXXMemberCallExpr(cast(S), Ctx);

272 case Stmt::CXXOperatorCallExprClass:

273 return translateCXXOperatorCallExpr(cast(S), Ctx);

274 case Stmt::UnaryOperatorClass:

275 return translateUnaryOperator(cast(S), Ctx);

276 case Stmt::BinaryOperatorClass:

277 case Stmt::CompoundAssignOperatorClass:

278 return translateBinaryOperator(cast(S), Ctx);

279

280 case Stmt::ArraySubscriptExprClass:

281 return translateArraySubscriptExpr(cast(S), Ctx);

282 case Stmt::ConditionalOperatorClass:

283 return translateAbstractConditionalOperator(

284 cast(S), Ctx);

285 case Stmt::BinaryConditionalOperatorClass:

286 return translateAbstractConditionalOperator(

287 cast(S), Ctx);

288

289

290 case Stmt::ConstantExprClass:

291 return translate(cast(S)->getSubExpr(), Ctx);

292 case Stmt::ParenExprClass:

293 return translate(cast(S)->getSubExpr(), Ctx);

294 case Stmt::ExprWithCleanupsClass:

295 return translate(cast(S)->getSubExpr(), Ctx);

296 case Stmt::CXXBindTemporaryExprClass:

297 return translate(cast(S)->getSubExpr(), Ctx);

298 case Stmt::MaterializeTemporaryExprClass:

299 return translate(cast(S)->getSubExpr(), Ctx);

300

301

302 case Stmt::CharacterLiteralClass:

303 case Stmt::CXXNullPtrLiteralExprClass:

304 case Stmt::GNUNullExprClass:

305 case Stmt::CXXBoolLiteralExprClass:

306 case Stmt::FloatingLiteralClass:

307 case Stmt::ImaginaryLiteralClass:

308 case Stmt::IntegerLiteralClass:

309 case Stmt::StringLiteralClass:

310 case Stmt::ObjCStringLiteralClass:

311 return new (Arena) til::Literal(cast(S));

312

313 case Stmt::DeclStmtClass:

314 return translateDeclStmt(cast(S), Ctx);

315 default:

316 break;

317 }

318 if (const auto *CE = dyn_cast(S))

319 return translateCastExpr(CE, Ctx);

320

322}

323

327

328

329 if (const auto *PV = dyn_cast(VD)) {

330 unsigned I = PV->getFunctionScopeIndex();

332 if (Ctx && Ctx->FunArgs) {

334 if (isa(D)

337

338 if (const Expr *const *FunArgs =

339 dyn_cast<const Expr *const *>(Ctx->FunArgs)) {

340 assert(I < Ctx->NumArgs);

342 }

343

344 assert(I == 0);

345 return cast<til::SExpr *>(Ctx->FunArgs);

346 }

347 }

348

349

350 VD = isa(D)

351 ? cast(D)->getCanonicalDecl()->getParamDecl(I)

352 : cast(D)->getCanonicalDecl()->getParamDecl(I);

353 }

354

355

357}

358

361

362 if (Ctx && Ctx->SelfArg) {

363 if (const auto *SelfArg = dyn_cast<const Expr *>(Ctx->SelfArg))

365 else

366 return cast<til::SExpr *>(Ctx->SelfArg);

367 }

368 assert(SelfVar && "We have no variable for 'this'!");

369 return SelfVar;

370}

371

373 if (const auto *V = dyn_casttil::Variable(E))

374 return V->clangDecl();

375 if (const auto *Ph = dyn_casttil::Phi(E))

376 return Ph->clangDecl();

377 if (const auto *P = dyn_casttil::Project(E))

378 return P->clangDecl();

379 if (const auto *L = dyn_casttil::LiteralPtr(E))

380 return L->clangDecl();

381 return nullptr;

382}

383

386 if (VD && VD->getType()->isAnyPointerType())

387 return true;

388 if (const auto *C = dyn_casttil::Cast(E))

390

391 return false;

392}

393

394

396 while (true) {

398 auto OverriddenMethods = D->overridden_methods();

399 if (OverriddenMethods.begin() == OverriddenMethods.end())

400 return D;

401

402 D = *OverriddenMethods.begin();

403 }

404 return nullptr;

405}

406

411

413 if (const auto *VD = dyn_cast(D))

415

418 P->setArrow(true);

419 return P;

420}

421

426

428

431 P->setArrow(true);

432 return P;

433}

434

437 const Expr *SelfE) {

438 if (CapabilityExprMode) {

439

441 FD = FD->getMostRecentDecl();

442 if (LockReturnedAttr *At = FD->getAttr()) {

445 LRCallCtx.SelfArg = SelfE;

446 LRCallCtx.NumArgs = CE->getNumArgs();

447 LRCallCtx.FunArgs = CE->getArgs();

450 }

451 }

452 }

453

455 for (const auto *Arg : CE->arguments()) {

458 }

460}

461

462til::SExpr *SExprBuilder::translateCXXMemberCallExpr(

464 if (CapabilityExprMode) {

465

470

471 }

472 }

473 return translateCallExpr(cast(ME), Ctx,

475}

476

477til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(

479 if (CapabilityExprMode) {

480

482 if (k == OO_Star || k == OO_Arrow) {

485

486 }

487 }

488 return translateCallExpr(cast(OCE), Ctx);

489}

490

494 case UO_PostInc:

495 case UO_PostDec:

496 case UO_PreInc:

497 case UO_PreDec:

499

500 case UO_AddrOf:

501 if (CapabilityExprMode) {

502

503 if (const auto *DRE = dyn_cast(UO->getSubExpr())) {

505

506

509 }

510 }

511 }

512

514

515

516 case UO_Deref:

517 case UO_Plus:

519

520 case UO_Minus:

521 return new (Arena)

523 case UO_Not:

524 return new (Arena)

526 case UO_LNot:

527 return new (Arena)

529

530

531 case UO_Real:

532 case UO_Imag:

533 case UO_Extension:

534 case UO_Coawait:

536 }

538}

539

545 if (Reverse)

547 else

549}

550

554 bool Assign) {

559

562 if (const auto *DRE = dyn_cast(LHS)) {

564 CV = lookupVarDecl(VD);

565 }

566

567 if (!Assign) {

570 E1 = addStatement(E1, nullptr, VD);

571 }

572 if (VD && CV)

573 return updateVarDecl(VD, E1);

574 return new (Arena) til::Store(E0, E1);

575}

576

580 case BO_PtrMemD:

581 case BO_PtrMemI:

583

584 case BO_Mul: return translateBinOp(til::BOP_Mul, BO, Ctx);

585 case BO_Div: return translateBinOp(til::BOP_Div, BO, Ctx);

586 case BO_Rem: return translateBinOp(til::BOP_Rem, BO, Ctx);

587 case BO_Add: return translateBinOp(til::BOP_Add, BO, Ctx);

588 case BO_Sub: return translateBinOp(til::BOP_Sub, BO, Ctx);

589 case BO_Shl: return translateBinOp(til::BOP_Shl, BO, Ctx);

590 case BO_Shr: return translateBinOp(til::BOP_Shr, BO, Ctx);

591 case BO_LT: return translateBinOp(til::BOP_Lt, BO, Ctx);

592 case BO_GT: return translateBinOp(til::BOP_Lt, BO, Ctx, true);

593 case BO_LE: return translateBinOp(til::BOP_Leq, BO, Ctx);

594 case BO_GE: return translateBinOp(til::BOP_Leq, BO, Ctx, true);

595 case BO_EQ: return translateBinOp(til::BOP_Eq, BO, Ctx);

596 case BO_NE: return translateBinOp(til::BOP_Neq, BO, Ctx);

597 case BO_Cmp: return translateBinOp(til::BOP_Cmp, BO, Ctx);

598 case BO_And: return translateBinOp(til::BOP_BitAnd, BO, Ctx);

599 case BO_Xor: return translateBinOp(til::BOP_BitXor, BO, Ctx);

600 case BO_Or: return translateBinOp(til::BOP_BitOr, BO, Ctx);

602 case BO_LOr: return translateBinOp(til::BOP_LogicOr, BO, Ctx);

603

604 case BO_Assign: return translateBinAssign(til::BOP_Eq, BO, Ctx, true);

605 case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx);

606 case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx);

607 case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx);

608 case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx);

609 case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx);

610 case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx);

611 case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx);

612 case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx);

613 case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx);

614 case BO_OrAssign: return translateBinAssign(til::BOP_BitOr, BO, Ctx);

615

616 case BO_Comma:

617

619 }

621}

622

626 switch (K) {

627 case CK_LValueToRValue: {

628 if (const auto *DRE = dyn_cast(CE->getSubExpr())) {

630 if (E0)

631 return E0;

632 }

634 return E0;

635

636

637 }

638 case CK_NoOp:

639 case CK_DerivedToBase:

640 case CK_UncheckedDerivedToBase:

641 case CK_ArrayToPointerDecay:

642 case CK_FunctionToPointerDecay: {

644 return E0;

645 }

646 default: {

647

649 if (CapabilityExprMode)

650 return E0;

652 }

653 }

654}

655

662}

663

665SExprBuilder::translateAbstractConditionalOperator(

671}

672

676 for (auto *I : DGrp) {

677 if (auto *VD = dyn_cast_or_null(I)) {

678 Expr *E = VD->getInit();

680

681

684 return addVarDecl(VD, SE);

685 else {

686

687 }

688 }

689 }

690 return nullptr;

691}

692

693

694

695

696

700 return E;

701 if (VD)

703 CurrentInstructions.push_back(E);

704 if (S)

705 insertStmt(S, E);

706 return E;

707}

708

709

711 auto It = LVarIdxMap.find(VD);

712 if (It != LVarIdxMap.end()) {

713 assert(CurrentLVarMap[It->second].first == VD);

714 return CurrentLVarMap[It->second].second;

715 }

716 return nullptr;

717}

718

719

721 if (E)

722 return;

723 if (auto *V = dyn_casttil::Variable(E)) {

724 if (V->clangDecl())

725 V->setClangDecl(VD);

726 }

727}

728

729

732 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));

734 CurrentLVarMap.push_back(std::make_pair(VD, E));

735 return E;

736}

737

738

741 auto It = LVarIdxMap.find(VD);

742 if (It == LVarIdxMap.end()) {

745 return St;

746 }

748 CurrentLVarMap.elem(It->second).second = E;

749 return E;

750}

751

752

753

754

755void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {

756 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;

757 assert(ArgIndex > 0 && ArgIndex < NPreds);

758

759 til::SExpr *CurrE = CurrentLVarMap[i].second;

760 if (CurrE->block() == CurrentBB) {

761

762

763 auto *Ph = dyn_casttil::Phi(CurrE);

764 assert(Ph && "Expecting Phi node.");

765 if (E)

766 Ph->values()[ArgIndex] = E;

767 return;

768 }

769

770

771

774 for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)

775 Ph->values()[PIdx] = CurrE;

776 if (E)

777 Ph->values()[ArgIndex] = E;

779

780

783

784

785 CurrentArguments.push_back(Ph);

787 IncompleteArgs.push_back(Ph);

788

790 CurrentLVarMap.elem(i).second = Ph;

791}

792

793

794

795void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {

796 assert(CurrentBlockInfo && "Not processing a block!");

797

798 if (!CurrentLVarMap.valid()) {

799

800 CurrentLVarMap = std::move(Map);

801 return;

802 }

803 if (CurrentLVarMap.sameAs(Map))

804 return;

805

807 unsigned ESz = CurrentLVarMap.size();

808 unsigned MSz = Map.size();

809 unsigned Sz = std::min(ESz, MSz);

810

811 for (unsigned i = 0; i < Sz; ++i) {

812 if (CurrentLVarMap[i].first != Map[i].first) {

813

816 break;

817 }

818 if (CurrentLVarMap[i].second != Map[i].second)

819 makePhiNodeVar(i, NPreds, Map[i].second);

820 }

821 if (ESz > MSz) {

823 CurrentLVarMap.downsize(Map.size());

824 }

825}

826

827

828

829void SExprBuilder::mergeEntryMapBackEdge() {

830

831

832

833

834

835

836

837

838 assert(CurrentBlockInfo && "Not processing a block!");

839

840 if (CurrentBlockInfo->HasBackEdges)

841 return;

842 CurrentBlockInfo->HasBackEdges = true;

843

845 unsigned Sz = CurrentLVarMap.size();

847

848 for (unsigned i = 0; i < Sz; ++i)

849 makePhiNodeVar(i, NPreds, nullptr);

850}

851

852

853

854

855void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {

857 unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors;

858 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());

859

861 auto *Ph = dyn_cast_or_nulltil::Phi(PE);

862 assert(Ph && "Expecting Phi Node.");

863 assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge.");

864

866 assert(E && "Couldn't find local variable for Phi node.");

867 Ph->values()[ArgIndex] = E;

868 }

869}

870

871void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,

873

875 Scfg = new (Arena) til::SCFG(Arena, NBlocks);

876

877

878 BBInfo.resize(NBlocks);

879 BlockMap.resize(NBlocks, nullptr);

880

881 for (auto *B : *Cfg) {

884 BlockMap[B->getBlockID()] = BB;

885 }

886

887 CurrentBB = lookupBlock(&Cfg->getEntry());

888 auto Parms = isa(D) ? cast(D)->parameters()

889 : cast(D)->parameters();

890 for (auto *Pm : Parms) {

892 if (T.isTrivialType(Pm->getASTContext()))

893 continue;

894

895

896

899 til::SExpr *V = addStatement(Ld, nullptr, Pm);

900 addVarDecl(Pm, V);

901 }

902}

903

904void SExprBuilder::enterCFGBlock(const CFGBlock *B) {

905

908 Scfg->add(CurrentBB);

909

910 CurrentBlockInfo = &BBInfo[B->getBlockID()];

911

912

913

914

915}

916

917void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {

918

919

921 BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];

922 assert(PredInfo->UnprocessedSuccessors > 0);

923

924 if (--PredInfo->UnprocessedSuccessors == 0)

925 mergeEntryMap(std::move(PredInfo->ExitMap));

926 else

927 mergeEntryMap(PredInfo->ExitMap.clone());

928

929 ++CurrentBlockInfo->ProcessedPredecessors;

930}

931

932void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {

933 mergeEntryMapBackEdge();

934}

935

936void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {

937

938

940 static_cast<unsigned>(CurrentArguments.size()), Arena);

941 for (auto *A : CurrentArguments)

943}

944

945void SExprBuilder::handleStatement(const Stmt *S) {

947 addStatement(E, S);

948}

949

950void SExprBuilder::handleDestructorCall(const VarDecl *VD,

956 addStatement(E, nullptr);

957}

958

959void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {

961 static_cast<unsigned>(CurrentInstructions.size()), Arena);

962 for (auto *V : CurrentInstructions)

964

965

968 if (N == 1) {

970

972 auto *Tm = new (Arena) til::Goto(BB, Idx);

974 }

975 else if (N == 2) {

978 ++It;

980

981 auto *Tm = new (Arena) til::Branch(C, BB1, BB2);

983 }

984}

985

986void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {

987 ++CurrentBlockInfo->UnprocessedSuccessors;

988}

989

990void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {

991 mergePhiNodesBackEdge(Succ);

992 ++BBInfo[Succ->getBlockID()].ProcessedPredecessors;

993}

994

995void SExprBuilder::exitCFGBlock(const CFGBlock *B) {

996 CurrentArguments.clear();

997 CurrentInstructions.clear();

998 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);

999 CurrentBB = nullptr;

1000 CurrentBlockInfo = nullptr;

1001}

1002

1003void SExprBuilder::exitCFG(const CFGBlock *Last) {

1004 for (auto *Ph : IncompleteArgs) {

1007 }

1008

1009 CurrentArguments.clear();

1010 CurrentInstructions.clear();

1011 IncompleteArgs.clear();

1012}

1013

1014#ifndef NDEBUG

1015namespace {

1016

1017class TILPrinter :

1019

1020}

1021

1022namespace clang {

1023namespace threadSafety {

1024

1026 llvm::BumpPtrAllocator Bpa;

1030 TILPrinter::print(Scfg, llvm::errs());

1031}

1032

1033}

1034}

1035#endif

llvm::DenseMap< const Stmt *, CFGBlock * > SMap

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

static const Decl * getCanonicalDecl(const Decl *D)

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 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 StringRef ClassifyDiagnostic(const CapabilityAttr *A)

static bool isCalleeArrow(const Expr *E)

C Language Family Type Representation.

AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...

Expr * getCond() const

getCond - Return the expression representing the condition for the ?: operator.

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...

ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.

A builtin binary operation expression such as "x + y" or "x <= y".

Represents a single basic block in a source-level CFG.

succ_iterator succ_begin()

unsigned pred_size() const

unsigned getBlockID() const

Stmt * getTerminatorCondition(bool StripParens=true)

unsigned succ_size() const

Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.

unsigned getNumBlockIDs() const

Returns the total number of BlockIDs allocated (which start at 0).

Represents a C++ destructor within a class.

Represents a call to a member function that may be written either with member call syntax (e....

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.

A call to an overloaded operator written using operator syntax.

OverloadedOperatorKind getOperator() const

Returns the kind of overloaded operator that this expression refers to.

Represents the this expression in C++.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

FunctionDecl * getDirectCallee()

If the callee is a FunctionDecl, return it. Otherwise return null.

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this call.

Expr ** getArgs()

Retrieve the call arguments.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

CastKind getCastKind() const

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

A reference to a declared variable, function, enum, etc.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

Decl - This represents one declaration (or definition), e.g.

ASTContext & getASTContext() const LLVM_READONLY

DeclContext * getDeclContext()

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.

Represents a function declaration or definition.

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.

std::string getNameAsString() const

Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...

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.

ObjCIvarRefExpr - A reference to an ObjC instance variable.

const Expr * getBase() const

A (possibly-)qualified type.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

Stmt - This represents one statement.

StmtClass getStmtClass() 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'.

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

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.

const til::SExpr * sexpr() const

void push_back(const T &Elem)

bool sameAs(const CopyOnWriteVector &V) const

void downsize(unsigned i)

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)

std::pair< til::LiteralPtr *, StringRef > createThisPlaceholder(const Expr *Exp)

til::SExpr * lookupStmt(const Stmt *S)

til::SCFG * buildCFG(CFGWalker &Walker)

til::LiteralPtr * createVariable(const VarDecl *VD)

til::BasicBlock * lookupBlock(const CFGBlock *B)

Apply an argument to a function.

If p is a reference to an array, then p[i] is a reference to the i'th element of the array.

A basic block is part of an SCFG.

unsigned addPredecessor(BasicBlock *Pred)

const InstrArray & arguments() const

void reserveInstructions(unsigned Nins)

void addArgument(Phi *V)

Add a new argument.

size_t numPredecessors() const

Returns the number of predecessors.

InstrArray & instructions()

void reservePredecessors(unsigned NumPreds)

unsigned findPredecessorIndex(const BasicBlock *BB) const

Return the index of BB, or Predecessors.size if BB is not a predecessor.

void setTerminator(Terminator *E)

void addInstruction(SExpr *V)

Add a new instruction.

Simple arithmetic binary operations, e.g.

A conditional branch to two other blocks.

Call a function (after all arguments have been applied).

Jump to another basic block.

An if-then-else expression.

A Literal pointer to an object allocated in memory.

Load a value from memory.

Phi Node, for code in SSA form.

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

Project a named slot from a C++ struct or class.

Apply a self-argument to a self-applicable function.

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)

void reserve(size_t Ncp, MemRegionRef A)

Simple arithmetic unary operations, e.g.

Placeholder for expressions that cannot be represented in the TIL.

Placeholder for a wildcard that matches any other expression.

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)

The JSON file list parser is used to communicate input to InstallAPI.

OverloadedOperatorKind

Enumeration specifying the different kinds of C++ overloaded operators.

@ Self

'self' clause, allowed on Compute and Combined Constructs, plus 'update'.

CastKind

CastKind - The kind of operation required for a conversion.

const FunctionProtoType * T

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