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