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