xref: /aosp_15_r20/external/clang/lib/AST/Stmt.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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