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