clang  6.0.0svn
Stmt.cpp
Go to the documentation of this file.
1 //===- Stmt.cpp - Statement AST Node Implementation -----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Stmt class and statement subclasses.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclGroup.h"
18 #include "clang/AST/ExprCXX.h"
19 #include "clang/AST/ExprObjC.h"
20 #include "clang/AST/ExprOpenMP.h"
21 #include "clang/AST/Stmt.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtObjC.h"
24 #include "clang/AST/StmtOpenMP.h"
25 #include "clang/AST/Type.h"
26 #include "clang/Basic/CharInfo.h"
27 #include "clang/Basic/LLVM.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Lex/Token.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/ADT/StringExtras.h"
33 #include "llvm/ADT/StringRef.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/Compiler.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/MathExtras.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include <algorithm>
40 #include <cassert>
41 #include <cstring>
42 #include <string>
43 #include <utility>
44 
45 using namespace clang;
46 
47 static struct StmtClassNameTable {
48  const char *Name;
49  unsigned Counter;
50  unsigned Size;
51 } StmtClassInfo[Stmt::lastStmtConstant+1];
52 
54  static bool Initialized = false;
55  if (Initialized)
56  return StmtClassInfo[E];
57 
58  // Intialize the table on the first use.
59  Initialized = true;
60 #define ABSTRACT_STMT(STMT)
61 #define STMT(CLASS, PARENT) \
62  StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
63  StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
64 #include "clang/AST/StmtNodes.inc"
65 
66  return StmtClassInfo[E];
67 }
68 
69 void *Stmt::operator new(size_t bytes, const ASTContext& C,
70  unsigned alignment) {
71  return ::operator new(bytes, C, alignment);
72 }
73 
74 const char *Stmt::getStmtClassName() const {
75  return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
76 }
77 
79  // Ensure the table is primed.
80  getStmtInfoTableEntry(Stmt::NullStmtClass);
81 
82  unsigned sum = 0;
83  llvm::errs() << "\n*** Stmt/Expr Stats:\n";
84  for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
85  if (StmtClassInfo[i].Name == nullptr) continue;
86  sum += StmtClassInfo[i].Counter;
87  }
88  llvm::errs() << " " << sum << " stmts/exprs total.\n";
89  sum = 0;
90  for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
91  if (StmtClassInfo[i].Name == nullptr) continue;
92  if (StmtClassInfo[i].Counter == 0) continue;
93  llvm::errs() << " " << StmtClassInfo[i].Counter << " "
94  << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
95  << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size
96  << " bytes)\n";
98  }
99 
100  llvm::errs() << "Total bytes = " << sum << "\n";
101 }
102 
105 }
106 
107 bool Stmt::StatisticsEnabled = false;
109  StatisticsEnabled = true;
110 }
111 
113  Stmt *s = this;
114 
115  if (auto *ewc = dyn_cast<ExprWithCleanups>(s))
116  s = ewc->getSubExpr();
117 
118  if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
119  s = mte->GetTemporaryExpr();
120 
121  if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
122  s = bte->getSubExpr();
123 
124  while (auto *ice = dyn_cast<ImplicitCastExpr>(s))
125  s = ice->getSubExpr();
126 
127  return s;
128 }
129 
130 /// \brief Skip no-op (attributed, compound) container stmts and skip captured
131 /// stmt at the top, if \a IgnoreCaptured is true.
132 Stmt *Stmt::IgnoreContainers(bool IgnoreCaptured) {
133  Stmt *S = this;
134  if (IgnoreCaptured)
135  if (auto CapS = dyn_cast_or_null<CapturedStmt>(S))
136  S = CapS->getCapturedStmt();
137  while (true) {
138  if (auto AS = dyn_cast_or_null<AttributedStmt>(S))
139  S = AS->getSubStmt();
140  else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
141  if (CS->size() != 1)
142  break;
143  S = CS->body_back();
144  } else
145  break;
146  }
147  return S;
148 }
149 
150 /// \brief Strip off all label-like statements.
151 ///
152 /// This will strip off label statements, case statements, attributed
153 /// statements and default statements recursively.
155  const Stmt *S = this;
156  while (true) {
157  if (const LabelStmt *LS = dyn_cast<LabelStmt>(S))
158  S = LS->getSubStmt();
159  else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S))
160  S = SC->getSubStmt();
161  else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S))
162  S = AS->getSubStmt();
163  else
164  return S;
165  }
166 }
167 
168 namespace {
169 
170  struct good {};
171  struct bad {};
172 
173  // These silly little functions have to be static inline to suppress
174  // unused warnings, and they have to be defined to suppress other
175  // warnings.
176  static inline good is_good(good) { return good(); }
177 
178  typedef Stmt::child_range children_t();
179  template <class T> good implements_children(children_t T::*) {
180  return good();
181  }
182  LLVM_ATTRIBUTE_UNUSED
183  static inline bad implements_children(children_t Stmt::*) {
184  return bad();
185  }
186 
187  typedef SourceLocation getLocStart_t() const;
188  template <class T> good implements_getLocStart(getLocStart_t T::*) {
189  return good();
190  }
191  LLVM_ATTRIBUTE_UNUSED
192  static inline bad implements_getLocStart(getLocStart_t Stmt::*) {
193  return bad();
194  }
195 
196  typedef SourceLocation getLocEnd_t() const;
197  template <class T> good implements_getLocEnd(getLocEnd_t T::*) {
198  return good();
199  }
200  LLVM_ATTRIBUTE_UNUSED
201  static inline bad implements_getLocEnd(getLocEnd_t Stmt::*) {
202  return bad();
203  }
204 
205 #define ASSERT_IMPLEMENTS_children(type) \
206  (void) is_good(implements_children(&type::children))
207 #define ASSERT_IMPLEMENTS_getLocStart(type) \
208  (void) is_good(implements_getLocStart(&type::getLocStart))
209 #define ASSERT_IMPLEMENTS_getLocEnd(type) \
210  (void) is_good(implements_getLocEnd(&type::getLocEnd))
211 
212 } // namespace
213 
214 /// Check whether the various Stmt classes implement their member
215 /// functions.
216 LLVM_ATTRIBUTE_UNUSED
217 static inline void check_implementations() {
218 #define ABSTRACT_STMT(type)
219 #define STMT(type, base) \
220  ASSERT_IMPLEMENTS_children(type); \
221  ASSERT_IMPLEMENTS_getLocStart(type); \
222  ASSERT_IMPLEMENTS_getLocEnd(type);
223 #include "clang/AST/StmtNodes.inc"
224 }
225 
227  switch (getStmtClass()) {
228  case Stmt::NoStmtClass: llvm_unreachable("statement without class");
229 #define ABSTRACT_STMT(type)
230 #define STMT(type, base) \
231  case Stmt::type##Class: \
232  return static_cast<type*>(this)->children();
233 #include "clang/AST/StmtNodes.inc"
234  }
235  llvm_unreachable("unknown statement kind!");
236 }
237 
238 // Amusing macro metaprogramming hack: check whether a class provides
239 // a more specific implementation of getSourceRange.
240 //
241 // See also Expr.cpp:getExprLoc().
242 namespace {
243 
244  /// This implementation is used when a class provides a custom
245  /// implementation of getSourceRange.
246  template <class S, class T>
247  SourceRange getSourceRangeImpl(const Stmt *stmt,
248  SourceRange (T::*v)() const) {
249  return static_cast<const S*>(stmt)->getSourceRange();
250  }
251 
252  /// This implementation is used when a class doesn't provide a custom
253  /// implementation of getSourceRange. Overload resolution should pick it over
254  /// the implementation above because it's more specialized according to
255  /// function template partial ordering.
256  template <class S>
257  SourceRange getSourceRangeImpl(const Stmt *stmt,
258  SourceRange (Stmt::*v)() const) {
259  return SourceRange(static_cast<const S*>(stmt)->getLocStart(),
260  static_cast<const S*>(stmt)->getLocEnd());
261  }
262 
263 } // namespace
264 
266  switch (getStmtClass()) {
267  case Stmt::NoStmtClass: llvm_unreachable("statement without class");
268 #define ABSTRACT_STMT(type)
269 #define STMT(type, base) \
270  case Stmt::type##Class: \
271  return getSourceRangeImpl<type>(this, &type::getSourceRange);
272 #include "clang/AST/StmtNodes.inc"
273  }
274  llvm_unreachable("unknown statement kind!");
275 }
276 
278 // llvm::errs() << "getLocStart() for " << getStmtClassName() << "\n";
279  switch (getStmtClass()) {
280  case Stmt::NoStmtClass: llvm_unreachable("statement without class");
281 #define ABSTRACT_STMT(type)
282 #define STMT(type, base) \
283  case Stmt::type##Class: \
284  return static_cast<const type*>(this)->getLocStart();
285 #include "clang/AST/StmtNodes.inc"
286  }
287  llvm_unreachable("unknown statement kind");
288 }
289 
291  switch (getStmtClass()) {
292  case Stmt::NoStmtClass: llvm_unreachable("statement without class");
293 #define ABSTRACT_STMT(type)
294 #define STMT(type, base) \
295  case Stmt::type##Class: \
296  return static_cast<const type*>(this)->getLocEnd();
297 #include "clang/AST/StmtNodes.inc"
298  }
299  llvm_unreachable("unknown statement kind");
300 }
301 
304  : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
305  CompoundStmtBits.NumStmts = Stmts.size();
306  assert(CompoundStmtBits.NumStmts == Stmts.size() &&
307  "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
308 
309  if (Stmts.empty()) {
310  Body = nullptr;
311  return;
312  }
313 
314  Body = new (C) Stmt*[Stmts.size()];
315  std::copy(Stmts.begin(), Stmts.end(), Body);
316 }
317 
319  if (Body)
320  C.Deallocate(Body);
321  CompoundStmtBits.NumStmts = Stmts.size();
322  assert(CompoundStmtBits.NumStmts == Stmts.size() &&
323  "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
324 
325  Body = new (C) Stmt*[Stmts.size()];
326  std::copy(Stmts.begin(), Stmts.end(), Body);
327 }
328 
329 const char *LabelStmt::getName() const {
330  return getDecl()->getIdentifier()->getNameStart();
331 }
332 
334  ArrayRef<const Attr*> Attrs,
335  Stmt *SubStmt) {
336  assert(!Attrs.empty() && "Attrs should not be empty");
337  void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * Attrs.size(),
338  alignof(AttributedStmt));
339  return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
340 }
341 
343  unsigned NumAttrs) {
344  assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
345  void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * NumAttrs,
346  alignof(AttributedStmt));
347  return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
348 }
349 
350 std::string AsmStmt::generateAsmString(const ASTContext &C) const {
351  if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
352  return gccAsmStmt->generateAsmString(C);
353  if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
354  return msAsmStmt->generateAsmString(C);
355  llvm_unreachable("unknown asm statement kind!");
356 }
357 
358 StringRef AsmStmt::getOutputConstraint(unsigned i) const {
359  if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
360  return gccAsmStmt->getOutputConstraint(i);
361  if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
362  return msAsmStmt->getOutputConstraint(i);
363  llvm_unreachable("unknown asm statement kind!");
364 }
365 
366 const Expr *AsmStmt::getOutputExpr(unsigned i) const {
367  if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
368  return gccAsmStmt->getOutputExpr(i);
369  if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
370  return msAsmStmt->getOutputExpr(i);
371  llvm_unreachable("unknown asm statement kind!");
372 }
373 
374 StringRef AsmStmt::getInputConstraint(unsigned i) const {
375  if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
376  return gccAsmStmt->getInputConstraint(i);
377  if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
378  return msAsmStmt->getInputConstraint(i);
379  llvm_unreachable("unknown asm statement kind!");
380 }
381 
382 const Expr *AsmStmt::getInputExpr(unsigned i) const {
383  if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
384  return gccAsmStmt->getInputExpr(i);
385  if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
386  return msAsmStmt->getInputExpr(i);
387  llvm_unreachable("unknown asm statement kind!");
388 }
389 
390 StringRef AsmStmt::getClobber(unsigned i) const {
391  if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
392  return gccAsmStmt->getClobber(i);
393  if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this))
394  return msAsmStmt->getClobber(i);
395  llvm_unreachable("unknown asm statement kind!");
396 }
397 
398 /// getNumPlusOperands - Return the number of output operands that have a "+"
399 /// constraint.
400 unsigned AsmStmt::getNumPlusOperands() const {
401  unsigned Res = 0;
402  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
403  if (isOutputPlusConstraint(i))
404  ++Res;
405  return Res;
406 }
407 
409  assert(isOperand() && "Only Operands can have modifiers.");
410  return isLetter(Str[0]) ? Str[0] : '\0';
411 }
412 
413 StringRef GCCAsmStmt::getClobber(unsigned i) const {
414  return getClobberStringLiteral(i)->getString();
415 }
416 
418  return cast<Expr>(Exprs[i]);
419 }
420 
421 /// getOutputConstraint - Return the constraint string for the specified
422 /// output operand. All output constraints are known to be non-empty (either
423 /// '=' or '+').
424 StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {
425  return getOutputConstraintLiteral(i)->getString();
426 }
427 
429  return cast<Expr>(Exprs[i + NumOutputs]);
430 }
431 
432 void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {
433  Exprs[i + NumOutputs] = E;
434 }
435 
436 /// getInputConstraint - Return the specified input constraint. Unlike output
437 /// constraints, these can be empty.
438 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
439  return getInputConstraintLiteral(i)->getString();
440 }
441 
442 void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
443  IdentifierInfo **Names,
444  StringLiteral **Constraints,
445  Stmt **Exprs,
446  unsigned NumOutputs,
447  unsigned NumInputs,
448  StringLiteral **Clobbers,
449  unsigned NumClobbers) {
450  this->NumOutputs = NumOutputs;
451  this->NumInputs = NumInputs;
452  this->NumClobbers = NumClobbers;
453 
454  unsigned NumExprs = NumOutputs + NumInputs;
455 
456  C.Deallocate(this->Names);
457  this->Names = new (C) IdentifierInfo*[NumExprs];
458  std::copy(Names, Names + NumExprs, this->Names);
459 
460  C.Deallocate(this->Exprs);
461  this->Exprs = new (C) Stmt*[NumExprs];
462  std::copy(Exprs, Exprs + NumExprs, this->Exprs);
463 
464  C.Deallocate(this->Constraints);
465  this->Constraints = new (C) StringLiteral*[NumExprs];
466  std::copy(Constraints, Constraints + NumExprs, this->Constraints);
467 
468  C.Deallocate(this->Clobbers);
469  this->Clobbers = new (C) StringLiteral*[NumClobbers];
470  std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
471 }
472 
473 /// getNamedOperand - Given a symbolic operand reference like %[foo],
474 /// translate this into a numeric value needed to reference the same operand.
475 /// This returns -1 if the operand name is invalid.
476 int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
477  unsigned NumPlusOperands = 0;
478 
479  // Check if this is an output operand.
480  for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
481  if (getOutputName(i) == SymbolicName)
482  return i;
483  }
484 
485  for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
486  if (getInputName(i) == SymbolicName)
487  return getNumOutputs() + NumPlusOperands + i;
488 
489  // Not found.
490  return -1;
491 }
492 
493 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
494 /// it into pieces. If the asm string is erroneous, emit errors and return
495 /// true, otherwise return false.
497  const ASTContext &C, unsigned &DiagOffs) const {
498  StringRef Str = getAsmString()->getString();
499  const char *StrStart = Str.begin();
500  const char *StrEnd = Str.end();
501  const char *CurPtr = StrStart;
502 
503  // "Simple" inline asms have no constraints or operands, just convert the asm
504  // string to escape $'s.
505  if (isSimple()) {
506  std::string Result;
507  for (; CurPtr != StrEnd; ++CurPtr) {
508  switch (*CurPtr) {
509  case '$':
510  Result += "$$";
511  break;
512  default:
513  Result += *CurPtr;
514  break;
515  }
516  }
517  Pieces.push_back(AsmStringPiece(Result));
518  return 0;
519  }
520 
521  // CurStringPiece - The current string that we are building up as we scan the
522  // asm string.
523  std::string CurStringPiece;
524 
525  bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
526 
527  unsigned LastAsmStringToken = 0;
528  unsigned LastAsmStringOffset = 0;
529 
530  while (true) {
531  // Done with the string?
532  if (CurPtr == StrEnd) {
533  if (!CurStringPiece.empty())
534  Pieces.push_back(AsmStringPiece(CurStringPiece));
535  return 0;
536  }
537 
538  char CurChar = *CurPtr++;
539  switch (CurChar) {
540  case '$': CurStringPiece += "$$"; continue;
541  case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
542  case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
543  case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
544  case '%':
545  break;
546  default:
547  CurStringPiece += CurChar;
548  continue;
549  }
550 
551  // Escaped "%" character in asm string.
552  if (CurPtr == StrEnd) {
553  // % at end of string is invalid (no escape).
554  DiagOffs = CurPtr-StrStart-1;
555  return diag::err_asm_invalid_escape;
556  }
557  // Handle escaped char and continue looping over the asm string.
558  char EscapedChar = *CurPtr++;
559  switch (EscapedChar) {
560  default:
561  break;
562  case '%': // %% -> %
563  case '{': // %{ -> {
564  case '}': // %} -> }
565  CurStringPiece += EscapedChar;
566  continue;
567  case '=': // %= -> Generate a unique ID.
568  CurStringPiece += "${:uid}";
569  continue;
570  }
571 
572  // Otherwise, we have an operand. If we have accumulated a string so far,
573  // add it to the Pieces list.
574  if (!CurStringPiece.empty()) {
575  Pieces.push_back(AsmStringPiece(CurStringPiece));
576  CurStringPiece.clear();
577  }
578 
579  // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
580  // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
581 
582  const char *Begin = CurPtr - 1; // Points to the character following '%'.
583  const char *Percent = Begin - 1; // Points to '%'.
584 
585  if (isLetter(EscapedChar)) {
586  if (CurPtr == StrEnd) { // Premature end.
587  DiagOffs = CurPtr-StrStart-1;
588  return diag::err_asm_invalid_escape;
589  }
590  EscapedChar = *CurPtr++;
591  }
592 
593  const TargetInfo &TI = C.getTargetInfo();
594  const SourceManager &SM = C.getSourceManager();
595  const LangOptions &LO = C.getLangOpts();
596 
597  // Handle operands that don't have asmSymbolicName (e.g., %x4).
598  if (isDigit(EscapedChar)) {
599  // %n - Assembler operand n
600  unsigned N = 0;
601 
602  --CurPtr;
603  while (CurPtr != StrEnd && isDigit(*CurPtr))
604  N = N*10 + ((*CurPtr++)-'0');
605 
606  unsigned NumOperands =
607  getNumOutputs() + getNumPlusOperands() + getNumInputs();
608  if (N >= NumOperands) {
609  DiagOffs = CurPtr-StrStart-1;
610  return diag::err_asm_invalid_operand_number;
611  }
612 
613  // Str contains "x4" (Operand without the leading %).
614  std::string Str(Begin, CurPtr - Begin);
615 
616  // (BeginLoc, EndLoc) represents the range of the operand we are currently
617  // processing. Unlike Str, the range includes the leading '%'.
618  SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
619  Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
620  &LastAsmStringOffset);
621  SourceLocation EndLoc = getAsmString()->getLocationOfByte(
622  CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
623  &LastAsmStringOffset);
624 
625  Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
626  continue;
627  }
628 
629  // Handle operands that have asmSymbolicName (e.g., %x[foo]).
630  if (EscapedChar == '[') {
631  DiagOffs = CurPtr-StrStart-1;
632 
633  // Find the ']'.
634  const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
635  if (NameEnd == nullptr)
636  return diag::err_asm_unterminated_symbolic_operand_name;
637  if (NameEnd == CurPtr)
638  return diag::err_asm_empty_symbolic_operand_name;
639 
640  StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
641 
642  int N = getNamedOperand(SymbolicName);
643  if (N == -1) {
644  // Verify that an operand with that name exists.
645  DiagOffs = CurPtr-StrStart;
646  return diag::err_asm_unknown_symbolic_operand_name;
647  }
648 
649  // Str contains "x[foo]" (Operand without the leading %).
650  std::string Str(Begin, NameEnd + 1 - Begin);
651 
652  // (BeginLoc, EndLoc) represents the range of the operand we are currently
653  // processing. Unlike Str, the range includes the leading '%'.
654  SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
655  Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
656  &LastAsmStringOffset);
657  SourceLocation EndLoc = getAsmString()->getLocationOfByte(
658  NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
659  &LastAsmStringOffset);
660 
661  Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
662 
663  CurPtr = NameEnd+1;
664  continue;
665  }
666 
667  DiagOffs = CurPtr-StrStart-1;
668  return diag::err_asm_invalid_escape;
669  }
670 }
671 
672 /// Assemble final IR asm string (GCC-style).
673 std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
674  // Analyze the asm string to decompose it into its pieces. We know that Sema
675  // has already done this, so it is guaranteed to be successful.
677  unsigned DiagOffs;
678  AnalyzeAsmString(Pieces, C, DiagOffs);
679 
680  std::string AsmString;
681  for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
682  if (Pieces[i].isString())
683  AsmString += Pieces[i].getString();
684  else if (Pieces[i].getModifier() == '\0')
685  AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo());
686  else
687  AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' +
688  Pieces[i].getModifier() + '}';
689  }
690  return AsmString;
691 }
692 
693 /// Assemble final IR asm string (MS-style).
694 std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
695  // FIXME: This needs to be translated into the IR string representation.
696  return AsmStr;
697 }
698 
700  return cast<Expr>(Exprs[i]);
701 }
702 
704  return cast<Expr>(Exprs[i + NumOutputs]);
705 }
706 
707 void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
708  Exprs[i + NumOutputs] = E;
709 }
710 
711 //===----------------------------------------------------------------------===//
712 // Constructors
713 //===----------------------------------------------------------------------===//
714 
716  bool issimple, bool isvolatile, unsigned numoutputs,
717  unsigned numinputs, IdentifierInfo **names,
718  StringLiteral **constraints, Expr **exprs,
719  StringLiteral *asmstr, unsigned numclobbers,
720  StringLiteral **clobbers, SourceLocation rparenloc)
721  : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
722  numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
723  unsigned NumExprs = NumOutputs + NumInputs;
724 
725  Names = new (C) IdentifierInfo*[NumExprs];
726  std::copy(names, names + NumExprs, Names);
727 
728  Exprs = new (C) Stmt*[NumExprs];
729  std::copy(exprs, exprs + NumExprs, Exprs);
730 
731  Constraints = new (C) StringLiteral*[NumExprs];
732  std::copy(constraints, constraints + NumExprs, Constraints);
733 
734  Clobbers = new (C) StringLiteral*[NumClobbers];
735  std::copy(clobbers, clobbers + NumClobbers, Clobbers);
736 }
737 
739  SourceLocation lbraceloc, bool issimple, bool isvolatile,
740  ArrayRef<Token> asmtoks, unsigned numoutputs,
741  unsigned numinputs,
742  ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
743  StringRef asmstr, ArrayRef<StringRef> clobbers,
744  SourceLocation endloc)
745  : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
746  numinputs, clobbers.size()), LBraceLoc(lbraceloc),
747  EndLoc(endloc), NumAsmToks(asmtoks.size()) {
748  initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
749 }
750 
751 static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
752  return str.copy(C);
753 }
754 
755 void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
756  ArrayRef<Token> asmtoks,
757  ArrayRef<StringRef> constraints,
758  ArrayRef<Expr*> exprs,
759  ArrayRef<StringRef> clobbers) {
760  assert(NumAsmToks == asmtoks.size());
761  assert(NumClobbers == clobbers.size());
762 
763  assert(exprs.size() == NumOutputs + NumInputs);
764  assert(exprs.size() == constraints.size());
765 
766  AsmStr = copyIntoContext(C, asmstr);
767 
768  Exprs = new (C) Stmt*[exprs.size()];
769  std::copy(exprs.begin(), exprs.end(), Exprs);
770 
771  AsmToks = new (C) Token[asmtoks.size()];
772  std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
773 
774  Constraints = new (C) StringRef[exprs.size()];
775  std::transform(constraints.begin(), constraints.end(), Constraints,
776  [&](StringRef Constraint) {
777  return copyIntoContext(C, Constraint);
778  });
779 
780  Clobbers = new (C) StringRef[NumClobbers];
781  // FIXME: Avoid the allocation/copy if at all possible.
782  std::transform(clobbers.begin(), clobbers.end(), Clobbers,
783  [&](StringRef Clobber) {
784  return copyIntoContext(C, Clobber);
785  });
786 }
787 
788 IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, bool IsConstexpr,
789  Stmt *init, VarDecl *var, Expr *cond, Stmt *then,
790  SourceLocation EL, Stmt *elsev)
791  : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) {
792  setConstexpr(IsConstexpr);
793  setConditionVariable(C, var);
794  SubExprs[INIT] = init;
795  SubExprs[COND] = cond;
796  SubExprs[THEN] = then;
797  SubExprs[ELSE] = elsev;
798 }
799 
801  if (!SubExprs[VAR])
802  return nullptr;
803 
804  DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
805  return cast<VarDecl>(DS->getSingleDecl());
806 }
807 
809  if (!V) {
810  SubExprs[VAR] = nullptr;
811  return;
812  }
813 
814  SourceRange VarRange = V->getSourceRange();
815  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
816  VarRange.getEnd());
817 }
818 
820  return isa<ObjCAvailabilityCheckExpr>(SubExprs[COND]);
821 }
822 
823 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
824  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
825  SourceLocation RP)
826  : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
827 {
828  SubExprs[INIT] = Init;
829  setConditionVariable(C, condVar);
830  SubExprs[COND] = Cond;
831  SubExprs[INC] = Inc;
832  SubExprs[BODY] = Body;
833 }
834 
836  if (!SubExprs[CONDVAR])
837  return nullptr;
838 
839  DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
840  return cast<VarDecl>(DS->getSingleDecl());
841 }
842 
844  if (!V) {
845  SubExprs[CONDVAR] = nullptr;
846  return;
847  }
848 
849  SourceRange VarRange = V->getSourceRange();
850  SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
851  VarRange.getEnd());
852 }
853 
855  Expr *cond)
856  : Stmt(SwitchStmtClass), FirstCase(nullptr, false) {
857  setConditionVariable(C, Var);
858  SubExprs[INIT] = init;
859  SubExprs[COND] = cond;
860  SubExprs[BODY] = nullptr;
861 }
862 
864  if (!SubExprs[VAR])
865  return nullptr;
866 
867  DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
868  return cast<VarDecl>(DS->getSingleDecl());
869 }
870 
872  if (!V) {
873  SubExprs[VAR] = nullptr;
874  return;
875  }
876 
877  SourceRange VarRange = V->getSourceRange();
878  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
879  VarRange.getEnd());
880 }
881 
883  if (isa<CaseStmt>(this))
884  return cast<CaseStmt>(this)->getSubStmt();
885  return cast<DefaultStmt>(this)->getSubStmt();
886 }
887 
888 WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
889  SourceLocation WL)
890  : Stmt(WhileStmtClass) {
891  setConditionVariable(C, Var);
892  SubExprs[COND] = cond;
893  SubExprs[BODY] = body;
894  WhileLoc = WL;
895 }
896 
898  if (!SubExprs[VAR])
899  return nullptr;
900 
901  DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
902  return cast<VarDecl>(DS->getSingleDecl());
903 }
904 
906  if (!V) {
907  SubExprs[VAR] = nullptr;
908  return;
909  }
910 
911  SourceRange VarRange = V->getSourceRange();
912  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
913  VarRange.getEnd());
914 }
915 
916 // IndirectGotoStmt
918  if (AddrLabelExpr *E =
919  dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
920  return E->getLabel();
921  return nullptr;
922 }
923 
924 // ReturnStmt
926  return cast_or_null<Expr>(RetExpr);
927 }
929  return cast_or_null<Expr>(RetExpr);
930 }
931 
932 SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
933  Stmt *Handler)
934  : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
935  Children[TRY] = TryBlock;
936  Children[HANDLER] = Handler;
937 }
938 
939 SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
940  SourceLocation TryLoc, Stmt *TryBlock,
941  Stmt *Handler) {
942  return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
943 }
944 
946  return dyn_cast<SEHExceptStmt>(getHandler());
947 }
948 
950  return dyn_cast<SEHFinallyStmt>(getHandler());
951 }
952 
953 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
954  : Stmt(SEHExceptStmtClass), Loc(Loc) {
955  Children[FILTER_EXPR] = FilterExpr;
956  Children[BLOCK] = Block;
957 }
958 
960  Expr *FilterExpr, Stmt *Block) {
961  return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
962 }
963 
964 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
965  : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
966 
968  Stmt *Block) {
969  return new(C)SEHFinallyStmt(Loc,Block);
970 }
971 
973  VarDecl *Var)
974  : VarAndKind(Var, Kind), Loc(Loc) {
975  switch (Kind) {
976  case VCK_This:
977  assert(!Var && "'this' capture cannot have a variable!");
978  break;
979  case VCK_ByRef:
980  assert(Var && "capturing by reference must have a variable!");
981  break;
982  case VCK_ByCopy:
983  assert(Var && "capturing by copy must have a variable!");
984  assert(
985  (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
986  Var->getType()
987  ->castAs<ReferenceType>()
988  ->getPointeeType()
989  ->isScalarType())) &&
990  "captures by copy are expected to have a scalar type!");
991  break;
992  case VCK_VLAType:
993  assert(!Var &&
994  "Variable-length array type capture cannot have a variable!");
995  break;
996  }
997 }
998 
1001  return VarAndKind.getInt();
1002 }
1003 
1005  assert((capturesVariable() || capturesVariableByCopy()) &&
1006  "No variable available for 'this' or VAT capture");
1007  return VarAndKind.getPointer();
1008 }
1009 
1010 CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
1011  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1012 
1013  // Offset of the first Capture object.
1014  unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));
1015 
1016  return reinterpret_cast<Capture *>(
1017  reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1018  + FirstCaptureOffset);
1019 }
1020 
1021 CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1022  ArrayRef<Capture> Captures,
1023  ArrayRef<Expr *> CaptureInits,
1024  CapturedDecl *CD,
1025  RecordDecl *RD)
1026  : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1027  CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
1028  assert( S && "null captured statement");
1029  assert(CD && "null captured declaration for captured statement");
1030  assert(RD && "null record declaration for captured statement");
1031 
1032  // Copy initialization expressions.
1033  Stmt **Stored = getStoredStmts();
1034  for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1035  *Stored++ = CaptureInits[I];
1036 
1037  // Copy the statement being captured.
1038  *Stored = S;
1039 
1040  // Copy all Capture objects.
1041  Capture *Buffer = getStoredCaptures();
1042  std::copy(Captures.begin(), Captures.end(), Buffer);
1043 }
1044 
1045 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1046  : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1047  CapDeclAndKind(nullptr, CR_Default) {
1048  getStoredStmts()[NumCaptures] = nullptr;
1049 }
1050 
1053  ArrayRef<Capture> Captures,
1054  ArrayRef<Expr *> CaptureInits,
1055  CapturedDecl *CD,
1056  RecordDecl *RD) {
1057  // The layout is
1058  //
1059  // -----------------------------------------------------------
1060  // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1061  // ----------------^-------------------^----------------------
1062  // getStoredStmts() getStoredCaptures()
1063  //
1064  // where S is the statement being captured.
1065  //
1066  assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1067 
1068  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1069  if (!Captures.empty()) {
1070  // Realign for the following Capture array.
1071  Size = llvm::alignTo(Size, alignof(Capture));
1072  Size += sizeof(Capture) * Captures.size();
1073  }
1074 
1075  void *Mem = Context.Allocate(Size);
1076  return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1077 }
1078 
1080  unsigned NumCaptures) {
1081  unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1082  if (NumCaptures > 0) {
1083  // Realign for the following Capture array.
1084  Size = llvm::alignTo(Size, alignof(Capture));
1085  Size += sizeof(Capture) * NumCaptures;
1086  }
1087 
1088  void *Mem = Context.Allocate(Size);
1089  return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1090 }
1091 
1093  // Children are captured field initializers.
1094  return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1095 }
1096 
1098  return CapDeclAndKind.getPointer();
1099 }
1100 
1102  return CapDeclAndKind.getPointer();
1103 }
1104 
1105 /// \brief Set the outlined function declaration.
1107  assert(D && "null CapturedDecl");
1108  CapDeclAndKind.setPointer(D);
1109 }
1110 
1111 /// \brief Retrieve the captured region kind.
1113  return CapDeclAndKind.getInt();
1114 }
1115 
1116 /// \brief Set the captured region kind.
1118  CapDeclAndKind.setInt(Kind);
1119 }
1120 
1121 bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
1122  for (const auto &I : captures()) {
1123  if (!I.capturesVariable() && !I.capturesVariableByCopy())
1124  continue;
1125  if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
1126  return true;
1127  }
1128 
1129  return false;
1130 }
static AttributedStmt * CreateEmpty(const ASTContext &C, unsigned NumAttrs)
Definition: Stmt.cpp:342
void setConditionVariable(const ASTContext &C, VarDecl *V)
Definition: Stmt.cpp:843
Defines the clang::ASTContext interface.
Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var=nullptr)
Create a new capture.
Definition: Stmt.cpp:972
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:1616
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Stmt - This represents one statement.
Definition: Stmt.h:66
const char * Name
Definition: Stmt.cpp:48
VarDecl * getCapturedVar() const
Retrieve the declaration of the variable being captured.
Definition: Stmt.cpp:1004
C Language Family Type Representation.
Represents an attribute applied to a statement.
Definition: Stmt.h:878
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc)
Definition: Stmt.cpp:715
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:443
unsigned NumOutputs
Definition: Stmt.h:1475
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:671
Stmt * IgnoreImplicit()
Skip past any implicit AST nodes which might surround this statement, such as ExprWithCleanups or Imp...
Definition: Stmt.cpp:112
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr *> Attrs, Stmt *SubStmt)
Definition: Stmt.cpp:333
static void addStmtClass(const StmtClass s)
Definition: Stmt.cpp:103
void setConditionVariable(const ASTContext &C, VarDecl *V)
Definition: Stmt.cpp:905
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "while" statement, if any.
Definition: Stmt.cpp:897
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1121
void setInputExpr(unsigned i, Expr *E)
Definition: Stmt.cpp:707
void setInputExpr(unsigned i, Expr *E)
Definition: Stmt.cpp:432
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:807
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:496
void setStmts(const ASTContext &C, ArrayRef< Stmt *> Stmts)
Definition: Stmt.cpp:318
const char * getName() const
Definition: Stmt.cpp:329
Defines the Objective-C statement AST node classes.
static StringRef bytes(const std::vector< T, Allocator > &v)
Definition: ASTWriter.cpp:119
int getNamedOperand(StringRef SymbolicName) const
getNamedOperand - Given a symbolic operand reference like %[foo], translate this into a numeric value...
Definition: Stmt.cpp:476
Defines the clang::Expr interface and subclasses for C++ expressions.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "switch" statement, if any.
Definition: Stmt.cpp:863
Stmt(StmtClass SC, EmptyShell)
Construct an empty statement.
Definition: Stmt.h:366
static struct StmtClassNameTable StmtClassInfo[Stmt::lastStmtConstant+1]
const char * getStmtClassName() const
Definition: Stmt.cpp:74
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:839
RecordDecl - Represents a struct/union/class.
Definition: Decl.h:3482
One of these records is kept for each identifier that is lexed.
IfStmt(const ASTContext &C, SourceLocation IL, bool IsConstexpr, Stmt *init, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL=SourceLocation(), Stmt *elsev=nullptr)
Definition: Stmt.cpp:788
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
Definition: Stmt.cpp:888
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
Definition: CharInfo.h:112
const Expr * getRetValue() const
Definition: Stmt.cpp:925
bool isReferenceType() const
Definition: Type.h:5956
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
void setCapturedDecl(CapturedDecl *D)
Set the outlined function declaration.
Definition: Stmt.cpp:1106
bool hasNoAsmVariants() const
Return true if {|} are normal characters in the asm string.
Definition: TargetInfo.h:966
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD)
Definition: Stmt.cpp:1051
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const Expr * getOutputExpr(unsigned i) const
Definition: Stmt.cpp:366
child_range children()
Definition: Stmt.cpp:226
Expr * getOutputExpr(unsigned i)
Definition: Stmt.cpp:417
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:694
unsigned getNumPlusOperands() const
getNumPlusOperands - Return the number of output operands that have a "+" constraint.
Definition: Stmt.cpp:400
bool isScalarType() const
Definition: Type.h:6206
This represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:3860
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
Definition: Stmt.cpp:835
StmtClass
Definition: Stmt.h:68
MSAsmStmt(const ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef< Token > asmtoks, unsigned numoutputs, unsigned numinputs, ArrayRef< StringRef > constraints, ArrayRef< Expr *> exprs, StringRef asmstr, ArrayRef< StringRef > clobbers, SourceLocation endloc)
Definition: Stmt.cpp:738
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Definition: Stmt.cpp:939
StringRef getClobber(unsigned i) const
Definition: Stmt.cpp:413
unsigned NumClobbers
Definition: Stmt.h:1477
Describes the capture of either a variable, or &#39;this&#39;, or variable-length array type.
Definition: Stmt.h:2067
SourceLocation getLocEnd() const LLVM_READONLY
Definition: Stmt.cpp:290
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:350
Exposes information about the current target.
Definition: TargetInfo.h:54
CompoundStmt(const ASTContext &C, ArrayRef< Stmt *> Stmts, SourceLocation LB, SourceLocation RB)
Definition: Stmt.cpp:302
Expr - This represents one expression.
Definition: Expr.h:106
const FunctionProtoType * T
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
Definition: Stmt.cpp:132
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:6370
AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...
Definition: Stmt.h:1649
VariableCaptureKind getCaptureKind() const
Determine the kind of capture.
Definition: Stmt.cpp:1000
LabelDecl * getConstantTarget()
getConstantTarget - Returns the fixed target of this indirect goto, if one exists.
Definition: Stmt.cpp:917
SourceLocation Begin
child_range children()
Definition: Stmt.cpp:1092
CompoundStmtBitfields CompoundStmtBits
Definition: Stmt.h:286
static StringRef copyIntoContext(const ASTContext &C, StringRef str)
Definition: Stmt.cpp:751
This represents a Microsoft inline-assembly statement extension.
Definition: Stmt.h:1795
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
Definition: Stmt.cpp:438
SourceLocation getEnd() const
Expr * getInputExpr(unsigned i)
Definition: Stmt.cpp:703
Expr * getOutputExpr(unsigned i)
Definition: Stmt.cpp:699
StringRef getClobber(unsigned i) const
Definition: Stmt.cpp:390
The result type of a method or function.
do v
Definition: arm_acle.h:78
const SourceManager & SM
Definition: Format.cpp:1337
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:1973
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Definition: Stmt.cpp:967
AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
Definition: Stmt.h:1461
#define false
Definition: stdbool.h:33
Kind
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
Definition: Stmt.cpp:374
This captures a statement into a function.
Definition: Stmt.h:2054
StringRef getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
Definition: Stmt.cpp:358
Encodes a location in the source.
static void PrintStats()
Definition: Stmt.cpp:78
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Definition: Stmt.cpp:673
void setConstexpr(bool C)
Definition: Stmt.h:982
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:487
LabelDecl - Represents the declaration of a label.
Definition: Decl.h:460
bool capturesVariable() const
Determine whether this capture handles a variable (by reference).
Definition: Stmt.h:2095
void setConditionVariable(const ASTContext &C, VarDecl *V)
Definition: Stmt.cpp:871
StringRef getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
Definition: Stmt.cpp:424
Expr * getInputExpr(unsigned i)
Definition: Stmt.cpp:428
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:1905
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
Definition: Stmt.h:325
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:650
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:3444
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "if" statement, if any.
Definition: Stmt.cpp:800
Dataflow Directional Tag Classes.
static CapturedStmt * CreateDeserialized(const ASTContext &Context, unsigned NumCaptures)
Definition: Stmt.cpp:1079
const Stmt * stripLabelLikeStatements() const
Strip off all label-like statements.
Definition: Stmt.cpp:154
SourceRange getSourceRange(const SourceRange &Range)
Returns the SourceRange of a SourceRange.
Definition: FixIt.h:34
unsigned Counter
Definition: Stmt.cpp:49
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition: Stmt.cpp:945
const Decl * getSingleDecl() const
Definition: Stmt.h:504
static LLVM_ATTRIBUTE_UNUSED void check_implementations()
Check whether the various Stmt classes implement their member functions.
Definition: Stmt.cpp:217
char getModifier() const
getModifier - Get the modifier for this operand, if present.
Definition: Stmt.cpp:408
bool isObjCAvailabilityCheck() const
Definition: Stmt.cpp:819
bool capturesVariableByCopy() const
Determine whether this capture handles a variable by copy.
Definition: Stmt.h:2098
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Definition: CharInfo.h:94
void setConditionVariable(const ASTContext &C, VarDecl *V)
Definition: Stmt.cpp:808
This file defines OpenMP AST classes for executable directives and clauses.
SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond)
Definition: Stmt.cpp:854
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2421
const Expr * getInputExpr(unsigned i) const
Definition: Stmt.cpp:382
ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP)
Definition: Stmt.cpp:823
Stmt * getSubStmt()
Definition: Stmt.cpp:882
SourceManager & getSourceManager()
Definition: ASTContext.h:643
SEHFinallyStmt * getFinallyHandler() const
Definition: Stmt.cpp:949
Stmt ** Exprs
Definition: Stmt.h:1479
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1097
void Deallocate(void *Ptr) const
Definition: ASTContext.h:656
Defines the clang::SourceLocation class and associated facilities.
unsigned Size
Definition: Stmt.cpp:50
OpenMPLinearClauseKind getModifier() const
Return modifier.
VariableCaptureKind
The different capture forms: by &#39;this&#39;, by reference, capture for variable-length array type etc...
Definition: Stmt.h:2058
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:265
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1509
Defines the clang::TargetInfo interface.
capture_range captures()
Definition: Stmt.h:2189
CapturedRegionKind
The different kinds of captured statement.
Definition: CapturedStmt.h:17
QualType getType() const
Definition: Decl.h:639
static StmtClassNameTable & getStmtInfoTableEntry(Stmt::StmtClass E)
Definition: Stmt.cpp:53
A trivial tuple used to represent a source range.
unsigned NumInputs
Definition: Stmt.h:1476
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:277
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Definition: ASTContext.h:688
static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)
Definition: Stmt.cpp:959
This class handles loading and caching of source files into memory.
void setCapturedRegionKind(CapturedRegionKind Kind)
Set the captured region kind.
Definition: Stmt.cpp:1117
CapturedRegionKind getCapturedRegionKind() const
Retrieve the captured region kind.
Definition: Stmt.cpp:1112
Attr - This represents one attribute.
Definition: Attr.h:43
static void EnableStatistics()
Definition: Stmt.cpp:108
#define BLOCK(DERIVED, BASE)
Definition: Template.h:448