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