10b57cec5SDimitry Andric //===--- StmtCXX.cpp - Classes for representing C++ statements ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the subclesses of Stmt class declared in StmtCXX.h
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h"
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric using namespace clang;
180b57cec5SDimitry Andric
getCaughtType() const190b57cec5SDimitry Andric QualType CXXCatchStmt::getCaughtType() const {
200b57cec5SDimitry Andric if (ExceptionDecl)
210b57cec5SDimitry Andric return ExceptionDecl->getType();
220b57cec5SDimitry Andric return QualType();
230b57cec5SDimitry Andric }
240b57cec5SDimitry Andric
Create(const ASTContext & C,SourceLocation tryLoc,CompoundStmt * tryBlock,ArrayRef<Stmt * > handlers)250b57cec5SDimitry Andric CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc,
26*06c3fb27SDimitry Andric CompoundStmt *tryBlock,
27*06c3fb27SDimitry Andric ArrayRef<Stmt *> handlers) {
280b57cec5SDimitry Andric const size_t Size = totalSizeToAlloc<Stmt *>(handlers.size() + 1);
290b57cec5SDimitry Andric void *Mem = C.Allocate(Size, alignof(CXXTryStmt));
300b57cec5SDimitry Andric return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers);
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
Create(const ASTContext & C,EmptyShell Empty,unsigned numHandlers)330b57cec5SDimitry Andric CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, EmptyShell Empty,
340b57cec5SDimitry Andric unsigned numHandlers) {
350b57cec5SDimitry Andric const size_t Size = totalSizeToAlloc<Stmt *>(numHandlers + 1);
360b57cec5SDimitry Andric void *Mem = C.Allocate(Size, alignof(CXXTryStmt));
370b57cec5SDimitry Andric return new (Mem) CXXTryStmt(Empty, numHandlers);
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric
CXXTryStmt(SourceLocation tryLoc,CompoundStmt * tryBlock,ArrayRef<Stmt * > handlers)40*06c3fb27SDimitry Andric CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock,
410b57cec5SDimitry Andric ArrayRef<Stmt *> handlers)
420b57cec5SDimitry Andric : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) {
430b57cec5SDimitry Andric Stmt **Stmts = getStmts();
440b57cec5SDimitry Andric Stmts[0] = tryBlock;
450b57cec5SDimitry Andric std::copy(handlers.begin(), handlers.end(), Stmts + 1);
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric
CXXForRangeStmt(Stmt * Init,DeclStmt * Range,DeclStmt * BeginStmt,DeclStmt * EndStmt,Expr * Cond,Expr * Inc,DeclStmt * LoopVar,Stmt * Body,SourceLocation FL,SourceLocation CAL,SourceLocation CL,SourceLocation RPL)480b57cec5SDimitry Andric CXXForRangeStmt::CXXForRangeStmt(Stmt *Init, DeclStmt *Range,
490b57cec5SDimitry Andric DeclStmt *BeginStmt, DeclStmt *EndStmt,
500b57cec5SDimitry Andric Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
510b57cec5SDimitry Andric Stmt *Body, SourceLocation FL,
520b57cec5SDimitry Andric SourceLocation CAL, SourceLocation CL,
530b57cec5SDimitry Andric SourceLocation RPL)
540b57cec5SDimitry Andric : Stmt(CXXForRangeStmtClass), ForLoc(FL), CoawaitLoc(CAL), ColonLoc(CL),
550b57cec5SDimitry Andric RParenLoc(RPL) {
560b57cec5SDimitry Andric SubExprs[INIT] = Init;
570b57cec5SDimitry Andric SubExprs[RANGE] = Range;
580b57cec5SDimitry Andric SubExprs[BEGINSTMT] = BeginStmt;
590b57cec5SDimitry Andric SubExprs[ENDSTMT] = EndStmt;
600b57cec5SDimitry Andric SubExprs[COND] = Cond;
610b57cec5SDimitry Andric SubExprs[INC] = Inc;
620b57cec5SDimitry Andric SubExprs[LOOPVAR] = LoopVar;
630b57cec5SDimitry Andric SubExprs[BODY] = Body;
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric
getRangeInit()660b57cec5SDimitry Andric Expr *CXXForRangeStmt::getRangeInit() {
670b57cec5SDimitry Andric DeclStmt *RangeStmt = getRangeStmt();
680b57cec5SDimitry Andric VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
690b57cec5SDimitry Andric assert(RangeDecl && "for-range should have a single var decl");
700b57cec5SDimitry Andric return RangeDecl->getInit();
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric
getRangeInit() const730b57cec5SDimitry Andric const Expr *CXXForRangeStmt::getRangeInit() const {
740b57cec5SDimitry Andric return const_cast<CXXForRangeStmt *>(this)->getRangeInit();
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric
getLoopVariable()770b57cec5SDimitry Andric VarDecl *CXXForRangeStmt::getLoopVariable() {
780b57cec5SDimitry Andric Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
790b57cec5SDimitry Andric assert(LV && "No loop variable in CXXForRangeStmt");
800b57cec5SDimitry Andric return cast<VarDecl>(LV);
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric
getLoopVariable() const830b57cec5SDimitry Andric const VarDecl *CXXForRangeStmt::getLoopVariable() const {
840b57cec5SDimitry Andric return const_cast<CXXForRangeStmt *>(this)->getLoopVariable();
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
Create(const ASTContext & C,CoroutineBodyStmt::CtorArgs const & Args)870b57cec5SDimitry Andric CoroutineBodyStmt *CoroutineBodyStmt::Create(
880b57cec5SDimitry Andric const ASTContext &C, CoroutineBodyStmt::CtorArgs const &Args) {
890b57cec5SDimitry Andric std::size_t Size = totalSizeToAlloc<Stmt *>(
900b57cec5SDimitry Andric CoroutineBodyStmt::FirstParamMove + Args.ParamMoves.size());
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));
930b57cec5SDimitry Andric return new (Mem) CoroutineBodyStmt(Args);
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric
Create(const ASTContext & C,EmptyShell,unsigned NumParams)960b57cec5SDimitry Andric CoroutineBodyStmt *CoroutineBodyStmt::Create(const ASTContext &C, EmptyShell,
970b57cec5SDimitry Andric unsigned NumParams) {
980b57cec5SDimitry Andric std::size_t Size = totalSizeToAlloc<Stmt *>(
990b57cec5SDimitry Andric CoroutineBodyStmt::FirstParamMove + NumParams);
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));
1020b57cec5SDimitry Andric auto *Result = new (Mem) CoroutineBodyStmt(CtorArgs());
1030b57cec5SDimitry Andric Result->NumParams = NumParams;
1040b57cec5SDimitry Andric auto *ParamBegin = Result->getStoredStmts() + SubStmt::FirstParamMove;
1050b57cec5SDimitry Andric std::uninitialized_fill(ParamBegin, ParamBegin + NumParams,
1060b57cec5SDimitry Andric static_cast<Stmt *>(nullptr));
1070b57cec5SDimitry Andric return Result;
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric
CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const & Args)1100b57cec5SDimitry Andric CoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args)
1110b57cec5SDimitry Andric : Stmt(CoroutineBodyStmtClass), NumParams(Args.ParamMoves.size()) {
1120b57cec5SDimitry Andric Stmt **SubStmts = getStoredStmts();
1130b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::Body] = Args.Body;
1140b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::Promise] = Args.Promise;
1150b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::InitSuspend] = Args.InitialSuspend;
1160b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::FinalSuspend] = Args.FinalSuspend;
1170b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::OnException] = Args.OnException;
1180b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::OnFallthrough] = Args.OnFallthrough;
1190b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::Allocate] = Args.Allocate;
1200b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::Deallocate] = Args.Deallocate;
121*06c3fb27SDimitry Andric SubStmts[CoroutineBodyStmt::ResultDecl] = Args.ResultDecl;
1220b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::ReturnValue] = Args.ReturnValue;
1230b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::ReturnStmt] = Args.ReturnStmt;
1240b57cec5SDimitry Andric SubStmts[CoroutineBodyStmt::ReturnStmtOnAllocFailure] =
1250b57cec5SDimitry Andric Args.ReturnStmtOnAllocFailure;
1260b57cec5SDimitry Andric std::copy(Args.ParamMoves.begin(), Args.ParamMoves.end(),
1270b57cec5SDimitry Andric const_cast<Stmt **>(getParamMoves().data()));
1280b57cec5SDimitry Andric }
129