128 lines · cpp
1//===--- StmtCXX.cpp - Classes for representing C++ statements ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the subclesses of Stmt class declared in StmtCXX.h10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/StmtCXX.h"14 15#include "clang/AST/ASTContext.h"16 17using namespace clang;18 19QualType CXXCatchStmt::getCaughtType() const {20 if (ExceptionDecl)21 return ExceptionDecl->getType();22 return QualType();23}24 25CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc,26 CompoundStmt *tryBlock,27 ArrayRef<Stmt *> handlers) {28 const size_t Size = totalSizeToAlloc<Stmt *>(handlers.size() + 1);29 void *Mem = C.Allocate(Size, alignof(CXXTryStmt));30 return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers);31}32 33CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, EmptyShell Empty,34 unsigned numHandlers) {35 const size_t Size = totalSizeToAlloc<Stmt *>(numHandlers + 1);36 void *Mem = C.Allocate(Size, alignof(CXXTryStmt));37 return new (Mem) CXXTryStmt(Empty, numHandlers);38}39 40CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock,41 ArrayRef<Stmt *> handlers)42 : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) {43 Stmt **Stmts = getStmts();44 Stmts[0] = tryBlock;45 llvm::copy(handlers, Stmts + 1);46}47 48CXXForRangeStmt::CXXForRangeStmt(Stmt *Init, DeclStmt *Range,49 DeclStmt *BeginStmt, DeclStmt *EndStmt,50 Expr *Cond, Expr *Inc, DeclStmt *LoopVar,51 Stmt *Body, SourceLocation FL,52 SourceLocation CAL, SourceLocation CL,53 SourceLocation RPL)54 : Stmt(CXXForRangeStmtClass), ForLoc(FL), CoawaitLoc(CAL), ColonLoc(CL),55 RParenLoc(RPL) {56 SubExprs[INIT] = Init;57 SubExprs[RANGE] = Range;58 SubExprs[BEGINSTMT] = BeginStmt;59 SubExprs[ENDSTMT] = EndStmt;60 SubExprs[COND] = Cond;61 SubExprs[INC] = Inc;62 SubExprs[LOOPVAR] = LoopVar;63 SubExprs[BODY] = Body;64}65 66Expr *CXXForRangeStmt::getRangeInit() {67 DeclStmt *RangeStmt = getRangeStmt();68 VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());69 assert(RangeDecl && "for-range should have a single var decl");70 return RangeDecl->getInit();71}72 73const Expr *CXXForRangeStmt::getRangeInit() const {74 return const_cast<CXXForRangeStmt *>(this)->getRangeInit();75}76 77VarDecl *CXXForRangeStmt::getLoopVariable() {78 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();79 assert(LV && "No loop variable in CXXForRangeStmt");80 return cast<VarDecl>(LV);81}82 83const VarDecl *CXXForRangeStmt::getLoopVariable() const {84 return const_cast<CXXForRangeStmt *>(this)->getLoopVariable();85}86 87CoroutineBodyStmt *CoroutineBodyStmt::Create(88 const ASTContext &C, CoroutineBodyStmt::CtorArgs const &Args) {89 std::size_t Size = totalSizeToAlloc<Stmt *>(90 CoroutineBodyStmt::FirstParamMove + Args.ParamMoves.size());91 92 void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));93 return new (Mem) CoroutineBodyStmt(Args);94}95 96CoroutineBodyStmt *CoroutineBodyStmt::Create(const ASTContext &C, EmptyShell,97 unsigned NumParams) {98 std::size_t Size = totalSizeToAlloc<Stmt *>(99 CoroutineBodyStmt::FirstParamMove + NumParams);100 101 void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));102 auto *Result = new (Mem) CoroutineBodyStmt(CtorArgs());103 Result->NumParams = NumParams;104 auto *ParamBegin = Result->getStoredStmts() + SubStmt::FirstParamMove;105 std::uninitialized_fill(ParamBegin, ParamBegin + NumParams,106 static_cast<Stmt *>(nullptr));107 return Result;108}109 110CoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args)111 : Stmt(CoroutineBodyStmtClass), NumParams(Args.ParamMoves.size()) {112 Stmt **SubStmts = getStoredStmts();113 SubStmts[CoroutineBodyStmt::Body] = Args.Body;114 SubStmts[CoroutineBodyStmt::Promise] = Args.Promise;115 SubStmts[CoroutineBodyStmt::InitSuspend] = Args.InitialSuspend;116 SubStmts[CoroutineBodyStmt::FinalSuspend] = Args.FinalSuspend;117 SubStmts[CoroutineBodyStmt::OnException] = Args.OnException;118 SubStmts[CoroutineBodyStmt::OnFallthrough] = Args.OnFallthrough;119 SubStmts[CoroutineBodyStmt::Allocate] = Args.Allocate;120 SubStmts[CoroutineBodyStmt::Deallocate] = Args.Deallocate;121 SubStmts[CoroutineBodyStmt::ResultDecl] = Args.ResultDecl;122 SubStmts[CoroutineBodyStmt::ReturnValue] = Args.ReturnValue;123 SubStmts[CoroutineBodyStmt::ReturnStmt] = Args.ReturnStmt;124 SubStmts[CoroutineBodyStmt::ReturnStmtOnAllocFailure] =125 Args.ReturnStmtOnAllocFailure;126 llvm::copy(Args.ParamMoves, const_cast<Stmt **>(getParamMoves().data()));127}128