StmtCXX.cpp revision 322320
1139749Simp//===--- StmtCXX.cpp - Classes for representing C++ statements ------------===// 253790Sobrien// 353790Sobrien// The LLVM Compiler Infrastructure 453790Sobrien// 586266Sgroudier// This file is distributed under the University of Illinois Open Source 653790Sobrien// License. See LICENSE.TXT for details. 753790Sobrien// 859743Sgroudier//===----------------------------------------------------------------------===// 959743Sgroudier// 1053790Sobrien// This file implements the subclesses of Stmt class declared in StmtCXX.h 1153790Sobrien// 1253790Sobrien//===----------------------------------------------------------------------===// 1353790Sobrien 1453790Sobrien#include "clang/AST/StmtCXX.h" 1553790Sobrien 1653790Sobrien#include "clang/AST/ASTContext.h" 1753790Sobrien 1853790Sobrienusing namespace clang; 1953790Sobrien 2053790SobrienQualType CXXCatchStmt::getCaughtType() const { 2153790Sobrien if (ExceptionDecl) 2253790Sobrien return ExceptionDecl->getType(); 2353790Sobrien return QualType(); 2453790Sobrien} 2553790Sobrien 2653790SobrienCXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc, 2753790Sobrien Stmt *tryBlock, ArrayRef<Stmt *> handlers) { 2853790Sobrien std::size_t Size = sizeof(CXXTryStmt); 2953790Sobrien Size += ((handlers.size() + 1) * sizeof(Stmt *)); 3053790Sobrien 3153790Sobrien void *Mem = C.Allocate(Size, alignof(CXXTryStmt)); 3253790Sobrien return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers); 3353790Sobrien} 3453790Sobrien 3553790SobrienCXXTryStmt *CXXTryStmt::Create(const ASTContext &C, EmptyShell Empty, 3653790Sobrien unsigned numHandlers) { 3753790Sobrien std::size_t Size = sizeof(CXXTryStmt); 3853790Sobrien Size += ((numHandlers + 1) * sizeof(Stmt *)); 3953790Sobrien 4053790Sobrien void *Mem = C.Allocate(Size, alignof(CXXTryStmt)); 4153790Sobrien return new (Mem) CXXTryStmt(Empty, numHandlers); 4253790Sobrien} 4353790Sobrien 4453790SobrienCXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, 4553790Sobrien ArrayRef<Stmt *> handlers) 4653790Sobrien : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) { 4753790Sobrien Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1); 4853790Sobrien Stmts[0] = tryBlock; 4953790Sobrien std::copy(handlers.begin(), handlers.end(), Stmts + 1); 5053790Sobrien} 5153790Sobrien 5253790SobrienCXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, 5353790Sobrien DeclStmt *BeginStmt, DeclStmt *EndStmt, 5453790Sobrien Expr *Cond, Expr *Inc, DeclStmt *LoopVar, 5553790Sobrien Stmt *Body, SourceLocation FL, 5653790Sobrien SourceLocation CAL, SourceLocation CL, 5755258Sobrien SourceLocation RPL) 5855258Sobrien : Stmt(CXXForRangeStmtClass), ForLoc(FL), CoawaitLoc(CAL), ColonLoc(CL), 5955258Sobrien RParenLoc(RPL) { 6053790Sobrien SubExprs[RANGE] = Range; 6153790Sobrien SubExprs[BEGINSTMT] = BeginStmt; 6253790Sobrien SubExprs[ENDSTMT] = EndStmt; 6353790Sobrien SubExprs[COND] = Cond; 6453790Sobrien SubExprs[INC] = Inc; 6553790Sobrien SubExprs[LOOPVAR] = LoopVar; 6653790Sobrien SubExprs[BODY] = Body; 6753790Sobrien} 6853790Sobrien 6959743SgroudierExpr *CXXForRangeStmt::getRangeInit() { 7059743Sgroudier DeclStmt *RangeStmt = getRangeStmt(); 7159743Sgroudier VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl()); 7259743Sgroudier assert(RangeDecl && "for-range should have a single var decl"); 7359743Sgroudier return RangeDecl->getInit(); 7453790Sobrien} 7553790Sobrien 7654690Sobrienconst Expr *CXXForRangeStmt::getRangeInit() const { 7753790Sobrien return const_cast<CXXForRangeStmt *>(this)->getRangeInit(); 7853790Sobrien} 7953790Sobrien 8053790SobrienVarDecl *CXXForRangeStmt::getLoopVariable() { 8153790Sobrien Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl(); 8253790Sobrien assert(LV && "No loop variable in CXXForRangeStmt"); 8354690Sobrien return cast<VarDecl>(LV); 8453790Sobrien} 8553790Sobrien 86236061Smariusconst VarDecl *CXXForRangeStmt::getLoopVariable() const { 87236061Smarius return const_cast<CXXForRangeStmt *>(this)->getLoopVariable(); 88236061Smarius} 89236061Smarius 90236061SmariusCoroutineBodyStmt *CoroutineBodyStmt::Create( 91236061Smarius const ASTContext &C, CoroutineBodyStmt::CtorArgs const &Args) { 92236061Smarius std::size_t Size = totalSizeToAlloc<Stmt *>( 93237101Smarius CoroutineBodyStmt::FirstParamMove + Args.ParamMoves.size()); 9453790Sobrien 95237101Smarius void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt)); 96237101Smarius return new (Mem) CoroutineBodyStmt(Args); 9753790Sobrien} 98237101Smarius 9953790SobrienCoroutineBodyStmt *CoroutineBodyStmt::Create(const ASTContext &C, EmptyShell, 10053790Sobrien unsigned NumParams) { 10153790Sobrien std::size_t Size = totalSizeToAlloc<Stmt *>( 10253790Sobrien CoroutineBodyStmt::FirstParamMove + NumParams); 10353790Sobrien 10454690Sobrien void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt)); 10553790Sobrien auto *Result = new (Mem) CoroutineBodyStmt(CtorArgs()); 10653790Sobrien Result->NumParams = NumParams; 10753790Sobrien auto *ParamBegin = Result->getStoredStmts() + SubStmt::FirstParamMove; 10853790Sobrien std::uninitialized_fill(ParamBegin, ParamBegin + NumParams, 10953790Sobrien static_cast<Stmt *>(nullptr)); 11053790Sobrien return Result; 11153790Sobrien} 11253790Sobrien 11354690SobrienCoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args) 11453790Sobrien : Stmt(CoroutineBodyStmtClass), NumParams(Args.ParamMoves.size()) { 11553790Sobrien Stmt **SubStmts = getStoredStmts(); 11653790Sobrien SubStmts[CoroutineBodyStmt::Body] = Args.Body; 11753790Sobrien SubStmts[CoroutineBodyStmt::Promise] = Args.Promise; 11853790Sobrien SubStmts[CoroutineBodyStmt::InitSuspend] = Args.InitialSuspend; 11953790Sobrien SubStmts[CoroutineBodyStmt::FinalSuspend] = Args.FinalSuspend; 12053790Sobrien SubStmts[CoroutineBodyStmt::OnException] = Args.OnException; 12153790Sobrien SubStmts[CoroutineBodyStmt::OnFallthrough] = Args.OnFallthrough; 12253790Sobrien SubStmts[CoroutineBodyStmt::Allocate] = Args.Allocate; 12353790Sobrien SubStmts[CoroutineBodyStmt::Deallocate] = Args.Deallocate; 12454690Sobrien SubStmts[CoroutineBodyStmt::ReturnValue] = Args.ReturnValue; 12553790Sobrien SubStmts[CoroutineBodyStmt::ResultDecl] = Args.ResultDecl; 12653790Sobrien SubStmts[CoroutineBodyStmt::ReturnStmt] = Args.ReturnStmt; 12753790Sobrien SubStmts[CoroutineBodyStmt::ReturnStmtOnAllocFailure] = 12853790Sobrien Args.ReturnStmtOnAllocFailure; 12954690Sobrien std::copy(Args.ParamMoves.begin(), Args.ParamMoves.end(), 13059743Sgroudier const_cast<Stmt **>(getParamMoves().data())); 13153790Sobrien} 13253790Sobrien