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 
448  return cast<AddrLabelExpr>(Exprs[i + NumInputs]);
449 }
450 
451 StringRef GCCAsmStmt::getLabelName(unsigned i) const {
452  return getLabelExpr(i)->getLabel()->getName();
453 }
454 
455 /// getInputConstraint - Return the specified input constraint. Unlike output
456 /// constraints, these can be empty.
457 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
458  return getInputConstraintLiteral(i)->getString();
459 }
460 
461 void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
462  IdentifierInfo **Names,
463  StringLiteral **Constraints,
464  Stmt **Exprs,
465  unsigned NumOutputs,
466  unsigned NumInputs,
467  unsigned NumLabels,
468  StringLiteral **Clobbers,
469  unsigned NumClobbers) {
470  this->NumOutputs = NumOutputs;
471  this->NumInputs = NumInputs;
472  this->NumClobbers = NumClobbers;
473  this->NumLabels = NumLabels;
474  assert(!(NumOutputs && NumLabels) && "asm goto cannot have outputs");
475 
476  unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
477 
478  C.Deallocate(this->Names);
479  this->Names = new (C) IdentifierInfo*[NumExprs];
480  std::copy(Names, Names + NumExprs, this->Names);
481 
482  C.Deallocate(this->Exprs);
483  this->Exprs = new (C) Stmt*[NumExprs];
484  std::copy(Exprs, Exprs + NumExprs, this->Exprs);
485 
486  unsigned NumConstraints = NumOutputs + NumInputs;
487  C.Deallocate(this->Constraints);
488  this->Constraints = new (C) StringLiteral*[NumConstraints];
489  std::copy(Constraints, Constraints + NumConstraints, this->Constraints);
490 
491  C.Deallocate(this->Clobbers);
492  this->Clobbers = new (C) StringLiteral*[NumClobbers];
493  std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
494 }
495 
496 /// getNamedOperand - Given a symbolic operand reference like %[foo],
497 /// translate this into a numeric value needed to reference the same operand.
498 /// This returns -1 if the operand name is invalid.
499 int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
500  unsigned NumPlusOperands = 0;
501 
502  // Check if this is an output operand.
503  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
504  if (getOutputName(i) == SymbolicName)
505  return i;
506  }
507 
508  for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
509  if (getInputName(i) == SymbolicName)
510  return getNumOutputs() + NumPlusOperands + i;
511 
512  for (unsigned i = 0, e = getNumLabels(); i != e; ++i)
513  if (getLabelName(i) == SymbolicName)
514  return i + getNumInputs();
515 
516  // Not found.
517  return -1;
518 }
519 
520 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
521 /// it into pieces. If the asm string is erroneous, emit errors and return
522 /// true, otherwise return false.
524  const ASTContext &C, unsigned &DiagOffs) const {
525  StringRef Str = getAsmString()->getString();
526  const char *StrStart = Str.begin();
527  const char *StrEnd = Str.end();
528  const char *CurPtr = StrStart;
529 
530  // "Simple" inline asms have no constraints or operands, just convert the asm
531  // string to escape $'s.
532  if (isSimple()) {
533  std::string Result;
534  for (; CurPtr != StrEnd; ++CurPtr) {
535  switch (*CurPtr) {
536  case '$':
537  Result += "$$";
538  break;
539  default:
540  Result += *CurPtr;
541  break;
542  }
543  }
544  Pieces.push_back(AsmStringPiece(Result));
545  return 0;
546  }
547 
548  // CurStringPiece - The current string that we are building up as we scan the
549  // asm string.
550  std::string CurStringPiece;
551 
552  bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
553 
554  unsigned LastAsmStringToken = 0;
555  unsigned LastAsmStringOffset = 0;
556 
557  while (true) {
558  // Done with the string?
559  if (CurPtr == StrEnd) {
560  if (!CurStringPiece.empty())
561  Pieces.push_back(AsmStringPiece(CurStringPiece));
562  return 0;
563  }
564 
565  char CurChar = *CurPtr++;
566  switch (CurChar) {
567  case '$': CurStringPiece += "$$"; continue;
568  case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
569  case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
570  case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
571  case '%':
572  break;
573  default:
574  CurStringPiece += CurChar;
575  continue;
576  }
577 
578  // Escaped "%" character in asm string.
579  if (CurPtr == StrEnd) {
580  // % at end of string is invalid (no escape).
581  DiagOffs = CurPtr-StrStart-1;
582  return diag::err_asm_invalid_escape;
583  }
584  // Handle escaped char and continue looping over the asm string.
585  char EscapedChar = *CurPtr++;
586  switch (EscapedChar) {
587  default:
588  break;
589  case '%': // %% -> %
590  case '{': // %{ -> {
591  case '}': // %} -> }
592  CurStringPiece += EscapedChar;
593  continue;
594  case '=': // %= -> Generate a unique ID.
595  CurStringPiece += "${:uid}";
596  continue;
597  }
598 
599  // Otherwise, we have an operand. If we have accumulated a string so far,
600  // add it to the Pieces list.
601  if (!CurStringPiece.empty()) {
602  Pieces.push_back(AsmStringPiece(CurStringPiece));
603  CurStringPiece.clear();
604  }
605 
606  // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
607  // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
608 
609  const char *Begin = CurPtr - 1; // Points to the character following '%'.
610  const char *Percent = Begin - 1; // Points to '%'.
611 
612  if (isLetter(EscapedChar)) {
613  if (CurPtr == StrEnd) { // Premature end.
614  DiagOffs = CurPtr-StrStart-1;
615  return diag::err_asm_invalid_escape;
616  }
617  EscapedChar = *CurPtr++;
618  }
619 
620  const TargetInfo &TI = C.getTargetInfo();
621  const SourceManager &SM = C.getSourceManager();
622  const LangOptions &LO = C.getLangOpts();
623 
624  // Handle operands that don't have asmSymbolicName (e.g., %x4).
625  if (isDigit(EscapedChar)) {
626  // %n - Assembler operand n
627  unsigned N = 0;
628 
629  --CurPtr;
630  while (CurPtr != StrEnd && isDigit(*CurPtr))
631  N = N*10 + ((*CurPtr++)-'0');
632 
633  unsigned NumOperands = getNumOutputs() + getNumPlusOperands() +
634  getNumInputs() + getNumLabels();
635  if (N >= NumOperands) {
636  DiagOffs = CurPtr-StrStart-1;
637  return diag::err_asm_invalid_operand_number;
638  }
639 
640  // Str contains "x4" (Operand without the leading %).
641  std::string Str(Begin, CurPtr - Begin);
642 
643  // (BeginLoc, EndLoc) represents the range of the operand we are currently
644  // processing. Unlike Str, the range includes the leading '%'.
645  SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
646  Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
647  &LastAsmStringOffset);
648  SourceLocation EndLoc = getAsmString()->getLocationOfByte(
649  CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
650  &LastAsmStringOffset);
651 
652  Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
653  continue;
654  }
655 
656  // Handle operands that have asmSymbolicName (e.g., %x[foo]).
657  if (EscapedChar == '[') {
658  DiagOffs = CurPtr-StrStart-1;
659 
660  // Find the ']'.
661  const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
662  if (NameEnd == nullptr)
663  return diag::err_asm_unterminated_symbolic_operand_name;
664  if (NameEnd == CurPtr)
665  return diag::err_asm_empty_symbolic_operand_name;
666 
667  StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
668 
669  int N = getNamedOperand(SymbolicName);
670  if (N == -1) {
671  // Verify that an operand with that name exists.
672  DiagOffs = CurPtr-StrStart;
673  return diag::err_asm_unknown_symbolic_operand_name;
674  }
675 
676  // Str contains "x[foo]" (Operand without the leading %).
677  std::string Str(Begin, NameEnd + 1 - Begin);
678 
679  // (BeginLoc, EndLoc) represents the range of the operand we are currently
680  // processing. Unlike Str, the range includes the leading '%'.
681  SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
682  Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
683  &LastAsmStringOffset);
684  SourceLocation EndLoc = getAsmString()->getLocationOfByte(
685  NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
686  &LastAsmStringOffset);
687 
688  Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
689 
690  CurPtr = NameEnd+1;
691  continue;
692  }
693 
694  DiagOffs = CurPtr-StrStart-1;
695  return diag::err_asm_invalid_escape;
696  }
697 }
698 
699 /// Assemble final IR asm string (GCC-style).
700 std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
701  // Analyze the asm string to decompose it into its pieces. We know that Sema
702  // has already done this, so it is guaranteed to be successful.
704  unsigned DiagOffs;
705  AnalyzeAsmString(Pieces, C, DiagOffs);
706 
707  std::string AsmString;
708  for (const auto &Piece : Pieces) {
709  if (Piece.isString())
710  AsmString += Piece.getString();
711  else if (Piece.getModifier() == '\0')
712  AsmString += '$' + llvm::utostr(Piece.getOperandNo());
713  else
714  AsmString += "${" + llvm::utostr(Piece.getOperandNo()) + ':' +
715  Piece.getModifier() + '}';
716  }
717  return AsmString;
718 }
719 
720 /// Assemble final IR asm string (MS-style).
721 std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
722  // FIXME: This needs to be translated into the IR string representation.
723  return AsmStr;
724 }
725 
727  return cast<Expr>(Exprs[i]);
728 }
729 
731  return cast<Expr>(Exprs[i + NumOutputs]);
732 }
733 
734 void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
735  Exprs[i + NumOutputs] = E;
736 }
737 
738 //===----------------------------------------------------------------------===//
739 // Constructors
740 //===----------------------------------------------------------------------===//
741 
743  bool issimple, bool isvolatile, unsigned numoutputs,
744  unsigned numinputs, IdentifierInfo **names,
745  StringLiteral **constraints, Expr **exprs,
746  StringLiteral *asmstr, unsigned numclobbers,
747  StringLiteral **clobbers, unsigned numlabels,
748  SourceLocation rparenloc)
749  : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
750  numinputs, numclobbers),
751  RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
752  unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
753 
754  Names = new (C) IdentifierInfo*[NumExprs];
755  std::copy(names, names + NumExprs, Names);
756 
757  Exprs = new (C) Stmt*[NumExprs];
758  std::copy(exprs, exprs + NumExprs, Exprs);
759 
760  unsigned NumConstraints = NumOutputs + NumInputs;
761  Constraints = new (C) StringLiteral*[NumConstraints];
762  std::copy(constraints, constraints + NumConstraints, Constraints);
763 
764  Clobbers = new (C) StringLiteral*[NumClobbers];
765  std::copy(clobbers, clobbers + NumClobbers, Clobbers);
766 }
767 
769  SourceLocation lbraceloc, bool issimple, bool isvolatile,
770  ArrayRef<Token> asmtoks, unsigned numoutputs,
771  unsigned numinputs,
772  ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
773  StringRef asmstr, ArrayRef<StringRef> clobbers,
774  SourceLocation endloc)
775  : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
776  numinputs, clobbers.size()), LBraceLoc(lbraceloc),
777  EndLoc(endloc), NumAsmToks(asmtoks.size()) {
778  initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
779 }
780 
781 static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
782  return str.copy(C);
783 }
784 
785 void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
786  ArrayRef<Token> asmtoks,
787  ArrayRef<StringRef> constraints,
788  ArrayRef<Expr*> exprs,
789  ArrayRef<StringRef> clobbers) {
790  assert(NumAsmToks == asmtoks.size());
791  assert(NumClobbers == clobbers.size());
792 
793  assert(exprs.size() == NumOutputs + NumInputs);
794  assert(exprs.size() == constraints.size());
795 
796  AsmStr = copyIntoContext(C, asmstr);
797 
798  Exprs = new (C) Stmt*[exprs.size()];
799  std::copy(exprs.begin(), exprs.end(), Exprs);
800 
801  AsmToks = new (C) Token[asmtoks.size()];
802  std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
803 
804  Constraints = new (C) StringRef[exprs.size()];
805  std::transform(constraints.begin(), constraints.end(), Constraints,
806  [&](StringRef Constraint) {
807  return copyIntoContext(C, Constraint);
808  });
809 
810  Clobbers = new (C) StringRef[NumClobbers];
811  // FIXME: Avoid the allocation/copy if at all possible.
812  std::transform(clobbers.begin(), clobbers.end(), Clobbers,
813  [&](StringRef Clobber) {
814  return copyIntoContext(C, Clobber);
815  });
816 }
817 
818 IfStmt::IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr,
819  Stmt *Init, VarDecl *Var, Expr *Cond, Stmt *Then,
820  SourceLocation EL, Stmt *Else)
821  : Stmt(IfStmtClass) {
822  bool HasElse = Else != nullptr;
823  bool HasVar = Var != nullptr;
824  bool HasInit = Init != nullptr;
825  IfStmtBits.HasElse = HasElse;
826  IfStmtBits.HasVar = HasVar;
827  IfStmtBits.HasInit = HasInit;
828 
829  setConstexpr(IsConstexpr);
830 
831  setCond(Cond);
832  setThen(Then);
833  if (HasElse)
834  setElse(Else);
835  if (HasVar)
836  setConditionVariable(Ctx, Var);
837  if (HasInit)
838  setInit(Init);
839 
840  setIfLoc(IL);
841  if (HasElse)
842  setElseLoc(EL);
843 }
844 
845 IfStmt::IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit)
846  : Stmt(IfStmtClass, Empty) {
847  IfStmtBits.HasElse = HasElse;
848  IfStmtBits.HasVar = HasVar;
849  IfStmtBits.HasInit = HasInit;
850 }
851 
853  bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
854  Stmt *Then, SourceLocation EL, Stmt *Else) {
855  bool HasElse = Else != nullptr;
856  bool HasVar = Var != nullptr;
857  bool HasInit = Init != nullptr;
858  void *Mem = Ctx.Allocate(
859  totalSizeToAlloc<Stmt *, SourceLocation>(
860  NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
861  alignof(IfStmt));
862  return new (Mem)
863  IfStmt(Ctx, IL, IsConstexpr, Init, Var, Cond, Then, EL, Else);
864 }
865 
866 IfStmt *IfStmt::CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
867  bool HasInit) {
868  void *Mem = Ctx.Allocate(
869  totalSizeToAlloc<Stmt *, SourceLocation>(
870  NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
871  alignof(IfStmt));
872  return new (Mem) IfStmt(EmptyShell(), HasElse, HasVar, HasInit);
873 }
874 
876  auto *DS = getConditionVariableDeclStmt();
877  if (!DS)
878  return nullptr;
879  return cast<VarDecl>(DS->getSingleDecl());
880 }
881 
883  assert(hasVarStorage() &&
884  "This if statement has no storage for a condition variable!");
885 
886  if (!V) {
887  getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
888  return;
889  }
890 
891  SourceRange VarRange = V->getSourceRange();
892  getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
893  DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
894 }
895 
897  return isa<ObjCAvailabilityCheckExpr>(getCond());
898 }
899 
900 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
901  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
902  SourceLocation RP)
903  : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
904 {
905  SubExprs[INIT] = Init;
906  setConditionVariable(C, condVar);
907  SubExprs[COND] = Cond;
908  SubExprs[INC] = Inc;
909  SubExprs[BODY] = Body;
910  ForStmtBits.ForLoc = FL;
911 }
912 
914  if (!SubExprs[CONDVAR])
915  return nullptr;
916 
917  auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
918  return cast<VarDecl>(DS->getSingleDecl());
919 }
920 
922  if (!V) {
923  SubExprs[CONDVAR] = nullptr;
924  return;
925  }
926 
927  SourceRange VarRange = V->getSourceRange();
928  SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
929  VarRange.getEnd());
930 }
931 
932 SwitchStmt::SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
933  Expr *Cond)
934  : Stmt(SwitchStmtClass), FirstCase(nullptr) {
935  bool HasInit = Init != nullptr;
936  bool HasVar = Var != nullptr;
937  SwitchStmtBits.HasInit = HasInit;
938  SwitchStmtBits.HasVar = HasVar;
939  SwitchStmtBits.AllEnumCasesCovered = false;
940 
941  setCond(Cond);
942  setBody(nullptr);
943  if (HasInit)
944  setInit(Init);
945  if (HasVar)
946  setConditionVariable(Ctx, Var);
947 
948  setSwitchLoc(SourceLocation{});
949 }
950 
951 SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)
952  : Stmt(SwitchStmtClass, Empty) {
953  SwitchStmtBits.HasInit = HasInit;
954  SwitchStmtBits.HasVar = HasVar;
955  SwitchStmtBits.AllEnumCasesCovered = false;
956 }
957 
959  Expr *Cond) {
960  bool HasInit = Init != nullptr;
961  bool HasVar = Var != nullptr;
962  void *Mem = Ctx.Allocate(
963  totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
964  alignof(SwitchStmt));
965  return new (Mem) SwitchStmt(Ctx, Init, Var, Cond);
966 }
967 
969  bool HasVar) {
970  void *Mem = Ctx.Allocate(
971  totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
972  alignof(SwitchStmt));
973  return new (Mem) SwitchStmt(EmptyShell(), HasInit, HasVar);
974 }
975 
977  auto *DS = getConditionVariableDeclStmt();
978  if (!DS)
979  return nullptr;
980  return cast<VarDecl>(DS->getSingleDecl());
981 }
982 
984  assert(hasVarStorage() &&
985  "This switch statement has no storage for a condition variable!");
986 
987  if (!V) {
988  getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
989  return;
990  }
991 
992  SourceRange VarRange = V->getSourceRange();
993  getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
994  DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
995 }
996 
997 WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
998  Stmt *Body, SourceLocation WL)
999  : Stmt(WhileStmtClass) {
1000  bool HasVar = Var != nullptr;
1001  WhileStmtBits.HasVar = HasVar;
1002 
1003  setCond(Cond);
1004  setBody(Body);
1005  if (HasVar)
1006  setConditionVariable(Ctx, Var);
1007 
1008  setWhileLoc(WL);
1009 }
1010 
1011 WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
1012  : Stmt(WhileStmtClass, Empty) {
1013  WhileStmtBits.HasVar = HasVar;
1014 }
1015 
1017  Stmt *Body, SourceLocation WL) {
1018  bool HasVar = Var != nullptr;
1019  void *Mem =
1020  Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1021  alignof(WhileStmt));
1022  return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL);
1023 }
1024 
1025 WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {
1026  void *Mem =
1027  Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1028  alignof(WhileStmt));
1029  return new (Mem) WhileStmt(EmptyShell(), HasVar);
1030 }
1031 
1033  auto *DS = getConditionVariableDeclStmt();
1034  if (!DS)
1035  return nullptr;
1036  return cast<VarDecl>(DS->getSingleDecl());
1037 }
1038 
1040  assert(hasVarStorage() &&
1041  "This while statement has no storage for a condition variable!");
1042 
1043  if (!V) {
1044  getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
1045  return;
1046  }
1047 
1048  SourceRange VarRange = V->getSourceRange();
1049  getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
1050  DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
1051 }
1052 
1053 // IndirectGotoStmt
1055  if (auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
1056  return E->getLabel();
1057  return nullptr;
1058 }
1059 
1060 // ReturnStmt
1061 ReturnStmt::ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1062  : Stmt(ReturnStmtClass), RetExpr(E) {
1063  bool HasNRVOCandidate = NRVOCandidate != nullptr;
1064  ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1065  if (HasNRVOCandidate)
1066  setNRVOCandidate(NRVOCandidate);
1067  setReturnLoc(RL);
1068 }
1069 
1070 ReturnStmt::ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate)
1071  : Stmt(ReturnStmtClass, Empty) {
1072  ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1073 }
1074 
1076  Expr *E, const VarDecl *NRVOCandidate) {
1077  bool HasNRVOCandidate = NRVOCandidate != nullptr;
1078  void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1079  alignof(ReturnStmt));
1080  return new (Mem) ReturnStmt(RL, E, NRVOCandidate);
1081 }
1082 
1084  bool HasNRVOCandidate) {
1085  void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1086  alignof(ReturnStmt));
1087  return new (Mem) ReturnStmt(EmptyShell(), HasNRVOCandidate);
1088 }
1089 
1090 // CaseStmt
1092  SourceLocation caseLoc, SourceLocation ellipsisLoc,
1093  SourceLocation colonLoc) {
1094  bool CaseStmtIsGNURange = rhs != nullptr;
1095  void *Mem = Ctx.Allocate(
1096  totalSizeToAlloc<Stmt *, SourceLocation>(
1097  NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1098  alignof(CaseStmt));
1099  return new (Mem) CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
1100 }
1101 
1103  bool CaseStmtIsGNURange) {
1104  void *Mem = Ctx.Allocate(
1105  totalSizeToAlloc<Stmt *, SourceLocation>(
1106  NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1107  alignof(CaseStmt));
1108  return new (Mem) CaseStmt(EmptyShell(), CaseStmtIsGNURange);
1109 }
1110 
1111 SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
1112  Stmt *Handler)
1113  : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
1114  Children[TRY] = TryBlock;
1115  Children[HANDLER] = Handler;
1116 }
1117 
1118 SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
1119  SourceLocation TryLoc, Stmt *TryBlock,
1120  Stmt *Handler) {
1121  return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
1122 }
1123 
1125  return dyn_cast<SEHExceptStmt>(getHandler());
1126 }
1127 
1129  return dyn_cast<SEHFinallyStmt>(getHandler());
1130 }
1131 
1132 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
1133  : Stmt(SEHExceptStmtClass), Loc(Loc) {
1134  Children[FILTER_EXPR] = FilterExpr;
1135  Children[BLOCK] = Block;
1136 }
1137 
1139  Expr *FilterExpr, Stmt *Block) {
1140  return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
1141 }
1142 
1143 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
1144  : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
1145 
1147  Stmt *Block) {
1148  return new(C)SEHFinallyStmt(Loc,Block);
1149 }
1150 
1152  VarDecl *Var)
1153  : VarAndKind(Var, Kind), Loc(Loc) {
1154  switch (Kind) {
1155  case VCK_This:
1156  assert(!Var && "'this' capture cannot have a variable!");
1157  break;
1158  case VCK_ByRef:
1159  assert(Var && "capturing by reference must have a variable!");
1160  break;
1161  case VCK_ByCopy:
1162  assert(Var && "capturing by copy must have a variable!");
1163  assert(
1164  (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
1165  Var->getType()
1166  ->castAs<ReferenceType>()
1167  ->getPointeeType()
1168  ->isScalarType())) &&
1169  "captures by copy are expected to have a scalar type!");
1170  break;
1171  case VCK_VLAType:
1172  assert(!Var &&
1173  "Variable-length array type capture cannot have a variable!");
1174  break;
1175  }
1176 }
1177 
1180  return VarAndKind.getInt();
1181 }
1182 
1184  assert((capturesVariable() || capturesVariableByCopy()) &&
1185  "No variable available for 'this' or VAT capture");
1186  return VarAndKind.getPointer();
1187 }
1188 
1189 CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
1190  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1191 
1192  // Offset of the first Capture object.
1193  unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));
1194 
1195  return reinterpret_cast<Capture *>(
1196  reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1197  + FirstCaptureOffset);
1198 }
1199 
1200 CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1201  ArrayRef<Capture> Captures,
1202  ArrayRef<Expr *> CaptureInits,
1203  CapturedDecl *CD,
1204  RecordDecl *RD)
1205  : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1206  CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
1207  assert( S && "null captured statement");
1208  assert(CD && "null captured declaration for captured statement");
1209  assert(RD && "null record declaration for captured statement");
1210 
1211  // Copy initialization expressions.
1212  Stmt **Stored = getStoredStmts();
1213  for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1214  *Stored++ = CaptureInits[I];
1215 
1216  // Copy the statement being captured.
1217  *Stored = S;
1218 
1219  // Copy all Capture objects.
1220  Capture *Buffer = getStoredCaptures();
1221  std::copy(Captures.begin(), Captures.end(), Buffer);
1222 }
1223 
1224 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1225  : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1226  CapDeclAndKind(nullptr, CR_Default) {
1227  getStoredStmts()[NumCaptures] = nullptr;
1228 }
1229 
1232  ArrayRef<Capture> Captures,
1233  ArrayRef<Expr *> CaptureInits,
1234  CapturedDecl *CD,
1235  RecordDecl *RD) {
1236  // The layout is
1237  //
1238  // -----------------------------------------------------------
1239  // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1240  // ----------------^-------------------^----------------------
1241  // getStoredStmts() getStoredCaptures()
1242  //
1243  // where S is the statement being captured.
1244  //
1245  assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1246 
1247  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1248  if (!Captures.empty()) {
1249  // Realign for the following Capture array.
1250  Size = llvm::alignTo(Size, alignof(Capture));
1251  Size += sizeof(Capture) * Captures.size();
1252  }
1253 
1254  void *Mem = Context.Allocate(Size);
1255  return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1256 }
1257 
1259  unsigned NumCaptures) {
1260  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1261  if (NumCaptures > 0) {
1262  // Realign for the following Capture array.
1263  Size = llvm::alignTo(Size, alignof(Capture));
1264  Size += sizeof(Capture) * NumCaptures;
1265  }
1266 
1267  void *Mem = Context.Allocate(Size);
1268  return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1269 }
1270 
1272  // Children are captured field initializers.
1273  return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1274 }
1275 
1277  return const_child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1278 }
1279 
1281  return CapDeclAndKind.getPointer();
1282 }
1283 
1285  return CapDeclAndKind.getPointer();
1286 }
1287 
1288 /// Set the outlined function declaration.
1290  assert(D && "null CapturedDecl");
1291  CapDeclAndKind.setPointer(D);
1292 }
1293 
1294 /// Retrieve the captured region kind.
1296  return CapDeclAndKind.getInt();
1297 }
1298 
1299 /// Set the captured region kind.
1301  CapDeclAndKind.setInt(Kind);
1302 }
1303 
1304 bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
1305  for (const auto &I : captures()) {
1306  if (!I.capturesVariable() && !I.capturesVariableByCopy())
1307  continue;
1308  if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
1309  return true;
1310  }
1311 
1312  return false;
1313 }
static AttributedStmt * CreateEmpty(const ASTContext &C, unsigned NumAttrs)
Definition: Stmt.cpp:353
void setConditionVariable(const ASTContext &C, VarDecl *V)
Definition: Stmt.cpp:921
Defines the clang::ASTContext interface.
Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var=nullptr)
Create a new capture.
Definition: Stmt.cpp:1151
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:2412
Stmt - This represents one statement.
Definition: Stmt.h:66
IfStmt - This represents an if/then/else.
Definition: Stmt.h:1812
const char * Name
Definition: Stmt.cpp:48
VarDecl * getCapturedVar() const
Retrieve the declaration of the variable being captured.
Definition: Stmt.cpp:1183
C Language Family Type Representation.
Represents an attribute applied to a statement.
Definition: Stmt.h:1754
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1158
unsigned NumOutputs
Definition: Stmt.h:2707
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:693
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:1304
void setInputExpr(unsigned i, Expr *E)
Definition: Stmt.cpp:734
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:523
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:499
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.
long i
Definition: xmmintrin.h:1456
static struct StmtClassNameTable StmtClassInfo[Stmt::lastStmtConstant+1]
const char * getStmtClassName() const
Definition: Stmt.cpp:74
Represents a struct/union/class.
Definition: Decl.h:3626
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:6396
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:1289
bool hasNoAsmVariants() const
Return true if {|} are normal characters in the asm string.
Definition: TargetInfo.h:1202
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:949
static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD)
Definition: Stmt.cpp:1230
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:852
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:1091
child_range children()
Definition: Stmt.cpp:212
Expr * getOutputExpr(unsigned i)
Definition: Stmt.cpp:428
SwitchStmtBitfields SwitchStmtBits
Definition: Stmt.h:948
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:1478
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:721
ReturnStmtBitfields ReturnStmtBits
Definition: Stmt.h:955
void setCond(Expr *E)
Definition: Stmt.h:2426
unsigned getNumPlusOperands() const
getNumPlusOperands - Return the number of output operands that have a "+" constraint.
Definition: Stmt.cpp:411
bool isScalarType() const
Definition: Type.h:6732
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4108
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
Definition: Stmt.cpp:913
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:768
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Definition: Stmt.cpp:1118
StringRef getClobber(unsigned i) const
Definition: Stmt.cpp:424
unsigned NumClobbers
Definition: Stmt.h:2709
llvm::iterator_range< const_child_iterator > const_child_range
Definition: Stmt.h:1159
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1310
Describes the capture of either a variable, or &#39;this&#39;, or variable-length array type.
Definition: Stmt.h:3363
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:882
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:6916
static ReturnStmt * CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate)
Create an empty return statement, optionally with storage for an NRVO candidate.
Definition: Stmt.cpp:1083
AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...
Definition: Stmt.h:2887
#define V(N, I)
Definition: ASTContext.h:2907
VariableCaptureKind getCaptureKind() const
Determine the kind of capture.
Definition: Stmt.cpp:1179
LabelDecl * getConstantTarget()
getConstantTarget - Returns the fixed target of this indirect goto, if one exists.
Definition: Stmt.cpp:1054
void setBody(Stmt *S)
Definition: Stmt.h:2428
SourceLocation Begin
child_range children()
Definition: Stmt.cpp:1271
Stmt()=delete
CompoundStmtBitfields CompoundStmtBits
Definition: Stmt.h:944
static StringRef copyIntoContext(const ASTContext &C, StringRef str)
Definition: Stmt.cpp:781
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:2610
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
Definition: Stmt.cpp:457
SourceLocation getEnd() const
Expr * getInputExpr(unsigned i)
Definition: Stmt.cpp:730
Expr * getOutputExpr(unsigned i)
Definition: Stmt.cpp:726
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:1016
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:1039
do v
Definition: arm_acle.h:64
const SourceManager & SM
Definition: Format.cpp:1572
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:1146
AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
Definition: Stmt.h:2693
void setConditionVariable(const ASTContext &Ctx, VarDecl *VD)
Set the condition variable in this switch statement.
Definition: Stmt.cpp:983
static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond)
Create a switch statement.
Definition: Stmt.cpp:958
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:3350
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.
StringRef getLabelName(unsigned i) const
Definition: Stmt.cpp:451
IfStmtBitfields IfStmtBits
Definition: Stmt.h:947
static void PrintStats()
Definition: Stmt.cpp:86
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:700
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:1203
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:3391
ForStmtBitfields ForStmtBits
Definition: Stmt.h:951
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:742
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:1025
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:976
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
Definition: Stmt.h:1034
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:672
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:3878
Dataflow Directional Tag Classes.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Definition: Stmt.cpp:1032
static CapturedStmt * CreateDeserialized(const ASTContext &Context, unsigned NumCaptures)
Definition: Stmt.cpp:1258
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:1075
unsigned Counter
Definition: Stmt.cpp:49
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition: Stmt.cpp:1124
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:896
llvm::BumpPtrAllocator & getAllocator() const
Definition: ASTContext.h:668
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:3394
SwitchStmt - This represents a &#39;switch&#39; stmt.
Definition: Stmt.h:2017
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:447
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2705
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:900
SourceManager & getSourceManager()
Definition: ASTContext.h:665
SEHFinallyStmt * getFinallyHandler() const
Definition: Stmt.cpp:1128
Stmt ** Exprs
Definition: Stmt.h:2711
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1280
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
Definition: Stmt.cpp:875
void Deallocate(void *Ptr) const
Definition: ASTContext.h:678
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:2200
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:866
VariableCaptureKind
The different capture forms: by &#39;this&#39;, by reference, capture for variable-length array type etc...
Definition: Stmt.h:3354
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:1681
Defines the clang::TargetInfo interface.
capture_range captures()
Definition: Stmt.h:3485
static CaseStmt * CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange)
Build an empty case statement.
Definition: Stmt.cpp:1102
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:968
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:2425
unsigned NumInputs
Definition: Stmt.h:2708
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Definition: ASTContext.h:710
static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)
Definition: Stmt.cpp:1138
This class handles loading and caching of source files into memory.
void setCapturedRegionKind(CapturedRegionKind Kind)
Set the captured region kind.
Definition: Stmt.cpp:1300
CapturedRegionKind getCapturedRegionKind() const
Retrieve the captured region kind.
Definition: Stmt.cpp:1295
static void EnableStatistics()
Definition: Stmt.cpp:116
#define BLOCK(DERIVED, BASE)
Definition: Template.h:469