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