clang: lib/AST/Stmt.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

35#include "llvm/ADT/SmallVector.h"

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

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

38#include "llvm/Support/Compiler.h"

39#include "llvm/Support/ErrorHandling.h"

40#include "llvm/Support/MathExtras.h"

41#include "llvm/Support/raw_ostream.h"

42#include

43#include

44#include

45#include

46#include

47#include

48

49using namespace clang;

50

51#define STMT(CLASS, PARENT)

52#define STMT_RANGE(BASE, FIRST, LAST)

53#define LAST_STMT_RANGE(BASE, FIRST, LAST) \

54 static_assert(llvm::isUInt(Stmt::StmtClass::LAST##Class), \

55 "The number of 'StmtClass'es is strictly bound " \

56 "by a bitfield of width NumStmtBits");

57#define ABSTRACT_STMT(STMT)

58#include "clang/AST/StmtNodes.inc"

59

65

70

71

73#define ABSTRACT_STMT(STMT)

74#define STMT(CLASS, PARENT) \

75 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \

76 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);

77#include "clang/AST/StmtNodes.inc"

78

80}

81

83 unsigned alignment) {

84 return ::operator new(bytes, C, alignment);

85}

86

90

91

92

93

94#define STMT(CLASS, PARENT) \

95 static_assert(!std::is_polymorphic::value, \

96 #CLASS " should not be polymorphic!");

97#include "clang/AST/StmtNodes.inc"

98

99

100

101

102#define STMT(CLASS, PARENT) \

103 static_assert(std::is_trivially_destructible::value, \

104 #CLASS " should be trivially destructible!");

105

106#define INITLISTEXPR(CLASS, PARENT)

107#include "clang/AST/StmtNodes.inc"

108

110

112

113 unsigned sum = 0;

114 llvm::errs() << "\n*** Stmt/Expr Stats:\n";

115 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {

118 }

119 llvm::errs() << " " << sum << " stmts/exprs total.\n";

120 sum = 0;

121 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {

124 llvm::errs() << " " << StmtClassInfo[i].Counter << " "

127 << " bytes)\n";

129 }

130

131 llvm::errs() << "Total bytes = " << sum << "\n";

132}

133

137

138bool Stmt::StatisticsEnabled = false;

140 StatisticsEnabled = true;

141}

142

143static std::pair<Stmt::Likelihood, const Attr *>

145 for (const auto *A : Attrs) {

148

151 }

152

154}

155

156static std::pair<Stmt::Likelihood, const Attr *> getLikelihood(const Stmt *S) {

157 if (const auto *AS = dyn_cast_or_null(S))

159

161}

162

164 return ::getLikelihood(Attrs).first;

165}

166

168 return ::getLikelihood(S).first;

169}

170

172 return ::getLikelihood(S).second;

173}

174

179 return LHT;

180

181

182 if (LHT == LHE)

184

186 return LHT;

187

188

190}

191

192std::tuple<bool, const Attr *, const Attr *>

194 std::pair<Likelihood, const Attr *> LHT = ::getLikelihood(Then);

195 std::pair<Likelihood, const Attr *> LHE = ::getLikelihood(Else);

196

197 if (LHT.first != LH_None && LHT.first == LHE.first)

198 return std::make_tuple(true, LHT.second, LHE.second);

199

200 return std::make_tuple(false, nullptr, nullptr);

201}

202

203

204

206 Stmt *S = this;

207 if (IgnoreCaptured)

208 if (auto CapS = dyn_cast_or_null(S))

209 S = CapS->getCapturedStmt();

210 while (true) {

211 if (auto AS = dyn_cast_or_null(S))

212 S = AS->getSubStmt();

213 else if (auto CS = dyn_cast_or_null(S)) {

214 if (CS->size() != 1)

215 break;

216 S = CS->body_back();

217 } else

218 break;

219 }

220 return S;

221}

222

223

224

225

226

228 const Stmt *S = this;

229 while (true) {

230 if (const auto *LS = dyn_cast(S))

231 S = LS->getSubStmt();

232 else if (const auto *SC = dyn_cast(S))

233 S = SC->getSubStmt();

234 else if (const auto *AS = dyn_cast(S))

235 S = AS->getSubStmt();

236 else

237 return S;

238 }

239}

240

241namespace {

242

243 struct good {};

244 struct bad {};

245

246

247

248

249 static good is_good(good) { return good(); }

250

252 template good implements_children(children_t T::*) {

253 return good();

254 }

255 [[maybe_unused]]

256 static bad implements_children(children_t Stmt::*) {

257 return bad();

258 }

259

261 template good implements_getBeginLoc(getBeginLoc_t T::*) {

262 return good();

263 }

264 [[maybe_unused]]

265 static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) {

266 return bad();

267 }

268

270 template good implements_getEndLoc(getLocEnd_t T::*) {

271 return good();

272 }

273 [[maybe_unused]]

274 static bad implements_getEndLoc(getLocEnd_t Stmt::*) {

275 return bad();

276 }

277

278#define ASSERT_IMPLEMENTS_children(type) \

279 (void) is_good(implements_children(&type::children))

280#define ASSERT_IMPLEMENTS_getBeginLoc(type) \

281 (void)is_good(implements_getBeginLoc(&type::getBeginLoc))

282#define ASSERT_IMPLEMENTS_getEndLoc(type) \

283 (void)is_good(implements_getEndLoc(&type::getEndLoc))

284

285}

286

287

288

289[[maybe_unused]]

291#define ABSTRACT_STMT(type)

292#define STMT(type, base) \

293 ASSERT_IMPLEMENTS_children(type); \

294 ASSERT_IMPLEMENTS_getBeginLoc(type); \

295 ASSERT_IMPLEMENTS_getEndLoc(type);

296#include "clang/AST/StmtNodes.inc"

297}

298

301 case Stmt::NoStmtClass: llvm_unreachable("statement without class");

302#define ABSTRACT_STMT(type)

303#define STMT(type, base) \

304 case Stmt::type##Class: \

305 return static_cast<type*>(this)->children();

306#include "clang/AST/StmtNodes.inc"

307 }

308 llvm_unreachable("unknown statement kind!");

309}

310

311

312

313

314

315namespace {

316

317

318

319 template <class S, class T>

322 return static_cast<const S*>(stmt)->getSourceRange();

323 }

324

325

326

327

328

329 template

332 return SourceRange(static_cast<const S *>(stmt)->getBeginLoc(),

333 static_cast<const S *>(stmt)->getEndLoc());

334 }

335

336}

337

340 case Stmt::NoStmtClass: llvm_unreachable("statement without class");

341#define ABSTRACT_STMT(type)

342#define STMT(type, base) \

343 case Stmt::type##Class: \

344 return getSourceRangeImpl(this, &type::getSourceRange);

345#include "clang/AST/StmtNodes.inc"

346 }

347 llvm_unreachable("unknown statement kind!");

348}

349

352 case Stmt::NoStmtClass: llvm_unreachable("statement without class");

353#define ABSTRACT_STMT(type)

354#define STMT(type, base) \

355 case Stmt::type##Class: \

356 return static_cast<const type *>(this)->getBeginLoc();

357#include "clang/AST/StmtNodes.inc"

358 }

359 llvm_unreachable("unknown statement kind");

360}

361

364 case Stmt::NoStmtClass: llvm_unreachable("statement without class");

365#define ABSTRACT_STMT(type)

366#define STMT(type, base) \

367 case Stmt::type##Class: \

368 return static_cast<const type *>(this)->getEndLoc();

369#include "clang/AST/StmtNodes.inc"

370 }

371 llvm_unreachable("unknown statement kind");

372}

373

375 return Context.getAllocator().identifyKnownAlignedObject<Stmt>(this);

376}

377

380 : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {

383 setStmts(Stmts);

384 if (hasStoredFPFeatures())

385 setStoredFPFeatures(FPFeatures);

386}

387

390 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");

392}

393

397 void *Mem =

398 C.Allocate(totalSizeToAlloc<Stmt *, FPOptionsOverride>(

400 alignof(CompoundStmt));

401 return new (Mem) CompoundStmt(Stmts, FPFeatures, LB, RB);

402}

403

405 bool HasFPFeatures) {

406 void *Mem = C.Allocate(

407 totalSizeToAlloc<Stmt *, FPOptionsOverride>(NumStmts, HasFPFeatures),

408 alignof(CompoundStmt));

410 New->CompoundStmtBits.NumStmts = NumStmts;

411 New->CompoundStmtBits.HasFPFeatures = HasFPFeatures;

412 return New;

413}

414

416 const Stmt *S = this;

417 do {

418 if (const auto *E = dyn_cast(S))

419 return E;

420

421 if (const auto *LS = dyn_cast(S))

422 S = LS->getSubStmt();

423 else if (const auto *AS = dyn_cast(S))

424 S = AS->getSubStmt();

425 else

426 llvm_unreachable("unknown kind of ValueStmt");

428

429 return nullptr;

430}

431

435

438 Stmt *SubStmt) {

439 assert(!Attrs.empty() && "Attrs should not be empty");

440 void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),

441 alignof(AttributedStmt));

442 return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);

443}

444

446 unsigned NumAttrs) {

447 assert(NumAttrs > 0 && "NumAttrs should be greater than zero");

448 void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),

449 alignof(AttributedStmt));

450 return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);

451}

452

454 if (const auto *gccAsmStmt = dyn_cast(this))

455 return gccAsmStmt->generateAsmString(C);

456 if (const auto *msAsmStmt = dyn_cast(this))

457 return msAsmStmt->generateAsmString(C);

458 llvm_unreachable("unknown asm statement kind!");

459}

460

462 if (const auto *gccAsmStmt = dyn_cast(this))

463 return gccAsmStmt->getOutputConstraint(i);

464 if (const auto *msAsmStmt = dyn_cast(this))

465 return msAsmStmt->getOutputConstraint(i).str();

466 llvm_unreachable("unknown asm statement kind!");

467}

468

470 if (const auto *gccAsmStmt = dyn_cast(this))

471 return gccAsmStmt->getOutputExpr(i);

472 if (const auto *msAsmStmt = dyn_cast(this))

473 return msAsmStmt->getOutputExpr(i);

474 llvm_unreachable("unknown asm statement kind!");

475}

476

478 if (const auto *gccAsmStmt = dyn_cast(this))

479 return gccAsmStmt->getInputConstraint(i);

480 if (const auto *msAsmStmt = dyn_cast(this))

481 return msAsmStmt->getInputConstraint(i).str();

482 llvm_unreachable("unknown asm statement kind!");

483}

484

486 if (const auto *gccAsmStmt = dyn_cast(this))

487 return gccAsmStmt->getInputExpr(i);

488 if (const auto *msAsmStmt = dyn_cast(this))

489 return msAsmStmt->getInputExpr(i);

490 llvm_unreachable("unknown asm statement kind!");

491}

492

494 if (const auto *gccAsmStmt = dyn_cast(this))

495 return gccAsmStmt->getClobber(i);

496 if (const auto *msAsmStmt = dyn_cast(this))

497 return msAsmStmt->getClobber(i).str();

498 llvm_unreachable("unknown asm statement kind!");

499}

500

501

502

504 unsigned Res = 0;

505 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)

507 ++Res;

508 return Res;

509}

510

512 assert(isOperand() && "Only Operands can have modifiers.");

513 return isLetter(Str[0]) ? Str[0] : '\0';

514}

515

517 if (auto *SL = llvm::dyn_cast(E))

518 return SL->getString().str();

519 assert(E->getDependence() == ExprDependence::None &&

520 "cannot extract a string from a dependent expression");

522 APValue Res = CE->getAPValueResult();

523 assert(Res.isArray() && "expected an array");

524

525 std::string Out;

527 for (unsigned I = 0; I < Res.getArraySize(); ++I) {

529 assert(C.isInt());

530 auto Ch = static_cast<char>(C.getInt().getExtValue());

531 Out.push_back(Ch);

532 }

533 return Out;

534}

535

539

543

547

548

549

550

554

558

562

566

570

571

572

576

577void GCCAsmStmt::setOutputsAndInputsAndClobbers(

584 this->NumLabels = NumLabels;

585

587

588 C.Deallocate(this->Names);

590 std::copy(Names, Names + NumExprs, this->Names);

591

592 C.Deallocate(this->Exprs);

593 this->Exprs = new (C) Stmt*[NumExprs];

594 std::copy(Exprs, Exprs + NumExprs, this->Exprs);

595

597 C.Deallocate(this->Constraints);

599 std::copy(Constraints, Constraints + NumConstraints, this->Constraints);

600

601 C.Deallocate(this->Clobbers);

603 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);

604}

605

606

607

608

610

612 for (unsigned i = 0; i != NumOutputs; ++i)

614 return i;

615

617 for (unsigned i = 0; i != NumInputs; ++i)

620

621 for (unsigned i = 0, e = getNumLabels(); i != e; ++i)

624

625

626 return -1;

627}

628

629

630

631

633 const ASTContext &C, unsigned &DiagOffs) const {

634

636 const char *StrStart = Str.data();

637 const char *StrEnd = Str.data() + Str.size();

638 const char *CurPtr = StrStart;

639

640

641

644 for (; CurPtr != StrEnd; ++CurPtr) {

645 switch (*CurPtr) {

646 case '$':

648 break;

649 default:

651 break;

652 }

653 }

655 return 0;

656 }

657

658

659

660 std::string CurStringPiece;

661

662 bool HasVariants = C.getTargetInfo().hasNoAsmVariants();

663

664 unsigned LastAsmStringToken = 0;

665 unsigned LastAsmStringOffset = 0;

666

667 while (true) {

668

669 if (CurPtr == StrEnd) {

670 if (!CurStringPiece.empty())

672 return 0;

673 }

674

675 char CurChar = *CurPtr++;

676 switch (CurChar) {

677 case '$': CurStringPiece += "$$"; continue;

678 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;

679 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;

680 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;

681 case '%':

682 break;

683 default:

684 CurStringPiece += CurChar;

685 continue;

686 }

687

688 const TargetInfo &TI = C.getTargetInfo();

689

690

691 if (CurPtr == StrEnd) {

692

693 DiagOffs = CurPtr-StrStart-1;

694 return diag::err_asm_invalid_escape;

695 }

696

697 char EscapedChar = *CurPtr++;

698 switch (EscapedChar) {

699 default:

700

702 CurStringPiece += *MaybeReplaceStr;

703 continue;

704 }

705 break;

706 case '%':

707 case '{':

708 case '}':

709 CurStringPiece += EscapedChar;

710 continue;

711 case '=':

712 CurStringPiece += "${:uid}";

713 continue;

714 }

715

716

717

718 if (!CurStringPiece.empty()) {

720 CurStringPiece.clear();

721 }

722

723

724

725

726 const char *Begin = CurPtr - 1;

727 const char *Percent = Begin - 1;

728

730 if (CurPtr == StrEnd) {

731 DiagOffs = CurPtr-StrStart-1;

732 return diag::err_asm_invalid_escape;

733 }

734

735

736

737

738 if (EscapedChar == 'c' && *CurPtr == 'c')

739 CurPtr++;

740

741 EscapedChar = *CurPtr++;

742 }

743

746

747

748 if (isDigit(EscapedChar)) {

749

750 unsigned N = 0;

751

752 --CurPtr;

753 while (CurPtr != StrEnd && isDigit(*CurPtr))

754 N = N*10 + ((*CurPtr++)-'0');

755

758 if (N >= NumOperands) {

759 DiagOffs = CurPtr-StrStart-1;

760 return diag::err_asm_invalid_operand_number;

761 }

762

763

764 std::string Str(Begin, CurPtr - Begin);

765

766

768 if (auto *SL = dyn_cast(getAsmStringExpr())) {

769 BeginLoc =

770 SL->getLocationOfByte(Percent - StrStart, SM, LO, TI,

771 &LastAsmStringToken, &LastAsmStringOffset);

772 EndLoc =

773 SL->getLocationOfByte(CurPtr - StrStart, SM, LO, TI,

774 &LastAsmStringToken, &LastAsmStringOffset);

775 } else {

778 }

779

780 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);

781 continue;

782 }

783

784

785 if (EscapedChar == '[') {

786 DiagOffs = CurPtr-StrStart-1;

787

788

789 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);

790 if (NameEnd == nullptr)

791 return diag::err_asm_unterminated_symbolic_operand_name;

792 if (NameEnd == CurPtr)

793 return diag::err_asm_empty_symbolic_operand_name;

794

795 StringRef SymbolicName(CurPtr, NameEnd - CurPtr);

796

798 if (N == -1) {

799

800 DiagOffs = CurPtr-StrStart;

801 return diag::err_asm_unknown_symbolic_operand_name;

802 }

803

804

805 std::string Str(Begin, NameEnd + 1 - Begin);

806

807

808

810 if (auto *SL = dyn_cast(getAsmStringExpr())) {

811 BeginLoc =

812 SL->getLocationOfByte(Percent - StrStart, SM, LO, TI,

813 &LastAsmStringToken, &LastAsmStringOffset);

814 EndLoc =

815 SL->getLocationOfByte(NameEnd + 1 - StrStart, SM, LO, TI,

816 &LastAsmStringToken, &LastAsmStringOffset);

817 } else {

820 }

821

822 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);

823

824 CurPtr = NameEnd+1;

825 continue;

826 }

827

828 DiagOffs = CurPtr-StrStart-1;

829 return diag::err_asm_invalid_escape;

830 }

831}

832

833

835

836

838 unsigned DiagOffs;

840

841 std::string AsmString;

842 for (const auto &Piece : Pieces) {

843 if (Piece.isString())

844 AsmString += Piece.getString();

845 else if (Piece.getModifier() == '\0')

846 AsmString += '$' + llvm::utostr(Piece.getOperandNo());

847 else

848 AsmString += "${" + llvm::utostr(Piece.getOperandNo()) + ':' +

849 Piece.getModifier() + '}';

850 }

851 return AsmString;

852}

853

854

856

858 AsmStr.split(Pieces, "\n\t");

859 std::string MSAsmString;

860 for (size_t I = 0, E = Pieces.size(); I < E; ++I) {

861 StringRef Instruction = Pieces[I];

862

863

864 if (Instruction.starts_with("vex "))

865 MSAsmString += '{' + Instruction.substr(0, 3).str() + '}' +

866 Instruction.substr(3).str();

867 else if (Instruction.starts_with("vex2 ") ||

868 Instruction.starts_with("vex3 ") ||

869 Instruction.starts_with("evex "))

870 MSAsmString += '{' + Instruction.substr(0, 4).str() + '}' +

871 Instruction.substr(4).str();

872 else

873 MSAsmString += Instruction.str();

874

875 if (I < E - 1)

876 MSAsmString += "\n\t";

877 }

878 return MSAsmString;

879}

880

884

888

892

893

894

895

896

898 bool issimple, bool isvolatile, unsigned numoutputs,

900 Expr **constraints, Expr **exprs, Expr *asmstr,

901 unsigned numclobbers, Expr **clobbers,

903 : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,

904 numinputs, numclobbers),

905 RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {

907

909 std::copy(names, names + NumExprs, Names);

910

912 std::copy(exprs, exprs + NumExprs, Exprs);

913

916 std::copy(constraints, constraints + NumConstraints, Constraints);

917

919 std::copy(clobbers, clobbers + NumClobbers, Clobbers);

920}

921

923 SourceLocation lbraceloc, bool issimple, bool isvolatile,

925 unsigned numinputs,

929 : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,

930 numinputs, clobbers.size()), LBraceLoc(lbraceloc),

931 EndLoc(endloc), NumAsmToks(asmtoks.size()) {

932 initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);

933}

934

936 return str.copy(C);

937}

938

939void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,

944 assert(NumAsmToks == asmtoks.size());

946

948 assert(exprs.size() == constraints.size());

949

951

953 llvm::copy(exprs, Exprs);

954

955 AsmToks = new (C) Token[asmtoks.size()];

956 llvm::copy(asmtoks, AsmToks);

957

958 Constraints = new (C) StringRef[exprs.size()];

959 std::transform(constraints.begin(), constraints.end(), Constraints,

960 [&](StringRef Constraint) {

961 return copyIntoContext(C, Constraint);

962 });

963

965

966 std::transform(clobbers.begin(), clobbers.end(), Clobbers,

967 [&](StringRef Clobber) {

968 return copyIntoContext(C, Clobber);

969 });

970}

971

975 : Stmt(IfStmtClass), LParenLoc(LPL), RParenLoc(RPL) {

976 bool HasElse = Else != nullptr;

977 bool HasVar = Var != nullptr;

978 bool HasInit = Init != nullptr;

979 IfStmtBits.HasElse = HasElse;

980 IfStmtBits.HasVar = HasVar;

981 IfStmtBits.HasInit = HasInit;

982

983 setStatementKind(Kind);

984

985 setCond(Cond);

986 setThen(Then);

987 if (HasElse)

988 setElse(Else);

989 if (HasVar)

990 setConditionVariable(Ctx, Var);

991 if (HasInit)

992 setInit(Init);

993

994 setIfLoc(IL);

995 if (HasElse)

996 setElseLoc(EL);

997}

998

999IfStmt::IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit)

1001 IfStmtBits.HasElse = HasElse;

1002 IfStmtBits.HasVar = HasVar;

1003 IfStmtBits.HasInit = HasInit;

1004}

1005

1010 bool HasElse = Else != nullptr;

1011 bool HasVar = Var != nullptr;

1012 bool HasInit = Init != nullptr;

1014 totalSizeToAlloc<Stmt *, SourceLocation>(

1015 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),

1016 alignof(IfStmt));

1017 return new (Mem)

1018 IfStmt(Ctx, IL, Kind, Init, Var, Cond, LPL, RPL, Then, EL, Else);

1019}

1020

1022 bool HasInit) {

1024 totalSizeToAlloc<Stmt *, SourceLocation>(

1025 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),

1026 alignof(IfStmt));

1027 return new (Mem) IfStmt(EmptyShell(), HasElse, HasVar, HasInit);

1028}

1029

1032 if (!DS)

1033 return nullptr;

1035}

1036

1039 "This if statement has no storage for a condition variable!");

1040

1041 if (V) {

1042 getTrailingObjects<Stmt *>()[varOffset()] = nullptr;

1043 return;

1044 }

1045

1047 getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)

1049}

1050

1054

1057 return std::nullopt;

1059}

1060

1061std::optional<const Stmt *>

1063 if (std::optional<Stmt *> Result =

1066 return std::nullopt;

1067}

1068

1072 : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)

1073{

1074 SubExprs[INIT] = Init;

1076 SubExprs[COND] = Cond;

1077 SubExprs[INC] = Inc;

1078 SubExprs[BODY] = Body;

1080}

1081

1083 if (!SubExprs[CONDVAR])

1084 return nullptr;

1085

1088}

1089

1091 if (V) {

1092 SubExprs[CONDVAR] = nullptr;

1093 return;

1094 }

1095

1099}

1100

1104 : Stmt(SwitchStmtClass), FirstCase(nullptr), LParenLoc(LParenLoc),

1105 RParenLoc(RParenLoc) {

1106 bool HasInit = Init != nullptr;

1107 bool HasVar = Var != nullptr;

1111

1114 if (HasInit)

1116 if (HasVar)

1118

1120}

1121

1122SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)

1123 : Stmt(SwitchStmtClass, Empty) {

1127}

1128

1132 bool HasInit = Init != nullptr;

1133 bool HasVar = Var != nullptr;

1135 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),

1136 alignof(SwitchStmt));

1137 return new (Mem) SwitchStmt(Ctx, Init, Var, Cond, LParenLoc, RParenLoc);

1138}

1139

1141 bool HasVar) {

1143 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),

1144 alignof(SwitchStmt));

1145 return new (Mem) SwitchStmt(EmptyShell(), HasInit, HasVar);

1146}

1147

1150 if (!DS)

1151 return nullptr;

1153}

1154

1157 "This switch statement has no storage for a condition variable!");

1158

1159 if (V) {

1160 getTrailingObjects()[varOffset()] = nullptr;

1161 return;

1162 }

1163

1165 getTrailingObjects()[varOffset()] = new (Ctx)

1167}

1168

1172 : Stmt(WhileStmtClass) {

1173 bool HasVar = Var != nullptr;

1175

1178 if (HasVar)

1180

1181 setWhileLoc(WL);

1184}

1185

1186WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)

1189}

1190

1195 bool HasVar = Var != nullptr;

1196 void *Mem =

1197 Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),

1198 alignof(WhileStmt));

1199 return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL, LParenLoc, RParenLoc);

1200}

1201

1203 void *Mem =

1204 Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),

1205 alignof(WhileStmt));

1206 return new (Mem) WhileStmt(EmptyShell(), HasVar);

1207}

1208

1211 if (!DS)

1212 return nullptr;

1214}

1215

1218 "This while statement has no storage for a condition variable!");

1219

1220 if (V) {

1221 getTrailingObjects()[varOffset()] = nullptr;

1222 return;

1223 }

1224

1226 getTrailingObjects()[varOffset()] = new (Ctx)

1228}

1229

1230

1232 if (auto *E = dyn_cast(getTarget()->IgnoreParenImpCasts()))

1233 return E->getLabel();

1234 return nullptr;

1235}

1236

1237

1239 : Stmt(ReturnStmtClass), RetExpr(E) {

1240 bool HasNRVOCandidate = NRVOCandidate != nullptr;

1242 if (HasNRVOCandidate)

1243 setNRVOCandidate(NRVOCandidate);

1244 setReturnLoc(RL);

1245}

1246

1247ReturnStmt::ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate)

1248 : Stmt(ReturnStmtClass, Empty) {

1250}

1251

1253 Expr *E, const VarDecl *NRVOCandidate) {

1254 bool HasNRVOCandidate = NRVOCandidate != nullptr;

1255 void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),

1256 alignof(ReturnStmt));

1257 return new (Mem) ReturnStmt(RL, E, NRVOCandidate);

1258}

1259

1261 bool HasNRVOCandidate) {

1262 void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),

1263 alignof(ReturnStmt));

1264 return new (Mem) ReturnStmt(EmptyShell(), HasNRVOCandidate);

1265}

1266

1267

1271 bool CaseStmtIsGNURange = rhs != nullptr;

1273 totalSizeToAlloc<Stmt *, SourceLocation>(

1274 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),

1275 alignof(CaseStmt));

1276 return new (Mem) CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);

1277}

1278

1280 bool CaseStmtIsGNURange) {

1282 totalSizeToAlloc<Stmt *, SourceLocation>(

1283 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),

1284 alignof(CaseStmt));

1285 return new (Mem) CaseStmt(EmptyShell(), CaseStmtIsGNURange);

1286}

1287

1288SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,

1289 Stmt *Handler)

1290 : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {

1292 Children[HANDLER] = Handler;

1293}

1294

1297 Stmt *Handler) {

1298 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);

1299}

1300

1302 return dyn_cast(getHandler());

1303}

1304

1306 return dyn_cast(getHandler());

1307}

1308

1310 : Stmt(SEHExceptStmtClass), Loc(Loc) {

1311 Children[FILTER_EXPR] = FilterExpr;

1313}

1314

1317 return new(C) SEHExceptStmt(Loc,FilterExpr,Block);

1318}

1319

1321 : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}

1322

1324 Stmt *Block) {

1325 return new(C)SEHFinallyStmt(Loc,Block);

1326}

1327

1330 : VarAndKind(Var, Kind), Loc(Loc) {

1331 switch (Kind) {

1333 assert(!Var && "'this' capture cannot have a variable!");

1334 break;

1336 assert(Var && "capturing by reference must have a variable!");

1337 break;

1339 assert(Var && "capturing by copy must have a variable!");

1340 break;

1342 assert(!Var &&

1343 "Variable-length array type capture cannot have a variable!");

1344 break;

1345 }

1346}

1347

1350 return VarAndKind.getInt();

1351}

1352

1355 "No variable available for 'this' or VAT capture");

1356 return VarAndKind.getPointer();

1357}

1358

1360 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);

1361

1362

1363 unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));

1364

1365 return reinterpret_cast<Capture *>(

1366 reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))

1367 + FirstCaptureOffset);

1368}

1369

1375 : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),

1376 CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {

1377 assert( S && "null captured statement");

1378 assert(CD && "null captured declaration for captured statement");

1379 assert(RD && "null record declaration for captured statement");

1380

1381

1382 Stmt **Stored = getStoredStmts();

1383 for (unsigned I = 0, N = NumCaptures; I != N; ++I)

1384 *Stored++ = CaptureInits[I];

1385

1386

1387 *Stored = S;

1388

1389

1390 Capture *Buffer = getStoredCaptures();

1391 llvm::copy(Captures, Buffer);

1392}

1393

1394CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)

1395 : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),

1397 getStoredStmts()[NumCaptures] = nullptr;

1398

1399

1400 Capture *Buffer = getStoredCaptures();

1401 for (unsigned I = 0, N = NumCaptures; I != N; ++I)

1402 new (Buffer++) Capture();

1403}

1404

1411

1412

1413

1414

1415

1416

1417

1418

1419

1420 assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");

1421

1422 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);

1423 if (!Captures.empty()) {

1424

1425 Size = llvm::alignTo(Size, alignof(Capture));

1426 Size += sizeof(Capture) * Captures.size();

1427 }

1428

1429 void *Mem = Context.Allocate(Size);

1430 return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);

1431}

1432

1434 unsigned NumCaptures) {

1435 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);

1436 if (NumCaptures > 0) {

1437

1438 Size = llvm::alignTo(Size, alignof(Capture));

1439 Size += sizeof(Capture) * NumCaptures;

1440 }

1441

1442 void *Mem = Context.Allocate(Size);

1443 return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);

1444}

1445

1447

1448 return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);

1449}

1450

1452 return const_child_range(getStoredStmts(), getStoredStmts() + NumCaptures);

1453}

1454

1456 return CapDeclAndKind.getPointer();

1457}

1458

1460 return CapDeclAndKind.getPointer();

1461}

1462

1463

1465 assert(D && "null CapturedDecl");

1466 CapDeclAndKind.setPointer(D);

1467}

1468

1469

1471 return CapDeclAndKind.getInt();

1472}

1473

1474

1476 CapDeclAndKind.setInt(Kind);

1477}

1478

1480 for (const auto &I : captures()) {

1481 if (!I.capturesVariable() && !I.capturesVariableByCopy())

1482 continue;

1483 if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())

1484 return true;

1485 }

1486

1487 return false;

1488}

1489

1492 while (isa_and_present(S))

1494 return S;

1495}

1496

1499 return nullptr;

1500 return getLabelDecl()->getStmt()->getInnermostLabeledStmt();

1501}

1502

1503DeferStmt::DeferStmt(EmptyShell Empty) : Stmt(DeferStmtClass, Empty) {}

1505 : Stmt(DeferStmtClass) {

1506 setDeferLoc(DeferLoc);

1507 setBody(Body);

1508}

1509

1511 return new (Context) DeferStmt(Empty);

1512}

1513

1515 Stmt *Body) {

1516 return new (Context) DeferStmt(DeferLoc, Body);

1517}

Defines the clang::ASTContext interface.

static StringRef bytes(const std::vector< T, Allocator > &v)

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

Defines Expressions and AST nodes for C++2a concepts.

SmallVector< AnnotatedLine *, 1 > Children

If this token starts a block, this contains all the unwrapped lines in it.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::SourceLocation class and associated facilities.

Defines the Objective-C statement AST node classes.

This file defines OpenACC AST classes for statement-level contructs.

This file defines OpenMP AST classes for executable directives and clauses.

This file defines SYCL AST classes used to represent calls to SYCL kernels.

static StmtClassNameTable & getStmtInfoTableEntry(Stmt::StmtClass E)

Definition Stmt.cpp:66

static void check_implementations()

Check whether the various Stmt classes implement their member functions.

Definition Stmt.cpp:290

static StringRef copyIntoContext(const ASTContext &C, StringRef str)

Definition Stmt.cpp:935

static std::pair< Stmt::Likelihood, const Attr * > getLikelihood(ArrayRef< const Attr * > Attrs)

Definition Stmt.cpp:144

static struct StmtClassNameTable StmtClassInfo[Stmt::lastStmtConstant+1]

#define BLOCK(DERIVED, BASE)

C Language Family Type Representation.

__device__ __2f16 float __ockl_bool s

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

APValue & getArrayInitializedElt(unsigned I)

unsigned getArraySize() const

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

void * Allocate(size_t Size, unsigned Align=8) const

AddrLabelExpr - The GNU address of label extension, representing &&label.

LabelDecl * getLabel() const

std::string getInputConstraint(unsigned i) const

getInputConstraint - Return the specified input constraint.

Definition Stmt.cpp:477

unsigned getNumPlusOperands() const

getNumPlusOperands - Return the number of output operands that have a "+" constraint.

Definition Stmt.cpp:503

std::string getOutputConstraint(unsigned i) const

getOutputConstraint - Return the constraint string for the specified output operand.

Definition Stmt.cpp:461

AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, unsigned numclobbers)

const Expr * getInputExpr(unsigned i) const

Definition Stmt.cpp:485

bool isOutputPlusConstraint(unsigned i) const

isOutputPlusConstraint - Return true if the specified output constraint is a "+" constraint (which is...

const Expr * getOutputExpr(unsigned i) const

Definition Stmt.cpp:469

unsigned getNumOutputs() const

std::string generateAsmString(const ASTContext &C) const

Assemble final IR asm string.

Definition Stmt.cpp:453

unsigned getNumInputs() const

std::string getClobber(unsigned i) const

Definition Stmt.cpp:493

Attr - This represents one attribute.

static AttributedStmt * CreateEmpty(const ASTContext &C, unsigned NumAttrs)

Definition Stmt.cpp:445

static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)

Definition Stmt.cpp:436

Represents the body of a CapturedStmt, and serves as its DeclContext.

Describes the capture of either a variable, or 'this', or variable-length array type.

bool capturesVariableByCopy() const

Determine whether this capture handles a variable by copy.

VariableCaptureKind getCaptureKind() const

Determine the kind of capture.

Definition Stmt.cpp:1349

VarDecl * getCapturedVar() const

Retrieve the declaration of the variable being captured.

Definition Stmt.cpp:1353

static CapturedStmt * CreateDeserialized(const ASTContext &Context, unsigned NumCaptures)

Definition Stmt.cpp:1433

void setCapturedRegionKind(CapturedRegionKind Kind)

Set the captured region kind.

Definition Stmt.cpp:1475

CapturedDecl * getCapturedDecl()

Retrieve the outlined function declaration.

Definition Stmt.cpp:1455

child_range children()

Definition Stmt.cpp:1446

bool capturesVariable(const VarDecl *Var) const

True if this variable has been captured.

Definition Stmt.cpp:1479

void setCapturedDecl(CapturedDecl *D)

Set the outlined function declaration.

Definition Stmt.cpp:1464

static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr * > CaptureInits, CapturedDecl *CD, RecordDecl *RD)

Definition Stmt.cpp:1405

CapturedRegionKind getCapturedRegionKind() const

Retrieve the captured region kind.

Definition Stmt.cpp:1470

VariableCaptureKind

The different capture forms: by 'this', by reference, capture for variable-length array type etc.

static CaseStmt * Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc)

Build a case statement.

Definition Stmt.cpp:1268

static CaseStmt * CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange)

Build an empty case statement.

Definition Stmt.cpp:1279

static CompoundStmt * CreateEmpty(const ASTContext &C, unsigned NumStmts, bool HasFPFeatures)

Definition Stmt.cpp:404

body_iterator body_begin()

static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)

Definition Stmt.cpp:394

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

static DeferStmt * Create(ASTContext &Context, SourceLocation DeferLoc, Stmt *Body)

Definition Stmt.cpp:1514

static DeferStmt * CreateEmpty(ASTContext &Context, EmptyShell Empty)

Definition Stmt.cpp:1510

This represents one expression.

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

ExprDependence getDependence() const

Represents difference between two FPOptions values.

bool requiresTrailingStorage() const

ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP)

Definition Stmt.cpp:1069

VarDecl * getConditionVariable() const

Retrieve the variable declared in this "for" statement, if any.

Definition Stmt.cpp:1082

void setConditionVariable(const ASTContext &C, VarDecl *V)

Definition Stmt.cpp:1090

AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...

char getModifier() const

getModifier - Get the modifier for this operand, if present.

Definition Stmt.cpp:511

std::string getOutputConstraint(unsigned i) const

getOutputConstraint - Return the constraint string for the specified output operand.

Definition Stmt.cpp:551

unsigned getNumLabels() const

std::string generateAsmString(const ASTContext &C) const

Assemble final IR asm string.

Definition Stmt.cpp:834

std::string getAsmString() const

Definition Stmt.cpp:536

std::string getInputConstraint(unsigned i) const

getInputConstraint - Return the specified input constraint.

Definition Stmt.cpp:573

const Expr * getOutputConstraintExpr(unsigned i) const

StringRef getLabelName(unsigned i) const

Definition Stmt.cpp:567

unsigned AnalyzeAsmString(SmallVectorImpl< AsmStringPiece > &Pieces, const ASTContext &C, unsigned &DiagOffs) const

AnalyzeAsmString - Analyze the asm string of the current asm, decomposing it into pieces.

Definition Stmt.cpp:632

void setInputExpr(unsigned i, Expr *E)

Definition Stmt.cpp:559

std::string getClobber(unsigned i) const

Definition Stmt.cpp:540

StringRef getInputName(unsigned i) const

StringRef getOutputName(unsigned i) const

const Expr * getInputConstraintExpr(unsigned i) const

const Expr * getAsmStringExpr() const

Expr * getOutputExpr(unsigned i)

Definition Stmt.cpp:544

GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, Expr **constraints, Expr **exprs, Expr *asmstr, unsigned numclobbers, Expr **clobbers, unsigned numlabels, SourceLocation rparenloc)

Definition Stmt.cpp:897

Expr * getClobberExpr(unsigned i)

int getNamedOperand(StringRef SymbolicName) const

getNamedOperand - Given a symbolic operand reference like %[foo], translate this into a numeric value...

Definition Stmt.cpp:609

Expr * getInputExpr(unsigned i)

Definition Stmt.cpp:555

AddrLabelExpr * getLabelExpr(unsigned i) const

Definition Stmt.cpp:563

static std::string ExtractStringFromGCCAsmStmtComponent(const Expr *E)

Definition Stmt.cpp:516

One of these records is kept for each identifier that is lexed.

const char * getNameStart() const

Return the beginning of the actual null-terminated string for this identifier.

static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL, SourceLocation RPL, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)

Create an IfStmt.

Definition Stmt.cpp:1006

void setConditionVariable(const ASTContext &Ctx, VarDecl *V)

Set the condition variable for this if statement.

Definition Stmt.cpp:1037

bool hasVarStorage() const

True if this IfStmt has storage for a variable declaration.

static IfStmt * CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar, bool HasInit)

Create an empty IfStmt optionally with storage for an else statement, condition variable and init exp...

Definition Stmt.cpp:1021

std::optional< const Stmt * > getNondiscardedCase(const ASTContext &Ctx) const

If this is an 'if constexpr', determine which substatement will be taken.

Definition Stmt.cpp:1062

bool isObjCAvailabilityCheck() const

Definition Stmt.cpp:1051

DeclStmt * getConditionVariableDeclStmt()

If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...

VarDecl * getConditionVariable()

Retrieve the variable declared in this "if" statement, if any.

Definition Stmt.cpp:1030

LabelDecl * getConstantTarget()

getConstantTarget - Returns the fixed target of this indirect goto, if one exists.

Definition Stmt.cpp:1231

Represents the declaration of a label.

LabelDecl * getDecl() const

const Stmt * getInnermostLabeledStmt() const

Look through nested labels and return the first non-label statement; e.g.

Definition Stmt.cpp:1490

const char * getName() const

Definition Stmt.cpp:432

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

LabelDecl * getLabelDecl()

const Stmt * getNamedLoopOrSwitch() const

If this is a named break/continue, get the loop or switch statement that this targets.

Definition Stmt.cpp:1497

bool hasLabelTarget() const

Expr * getOutputExpr(unsigned i)

Definition Stmt.cpp:881

void setInputExpr(unsigned i, Expr *E)

Definition Stmt.cpp:889

MSAsmStmt(const ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef< Token > asmtoks, unsigned numoutputs, unsigned numinputs, ArrayRef< StringRef > constraints, ArrayRef< Expr * > exprs, StringRef asmstr, ArrayRef< StringRef > clobbers, SourceLocation endloc)

Definition Stmt.cpp:922

std::string generateAsmString(const ASTContext &C) const

Assemble final IR asm string.

Definition Stmt.cpp:855

Expr * getInputExpr(unsigned i)

Definition Stmt.cpp:885

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

Represents a struct/union/class.

static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)

Create a return statement.

Definition Stmt.cpp:1252

static ReturnStmt * CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate)

Create an empty return statement, optionally with storage for an NRVO candidate.

Definition Stmt.cpp:1260

static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)

Definition Stmt.cpp:1315

static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)

Definition Stmt.cpp:1323

SEHFinallyStmt * getFinallyHandler() const

Definition Stmt.cpp:1305

static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)

Definition Stmt.cpp:1295

SEHExceptStmt * getExceptHandler() const

Returns 0 if not defined.

Definition Stmt.cpp:1301

Stmt * getHandler() const

Encodes a location in the source.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

Definition Stmt.cpp:362

WhileStmtBitfields WhileStmtBits

static void EnableStatistics()

Definition Stmt.cpp:139

SwitchStmtBitfields SwitchStmtBits

const Stmt * stripLabelLikeStatements() const

Strip off all label-like statements.

Definition Stmt.cpp:227

child_range children()

Definition Stmt.cpp:299

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

Definition Stmt.cpp:338

static std::tuple< bool, const Attr *, const Attr * > determineLikelihoodConflict(const Stmt *Then, const Stmt *Else)

Definition Stmt.cpp:193

static void PrintStats()

Definition Stmt.cpp:109

Stmt(StmtClass SC, EmptyShell)

Construct an empty statement.

llvm::iterator_range< child_iterator > child_range

CompoundStmtBitfields CompoundStmtBits

Likelihood

The likelihood of a branch being taken.

@ LH_Unlikely

Branch has the [[unlikely]] attribute.

@ LH_None

No attribute set or branches of the IfStmt have the same attribute.

@ LH_Likely

Branch has the [[likely]] attribute.

static void addStmtClass(const StmtClass s)

Definition Stmt.cpp:134

ForStmtBitfields ForStmtBits

const char * getStmtClassName() const

Definition Stmt.cpp:87

static const Attr * getLikelihoodAttr(const Stmt *S)

Definition Stmt.cpp:171

Stmt * IgnoreContainers(bool IgnoreCaptured=false)

Skip no-op (attributed, compound) container stmts and skip captured stmt at the top,...

Definition Stmt.cpp:205

int64_t getID(const ASTContext &Context) const

Definition Stmt.cpp:374

ReturnStmtBitfields ReturnStmtBits

SourceLocation getBeginLoc() const LLVM_READONLY

Definition Stmt.cpp:350

llvm::iterator_range< const_child_iterator > const_child_range

static Likelihood getLikelihood(ArrayRef< const Attr * > Attrs)

Definition Stmt.cpp:163

void setRParenLoc(SourceLocation Loc)

void setConditionVariable(const ASTContext &Ctx, VarDecl *VD)

Set the condition variable in this switch statement.

Definition Stmt.cpp:1155

static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, SourceLocation RParenLoc)

Create a switch statement.

Definition Stmt.cpp:1129

void setLParenLoc(SourceLocation Loc)

static SwitchStmt * CreateEmpty(const ASTContext &Ctx, bool HasInit, bool HasVar)

Create an empty switch statement optionally with storage for an init expression and a condition varia...

Definition Stmt.cpp:1140

bool hasVarStorage() const

True if this SwitchStmt has storage for a condition variable.

VarDecl * getConditionVariable()

Retrieve the variable declared in this "switch" statement, if any.

Definition Stmt.cpp:1148

DeclStmt * getConditionVariableDeclStmt()

If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...

Exposes information about the current target.

virtual std::optional< std::string > handleAsmEscapedChar(char C) const

Replace some escaped characters with another string based on target-specific rules.

const Expr * getExprStmt() const

Definition Stmt.cpp:415

Stmt(StmtClass SC, EmptyShell)

Construct an empty statement.

Represents a variable declaration or definition.

VarDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

DeclStmt * getConditionVariableDeclStmt()

If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...

VarDecl * getConditionVariable()

Retrieve the variable declared in this "while" statement, if any.

Definition Stmt.cpp:1209

void setConditionVariable(const ASTContext &Ctx, VarDecl *V)

Set the condition variable of this while statement.

Definition Stmt.cpp:1216

bool hasVarStorage() const

True if this WhileStmt has storage for a condition variable.

static WhileStmt * Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, SourceLocation WL, SourceLocation LParenLoc, SourceLocation RParenLoc)

Create a while statement.

Definition Stmt.cpp:1191

static WhileStmt * CreateEmpty(const ASTContext &Ctx, bool HasVar)

Create an empty while statement optionally with storage for a condition variable.

Definition Stmt.cpp:1202

Defines the clang::TargetInfo interface.

const internal::VariadicAllOfMatcher< Stmt > stmt

Matches statements.

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

bool isa(CodeGen::Address addr)

IfStatementKind

In an if statement, this denotes whether the statement is a constexpr or consteval if statement.

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

CapturedRegionKind

The different kinds of captured statement.

LLVM_READONLY bool isLetter(unsigned char c)

Return true if this character is an ASCII letter: [a-zA-Z].

@ Result

The result type of a method or function.

const FunctionProtoType * T

LLVM_READONLY bool isDigit(unsigned char c)

Return true if this character is an ASCII digit: [0-9].

U cast(CodeGen::Address addr)

A placeholder type used to construct an empty shell of a type, that will be filled in later (e....