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