clang 24.0.0git
StmtCXX.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the subclesses of Stmt class declared in StmtCXX.h
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/StmtCXX.h"
14#include "clang/AST/ExprCXX.h"
15
17
18using namespace clang;
19
21 if (ExceptionDecl)
22 return ExceptionDecl->getType();
23 return QualType();
24}
25
26CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc,
27 CompoundStmt *tryBlock,
28 ArrayRef<Stmt *> handlers) {
29 const size_t Size = totalSizeToAlloc<Stmt *>(handlers.size() + 1);
30 void *Mem = C.Allocate(Size, alignof(CXXTryStmt));
31 return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers);
32}
33
35 unsigned numHandlers) {
36 const size_t Size = totalSizeToAlloc<Stmt *>(numHandlers + 1);
37 void *Mem = C.Allocate(Size, alignof(CXXTryStmt));
38 return new (Mem) CXXTryStmt(Empty, numHandlers);
39}
40
41CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock,
42 ArrayRef<Stmt *> handlers)
43 : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) {
44 Stmt **Stmts = getStmts();
45 Stmts[0] = tryBlock;
46 llvm::copy(handlers, Stmts + 1);
47}
48
50 DeclStmt *BeginStmt, DeclStmt *EndStmt,
51 Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
52 Stmt *Body, SourceLocation FL,
55 : Stmt(CXXForRangeStmtClass), ForLoc(FL), CoawaitLoc(CAL), ColonLoc(CL),
56 RParenLoc(RPL) {
57 SubExprs[INIT] = Init;
58 SubExprs[RANGE] = Range;
59 SubExprs[BEGINSTMT] = BeginStmt;
60 SubExprs[ENDSTMT] = EndStmt;
61 SubExprs[COND] = Cond;
62 SubExprs[INC] = Inc;
63 SubExprs[LOOPVAR] = LoopVar;
64 SubExprs[BODY] = Body;
65}
66
68 DeclStmt *RangeStmt = getRangeStmt();
69 VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
70 assert(RangeDecl && "for-range should have a single var decl");
71 return RangeDecl->getInit();
72}
73
75 return const_cast<CXXForRangeStmt *>(this)->getRangeInit();
76}
77
79 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
80 assert(LV && "No loop variable in CXXForRangeStmt");
81 return cast<VarDecl>(LV);
82}
83
85 return const_cast<CXXForRangeStmt *>(this)->getLoopVariable();
86}
87
88CoroutineBodyStmt *CoroutineBodyStmt::Create(
89 const ASTContext &C, CoroutineBodyStmt::CtorArgs const &Args) {
90 std::size_t Size = totalSizeToAlloc<Stmt *>(
91 CoroutineBodyStmt::FirstParamMove + Args.ParamMoves.size());
92
93 void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));
94 return new (Mem) CoroutineBodyStmt(Args);
95}
96
98 unsigned NumParams) {
99 std::size_t Size = totalSizeToAlloc<Stmt *>(
100 CoroutineBodyStmt::FirstParamMove + NumParams);
101
102 void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));
103 auto *Result = new (Mem) CoroutineBodyStmt(CtorArgs());
104 Result->NumParams = NumParams;
105 auto *ParamBegin = Result->getStoredStmts() + SubStmt::FirstParamMove;
106 std::uninitialized_fill(ParamBegin, ParamBegin + NumParams,
107 static_cast<Stmt *>(nullptr));
108 return Result;
109}
110
111CoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args)
112 : Stmt(CoroutineBodyStmtClass), NumParams(Args.ParamMoves.size()) {
113 Stmt **SubStmts = getStoredStmts();
114 SubStmts[CoroutineBodyStmt::Body] = Args.Body;
115 SubStmts[CoroutineBodyStmt::Promise] = Args.Promise;
116 SubStmts[CoroutineBodyStmt::InitSuspend] = Args.InitialSuspend;
117 SubStmts[CoroutineBodyStmt::FinalSuspend] = Args.FinalSuspend;
118 SubStmts[CoroutineBodyStmt::OnException] = Args.OnException;
119 SubStmts[CoroutineBodyStmt::OnFallthrough] = Args.OnFallthrough;
120 SubStmts[CoroutineBodyStmt::Allocate] = Args.Allocate;
121 SubStmts[CoroutineBodyStmt::Deallocate] = Args.Deallocate;
122 SubStmts[CoroutineBodyStmt::ResultDecl] = Args.ResultDecl;
123 SubStmts[CoroutineBodyStmt::ReturnValue] = Args.ReturnValue;
124 SubStmts[CoroutineBodyStmt::ReturnStmt] = Args.ReturnStmt;
125 SubStmts[CoroutineBodyStmt::ReturnStmtOnAllocFailure] =
127 llvm::copy(Args.ParamMoves, const_cast<Stmt **>(getParamMoves().data()));
128}
129
130CXXExpansionStmtPattern::CXXExpansionStmtPattern(ExpansionStmtKind PatternKind,
131 EmptyShell Empty)
132 : Stmt(CXXExpansionStmtPatternClass, Empty), PatternKind(PatternKind) {}
133
134CXXExpansionStmtPattern::CXXExpansionStmtPattern(
135 ExpansionStmtKind PatternKind, CXXExpansionStmtDecl *ESD, Stmt *Init,
136 DeclStmt *ExpansionVar, SourceLocation LParenLoc, SourceLocation ColonLoc,
137 SourceLocation RParenLoc)
138 : Stmt(CXXExpansionStmtPatternClass), PatternKind(PatternKind),
139 LParenLoc(LParenLoc), ColonLoc(ColonLoc), RParenLoc(RParenLoc),
140 ParentDecl(ESD) {
141 setInit(Init);
142 setExpansionVarStmt(ExpansionVar);
143 setBody(nullptr);
144}
145
146template <typename... Args>
147CXXExpansionStmtPattern *CXXExpansionStmtPattern::AllocateAndConstruct(
148 ASTContext &Context, ExpansionStmtKind Kind, Args &&...Arguments) {
149 std::size_t Size = totalSizeToAlloc<Stmt *>(getNumSubStmts(Kind));
150 void *Mem = Context.Allocate(Size, alignof(CXXExpansionStmtPattern));
151 return new (Mem)
152 CXXExpansionStmtPattern(Kind, std::forward<Args>(Arguments)...);
153}
154
156 ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init,
157 DeclStmt *ExpansionVar, Expr *ExpansionInitializer,
158 SourceLocation LParenLoc, SourceLocation ColonLoc,
159 SourceLocation RParenLoc) {
160 CXXExpansionStmtPattern *Pattern =
161 AllocateAndConstruct(Context, ExpansionStmtKind::Dependent, ESD, Init,
162 ExpansionVar, LParenLoc, ColonLoc, RParenLoc);
163 Pattern->setExpansionInitializer(ExpansionInitializer);
164 return Pattern;
165}
166
168 ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init,
169 DeclStmt *ExpansionVar, Stmt *DecompositionDeclStmt,
170 SourceLocation LParenLoc, SourceLocation ColonLoc,
171 SourceLocation RParenLoc) {
172 CXXExpansionStmtPattern *Pattern =
173 AllocateAndConstruct(Context, ExpansionStmtKind::Destructuring, ESD, Init,
174 ExpansionVar, LParenLoc, ColonLoc, RParenLoc);
175 Pattern->setDecompositionDeclStmt(DecompositionDeclStmt);
176 return Pattern;
177}
178
181 ExpansionStmtKind Kind) {
182 return AllocateAndConstruct(Context, Kind, Empty);
183}
184
186 ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init,
187 DeclStmt *ExpansionVar, SourceLocation LParenLoc, SourceLocation ColonLoc,
188 SourceLocation RParenLoc) {
189 return AllocateAndConstruct(Context, ExpansionStmtKind::Enumerating, ESD,
190 Init, ExpansionVar, LParenLoc, ColonLoc,
191 RParenLoc);
192}
193
195 ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init,
196 DeclStmt *ExpansionVar, DeclStmt *Range, DeclStmt *Begin, DeclStmt *Iter,
197 SourceLocation LParenLoc, SourceLocation ColonLoc,
198 SourceLocation RParenLoc) {
199 CXXExpansionStmtPattern *Pattern =
200 AllocateAndConstruct(Context, ExpansionStmtKind::Iterating, ESD, Init,
201 ExpansionVar, LParenLoc, ColonLoc, RParenLoc);
202 Pattern->setRangeVarStmt(Range);
203 Pattern->setBeginVarStmt(Begin);
204 Pattern->setIterVarStmt(Iter);
205 return Pattern;
206}
207
209 return ParentDecl->getLocation();
210}
211
217
219 Decl *LV = cast<DeclStmt>(getExpansionVarStmt())->getSingleDecl();
220 assert(LV && "No expansion variable in CXXExpansionStmtPattern");
221 return cast<VarDecl>(LV);
222}
223
224unsigned
225CXXExpansionStmtPattern::getNumSubStmts(ExpansionStmtKind PatternKind) {
226 switch (PatternKind) {
228 return COUNT_Enumerating;
230 return COUNT_Iterating;
232 return COUNT_Destructuring;
234 return COUNT_Dependent;
235 }
236
237 llvm_unreachable("invalid pattern kind");
238}
239
240CXXExpansionStmtInstantiation::CXXExpansionStmtInstantiation(
241 EmptyShell Empty, unsigned NumInstantiations, unsigned NumPreambleStmts)
242 : Stmt(CXXExpansionStmtInstantiationClass, Empty),
243 NumInstantiations(NumInstantiations), NumPreambleStmts(NumPreambleStmts) {
244 assert(NumPreambleStmts <= 4 && "might have to allocate more bits for this");
245}
246
247CXXExpansionStmtInstantiation::CXXExpansionStmtInstantiation(
248 CXXExpansionStmtDecl *Parent, ArrayRef<Stmt *> Instantiations,
249 ArrayRef<Stmt *> PreambleStmts, bool ShouldApplyLifetimeExtensionToPreamble)
250 : Stmt(CXXExpansionStmtInstantiationClass), Parent(Parent),
251 NumInstantiations(unsigned(Instantiations.size())),
252 NumPreambleStmts(unsigned(PreambleStmts.size())),
253 ShouldApplyLifetimeExtensionToPreamble(
254 ShouldApplyLifetimeExtensionToPreamble) {
255 assert(NumPreambleStmts <= 4 && "might have to allocate more bits for this");
256 llvm::uninitialized_copy(Instantiations, getTrailingObjects());
257 llvm::uninitialized_copy(PreambleStmts,
258 getTrailingObjects() + NumInstantiations);
259}
260
261CXXExpansionStmtInstantiation *CXXExpansionStmtInstantiation::Create(
263 ArrayRef<Stmt *> Instantiations, ArrayRef<Stmt *> PreambleStmts,
264 bool ShouldApplyLifetimeExtensionToPreamble) {
265 void *Mem = C.Allocate(
266 totalSizeToAlloc<Stmt *>(Instantiations.size() + PreambleStmts.size()),
267 alignof(CXXExpansionStmtInstantiation));
268 return new (Mem)
269 CXXExpansionStmtInstantiation(Parent, Instantiations, PreambleStmts,
270 ShouldApplyLifetimeExtensionToPreamble);
271}
272
275 unsigned NumInstantiations,
276 unsigned NumPreambleStmts) {
277 void *Mem =
278 C.Allocate(totalSizeToAlloc<Stmt *>(NumInstantiations + NumPreambleStmts),
279 alignof(CXXExpansionStmtInstantiation));
280 return new (Mem)
281 CXXExpansionStmtInstantiation(Empty, NumInstantiations, NumPreambleStmts);
282}
283
285 return Parent->getExpansionPattern()->getBeginLoc();
286}
287
289 return Parent->getExpansionPattern()->getEndLoc();
290}
Defines the clang::ASTContext interface.
Defines the clang::Expr interface and subclasses for C++ expressions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
void * Allocate(size_t Size, unsigned Align=8) const
Definition ASTContext.h:882
QualType getCaughtType() const
Definition StmtCXX.cpp:20
Represents a C++26 expansion statement declaration.
Represents the code generated for an expanded expansion statement.
Definition StmtCXX.h:1028
SourceLocation getBeginLoc() const
Definition StmtCXX.cpp:284
SourceLocation getEndLoc() const
Definition StmtCXX.cpp:288
static CXXExpansionStmtInstantiation * Create(ASTContext &C, CXXExpansionStmtDecl *Parent, ArrayRef< Stmt * > Instantiations, ArrayRef< Stmt * > PreambleStmts, bool ShouldApplyLifetimeExtensionToPreamble)
Definition StmtCXX.cpp:261
static CXXExpansionStmtInstantiation * CreateEmpty(ASTContext &C, EmptyShell Empty, unsigned NumInstantiations, unsigned NumPreambleStmts)
Definition StmtCXX.cpp:274
CXXExpansionStmtPattern - Represents an unexpanded C++ expansion statement.
Definition StmtCXX.h:675
static CXXExpansionStmtPattern * CreateIterating(ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVar, DeclStmt *Range, DeclStmt *Begin, DeclStmt *Iter, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation RParenLoc)
Create an iterating expansion statement pattern.
Definition StmtCXX.cpp:194
SourceLocation getBeginLoc() const
Definition StmtCXX.cpp:208
DecompositionDecl * getDecompositionDecl()
Definition StmtCXX.cpp:212
DeclStmt * getExpansionVarStmt()
Definition StmtCXX.h:803
static CXXExpansionStmtPattern * CreateDependent(ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVar, Expr *ExpansionInitializer, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation RParenLoc)
Create a dependent expansion statement pattern.
Definition StmtCXX.cpp:155
static CXXExpansionStmtPattern * CreateEmpty(ASTContext &Context, EmptyShell Empty, ExpansionStmtKind Kind)
Definition StmtCXX.cpp:180
static CXXExpansionStmtPattern * CreateDestructuring(ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVar, Stmt *DecompositionDeclStmt, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation RParenLoc)
Create a destructuring expansion statement pattern.
Definition StmtCXX.cpp:167
void setRangeVarStmt(DeclStmt *S)
Definition StmtCXX.h:825
void setBeginVarStmt(DeclStmt *S)
Definition StmtCXX.h:850
unsigned getNumSubStmts() const
Definition StmtCXX.h:788
void setIterVarStmt(DeclStmt *S)
Definition StmtCXX.h:875
void setDecompositionDeclStmt(Stmt *S)
Definition StmtCXX.h:901
void setExpansionInitializer(Expr *S)
Definition StmtCXX.h:922
static CXXExpansionStmtPattern * CreateEnumerating(ASTContext &Context, CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVar, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation RParenLoc)
Create an enumerating expansion statement pattern.
Definition StmtCXX.cpp:185
CXXForRangeStmt(Stmt *InitStmt, DeclStmt *Range, DeclStmt *Begin, DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, SourceLocation FL, SourceLocation CAL, SourceLocation CL, SourceLocation RPL)
Definition StmtCXX.cpp:49
DeclStmt * getLoopVarStmt()
Definition StmtCXX.h:170
DeclStmt * getRangeStmt()
Definition StmtCXX.h:163
VarDecl * getLoopVariable()
Definition StmtCXX.cpp:78
static CXXTryStmt * Create(const ASTContext &C, SourceLocation tryLoc, CompoundStmt *tryBlock, ArrayRef< Stmt * > handlers)
Definition StmtCXX.cpp:26
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1750
static CoroutineBodyStmt * Create(const ASTContext &C, CtorArgs const &Args)
Definition StmtCXX.cpp:88
ArrayRef< Stmt const * > getParamMoves() const
Definition StmtCXX.h:424
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1641
const Decl * getSingleDecl() const
Definition Stmt.h:1656
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
A decomposition declaration.
Definition DeclCXX.h:4270
This represents one expression.
Definition Expr.h:112
A (possibly-)qualified type.
Definition TypeBase.h:937
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:86
Stmt(StmtClass SC, EmptyShell)
Construct an empty statement.
Definition Stmt.h:1485
Represents a variable declaration or definition.
Definition Decl.h:932
const Expr * getInit() const
Definition Decl.h:1391
Definition SPIR.cpp:35
The JSON file list parser is used to communicate input to InstallAPI.
Expr * Cond
};
@ Result
The result type of a method or function.
Definition TypeBase.h:905
U cast(CodeGen::Address addr)
Definition Address.h:327
ArrayRef< Stmt * > ParamMoves
Definition StmtCXX.h:362
A placeholder type used to construct an empty shell of a type, that will be filled in later (e....
Definition Stmt.h:1443