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