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