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