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