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