File indexing completed on 2026-05-10 08:36:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_AST_STMTCXX_H
0014 #define LLVM_CLANG_AST_STMTCXX_H
0015
0016 #include "clang/AST/DeclarationName.h"
0017 #include "clang/AST/Expr.h"
0018 #include "clang/AST/NestedNameSpecifier.h"
0019 #include "clang/AST/Stmt.h"
0020 #include "llvm/Support/Compiler.h"
0021
0022 namespace clang {
0023
0024 class VarDecl;
0025
0026
0027
0028 class CXXCatchStmt : public Stmt {
0029 SourceLocation CatchLoc;
0030
0031 VarDecl *ExceptionDecl;
0032
0033 Stmt *HandlerBlock;
0034
0035 public:
0036 CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
0037 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
0038 HandlerBlock(handlerBlock) {}
0039
0040 CXXCatchStmt(EmptyShell Empty)
0041 : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
0042
0043 SourceLocation getBeginLoc() const LLVM_READONLY { return CatchLoc; }
0044 SourceLocation getEndLoc() const LLVM_READONLY {
0045 return HandlerBlock->getEndLoc();
0046 }
0047
0048 SourceLocation getCatchLoc() const { return CatchLoc; }
0049 VarDecl *getExceptionDecl() const { return ExceptionDecl; }
0050 QualType getCaughtType() const;
0051 Stmt *getHandlerBlock() const { return HandlerBlock; }
0052
0053 static bool classof(const Stmt *T) {
0054 return T->getStmtClass() == CXXCatchStmtClass;
0055 }
0056
0057 child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
0058
0059 const_child_range children() const {
0060 return const_child_range(&HandlerBlock, &HandlerBlock + 1);
0061 }
0062
0063 friend class ASTStmtReader;
0064 };
0065
0066
0067
0068 class CXXTryStmt final : public Stmt,
0069 private llvm::TrailingObjects<CXXTryStmt, Stmt *> {
0070
0071 friend TrailingObjects;
0072 friend class ASTStmtReader;
0073
0074 SourceLocation TryLoc;
0075 unsigned NumHandlers;
0076 size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumHandlers; }
0077
0078 CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock,
0079 ArrayRef<Stmt *> handlers);
0080 CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
0081 : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
0082
0083 Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); }
0084 Stmt **getStmts() { return getTrailingObjects<Stmt *>(); }
0085
0086 public:
0087 static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
0088 CompoundStmt *tryBlock, ArrayRef<Stmt *> handlers);
0089
0090 static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
0091 unsigned numHandlers);
0092
0093 SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
0094
0095 SourceLocation getTryLoc() const { return TryLoc; }
0096 SourceLocation getEndLoc() const {
0097 return getStmts()[NumHandlers]->getEndLoc();
0098 }
0099
0100 CompoundStmt *getTryBlock() {
0101 return cast<CompoundStmt>(getStmts()[0]);
0102 }
0103 const CompoundStmt *getTryBlock() const {
0104 return cast<CompoundStmt>(getStmts()[0]);
0105 }
0106
0107 unsigned getNumHandlers() const { return NumHandlers; }
0108 CXXCatchStmt *getHandler(unsigned i) {
0109 return cast<CXXCatchStmt>(getStmts()[i + 1]);
0110 }
0111 const CXXCatchStmt *getHandler(unsigned i) const {
0112 return cast<CXXCatchStmt>(getStmts()[i + 1]);
0113 }
0114
0115 static bool classof(const Stmt *T) {
0116 return T->getStmtClass() == CXXTryStmtClass;
0117 }
0118
0119 child_range children() {
0120 return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
0121 }
0122
0123 const_child_range children() const {
0124 return const_child_range(getStmts(), getStmts() + getNumHandlers() + 1);
0125 }
0126 };
0127
0128
0129
0130
0131
0132
0133
0134
0135 class CXXForRangeStmt : public Stmt {
0136 SourceLocation ForLoc;
0137 enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
0138
0139
0140 Stmt *SubExprs[END];
0141 SourceLocation CoawaitLoc;
0142 SourceLocation ColonLoc;
0143 SourceLocation RParenLoc;
0144
0145 friend class ASTStmtReader;
0146 public:
0147 CXXForRangeStmt(Stmt *InitStmt, DeclStmt *Range, DeclStmt *Begin,
0148 DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
0149 Stmt *Body, SourceLocation FL, SourceLocation CAL,
0150 SourceLocation CL, SourceLocation RPL);
0151 CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
0152
0153 Stmt *getInit() { return SubExprs[INIT]; }
0154 VarDecl *getLoopVariable();
0155 Expr *getRangeInit();
0156
0157 const Stmt *getInit() const { return SubExprs[INIT]; }
0158 const VarDecl *getLoopVariable() const;
0159 const Expr *getRangeInit() const;
0160
0161
0162 DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
0163 DeclStmt *getBeginStmt() {
0164 return cast_or_null<DeclStmt>(SubExprs[BEGINSTMT]);
0165 }
0166 DeclStmt *getEndStmt() { return cast_or_null<DeclStmt>(SubExprs[ENDSTMT]); }
0167 Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
0168 Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
0169 DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
0170 Stmt *getBody() { return SubExprs[BODY]; }
0171
0172 const DeclStmt *getRangeStmt() const {
0173 return cast<DeclStmt>(SubExprs[RANGE]);
0174 }
0175 const DeclStmt *getBeginStmt() const {
0176 return cast_or_null<DeclStmt>(SubExprs[BEGINSTMT]);
0177 }
0178 const DeclStmt *getEndStmt() const {
0179 return cast_or_null<DeclStmt>(SubExprs[ENDSTMT]);
0180 }
0181 const Expr *getCond() const {
0182 return cast_or_null<Expr>(SubExprs[COND]);
0183 }
0184 const Expr *getInc() const {
0185 return cast_or_null<Expr>(SubExprs[INC]);
0186 }
0187 const DeclStmt *getLoopVarStmt() const {
0188 return cast<DeclStmt>(SubExprs[LOOPVAR]);
0189 }
0190 const Stmt *getBody() const { return SubExprs[BODY]; }
0191
0192 void setInit(Stmt *S) { SubExprs[INIT] = S; }
0193 void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
0194 void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
0195 void setBeginStmt(Stmt *S) { SubExprs[BEGINSTMT] = S; }
0196 void setEndStmt(Stmt *S) { SubExprs[ENDSTMT] = S; }
0197 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
0198 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
0199 void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
0200 void setBody(Stmt *S) { SubExprs[BODY] = S; }
0201
0202 SourceLocation getForLoc() const { return ForLoc; }
0203 SourceLocation getCoawaitLoc() const { return CoawaitLoc; }
0204 SourceLocation getColonLoc() const { return ColonLoc; }
0205 SourceLocation getRParenLoc() const { return RParenLoc; }
0206
0207 SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
0208 SourceLocation getEndLoc() const LLVM_READONLY {
0209 return SubExprs[BODY]->getEndLoc();
0210 }
0211
0212 static bool classof(const Stmt *T) {
0213 return T->getStmtClass() == CXXForRangeStmtClass;
0214 }
0215
0216
0217 child_range children() {
0218 return child_range(&SubExprs[0], &SubExprs[END]);
0219 }
0220
0221 const_child_range children() const {
0222 return const_child_range(&SubExprs[0], &SubExprs[END]);
0223 }
0224 };
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 class MSDependentExistsStmt : public Stmt {
0254 SourceLocation KeywordLoc;
0255 bool IsIfExists;
0256 NestedNameSpecifierLoc QualifierLoc;
0257 DeclarationNameInfo NameInfo;
0258 Stmt *SubStmt;
0259
0260 friend class ASTReader;
0261 friend class ASTStmtReader;
0262
0263 public:
0264 MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
0265 NestedNameSpecifierLoc QualifierLoc,
0266 DeclarationNameInfo NameInfo,
0267 CompoundStmt *SubStmt)
0268 : Stmt(MSDependentExistsStmtClass),
0269 KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
0270 QualifierLoc(QualifierLoc), NameInfo(NameInfo),
0271 SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
0272
0273
0274
0275 SourceLocation getKeywordLoc() const { return KeywordLoc; }
0276
0277
0278 bool isIfExists() const { return IsIfExists; }
0279
0280
0281 bool isIfNotExists() const { return !IsIfExists; }
0282
0283
0284
0285 NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
0286
0287
0288
0289 DeclarationNameInfo getNameInfo() const { return NameInfo; }
0290
0291
0292
0293 CompoundStmt *getSubStmt() const {
0294 return reinterpret_cast<CompoundStmt *>(SubStmt);
0295 }
0296
0297 SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
0298 SourceLocation getEndLoc() const LLVM_READONLY {
0299 return SubStmt->getEndLoc();
0300 }
0301
0302 child_range children() {
0303 return child_range(&SubStmt, &SubStmt+1);
0304 }
0305
0306 const_child_range children() const {
0307 return const_child_range(&SubStmt, &SubStmt + 1);
0308 }
0309
0310 static bool classof(const Stmt *T) {
0311 return T->getStmtClass() == MSDependentExistsStmtClass;
0312 }
0313 };
0314
0315
0316
0317
0318 class CoroutineBodyStmt final
0319 : public Stmt,
0320 private llvm::TrailingObjects<CoroutineBodyStmt, Stmt *> {
0321 enum SubStmt {
0322 Body,
0323 Promise,
0324 InitSuspend,
0325 FinalSuspend,
0326 OnException,
0327 OnFallthrough,
0328 Allocate,
0329 Deallocate,
0330 ResultDecl,
0331 ReturnValue,
0332 ReturnStmt,
0333 ReturnStmtOnAllocFailure,
0334 FirstParamMove
0335 };
0336 unsigned NumParams;
0337
0338 friend class ASTStmtReader;
0339 friend class ASTReader;
0340 friend TrailingObjects;
0341
0342 Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
0343
0344 Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
0345
0346 public:
0347
0348 struct CtorArgs {
0349 Stmt *Body = nullptr;
0350 Stmt *Promise = nullptr;
0351 Expr *InitialSuspend = nullptr;
0352 Expr *FinalSuspend = nullptr;
0353 Stmt *OnException = nullptr;
0354 Stmt *OnFallthrough = nullptr;
0355 Expr *Allocate = nullptr;
0356 Expr *Deallocate = nullptr;
0357 Stmt *ResultDecl = nullptr;
0358 Expr *ReturnValue = nullptr;
0359 Stmt *ReturnStmt = nullptr;
0360 Stmt *ReturnStmtOnAllocFailure = nullptr;
0361 ArrayRef<Stmt *> ParamMoves;
0362 };
0363
0364 private:
0365
0366 CoroutineBodyStmt(CtorArgs const& Args);
0367
0368 public:
0369 static CoroutineBodyStmt *Create(const ASTContext &C, CtorArgs const &Args);
0370 static CoroutineBodyStmt *Create(const ASTContext &C, EmptyShell,
0371 unsigned NumParams);
0372
0373 bool hasDependentPromiseType() const {
0374 return getPromiseDecl()->getType()->isDependentType();
0375 }
0376
0377
0378
0379
0380 CompoundStmt *getBody() const {
0381 return cast<CompoundStmt>(getStoredStmts()[SubStmt::Body]);
0382 }
0383
0384 Stmt *getPromiseDeclStmt() const {
0385 return getStoredStmts()[SubStmt::Promise];
0386 }
0387 VarDecl *getPromiseDecl() const {
0388 return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
0389 }
0390
0391 Stmt *getInitSuspendStmt() const {
0392 return getStoredStmts()[SubStmt::InitSuspend];
0393 }
0394 Stmt *getFinalSuspendStmt() const {
0395 return getStoredStmts()[SubStmt::FinalSuspend];
0396 }
0397
0398 Stmt *getExceptionHandler() const {
0399 return getStoredStmts()[SubStmt::OnException];
0400 }
0401 Stmt *getFallthroughHandler() const {
0402 return getStoredStmts()[SubStmt::OnFallthrough];
0403 }
0404
0405 Expr *getAllocate() const {
0406 return cast_or_null<Expr>(getStoredStmts()[SubStmt::Allocate]);
0407 }
0408 Expr *getDeallocate() const {
0409 return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
0410 }
0411 Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
0412 Expr *getReturnValueInit() const {
0413 return cast<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
0414 }
0415 Expr *getReturnValue() const {
0416 auto *RS = dyn_cast_or_null<clang::ReturnStmt>(getReturnStmt());
0417 return RS ? RS->getRetValue() : nullptr;
0418 }
0419 Stmt *getReturnStmt() const { return getStoredStmts()[SubStmt::ReturnStmt]; }
0420 Stmt *getReturnStmtOnAllocFailure() const {
0421 return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
0422 }
0423 ArrayRef<Stmt const *> getParamMoves() const {
0424 return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
0425 }
0426
0427 SourceLocation getBeginLoc() const LLVM_READONLY {
0428 return getBody() ? getBody()->getBeginLoc()
0429 : getPromiseDecl()->getBeginLoc();
0430 }
0431 SourceLocation getEndLoc() const LLVM_READONLY {
0432 return getBody() ? getBody()->getEndLoc() : getPromiseDecl()->getEndLoc();
0433 }
0434
0435 child_range children() {
0436 return child_range(getStoredStmts(),
0437 getStoredStmts() + SubStmt::FirstParamMove + NumParams);
0438 }
0439
0440 const_child_range children() const {
0441 return const_child_range(getStoredStmts(), getStoredStmts() +
0442 SubStmt::FirstParamMove +
0443 NumParams);
0444 }
0445
0446 child_range childrenExclBody() {
0447 return child_range(getStoredStmts() + SubStmt::Body + 1,
0448 getStoredStmts() + SubStmt::FirstParamMove + NumParams);
0449 }
0450
0451 const_child_range childrenExclBody() const {
0452 return const_child_range(getStoredStmts() + SubStmt::Body + 1,
0453 getStoredStmts() + SubStmt::FirstParamMove +
0454 NumParams);
0455 }
0456
0457 static bool classof(const Stmt *T) {
0458 return T->getStmtClass() == CoroutineBodyStmtClass;
0459 }
0460 };
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473 class CoreturnStmt : public Stmt {
0474 SourceLocation CoreturnLoc;
0475
0476 enum SubStmt { Operand, PromiseCall, Count };
0477 Stmt *SubStmts[SubStmt::Count];
0478
0479 bool IsImplicit : 1;
0480
0481 friend class ASTStmtReader;
0482 public:
0483 CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall,
0484 bool IsImplicit = false)
0485 : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc),
0486 IsImplicit(IsImplicit) {
0487 SubStmts[SubStmt::Operand] = Operand;
0488 SubStmts[SubStmt::PromiseCall] = PromiseCall;
0489 }
0490
0491 CoreturnStmt(EmptyShell) : CoreturnStmt({}, {}, {}) {}
0492
0493 SourceLocation getKeywordLoc() const { return CoreturnLoc; }
0494
0495
0496
0497 Expr *getOperand() const { return static_cast<Expr*>(SubStmts[Operand]); }
0498
0499
0500
0501
0502 Expr *getPromiseCall() const {
0503 return static_cast<Expr*>(SubStmts[PromiseCall]);
0504 }
0505
0506 bool isImplicit() const { return IsImplicit; }
0507 void setIsImplicit(bool value = true) { IsImplicit = value; }
0508
0509 SourceLocation getBeginLoc() const LLVM_READONLY { return CoreturnLoc; }
0510 SourceLocation getEndLoc() const LLVM_READONLY {
0511 return getOperand() ? getOperand()->getEndLoc() : getBeginLoc();
0512 }
0513
0514 child_range children() {
0515 return child_range(SubStmts, SubStmts + SubStmt::Count);
0516 }
0517
0518 const_child_range children() const {
0519 return const_child_range(SubStmts, SubStmts + SubStmt::Count);
0520 }
0521
0522 static bool classof(const Stmt *T) {
0523 return T->getStmtClass() == CoreturnStmtClass;
0524 }
0525 };
0526
0527 }
0528
0529 #endif