xref: /llvm-project-15.0.7/clang/lib/AST/Stmt.cpp (revision abacc253)
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 int64_t Stmt::getID(const ASTContext &Context) const {
306   Optional<int64_t> Out = Context.getAllocator().identifyObject(this);
307   assert(Out && "Wrong allocator used");
308   assert(*Out % alignof(Stmt) == 0 && "Wrong alignment information");
309   return *Out / alignof(Stmt);
310 }
311 
312 CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB,
313                            SourceLocation RB)
314     : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
315   CompoundStmtBits.NumStmts = Stmts.size();
316   setStmts(Stmts);
317 }
318 
319 void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
320   assert(CompoundStmtBits.NumStmts == Stmts.size() &&
321          "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
322 
323   std::copy(Stmts.begin(), Stmts.end(), body_begin());
324 }
325 
326 CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
327                                    SourceLocation LB, SourceLocation RB) {
328   void *Mem =
329       C.Allocate(totalSizeToAlloc<Stmt *>(Stmts.size()), alignof(CompoundStmt));
330   return new (Mem) CompoundStmt(Stmts, LB, RB);
331 }
332 
333 CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C,
334                                         unsigned NumStmts) {
335   void *Mem =
336       C.Allocate(totalSizeToAlloc<Stmt *>(NumStmts), alignof(CompoundStmt));
337   CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
338   New->CompoundStmtBits.NumStmts = NumStmts;
339   return New;
340 }
341 
342 const char *LabelStmt::getName() const {
343   return getDecl()->getIdentifier()->getNameStart();
344 }
345 
346 AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
347                                        ArrayRef<const Attr*> Attrs,
348                                        Stmt *SubStmt) {
349   assert(!Attrs.empty() && "Attrs should not be empty");
350   void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),
351                          alignof(AttributedStmt));
352   return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
353 }
354 
355 AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
356                                             unsigned NumAttrs) {
357   assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
358   void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),
359                          alignof(AttributedStmt));
360   return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
361 }
362 
363 std::string AsmStmt::generateAsmString(const ASTContext &C) const {
364   if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
365     return gccAsmStmt->generateAsmString(C);
366   if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
367     return msAsmStmt->generateAsmString(C);
368   llvm_unreachable("unknown asm statement kind!");
369 }
370 
371 StringRef AsmStmt::getOutputConstraint(unsigned i) const {
372   if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
373     return gccAsmStmt->getOutputConstraint(i);
374   if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
375     return msAsmStmt->getOutputConstraint(i);
376   llvm_unreachable("unknown asm statement kind!");
377 }
378 
379 const Expr *AsmStmt::getOutputExpr(unsigned i) const {
380   if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
381     return gccAsmStmt->getOutputExpr(i);
382   if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
383     return msAsmStmt->getOutputExpr(i);
384   llvm_unreachable("unknown asm statement kind!");
385 }
386 
387 StringRef AsmStmt::getInputConstraint(unsigned i) const {
388   if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
389     return gccAsmStmt->getInputConstraint(i);
390   if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
391     return msAsmStmt->getInputConstraint(i);
392   llvm_unreachable("unknown asm statement kind!");
393 }
394 
395 const Expr *AsmStmt::getInputExpr(unsigned i) const {
396   if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
397     return gccAsmStmt->getInputExpr(i);
398   if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
399     return msAsmStmt->getInputExpr(i);
400   llvm_unreachable("unknown asm statement kind!");
401 }
402 
403 StringRef AsmStmt::getClobber(unsigned i) const {
404   if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
405     return gccAsmStmt->getClobber(i);
406   if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
407     return msAsmStmt->getClobber(i);
408   llvm_unreachable("unknown asm statement kind!");
409 }
410 
411 /// getNumPlusOperands - Return the number of output operands that have a "+"
412 /// constraint.
413 unsigned AsmStmt::getNumPlusOperands() const {
414   unsigned Res = 0;
415   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
416     if (isOutputPlusConstraint(i))
417       ++Res;
418   return Res;
419 }
420 
421 char GCCAsmStmt::AsmStringPiece::getModifier() const {
422   assert(isOperand() && "Only Operands can have modifiers.");
423   return isLetter(Str[0]) ? Str[0] : '\0';
424 }
425 
426 StringRef GCCAsmStmt::getClobber(unsigned i) const {
427   return getClobberStringLiteral(i)->getString();
428 }
429 
430 Expr *GCCAsmStmt::getOutputExpr(unsigned i) {
431   return cast<Expr>(Exprs[i]);
432 }
433 
434 /// getOutputConstraint - Return the constraint string for the specified
435 /// output operand.  All output constraints are known to be non-empty (either
436 /// '=' or '+').
437 StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {
438   return getOutputConstraintLiteral(i)->getString();
439 }
440 
441 Expr *GCCAsmStmt::getInputExpr(unsigned i) {
442   return cast<Expr>(Exprs[i + NumOutputs]);
443 }
444 
445 void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {
446   Exprs[i + NumOutputs] = E;
447 }
448 
449 /// getInputConstraint - Return the specified input constraint.  Unlike output
450 /// constraints, these can be empty.
451 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
452   return getInputConstraintLiteral(i)->getString();
453 }
454 
455 void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
456                                                 IdentifierInfo **Names,
457                                                 StringLiteral **Constraints,
458                                                 Stmt **Exprs,
459                                                 unsigned NumOutputs,
460                                                 unsigned NumInputs,
461                                                 StringLiteral **Clobbers,
462                                                 unsigned NumClobbers) {
463   this->NumOutputs = NumOutputs;
464   this->NumInputs = NumInputs;
465   this->NumClobbers = NumClobbers;
466 
467   unsigned NumExprs = NumOutputs + NumInputs;
468 
469   C.Deallocate(this->Names);
470   this->Names = new (C) IdentifierInfo*[NumExprs];
471   std::copy(Names, Names + NumExprs, this->Names);
472 
473   C.Deallocate(this->Exprs);
474   this->Exprs = new (C) Stmt*[NumExprs];
475   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
476 
477   C.Deallocate(this->Constraints);
478   this->Constraints = new (C) StringLiteral*[NumExprs];
479   std::copy(Constraints, Constraints + NumExprs, this->Constraints);
480 
481   C.Deallocate(this->Clobbers);
482   this->Clobbers = new (C) StringLiteral*[NumClobbers];
483   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
484 }
485 
486 /// getNamedOperand - Given a symbolic operand reference like %[foo],
487 /// translate this into a numeric value needed to reference the same operand.
488 /// This returns -1 if the operand name is invalid.
489 int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
490   unsigned NumPlusOperands = 0;
491 
492   // Check if this is an output operand.
493   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
494     if (getOutputName(i) == SymbolicName)
495       return i;
496   }
497 
498   for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
499     if (getInputName(i) == SymbolicName)
500       return getNumOutputs() + NumPlusOperands + i;
501 
502   // Not found.
503   return -1;
504 }
505 
506 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
507 /// it into pieces.  If the asm string is erroneous, emit errors and return
508 /// true, otherwise return false.
509 unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
510                                 const ASTContext &C, unsigned &DiagOffs) const {
511   StringRef Str = getAsmString()->getString();
512   const char *StrStart = Str.begin();
513   const char *StrEnd = Str.end();
514   const char *CurPtr = StrStart;
515 
516   // "Simple" inline asms have no constraints or operands, just convert the asm
517   // string to escape $'s.
518   if (isSimple()) {
519     std::string Result;
520     for (; CurPtr != StrEnd; ++CurPtr) {
521       switch (*CurPtr) {
522       case '$':
523         Result += "$$";
524         break;
525       default:
526         Result += *CurPtr;
527         break;
528       }
529     }
530     Pieces.push_back(AsmStringPiece(Result));
531     return 0;
532   }
533 
534   // CurStringPiece - The current string that we are building up as we scan the
535   // asm string.
536   std::string CurStringPiece;
537 
538   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
539 
540   unsigned LastAsmStringToken = 0;
541   unsigned LastAsmStringOffset = 0;
542 
543   while (true) {
544     // Done with the string?
545     if (CurPtr == StrEnd) {
546       if (!CurStringPiece.empty())
547         Pieces.push_back(AsmStringPiece(CurStringPiece));
548       return 0;
549     }
550 
551     char CurChar = *CurPtr++;
552     switch (CurChar) {
553     case '$': CurStringPiece += "$$"; continue;
554     case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
555     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
556     case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
557     case '%':
558       break;
559     default:
560       CurStringPiece += CurChar;
561       continue;
562     }
563 
564     // Escaped "%" character in asm string.
565     if (CurPtr == StrEnd) {
566       // % at end of string is invalid (no escape).
567       DiagOffs = CurPtr-StrStart-1;
568       return diag::err_asm_invalid_escape;
569     }
570     // Handle escaped char and continue looping over the asm string.
571     char EscapedChar = *CurPtr++;
572     switch (EscapedChar) {
573     default:
574       break;
575     case '%': // %% -> %
576     case '{': // %{ -> {
577     case '}': // %} -> }
578       CurStringPiece += EscapedChar;
579       continue;
580     case '=': // %= -> Generate a unique ID.
581       CurStringPiece += "${:uid}";
582       continue;
583     }
584 
585     // Otherwise, we have an operand.  If we have accumulated a string so far,
586     // add it to the Pieces list.
587     if (!CurStringPiece.empty()) {
588       Pieces.push_back(AsmStringPiece(CurStringPiece));
589       CurStringPiece.clear();
590     }
591 
592     // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
593     // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
594 
595     const char *Begin = CurPtr - 1; // Points to the character following '%'.
596     const char *Percent = Begin - 1; // Points to '%'.
597 
598     if (isLetter(EscapedChar)) {
599       if (CurPtr == StrEnd) { // Premature end.
600         DiagOffs = CurPtr-StrStart-1;
601         return diag::err_asm_invalid_escape;
602       }
603       EscapedChar = *CurPtr++;
604     }
605 
606     const TargetInfo &TI = C.getTargetInfo();
607     const SourceManager &SM = C.getSourceManager();
608     const LangOptions &LO = C.getLangOpts();
609 
610     // Handle operands that don't have asmSymbolicName (e.g., %x4).
611     if (isDigit(EscapedChar)) {
612       // %n - Assembler operand n
613       unsigned N = 0;
614 
615       --CurPtr;
616       while (CurPtr != StrEnd && isDigit(*CurPtr))
617         N = N*10 + ((*CurPtr++)-'0');
618 
619       unsigned NumOperands =
620         getNumOutputs() + getNumPlusOperands() + getNumInputs();
621       if (N >= NumOperands) {
622         DiagOffs = CurPtr-StrStart-1;
623         return diag::err_asm_invalid_operand_number;
624       }
625 
626       // Str contains "x4" (Operand without the leading %).
627       std::string Str(Begin, CurPtr - Begin);
628 
629       // (BeginLoc, EndLoc) represents the range of the operand we are currently
630       // processing. Unlike Str, the range includes the leading '%'.
631       SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
632           Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
633           &LastAsmStringOffset);
634       SourceLocation EndLoc = getAsmString()->getLocationOfByte(
635           CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
636           &LastAsmStringOffset);
637 
638       Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
639       continue;
640     }
641 
642     // Handle operands that have asmSymbolicName (e.g., %x[foo]).
643     if (EscapedChar == '[') {
644       DiagOffs = CurPtr-StrStart-1;
645 
646       // Find the ']'.
647       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
648       if (NameEnd == nullptr)
649         return diag::err_asm_unterminated_symbolic_operand_name;
650       if (NameEnd == CurPtr)
651         return diag::err_asm_empty_symbolic_operand_name;
652 
653       StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
654 
655       int N = getNamedOperand(SymbolicName);
656       if (N == -1) {
657         // Verify that an operand with that name exists.
658         DiagOffs = CurPtr-StrStart;
659         return diag::err_asm_unknown_symbolic_operand_name;
660       }
661 
662       // Str contains "x[foo]" (Operand without the leading %).
663       std::string Str(Begin, NameEnd + 1 - Begin);
664 
665       // (BeginLoc, EndLoc) represents the range of the operand we are currently
666       // processing. Unlike Str, the range includes the leading '%'.
667       SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
668           Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
669           &LastAsmStringOffset);
670       SourceLocation EndLoc = getAsmString()->getLocationOfByte(
671           NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
672           &LastAsmStringOffset);
673 
674       Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
675 
676       CurPtr = NameEnd+1;
677       continue;
678     }
679 
680     DiagOffs = CurPtr-StrStart-1;
681     return diag::err_asm_invalid_escape;
682   }
683 }
684 
685 /// Assemble final IR asm string (GCC-style).
686 std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
687   // Analyze the asm string to decompose it into its pieces.  We know that Sema
688   // has already done this, so it is guaranteed to be successful.
689   SmallVector<GCCAsmStmt::AsmStringPiece, 4> Pieces;
690   unsigned DiagOffs;
691   AnalyzeAsmString(Pieces, C, DiagOffs);
692 
693   std::string AsmString;
694   for (const auto &Piece : Pieces) {
695     if (Piece.isString())
696       AsmString += Piece.getString();
697     else if (Piece.getModifier() == '\0')
698       AsmString += '$' + llvm::utostr(Piece.getOperandNo());
699     else
700       AsmString += "${" + llvm::utostr(Piece.getOperandNo()) + ':' +
701                    Piece.getModifier() + '}';
702   }
703   return AsmString;
704 }
705 
706 /// Assemble final IR asm string (MS-style).
707 std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
708   // FIXME: This needs to be translated into the IR string representation.
709   return AsmStr;
710 }
711 
712 Expr *MSAsmStmt::getOutputExpr(unsigned i) {
713   return cast<Expr>(Exprs[i]);
714 }
715 
716 Expr *MSAsmStmt::getInputExpr(unsigned i) {
717   return cast<Expr>(Exprs[i + NumOutputs]);
718 }
719 
720 void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
721   Exprs[i + NumOutputs] = E;
722 }
723 
724 //===----------------------------------------------------------------------===//
725 // Constructors
726 //===----------------------------------------------------------------------===//
727 
728 GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
729                        bool issimple, bool isvolatile, unsigned numoutputs,
730                        unsigned numinputs, IdentifierInfo **names,
731                        StringLiteral **constraints, Expr **exprs,
732                        StringLiteral *asmstr, unsigned numclobbers,
733                        StringLiteral **clobbers, SourceLocation rparenloc)
734     : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
735               numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
736   unsigned NumExprs = NumOutputs + NumInputs;
737 
738   Names = new (C) IdentifierInfo*[NumExprs];
739   std::copy(names, names + NumExprs, Names);
740 
741   Exprs = new (C) Stmt*[NumExprs];
742   std::copy(exprs, exprs + NumExprs, Exprs);
743 
744   Constraints = new (C) StringLiteral*[NumExprs];
745   std::copy(constraints, constraints + NumExprs, Constraints);
746 
747   Clobbers = new (C) StringLiteral*[NumClobbers];
748   std::copy(clobbers, clobbers + NumClobbers, Clobbers);
749 }
750 
751 MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
752                      SourceLocation lbraceloc, bool issimple, bool isvolatile,
753                      ArrayRef<Token> asmtoks, unsigned numoutputs,
754                      unsigned numinputs,
755                      ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
756                      StringRef asmstr, ArrayRef<StringRef> clobbers,
757                      SourceLocation endloc)
758     : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
759               numinputs, clobbers.size()), LBraceLoc(lbraceloc),
760               EndLoc(endloc), NumAsmToks(asmtoks.size()) {
761   initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
762 }
763 
764 static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
765   return str.copy(C);
766 }
767 
768 void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
769                            ArrayRef<Token> asmtoks,
770                            ArrayRef<StringRef> constraints,
771                            ArrayRef<Expr*> exprs,
772                            ArrayRef<StringRef> clobbers) {
773   assert(NumAsmToks == asmtoks.size());
774   assert(NumClobbers == clobbers.size());
775 
776   assert(exprs.size() == NumOutputs + NumInputs);
777   assert(exprs.size() == constraints.size());
778 
779   AsmStr = copyIntoContext(C, asmstr);
780 
781   Exprs = new (C) Stmt*[exprs.size()];
782   std::copy(exprs.begin(), exprs.end(), Exprs);
783 
784   AsmToks = new (C) Token[asmtoks.size()];
785   std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
786 
787   Constraints = new (C) StringRef[exprs.size()];
788   std::transform(constraints.begin(), constraints.end(), Constraints,
789                  [&](StringRef Constraint) {
790                    return copyIntoContext(C, Constraint);
791                  });
792 
793   Clobbers = new (C) StringRef[NumClobbers];
794   // FIXME: Avoid the allocation/copy if at all possible.
795   std::transform(clobbers.begin(), clobbers.end(), Clobbers,
796                  [&](StringRef Clobber) {
797                    return copyIntoContext(C, Clobber);
798                  });
799 }
800 
801 IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, bool IsConstexpr,
802                Stmt *init, VarDecl *var, Expr *cond, Stmt *then,
803                SourceLocation EL, Stmt *elsev)
804     : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) {
805   setConstexpr(IsConstexpr);
806   setConditionVariable(C, var);
807   SubExprs[INIT] = init;
808   SubExprs[COND] = cond;
809   SubExprs[THEN] = then;
810   SubExprs[ELSE] = elsev;
811 }
812 
813 VarDecl *IfStmt::getConditionVariable() const {
814   if (!SubExprs[VAR])
815     return nullptr;
816 
817   auto *DS = cast<DeclStmt>(SubExprs[VAR]);
818   return cast<VarDecl>(DS->getSingleDecl());
819 }
820 
821 void IfStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
822   if (!V) {
823     SubExprs[VAR] = nullptr;
824     return;
825   }
826 
827   SourceRange VarRange = V->getSourceRange();
828   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
829                                    VarRange.getEnd());
830 }
831 
832 bool IfStmt::isObjCAvailabilityCheck() const {
833   return isa<ObjCAvailabilityCheckExpr>(SubExprs[COND]);
834 }
835 
836 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
837                  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
838                  SourceLocation RP)
839   : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
840 {
841   SubExprs[INIT] = Init;
842   setConditionVariable(C, condVar);
843   SubExprs[COND] = Cond;
844   SubExprs[INC] = Inc;
845   SubExprs[BODY] = Body;
846 }
847 
848 VarDecl *ForStmt::getConditionVariable() const {
849   if (!SubExprs[CONDVAR])
850     return nullptr;
851 
852   auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
853   return cast<VarDecl>(DS->getSingleDecl());
854 }
855 
856 void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
857   if (!V) {
858     SubExprs[CONDVAR] = nullptr;
859     return;
860   }
861 
862   SourceRange VarRange = V->getSourceRange();
863   SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
864                                        VarRange.getEnd());
865 }
866 
867 SwitchStmt::SwitchStmt(const ASTContext &C, Stmt *init, VarDecl *Var,
868                        Expr *cond)
869     : Stmt(SwitchStmtClass), FirstCase(nullptr, false) {
870   setConditionVariable(C, Var);
871   SubExprs[INIT] = init;
872   SubExprs[COND] = cond;
873   SubExprs[BODY] = nullptr;
874 }
875 
876 VarDecl *SwitchStmt::getConditionVariable() const {
877   if (!SubExprs[VAR])
878     return nullptr;
879 
880   auto *DS = cast<DeclStmt>(SubExprs[VAR]);
881   return cast<VarDecl>(DS->getSingleDecl());
882 }
883 
884 void SwitchStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
885   if (!V) {
886     SubExprs[VAR] = nullptr;
887     return;
888   }
889 
890   SourceRange VarRange = V->getSourceRange();
891   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
892                                    VarRange.getEnd());
893 }
894 
895 Stmt *SwitchCase::getSubStmt() {
896   if (isa<CaseStmt>(this))
897     return cast<CaseStmt>(this)->getSubStmt();
898   return cast<DefaultStmt>(this)->getSubStmt();
899 }
900 
901 WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
902                      SourceLocation WL)
903   : Stmt(WhileStmtClass) {
904   setConditionVariable(C, Var);
905   SubExprs[COND] = cond;
906   SubExprs[BODY] = body;
907   WhileLoc = WL;
908 }
909 
910 VarDecl *WhileStmt::getConditionVariable() const {
911   if (!SubExprs[VAR])
912     return nullptr;
913 
914   auto *DS = cast<DeclStmt>(SubExprs[VAR]);
915   return cast<VarDecl>(DS->getSingleDecl());
916 }
917 
918 void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
919   if (!V) {
920     SubExprs[VAR] = nullptr;
921     return;
922   }
923 
924   SourceRange VarRange = V->getSourceRange();
925   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
926                                    VarRange.getEnd());
927 }
928 
929 // IndirectGotoStmt
930 LabelDecl *IndirectGotoStmt::getConstantTarget() {
931   if (auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
932     return E->getLabel();
933   return nullptr;
934 }
935 
936 // ReturnStmt
937 const Expr* ReturnStmt::getRetValue() const {
938   return cast_or_null<Expr>(RetExpr);
939 }
940 Expr* ReturnStmt::getRetValue() {
941   return cast_or_null<Expr>(RetExpr);
942 }
943 
944 SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
945                        Stmt *Handler)
946     : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
947   Children[TRY]     = TryBlock;
948   Children[HANDLER] = Handler;
949 }
950 
951 SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
952                                SourceLocation TryLoc, Stmt *TryBlock,
953                                Stmt *Handler) {
954   return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
955 }
956 
957 SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
958   return dyn_cast<SEHExceptStmt>(getHandler());
959 }
960 
961 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
962   return dyn_cast<SEHFinallyStmt>(getHandler());
963 }
964 
965 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
966     : Stmt(SEHExceptStmtClass), Loc(Loc) {
967   Children[FILTER_EXPR] = FilterExpr;
968   Children[BLOCK]       = Block;
969 }
970 
971 SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc,
972                                      Expr *FilterExpr, Stmt *Block) {
973   return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
974 }
975 
976 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
977     : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
978 
979 SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
980                                        Stmt *Block) {
981   return new(C)SEHFinallyStmt(Loc,Block);
982 }
983 
984 CapturedStmt::Capture::Capture(SourceLocation Loc, VariableCaptureKind Kind,
985                                VarDecl *Var)
986     : VarAndKind(Var, Kind), Loc(Loc) {
987   switch (Kind) {
988   case VCK_This:
989     assert(!Var && "'this' capture cannot have a variable!");
990     break;
991   case VCK_ByRef:
992     assert(Var && "capturing by reference must have a variable!");
993     break;
994   case VCK_ByCopy:
995     assert(Var && "capturing by copy must have a variable!");
996     assert(
997         (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
998                                             Var->getType()
999                                                 ->castAs<ReferenceType>()
1000                                                 ->getPointeeType()
1001                                                 ->isScalarType())) &&
1002         "captures by copy are expected to have a scalar type!");
1003     break;
1004   case VCK_VLAType:
1005     assert(!Var &&
1006            "Variable-length array type capture cannot have a variable!");
1007     break;
1008   }
1009 }
1010 
1011 CapturedStmt::VariableCaptureKind
1012 CapturedStmt::Capture::getCaptureKind() const {
1013   return VarAndKind.getInt();
1014 }
1015 
1016 VarDecl *CapturedStmt::Capture::getCapturedVar() const {
1017   assert((capturesVariable() || capturesVariableByCopy()) &&
1018          "No variable available for 'this' or VAT capture");
1019   return VarAndKind.getPointer();
1020 }
1021 
1022 CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
1023   unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1024 
1025   // Offset of the first Capture object.
1026   unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));
1027 
1028   return reinterpret_cast<Capture *>(
1029       reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1030       + FirstCaptureOffset);
1031 }
1032 
1033 CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1034                            ArrayRef<Capture> Captures,
1035                            ArrayRef<Expr *> CaptureInits,
1036                            CapturedDecl *CD,
1037                            RecordDecl *RD)
1038   : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1039     CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
1040   assert( S && "null captured statement");
1041   assert(CD && "null captured declaration for captured statement");
1042   assert(RD && "null record declaration for captured statement");
1043 
1044   // Copy initialization expressions.
1045   Stmt **Stored = getStoredStmts();
1046   for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1047     *Stored++ = CaptureInits[I];
1048 
1049   // Copy the statement being captured.
1050   *Stored = S;
1051 
1052   // Copy all Capture objects.
1053   Capture *Buffer = getStoredCaptures();
1054   std::copy(Captures.begin(), Captures.end(), Buffer);
1055 }
1056 
1057 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1058   : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1059     CapDeclAndKind(nullptr, CR_Default) {
1060   getStoredStmts()[NumCaptures] = nullptr;
1061 }
1062 
1063 CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
1064                                    CapturedRegionKind Kind,
1065                                    ArrayRef<Capture> Captures,
1066                                    ArrayRef<Expr *> CaptureInits,
1067                                    CapturedDecl *CD,
1068                                    RecordDecl *RD) {
1069   // The layout is
1070   //
1071   // -----------------------------------------------------------
1072   // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1073   // ----------------^-------------------^----------------------
1074   //                 getStoredStmts()    getStoredCaptures()
1075   //
1076   // where S is the statement being captured.
1077   //
1078   assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1079 
1080   unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1081   if (!Captures.empty()) {
1082     // Realign for the following Capture array.
1083     Size = llvm::alignTo(Size, alignof(Capture));
1084     Size += sizeof(Capture) * Captures.size();
1085   }
1086 
1087   void *Mem = Context.Allocate(Size);
1088   return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1089 }
1090 
1091 CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context,
1092                                                unsigned NumCaptures) {
1093   unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1094   if (NumCaptures > 0) {
1095     // Realign for the following Capture array.
1096     Size = llvm::alignTo(Size, alignof(Capture));
1097     Size += sizeof(Capture) * NumCaptures;
1098   }
1099 
1100   void *Mem = Context.Allocate(Size);
1101   return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1102 }
1103 
1104 Stmt::child_range CapturedStmt::children() {
1105   // Children are captured field initializers.
1106   return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1107 }
1108 
1109 CapturedDecl *CapturedStmt::getCapturedDecl() {
1110   return CapDeclAndKind.getPointer();
1111 }
1112 
1113 const CapturedDecl *CapturedStmt::getCapturedDecl() const {
1114   return CapDeclAndKind.getPointer();
1115 }
1116 
1117 /// Set the outlined function declaration.
1118 void CapturedStmt::setCapturedDecl(CapturedDecl *D) {
1119   assert(D && "null CapturedDecl");
1120   CapDeclAndKind.setPointer(D);
1121 }
1122 
1123 /// Retrieve the captured region kind.
1124 CapturedRegionKind CapturedStmt::getCapturedRegionKind() const {
1125   return CapDeclAndKind.getInt();
1126 }
1127 
1128 /// Set the captured region kind.
1129 void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {
1130   CapDeclAndKind.setInt(Kind);
1131 }
1132 
1133 bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
1134   for (const auto &I : captures()) {
1135     if (!I.capturesVariable() && !I.capturesVariableByCopy())
1136       continue;
1137     if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
1138       return true;
1139   }
1140 
1141   return false;
1142 }
1143