clang  14.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, SourceLocation LB,
365  SourceLocation RB)
366  : Stmt(CompoundStmtClass), RBraceLoc(RB) {
367  CompoundStmtBits.NumStmts = Stmts.size();
368  setStmts(Stmts);
369  CompoundStmtBits.LBraceLoc = LB;
370 }
371 
372 void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
373  assert(CompoundStmtBits.NumStmts == Stmts.size() &&
374  "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
375 
376  std::copy(Stmts.begin(), Stmts.end(), body_begin());
377 }
378 
381  void *Mem =
382  C.Allocate(totalSizeToAlloc<Stmt *>(Stmts.size()), alignof(CompoundStmt));
383  return new (Mem) CompoundStmt(Stmts, LB, RB);
384 }
385 
387  unsigned NumStmts) {
388  void *Mem =
389  C.Allocate(totalSizeToAlloc<Stmt *>(NumStmts), alignof(CompoundStmt));
390  CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
391  New->CompoundStmtBits.NumStmts = NumStmts;
392  return New;
393 }
394 
395 const Expr *ValueStmt::getExprStmt() const {
396  const Stmt *S = this;
397  do {
398  if (const auto *E = dyn_cast<Expr>(S))
399  return E;
400 
401  if (const auto *LS = dyn_cast<LabelStmt>(S))
402  S = LS->getSubStmt();
403  else if (const auto *AS = dyn_cast<AttributedStmt>(S))
404  S = AS->getSubStmt();
405  else
406  llvm_unreachable("unknown kind of ValueStmt");
407  } while (isa<ValueStmt>(S));
408 
409  return nullptr;
410 }
411 
412 const char *LabelStmt::getName() const {
413  return getDecl()->getIdentifier()->getNameStart();
414 }
415 
417  ArrayRef<const Attr*> Attrs,
418  Stmt *SubStmt) {
419  assert(!Attrs.empty() && "Attrs should not be empty");
420  void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),
421  alignof(AttributedStmt));
422  return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
423 }
424 
426  unsigned NumAttrs) {
427  assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
428  void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),
429  alignof(AttributedStmt));
430  return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
431 }
432 
434  if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
435  return gccAsmStmt->generateAsmString(C);
436  if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
437  return msAsmStmt->generateAsmString(C);
438  llvm_unreachable("unknown asm statement kind!");
439 }
440 
441 StringRef AsmStmt::getOutputConstraint(unsigned i) const {
442  if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
443  return gccAsmStmt->getOutputConstraint(i);
444  if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
445  return msAsmStmt->getOutputConstraint(i);
446  llvm_unreachable("unknown asm statement kind!");
447 }
448 
449 const Expr *AsmStmt::getOutputExpr(unsigned i) const {
450  if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
451  return gccAsmStmt->getOutputExpr(i);
452  if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
453  return msAsmStmt->getOutputExpr(i);
454  llvm_unreachable("unknown asm statement kind!");
455 }
456 
457 StringRef AsmStmt::getInputConstraint(unsigned i) const {
458  if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
459  return gccAsmStmt->getInputConstraint(i);
460  if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
461  return msAsmStmt->getInputConstraint(i);
462  llvm_unreachable("unknown asm statement kind!");
463 }
464 
465 const Expr *AsmStmt::getInputExpr(unsigned i) const {
466  if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
467  return gccAsmStmt->getInputExpr(i);
468  if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
469  return msAsmStmt->getInputExpr(i);
470  llvm_unreachable("unknown asm statement kind!");
471 }
472 
473 StringRef AsmStmt::getClobber(unsigned i) const {
474  if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
475  return gccAsmStmt->getClobber(i);
476  if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
477  return msAsmStmt->getClobber(i);
478  llvm_unreachable("unknown asm statement kind!");
479 }
480 
481 /// getNumPlusOperands - Return the number of output operands that have a "+"
482 /// constraint.
483 unsigned AsmStmt::getNumPlusOperands() const {
484  unsigned Res = 0;
485  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
486  if (isOutputPlusConstraint(i))
487  ++Res;
488  return Res;
489 }
490 
492  assert(isOperand() && "Only Operands can have modifiers.");
493  return isLetter(Str[0]) ? Str[0] : '\0';
494 }
495 
496 StringRef GCCAsmStmt::getClobber(unsigned i) const {
497  return getClobberStringLiteral(i)->getString();
498 }
499 
501  return cast<Expr>(Exprs[i]);
502 }
503 
504 /// getOutputConstraint - Return the constraint string for the specified
505 /// output operand. All output constraints are known to be non-empty (either
506 /// '=' or '+').
507 StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {
509 }
510 
512  return cast<Expr>(Exprs[i + NumOutputs]);
513 }
514 
515 void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {
516  Exprs[i + NumOutputs] = E;
517 }
518 
520  return cast<AddrLabelExpr>(Exprs[i + NumOutputs + NumInputs]);
521 }
522 
523 StringRef GCCAsmStmt::getLabelName(unsigned i) const {
524  return getLabelExpr(i)->getLabel()->getName();
525 }
526 
527 /// getInputConstraint - Return the specified input constraint. Unlike output
528 /// constraints, these can be empty.
529 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
531 }
532 
533 void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
534  IdentifierInfo **Names,
535  StringLiteral **Constraints,
536  Stmt **Exprs,
537  unsigned NumOutputs,
538  unsigned NumInputs,
539  unsigned NumLabels,
540  StringLiteral **Clobbers,
541  unsigned NumClobbers) {
542  this->NumOutputs = NumOutputs;
543  this->NumInputs = NumInputs;
544  this->NumClobbers = NumClobbers;
545  this->NumLabels = NumLabels;
546 
547  unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
548 
549  C.Deallocate(this->Names);
550  this->Names = new (C) IdentifierInfo*[NumExprs];
551  std::copy(Names, Names + NumExprs, this->Names);
552 
553  C.Deallocate(this->Exprs);
554  this->Exprs = new (C) Stmt*[NumExprs];
555  std::copy(Exprs, Exprs + NumExprs, this->Exprs);
556 
557  unsigned NumConstraints = NumOutputs + NumInputs;
558  C.Deallocate(this->Constraints);
559  this->Constraints = new (C) StringLiteral*[NumConstraints];
560  std::copy(Constraints, Constraints + NumConstraints, this->Constraints);
561 
562  C.Deallocate(this->Clobbers);
563  this->Clobbers = new (C) StringLiteral*[NumClobbers];
564  std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
565 }
566 
567 /// getNamedOperand - Given a symbolic operand reference like %[foo],
568 /// translate this into a numeric value needed to reference the same operand.
569 /// This returns -1 if the operand name is invalid.
570 int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
571  // Check if this is an output operand.
572  unsigned NumOutputs = getNumOutputs();
573  for (unsigned i = 0; i != NumOutputs; ++i)
574  if (getOutputName(i) == SymbolicName)
575  return i;
576 
577  unsigned NumInputs = getNumInputs();
578  for (unsigned i = 0; i != NumInputs; ++i)
579  if (getInputName(i) == SymbolicName)
580  return NumOutputs + i;
581 
582  for (unsigned i = 0, e = getNumLabels(); i != e; ++i)
583  if (getLabelName(i) == SymbolicName)
584  return NumOutputs + NumInputs + getNumPlusOperands() + i;
585 
586  // Not found.
587  return -1;
588 }
589 
590 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
591 /// it into pieces. If the asm string is erroneous, emit errors and return
592 /// true, otherwise return false.
594  const ASTContext &C, unsigned &DiagOffs) const {
595  StringRef Str = getAsmString()->getString();
596  const char *StrStart = Str.begin();
597  const char *StrEnd = Str.end();
598  const char *CurPtr = StrStart;
599 
600  // "Simple" inline asms have no constraints or operands, just convert the asm
601  // string to escape $'s.
602  if (isSimple()) {
603  std::string Result;
604  for (; CurPtr != StrEnd; ++CurPtr) {
605  switch (*CurPtr) {
606  case '$':
607  Result += "$$";
608  break;
609  default:
610  Result += *CurPtr;
611  break;
612  }
613  }
614  Pieces.push_back(AsmStringPiece(Result));
615  return 0;
616  }
617 
618  // CurStringPiece - The current string that we are building up as we scan the
619  // asm string.
620  std::string CurStringPiece;
621 
622  bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
623 
624  unsigned LastAsmStringToken = 0;
625  unsigned LastAsmStringOffset = 0;
626 
627  while (true) {
628  // Done with the string?
629  if (CurPtr == StrEnd) {
630  if (!CurStringPiece.empty())
631  Pieces.push_back(AsmStringPiece(CurStringPiece));
632  return 0;
633  }
634 
635  char CurChar = *CurPtr++;
636  switch (CurChar) {
637  case '$': CurStringPiece += "$$"; continue;
638  case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
639  case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
640  case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
641  case '%':
642  break;
643  default:
644  CurStringPiece += CurChar;
645  continue;
646  }
647 
648  const TargetInfo &TI = C.getTargetInfo();
649 
650  // Escaped "%" character in asm string.
651  if (CurPtr == StrEnd) {
652  // % at end of string is invalid (no escape).
653  DiagOffs = CurPtr-StrStart-1;
654  return diag::err_asm_invalid_escape;
655  }
656  // Handle escaped char and continue looping over the asm string.
657  char EscapedChar = *CurPtr++;
658  switch (EscapedChar) {
659  default:
660  // Handle target-specific escaped characters.
661  if (auto MaybeReplaceStr = TI.handleAsmEscapedChar(EscapedChar)) {
662  CurStringPiece += *MaybeReplaceStr;
663  continue;
664  }
665  break;
666  case '%': // %% -> %
667  case '{': // %{ -> {
668  case '}': // %} -> }
669  CurStringPiece += EscapedChar;
670  continue;
671  case '=': // %= -> Generate a unique ID.
672  CurStringPiece += "${:uid}";
673  continue;
674  }
675 
676  // Otherwise, we have an operand. If we have accumulated a string so far,
677  // add it to the Pieces list.
678  if (!CurStringPiece.empty()) {
679  Pieces.push_back(AsmStringPiece(CurStringPiece));
680  CurStringPiece.clear();
681  }
682 
683  // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
684  // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
685 
686  const char *Begin = CurPtr - 1; // Points to the character following '%'.
687  const char *Percent = Begin - 1; // Points to '%'.
688 
689  if (isLetter(EscapedChar)) {
690  if (CurPtr == StrEnd) { // Premature end.
691  DiagOffs = CurPtr-StrStart-1;
692  return diag::err_asm_invalid_escape;
693  }
694  EscapedChar = *CurPtr++;
695  }
696 
697  const SourceManager &SM = C.getSourceManager();
698  const LangOptions &LO = C.getLangOpts();
699 
700  // Handle operands that don't have asmSymbolicName (e.g., %x4).
701  if (isDigit(EscapedChar)) {
702  // %n - Assembler operand n
703  unsigned N = 0;
704 
705  --CurPtr;
706  while (CurPtr != StrEnd && isDigit(*CurPtr))
707  N = N*10 + ((*CurPtr++)-'0');
708 
709  unsigned NumOperands = getNumOutputs() + getNumPlusOperands() +
711  if (N >= NumOperands) {
712  DiagOffs = CurPtr-StrStart-1;
713  return diag::err_asm_invalid_operand_number;
714  }
715 
716  // Str contains "x4" (Operand without the leading %).
717  std::string Str(Begin, CurPtr - Begin);
718 
719  // (BeginLoc, EndLoc) represents the range of the operand we are currently
720  // processing. Unlike Str, the range includes the leading '%'.
722  Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
723  &LastAsmStringOffset);
725  CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
726  &LastAsmStringOffset);
727 
728  Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
729  continue;
730  }
731 
732  // Handle operands that have asmSymbolicName (e.g., %x[foo]).
733  if (EscapedChar == '[') {
734  DiagOffs = CurPtr-StrStart-1;
735 
736  // Find the ']'.
737  const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
738  if (NameEnd == nullptr)
739  return diag::err_asm_unterminated_symbolic_operand_name;
740  if (NameEnd == CurPtr)
741  return diag::err_asm_empty_symbolic_operand_name;
742 
743  StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
744 
745  int N = getNamedOperand(SymbolicName);
746  if (N == -1) {
747  // Verify that an operand with that name exists.
748  DiagOffs = CurPtr-StrStart;
749  return diag::err_asm_unknown_symbolic_operand_name;
750  }
751 
752  // Str contains "x[foo]" (Operand without the leading %).
753  std::string Str(Begin, NameEnd + 1 - Begin);
754 
755  // (BeginLoc, EndLoc) represents the range of the operand we are currently
756  // processing. Unlike Str, the range includes the leading '%'.
758  Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
759  &LastAsmStringOffset);
761  NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
762  &LastAsmStringOffset);
763 
764  Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
765 
766  CurPtr = NameEnd+1;
767  continue;
768  }
769 
770  DiagOffs = CurPtr-StrStart-1;
771  return diag::err_asm_invalid_escape;
772  }
773 }
774 
775 /// Assemble final IR asm string (GCC-style).
777  // Analyze the asm string to decompose it into its pieces. We know that Sema
778  // has already done this, so it is guaranteed to be successful.
780  unsigned DiagOffs;
781  AnalyzeAsmString(Pieces, C, DiagOffs);
782 
783  std::string AsmString;
784  for (const auto &Piece : Pieces) {
785  if (Piece.isString())
786  AsmString += Piece.getString();
787  else if (Piece.getModifier() == '\0')
788  AsmString += '$' + llvm::utostr(Piece.getOperandNo());
789  else
790  AsmString += "${" + llvm::utostr(Piece.getOperandNo()) + ':' +
791  Piece.getModifier() + '}';
792  }
793  return AsmString;
794 }
795 
796 /// Assemble final IR asm string (MS-style).
798  // FIXME: This needs to be translated into the IR string representation.
800  AsmStr.split(Pieces, "\n\t");
801  std::string MSAsmString;
802  for (size_t I = 0, E = Pieces.size(); I < E; ++I) {
803  StringRef Instruction = Pieces[I];
804  // For vex/vex2/vex3/evex masm style prefix, convert it to att style
805  // since we don't support masm style prefix in backend.
806  if (Instruction.startswith("vex "))
807  MSAsmString += '{' + Instruction.substr(0, 3).str() + '}' +
808  Instruction.substr(3).str();
809  else if (Instruction.startswith("vex2 ") ||
810  Instruction.startswith("vex3 ") || Instruction.startswith("evex "))
811  MSAsmString += '{' + Instruction.substr(0, 4).str() + '}' +
812  Instruction.substr(4).str();
813  else
814  MSAsmString += Instruction.str();
815  // If this is not the last instruction, adding back the '\n\t'.
816  if (I < E - 1)
817  MSAsmString += "\n\t";
818  }
819  return MSAsmString;
820 }
821 
823  return cast<Expr>(Exprs[i]);
824 }
825 
827  return cast<Expr>(Exprs[i + NumOutputs]);
828 }
829 
830 void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
831  Exprs[i + NumOutputs] = E;
832 }
833 
834 //===----------------------------------------------------------------------===//
835 // Constructors
836 //===----------------------------------------------------------------------===//
837 
839  bool issimple, bool isvolatile, unsigned numoutputs,
840  unsigned numinputs, IdentifierInfo **names,
841  StringLiteral **constraints, Expr **exprs,
842  StringLiteral *asmstr, unsigned numclobbers,
843  StringLiteral **clobbers, unsigned numlabels,
844  SourceLocation rparenloc)
845  : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
846  numinputs, numclobbers),
847  RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
848  unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
849 
850  Names = new (C) IdentifierInfo*[NumExprs];
851  std::copy(names, names + NumExprs, Names);
852 
853  Exprs = new (C) Stmt*[NumExprs];
854  std::copy(exprs, exprs + NumExprs, Exprs);
855 
856  unsigned NumConstraints = NumOutputs + NumInputs;
857  Constraints = new (C) StringLiteral*[NumConstraints];
858  std::copy(constraints, constraints + NumConstraints, Constraints);
859 
860  Clobbers = new (C) StringLiteral*[NumClobbers];
861  std::copy(clobbers, clobbers + NumClobbers, Clobbers);
862 }
863 
865  SourceLocation lbraceloc, bool issimple, bool isvolatile,
866  ArrayRef<Token> asmtoks, unsigned numoutputs,
867  unsigned numinputs,
868  ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
869  StringRef asmstr, ArrayRef<StringRef> clobbers,
870  SourceLocation endloc)
871  : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
872  numinputs, clobbers.size()), LBraceLoc(lbraceloc),
873  EndLoc(endloc), NumAsmToks(asmtoks.size()) {
874  initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
875 }
876 
877 static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
878  return str.copy(C);
879 }
880 
881 void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
882  ArrayRef<Token> asmtoks,
883  ArrayRef<StringRef> constraints,
884  ArrayRef<Expr*> exprs,
885  ArrayRef<StringRef> clobbers) {
886  assert(NumAsmToks == asmtoks.size());
887  assert(NumClobbers == clobbers.size());
888 
889  assert(exprs.size() == NumOutputs + NumInputs);
890  assert(exprs.size() == constraints.size());
891 
892  AsmStr = copyIntoContext(C, asmstr);
893 
894  Exprs = new (C) Stmt*[exprs.size()];
895  std::copy(exprs.begin(), exprs.end(), Exprs);
896 
897  AsmToks = new (C) Token[asmtoks.size()];
898  std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
899 
900  Constraints = new (C) StringRef[exprs.size()];
901  std::transform(constraints.begin(), constraints.end(), Constraints,
902  [&](StringRef Constraint) {
903  return copyIntoContext(C, Constraint);
904  });
905 
906  Clobbers = new (C) StringRef[NumClobbers];
907  // FIXME: Avoid the allocation/copy if at all possible.
908  std::transform(clobbers.begin(), clobbers.end(), Clobbers,
909  [&](StringRef Clobber) {
910  return copyIntoContext(C, Clobber);
911  });
912 }
913 
914 IfStmt::IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind,
915  Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL,
916  SourceLocation RPL, Stmt *Then, SourceLocation EL, Stmt *Else)
917  : Stmt(IfStmtClass), LParenLoc(LPL), RParenLoc(RPL) {
918  bool HasElse = Else != nullptr;
919  bool HasVar = Var != nullptr;
920  bool HasInit = Init != nullptr;
921  IfStmtBits.HasElse = HasElse;
922  IfStmtBits.HasVar = HasVar;
923  IfStmtBits.HasInit = HasInit;
924 
925  setStatementKind(Kind);
926 
927  setCond(Cond);
928  setThen(Then);
929  if (HasElse)
930  setElse(Else);
931  if (HasVar)
932  setConditionVariable(Ctx, Var);
933  if (HasInit)
934  setInit(Init);
935 
936  setIfLoc(IL);
937  if (HasElse)
938  setElseLoc(EL);
939 }
940 
941 IfStmt::IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit)
942  : Stmt(IfStmtClass, Empty) {
943  IfStmtBits.HasElse = HasElse;
944  IfStmtBits.HasVar = HasVar;
945  IfStmtBits.HasInit = HasInit;
946 }
947 
948 IfStmt *IfStmt::Create(const ASTContext &Ctx, SourceLocation IL,
949  IfStatementKind Kind, Stmt *Init, VarDecl *Var,
950  Expr *Cond, SourceLocation LPL, SourceLocation RPL,
951  Stmt *Then, SourceLocation EL, Stmt *Else) {
952  bool HasElse = Else != nullptr;
953  bool HasVar = Var != nullptr;
954  bool HasInit = Init != nullptr;
955  void *Mem = Ctx.Allocate(
956  totalSizeToAlloc<Stmt *, SourceLocation>(
957  NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
958  alignof(IfStmt));
959  return new (Mem)
960  IfStmt(Ctx, IL, Kind, Init, Var, Cond, LPL, RPL, Then, EL, Else);
961 }
962 
963 IfStmt *IfStmt::CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
964  bool HasInit) {
965  void *Mem = Ctx.Allocate(
966  totalSizeToAlloc<Stmt *, SourceLocation>(
967  NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
968  alignof(IfStmt));
969  return new (Mem) IfStmt(EmptyShell(), HasElse, HasVar, HasInit);
970 }
971 
973  auto *DS = getConditionVariableDeclStmt();
974  if (!DS)
975  return nullptr;
976  return cast<VarDecl>(DS->getSingleDecl());
977 }
978 
980  assert(hasVarStorage() &&
981  "This if statement has no storage for a condition variable!");
982 
983  if (!V) {
984  getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
985  return;
986  }
987 
988  SourceRange VarRange = V->getSourceRange();
989  getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
990  DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
991 }
992 
994  return isa<ObjCAvailabilityCheckExpr>(getCond());
995 }
996 
998  if (!isConstexpr() || getCond()->isValueDependent())
999  return None;
1000  return !getCond()->EvaluateKnownConstInt(Ctx) ? getElse() : getThen();
1001 }
1002 
1005  if (Optional<Stmt *> Result =
1006  const_cast<IfStmt *>(this)->getNondiscardedCase(Ctx))
1007  return *Result;
1008  return None;
1009 }
1010 
1011 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
1012  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
1013  SourceLocation RP)
1014  : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
1015 {
1016  SubExprs[INIT] = Init;
1017  setConditionVariable(C, condVar);
1018  SubExprs[COND] = Cond;
1019  SubExprs[INC] = Inc;
1020  SubExprs[BODY] = Body;
1021  ForStmtBits.ForLoc = FL;
1022 }
1023 
1025  if (!SubExprs[CONDVAR])
1026  return nullptr;
1027 
1028  auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
1029  return cast<VarDecl>(DS->getSingleDecl());
1030 }
1031 
1033  if (!V) {
1034  SubExprs[CONDVAR] = nullptr;
1035  return;
1036  }
1037 
1038  SourceRange VarRange = V->getSourceRange();
1039  SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
1040  VarRange.getEnd());
1041 }
1042 
1043 SwitchStmt::SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
1044  Expr *Cond, SourceLocation LParenLoc,
1045  SourceLocation RParenLoc)
1046  : Stmt(SwitchStmtClass), FirstCase(nullptr), LParenLoc(LParenLoc),
1047  RParenLoc(RParenLoc) {
1048  bool HasInit = Init != nullptr;
1049  bool HasVar = Var != nullptr;
1050  SwitchStmtBits.HasInit = HasInit;
1051  SwitchStmtBits.HasVar = HasVar;
1052  SwitchStmtBits.AllEnumCasesCovered = false;
1053 
1054  setCond(Cond);
1055  setBody(nullptr);
1056  if (HasInit)
1057  setInit(Init);
1058  if (HasVar)
1059  setConditionVariable(Ctx, Var);
1060 
1061  setSwitchLoc(SourceLocation{});
1062 }
1063 
1064 SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)
1065  : Stmt(SwitchStmtClass, Empty) {
1066  SwitchStmtBits.HasInit = HasInit;
1067  SwitchStmtBits.HasVar = HasVar;
1068  SwitchStmtBits.AllEnumCasesCovered = false;
1069 }
1070 
1072  Expr *Cond, SourceLocation LParenLoc,
1073  SourceLocation RParenLoc) {
1074  bool HasInit = Init != nullptr;
1075  bool HasVar = Var != nullptr;
1076  void *Mem = Ctx.Allocate(
1077  totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
1078  alignof(SwitchStmt));
1079  return new (Mem) SwitchStmt(Ctx, Init, Var, Cond, LParenLoc, RParenLoc);
1080 }
1081 
1083  bool HasVar) {
1084  void *Mem = Ctx.Allocate(
1085  totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
1086  alignof(SwitchStmt));
1087  return new (Mem) SwitchStmt(EmptyShell(), HasInit, HasVar);
1088 }
1089 
1091  auto *DS = getConditionVariableDeclStmt();
1092  if (!DS)
1093  return nullptr;
1094  return cast<VarDecl>(DS->getSingleDecl());
1095 }
1096 
1098  assert(hasVarStorage() &&
1099  "This switch statement has no storage for a condition variable!");
1100 
1101  if (!V) {
1102  getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
1103  return;
1104  }
1105 
1106  SourceRange VarRange = V->getSourceRange();
1107  getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
1108  DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
1109 }
1110 
1111 WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
1112  Stmt *Body, SourceLocation WL, SourceLocation LParenLoc,
1113  SourceLocation RParenLoc)
1114  : Stmt(WhileStmtClass) {
1115  bool HasVar = Var != nullptr;
1116  WhileStmtBits.HasVar = HasVar;
1117 
1118  setCond(Cond);
1119  setBody(Body);
1120  if (HasVar)
1121  setConditionVariable(Ctx, Var);
1122 
1123  setWhileLoc(WL);
1124  setLParenLoc(LParenLoc);
1125  setRParenLoc(RParenLoc);
1126 }
1127 
1128 WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
1129  : Stmt(WhileStmtClass, Empty) {
1130  WhileStmtBits.HasVar = HasVar;
1131 }
1132 
1134  Stmt *Body, SourceLocation WL,
1135  SourceLocation LParenLoc,
1136  SourceLocation RParenLoc) {
1137  bool HasVar = Var != nullptr;
1138  void *Mem =
1139  Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1140  alignof(WhileStmt));
1141  return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL, LParenLoc, RParenLoc);
1142 }
1143 
1144 WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {
1145  void *Mem =
1146  Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1147  alignof(WhileStmt));
1148  return new (Mem) WhileStmt(EmptyShell(), HasVar);
1149 }
1150 
1152  auto *DS = getConditionVariableDeclStmt();
1153  if (!DS)
1154  return nullptr;
1155  return cast<VarDecl>(DS->getSingleDecl());
1156 }
1157 
1159  assert(hasVarStorage() &&
1160  "This while statement has no storage for a condition variable!");
1161 
1162  if (!V) {
1163  getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
1164  return;
1165  }
1166 
1167  SourceRange VarRange = V->getSourceRange();
1168  getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
1169  DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
1170 }
1171 
1172 // IndirectGotoStmt
1174  if (auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
1175  return E->getLabel();
1176  return nullptr;
1177 }
1178 
1179 // ReturnStmt
1180 ReturnStmt::ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1181  : Stmt(ReturnStmtClass), RetExpr(E) {
1182  bool HasNRVOCandidate = NRVOCandidate != nullptr;
1183  ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1184  if (HasNRVOCandidate)
1185  setNRVOCandidate(NRVOCandidate);
1186  setReturnLoc(RL);
1187 }
1188 
1189 ReturnStmt::ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate)
1190  : Stmt(ReturnStmtClass, Empty) {
1191  ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1192 }
1193 
1195  Expr *E, const VarDecl *NRVOCandidate) {
1196  bool HasNRVOCandidate = NRVOCandidate != nullptr;
1197  void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1198  alignof(ReturnStmt));
1199  return new (Mem) ReturnStmt(RL, E, NRVOCandidate);
1200 }
1201 
1203  bool HasNRVOCandidate) {
1204  void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1205  alignof(ReturnStmt));
1206  return new (Mem) ReturnStmt(EmptyShell(), HasNRVOCandidate);
1207 }
1208 
1209 // CaseStmt
1211  SourceLocation caseLoc, SourceLocation ellipsisLoc,
1212  SourceLocation colonLoc) {
1213  bool CaseStmtIsGNURange = rhs != nullptr;
1214  void *Mem = Ctx.Allocate(
1215  totalSizeToAlloc<Stmt *, SourceLocation>(
1216  NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1217  alignof(CaseStmt));
1218  return new (Mem) CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
1219 }
1220 
1222  bool CaseStmtIsGNURange) {
1223  void *Mem = Ctx.Allocate(
1224  totalSizeToAlloc<Stmt *, SourceLocation>(
1225  NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1226  alignof(CaseStmt));
1227  return new (Mem) CaseStmt(EmptyShell(), CaseStmtIsGNURange);
1228 }
1229 
1230 SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
1231  Stmt *Handler)
1232  : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
1233  Children[TRY] = TryBlock;
1234  Children[HANDLER] = Handler;
1235 }
1236 
1237 SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
1238  SourceLocation TryLoc, Stmt *TryBlock,
1239  Stmt *Handler) {
1240  return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
1241 }
1242 
1244  return dyn_cast<SEHExceptStmt>(getHandler());
1245 }
1246 
1248  return dyn_cast<SEHFinallyStmt>(getHandler());
1249 }
1250 
1251 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
1252  : Stmt(SEHExceptStmtClass), Loc(Loc) {
1253  Children[FILTER_EXPR] = FilterExpr;
1254  Children[BLOCK] = Block;
1255 }
1256 
1258  Expr *FilterExpr, Stmt *Block) {
1259  return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
1260 }
1261 
1262 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
1263  : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
1264 
1266  Stmt *Block) {
1267  return new(C)SEHFinallyStmt(Loc,Block);
1268 }
1269 
1271  VarDecl *Var)
1272  : VarAndKind(Var, Kind), Loc(Loc) {
1273  switch (Kind) {
1274  case VCK_This:
1275  assert(!Var && "'this' capture cannot have a variable!");
1276  break;
1277  case VCK_ByRef:
1278  assert(Var && "capturing by reference must have a variable!");
1279  break;
1280  case VCK_ByCopy:
1281  assert(Var && "capturing by copy must have a variable!");
1282  break;
1283  case VCK_VLAType:
1284  assert(!Var &&
1285  "Variable-length array type capture cannot have a variable!");
1286  break;
1287  }
1288 }
1289 
1292  return VarAndKind.getInt();
1293 }
1294 
1296  assert((capturesVariable() || capturesVariableByCopy()) &&
1297  "No variable available for 'this' or VAT capture");
1298  return VarAndKind.getPointer();
1299 }
1300 
1301 CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
1302  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1303 
1304  // Offset of the first Capture object.
1305  unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));
1306 
1307  return reinterpret_cast<Capture *>(
1308  reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1309  + FirstCaptureOffset);
1310 }
1311 
1312 CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1313  ArrayRef<Capture> Captures,
1314  ArrayRef<Expr *> CaptureInits,
1315  CapturedDecl *CD,
1316  RecordDecl *RD)
1317  : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1318  CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
1319  assert( S && "null captured statement");
1320  assert(CD && "null captured declaration for captured statement");
1321  assert(RD && "null record declaration for captured statement");
1322 
1323  // Copy initialization expressions.
1324  Stmt **Stored = getStoredStmts();
1325  for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1326  *Stored++ = CaptureInits[I];
1327 
1328  // Copy the statement being captured.
1329  *Stored = S;
1330 
1331  // Copy all Capture objects.
1332  Capture *Buffer = getStoredCaptures();
1333  std::copy(Captures.begin(), Captures.end(), Buffer);
1334 }
1335 
1336 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1337  : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1338  CapDeclAndKind(nullptr, CR_Default) {
1339  getStoredStmts()[NumCaptures] = nullptr;
1340 }
1341 
1344  ArrayRef<Capture> Captures,
1345  ArrayRef<Expr *> CaptureInits,
1346  CapturedDecl *CD,
1347  RecordDecl *RD) {
1348  // The layout is
1349  //
1350  // -----------------------------------------------------------
1351  // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1352  // ----------------^-------------------^----------------------
1353  // getStoredStmts() getStoredCaptures()
1354  //
1355  // where S is the statement being captured.
1356  //
1357  assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1358 
1359  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1360  if (!Captures.empty()) {
1361  // Realign for the following Capture array.
1362  Size = llvm::alignTo(Size, alignof(Capture));
1363  Size += sizeof(Capture) * Captures.size();
1364  }
1365 
1366  void *Mem = Context.Allocate(Size);
1367  return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1368 }
1369 
1371  unsigned NumCaptures) {
1372  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1373  if (NumCaptures > 0) {
1374  // Realign for the following Capture array.
1375  Size = llvm::alignTo(Size, alignof(Capture));
1376  Size += sizeof(Capture) * NumCaptures;
1377  }
1378 
1379  void *Mem = Context.Allocate(Size);
1380  return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1381 }
1382 
1384  // Children are captured field initializers.
1385  return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1386 }
1387 
1389  return const_child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1390 }
1391 
1393  return CapDeclAndKind.getPointer();
1394 }
1395 
1397  return CapDeclAndKind.getPointer();
1398 }
1399 
1400 /// Set the outlined function declaration.
1402  assert(D && "null CapturedDecl");
1403  CapDeclAndKind.setPointer(D);
1404 }
1405 
1406 /// Retrieve the captured region kind.
1408  return CapDeclAndKind.getInt();
1409 }
1410 
1411 /// Set the captured region kind.
1413  CapDeclAndKind.setInt(Kind);
1414 }
1415 
1416 bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
1417  for (const auto &I : captures()) {
1418  if (!I.capturesVariable() && !I.capturesVariableByCopy())
1419  continue;
1420  if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
1421  return true;
1422  }
1423 
1424  return false;
1425 }
clang::CapturedStmt::VCK_VLAType
@ VCK_VLAType
Definition: Stmt.h:3513
StmtClassNameTable
Definition: Stmt.cpp:50
clang::CapturedStmt::VCK_ByCopy
@ VCK_ByCopy
Definition: Stmt.h:3512
clang::SwitchStmt::hasVarStorage
bool hasVarStorage() const
True if this SwitchStmt has storage for a condition variable.
Definition: Stmt.h:2217
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:570
clang::ForStmt::getConditionVariable
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
Definition: Stmt.cpp:1024
clang::CaseStmt
CaseStmt - Represent a case statement.
Definition: Stmt.h:1572
clang::AsmStmt::getInputConstraint
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
Definition: Stmt.cpp:457
clang::CaseStmt::CreateEmpty
static CaseStmt * CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange)
Build an empty case statement.
Definition: Stmt.cpp:1221
clang::ForStmt::setBody
void setBody(Stmt *S)
Definition: Stmt.h:2583
clang::SEHTryStmt::getFinallyHandler
SEHFinallyStmt * getFinallyHandler() const
Definition: Stmt.cpp:1247
clang::GCCAsmStmt::getLabelExpr
AddrLabelExpr * getLabelExpr(unsigned i) const
Definition: Stmt.cpp:519
copyIntoContext
static StringRef copyIntoContext(const ASTContext &C, StringRef str)
Definition: Stmt.cpp:877
clang::SwitchStmt
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2155
clang::AsmStmt::generateAsmString
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:433
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:1983
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:473
clang::WhileStmt
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2346
clang::CapturedStmt::captures
capture_range captures()
Definition: Stmt.h:3640
clang::ast_matchers::stmt
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchersInternal.cpp:810
clang::IfStmt::isObjCAvailabilityCheck
bool isObjCAvailabilityCheck() const
Definition: Stmt.cpp:993
clang::SEHTryStmt::getExceptHandler
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition: Stmt.cpp:1243
clang::VarDecl::getCanonicalDecl
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2144
clang::CapturedStmt::setCapturedRegionKind
void setCapturedRegionKind(CapturedRegionKind Kind)
Set the captured region kind.
Definition: Stmt.cpp:1412
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:425
clang::CompoundStmt::body_begin
body_iterator body_begin()
Definition: Stmt.h:1438
clang::Stmt::EnableStatistics
static void EnableStatistics()
Definition: Stmt.cpp:129
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::Stmt::StmtClass
StmtClass
Definition: Stmt.h:71
TargetInfo.h
clang::WhileStmt::hasVarStorage
bool hasVarStorage() const
True if this WhileStmt has storage for a condition variable.
Definition: Stmt.h:2397
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:523
Attr.h
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:54
clang::AsmStmt::getOutputConstraint
StringRef getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
Definition: Stmt.cpp:441
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:186
clang::IfStmt
IfStmt - This represents an if/then/else.
Definition: Stmt.h:1909
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:1004
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:864
clang::sema::Capture
Definition: ScopeInfo.h:528
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:4349
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:1257
clang::CapturedStmt::getCapturedRegionKind
CapturedRegionKind getCapturedRegionKind() const
Retrieve the captured region kind.
Definition: Stmt.cpp:1407
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:626
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:1103
clang::SEHTryStmt
Definition: Stmt.h:3413
clang::AsmStmt::isSimple
bool isSimple() const
Definition: Stmt.h:2881
Decl.h
clang::Stmt::NoStmtClass
@ NoStmtClass
Definition: Stmt.h:72
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:1011
ExprConcepts.h
clang::CapturedStmt::VCK_ByRef
@ VCK_ByRef
Definition: Stmt.h:3511
clang::ASTContext::Allocate
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:706
clang::AsmStmt::Exprs
Stmt ** Exprs
Definition: Stmt.h:2866
clang::AttributedStmt
Represents an attribute applied to a statement.
Definition: Stmt.h:1851
clang::CapturedStmt::capturesVariable
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1416
BLOCK
#define BLOCK(DERIVED, BASE)
Definition: Template.h:516
V
#define V(N, I)
Definition: ASTContext.h:3127
clang::ReturnStmt::Create
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
Definition: Stmt.cpp:1194
clang::CompoundStmt
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1404
StmtOpenMP.h
clang::IndirectGotoStmt::getConstantTarget
LabelDecl * getConstantTarget()
getConstantTarget - Returns the fixed target of this indirect goto, if one exists.
Definition: Stmt.cpp:1173
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:1133
clang::Stmt::SwitchStmtBits
SwitchStmtBitfields SwitchStmtBits
Definition: Stmt.h:1011
clang::GCCAsmStmt::getClobber
StringRef getClobber(unsigned i) const
Definition: Stmt.cpp:496
clang::CapturedStmt::Capture::Capture
Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var=nullptr)
Create a new capture.
Definition: Stmt.cpp:1270
clang::AsmStmt::getInputExpr
const Expr * getInputExpr(unsigned i) const
Definition: Stmt.cpp:465
clang::SourceRange::getEnd
SourceLocation getEnd() const
Definition: SourceLocation.h:220
clang::GCCAsmStmt::getAsmString
const StringLiteral * getAsmString() const
Definition: Stmt.h:3035
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:209
clang::isLetter
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
Definition: CharInfo.h:116
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:2044
clang::GCCAsmStmt::AsmStringPiece
AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...
Definition: Stmt.h:3042
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:1082
clang::CapturedStmt::setCapturedDecl
void setCapturedDecl(CapturedDecl *D)
Set the outlined function declaration.
Definition: Stmt.cpp:1401
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:1210
clang::Stmt::children
child_range children()
Definition: Stmt.cpp:285
clang::GCCAsmStmt::getOutputName
StringRef getOutputName(unsigned i) const
Definition: Stmt.h:3099
clang::Stmt::LH_None
@ LH_None
No attribute set or branches of the IfStmt have the same attribute.
Definition: Stmt.h:1108
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:3509
clang::ValueStmt::getExprStmt
const Expr * getExprStmt() const
Definition: Stmt.cpp:395
clang::SwitchStmt::getConditionVariableDeclStmt
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition: Stmt.h:2276
clang::AttributedStmt::Create
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Definition: Stmt.cpp:416
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:1370
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:1110
clang::CapturedStmt
This captures a statement into a function.
Definition: Stmt.h:3505
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:15088
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:3518
clang::IfStmt::getElse
Stmt * getElse()
Definition: Stmt.h:2009
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:1071
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:1202
clang::Stmt::child_range
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1252
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:963
DeclGroup.h
clang::Stmt::WhileStmtBits
WhileStmtBitfields WhileStmtBits
Definition: Stmt.h:1012
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:593
clang::SwitchStmt::setBody
void setBody(Stmt *Body)
Definition: Stmt.h:2236
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:1266
clang::WhileStmt::getConditionVariable
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Definition: Stmt.cpp:1151
clang::GCCAsmStmt::getInputName
StringRef getInputName(unsigned i) const
Definition: Stmt.h:3127
clang::MSAsmStmt::generateAsmString
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:797
StmtObjC.h
clang::CompoundStmt::CreateEmpty
static CompoundStmt * CreateEmpty(const ASTContext &C, unsigned NumStmts)
Definition: Stmt.cpp:386
clang::AsmStmt::getNumOutputs
unsigned getNumOutputs() const
Definition: Stmt.h:2897
clang::SEHExceptStmt
Definition: Stmt.h:3334
StmtClassNameTable::Counter
unsigned Counter
Definition: Stmt.cpp:52
clang::GCCAsmStmt::getInputConstraintLiteral
const StringLiteral * getInputConstraintLiteral(unsigned i) const
Definition: Stmt.h:3136
clang::Stmt::const_child_range
llvm::iterator_range< const_child_iterator > const_child_range
Definition: Stmt.h:1253
clang::AsmStmt::NumOutputs
unsigned NumOutputs
Definition: Stmt.h:2862
clang::GCCAsmStmt::getInputConstraint
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
Definition: Stmt.cpp:529
clang::WhileStmt::setConditionVariable
void setConditionVariable(const ASTContext &Ctx, VarDecl *V)
Set the condition variable of this while statement.
Definition: Stmt.cpp:1158
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:2848
clang::GCCAsmStmt::getOutputConstraint
StringRef getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
Definition: Stmt.cpp:507
clang::ForStmt::setInit
void setInit(Stmt *S)
Definition: Stmt.h:2580
clang::Stmt::getID
int64_t getID(const ASTContext &Context) const
Definition: Stmt.cpp:360
clang::AsmStmt::NumInputs
unsigned NumInputs
Definition: Stmt.h:2863
clang::SwitchStmt::setCond
void setCond(Expr *Cond)
Definition: Stmt.h:2227
CharInfo.h
clang::MSAsmStmt::setInputExpr
void setInputExpr(unsigned i, Expr *E)
Definition: Stmt.cpp:830
clang::Stmt::getStmtClass
StmtClass getStmtClass() const
Definition: Stmt.h:1163
clang::SwitchStmt::setRParenLoc
void setRParenLoc(SourceLocation Loc)
Definition: Stmt.h:2297
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:2295
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:412
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:1106
clang::ForStmt::setConditionVariable
void setConditionVariable(const ASTContext &C, VarDecl *V)
Definition: Stmt.cpp:1032
clang::AddrLabelExpr
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4306
clang::DeclGroupRef
Definition: DeclGroup.h:51
clang::AsmStmt::getNumInputs
unsigned getNumInputs() const
Definition: Stmt.h:2919
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:1144
clang::IndirectGotoStmt::getTarget
Expr * getTarget()
Definition: Stmt.h:2669
clang::SEHFinallyStmt::Create
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Definition: Stmt.cpp:1265
LLVM.h
clang::GCCAsmStmt::getOutputConstraintLiteral
const StringLiteral * getOutputConstraintLiteral(unsigned i) const
Definition: Stmt.h:3108
clang::SEHTryStmt::getHandler
Stmt * getHandler() const
Definition: Stmt.h:3446
clang::GCCAsmStmt::getOutputExpr
Expr * getOutputExpr(unsigned i)
Definition: Stmt.cpp:500
clang::IfStmt::getConditionVariable
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
Definition: Stmt.cpp:972
clang::GCCAsmStmt::AsmStringPiece::getModifier
char getModifier() const
getModifier - Get the modifier for this operand, if present.
Definition: Stmt.cpp:491
clang::MSAsmStmt::getOutputExpr
Expr * getOutputExpr(unsigned i)
Definition: Stmt.cpp:822
clang::Stmt::getLikelihood
static Likelihood getLikelihood(ArrayRef< const Attr * > Attrs)
Definition: Stmt.cpp:153
clang::GCCAsmStmt::getNumLabels
unsigned getNumLabels() const
Definition: Stmt.h:3156
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:838
clang::AsmStmt::getNumPlusOperands
unsigned getNumPlusOperands() const
getNumPlusOperands - Return the number of output operands that have a "+" constraint.
Definition: Stmt.cpp:483
clang::Stmt::LH_Unlikely
@ LH_Unlikely
Branch has the [[unlikely]] attribute.
Definition: Stmt.h:1107
clang::AsmStmt::isOutputPlusConstraint
bool isOutputPlusConstraint(unsigned i) const
isOutputPlusConstraint - Return true if the specified output constraint is a "+" constraint (which is...
Definition: Stmt.h:2907
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:58
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:1297
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:1129
clang::IfStmt::getCond
Expr * getCond()
Definition: Stmt.h:1988
clang::GCCAsmStmt::generateAsmString
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:776
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:3378
clang::MSAsmStmt::getInputExpr
Expr * getInputExpr(unsigned i)
Definition: Stmt.cpp:826
clang::AsmStmt::getOutputExpr
const Expr * getOutputExpr(unsigned i) const
Definition: Stmt.cpp:449
clang::IfStmt::isConstexpr
bool isConstexpr() const
Definition: Stmt.h:2099
clang::CapturedStmt::children
child_range children()
Definition: Stmt.cpp:1383
clang::IfStmt::setConditionVariable
void setConditionVariable(const ASTContext &Ctx, VarDecl *V)
Set the condition variable for this if statement.
Definition: Stmt.cpp:979
clang::Stmt::ForStmtBits
ForStmtBitfields ForStmtBits
Definition: Stmt.h:1014
clang
Definition: CalledOnceCheck.h:17
clang::NumConstraints
@ NumConstraints
Definition: AnalyzerOptions.h:54
clang::DeclaratorContext::Block
@ Block
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
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:1295
clang::GCCAsmStmt::getClobberStringLiteral
StringLiteral * getClobberStringLiteral(unsigned i)
Definition: Stmt.h:3216
clang::GCCAsmStmt::getInputExpr
Expr * getInputExpr(unsigned i)
Definition: Stmt.cpp:511
clang::isDigit
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Definition: CharInfo.h:98
StmtClassNameTable::Name
const char * Name
Definition: Stmt.cpp:51
clang::CapturedStmt::VCK_This
@ VCK_This
Definition: Stmt.h:3510
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:2439
clang::CapturedStmt::Capture::getCaptureKind
VariableCaptureKind getCaptureKind() const
Determine the kind of capture.
Definition: Stmt.cpp:1291
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::IfStmt::getThen
Stmt * getThen()
Definition: Stmt.h:2000
clang::Stmt::CompoundStmtBits
CompoundStmtBitfields CompoundStmtBits
Definition: Stmt.h:1007
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:1342
clang::LabelStmt::getDecl
LabelDecl * getDecl() const
Definition: Stmt.h:1822
clang::SwitchStmt::setConditionVariable
void setConditionVariable(const ASTContext &Ctx, VarDecl *VD)
Set the condition variable in this switch statement.
Definition: Stmt.cpp:1097
clang::SEHTryStmt::Create
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Definition: Stmt.cpp:1237
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:1018
clang::SwitchStmt::getConditionVariable
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
Definition: Stmt.cpp:1090
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::ForStmt::setCond
void setCond(Expr *E)
Definition: Stmt.h:2581
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:1392
Token.h
clang::AsmStmt::NumClobbers
unsigned NumClobbers
Definition: Stmt.h:2864
clang::GCCAsmStmt::setInputExpr
void setInputExpr(unsigned i, Expr *E)
Definition: Stmt.cpp:515
clang::Stmt::StmtBits
StmtBitfields StmtBits
Definition: Stmt.h:1005
clang::AddrLabelExpr::getLabel
LabelDecl * getLabel() const
Definition: Expr.h:4329
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3866
clang::CompoundStmt::Create
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, SourceLocation LB, SourceLocation RB)
Definition: Stmt.cpp:379
StmtCXX.h
clang::StringLiteral::getString
StringRef getString() const
Definition: Expr.h:1850
clang::ASTContext::getAllocator
llvm::BumpPtrAllocator & getAllocator() const
Definition: ASTContext.h:702
clang::ReturnStmt
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:2765
clang::GCCAsmStmt::AsmStringPiece::isOperand
bool isOperand() const
Definition: Stmt.h:3065
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274