xref: /freebsd/contrib/llvm-project/clang/lib/AST/Stmt.cpp (revision 7029da5c36f2d3cf6bb6c81bf551229f416399e8)
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 AddrLabelExpr *GCCAsmStmt::getLabelExpr(unsigned i) const {
448   return cast<AddrLabelExpr>(Exprs[i + NumInputs]);
449 }
450 
451 StringRef GCCAsmStmt::getLabelName(unsigned i) const {
452   return getLabelExpr(i)->getLabel()->getName();
453 }
454 
455 /// getInputConstraint - Return the specified input constraint.  Unlike output
456 /// constraints, these can be empty.
457 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
458   return getInputConstraintLiteral(i)->getString();
459 }
460 
461 void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
462                                                 IdentifierInfo **Names,
463                                                 StringLiteral **Constraints,
464                                                 Stmt **Exprs,
465                                                 unsigned NumOutputs,
466                                                 unsigned NumInputs,
467                                                 unsigned NumLabels,
468                                                 StringLiteral **Clobbers,
469                                                 unsigned NumClobbers) {
470   this->NumOutputs = NumOutputs;
471   this->NumInputs = NumInputs;
472   this->NumClobbers = NumClobbers;
473   this->NumLabels = NumLabels;
474   assert(!(NumOutputs && NumLabels) && "asm goto cannot have outputs");
475 
476   unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
477 
478   C.Deallocate(this->Names);
479   this->Names = new (C) IdentifierInfo*[NumExprs];
480   std::copy(Names, Names + NumExprs, this->Names);
481 
482   C.Deallocate(this->Exprs);
483   this->Exprs = new (C) Stmt*[NumExprs];
484   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
485 
486   unsigned NumConstraints = NumOutputs + NumInputs;
487   C.Deallocate(this->Constraints);
488   this->Constraints = new (C) StringLiteral*[NumConstraints];
489   std::copy(Constraints, Constraints + NumConstraints, this->Constraints);
490 
491   C.Deallocate(this->Clobbers);
492   this->Clobbers = new (C) StringLiteral*[NumClobbers];
493   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
494 }
495 
496 /// getNamedOperand - Given a symbolic operand reference like %[foo],
497 /// translate this into a numeric value needed to reference the same operand.
498 /// This returns -1 if the operand name is invalid.
499 int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
500   unsigned NumPlusOperands = 0;
501 
502   // Check if this is an output operand.
503   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
504     if (getOutputName(i) == SymbolicName)
505       return i;
506   }
507 
508   for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
509     if (getInputName(i) == SymbolicName)
510       return getNumOutputs() + NumPlusOperands + i;
511 
512   for (unsigned i = 0, e = getNumLabels(); i != e; ++i)
513     if (getLabelName(i) == SymbolicName)
514       return i + getNumInputs();
515 
516   // Not found.
517   return -1;
518 }
519 
520 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
521 /// it into pieces.  If the asm string is erroneous, emit errors and return
522 /// true, otherwise return false.
523 unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
524                                 const ASTContext &C, unsigned &DiagOffs) const {
525   StringRef Str = getAsmString()->getString();
526   const char *StrStart = Str.begin();
527   const char *StrEnd = Str.end();
528   const char *CurPtr = StrStart;
529 
530   // "Simple" inline asms have no constraints or operands, just convert the asm
531   // string to escape $'s.
532   if (isSimple()) {
533     std::string Result;
534     for (; CurPtr != StrEnd; ++CurPtr) {
535       switch (*CurPtr) {
536       case '$':
537         Result += "$$";
538         break;
539       default:
540         Result += *CurPtr;
541         break;
542       }
543     }
544     Pieces.push_back(AsmStringPiece(Result));
545     return 0;
546   }
547 
548   // CurStringPiece - The current string that we are building up as we scan the
549   // asm string.
550   std::string CurStringPiece;
551 
552   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
553 
554   unsigned LastAsmStringToken = 0;
555   unsigned LastAsmStringOffset = 0;
556 
557   while (true) {
558     // Done with the string?
559     if (CurPtr == StrEnd) {
560       if (!CurStringPiece.empty())
561         Pieces.push_back(AsmStringPiece(CurStringPiece));
562       return 0;
563     }
564 
565     char CurChar = *CurPtr++;
566     switch (CurChar) {
567     case '$': CurStringPiece += "$$"; continue;
568     case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
569     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
570     case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
571     case '%':
572       break;
573     default:
574       CurStringPiece += CurChar;
575       continue;
576     }
577 
578     // Escaped "%" character in asm string.
579     if (CurPtr == StrEnd) {
580       // % at end of string is invalid (no escape).
581       DiagOffs = CurPtr-StrStart-1;
582       return diag::err_asm_invalid_escape;
583     }
584     // Handle escaped char and continue looping over the asm string.
585     char EscapedChar = *CurPtr++;
586     switch (EscapedChar) {
587     default:
588       break;
589     case '%': // %% -> %
590     case '{': // %{ -> {
591     case '}': // %} -> }
592       CurStringPiece += EscapedChar;
593       continue;
594     case '=': // %= -> Generate a unique ID.
595       CurStringPiece += "${:uid}";
596       continue;
597     }
598 
599     // Otherwise, we have an operand.  If we have accumulated a string so far,
600     // add it to the Pieces list.
601     if (!CurStringPiece.empty()) {
602       Pieces.push_back(AsmStringPiece(CurStringPiece));
603       CurStringPiece.clear();
604     }
605 
606     // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
607     // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
608 
609     const char *Begin = CurPtr - 1; // Points to the character following '%'.
610     const char *Percent = Begin - 1; // Points to '%'.
611 
612     if (isLetter(EscapedChar)) {
613       if (CurPtr == StrEnd) { // Premature end.
614         DiagOffs = CurPtr-StrStart-1;
615         return diag::err_asm_invalid_escape;
616       }
617       EscapedChar = *CurPtr++;
618     }
619 
620     const TargetInfo &TI = C.getTargetInfo();
621     const SourceManager &SM = C.getSourceManager();
622     const LangOptions &LO = C.getLangOpts();
623 
624     // Handle operands that don't have asmSymbolicName (e.g., %x4).
625     if (isDigit(EscapedChar)) {
626       // %n - Assembler operand n
627       unsigned N = 0;
628 
629       --CurPtr;
630       while (CurPtr != StrEnd && isDigit(*CurPtr))
631         N = N*10 + ((*CurPtr++)-'0');
632 
633       unsigned NumOperands = getNumOutputs() + getNumPlusOperands() +
634                              getNumInputs() + getNumLabels();
635       if (N >= NumOperands) {
636         DiagOffs = CurPtr-StrStart-1;
637         return diag::err_asm_invalid_operand_number;
638       }
639 
640       // Str contains "x4" (Operand without the leading %).
641       std::string Str(Begin, CurPtr - Begin);
642 
643       // (BeginLoc, EndLoc) represents the range of the operand we are currently
644       // processing. Unlike Str, the range includes the leading '%'.
645       SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
646           Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
647           &LastAsmStringOffset);
648       SourceLocation EndLoc = getAsmString()->getLocationOfByte(
649           CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
650           &LastAsmStringOffset);
651 
652       Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
653       continue;
654     }
655 
656     // Handle operands that have asmSymbolicName (e.g., %x[foo]).
657     if (EscapedChar == '[') {
658       DiagOffs = CurPtr-StrStart-1;
659 
660       // Find the ']'.
661       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
662       if (NameEnd == nullptr)
663         return diag::err_asm_unterminated_symbolic_operand_name;
664       if (NameEnd == CurPtr)
665         return diag::err_asm_empty_symbolic_operand_name;
666 
667       StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
668 
669       int N = getNamedOperand(SymbolicName);
670       if (N == -1) {
671         // Verify that an operand with that name exists.
672         DiagOffs = CurPtr-StrStart;
673         return diag::err_asm_unknown_symbolic_operand_name;
674       }
675 
676       // Str contains "x[foo]" (Operand without the leading %).
677       std::string Str(Begin, NameEnd + 1 - Begin);
678 
679       // (BeginLoc, EndLoc) represents the range of the operand we are currently
680       // processing. Unlike Str, the range includes the leading '%'.
681       SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
682           Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
683           &LastAsmStringOffset);
684       SourceLocation EndLoc = getAsmString()->getLocationOfByte(
685           NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
686           &LastAsmStringOffset);
687 
688       Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
689 
690       CurPtr = NameEnd+1;
691       continue;
692     }
693 
694     DiagOffs = CurPtr-StrStart-1;
695     return diag::err_asm_invalid_escape;
696   }
697 }
698 
699 /// Assemble final IR asm string (GCC-style).
700 std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
701   // Analyze the asm string to decompose it into its pieces.  We know that Sema
702   // has already done this, so it is guaranteed to be successful.
703   SmallVector<GCCAsmStmt::AsmStringPiece, 4> Pieces;
704   unsigned DiagOffs;
705   AnalyzeAsmString(Pieces, C, DiagOffs);
706 
707   std::string AsmString;
708   for (const auto &Piece : Pieces) {
709     if (Piece.isString())
710       AsmString += Piece.getString();
711     else if (Piece.getModifier() == '\0')
712       AsmString += '$' + llvm::utostr(Piece.getOperandNo());
713     else
714       AsmString += "${" + llvm::utostr(Piece.getOperandNo()) + ':' +
715                    Piece.getModifier() + '}';
716   }
717   return AsmString;
718 }
719 
720 /// Assemble final IR asm string (MS-style).
721 std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
722   // FIXME: This needs to be translated into the IR string representation.
723   return AsmStr;
724 }
725 
726 Expr *MSAsmStmt::getOutputExpr(unsigned i) {
727   return cast<Expr>(Exprs[i]);
728 }
729 
730 Expr *MSAsmStmt::getInputExpr(unsigned i) {
731   return cast<Expr>(Exprs[i + NumOutputs]);
732 }
733 
734 void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
735   Exprs[i + NumOutputs] = E;
736 }
737 
738 //===----------------------------------------------------------------------===//
739 // Constructors
740 //===----------------------------------------------------------------------===//
741 
742 GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
743                        bool issimple, bool isvolatile, unsigned numoutputs,
744                        unsigned numinputs, IdentifierInfo **names,
745                        StringLiteral **constraints, Expr **exprs,
746                        StringLiteral *asmstr, unsigned numclobbers,
747                        StringLiteral **clobbers, unsigned numlabels,
748                        SourceLocation rparenloc)
749     : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
750               numinputs, numclobbers),
751               RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
752   unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
753 
754   Names = new (C) IdentifierInfo*[NumExprs];
755   std::copy(names, names + NumExprs, Names);
756 
757   Exprs = new (C) Stmt*[NumExprs];
758   std::copy(exprs, exprs + NumExprs, Exprs);
759 
760   unsigned NumConstraints = NumOutputs + NumInputs;
761   Constraints = new (C) StringLiteral*[NumConstraints];
762   std::copy(constraints, constraints + NumConstraints, Constraints);
763 
764   Clobbers = new (C) StringLiteral*[NumClobbers];
765   std::copy(clobbers, clobbers + NumClobbers, Clobbers);
766 }
767 
768 MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
769                      SourceLocation lbraceloc, bool issimple, bool isvolatile,
770                      ArrayRef<Token> asmtoks, unsigned numoutputs,
771                      unsigned numinputs,
772                      ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
773                      StringRef asmstr, ArrayRef<StringRef> clobbers,
774                      SourceLocation endloc)
775     : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
776               numinputs, clobbers.size()), LBraceLoc(lbraceloc),
777               EndLoc(endloc), NumAsmToks(asmtoks.size()) {
778   initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
779 }
780 
781 static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
782   return str.copy(C);
783 }
784 
785 void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
786                            ArrayRef<Token> asmtoks,
787                            ArrayRef<StringRef> constraints,
788                            ArrayRef<Expr*> exprs,
789                            ArrayRef<StringRef> clobbers) {
790   assert(NumAsmToks == asmtoks.size());
791   assert(NumClobbers == clobbers.size());
792 
793   assert(exprs.size() == NumOutputs + NumInputs);
794   assert(exprs.size() == constraints.size());
795 
796   AsmStr = copyIntoContext(C, asmstr);
797 
798   Exprs = new (C) Stmt*[exprs.size()];
799   std::copy(exprs.begin(), exprs.end(), Exprs);
800 
801   AsmToks = new (C) Token[asmtoks.size()];
802   std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
803 
804   Constraints = new (C) StringRef[exprs.size()];
805   std::transform(constraints.begin(), constraints.end(), Constraints,
806                  [&](StringRef Constraint) {
807                    return copyIntoContext(C, Constraint);
808                  });
809 
810   Clobbers = new (C) StringRef[NumClobbers];
811   // FIXME: Avoid the allocation/copy if at all possible.
812   std::transform(clobbers.begin(), clobbers.end(), Clobbers,
813                  [&](StringRef Clobber) {
814                    return copyIntoContext(C, Clobber);
815                  });
816 }
817 
818 IfStmt::IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr,
819                Stmt *Init, VarDecl *Var, Expr *Cond, Stmt *Then,
820                SourceLocation EL, Stmt *Else)
821     : Stmt(IfStmtClass) {
822   bool HasElse = Else != nullptr;
823   bool HasVar = Var != nullptr;
824   bool HasInit = Init != nullptr;
825   IfStmtBits.HasElse = HasElse;
826   IfStmtBits.HasVar = HasVar;
827   IfStmtBits.HasInit = HasInit;
828 
829   setConstexpr(IsConstexpr);
830 
831   setCond(Cond);
832   setThen(Then);
833   if (HasElse)
834     setElse(Else);
835   if (HasVar)
836     setConditionVariable(Ctx, Var);
837   if (HasInit)
838     setInit(Init);
839 
840   setIfLoc(IL);
841   if (HasElse)
842     setElseLoc(EL);
843 }
844 
845 IfStmt::IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit)
846     : Stmt(IfStmtClass, Empty) {
847   IfStmtBits.HasElse = HasElse;
848   IfStmtBits.HasVar = HasVar;
849   IfStmtBits.HasInit = HasInit;
850 }
851 
852 IfStmt *IfStmt::Create(const ASTContext &Ctx, SourceLocation IL,
853                        bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
854                        Stmt *Then, SourceLocation EL, Stmt *Else) {
855   bool HasElse = Else != nullptr;
856   bool HasVar = Var != nullptr;
857   bool HasInit = Init != nullptr;
858   void *Mem = Ctx.Allocate(
859       totalSizeToAlloc<Stmt *, SourceLocation>(
860           NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
861       alignof(IfStmt));
862   return new (Mem)
863       IfStmt(Ctx, IL, IsConstexpr, Init, Var, Cond, Then, EL, Else);
864 }
865 
866 IfStmt *IfStmt::CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
867                             bool HasInit) {
868   void *Mem = Ctx.Allocate(
869       totalSizeToAlloc<Stmt *, SourceLocation>(
870           NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
871       alignof(IfStmt));
872   return new (Mem) IfStmt(EmptyShell(), HasElse, HasVar, HasInit);
873 }
874 
875 VarDecl *IfStmt::getConditionVariable() {
876   auto *DS = getConditionVariableDeclStmt();
877   if (!DS)
878     return nullptr;
879   return cast<VarDecl>(DS->getSingleDecl());
880 }
881 
882 void IfStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
883   assert(hasVarStorage() &&
884          "This if statement has no storage for a condition variable!");
885 
886   if (!V) {
887     getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
888     return;
889   }
890 
891   SourceRange VarRange = V->getSourceRange();
892   getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
893       DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
894 }
895 
896 bool IfStmt::isObjCAvailabilityCheck() const {
897   return isa<ObjCAvailabilityCheckExpr>(getCond());
898 }
899 
900 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
901                  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
902                  SourceLocation RP)
903   : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
904 {
905   SubExprs[INIT] = Init;
906   setConditionVariable(C, condVar);
907   SubExprs[COND] = Cond;
908   SubExprs[INC] = Inc;
909   SubExprs[BODY] = Body;
910   ForStmtBits.ForLoc = FL;
911 }
912 
913 VarDecl *ForStmt::getConditionVariable() const {
914   if (!SubExprs[CONDVAR])
915     return nullptr;
916 
917   auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
918   return cast<VarDecl>(DS->getSingleDecl());
919 }
920 
921 void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
922   if (!V) {
923     SubExprs[CONDVAR] = nullptr;
924     return;
925   }
926 
927   SourceRange VarRange = V->getSourceRange();
928   SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
929                                        VarRange.getEnd());
930 }
931 
932 SwitchStmt::SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
933                        Expr *Cond)
934     : Stmt(SwitchStmtClass), FirstCase(nullptr) {
935   bool HasInit = Init != nullptr;
936   bool HasVar = Var != nullptr;
937   SwitchStmtBits.HasInit = HasInit;
938   SwitchStmtBits.HasVar = HasVar;
939   SwitchStmtBits.AllEnumCasesCovered = false;
940 
941   setCond(Cond);
942   setBody(nullptr);
943   if (HasInit)
944     setInit(Init);
945   if (HasVar)
946     setConditionVariable(Ctx, Var);
947 
948   setSwitchLoc(SourceLocation{});
949 }
950 
951 SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)
952     : Stmt(SwitchStmtClass, Empty) {
953   SwitchStmtBits.HasInit = HasInit;
954   SwitchStmtBits.HasVar = HasVar;
955   SwitchStmtBits.AllEnumCasesCovered = false;
956 }
957 
958 SwitchStmt *SwitchStmt::Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
959                                Expr *Cond) {
960   bool HasInit = Init != nullptr;
961   bool HasVar = Var != nullptr;
962   void *Mem = Ctx.Allocate(
963       totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
964       alignof(SwitchStmt));
965   return new (Mem) SwitchStmt(Ctx, Init, Var, Cond);
966 }
967 
968 SwitchStmt *SwitchStmt::CreateEmpty(const ASTContext &Ctx, bool HasInit,
969                                     bool HasVar) {
970   void *Mem = Ctx.Allocate(
971       totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
972       alignof(SwitchStmt));
973   return new (Mem) SwitchStmt(EmptyShell(), HasInit, HasVar);
974 }
975 
976 VarDecl *SwitchStmt::getConditionVariable() {
977   auto *DS = getConditionVariableDeclStmt();
978   if (!DS)
979     return nullptr;
980   return cast<VarDecl>(DS->getSingleDecl());
981 }
982 
983 void SwitchStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
984   assert(hasVarStorage() &&
985          "This switch statement has no storage for a condition variable!");
986 
987   if (!V) {
988     getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
989     return;
990   }
991 
992   SourceRange VarRange = V->getSourceRange();
993   getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
994       DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
995 }
996 
997 WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
998                      Stmt *Body, SourceLocation WL)
999     : Stmt(WhileStmtClass) {
1000   bool HasVar = Var != nullptr;
1001   WhileStmtBits.HasVar = HasVar;
1002 
1003   setCond(Cond);
1004   setBody(Body);
1005   if (HasVar)
1006     setConditionVariable(Ctx, Var);
1007 
1008   setWhileLoc(WL);
1009 }
1010 
1011 WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
1012     : Stmt(WhileStmtClass, Empty) {
1013   WhileStmtBits.HasVar = HasVar;
1014 }
1015 
1016 WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
1017                              Stmt *Body, SourceLocation WL) {
1018   bool HasVar = Var != nullptr;
1019   void *Mem =
1020       Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1021                    alignof(WhileStmt));
1022   return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL);
1023 }
1024 
1025 WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {
1026   void *Mem =
1027       Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1028                    alignof(WhileStmt));
1029   return new (Mem) WhileStmt(EmptyShell(), HasVar);
1030 }
1031 
1032 VarDecl *WhileStmt::getConditionVariable() {
1033   auto *DS = getConditionVariableDeclStmt();
1034   if (!DS)
1035     return nullptr;
1036   return cast<VarDecl>(DS->getSingleDecl());
1037 }
1038 
1039 void WhileStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
1040   assert(hasVarStorage() &&
1041          "This while statement has no storage for a condition variable!");
1042 
1043   if (!V) {
1044     getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
1045     return;
1046   }
1047 
1048   SourceRange VarRange = V->getSourceRange();
1049   getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
1050       DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
1051 }
1052 
1053 // IndirectGotoStmt
1054 LabelDecl *IndirectGotoStmt::getConstantTarget() {
1055   if (auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
1056     return E->getLabel();
1057   return nullptr;
1058 }
1059 
1060 // ReturnStmt
1061 ReturnStmt::ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1062     : Stmt(ReturnStmtClass), RetExpr(E) {
1063   bool HasNRVOCandidate = NRVOCandidate != nullptr;
1064   ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1065   if (HasNRVOCandidate)
1066     setNRVOCandidate(NRVOCandidate);
1067   setReturnLoc(RL);
1068 }
1069 
1070 ReturnStmt::ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate)
1071     : Stmt(ReturnStmtClass, Empty) {
1072   ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1073 }
1074 
1075 ReturnStmt *ReturnStmt::Create(const ASTContext &Ctx, SourceLocation RL,
1076                                Expr *E, const VarDecl *NRVOCandidate) {
1077   bool HasNRVOCandidate = NRVOCandidate != nullptr;
1078   void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1079                            alignof(ReturnStmt));
1080   return new (Mem) ReturnStmt(RL, E, NRVOCandidate);
1081 }
1082 
1083 ReturnStmt *ReturnStmt::CreateEmpty(const ASTContext &Ctx,
1084                                     bool HasNRVOCandidate) {
1085   void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1086                            alignof(ReturnStmt));
1087   return new (Mem) ReturnStmt(EmptyShell(), HasNRVOCandidate);
1088 }
1089 
1090 // CaseStmt
1091 CaseStmt *CaseStmt::Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
1092                            SourceLocation caseLoc, SourceLocation ellipsisLoc,
1093                            SourceLocation colonLoc) {
1094   bool CaseStmtIsGNURange = rhs != nullptr;
1095   void *Mem = Ctx.Allocate(
1096       totalSizeToAlloc<Stmt *, SourceLocation>(
1097           NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1098       alignof(CaseStmt));
1099   return new (Mem) CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
1100 }
1101 
1102 CaseStmt *CaseStmt::CreateEmpty(const ASTContext &Ctx,
1103                                 bool CaseStmtIsGNURange) {
1104   void *Mem = Ctx.Allocate(
1105       totalSizeToAlloc<Stmt *, SourceLocation>(
1106           NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1107       alignof(CaseStmt));
1108   return new (Mem) CaseStmt(EmptyShell(), CaseStmtIsGNURange);
1109 }
1110 
1111 SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
1112                        Stmt *Handler)
1113     : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
1114   Children[TRY]     = TryBlock;
1115   Children[HANDLER] = Handler;
1116 }
1117 
1118 SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
1119                                SourceLocation TryLoc, Stmt *TryBlock,
1120                                Stmt *Handler) {
1121   return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
1122 }
1123 
1124 SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
1125   return dyn_cast<SEHExceptStmt>(getHandler());
1126 }
1127 
1128 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
1129   return dyn_cast<SEHFinallyStmt>(getHandler());
1130 }
1131 
1132 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
1133     : Stmt(SEHExceptStmtClass), Loc(Loc) {
1134   Children[FILTER_EXPR] = FilterExpr;
1135   Children[BLOCK]       = Block;
1136 }
1137 
1138 SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc,
1139                                      Expr *FilterExpr, Stmt *Block) {
1140   return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
1141 }
1142 
1143 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
1144     : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
1145 
1146 SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
1147                                        Stmt *Block) {
1148   return new(C)SEHFinallyStmt(Loc,Block);
1149 }
1150 
1151 CapturedStmt::Capture::Capture(SourceLocation Loc, VariableCaptureKind Kind,
1152                                VarDecl *Var)
1153     : VarAndKind(Var, Kind), Loc(Loc) {
1154   switch (Kind) {
1155   case VCK_This:
1156     assert(!Var && "'this' capture cannot have a variable!");
1157     break;
1158   case VCK_ByRef:
1159     assert(Var && "capturing by reference must have a variable!");
1160     break;
1161   case VCK_ByCopy:
1162     assert(Var && "capturing by copy must have a variable!");
1163     assert(
1164         (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
1165                                             Var->getType()
1166                                                 ->castAs<ReferenceType>()
1167                                                 ->getPointeeType()
1168                                                 ->isScalarType())) &&
1169         "captures by copy are expected to have a scalar type!");
1170     break;
1171   case VCK_VLAType:
1172     assert(!Var &&
1173            "Variable-length array type capture cannot have a variable!");
1174     break;
1175   }
1176 }
1177 
1178 CapturedStmt::VariableCaptureKind
1179 CapturedStmt::Capture::getCaptureKind() const {
1180   return VarAndKind.getInt();
1181 }
1182 
1183 VarDecl *CapturedStmt::Capture::getCapturedVar() const {
1184   assert((capturesVariable() || capturesVariableByCopy()) &&
1185          "No variable available for 'this' or VAT capture");
1186   return VarAndKind.getPointer();
1187 }
1188 
1189 CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
1190   unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1191 
1192   // Offset of the first Capture object.
1193   unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));
1194 
1195   return reinterpret_cast<Capture *>(
1196       reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1197       + FirstCaptureOffset);
1198 }
1199 
1200 CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1201                            ArrayRef<Capture> Captures,
1202                            ArrayRef<Expr *> CaptureInits,
1203                            CapturedDecl *CD,
1204                            RecordDecl *RD)
1205   : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1206     CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
1207   assert( S && "null captured statement");
1208   assert(CD && "null captured declaration for captured statement");
1209   assert(RD && "null record declaration for captured statement");
1210 
1211   // Copy initialization expressions.
1212   Stmt **Stored = getStoredStmts();
1213   for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1214     *Stored++ = CaptureInits[I];
1215 
1216   // Copy the statement being captured.
1217   *Stored = S;
1218 
1219   // Copy all Capture objects.
1220   Capture *Buffer = getStoredCaptures();
1221   std::copy(Captures.begin(), Captures.end(), Buffer);
1222 }
1223 
1224 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1225   : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1226     CapDeclAndKind(nullptr, CR_Default) {
1227   getStoredStmts()[NumCaptures] = nullptr;
1228 }
1229 
1230 CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
1231                                    CapturedRegionKind Kind,
1232                                    ArrayRef<Capture> Captures,
1233                                    ArrayRef<Expr *> CaptureInits,
1234                                    CapturedDecl *CD,
1235                                    RecordDecl *RD) {
1236   // The layout is
1237   //
1238   // -----------------------------------------------------------
1239   // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1240   // ----------------^-------------------^----------------------
1241   //                 getStoredStmts()    getStoredCaptures()
1242   //
1243   // where S is the statement being captured.
1244   //
1245   assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1246 
1247   unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1248   if (!Captures.empty()) {
1249     // Realign for the following Capture array.
1250     Size = llvm::alignTo(Size, alignof(Capture));
1251     Size += sizeof(Capture) * Captures.size();
1252   }
1253 
1254   void *Mem = Context.Allocate(Size);
1255   return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1256 }
1257 
1258 CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context,
1259                                                unsigned NumCaptures) {
1260   unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1261   if (NumCaptures > 0) {
1262     // Realign for the following Capture array.
1263     Size = llvm::alignTo(Size, alignof(Capture));
1264     Size += sizeof(Capture) * NumCaptures;
1265   }
1266 
1267   void *Mem = Context.Allocate(Size);
1268   return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1269 }
1270 
1271 Stmt::child_range CapturedStmt::children() {
1272   // Children are captured field initializers.
1273   return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1274 }
1275 
1276 Stmt::const_child_range CapturedStmt::children() const {
1277   return const_child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1278 }
1279 
1280 CapturedDecl *CapturedStmt::getCapturedDecl() {
1281   return CapDeclAndKind.getPointer();
1282 }
1283 
1284 const CapturedDecl *CapturedStmt::getCapturedDecl() const {
1285   return CapDeclAndKind.getPointer();
1286 }
1287 
1288 /// Set the outlined function declaration.
1289 void CapturedStmt::setCapturedDecl(CapturedDecl *D) {
1290   assert(D && "null CapturedDecl");
1291   CapDeclAndKind.setPointer(D);
1292 }
1293 
1294 /// Retrieve the captured region kind.
1295 CapturedRegionKind CapturedStmt::getCapturedRegionKind() const {
1296   return CapDeclAndKind.getInt();
1297 }
1298 
1299 /// Set the captured region kind.
1300 void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {
1301   CapDeclAndKind.setInt(Kind);
1302 }
1303 
1304 bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
1305   for (const auto &I : captures()) {
1306     if (!I.capturesVariable() && !I.capturesVariableByCopy())
1307       continue;
1308     if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
1309       return true;
1310   }
1311 
1312   return false;
1313 }
1314