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