1*67e74705SXin Li //===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the Stmt class and statement subclasses.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li
14*67e74705SXin Li #include "clang/AST/ASTContext.h"
15*67e74705SXin Li #include "clang/AST/ASTDiagnostic.h"
16*67e74705SXin Li #include "clang/AST/ExprCXX.h"
17*67e74705SXin Li #include "clang/AST/ExprObjC.h"
18*67e74705SXin Li #include "clang/AST/ExprOpenMP.h"
19*67e74705SXin Li #include "clang/AST/Stmt.h"
20*67e74705SXin Li #include "clang/AST/StmtCXX.h"
21*67e74705SXin Li #include "clang/AST/StmtObjC.h"
22*67e74705SXin Li #include "clang/AST/StmtOpenMP.h"
23*67e74705SXin Li #include "clang/AST/Type.h"
24*67e74705SXin Li #include "clang/Basic/CharInfo.h"
25*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
26*67e74705SXin Li #include "clang/Lex/Token.h"
27*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
28*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
29*67e74705SXin Li using namespace clang;
30*67e74705SXin Li
31*67e74705SXin Li static struct StmtClassNameTable {
32*67e74705SXin Li const char *Name;
33*67e74705SXin Li unsigned Counter;
34*67e74705SXin Li unsigned Size;
35*67e74705SXin Li } StmtClassInfo[Stmt::lastStmtConstant+1];
36*67e74705SXin Li
getStmtInfoTableEntry(Stmt::StmtClass E)37*67e74705SXin Li static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
38*67e74705SXin Li static bool Initialized = false;
39*67e74705SXin Li if (Initialized)
40*67e74705SXin Li return StmtClassInfo[E];
41*67e74705SXin Li
42*67e74705SXin Li // Intialize the table on the first use.
43*67e74705SXin Li Initialized = true;
44*67e74705SXin Li #define ABSTRACT_STMT(STMT)
45*67e74705SXin Li #define STMT(CLASS, PARENT) \
46*67e74705SXin Li StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
47*67e74705SXin Li StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
48*67e74705SXin Li #include "clang/AST/StmtNodes.inc"
49*67e74705SXin Li
50*67e74705SXin Li return StmtClassInfo[E];
51*67e74705SXin Li }
52*67e74705SXin Li
operator new(size_t bytes,const ASTContext & C,unsigned alignment)53*67e74705SXin Li void *Stmt::operator new(size_t bytes, const ASTContext& C,
54*67e74705SXin Li unsigned alignment) {
55*67e74705SXin Li return ::operator new(bytes, C, alignment);
56*67e74705SXin Li }
57*67e74705SXin Li
getStmtClassName() const58*67e74705SXin Li const char *Stmt::getStmtClassName() const {
59*67e74705SXin Li return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
60*67e74705SXin Li }
61*67e74705SXin Li
PrintStats()62*67e74705SXin Li void Stmt::PrintStats() {
63*67e74705SXin Li // Ensure the table is primed.
64*67e74705SXin Li getStmtInfoTableEntry(Stmt::NullStmtClass);
65*67e74705SXin Li
66*67e74705SXin Li unsigned sum = 0;
67*67e74705SXin Li llvm::errs() << "\n*** Stmt/Expr Stats:\n";
68*67e74705SXin Li for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
69*67e74705SXin Li if (StmtClassInfo[i].Name == nullptr) continue;
70*67e74705SXin Li sum += StmtClassInfo[i].Counter;
71*67e74705SXin Li }
72*67e74705SXin Li llvm::errs() << " " << sum << " stmts/exprs total.\n";
73*67e74705SXin Li sum = 0;
74*67e74705SXin Li for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
75*67e74705SXin Li if (StmtClassInfo[i].Name == nullptr) continue;
76*67e74705SXin Li if (StmtClassInfo[i].Counter == 0) continue;
77*67e74705SXin Li llvm::errs() << " " << StmtClassInfo[i].Counter << " "
78*67e74705SXin Li << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
79*67e74705SXin Li << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size
80*67e74705SXin Li << " bytes)\n";
81*67e74705SXin Li sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
82*67e74705SXin Li }
83*67e74705SXin Li
84*67e74705SXin Li llvm::errs() << "Total bytes = " << sum << "\n";
85*67e74705SXin Li }
86*67e74705SXin Li
addStmtClass(StmtClass s)87*67e74705SXin Li void Stmt::addStmtClass(StmtClass s) {
88*67e74705SXin Li ++getStmtInfoTableEntry(s).Counter;
89*67e74705SXin Li }
90*67e74705SXin Li
91*67e74705SXin Li bool Stmt::StatisticsEnabled = false;
EnableStatistics()92*67e74705SXin Li void Stmt::EnableStatistics() {
93*67e74705SXin Li StatisticsEnabled = true;
94*67e74705SXin Li }
95*67e74705SXin Li
IgnoreImplicit()96*67e74705SXin Li Stmt *Stmt::IgnoreImplicit() {
97*67e74705SXin Li Stmt *s = this;
98*67e74705SXin Li
99*67e74705SXin Li if (auto *ewc = dyn_cast<ExprWithCleanups>(s))
100*67e74705SXin Li s = ewc->getSubExpr();
101*67e74705SXin Li
102*67e74705SXin Li if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
103*67e74705SXin Li s = mte->GetTemporaryExpr();
104*67e74705SXin Li
105*67e74705SXin Li if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
106*67e74705SXin Li s = bte->getSubExpr();
107*67e74705SXin Li
108*67e74705SXin Li while (auto *ice = dyn_cast<ImplicitCastExpr>(s))
109*67e74705SXin Li s = ice->getSubExpr();
110*67e74705SXin Li
111*67e74705SXin Li return s;
112*67e74705SXin Li }
113*67e74705SXin Li
114*67e74705SXin Li /// \brief Skip no-op (attributed, compound) container stmts and skip captured
115*67e74705SXin Li /// stmt at the top, if \a IgnoreCaptured is true.
IgnoreContainers(bool IgnoreCaptured)116*67e74705SXin Li Stmt *Stmt::IgnoreContainers(bool IgnoreCaptured) {
117*67e74705SXin Li Stmt *S = this;
118*67e74705SXin Li if (IgnoreCaptured)
119*67e74705SXin Li if (auto CapS = dyn_cast_or_null<CapturedStmt>(S))
120*67e74705SXin Li S = CapS->getCapturedStmt();
121*67e74705SXin Li while (true) {
122*67e74705SXin Li if (auto AS = dyn_cast_or_null<AttributedStmt>(S))
123*67e74705SXin Li S = AS->getSubStmt();
124*67e74705SXin Li else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
125*67e74705SXin Li if (CS->size() != 1)
126*67e74705SXin Li break;
127*67e74705SXin Li S = CS->body_back();
128*67e74705SXin Li } else
129*67e74705SXin Li break;
130*67e74705SXin Li }
131*67e74705SXin Li return S;
132*67e74705SXin Li }
133*67e74705SXin Li
134*67e74705SXin Li /// \brief Strip off all label-like statements.
135*67e74705SXin Li ///
136*67e74705SXin Li /// This will strip off label statements, case statements, attributed
137*67e74705SXin Li /// statements and default statements recursively.
stripLabelLikeStatements() const138*67e74705SXin Li const Stmt *Stmt::stripLabelLikeStatements() const {
139*67e74705SXin Li const Stmt *S = this;
140*67e74705SXin Li while (true) {
141*67e74705SXin Li if (const LabelStmt *LS = dyn_cast<LabelStmt>(S))
142*67e74705SXin Li S = LS->getSubStmt();
143*67e74705SXin Li else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S))
144*67e74705SXin Li S = SC->getSubStmt();
145*67e74705SXin Li else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S))
146*67e74705SXin Li S = AS->getSubStmt();
147*67e74705SXin Li else
148*67e74705SXin Li return S;
149*67e74705SXin Li }
150*67e74705SXin Li }
151*67e74705SXin Li
152*67e74705SXin Li namespace {
153*67e74705SXin Li struct good {};
154*67e74705SXin Li struct bad {};
155*67e74705SXin Li
156*67e74705SXin Li // These silly little functions have to be static inline to suppress
157*67e74705SXin Li // unused warnings, and they have to be defined to suppress other
158*67e74705SXin Li // warnings.
is_good(good)159*67e74705SXin Li static inline good is_good(good) { return good(); }
160*67e74705SXin Li
161*67e74705SXin Li typedef Stmt::child_range children_t();
implements_children(children_t T::*)162*67e74705SXin Li template <class T> good implements_children(children_t T::*) {
163*67e74705SXin Li return good();
164*67e74705SXin Li }
165*67e74705SXin Li LLVM_ATTRIBUTE_UNUSED
implements_children(children_t Stmt::*)166*67e74705SXin Li static inline bad implements_children(children_t Stmt::*) {
167*67e74705SXin Li return bad();
168*67e74705SXin Li }
169*67e74705SXin Li
170*67e74705SXin Li typedef SourceLocation getLocStart_t() const;
implements_getLocStart(getLocStart_t T::*)171*67e74705SXin Li template <class T> good implements_getLocStart(getLocStart_t T::*) {
172*67e74705SXin Li return good();
173*67e74705SXin Li }
174*67e74705SXin Li LLVM_ATTRIBUTE_UNUSED
implements_getLocStart(getLocStart_t Stmt::*)175*67e74705SXin Li static inline bad implements_getLocStart(getLocStart_t Stmt::*) {
176*67e74705SXin Li return bad();
177*67e74705SXin Li }
178*67e74705SXin Li
179*67e74705SXin Li typedef SourceLocation getLocEnd_t() const;
implements_getLocEnd(getLocEnd_t T::*)180*67e74705SXin Li template <class T> good implements_getLocEnd(getLocEnd_t T::*) {
181*67e74705SXin Li return good();
182*67e74705SXin Li }
183*67e74705SXin Li LLVM_ATTRIBUTE_UNUSED
implements_getLocEnd(getLocEnd_t Stmt::*)184*67e74705SXin Li static inline bad implements_getLocEnd(getLocEnd_t Stmt::*) {
185*67e74705SXin Li return bad();
186*67e74705SXin Li }
187*67e74705SXin Li
188*67e74705SXin Li #define ASSERT_IMPLEMENTS_children(type) \
189*67e74705SXin Li (void) is_good(implements_children(&type::children))
190*67e74705SXin Li #define ASSERT_IMPLEMENTS_getLocStart(type) \
191*67e74705SXin Li (void) is_good(implements_getLocStart(&type::getLocStart))
192*67e74705SXin Li #define ASSERT_IMPLEMENTS_getLocEnd(type) \
193*67e74705SXin Li (void) is_good(implements_getLocEnd(&type::getLocEnd))
194*67e74705SXin Li }
195*67e74705SXin Li
196*67e74705SXin Li /// Check whether the various Stmt classes implement their member
197*67e74705SXin Li /// functions.
198*67e74705SXin Li LLVM_ATTRIBUTE_UNUSED
check_implementations()199*67e74705SXin Li static inline void check_implementations() {
200*67e74705SXin Li #define ABSTRACT_STMT(type)
201*67e74705SXin Li #define STMT(type, base) \
202*67e74705SXin Li ASSERT_IMPLEMENTS_children(type); \
203*67e74705SXin Li ASSERT_IMPLEMENTS_getLocStart(type); \
204*67e74705SXin Li ASSERT_IMPLEMENTS_getLocEnd(type);
205*67e74705SXin Li #include "clang/AST/StmtNodes.inc"
206*67e74705SXin Li }
207*67e74705SXin Li
children()208*67e74705SXin Li Stmt::child_range Stmt::children() {
209*67e74705SXin Li switch (getStmtClass()) {
210*67e74705SXin Li case Stmt::NoStmtClass: llvm_unreachable("statement without class");
211*67e74705SXin Li #define ABSTRACT_STMT(type)
212*67e74705SXin Li #define STMT(type, base) \
213*67e74705SXin Li case Stmt::type##Class: \
214*67e74705SXin Li return static_cast<type*>(this)->children();
215*67e74705SXin Li #include "clang/AST/StmtNodes.inc"
216*67e74705SXin Li }
217*67e74705SXin Li llvm_unreachable("unknown statement kind!");
218*67e74705SXin Li }
219*67e74705SXin Li
220*67e74705SXin Li // Amusing macro metaprogramming hack: check whether a class provides
221*67e74705SXin Li // a more specific implementation of getSourceRange.
222*67e74705SXin Li //
223*67e74705SXin Li // See also Expr.cpp:getExprLoc().
224*67e74705SXin Li namespace {
225*67e74705SXin Li /// This implementation is used when a class provides a custom
226*67e74705SXin Li /// implementation of getSourceRange.
227*67e74705SXin Li template <class S, class T>
getSourceRangeImpl(const Stmt * stmt,SourceRange (T::* v)()const)228*67e74705SXin Li SourceRange getSourceRangeImpl(const Stmt *stmt,
229*67e74705SXin Li SourceRange (T::*v)() const) {
230*67e74705SXin Li return static_cast<const S*>(stmt)->getSourceRange();
231*67e74705SXin Li }
232*67e74705SXin Li
233*67e74705SXin Li /// This implementation is used when a class doesn't provide a custom
234*67e74705SXin Li /// implementation of getSourceRange. Overload resolution should pick it over
235*67e74705SXin Li /// the implementation above because it's more specialized according to
236*67e74705SXin Li /// function template partial ordering.
237*67e74705SXin Li template <class S>
getSourceRangeImpl(const Stmt * stmt,SourceRange (Stmt::* v)()const)238*67e74705SXin Li SourceRange getSourceRangeImpl(const Stmt *stmt,
239*67e74705SXin Li SourceRange (Stmt::*v)() const) {
240*67e74705SXin Li return SourceRange(static_cast<const S*>(stmt)->getLocStart(),
241*67e74705SXin Li static_cast<const S*>(stmt)->getLocEnd());
242*67e74705SXin Li }
243*67e74705SXin Li }
244*67e74705SXin Li
getSourceRange() const245*67e74705SXin Li SourceRange Stmt::getSourceRange() const {
246*67e74705SXin Li switch (getStmtClass()) {
247*67e74705SXin Li case Stmt::NoStmtClass: llvm_unreachable("statement without class");
248*67e74705SXin Li #define ABSTRACT_STMT(type)
249*67e74705SXin Li #define STMT(type, base) \
250*67e74705SXin Li case Stmt::type##Class: \
251*67e74705SXin Li return getSourceRangeImpl<type>(this, &type::getSourceRange);
252*67e74705SXin Li #include "clang/AST/StmtNodes.inc"
253*67e74705SXin Li }
254*67e74705SXin Li llvm_unreachable("unknown statement kind!");
255*67e74705SXin Li }
256*67e74705SXin Li
getLocStart() const257*67e74705SXin Li SourceLocation Stmt::getLocStart() const {
258*67e74705SXin Li // llvm::errs() << "getLocStart() for " << getStmtClassName() << "\n";
259*67e74705SXin Li switch (getStmtClass()) {
260*67e74705SXin Li case Stmt::NoStmtClass: llvm_unreachable("statement without class");
261*67e74705SXin Li #define ABSTRACT_STMT(type)
262*67e74705SXin Li #define STMT(type, base) \
263*67e74705SXin Li case Stmt::type##Class: \
264*67e74705SXin Li return static_cast<const type*>(this)->getLocStart();
265*67e74705SXin Li #include "clang/AST/StmtNodes.inc"
266*67e74705SXin Li }
267*67e74705SXin Li llvm_unreachable("unknown statement kind");
268*67e74705SXin Li }
269*67e74705SXin Li
getLocEnd() const270*67e74705SXin Li SourceLocation Stmt::getLocEnd() const {
271*67e74705SXin Li switch (getStmtClass()) {
272*67e74705SXin Li case Stmt::NoStmtClass: llvm_unreachable("statement without class");
273*67e74705SXin Li #define ABSTRACT_STMT(type)
274*67e74705SXin Li #define STMT(type, base) \
275*67e74705SXin Li case Stmt::type##Class: \
276*67e74705SXin Li return static_cast<const type*>(this)->getLocEnd();
277*67e74705SXin Li #include "clang/AST/StmtNodes.inc"
278*67e74705SXin Li }
279*67e74705SXin Li llvm_unreachable("unknown statement kind");
280*67e74705SXin Li }
281*67e74705SXin Li
CompoundStmt(const ASTContext & C,ArrayRef<Stmt * > Stmts,SourceLocation LB,SourceLocation RB)282*67e74705SXin Li CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
283*67e74705SXin Li SourceLocation LB, SourceLocation RB)
284*67e74705SXin Li : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
285*67e74705SXin Li CompoundStmtBits.NumStmts = Stmts.size();
286*67e74705SXin Li assert(CompoundStmtBits.NumStmts == Stmts.size() &&
287*67e74705SXin Li "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
288*67e74705SXin Li
289*67e74705SXin Li if (Stmts.size() == 0) {
290*67e74705SXin Li Body = nullptr;
291*67e74705SXin Li return;
292*67e74705SXin Li }
293*67e74705SXin Li
294*67e74705SXin Li Body = new (C) Stmt*[Stmts.size()];
295*67e74705SXin Li std::copy(Stmts.begin(), Stmts.end(), Body);
296*67e74705SXin Li }
297*67e74705SXin Li
setStmts(const ASTContext & C,ArrayRef<Stmt * > Stmts)298*67e74705SXin Li void CompoundStmt::setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts) {
299*67e74705SXin Li if (Body)
300*67e74705SXin Li C.Deallocate(Body);
301*67e74705SXin Li CompoundStmtBits.NumStmts = Stmts.size();
302*67e74705SXin Li assert(CompoundStmtBits.NumStmts == Stmts.size() &&
303*67e74705SXin Li "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
304*67e74705SXin Li
305*67e74705SXin Li Body = new (C) Stmt*[Stmts.size()];
306*67e74705SXin Li std::copy(Stmts.begin(), Stmts.end(), Body);
307*67e74705SXin Li }
308*67e74705SXin Li
getName() const309*67e74705SXin Li const char *LabelStmt::getName() const {
310*67e74705SXin Li return getDecl()->getIdentifier()->getNameStart();
311*67e74705SXin Li }
312*67e74705SXin Li
Create(const ASTContext & C,SourceLocation Loc,ArrayRef<const Attr * > Attrs,Stmt * SubStmt)313*67e74705SXin Li AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
314*67e74705SXin Li ArrayRef<const Attr*> Attrs,
315*67e74705SXin Li Stmt *SubStmt) {
316*67e74705SXin Li assert(!Attrs.empty() && "Attrs should not be empty");
317*67e74705SXin Li void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * Attrs.size(),
318*67e74705SXin Li llvm::alignOf<AttributedStmt>());
319*67e74705SXin Li return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
320*67e74705SXin Li }
321*67e74705SXin Li
CreateEmpty(const ASTContext & C,unsigned NumAttrs)322*67e74705SXin Li AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
323*67e74705SXin Li unsigned NumAttrs) {
324*67e74705SXin Li assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
325*67e74705SXin Li void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * NumAttrs,
326*67e74705SXin Li llvm::alignOf<AttributedStmt>());
327*67e74705SXin Li return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
328*67e74705SXin Li }
329*67e74705SXin Li
generateAsmString(const ASTContext & C) const330*67e74705SXin Li std::string AsmStmt::generateAsmString(const ASTContext &C) const {
331*67e74705SXin Li if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
332*67e74705SXin Li return gccAsmStmt->generateAsmString(C);
333*67e74705SXin Li if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
334*67e74705SXin Li return msAsmStmt->generateAsmString(C);
335*67e74705SXin Li llvm_unreachable("unknown asm statement kind!");
336*67e74705SXin Li }
337*67e74705SXin Li
getOutputConstraint(unsigned i) const338*67e74705SXin Li StringRef AsmStmt::getOutputConstraint(unsigned i) const {
339*67e74705SXin Li if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
340*67e74705SXin Li return gccAsmStmt->getOutputConstraint(i);
341*67e74705SXin Li if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
342*67e74705SXin Li return msAsmStmt->getOutputConstraint(i);
343*67e74705SXin Li llvm_unreachable("unknown asm statement kind!");
344*67e74705SXin Li }
345*67e74705SXin Li
getOutputExpr(unsigned i) const346*67e74705SXin Li const Expr *AsmStmt::getOutputExpr(unsigned i) const {
347*67e74705SXin Li if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
348*67e74705SXin Li return gccAsmStmt->getOutputExpr(i);
349*67e74705SXin Li if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
350*67e74705SXin Li return msAsmStmt->getOutputExpr(i);
351*67e74705SXin Li llvm_unreachable("unknown asm statement kind!");
352*67e74705SXin Li }
353*67e74705SXin Li
getInputConstraint(unsigned i) const354*67e74705SXin Li StringRef AsmStmt::getInputConstraint(unsigned i) const {
355*67e74705SXin Li if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
356*67e74705SXin Li return gccAsmStmt->getInputConstraint(i);
357*67e74705SXin Li if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
358*67e74705SXin Li return msAsmStmt->getInputConstraint(i);
359*67e74705SXin Li llvm_unreachable("unknown asm statement kind!");
360*67e74705SXin Li }
361*67e74705SXin Li
getInputExpr(unsigned i) const362*67e74705SXin Li const Expr *AsmStmt::getInputExpr(unsigned i) const {
363*67e74705SXin Li if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
364*67e74705SXin Li return gccAsmStmt->getInputExpr(i);
365*67e74705SXin Li if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
366*67e74705SXin Li return msAsmStmt->getInputExpr(i);
367*67e74705SXin Li llvm_unreachable("unknown asm statement kind!");
368*67e74705SXin Li }
369*67e74705SXin Li
getClobber(unsigned i) const370*67e74705SXin Li StringRef AsmStmt::getClobber(unsigned i) const {
371*67e74705SXin Li if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
372*67e74705SXin Li return gccAsmStmt->getClobber(i);
373*67e74705SXin Li if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
374*67e74705SXin Li return msAsmStmt->getClobber(i);
375*67e74705SXin Li llvm_unreachable("unknown asm statement kind!");
376*67e74705SXin Li }
377*67e74705SXin Li
378*67e74705SXin Li /// getNumPlusOperands - Return the number of output operands that have a "+"
379*67e74705SXin Li /// constraint.
getNumPlusOperands() const380*67e74705SXin Li unsigned AsmStmt::getNumPlusOperands() const {
381*67e74705SXin Li unsigned Res = 0;
382*67e74705SXin Li for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
383*67e74705SXin Li if (isOutputPlusConstraint(i))
384*67e74705SXin Li ++Res;
385*67e74705SXin Li return Res;
386*67e74705SXin Li }
387*67e74705SXin Li
getModifier() const388*67e74705SXin Li char GCCAsmStmt::AsmStringPiece::getModifier() const {
389*67e74705SXin Li assert(isOperand() && "Only Operands can have modifiers.");
390*67e74705SXin Li return isLetter(Str[0]) ? Str[0] : '\0';
391*67e74705SXin Li }
392*67e74705SXin Li
getClobber(unsigned i) const393*67e74705SXin Li StringRef GCCAsmStmt::getClobber(unsigned i) const {
394*67e74705SXin Li return getClobberStringLiteral(i)->getString();
395*67e74705SXin Li }
396*67e74705SXin Li
getOutputExpr(unsigned i)397*67e74705SXin Li Expr *GCCAsmStmt::getOutputExpr(unsigned i) {
398*67e74705SXin Li return cast<Expr>(Exprs[i]);
399*67e74705SXin Li }
400*67e74705SXin Li
401*67e74705SXin Li /// getOutputConstraint - Return the constraint string for the specified
402*67e74705SXin Li /// output operand. All output constraints are known to be non-empty (either
403*67e74705SXin Li /// '=' or '+').
getOutputConstraint(unsigned i) const404*67e74705SXin Li StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {
405*67e74705SXin Li return getOutputConstraintLiteral(i)->getString();
406*67e74705SXin Li }
407*67e74705SXin Li
getInputExpr(unsigned i)408*67e74705SXin Li Expr *GCCAsmStmt::getInputExpr(unsigned i) {
409*67e74705SXin Li return cast<Expr>(Exprs[i + NumOutputs]);
410*67e74705SXin Li }
setInputExpr(unsigned i,Expr * E)411*67e74705SXin Li void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {
412*67e74705SXin Li Exprs[i + NumOutputs] = E;
413*67e74705SXin Li }
414*67e74705SXin Li
415*67e74705SXin Li /// getInputConstraint - Return the specified input constraint. Unlike output
416*67e74705SXin Li /// constraints, these can be empty.
getInputConstraint(unsigned i) const417*67e74705SXin Li StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
418*67e74705SXin Li return getInputConstraintLiteral(i)->getString();
419*67e74705SXin Li }
420*67e74705SXin Li
setOutputsAndInputsAndClobbers(const ASTContext & C,IdentifierInfo ** Names,StringLiteral ** Constraints,Stmt ** Exprs,unsigned NumOutputs,unsigned NumInputs,StringLiteral ** Clobbers,unsigned NumClobbers)421*67e74705SXin Li void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
422*67e74705SXin Li IdentifierInfo **Names,
423*67e74705SXin Li StringLiteral **Constraints,
424*67e74705SXin Li Stmt **Exprs,
425*67e74705SXin Li unsigned NumOutputs,
426*67e74705SXin Li unsigned NumInputs,
427*67e74705SXin Li StringLiteral **Clobbers,
428*67e74705SXin Li unsigned NumClobbers) {
429*67e74705SXin Li this->NumOutputs = NumOutputs;
430*67e74705SXin Li this->NumInputs = NumInputs;
431*67e74705SXin Li this->NumClobbers = NumClobbers;
432*67e74705SXin Li
433*67e74705SXin Li unsigned NumExprs = NumOutputs + NumInputs;
434*67e74705SXin Li
435*67e74705SXin Li C.Deallocate(this->Names);
436*67e74705SXin Li this->Names = new (C) IdentifierInfo*[NumExprs];
437*67e74705SXin Li std::copy(Names, Names + NumExprs, this->Names);
438*67e74705SXin Li
439*67e74705SXin Li C.Deallocate(this->Exprs);
440*67e74705SXin Li this->Exprs = new (C) Stmt*[NumExprs];
441*67e74705SXin Li std::copy(Exprs, Exprs + NumExprs, this->Exprs);
442*67e74705SXin Li
443*67e74705SXin Li C.Deallocate(this->Constraints);
444*67e74705SXin Li this->Constraints = new (C) StringLiteral*[NumExprs];
445*67e74705SXin Li std::copy(Constraints, Constraints + NumExprs, this->Constraints);
446*67e74705SXin Li
447*67e74705SXin Li C.Deallocate(this->Clobbers);
448*67e74705SXin Li this->Clobbers = new (C) StringLiteral*[NumClobbers];
449*67e74705SXin Li std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
450*67e74705SXin Li }
451*67e74705SXin Li
452*67e74705SXin Li /// getNamedOperand - Given a symbolic operand reference like %[foo],
453*67e74705SXin Li /// translate this into a numeric value needed to reference the same operand.
454*67e74705SXin Li /// This returns -1 if the operand name is invalid.
getNamedOperand(StringRef SymbolicName) const455*67e74705SXin Li int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
456*67e74705SXin Li unsigned NumPlusOperands = 0;
457*67e74705SXin Li
458*67e74705SXin Li // Check if this is an output operand.
459*67e74705SXin Li for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
460*67e74705SXin Li if (getOutputName(i) == SymbolicName)
461*67e74705SXin Li return i;
462*67e74705SXin Li }
463*67e74705SXin Li
464*67e74705SXin Li for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
465*67e74705SXin Li if (getInputName(i) == SymbolicName)
466*67e74705SXin Li return getNumOutputs() + NumPlusOperands + i;
467*67e74705SXin Li
468*67e74705SXin Li // Not found.
469*67e74705SXin Li return -1;
470*67e74705SXin Li }
471*67e74705SXin Li
472*67e74705SXin Li /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
473*67e74705SXin Li /// it into pieces. If the asm string is erroneous, emit errors and return
474*67e74705SXin Li /// true, otherwise return false.
AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> & Pieces,const ASTContext & C,unsigned & DiagOffs) const475*67e74705SXin Li unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
476*67e74705SXin Li const ASTContext &C, unsigned &DiagOffs) const {
477*67e74705SXin Li StringRef Str = getAsmString()->getString();
478*67e74705SXin Li const char *StrStart = Str.begin();
479*67e74705SXin Li const char *StrEnd = Str.end();
480*67e74705SXin Li const char *CurPtr = StrStart;
481*67e74705SXin Li
482*67e74705SXin Li // "Simple" inline asms have no constraints or operands, just convert the asm
483*67e74705SXin Li // string to escape $'s.
484*67e74705SXin Li if (isSimple()) {
485*67e74705SXin Li std::string Result;
486*67e74705SXin Li for (; CurPtr != StrEnd; ++CurPtr) {
487*67e74705SXin Li switch (*CurPtr) {
488*67e74705SXin Li case '$':
489*67e74705SXin Li Result += "$$";
490*67e74705SXin Li break;
491*67e74705SXin Li default:
492*67e74705SXin Li Result += *CurPtr;
493*67e74705SXin Li break;
494*67e74705SXin Li }
495*67e74705SXin Li }
496*67e74705SXin Li Pieces.push_back(AsmStringPiece(Result));
497*67e74705SXin Li return 0;
498*67e74705SXin Li }
499*67e74705SXin Li
500*67e74705SXin Li // CurStringPiece - The current string that we are building up as we scan the
501*67e74705SXin Li // asm string.
502*67e74705SXin Li std::string CurStringPiece;
503*67e74705SXin Li
504*67e74705SXin Li bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
505*67e74705SXin Li
506*67e74705SXin Li unsigned LastAsmStringToken = 0;
507*67e74705SXin Li unsigned LastAsmStringOffset = 0;
508*67e74705SXin Li
509*67e74705SXin Li while (1) {
510*67e74705SXin Li // Done with the string?
511*67e74705SXin Li if (CurPtr == StrEnd) {
512*67e74705SXin Li if (!CurStringPiece.empty())
513*67e74705SXin Li Pieces.push_back(AsmStringPiece(CurStringPiece));
514*67e74705SXin Li return 0;
515*67e74705SXin Li }
516*67e74705SXin Li
517*67e74705SXin Li char CurChar = *CurPtr++;
518*67e74705SXin Li switch (CurChar) {
519*67e74705SXin Li case '$': CurStringPiece += "$$"; continue;
520*67e74705SXin Li case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
521*67e74705SXin Li case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
522*67e74705SXin Li case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
523*67e74705SXin Li case '%':
524*67e74705SXin Li break;
525*67e74705SXin Li default:
526*67e74705SXin Li CurStringPiece += CurChar;
527*67e74705SXin Li continue;
528*67e74705SXin Li }
529*67e74705SXin Li
530*67e74705SXin Li // Escaped "%" character in asm string.
531*67e74705SXin Li if (CurPtr == StrEnd) {
532*67e74705SXin Li // % at end of string is invalid (no escape).
533*67e74705SXin Li DiagOffs = CurPtr-StrStart-1;
534*67e74705SXin Li return diag::err_asm_invalid_escape;
535*67e74705SXin Li }
536*67e74705SXin Li
537*67e74705SXin Li char EscapedChar = *CurPtr++;
538*67e74705SXin Li if (EscapedChar == '%') { // %% -> %
539*67e74705SXin Li // Escaped percentage sign.
540*67e74705SXin Li CurStringPiece += '%';
541*67e74705SXin Li continue;
542*67e74705SXin Li }
543*67e74705SXin Li
544*67e74705SXin Li if (EscapedChar == '=') { // %= -> Generate an unique ID.
545*67e74705SXin Li CurStringPiece += "${:uid}";
546*67e74705SXin Li continue;
547*67e74705SXin Li }
548*67e74705SXin Li
549*67e74705SXin Li // Otherwise, we have an operand. If we have accumulated a string so far,
550*67e74705SXin Li // add it to the Pieces list.
551*67e74705SXin Li if (!CurStringPiece.empty()) {
552*67e74705SXin Li Pieces.push_back(AsmStringPiece(CurStringPiece));
553*67e74705SXin Li CurStringPiece.clear();
554*67e74705SXin Li }
555*67e74705SXin Li
556*67e74705SXin Li // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
557*67e74705SXin Li // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
558*67e74705SXin Li
559*67e74705SXin Li const char *Begin = CurPtr - 1; // Points to the character following '%'.
560*67e74705SXin Li const char *Percent = Begin - 1; // Points to '%'.
561*67e74705SXin Li
562*67e74705SXin Li if (isLetter(EscapedChar)) {
563*67e74705SXin Li if (CurPtr == StrEnd) { // Premature end.
564*67e74705SXin Li DiagOffs = CurPtr-StrStart-1;
565*67e74705SXin Li return diag::err_asm_invalid_escape;
566*67e74705SXin Li }
567*67e74705SXin Li EscapedChar = *CurPtr++;
568*67e74705SXin Li }
569*67e74705SXin Li
570*67e74705SXin Li const TargetInfo &TI = C.getTargetInfo();
571*67e74705SXin Li const SourceManager &SM = C.getSourceManager();
572*67e74705SXin Li const LangOptions &LO = C.getLangOpts();
573*67e74705SXin Li
574*67e74705SXin Li // Handle operands that don't have asmSymbolicName (e.g., %x4).
575*67e74705SXin Li if (isDigit(EscapedChar)) {
576*67e74705SXin Li // %n - Assembler operand n
577*67e74705SXin Li unsigned N = 0;
578*67e74705SXin Li
579*67e74705SXin Li --CurPtr;
580*67e74705SXin Li while (CurPtr != StrEnd && isDigit(*CurPtr))
581*67e74705SXin Li N = N*10 + ((*CurPtr++)-'0');
582*67e74705SXin Li
583*67e74705SXin Li unsigned NumOperands =
584*67e74705SXin Li getNumOutputs() + getNumPlusOperands() + getNumInputs();
585*67e74705SXin Li if (N >= NumOperands) {
586*67e74705SXin Li DiagOffs = CurPtr-StrStart-1;
587*67e74705SXin Li return diag::err_asm_invalid_operand_number;
588*67e74705SXin Li }
589*67e74705SXin Li
590*67e74705SXin Li // Str contains "x4" (Operand without the leading %).
591*67e74705SXin Li std::string Str(Begin, CurPtr - Begin);
592*67e74705SXin Li
593*67e74705SXin Li // (BeginLoc, EndLoc) represents the range of the operand we are currently
594*67e74705SXin Li // processing. Unlike Str, the range includes the leading '%'.
595*67e74705SXin Li SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
596*67e74705SXin Li Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
597*67e74705SXin Li &LastAsmStringOffset);
598*67e74705SXin Li SourceLocation EndLoc = getAsmString()->getLocationOfByte(
599*67e74705SXin Li CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
600*67e74705SXin Li &LastAsmStringOffset);
601*67e74705SXin Li
602*67e74705SXin Li Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
603*67e74705SXin Li continue;
604*67e74705SXin Li }
605*67e74705SXin Li
606*67e74705SXin Li // Handle operands that have asmSymbolicName (e.g., %x[foo]).
607*67e74705SXin Li if (EscapedChar == '[') {
608*67e74705SXin Li DiagOffs = CurPtr-StrStart-1;
609*67e74705SXin Li
610*67e74705SXin Li // Find the ']'.
611*67e74705SXin Li const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
612*67e74705SXin Li if (NameEnd == nullptr)
613*67e74705SXin Li return diag::err_asm_unterminated_symbolic_operand_name;
614*67e74705SXin Li if (NameEnd == CurPtr)
615*67e74705SXin Li return diag::err_asm_empty_symbolic_operand_name;
616*67e74705SXin Li
617*67e74705SXin Li StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
618*67e74705SXin Li
619*67e74705SXin Li int N = getNamedOperand(SymbolicName);
620*67e74705SXin Li if (N == -1) {
621*67e74705SXin Li // Verify that an operand with that name exists.
622*67e74705SXin Li DiagOffs = CurPtr-StrStart;
623*67e74705SXin Li return diag::err_asm_unknown_symbolic_operand_name;
624*67e74705SXin Li }
625*67e74705SXin Li
626*67e74705SXin Li // Str contains "x[foo]" (Operand without the leading %).
627*67e74705SXin Li std::string Str(Begin, NameEnd + 1 - Begin);
628*67e74705SXin Li
629*67e74705SXin Li // (BeginLoc, EndLoc) represents the range of the operand we are currently
630*67e74705SXin Li // processing. Unlike Str, the range includes the leading '%'.
631*67e74705SXin Li SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
632*67e74705SXin Li Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
633*67e74705SXin Li &LastAsmStringOffset);
634*67e74705SXin Li SourceLocation EndLoc = getAsmString()->getLocationOfByte(
635*67e74705SXin Li NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
636*67e74705SXin Li &LastAsmStringOffset);
637*67e74705SXin Li
638*67e74705SXin Li Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
639*67e74705SXin Li
640*67e74705SXin Li CurPtr = NameEnd+1;
641*67e74705SXin Li continue;
642*67e74705SXin Li }
643*67e74705SXin Li
644*67e74705SXin Li DiagOffs = CurPtr-StrStart-1;
645*67e74705SXin Li return diag::err_asm_invalid_escape;
646*67e74705SXin Li }
647*67e74705SXin Li }
648*67e74705SXin Li
649*67e74705SXin Li /// Assemble final IR asm string (GCC-style).
generateAsmString(const ASTContext & C) const650*67e74705SXin Li std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
651*67e74705SXin Li // Analyze the asm string to decompose it into its pieces. We know that Sema
652*67e74705SXin Li // has already done this, so it is guaranteed to be successful.
653*67e74705SXin Li SmallVector<GCCAsmStmt::AsmStringPiece, 4> Pieces;
654*67e74705SXin Li unsigned DiagOffs;
655*67e74705SXin Li AnalyzeAsmString(Pieces, C, DiagOffs);
656*67e74705SXin Li
657*67e74705SXin Li std::string AsmString;
658*67e74705SXin Li for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
659*67e74705SXin Li if (Pieces[i].isString())
660*67e74705SXin Li AsmString += Pieces[i].getString();
661*67e74705SXin Li else if (Pieces[i].getModifier() == '\0')
662*67e74705SXin Li AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo());
663*67e74705SXin Li else
664*67e74705SXin Li AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' +
665*67e74705SXin Li Pieces[i].getModifier() + '}';
666*67e74705SXin Li }
667*67e74705SXin Li return AsmString;
668*67e74705SXin Li }
669*67e74705SXin Li
670*67e74705SXin Li /// Assemble final IR asm string (MS-style).
generateAsmString(const ASTContext & C) const671*67e74705SXin Li std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
672*67e74705SXin Li // FIXME: This needs to be translated into the IR string representation.
673*67e74705SXin Li return AsmStr;
674*67e74705SXin Li }
675*67e74705SXin Li
getOutputExpr(unsigned i)676*67e74705SXin Li Expr *MSAsmStmt::getOutputExpr(unsigned i) {
677*67e74705SXin Li return cast<Expr>(Exprs[i]);
678*67e74705SXin Li }
679*67e74705SXin Li
getInputExpr(unsigned i)680*67e74705SXin Li Expr *MSAsmStmt::getInputExpr(unsigned i) {
681*67e74705SXin Li return cast<Expr>(Exprs[i + NumOutputs]);
682*67e74705SXin Li }
setInputExpr(unsigned i,Expr * E)683*67e74705SXin Li void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
684*67e74705SXin Li Exprs[i + NumOutputs] = E;
685*67e74705SXin Li }
686*67e74705SXin Li
687*67e74705SXin Li //===----------------------------------------------------------------------===//
688*67e74705SXin Li // Constructors
689*67e74705SXin Li //===----------------------------------------------------------------------===//
690*67e74705SXin Li
GCCAsmStmt(const ASTContext & C,SourceLocation asmloc,bool issimple,bool isvolatile,unsigned numoutputs,unsigned numinputs,IdentifierInfo ** names,StringLiteral ** constraints,Expr ** exprs,StringLiteral * asmstr,unsigned numclobbers,StringLiteral ** clobbers,SourceLocation rparenloc)691*67e74705SXin Li GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
692*67e74705SXin Li bool issimple, bool isvolatile, unsigned numoutputs,
693*67e74705SXin Li unsigned numinputs, IdentifierInfo **names,
694*67e74705SXin Li StringLiteral **constraints, Expr **exprs,
695*67e74705SXin Li StringLiteral *asmstr, unsigned numclobbers,
696*67e74705SXin Li StringLiteral **clobbers, SourceLocation rparenloc)
697*67e74705SXin Li : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
698*67e74705SXin Li numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
699*67e74705SXin Li
700*67e74705SXin Li unsigned NumExprs = NumOutputs + NumInputs;
701*67e74705SXin Li
702*67e74705SXin Li Names = new (C) IdentifierInfo*[NumExprs];
703*67e74705SXin Li std::copy(names, names + NumExprs, Names);
704*67e74705SXin Li
705*67e74705SXin Li Exprs = new (C) Stmt*[NumExprs];
706*67e74705SXin Li std::copy(exprs, exprs + NumExprs, Exprs);
707*67e74705SXin Li
708*67e74705SXin Li Constraints = new (C) StringLiteral*[NumExprs];
709*67e74705SXin Li std::copy(constraints, constraints + NumExprs, Constraints);
710*67e74705SXin Li
711*67e74705SXin Li Clobbers = new (C) StringLiteral*[NumClobbers];
712*67e74705SXin Li std::copy(clobbers, clobbers + NumClobbers, Clobbers);
713*67e74705SXin Li }
714*67e74705SXin Li
MSAsmStmt(const ASTContext & C,SourceLocation asmloc,SourceLocation lbraceloc,bool issimple,bool isvolatile,ArrayRef<Token> asmtoks,unsigned numoutputs,unsigned numinputs,ArrayRef<StringRef> constraints,ArrayRef<Expr * > exprs,StringRef asmstr,ArrayRef<StringRef> clobbers,SourceLocation endloc)715*67e74705SXin Li MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
716*67e74705SXin Li SourceLocation lbraceloc, bool issimple, bool isvolatile,
717*67e74705SXin Li ArrayRef<Token> asmtoks, unsigned numoutputs,
718*67e74705SXin Li unsigned numinputs,
719*67e74705SXin Li ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
720*67e74705SXin Li StringRef asmstr, ArrayRef<StringRef> clobbers,
721*67e74705SXin Li SourceLocation endloc)
722*67e74705SXin Li : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
723*67e74705SXin Li numinputs, clobbers.size()), LBraceLoc(lbraceloc),
724*67e74705SXin Li EndLoc(endloc), NumAsmToks(asmtoks.size()) {
725*67e74705SXin Li
726*67e74705SXin Li initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
727*67e74705SXin Li }
728*67e74705SXin Li
copyIntoContext(const ASTContext & C,StringRef str)729*67e74705SXin Li static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
730*67e74705SXin Li return str.copy(C);
731*67e74705SXin Li }
732*67e74705SXin Li
initialize(const ASTContext & C,StringRef asmstr,ArrayRef<Token> asmtoks,ArrayRef<StringRef> constraints,ArrayRef<Expr * > exprs,ArrayRef<StringRef> clobbers)733*67e74705SXin Li void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
734*67e74705SXin Li ArrayRef<Token> asmtoks,
735*67e74705SXin Li ArrayRef<StringRef> constraints,
736*67e74705SXin Li ArrayRef<Expr*> exprs,
737*67e74705SXin Li ArrayRef<StringRef> clobbers) {
738*67e74705SXin Li assert(NumAsmToks == asmtoks.size());
739*67e74705SXin Li assert(NumClobbers == clobbers.size());
740*67e74705SXin Li
741*67e74705SXin Li assert(exprs.size() == NumOutputs + NumInputs);
742*67e74705SXin Li assert(exprs.size() == constraints.size());
743*67e74705SXin Li
744*67e74705SXin Li AsmStr = copyIntoContext(C, asmstr);
745*67e74705SXin Li
746*67e74705SXin Li Exprs = new (C) Stmt*[exprs.size()];
747*67e74705SXin Li std::copy(exprs.begin(), exprs.end(), Exprs);
748*67e74705SXin Li
749*67e74705SXin Li AsmToks = new (C) Token[asmtoks.size()];
750*67e74705SXin Li std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
751*67e74705SXin Li
752*67e74705SXin Li Constraints = new (C) StringRef[exprs.size()];
753*67e74705SXin Li std::transform(constraints.begin(), constraints.end(), Constraints,
754*67e74705SXin Li [&](StringRef Constraint) {
755*67e74705SXin Li return copyIntoContext(C, Constraint);
756*67e74705SXin Li });
757*67e74705SXin Li
758*67e74705SXin Li Clobbers = new (C) StringRef[NumClobbers];
759*67e74705SXin Li // FIXME: Avoid the allocation/copy if at all possible.
760*67e74705SXin Li std::transform(clobbers.begin(), clobbers.end(), Clobbers,
761*67e74705SXin Li [&](StringRef Clobber) {
762*67e74705SXin Li return copyIntoContext(C, Clobber);
763*67e74705SXin Li });
764*67e74705SXin Li }
765*67e74705SXin Li
IfStmt(const ASTContext & C,SourceLocation IL,bool IsConstexpr,Stmt * init,VarDecl * var,Expr * cond,Stmt * then,SourceLocation EL,Stmt * elsev)766*67e74705SXin Li IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, bool IsConstexpr,
767*67e74705SXin Li Stmt *init, VarDecl *var, Expr *cond, Stmt *then,
768*67e74705SXin Li SourceLocation EL, Stmt *elsev)
769*67e74705SXin Li : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) {
770*67e74705SXin Li setConstexpr(IsConstexpr);
771*67e74705SXin Li setConditionVariable(C, var);
772*67e74705SXin Li SubExprs[INIT] = init;
773*67e74705SXin Li SubExprs[COND] = cond;
774*67e74705SXin Li SubExprs[THEN] = then;
775*67e74705SXin Li SubExprs[ELSE] = elsev;
776*67e74705SXin Li }
777*67e74705SXin Li
getConditionVariable() const778*67e74705SXin Li VarDecl *IfStmt::getConditionVariable() const {
779*67e74705SXin Li if (!SubExprs[VAR])
780*67e74705SXin Li return nullptr;
781*67e74705SXin Li
782*67e74705SXin Li DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
783*67e74705SXin Li return cast<VarDecl>(DS->getSingleDecl());
784*67e74705SXin Li }
785*67e74705SXin Li
setConditionVariable(const ASTContext & C,VarDecl * V)786*67e74705SXin Li void IfStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
787*67e74705SXin Li if (!V) {
788*67e74705SXin Li SubExprs[VAR] = nullptr;
789*67e74705SXin Li return;
790*67e74705SXin Li }
791*67e74705SXin Li
792*67e74705SXin Li SourceRange VarRange = V->getSourceRange();
793*67e74705SXin Li SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
794*67e74705SXin Li VarRange.getEnd());
795*67e74705SXin Li }
796*67e74705SXin Li
ForStmt(const ASTContext & C,Stmt * Init,Expr * Cond,VarDecl * condVar,Expr * Inc,Stmt * Body,SourceLocation FL,SourceLocation LP,SourceLocation RP)797*67e74705SXin Li ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
798*67e74705SXin Li Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
799*67e74705SXin Li SourceLocation RP)
800*67e74705SXin Li : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
801*67e74705SXin Li {
802*67e74705SXin Li SubExprs[INIT] = Init;
803*67e74705SXin Li setConditionVariable(C, condVar);
804*67e74705SXin Li SubExprs[COND] = Cond;
805*67e74705SXin Li SubExprs[INC] = Inc;
806*67e74705SXin Li SubExprs[BODY] = Body;
807*67e74705SXin Li }
808*67e74705SXin Li
getConditionVariable() const809*67e74705SXin Li VarDecl *ForStmt::getConditionVariable() const {
810*67e74705SXin Li if (!SubExprs[CONDVAR])
811*67e74705SXin Li return nullptr;
812*67e74705SXin Li
813*67e74705SXin Li DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
814*67e74705SXin Li return cast<VarDecl>(DS->getSingleDecl());
815*67e74705SXin Li }
816*67e74705SXin Li
setConditionVariable(const ASTContext & C,VarDecl * V)817*67e74705SXin Li void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
818*67e74705SXin Li if (!V) {
819*67e74705SXin Li SubExprs[CONDVAR] = nullptr;
820*67e74705SXin Li return;
821*67e74705SXin Li }
822*67e74705SXin Li
823*67e74705SXin Li SourceRange VarRange = V->getSourceRange();
824*67e74705SXin Li SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
825*67e74705SXin Li VarRange.getEnd());
826*67e74705SXin Li }
827*67e74705SXin Li
SwitchStmt(const ASTContext & C,Stmt * init,VarDecl * Var,Expr * cond)828*67e74705SXin Li SwitchStmt::SwitchStmt(const ASTContext &C, Stmt *init, VarDecl *Var,
829*67e74705SXin Li Expr *cond)
830*67e74705SXin Li : Stmt(SwitchStmtClass), FirstCase(nullptr, false) {
831*67e74705SXin Li setConditionVariable(C, Var);
832*67e74705SXin Li SubExprs[INIT] = init;
833*67e74705SXin Li SubExprs[COND] = cond;
834*67e74705SXin Li SubExprs[BODY] = nullptr;
835*67e74705SXin Li }
836*67e74705SXin Li
getConditionVariable() const837*67e74705SXin Li VarDecl *SwitchStmt::getConditionVariable() const {
838*67e74705SXin Li if (!SubExprs[VAR])
839*67e74705SXin Li return nullptr;
840*67e74705SXin Li
841*67e74705SXin Li DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
842*67e74705SXin Li return cast<VarDecl>(DS->getSingleDecl());
843*67e74705SXin Li }
844*67e74705SXin Li
setConditionVariable(const ASTContext & C,VarDecl * V)845*67e74705SXin Li void SwitchStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
846*67e74705SXin Li if (!V) {
847*67e74705SXin Li SubExprs[VAR] = nullptr;
848*67e74705SXin Li return;
849*67e74705SXin Li }
850*67e74705SXin Li
851*67e74705SXin Li SourceRange VarRange = V->getSourceRange();
852*67e74705SXin Li SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
853*67e74705SXin Li VarRange.getEnd());
854*67e74705SXin Li }
855*67e74705SXin Li
getSubStmt()856*67e74705SXin Li Stmt *SwitchCase::getSubStmt() {
857*67e74705SXin Li if (isa<CaseStmt>(this))
858*67e74705SXin Li return cast<CaseStmt>(this)->getSubStmt();
859*67e74705SXin Li return cast<DefaultStmt>(this)->getSubStmt();
860*67e74705SXin Li }
861*67e74705SXin Li
WhileStmt(const ASTContext & C,VarDecl * Var,Expr * cond,Stmt * body,SourceLocation WL)862*67e74705SXin Li WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
863*67e74705SXin Li SourceLocation WL)
864*67e74705SXin Li : Stmt(WhileStmtClass) {
865*67e74705SXin Li setConditionVariable(C, Var);
866*67e74705SXin Li SubExprs[COND] = cond;
867*67e74705SXin Li SubExprs[BODY] = body;
868*67e74705SXin Li WhileLoc = WL;
869*67e74705SXin Li }
870*67e74705SXin Li
getConditionVariable() const871*67e74705SXin Li VarDecl *WhileStmt::getConditionVariable() const {
872*67e74705SXin Li if (!SubExprs[VAR])
873*67e74705SXin Li return nullptr;
874*67e74705SXin Li
875*67e74705SXin Li DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
876*67e74705SXin Li return cast<VarDecl>(DS->getSingleDecl());
877*67e74705SXin Li }
878*67e74705SXin Li
setConditionVariable(const ASTContext & C,VarDecl * V)879*67e74705SXin Li void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
880*67e74705SXin Li if (!V) {
881*67e74705SXin Li SubExprs[VAR] = nullptr;
882*67e74705SXin Li return;
883*67e74705SXin Li }
884*67e74705SXin Li
885*67e74705SXin Li SourceRange VarRange = V->getSourceRange();
886*67e74705SXin Li SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
887*67e74705SXin Li VarRange.getEnd());
888*67e74705SXin Li }
889*67e74705SXin Li
890*67e74705SXin Li // IndirectGotoStmt
getConstantTarget()891*67e74705SXin Li LabelDecl *IndirectGotoStmt::getConstantTarget() {
892*67e74705SXin Li if (AddrLabelExpr *E =
893*67e74705SXin Li dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
894*67e74705SXin Li return E->getLabel();
895*67e74705SXin Li return nullptr;
896*67e74705SXin Li }
897*67e74705SXin Li
898*67e74705SXin Li // ReturnStmt
getRetValue() const899*67e74705SXin Li const Expr* ReturnStmt::getRetValue() const {
900*67e74705SXin Li return cast_or_null<Expr>(RetExpr);
901*67e74705SXin Li }
getRetValue()902*67e74705SXin Li Expr* ReturnStmt::getRetValue() {
903*67e74705SXin Li return cast_or_null<Expr>(RetExpr);
904*67e74705SXin Li }
905*67e74705SXin Li
SEHTryStmt(bool IsCXXTry,SourceLocation TryLoc,Stmt * TryBlock,Stmt * Handler)906*67e74705SXin Li SEHTryStmt::SEHTryStmt(bool IsCXXTry,
907*67e74705SXin Li SourceLocation TryLoc,
908*67e74705SXin Li Stmt *TryBlock,
909*67e74705SXin Li Stmt *Handler)
910*67e74705SXin Li : Stmt(SEHTryStmtClass),
911*67e74705SXin Li IsCXXTry(IsCXXTry),
912*67e74705SXin Li TryLoc(TryLoc)
913*67e74705SXin Li {
914*67e74705SXin Li Children[TRY] = TryBlock;
915*67e74705SXin Li Children[HANDLER] = Handler;
916*67e74705SXin Li }
917*67e74705SXin Li
Create(const ASTContext & C,bool IsCXXTry,SourceLocation TryLoc,Stmt * TryBlock,Stmt * Handler)918*67e74705SXin Li SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
919*67e74705SXin Li SourceLocation TryLoc, Stmt *TryBlock,
920*67e74705SXin Li Stmt *Handler) {
921*67e74705SXin Li return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
922*67e74705SXin Li }
923*67e74705SXin Li
getExceptHandler() const924*67e74705SXin Li SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
925*67e74705SXin Li return dyn_cast<SEHExceptStmt>(getHandler());
926*67e74705SXin Li }
927*67e74705SXin Li
getFinallyHandler() const928*67e74705SXin Li SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
929*67e74705SXin Li return dyn_cast<SEHFinallyStmt>(getHandler());
930*67e74705SXin Li }
931*67e74705SXin Li
SEHExceptStmt(SourceLocation Loc,Expr * FilterExpr,Stmt * Block)932*67e74705SXin Li SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
933*67e74705SXin Li Expr *FilterExpr,
934*67e74705SXin Li Stmt *Block)
935*67e74705SXin Li : Stmt(SEHExceptStmtClass),
936*67e74705SXin Li Loc(Loc)
937*67e74705SXin Li {
938*67e74705SXin Li Children[FILTER_EXPR] = FilterExpr;
939*67e74705SXin Li Children[BLOCK] = Block;
940*67e74705SXin Li }
941*67e74705SXin Li
Create(const ASTContext & C,SourceLocation Loc,Expr * FilterExpr,Stmt * Block)942*67e74705SXin Li SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc,
943*67e74705SXin Li Expr *FilterExpr, Stmt *Block) {
944*67e74705SXin Li return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
945*67e74705SXin Li }
946*67e74705SXin Li
SEHFinallyStmt(SourceLocation Loc,Stmt * Block)947*67e74705SXin Li SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
948*67e74705SXin Li Stmt *Block)
949*67e74705SXin Li : Stmt(SEHFinallyStmtClass),
950*67e74705SXin Li Loc(Loc),
951*67e74705SXin Li Block(Block)
952*67e74705SXin Li {}
953*67e74705SXin Li
Create(const ASTContext & C,SourceLocation Loc,Stmt * Block)954*67e74705SXin Li SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
955*67e74705SXin Li Stmt *Block) {
956*67e74705SXin Li return new(C)SEHFinallyStmt(Loc,Block);
957*67e74705SXin Li }
958*67e74705SXin Li
Capture(SourceLocation Loc,VariableCaptureKind Kind,VarDecl * Var)959*67e74705SXin Li CapturedStmt::Capture::Capture(SourceLocation Loc, VariableCaptureKind Kind,
960*67e74705SXin Li VarDecl *Var)
961*67e74705SXin Li : VarAndKind(Var, Kind), Loc(Loc) {
962*67e74705SXin Li switch (Kind) {
963*67e74705SXin Li case VCK_This:
964*67e74705SXin Li assert(!Var && "'this' capture cannot have a variable!");
965*67e74705SXin Li break;
966*67e74705SXin Li case VCK_ByRef:
967*67e74705SXin Li assert(Var && "capturing by reference must have a variable!");
968*67e74705SXin Li break;
969*67e74705SXin Li case VCK_ByCopy:
970*67e74705SXin Li assert(Var && "capturing by copy must have a variable!");
971*67e74705SXin Li assert(
972*67e74705SXin Li (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
973*67e74705SXin Li Var->getType()
974*67e74705SXin Li ->castAs<ReferenceType>()
975*67e74705SXin Li ->getPointeeType()
976*67e74705SXin Li ->isScalarType())) &&
977*67e74705SXin Li "captures by copy are expected to have a scalar type!");
978*67e74705SXin Li break;
979*67e74705SXin Li case VCK_VLAType:
980*67e74705SXin Li assert(!Var &&
981*67e74705SXin Li "Variable-length array type capture cannot have a variable!");
982*67e74705SXin Li break;
983*67e74705SXin Li }
984*67e74705SXin Li }
985*67e74705SXin Li
986*67e74705SXin Li CapturedStmt::VariableCaptureKind
getCaptureKind() const987*67e74705SXin Li CapturedStmt::Capture::getCaptureKind() const {
988*67e74705SXin Li return VarAndKind.getInt();
989*67e74705SXin Li }
990*67e74705SXin Li
getCapturedVar() const991*67e74705SXin Li VarDecl *CapturedStmt::Capture::getCapturedVar() const {
992*67e74705SXin Li assert((capturesVariable() || capturesVariableByCopy()) &&
993*67e74705SXin Li "No variable available for 'this' or VAT capture");
994*67e74705SXin Li return VarAndKind.getPointer();
995*67e74705SXin Li }
996*67e74705SXin Li
getStoredCaptures() const997*67e74705SXin Li CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
998*67e74705SXin Li unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
999*67e74705SXin Li
1000*67e74705SXin Li // Offset of the first Capture object.
1001*67e74705SXin Li unsigned FirstCaptureOffset = llvm::alignTo(Size, llvm::alignOf<Capture>());
1002*67e74705SXin Li
1003*67e74705SXin Li return reinterpret_cast<Capture *>(
1004*67e74705SXin Li reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1005*67e74705SXin Li + FirstCaptureOffset);
1006*67e74705SXin Li }
1007*67e74705SXin Li
CapturedStmt(Stmt * S,CapturedRegionKind Kind,ArrayRef<Capture> Captures,ArrayRef<Expr * > CaptureInits,CapturedDecl * CD,RecordDecl * RD)1008*67e74705SXin Li CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1009*67e74705SXin Li ArrayRef<Capture> Captures,
1010*67e74705SXin Li ArrayRef<Expr *> CaptureInits,
1011*67e74705SXin Li CapturedDecl *CD,
1012*67e74705SXin Li RecordDecl *RD)
1013*67e74705SXin Li : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1014*67e74705SXin Li CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
1015*67e74705SXin Li assert( S && "null captured statement");
1016*67e74705SXin Li assert(CD && "null captured declaration for captured statement");
1017*67e74705SXin Li assert(RD && "null record declaration for captured statement");
1018*67e74705SXin Li
1019*67e74705SXin Li // Copy initialization expressions.
1020*67e74705SXin Li Stmt **Stored = getStoredStmts();
1021*67e74705SXin Li for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1022*67e74705SXin Li *Stored++ = CaptureInits[I];
1023*67e74705SXin Li
1024*67e74705SXin Li // Copy the statement being captured.
1025*67e74705SXin Li *Stored = S;
1026*67e74705SXin Li
1027*67e74705SXin Li // Copy all Capture objects.
1028*67e74705SXin Li Capture *Buffer = getStoredCaptures();
1029*67e74705SXin Li std::copy(Captures.begin(), Captures.end(), Buffer);
1030*67e74705SXin Li }
1031*67e74705SXin Li
CapturedStmt(EmptyShell Empty,unsigned NumCaptures)1032*67e74705SXin Li CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1033*67e74705SXin Li : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1034*67e74705SXin Li CapDeclAndKind(nullptr, CR_Default), TheRecordDecl(nullptr) {
1035*67e74705SXin Li getStoredStmts()[NumCaptures] = nullptr;
1036*67e74705SXin Li }
1037*67e74705SXin Li
Create(const ASTContext & Context,Stmt * S,CapturedRegionKind Kind,ArrayRef<Capture> Captures,ArrayRef<Expr * > CaptureInits,CapturedDecl * CD,RecordDecl * RD)1038*67e74705SXin Li CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
1039*67e74705SXin Li CapturedRegionKind Kind,
1040*67e74705SXin Li ArrayRef<Capture> Captures,
1041*67e74705SXin Li ArrayRef<Expr *> CaptureInits,
1042*67e74705SXin Li CapturedDecl *CD,
1043*67e74705SXin Li RecordDecl *RD) {
1044*67e74705SXin Li // The layout is
1045*67e74705SXin Li //
1046*67e74705SXin Li // -----------------------------------------------------------
1047*67e74705SXin Li // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1048*67e74705SXin Li // ----------------^-------------------^----------------------
1049*67e74705SXin Li // getStoredStmts() getStoredCaptures()
1050*67e74705SXin Li //
1051*67e74705SXin Li // where S is the statement being captured.
1052*67e74705SXin Li //
1053*67e74705SXin Li assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1054*67e74705SXin Li
1055*67e74705SXin Li unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1056*67e74705SXin Li if (!Captures.empty()) {
1057*67e74705SXin Li // Realign for the following Capture array.
1058*67e74705SXin Li Size = llvm::alignTo(Size, llvm::alignOf<Capture>());
1059*67e74705SXin Li Size += sizeof(Capture) * Captures.size();
1060*67e74705SXin Li }
1061*67e74705SXin Li
1062*67e74705SXin Li void *Mem = Context.Allocate(Size);
1063*67e74705SXin Li return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1064*67e74705SXin Li }
1065*67e74705SXin Li
CreateDeserialized(const ASTContext & Context,unsigned NumCaptures)1066*67e74705SXin Li CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context,
1067*67e74705SXin Li unsigned NumCaptures) {
1068*67e74705SXin Li unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1069*67e74705SXin Li if (NumCaptures > 0) {
1070*67e74705SXin Li // Realign for the following Capture array.
1071*67e74705SXin Li Size = llvm::alignTo(Size, llvm::alignOf<Capture>());
1072*67e74705SXin Li Size += sizeof(Capture) * NumCaptures;
1073*67e74705SXin Li }
1074*67e74705SXin Li
1075*67e74705SXin Li void *Mem = Context.Allocate(Size);
1076*67e74705SXin Li return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1077*67e74705SXin Li }
1078*67e74705SXin Li
children()1079*67e74705SXin Li Stmt::child_range CapturedStmt::children() {
1080*67e74705SXin Li // Children are captured field initilizers.
1081*67e74705SXin Li return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1082*67e74705SXin Li }
1083*67e74705SXin Li
getCapturedDecl()1084*67e74705SXin Li CapturedDecl *CapturedStmt::getCapturedDecl() {
1085*67e74705SXin Li return CapDeclAndKind.getPointer();
1086*67e74705SXin Li }
getCapturedDecl() const1087*67e74705SXin Li const CapturedDecl *CapturedStmt::getCapturedDecl() const {
1088*67e74705SXin Li return CapDeclAndKind.getPointer();
1089*67e74705SXin Li }
1090*67e74705SXin Li
1091*67e74705SXin Li /// \brief Set the outlined function declaration.
setCapturedDecl(CapturedDecl * D)1092*67e74705SXin Li void CapturedStmt::setCapturedDecl(CapturedDecl *D) {
1093*67e74705SXin Li assert(D && "null CapturedDecl");
1094*67e74705SXin Li CapDeclAndKind.setPointer(D);
1095*67e74705SXin Li }
1096*67e74705SXin Li
1097*67e74705SXin Li /// \brief Retrieve the captured region kind.
getCapturedRegionKind() const1098*67e74705SXin Li CapturedRegionKind CapturedStmt::getCapturedRegionKind() const {
1099*67e74705SXin Li return CapDeclAndKind.getInt();
1100*67e74705SXin Li }
1101*67e74705SXin Li
1102*67e74705SXin Li /// \brief Set the captured region kind.
setCapturedRegionKind(CapturedRegionKind Kind)1103*67e74705SXin Li void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {
1104*67e74705SXin Li CapDeclAndKind.setInt(Kind);
1105*67e74705SXin Li }
1106*67e74705SXin Li
capturesVariable(const VarDecl * Var) const1107*67e74705SXin Li bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
1108*67e74705SXin Li for (const auto &I : captures()) {
1109*67e74705SXin Li if (!I.capturesVariable())
1110*67e74705SXin Li continue;
1111*67e74705SXin Li
1112*67e74705SXin Li // This does not handle variable redeclarations. This should be
1113*67e74705SXin Li // extended to capture variables with redeclarations, for example
1114*67e74705SXin Li // a thread-private variable in OpenMP.
1115*67e74705SXin Li if (I.getCapturedVar() == Var)
1116*67e74705SXin Li return true;
1117*67e74705SXin Li }
1118*67e74705SXin Li
1119*67e74705SXin Li return false;
1120*67e74705SXin Li }
1121