blob: 09503079ffae587d88319647102d44e12ec15072 [file] [log] [blame]
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001//===- Stmt.cpp - Statement AST Node Implementation -----------------------===//
Chris Lattnerf42cce72006-10-25 04:09:21 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattnerf42cce72006-10-25 04:09:21 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Stmt class and statement subclasses.
10//
11//===----------------------------------------------------------------------===//
12
Eugene Zelenko7855e772018-04-03 00:11:50 +000013#include "clang/AST/Stmt.h"
Benjamin Kramer444a1302012-12-01 17:12:56 +000014#include "clang/AST/ASTContext.h"
15#include "clang/AST/ASTDiagnostic.h"
Mark de Wever08196e02020-09-09 19:12:32 +020016#include "clang/AST/Attr.h"
Eugene Zelenko1eab6c12017-11-14 23:35:42 +000017#include "clang/AST/Decl.h"
18#include "clang/AST/DeclGroup.h"
Eugene Zelenko7855e772018-04-03 00:11:50 +000019#include "clang/AST/Expr.h"
Chris Lattner29375652006-12-04 18:06:35 +000020#include "clang/AST/ExprCXX.h"
Mark de Wever08196e02020-09-09 19:12:32 +020021#include "clang/AST/ExprConcepts.h"
Steve Naroff021ca182008-05-29 21:12:08 +000022#include "clang/AST/ExprObjC.h"
Alexey Bataev1a3320e2015-08-25 14:24:04 +000023#include "clang/AST/ExprOpenMP.h"
Chris Lattnerf0b64d72009-04-26 01:32:48 +000024#include "clang/AST/StmtCXX.h"
25#include "clang/AST/StmtObjC.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000026#include "clang/AST/StmtOpenMP.h"
Sebastian Redl54c04d42008-12-22 19:15:10 +000027#include "clang/AST/Type.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000028#include "clang/Basic/CharInfo.h"
Eugene Zelenko1eab6c12017-11-14 23:35:42 +000029#include "clang/Basic/LLVM.h"
30#include "clang/Basic/SourceLocation.h"
Chris Lattner1a8f3942010-04-23 16:29:58 +000031#include "clang/Basic/TargetInfo.h"
Benjamin Kramer444a1302012-12-01 17:12:56 +000032#include "clang/Lex/Token.h"
Eugene Zelenko1eab6c12017-11-14 23:35:42 +000033#include "llvm/ADT/SmallVector.h"
Chad Rosier14836ba2012-08-24 17:05:45 +000034#include "llvm/ADT/StringExtras.h"
Eugene Zelenko1eab6c12017-11-14 23:35:42 +000035#include "llvm/ADT/StringRef.h"
36#include "llvm/Support/Casting.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/ErrorHandling.h"
39#include "llvm/Support/MathExtras.h"
Chandler Carruthbfb154a2011-07-04 06:13:27 +000040#include "llvm/Support/raw_ostream.h"
Eugene Zelenko1eab6c12017-11-14 23:35:42 +000041#include <algorithm>
42#include <cassert>
43#include <cstring>
44#include <string>
Bruno Riccic397a262019-08-27 11:35:49 +000045#include <type_traits>
Mark de Wever08196e02020-09-09 19:12:32 +020046#include <utility>
Eugene Zelenko1eab6c12017-11-14 23:35:42 +000047
Chris Lattnerf42cce72006-10-25 04:09:21 +000048using namespace clang;
49
Steve Narofff84d11f2007-05-23 21:48:04 +000050static struct StmtClassNameTable {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000051 const char *Name;
52 unsigned Counter;
53 unsigned Size;
Alexis Hunt656bb312010-05-05 15:24:00 +000054} StmtClassInfo[Stmt::lastStmtConstant+1];
Chris Lattner4d15a0d2007-08-25 01:42:24 +000055
56static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
57 static bool Initialized = false;
58 if (Initialized)
59 return StmtClassInfo[E];
60
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +000061 // Initialize the table on the first use.
Chris Lattner4d15a0d2007-08-25 01:42:24 +000062 Initialized = true;
Alexis Huntabb2ac82010-05-18 06:22:21 +000063#define ABSTRACT_STMT(STMT)
Douglas Gregorbe35ce92008-11-14 12:46:07 +000064#define STMT(CLASS, PARENT) \
65 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
66 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
Alexis Hunt656bb312010-05-05 15:24:00 +000067#include "clang/AST/StmtNodes.inc"
Nico Weberde565e32008-08-05 23:15:29 +000068
Chris Lattner4d15a0d2007-08-25 01:42:24 +000069 return StmtClassInfo[E];
70}
71
Craig Topper37932912013-08-18 10:09:15 +000072void *Stmt::operator new(size_t bytes, const ASTContext& C,
Craig Topper5a050012013-08-18 17:45:38 +000073 unsigned alignment) {
Benjamin Kramerea70eb32012-12-01 15:09:41 +000074 return ::operator new(bytes, C, alignment);
75}
76
Steve Narofff1e53692007-03-23 22:27:02 +000077const char *Stmt::getStmtClassName() const {
John McCall925b16622010-10-26 08:39:16 +000078 return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
Steve Narofff1e53692007-03-23 22:27:02 +000079}
Steve Narofff84d11f2007-05-23 21:48:04 +000080
Bruno Ricci65034b82018-12-04 16:04:19 +000081// Check that no statement / expression class is polymorphic. LLVM style RTTI
82// should be used instead. If absolutely needed an exception can still be added
83// here by defining the appropriate macro (but please don't do this).
84#define STMT(CLASS, PARENT) \
85 static_assert(!std::is_polymorphic<CLASS>::value, \
86 #CLASS " should not be polymorphic!");
87#include "clang/AST/StmtNodes.inc"
88
Bruno Riccic397a262019-08-27 11:35:49 +000089// Check that no statement / expression class has a non-trival destructor.
90// Statements and expressions are allocated with the BumpPtrAllocator from
91// ASTContext and therefore their destructor is not executed.
92#define STMT(CLASS, PARENT) \
93 static_assert(std::is_trivially_destructible<CLASS>::value, \
94 #CLASS " should be trivially destructible!");
95// FIXME: InitListExpr is not trivially destructible due to its ASTVector.
96#define INITLISTEXPR(CLASS, PARENT)
97#include "clang/AST/StmtNodes.inc"
98
Steve Narofff84d11f2007-05-23 21:48:04 +000099void Stmt::PrintStats() {
Chris Lattner4d15a0d2007-08-25 01:42:24 +0000100 // Ensure the table is primed.
101 getStmtInfoTableEntry(Stmt::NullStmtClass);
Nico Weberde565e32008-08-05 23:15:29 +0000102
Steve Narofff84d11f2007-05-23 21:48:04 +0000103 unsigned sum = 0;
Chandler Carruthbfb154a2011-07-04 06:13:27 +0000104 llvm::errs() << "\n*** Stmt/Expr Stats:\n";
Alexis Hunt656bb312010-05-05 15:24:00 +0000105 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
Craig Topper36250ad2014-05-12 05:36:57 +0000106 if (StmtClassInfo[i].Name == nullptr) continue;
Chris Lattner4d15a0d2007-08-25 01:42:24 +0000107 sum += StmtClassInfo[i].Counter;
Steve Narofff84d11f2007-05-23 21:48:04 +0000108 }
Chandler Carruthbfb154a2011-07-04 06:13:27 +0000109 llvm::errs() << " " << sum << " stmts/exprs total.\n";
Steve Narofff84d11f2007-05-23 21:48:04 +0000110 sum = 0;
Alexis Hunt656bb312010-05-05 15:24:00 +0000111 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
Craig Topper36250ad2014-05-12 05:36:57 +0000112 if (StmtClassInfo[i].Name == nullptr) continue;
Douglas Gregora30d0462009-05-26 14:40:08 +0000113 if (StmtClassInfo[i].Counter == 0) continue;
Chandler Carruthbfb154a2011-07-04 06:13:27 +0000114 llvm::errs() << " " << StmtClassInfo[i].Counter << " "
115 << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
116 << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size
117 << " bytes)\n";
Chris Lattner4d15a0d2007-08-25 01:42:24 +0000118 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
Steve Narofff84d11f2007-05-23 21:48:04 +0000119 }
Chandler Carruthbfb154a2011-07-04 06:13:27 +0000120
121 llvm::errs() << "Total bytes = " << sum << "\n";
Steve Narofff84d11f2007-05-23 21:48:04 +0000122}
123
124void Stmt::addStmtClass(StmtClass s) {
Chris Lattner4d15a0d2007-08-25 01:42:24 +0000125 ++getStmtInfoTableEntry(s).Counter;
Steve Narofff84d11f2007-05-23 21:48:04 +0000126}
127
Daniel Dunbar62905572012-03-05 21:42:49 +0000128bool Stmt::StatisticsEnabled = false;
129void Stmt::EnableStatistics() {
130 StatisticsEnabled = true;
Steve Narofff84d11f2007-05-23 21:48:04 +0000131}
132
Mark de Wever2bcda6b2020-10-18 13:34:41 +0200133static std::pair<Stmt::Likelihood, const Attr *>
134getLikelihood(ArrayRef<const Attr *> Attrs) {
135 for (const auto *A : Attrs) {
136 if (isa<LikelyAttr>(A))
137 return std::make_pair(Stmt::LH_Likely, A);
Mark de Wever08196e02020-09-09 19:12:32 +0200138
Mark de Wever2bcda6b2020-10-18 13:34:41 +0200139 if (isa<UnlikelyAttr>(A))
140 return std::make_pair(Stmt::LH_Unlikely, A);
141 }
Mark de Wever08196e02020-09-09 19:12:32 +0200142
143 return std::make_pair(Stmt::LH_None, nullptr);
144}
145
Mark de Wever2bcda6b2020-10-18 13:34:41 +0200146static std::pair<Stmt::Likelihood, const Attr *> getLikelihood(const Stmt *S) {
147 if (const auto *AS = dyn_cast_or_null<AttributedStmt>(S))
148 return getLikelihood(AS->getAttrs());
149
150 return std::make_pair(Stmt::LH_None, nullptr);
151}
152
153Stmt::Likelihood Stmt::getLikelihood(ArrayRef<const Attr *> Attrs) {
154 return ::getLikelihood(Attrs).first;
155}
156
Mark de Wever08196e02020-09-09 19:12:32 +0200157Stmt::Likelihood Stmt::getLikelihood(const Stmt *S) {
158 return ::getLikelihood(S).first;
159}
160
161Stmt::Likelihood Stmt::getLikelihood(const Stmt *Then, const Stmt *Else) {
162 Likelihood LHT = ::getLikelihood(Then).first;
163 Likelihood LHE = ::getLikelihood(Else).first;
164 if (LHE == LH_None)
165 return LHT;
166
167 // If the same attribute is used on both branches there's a conflict.
168 if (LHT == LHE)
169 return LH_None;
170
171 if (LHT != LH_None)
172 return LHT;
173
174 // Invert the value of Else to get the value for Then.
175 return LHE == LH_Likely ? LH_Unlikely : LH_Likely;
176}
177
178std::tuple<bool, const Attr *, const Attr *>
179Stmt::determineLikelihoodConflict(const Stmt *Then, const Stmt *Else) {
180 std::pair<Likelihood, const Attr *> LHT = ::getLikelihood(Then);
181 std::pair<Likelihood, const Attr *> LHE = ::getLikelihood(Else);
182 // If the same attribute is used on both branches there's a conflict.
183 if (LHT.first != LH_None && LHT.first == LHE.first)
184 return std::make_tuple(true, LHT.second, LHE.second);
185
186 return std::make_tuple(false, nullptr, nullptr);
187}
188
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000189/// Skip no-op (attributed, compound) container stmts and skip captured
Alexander Musmana5f070a2014-10-01 06:03:56 +0000190/// stmt at the top, if \a IgnoreCaptured is true.
191Stmt *Stmt::IgnoreContainers(bool IgnoreCaptured) {
192 Stmt *S = this;
193 if (IgnoreCaptured)
194 if (auto CapS = dyn_cast_or_null<CapturedStmt>(S))
195 S = CapS->getCapturedStmt();
196 while (true) {
197 if (auto AS = dyn_cast_or_null<AttributedStmt>(S))
198 S = AS->getSubStmt();
199 else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
200 if (CS->size() != 1)
201 break;
202 S = CS->body_back();
203 } else
204 break;
205 }
206 return S;
207}
208
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000209/// Strip off all label-like statements.
Chandler Carrutha626d642011-09-10 00:02:34 +0000210///
Richard Smithc202b282012-04-14 00:33:13 +0000211/// This will strip off label statements, case statements, attributed
212/// statements and default statements recursively.
Chandler Carrutha626d642011-09-10 00:02:34 +0000213const Stmt *Stmt::stripLabelLikeStatements() const {
214 const Stmt *S = this;
215 while (true) {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000216 if (const auto *LS = dyn_cast<LabelStmt>(S))
Chandler Carrutha626d642011-09-10 00:02:34 +0000217 S = LS->getSubStmt();
Eugene Zelenko7855e772018-04-03 00:11:50 +0000218 else if (const auto *SC = dyn_cast<SwitchCase>(S))
Chandler Carrutha626d642011-09-10 00:02:34 +0000219 S = SC->getSubStmt();
Eugene Zelenko7855e772018-04-03 00:11:50 +0000220 else if (const auto *AS = dyn_cast<AttributedStmt>(S))
Richard Smithc202b282012-04-14 00:33:13 +0000221 S = AS->getSubStmt();
Chandler Carrutha626d642011-09-10 00:02:34 +0000222 else
223 return S;
224 }
225}
226
John McCallbd066782011-02-09 08:16:59 +0000227namespace {
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000228
John McCallbd066782011-02-09 08:16:59 +0000229 struct good {};
230 struct bad {};
John McCallf75152f2011-02-09 08:31:17 +0000231
232 // These silly little functions have to be static inline to suppress
233 // unused warnings, and they have to be defined to suppress other
234 // warnings.
Eugene Zelenko7855e772018-04-03 00:11:50 +0000235 static good is_good(good) { return good(); }
John McCallbd066782011-02-09 08:16:59 +0000236
237 typedef Stmt::child_range children_t();
Nick Lewyckybae992f2011-02-09 08:42:57 +0000238 template <class T> good implements_children(children_t T::*) {
239 return good();
240 }
Eli Friedmandc41d792013-09-10 22:57:15 +0000241 LLVM_ATTRIBUTE_UNUSED
Eugene Zelenko7855e772018-04-03 00:11:50 +0000242 static bad implements_children(children_t Stmt::*) {
Nick Lewyckybae992f2011-02-09 08:42:57 +0000243 return bad();
244 }
John McCallbd066782011-02-09 08:16:59 +0000245
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000246 typedef SourceLocation getBeginLoc_t() const;
247 template <class T> good implements_getBeginLoc(getBeginLoc_t T::*) {
Nick Lewyckybae992f2011-02-09 08:42:57 +0000248 return good();
249 }
Eli Friedmandc41d792013-09-10 22:57:15 +0000250 LLVM_ATTRIBUTE_UNUSED
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000251 static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) { return bad(); }
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000252
253 typedef SourceLocation getLocEnd_t() const;
Stephen Kelly1c301dc2018-08-09 21:09:38 +0000254 template <class T> good implements_getEndLoc(getLocEnd_t T::*) {
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000255 return good();
256 }
Eli Friedmandc41d792013-09-10 22:57:15 +0000257 LLVM_ATTRIBUTE_UNUSED
Stephen Kelly1c301dc2018-08-09 21:09:38 +0000258 static bad implements_getEndLoc(getLocEnd_t Stmt::*) { return bad(); }
John McCallbd066782011-02-09 08:16:59 +0000259
260#define ASSERT_IMPLEMENTS_children(type) \
Eli Friedmandc41d792013-09-10 22:57:15 +0000261 (void) is_good(implements_children(&type::children))
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000262#define ASSERT_IMPLEMENTS_getBeginLoc(type) \
263 (void)is_good(implements_getBeginLoc(&type::getBeginLoc))
Stephen Kelly1c301dc2018-08-09 21:09:38 +0000264#define ASSERT_IMPLEMENTS_getEndLoc(type) \
265 (void)is_good(implements_getEndLoc(&type::getEndLoc))
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000266
267} // namespace
John McCallbd066782011-02-09 08:16:59 +0000268
269/// Check whether the various Stmt classes implement their member
270/// functions.
Eli Friedmandc41d792013-09-10 22:57:15 +0000271LLVM_ATTRIBUTE_UNUSED
John McCallbd066782011-02-09 08:16:59 +0000272static inline void check_implementations() {
273#define ABSTRACT_STMT(type)
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000274#define STMT(type, base) \
275 ASSERT_IMPLEMENTS_children(type); \
276 ASSERT_IMPLEMENTS_getBeginLoc(type); \
Stephen Kelly1c301dc2018-08-09 21:09:38 +0000277 ASSERT_IMPLEMENTS_getEndLoc(type);
John McCallbd066782011-02-09 08:16:59 +0000278#include "clang/AST/StmtNodes.inc"
279}
280
281Stmt::child_range Stmt::children() {
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<type*>(this)->children();
288#include "clang/AST/StmtNodes.inc"
289 }
290 llvm_unreachable("unknown statement kind!");
John McCallbd066782011-02-09 08:16:59 +0000291}
292
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000293// Amusing macro metaprogramming hack: check whether a class provides
294// a more specific implementation of getSourceRange.
295//
296// See also Expr.cpp:getExprLoc().
297namespace {
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000298
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000299 /// This implementation is used when a class provides a custom
300 /// implementation of getSourceRange.
301 template <class S, class T>
302 SourceRange getSourceRangeImpl(const Stmt *stmt,
303 SourceRange (T::*v)() const) {
304 return static_cast<const S*>(stmt)->getSourceRange();
305 }
306
307 /// This implementation is used when a class doesn't provide a custom
308 /// implementation of getSourceRange. Overload resolution should pick it over
309 /// the implementation above because it's more specialized according to
310 /// function template partial ordering.
311 template <class S>
312 SourceRange getSourceRangeImpl(const Stmt *stmt,
313 SourceRange (Stmt::*v)() const) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000314 return SourceRange(static_cast<const S *>(stmt)->getBeginLoc(),
Stephen Kelly1c301dc2018-08-09 21:09:38 +0000315 static_cast<const S *>(stmt)->getEndLoc());
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000316 }
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000317
318} // namespace
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000319
John McCallbd066782011-02-09 08:16:59 +0000320SourceRange Stmt::getSourceRange() const {
321 switch (getStmtClass()) {
322 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
323#define ABSTRACT_STMT(type)
324#define STMT(type, base) \
325 case Stmt::type##Class: \
Erik Verbruggen11a2ecc2012-12-25 14:51:39 +0000326 return getSourceRangeImpl<type>(this, &type::getSourceRange);
John McCallbd066782011-02-09 08:16:59 +0000327#include "clang/AST/StmtNodes.inc"
328 }
329 llvm_unreachable("unknown statement kind!");
John McCallbd066782011-02-09 08:16:59 +0000330}
331
Stephen Kelly724e9e52018-08-09 20:05:03 +0000332SourceLocation Stmt::getBeginLoc() const {
Daniel Dunbarb0ab5e92012-03-09 15:39:19 +0000333 switch (getStmtClass()) {
334 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
335#define ABSTRACT_STMT(type)
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000336#define STMT(type, base) \
337 case Stmt::type##Class: \
338 return static_cast<const type *>(this)->getBeginLoc();
Daniel Dunbarb0ab5e92012-03-09 15:39:19 +0000339#include "clang/AST/StmtNodes.inc"
340 }
341 llvm_unreachable("unknown statement kind");
342}
343
Stephen Kelly02a67ba2018-08-09 20:05:47 +0000344SourceLocation Stmt::getEndLoc() const {
Daniel Dunbarb0ab5e92012-03-09 15:39:19 +0000345 switch (getStmtClass()) {
346 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
347#define ABSTRACT_STMT(type)
Stephen Kelly1c301dc2018-08-09 21:09:38 +0000348#define STMT(type, base) \
349 case Stmt::type##Class: \
350 return static_cast<const type *>(this)->getEndLoc();
Daniel Dunbarb0ab5e92012-03-09 15:39:19 +0000351#include "clang/AST/StmtNodes.inc"
352 }
353 llvm_unreachable("unknown statement kind");
354}
355
George Karpenkov5eb4cc62018-09-15 02:01:47 +0000356int64_t Stmt::getID(const ASTContext &Context) const {
Artem Dergachev057647d2018-12-03 22:19:05 +0000357 return Context.getAllocator().identifyKnownAlignedObject<Stmt>(this);
George Karpenkov5eb4cc62018-09-15 02:01:47 +0000358}
359
Benjamin Kramer07420902017-12-24 16:24:20 +0000360CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB,
361 SourceLocation RB)
Bruno Ricci41d11c02018-10-27 18:43:27 +0000362 : Stmt(CompoundStmtClass), RBraceLoc(RB) {
Nico Webera2a0eb92012-12-29 20:03:39 +0000363 CompoundStmtBits.NumStmts = Stmts.size();
Benjamin Kramer07420902017-12-24 16:24:20 +0000364 setStmts(Stmts);
Bruno Ricci41d11c02018-10-27 18:43:27 +0000365 CompoundStmtBits.LBraceLoc = LB;
Benjamin Kramere2a929d2012-07-04 17:03:41 +0000366}
367
Benjamin Kramer07420902017-12-24 16:24:20 +0000368void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
Craig Topper9ee84ad2015-12-04 05:01:44 +0000369 assert(CompoundStmtBits.NumStmts == Stmts.size() &&
370 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
Douglas Gregora9af1d12009-04-17 00:04:06 +0000371
Benjamin Kramer07420902017-12-24 16:24:20 +0000372 std::copy(Stmts.begin(), Stmts.end(), body_begin());
373}
374
375CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
376 SourceLocation LB, SourceLocation RB) {
377 void *Mem =
378 C.Allocate(totalSizeToAlloc<Stmt *>(Stmts.size()), alignof(CompoundStmt));
379 return new (Mem) CompoundStmt(Stmts, LB, RB);
380}
381
382CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C,
383 unsigned NumStmts) {
384 void *Mem =
385 C.Allocate(totalSizeToAlloc<Stmt *>(NumStmts), alignof(CompoundStmt));
386 CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
387 New->CompoundStmtBits.NumStmts = NumStmts;
388 return New;
Douglas Gregora9af1d12009-04-17 00:04:06 +0000389}
Steve Narofff84d11f2007-05-23 21:48:04 +0000390
Richard Smitha6e8d5e2019-02-15 00:27:53 +0000391const Expr *ValueStmt::getExprStmt() const {
392 const Stmt *S = this;
393 do {
394 if (const auto *E = dyn_cast<Expr>(S))
395 return E;
396
397 if (const auto *LS = dyn_cast<LabelStmt>(S))
398 S = LS->getSubStmt();
399 else if (const auto *AS = dyn_cast<AttributedStmt>(S))
400 S = AS->getSubStmt();
401 else
402 llvm_unreachable("unknown kind of ValueStmt");
403 } while (isa<ValueStmt>(S));
404
405 return nullptr;
406}
407
Chris Lattnereefa10e2007-05-28 06:56:27 +0000408const char *LabelStmt::getName() const {
Chris Lattnerc8e630e2011-02-17 07:39:24 +0000409 return getDecl()->getIdentifier()->getNameStart();
Chris Lattnereefa10e2007-05-28 06:56:27 +0000410}
411
Craig Toppere6960e22013-08-22 05:28:54 +0000412AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
Alexander Kornienko20f6fc62012-07-09 10:04:07 +0000413 ArrayRef<const Attr*> Attrs,
414 Stmt *SubStmt) {
Aaron Ballmanf3d9b092014-05-13 14:55:01 +0000415 assert(!Attrs.empty() && "Attrs should not be empty");
Benjamin Kramer917fdbe2017-12-24 16:24:11 +0000416 void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),
Benjamin Kramerc3f89252016-10-20 14:27:22 +0000417 alignof(AttributedStmt));
Alexander Kornienko20f6fc62012-07-09 10:04:07 +0000418 return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
419}
420
Craig Toppere6960e22013-08-22 05:28:54 +0000421AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
422 unsigned NumAttrs) {
Alexander Kornienko20f6fc62012-07-09 10:04:07 +0000423 assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
Benjamin Kramer917fdbe2017-12-24 16:24:11 +0000424 void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),
Benjamin Kramerc3f89252016-10-20 14:27:22 +0000425 alignof(AttributedStmt));
Alexander Kornienko20f6fc62012-07-09 10:04:07 +0000426 return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
427}
428
Craig Topperc571c812013-08-22 06:02:26 +0000429std::string AsmStmt::generateAsmString(const ASTContext &C) const {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000430 if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000431 return gccAsmStmt->generateAsmString(C);
Eugene Zelenko7855e772018-04-03 00:11:50 +0000432 if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000433 return msAsmStmt->generateAsmString(C);
Chad Rosierbbbe9ab2012-08-28 17:43:23 +0000434 llvm_unreachable("unknown asm statement kind!");
435}
436
437StringRef AsmStmt::getOutputConstraint(unsigned i) const {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000438 if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000439 return gccAsmStmt->getOutputConstraint(i);
Eugene Zelenko7855e772018-04-03 00:11:50 +0000440 if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000441 return msAsmStmt->getOutputConstraint(i);
Chad Rosierbbbe9ab2012-08-28 17:43:23 +0000442 llvm_unreachable("unknown asm statement kind!");
443}
444
445const Expr *AsmStmt::getOutputExpr(unsigned i) const {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000446 if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000447 return gccAsmStmt->getOutputExpr(i);
Eugene Zelenko7855e772018-04-03 00:11:50 +0000448 if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000449 return msAsmStmt->getOutputExpr(i);
Chad Rosierbbbe9ab2012-08-28 17:43:23 +0000450 llvm_unreachable("unknown asm statement kind!");
451}
452
453StringRef AsmStmt::getInputConstraint(unsigned i) const {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000454 if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000455 return gccAsmStmt->getInputConstraint(i);
Eugene Zelenko7855e772018-04-03 00:11:50 +0000456 if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000457 return msAsmStmt->getInputConstraint(i);
Chad Rosierbbbe9ab2012-08-28 17:43:23 +0000458 llvm_unreachable("unknown asm statement kind!");
459}
460
461const Expr *AsmStmt::getInputExpr(unsigned i) const {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000462 if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000463 return gccAsmStmt->getInputExpr(i);
Eugene Zelenko7855e772018-04-03 00:11:50 +0000464 if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000465 return msAsmStmt->getInputExpr(i);
Chad Rosierbbbe9ab2012-08-28 17:43:23 +0000466 llvm_unreachable("unknown asm statement kind!");
467}
468
469StringRef AsmStmt::getClobber(unsigned i) const {
Eugene Zelenko7855e772018-04-03 00:11:50 +0000470 if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000471 return gccAsmStmt->getClobber(i);
Eugene Zelenko7855e772018-04-03 00:11:50 +0000472 if (const auto *msAsmStmt = dyn_cast<MSAsmStmt>(this))
Chad Rosierf70b7e22012-08-28 18:21:14 +0000473 return msAsmStmt->getClobber(i);
Chad Rosierbbbe9ab2012-08-28 17:43:23 +0000474 llvm_unreachable("unknown asm statement kind!");
475}
476
Chad Rosiera1b5c8c2012-08-28 00:24:05 +0000477/// getNumPlusOperands - Return the number of output operands that have a "+"
478/// constraint.
479unsigned AsmStmt::getNumPlusOperands() const {
480 unsigned Res = 0;
481 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
482 if (isOutputPlusConstraint(i))
483 ++Res;
484 return Res;
485}
486
Akira Hatanaka987f1862014-08-22 06:05:21 +0000487char GCCAsmStmt::AsmStringPiece::getModifier() const {
488 assert(isOperand() && "Only Operands can have modifiers.");
489 return isLetter(Str[0]) ? Str[0] : '\0';
490}
491
Chad Rosier6100ae12012-08-27 23:47:56 +0000492StringRef GCCAsmStmt::getClobber(unsigned i) const {
493 return getClobberStringLiteral(i)->getString();
494}
495
Chad Rosierde70e0e2012-08-25 00:11:56 +0000496Expr *GCCAsmStmt::getOutputExpr(unsigned i) {
Ted Kremenek5778acf2008-10-27 18:40:21 +0000497 return cast<Expr>(Exprs[i]);
498}
Chris Lattner72bbf172009-03-10 04:59:06 +0000499
500/// getOutputConstraint - Return the constraint string for the specified
501/// output operand. All output constraints are known to be non-empty (either
502/// '=' or '+').
Chad Rosierde70e0e2012-08-25 00:11:56 +0000503StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {
Anders Carlsson66de0812010-01-30 20:38:10 +0000504 return getOutputConstraintLiteral(i)->getString();
Ted Kremenek5778acf2008-10-27 18:40:21 +0000505}
Chris Lattner72bbf172009-03-10 04:59:06 +0000506
Chad Rosierde70e0e2012-08-25 00:11:56 +0000507Expr *GCCAsmStmt::getInputExpr(unsigned i) {
Ted Kremenek5778acf2008-10-27 18:40:21 +0000508 return cast<Expr>(Exprs[i + NumOutputs]);
509}
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000510
Chad Rosierde70e0e2012-08-25 00:11:56 +0000511void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {
Chris Lattner93ede022011-02-21 22:09:29 +0000512 Exprs[i + NumOutputs] = E;
513}
514
Jennifer Yub8fee672019-06-03 15:57:25 +0000515AddrLabelExpr *GCCAsmStmt::getLabelExpr(unsigned i) const {
Bill Wendling50cac242020-02-24 18:32:50 -0800516 return cast<AddrLabelExpr>(Exprs[i + NumOutputs + NumInputs]);
Jennifer Yub8fee672019-06-03 15:57:25 +0000517}
518
519StringRef GCCAsmStmt::getLabelName(unsigned i) const {
520 return getLabelExpr(i)->getLabel()->getName();
521}
522
Chris Lattner72bbf172009-03-10 04:59:06 +0000523/// getInputConstraint - Return the specified input constraint. Unlike output
524/// constraints, these can be empty.
Chad Rosierde70e0e2012-08-25 00:11:56 +0000525StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {
Anders Carlsson66de0812010-01-30 20:38:10 +0000526 return getInputConstraintLiteral(i)->getString();
Ted Kremenek5778acf2008-10-27 18:40:21 +0000527}
528
Craig Topperc571c812013-08-22 06:02:26 +0000529void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
530 IdentifierInfo **Names,
531 StringLiteral **Constraints,
532 Stmt **Exprs,
533 unsigned NumOutputs,
534 unsigned NumInputs,
Jennifer Yub8fee672019-06-03 15:57:25 +0000535 unsigned NumLabels,
Craig Topperc571c812013-08-22 06:02:26 +0000536 StringLiteral **Clobbers,
537 unsigned NumClobbers) {
Douglas Gregorf994f062009-04-17 20:57:14 +0000538 this->NumOutputs = NumOutputs;
539 this->NumInputs = NumInputs;
Anders Carlsson98323d22010-01-30 23:19:41 +0000540 this->NumClobbers = NumClobbers;
Jennifer Yub8fee672019-06-03 15:57:25 +0000541 this->NumLabels = NumLabels;
Anders Carlsson98323d22010-01-30 23:19:41 +0000542
Jennifer Yub8fee672019-06-03 15:57:25 +0000543 unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
Chad Rosier42032fa2012-08-07 23:12:23 +0000544
Anders Carlsson98323d22010-01-30 23:19:41 +0000545 C.Deallocate(this->Names);
546 this->Names = new (C) IdentifierInfo*[NumExprs];
547 std::copy(Names, Names + NumExprs, this->Names);
Chad Rosier42032fa2012-08-07 23:12:23 +0000548
Anders Carlsson98323d22010-01-30 23:19:41 +0000549 C.Deallocate(this->Exprs);
550 this->Exprs = new (C) Stmt*[NumExprs];
551 std::copy(Exprs, Exprs + NumExprs, this->Exprs);
Chad Rosier42032fa2012-08-07 23:12:23 +0000552
Benjamin Kramer851f57e2019-05-30 07:21:08 +0000553 unsigned NumConstraints = NumOutputs + NumInputs;
Anders Carlsson98323d22010-01-30 23:19:41 +0000554 C.Deallocate(this->Constraints);
Benjamin Kramer851f57e2019-05-30 07:21:08 +0000555 this->Constraints = new (C) StringLiteral*[NumConstraints];
556 std::copy(Constraints, Constraints + NumConstraints, this->Constraints);
Chad Rosier42032fa2012-08-07 23:12:23 +0000557
Anders Carlsson98323d22010-01-30 23:19:41 +0000558 C.Deallocate(this->Clobbers);
559 this->Clobbers = new (C) StringLiteral*[NumClobbers];
560 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
Douglas Gregorf994f062009-04-17 20:57:14 +0000561}
562
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000563/// getNamedOperand - Given a symbolic operand reference like %[foo],
564/// translate this into a numeric value needed to reference the same operand.
565/// This returns -1 if the operand name is invalid.
Chad Rosierde70e0e2012-08-25 00:11:56 +0000566int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000567 unsigned NumPlusOperands = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000568
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000569 // Check if this is an output operand.
570 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
571 if (getOutputName(i) == SymbolicName)
572 return i;
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000573 }
Mike Stump11289f42009-09-09 15:08:12 +0000574
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000575 for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
576 if (getInputName(i) == SymbolicName)
577 return getNumOutputs() + NumPlusOperands + i;
578
Jennifer Yub8fee672019-06-03 15:57:25 +0000579 for (unsigned i = 0, e = getNumLabels(); i != e; ++i)
580 if (getLabelName(i) == SymbolicName)
Bill Wendling50cac242020-02-24 18:32:50 -0800581 return i + getNumOutputs() + getNumInputs();
Jennifer Yub8fee672019-06-03 15:57:25 +0000582
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000583 // Not found.
584 return -1;
585}
586
Chris Lattner35b58362009-03-10 23:21:44 +0000587/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
588/// it into pieces. If the asm string is erroneous, emit errors and return
589/// true, otherwise return false.
Chad Rosierde70e0e2012-08-25 00:11:56 +0000590unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
Craig Topperc571c812013-08-22 06:02:26 +0000591 const ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000592 StringRef Str = getAsmString()->getString();
Benjamin Kramer35b077e2010-08-17 12:54:38 +0000593 const char *StrStart = Str.begin();
594 const char *StrEnd = Str.end();
Chris Lattnera41b8472009-03-10 23:51:40 +0000595 const char *CurPtr = StrStart;
Mike Stump11289f42009-09-09 15:08:12 +0000596
Chris Lattner35b58362009-03-10 23:21:44 +0000597 // "Simple" inline asms have no constraints or operands, just convert the asm
598 // string to escape $'s.
599 if (isSimple()) {
600 std::string Result;
Chris Lattnera41b8472009-03-10 23:51:40 +0000601 for (; CurPtr != StrEnd; ++CurPtr) {
602 switch (*CurPtr) {
Chris Lattner35b58362009-03-10 23:21:44 +0000603 case '$':
604 Result += "$$";
605 break;
606 default:
Chris Lattnera41b8472009-03-10 23:51:40 +0000607 Result += *CurPtr;
Chris Lattner35b58362009-03-10 23:21:44 +0000608 break;
609 }
610 }
611 Pieces.push_back(AsmStringPiece(Result));
Chris Lattnera41b8472009-03-10 23:51:40 +0000612 return 0;
Chris Lattner35b58362009-03-10 23:21:44 +0000613 }
614
615 // CurStringPiece - The current string that we are building up as we scan the
616 // asm string.
617 std::string CurStringPiece;
Mike Stump11289f42009-09-09 15:08:12 +0000618
Douglas Gregore8bbc122011-09-02 00:18:52 +0000619 bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
Chad Rosier42032fa2012-08-07 23:12:23 +0000620
Richard Smithd18ab802016-05-16 22:52:23 +0000621 unsigned LastAsmStringToken = 0;
622 unsigned LastAsmStringOffset = 0;
623
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000624 while (true) {
Chris Lattner35b58362009-03-10 23:21:44 +0000625 // Done with the string?
Chris Lattnera41b8472009-03-10 23:51:40 +0000626 if (CurPtr == StrEnd) {
Chris Lattner35b58362009-03-10 23:21:44 +0000627 if (!CurStringPiece.empty())
628 Pieces.push_back(AsmStringPiece(CurStringPiece));
Chris Lattnera41b8472009-03-10 23:51:40 +0000629 return 0;
Chris Lattner35b58362009-03-10 23:21:44 +0000630 }
Mike Stump11289f42009-09-09 15:08:12 +0000631
Chris Lattnera41b8472009-03-10 23:51:40 +0000632 char CurChar = *CurPtr++;
Chris Lattnerda081a82010-04-05 18:44:00 +0000633 switch (CurChar) {
634 case '$': CurStringPiece += "$$"; continue;
Chris Lattner1a8f3942010-04-23 16:29:58 +0000635 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
636 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
637 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
Chris Lattnerda081a82010-04-05 18:44:00 +0000638 case '%':
639 break;
640 default:
Chris Lattner35b58362009-03-10 23:21:44 +0000641 CurStringPiece += CurChar;
642 continue;
643 }
Chad Rosier42032fa2012-08-07 23:12:23 +0000644
Chris Lattner35b58362009-03-10 23:21:44 +0000645 // Escaped "%" character in asm string.
Chris Lattner3fa25c62009-03-11 00:06:36 +0000646 if (CurPtr == StrEnd) {
647 // % at end of string is invalid (no escape).
648 DiagOffs = CurPtr-StrStart-1;
649 return diag::err_asm_invalid_escape;
650 }
Michael Zuckerman2460bad2016-10-31 15:27:54 +0000651 // Handle escaped char and continue looping over the asm string.
Chris Lattnera41b8472009-03-10 23:51:40 +0000652 char EscapedChar = *CurPtr++;
Michael Zuckerman2460bad2016-10-31 15:27:54 +0000653 switch (EscapedChar) {
654 default:
655 break;
656 case '%': // %% -> %
657 case '{': // %{ -> {
658 case '}': // %} -> }
659 CurStringPiece += EscapedChar;
Chris Lattner35b58362009-03-10 23:21:44 +0000660 continue;
Michael Zuckerman2460bad2016-10-31 15:27:54 +0000661 case '=': // %= -> Generate a unique ID.
Chris Lattner35b58362009-03-10 23:21:44 +0000662 CurStringPiece += "${:uid}";
663 continue;
664 }
Mike Stump11289f42009-09-09 15:08:12 +0000665
Chris Lattner35b58362009-03-10 23:21:44 +0000666 // Otherwise, we have an operand. If we have accumulated a string so far,
667 // add it to the Pieces list.
668 if (!CurStringPiece.empty()) {
669 Pieces.push_back(AsmStringPiece(CurStringPiece));
670 CurStringPiece.clear();
671 }
Mike Stump11289f42009-09-09 15:08:12 +0000672
Akira Hatanaka987f1862014-08-22 06:05:21 +0000673 // Handle operands that have asmSymbolicName (e.g., %x[foo]) and those that
674 // don't (e.g., %x4). 'x' following the '%' is the constraint modifier.
675
676 const char *Begin = CurPtr - 1; // Points to the character following '%'.
677 const char *Percent = Begin - 1; // Points to '%'.
678
Jordan Rosea7d03842013-02-08 22:30:41 +0000679 if (isLetter(EscapedChar)) {
Benjamin Kramere87c38b2011-07-05 11:13:37 +0000680 if (CurPtr == StrEnd) { // Premature end.
681 DiagOffs = CurPtr-StrStart-1;
682 return diag::err_asm_invalid_escape;
683 }
Chris Lattnera41b8472009-03-10 23:51:40 +0000684 EscapedChar = *CurPtr++;
Chris Lattner35b58362009-03-10 23:21:44 +0000685 }
Mike Stump11289f42009-09-09 15:08:12 +0000686
Akira Hatanaka987f1862014-08-22 06:05:21 +0000687 const TargetInfo &TI = C.getTargetInfo();
688 const SourceManager &SM = C.getSourceManager();
689 const LangOptions &LO = C.getLangOpts();
690
691 // Handle operands that don't have asmSymbolicName (e.g., %x4).
Jordan Rosea7d03842013-02-08 22:30:41 +0000692 if (isDigit(EscapedChar)) {
Chris Lattner35b58362009-03-10 23:21:44 +0000693 // %n - Assembler operand n
Chris Lattner99d892b2009-03-11 22:52:17 +0000694 unsigned N = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000695
Chris Lattner99d892b2009-03-11 22:52:17 +0000696 --CurPtr;
Jordan Rosea7d03842013-02-08 22:30:41 +0000697 while (CurPtr != StrEnd && isDigit(*CurPtr))
Chris Lattner84f3afa2009-03-11 23:09:16 +0000698 N = N*10 + ((*CurPtr++)-'0');
Mike Stump11289f42009-09-09 15:08:12 +0000699
Jennifer Yub8fee672019-06-03 15:57:25 +0000700 unsigned NumOperands = getNumOutputs() + getNumPlusOperands() +
701 getNumInputs() + getNumLabels();
Chris Lattner14311922009-03-11 00:23:13 +0000702 if (N >= NumOperands) {
703 DiagOffs = CurPtr-StrStart-1;
704 return diag::err_asm_invalid_operand_number;
705 }
706
Akira Hatanaka987f1862014-08-22 06:05:21 +0000707 // Str contains "x4" (Operand without the leading %).
708 std::string Str(Begin, CurPtr - Begin);
709
710 // (BeginLoc, EndLoc) represents the range of the operand we are currently
711 // processing. Unlike Str, the range includes the leading '%'.
Richard Smithd18ab802016-05-16 22:52:23 +0000712 SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
713 Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
714 &LastAsmStringOffset);
715 SourceLocation EndLoc = getAsmString()->getLocationOfByte(
716 CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
717 &LastAsmStringOffset);
Akira Hatanaka987f1862014-08-22 06:05:21 +0000718
Benjamin Kramer3204b152015-05-29 19:42:19 +0000719 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
Chris Lattner35b58362009-03-10 23:21:44 +0000720 continue;
721 }
Mike Stump11289f42009-09-09 15:08:12 +0000722
Akira Hatanaka987f1862014-08-22 06:05:21 +0000723 // Handle operands that have asmSymbolicName (e.g., %x[foo]).
Chris Lattner35b58362009-03-10 23:21:44 +0000724 if (EscapedChar == '[') {
Chris Lattner3fa25c62009-03-11 00:06:36 +0000725 DiagOffs = CurPtr-StrStart-1;
Mike Stump11289f42009-09-09 15:08:12 +0000726
Chris Lattner3fa25c62009-03-11 00:06:36 +0000727 // Find the ']'.
Chris Lattnera41b8472009-03-10 23:51:40 +0000728 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
Craig Topper36250ad2014-05-12 05:36:57 +0000729 if (NameEnd == nullptr)
Chris Lattner3fa25c62009-03-11 00:06:36 +0000730 return diag::err_asm_unterminated_symbolic_operand_name;
731 if (NameEnd == CurPtr)
732 return diag::err_asm_empty_symbolic_operand_name;
Mike Stump11289f42009-09-09 15:08:12 +0000733
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000734 StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
Mike Stump11289f42009-09-09 15:08:12 +0000735
Chris Lattner35b58362009-03-10 23:21:44 +0000736 int N = getNamedOperand(SymbolicName);
Chris Lattner3fa25c62009-03-11 00:06:36 +0000737 if (N == -1) {
738 // Verify that an operand with that name exists.
739 DiagOffs = CurPtr-StrStart;
740 return diag::err_asm_unknown_symbolic_operand_name;
741 }
Akira Hatanaka987f1862014-08-22 06:05:21 +0000742
743 // Str contains "x[foo]" (Operand without the leading %).
744 std::string Str(Begin, NameEnd + 1 - Begin);
745
746 // (BeginLoc, EndLoc) represents the range of the operand we are currently
747 // processing. Unlike Str, the range includes the leading '%'.
Richard Smithd18ab802016-05-16 22:52:23 +0000748 SourceLocation BeginLoc = getAsmString()->getLocationOfByte(
749 Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
750 &LastAsmStringOffset);
751 SourceLocation EndLoc = getAsmString()->getLocationOfByte(
752 NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
753 &LastAsmStringOffset);
Akira Hatanaka987f1862014-08-22 06:05:21 +0000754
Benjamin Kramer3204b152015-05-29 19:42:19 +0000755 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000756
Chris Lattner3fa25c62009-03-11 00:06:36 +0000757 CurPtr = NameEnd+1;
Chris Lattner35b58362009-03-10 23:21:44 +0000758 continue;
759 }
Mike Stump11289f42009-09-09 15:08:12 +0000760
Chris Lattner0cdaa2e2009-03-10 23:57:07 +0000761 DiagOffs = CurPtr-StrStart-1;
Chris Lattnera41b8472009-03-10 23:51:40 +0000762 return diag::err_asm_invalid_escape;
Chris Lattner35b58362009-03-10 23:21:44 +0000763 }
764}
Chad Rosier3b0c2602012-08-27 20:23:31 +0000765
766/// Assemble final IR asm string (GCC-style).
Craig Topperc571c812013-08-22 06:02:26 +0000767std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
Chad Rosier14836ba2012-08-24 17:05:45 +0000768 // Analyze the asm string to decompose it into its pieces. We know that Sema
769 // has already done this, so it is guaranteed to be successful.
Chad Rosierde70e0e2012-08-25 00:11:56 +0000770 SmallVector<GCCAsmStmt::AsmStringPiece, 4> Pieces;
Chad Rosier14836ba2012-08-24 17:05:45 +0000771 unsigned DiagOffs;
772 AnalyzeAsmString(Pieces, C, DiagOffs);
773
774 std::string AsmString;
Eugene Zelenko7855e772018-04-03 00:11:50 +0000775 for (const auto &Piece : Pieces) {
776 if (Piece.isString())
777 AsmString += Piece.getString();
778 else if (Piece.getModifier() == '\0')
779 AsmString += '$' + llvm::utostr(Piece.getOperandNo());
Chad Rosier14836ba2012-08-24 17:05:45 +0000780 else
Eugene Zelenko7855e772018-04-03 00:11:50 +0000781 AsmString += "${" + llvm::utostr(Piece.getOperandNo()) + ':' +
782 Piece.getModifier() + '}';
Chad Rosier14836ba2012-08-24 17:05:45 +0000783 }
784 return AsmString;
785}
Chris Lattner35b58362009-03-10 23:21:44 +0000786
Chad Rosier3b0c2602012-08-27 20:23:31 +0000787/// Assemble final IR asm string (MS-style).
Craig Topperc571c812013-08-22 06:02:26 +0000788std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
Chad Rosier3b0c2602012-08-27 20:23:31 +0000789 // FIXME: This needs to be translated into the IR string representation.
Benjamin Krameradcd0262020-01-28 20:23:46 +0100790 return std::string(AsmStr);
Chad Rosier3b0c2602012-08-27 20:23:31 +0000791}
792
Chad Rosierfe31e622012-08-24 00:07:09 +0000793Expr *MSAsmStmt::getOutputExpr(unsigned i) {
794 return cast<Expr>(Exprs[i]);
795}
796
797Expr *MSAsmStmt::getInputExpr(unsigned i) {
798 return cast<Expr>(Exprs[i + NumOutputs]);
799}
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000800
Chad Rosierfe31e622012-08-24 00:07:09 +0000801void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
802 Exprs[i + NumOutputs] = E;
803}
804
Chris Lattner86f5e132008-01-30 05:01:46 +0000805//===----------------------------------------------------------------------===//
806// Constructors
807//===----------------------------------------------------------------------===//
808
Craig Toppere6960e22013-08-22 05:28:54 +0000809GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
810 bool issimple, bool isvolatile, unsigned numoutputs,
811 unsigned numinputs, IdentifierInfo **names,
812 StringLiteral **constraints, Expr **exprs,
813 StringLiteral *asmstr, unsigned numclobbers,
Jennifer Yub8fee672019-06-03 15:57:25 +0000814 StringLiteral **clobbers, unsigned numlabels,
815 SourceLocation rparenloc)
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000816 : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
Jennifer Yub8fee672019-06-03 15:57:25 +0000817 numinputs, numclobbers),
818 RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
819 unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
Chad Rosier42032fa2012-08-07 23:12:23 +0000820
Anders Carlsson98323d22010-01-30 23:19:41 +0000821 Names = new (C) IdentifierInfo*[NumExprs];
822 std::copy(names, names + NumExprs, Names);
823
824 Exprs = new (C) Stmt*[NumExprs];
825 std::copy(exprs, exprs + NumExprs, Exprs);
826
Benjamin Kramer851f57e2019-05-30 07:21:08 +0000827 unsigned NumConstraints = NumOutputs + NumInputs;
828 Constraints = new (C) StringLiteral*[NumConstraints];
829 std::copy(constraints, constraints + NumConstraints, Constraints);
Anders Carlsson98323d22010-01-30 23:19:41 +0000830
831 Clobbers = new (C) StringLiteral*[NumClobbers];
832 std::copy(clobbers, clobbers + NumClobbers, Clobbers);
Anders Carlsson94ea8aa2007-11-22 01:36:19 +0000833}
834
Craig Toppere6960e22013-08-22 05:28:54 +0000835MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
Chad Rosier7dbef3e2012-08-16 00:06:53 +0000836 SourceLocation lbraceloc, bool issimple, bool isvolatile,
Chad Rosierf8037a12012-10-16 21:55:39 +0000837 ArrayRef<Token> asmtoks, unsigned numoutputs,
John McCallf413f5e2013-05-03 00:10:13 +0000838 unsigned numinputs,
Chad Rosierf8037a12012-10-16 21:55:39 +0000839 ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
840 StringRef asmstr, ArrayRef<StringRef> clobbers,
841 SourceLocation endloc)
Eugene Zelenko1eab6c12017-11-14 23:35:42 +0000842 : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
843 numinputs, clobbers.size()), LBraceLoc(lbraceloc),
844 EndLoc(endloc), NumAsmToks(asmtoks.size()) {
John McCallf413f5e2013-05-03 00:10:13 +0000845 initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
846}
Chad Rosier7dbef3e2012-08-16 00:06:53 +0000847
Craig Toppere6960e22013-08-22 05:28:54 +0000848static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
Benjamin Kramer2ab0d882015-08-04 12:34:23 +0000849 return str.copy(C);
John McCallf413f5e2013-05-03 00:10:13 +0000850}
851
Craig Toppere6960e22013-08-22 05:28:54 +0000852void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
John McCallf413f5e2013-05-03 00:10:13 +0000853 ArrayRef<Token> asmtoks,
854 ArrayRef<StringRef> constraints,
855 ArrayRef<Expr*> exprs,
856 ArrayRef<StringRef> clobbers) {
857 assert(NumAsmToks == asmtoks.size());
858 assert(NumClobbers == clobbers.size());
859
Craig Toppercaf138e2015-12-05 07:41:42 +0000860 assert(exprs.size() == NumOutputs + NumInputs);
861 assert(exprs.size() == constraints.size());
John McCallf413f5e2013-05-03 00:10:13 +0000862
863 AsmStr = copyIntoContext(C, asmstr);
Chad Rosier99fc3812012-08-07 00:29:06 +0000864
Craig Toppercaf138e2015-12-05 07:41:42 +0000865 Exprs = new (C) Stmt*[exprs.size()];
866 std::copy(exprs.begin(), exprs.end(), Exprs);
Chad Rosierfe31e622012-08-24 00:07:09 +0000867
Craig Toppercaf138e2015-12-05 07:41:42 +0000868 AsmToks = new (C) Token[asmtoks.size()];
869 std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
Chad Rosier3ed0bd92012-08-08 19:48:07 +0000870
Craig Toppercaf138e2015-12-05 07:41:42 +0000871 Constraints = new (C) StringRef[exprs.size()];
872 std::transform(constraints.begin(), constraints.end(), Constraints,
873 [&](StringRef Constraint) {
874 return copyIntoContext(C, Constraint);
875 });
Chad Rosier3dd7bf22012-08-28 20:28:20 +0000876
Chad Rosierbaf53f92012-08-10 21:36:25 +0000877 Clobbers = new (C) StringRef[NumClobbers];
Craig Toppercaf138e2015-12-05 07:41:42 +0000878 // FIXME: Avoid the allocation/copy if at all possible.
879 std::transform(clobbers.begin(), clobbers.end(), Clobbers,
880 [&](StringRef Clobber) {
881 return copyIntoContext(C, Clobber);
882 });
Chad Rosier32503022012-06-11 20:47:18 +0000883}
884
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000885IfStmt::IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr,
Zequan Wu94c6cea2020-08-10 16:29:33 -0700886 Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL,
887 SourceLocation RPL, Stmt *Then, SourceLocation EL, Stmt *Else)
888 : Stmt(IfStmtClass), LParenLoc(LPL), RParenLoc(RPL) {
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000889 bool HasElse = Else != nullptr;
890 bool HasVar = Var != nullptr;
891 bool HasInit = Init != nullptr;
892 IfStmtBits.HasElse = HasElse;
893 IfStmtBits.HasVar = HasVar;
894 IfStmtBits.HasInit = HasInit;
895
Richard Smithb130fe72016-06-23 19:16:49 +0000896 setConstexpr(IsConstexpr);
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000897
898 setCond(Cond);
899 setThen(Then);
900 if (HasElse)
901 setElse(Else);
902 if (HasVar)
903 setConditionVariable(Ctx, Var);
904 if (HasInit)
905 setInit(Init);
906
907 setIfLoc(IL);
908 if (HasElse)
909 setElseLoc(EL);
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000910}
911
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000912IfStmt::IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit)
913 : Stmt(IfStmtClass, Empty) {
914 IfStmtBits.HasElse = HasElse;
915 IfStmtBits.HasVar = HasVar;
916 IfStmtBits.HasInit = HasInit;
917}
Chad Rosier42032fa2012-08-07 23:12:23 +0000918
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000919IfStmt *IfStmt::Create(const ASTContext &Ctx, SourceLocation IL,
920 bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
Zequan Wu94c6cea2020-08-10 16:29:33 -0700921 SourceLocation LPL, SourceLocation RPL, Stmt *Then,
922 SourceLocation EL, Stmt *Else) {
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000923 bool HasElse = Else != nullptr;
924 bool HasVar = Var != nullptr;
925 bool HasInit = Init != nullptr;
926 void *Mem = Ctx.Allocate(
927 totalSizeToAlloc<Stmt *, SourceLocation>(
928 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
929 alignof(IfStmt));
930 return new (Mem)
Zequan Wu94c6cea2020-08-10 16:29:33 -0700931 IfStmt(Ctx, IL, IsConstexpr, Init, Var, Cond, LPL, RPL, Then, EL, Else);
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000932}
933
934IfStmt *IfStmt::CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
935 bool HasInit) {
936 void *Mem = Ctx.Allocate(
937 totalSizeToAlloc<Stmt *, SourceLocation>(
938 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
939 alignof(IfStmt));
940 return new (Mem) IfStmt(EmptyShell(), HasElse, HasVar, HasInit);
941}
942
943VarDecl *IfStmt::getConditionVariable() {
944 auto *DS = getConditionVariableDeclStmt();
945 if (!DS)
946 return nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000947 return cast<VarDecl>(DS->getSingleDecl());
948}
949
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000950void IfStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
951 assert(hasVarStorage() &&
952 "This if statement has no storage for a condition variable!");
953
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000954 if (!V) {
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000955 getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000956 return;
957 }
Chad Rosier42032fa2012-08-07 23:12:23 +0000958
Daniel Dunbar62ee6412012-03-09 18:35:03 +0000959 SourceRange VarRange = V->getSourceRange();
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000960 getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
961 DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000962}
963
Erik Pilkington5cd57172016-08-16 17:44:11 +0000964bool IfStmt::isObjCAvailabilityCheck() const {
Bruno Riccib1cc94b2018-10-27 21:12:20 +0000965 return isa<ObjCAvailabilityCheckExpr>(getCond());
Erik Pilkington5cd57172016-08-16 17:44:11 +0000966}
967
Richard Smithfbf60b72019-12-13 14:10:13 -0800968Optional<const Stmt*> IfStmt::getNondiscardedCase(const ASTContext &Ctx) const {
969 if (!isConstexpr() || getCond()->isValueDependent())
970 return None;
971 return !getCond()->EvaluateKnownConstInt(Ctx) ? getElse() : getThen();
972}
973
Craig Toppere6960e22013-08-22 05:28:54 +0000974ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
Chad Rosier42032fa2012-08-07 23:12:23 +0000975 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000976 SourceLocation RP)
Bruno Ricci41d11c02018-10-27 18:43:27 +0000977 : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000978{
979 SubExprs[INIT] = Init;
980 setConditionVariable(C, condVar);
Pavel Labath515f4db2013-09-03 14:41:16 +0000981 SubExprs[COND] = Cond;
982 SubExprs[INC] = Inc;
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000983 SubExprs[BODY] = Body;
Bruno Ricci41d11c02018-10-27 18:43:27 +0000984 ForStmtBits.ForLoc = FL;
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000985}
986
987VarDecl *ForStmt::getConditionVariable() const {
988 if (!SubExprs[CONDVAR])
Craig Topper36250ad2014-05-12 05:36:57 +0000989 return nullptr;
Chad Rosier42032fa2012-08-07 23:12:23 +0000990
Eugene Zelenko7855e772018-04-03 00:11:50 +0000991 auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000992 return cast<VarDecl>(DS->getSingleDecl());
993}
994
Craig Toppere6960e22013-08-22 05:28:54 +0000995void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000996 if (!V) {
Craig Topper36250ad2014-05-12 05:36:57 +0000997 SubExprs[CONDVAR] = nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +0000998 return;
999 }
Chad Rosier42032fa2012-08-07 23:12:23 +00001000
Daniel Dunbar62ee6412012-03-09 18:35:03 +00001001 SourceRange VarRange = V->getSourceRange();
1002 SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
1003 VarRange.getEnd());
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001004}
1005
Bruno Riccie2806f82018-10-29 16:12:37 +00001006SwitchStmt::SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
Zequan Wu94c6cea2020-08-10 16:29:33 -07001007 Expr *Cond, SourceLocation LParenLoc,
1008 SourceLocation RParenLoc)
1009 : Stmt(SwitchStmtClass), FirstCase(nullptr), LParenLoc(LParenLoc),
1010 RParenLoc(RParenLoc) {
Bruno Riccie2806f82018-10-29 16:12:37 +00001011 bool HasInit = Init != nullptr;
1012 bool HasVar = Var != nullptr;
1013 SwitchStmtBits.HasInit = HasInit;
1014 SwitchStmtBits.HasVar = HasVar;
1015 SwitchStmtBits.AllEnumCasesCovered = false;
1016
1017 setCond(Cond);
1018 setBody(nullptr);
1019 if (HasInit)
1020 setInit(Init);
1021 if (HasVar)
1022 setConditionVariable(Ctx, Var);
1023
1024 setSwitchLoc(SourceLocation{});
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001025}
1026
Bruno Riccie2806f82018-10-29 16:12:37 +00001027SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)
1028 : Stmt(SwitchStmtClass, Empty) {
1029 SwitchStmtBits.HasInit = HasInit;
1030 SwitchStmtBits.HasVar = HasVar;
1031 SwitchStmtBits.AllEnumCasesCovered = false;
1032}
Chad Rosier42032fa2012-08-07 23:12:23 +00001033
Bruno Riccie2806f82018-10-29 16:12:37 +00001034SwitchStmt *SwitchStmt::Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
Zequan Wu94c6cea2020-08-10 16:29:33 -07001035 Expr *Cond, SourceLocation LParenLoc,
1036 SourceLocation RParenLoc) {
Bruno Riccie2806f82018-10-29 16:12:37 +00001037 bool HasInit = Init != nullptr;
1038 bool HasVar = Var != nullptr;
1039 void *Mem = Ctx.Allocate(
1040 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
1041 alignof(SwitchStmt));
Zequan Wu94c6cea2020-08-10 16:29:33 -07001042 return new (Mem) SwitchStmt(Ctx, Init, Var, Cond, LParenLoc, RParenLoc);
Bruno Riccie2806f82018-10-29 16:12:37 +00001043}
1044
1045SwitchStmt *SwitchStmt::CreateEmpty(const ASTContext &Ctx, bool HasInit,
1046 bool HasVar) {
1047 void *Mem = Ctx.Allocate(
1048 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
1049 alignof(SwitchStmt));
1050 return new (Mem) SwitchStmt(EmptyShell(), HasInit, HasVar);
1051}
1052
1053VarDecl *SwitchStmt::getConditionVariable() {
1054 auto *DS = getConditionVariableDeclStmt();
1055 if (!DS)
1056 return nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001057 return cast<VarDecl>(DS->getSingleDecl());
1058}
1059
Bruno Riccie2806f82018-10-29 16:12:37 +00001060void SwitchStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
1061 assert(hasVarStorage() &&
1062 "This switch statement has no storage for a condition variable!");
1063
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001064 if (!V) {
Bruno Riccie2806f82018-10-29 16:12:37 +00001065 getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001066 return;
1067 }
Chad Rosier42032fa2012-08-07 23:12:23 +00001068
Daniel Dunbar62ee6412012-03-09 18:35:03 +00001069 SourceRange VarRange = V->getSourceRange();
Bruno Riccie2806f82018-10-29 16:12:37 +00001070 getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
1071 DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001072}
1073
Bruno Riccibacf7512018-10-30 13:42:41 +00001074WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
Vy Nguyen17ea41e2020-07-09 23:19:06 -04001075 Stmt *Body, SourceLocation WL, SourceLocation LParenLoc,
1076 SourceLocation RParenLoc)
Bruno Riccibacf7512018-10-30 13:42:41 +00001077 : Stmt(WhileStmtClass) {
1078 bool HasVar = Var != nullptr;
1079 WhileStmtBits.HasVar = HasVar;
1080
1081 setCond(Cond);
1082 setBody(Body);
1083 if (HasVar)
1084 setConditionVariable(Ctx, Var);
1085
1086 setWhileLoc(WL);
Vy Nguyen17ea41e2020-07-09 23:19:06 -04001087 setLParenLoc(LParenLoc);
1088 setRParenLoc(RParenLoc);
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001089}
1090
Bruno Riccibacf7512018-10-30 13:42:41 +00001091WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
1092 : Stmt(WhileStmtClass, Empty) {
1093 WhileStmtBits.HasVar = HasVar;
1094}
Chad Rosier42032fa2012-08-07 23:12:23 +00001095
Bruno Riccibacf7512018-10-30 13:42:41 +00001096WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
Vy Nguyen17ea41e2020-07-09 23:19:06 -04001097 Stmt *Body, SourceLocation WL,
1098 SourceLocation LParenLoc,
1099 SourceLocation RParenLoc) {
Bruno Riccibacf7512018-10-30 13:42:41 +00001100 bool HasVar = Var != nullptr;
1101 void *Mem =
1102 Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1103 alignof(WhileStmt));
Vy Nguyen17ea41e2020-07-09 23:19:06 -04001104 return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL, LParenLoc, RParenLoc);
Bruno Riccibacf7512018-10-30 13:42:41 +00001105}
1106
1107WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {
1108 void *Mem =
1109 Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1110 alignof(WhileStmt));
1111 return new (Mem) WhileStmt(EmptyShell(), HasVar);
1112}
1113
1114VarDecl *WhileStmt::getConditionVariable() {
1115 auto *DS = getConditionVariableDeclStmt();
1116 if (!DS)
1117 return nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001118 return cast<VarDecl>(DS->getSingleDecl());
1119}
1120
Bruno Riccibacf7512018-10-30 13:42:41 +00001121void WhileStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
1122 assert(hasVarStorage() &&
1123 "This while statement has no storage for a condition variable!");
1124
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001125 if (!V) {
Bruno Riccibacf7512018-10-30 13:42:41 +00001126 getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001127 return;
1128 }
Daniel Dunbar62ee6412012-03-09 18:35:03 +00001129
1130 SourceRange VarRange = V->getSourceRange();
Bruno Riccibacf7512018-10-30 13:42:41 +00001131 getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
1132 DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
Douglas Gregor27b98ea2010-06-21 23:44:13 +00001133}
1134
Ted Kremenek066dd932007-08-24 21:09:09 +00001135// IndirectGotoStmt
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001136LabelDecl *IndirectGotoStmt::getConstantTarget() {
Eugene Zelenko7855e772018-04-03 00:11:50 +00001137 if (auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
John McCall9de91602010-10-28 08:53:48 +00001138 return E->getLabel();
Craig Topper36250ad2014-05-12 05:36:57 +00001139 return nullptr;
John McCall9de91602010-10-28 08:53:48 +00001140}
Ted Kremenek066dd932007-08-24 21:09:09 +00001141
Ted Kremenek066dd932007-08-24 21:09:09 +00001142// ReturnStmt
Bruno Ricci023b1d12018-10-30 14:40:49 +00001143ReturnStmt::ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1144 : Stmt(ReturnStmtClass), RetExpr(E) {
1145 bool HasNRVOCandidate = NRVOCandidate != nullptr;
1146 ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1147 if (HasNRVOCandidate)
1148 setNRVOCandidate(NRVOCandidate);
1149 setReturnLoc(RL);
Ted Kremenekc6501db2008-06-17 03:11:08 +00001150}
Bruno Ricci023b1d12018-10-30 14:40:49 +00001151
1152ReturnStmt::ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate)
1153 : Stmt(ReturnStmtClass, Empty) {
1154 ReturnStmtBits.HasNRVOCandidate = HasNRVOCandidate;
1155}
1156
1157ReturnStmt *ReturnStmt::Create(const ASTContext &Ctx, SourceLocation RL,
1158 Expr *E, const VarDecl *NRVOCandidate) {
1159 bool HasNRVOCandidate = NRVOCandidate != nullptr;
1160 void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1161 alignof(ReturnStmt));
1162 return new (Mem) ReturnStmt(RL, E, NRVOCandidate);
1163}
1164
1165ReturnStmt *ReturnStmt::CreateEmpty(const ASTContext &Ctx,
1166 bool HasNRVOCandidate) {
1167 void *Mem = Ctx.Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1168 alignof(ReturnStmt));
1169 return new (Mem) ReturnStmt(EmptyShell(), HasNRVOCandidate);
Ted Kremenek066dd932007-08-24 21:09:09 +00001170}
John Wiegley1c0675e2011-04-28 01:08:34 +00001171
Bruno Ricci5b30571752018-10-28 12:30:53 +00001172// CaseStmt
1173CaseStmt *CaseStmt::Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
1174 SourceLocation caseLoc, SourceLocation ellipsisLoc,
1175 SourceLocation colonLoc) {
1176 bool CaseStmtIsGNURange = rhs != nullptr;
1177 void *Mem = Ctx.Allocate(
1178 totalSizeToAlloc<Stmt *, SourceLocation>(
1179 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1180 alignof(CaseStmt));
1181 return new (Mem) CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
1182}
1183
1184CaseStmt *CaseStmt::CreateEmpty(const ASTContext &Ctx,
1185 bool CaseStmtIsGNURange) {
1186 void *Mem = Ctx.Allocate(
1187 totalSizeToAlloc<Stmt *, SourceLocation>(
1188 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1189 alignof(CaseStmt));
1190 return new (Mem) CaseStmt(EmptyShell(), CaseStmtIsGNURange);
1191}
1192
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001193SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
Warren Huntf6be4cb2014-07-25 20:52:51 +00001194 Stmt *Handler)
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001195 : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
Warren Huntf6be4cb2014-07-25 20:52:51 +00001196 Children[TRY] = TryBlock;
John Wiegley1c0675e2011-04-28 01:08:34 +00001197 Children[HANDLER] = Handler;
1198}
1199
Warren Huntf6be4cb2014-07-25 20:52:51 +00001200SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
Craig Toppere6960e22013-08-22 05:28:54 +00001201 SourceLocation TryLoc, Stmt *TryBlock,
Warren Huntf6be4cb2014-07-25 20:52:51 +00001202 Stmt *Handler) {
1203 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
John Wiegley1c0675e2011-04-28 01:08:34 +00001204}
1205
1206SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
1207 return dyn_cast<SEHExceptStmt>(getHandler());
1208}
1209
1210SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
1211 return dyn_cast<SEHFinallyStmt>(getHandler());
1212}
1213
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001214SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
1215 : Stmt(SEHExceptStmtClass), Loc(Loc) {
Pavel Labath515f4db2013-09-03 14:41:16 +00001216 Children[FILTER_EXPR] = FilterExpr;
John Wiegley1c0675e2011-04-28 01:08:34 +00001217 Children[BLOCK] = Block;
1218}
1219
Craig Toppere6960e22013-08-22 05:28:54 +00001220SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc,
1221 Expr *FilterExpr, Stmt *Block) {
John Wiegley1c0675e2011-04-28 01:08:34 +00001222 return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
1223}
1224
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001225SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
1226 : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
John Wiegley1c0675e2011-04-28 01:08:34 +00001227
Craig Toppere6960e22013-08-22 05:28:54 +00001228SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
John Wiegley1c0675e2011-04-28 01:08:34 +00001229 Stmt *Block) {
1230 return new(C)SEHFinallyStmt(Loc,Block);
1231}
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001232
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001233CapturedStmt::Capture::Capture(SourceLocation Loc, VariableCaptureKind Kind,
1234 VarDecl *Var)
1235 : VarAndKind(Var, Kind), Loc(Loc) {
1236 switch (Kind) {
1237 case VCK_This:
1238 assert(!Var && "'this' capture cannot have a variable!");
1239 break;
1240 case VCK_ByRef:
1241 assert(Var && "capturing by reference must have a variable!");
1242 break;
1243 case VCK_ByCopy:
1244 assert(Var && "capturing by copy must have a variable!");
1245 assert(
1246 (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
1247 Var->getType()
1248 ->castAs<ReferenceType>()
1249 ->getPointeeType()
1250 ->isScalarType())) &&
1251 "captures by copy are expected to have a scalar type!");
1252 break;
1253 case VCK_VLAType:
1254 assert(!Var &&
1255 "Variable-length array type capture cannot have a variable!");
1256 break;
1257 }
1258}
1259
Chandler Carruth21c90602015-12-30 03:24:14 +00001260CapturedStmt::VariableCaptureKind
1261CapturedStmt::Capture::getCaptureKind() const {
1262 return VarAndKind.getInt();
1263}
1264
1265VarDecl *CapturedStmt::Capture::getCapturedVar() const {
1266 assert((capturesVariable() || capturesVariableByCopy()) &&
1267 "No variable available for 'this' or VAT capture");
1268 return VarAndKind.getPointer();
1269}
1270
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001271CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
1272 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1273
1274 // Offset of the first Capture object.
Benjamin Kramerc3f89252016-10-20 14:27:22 +00001275 unsigned FirstCaptureOffset = llvm::alignTo(Size, alignof(Capture));
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001276
1277 return reinterpret_cast<Capture *>(
1278 reinterpret_cast<char *>(const_cast<CapturedStmt *>(this))
1279 + FirstCaptureOffset);
1280}
1281
Wei Pan17fbf6e2013-05-04 03:59:06 +00001282CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
1283 ArrayRef<Capture> Captures,
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001284 ArrayRef<Expr *> CaptureInits,
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00001285 CapturedDecl *CD,
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001286 RecordDecl *RD)
1287 : Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
Wei Pan17fbf6e2013-05-04 03:59:06 +00001288 CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001289 assert( S && "null captured statement");
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00001290 assert(CD && "null captured declaration for captured statement");
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001291 assert(RD && "null record declaration for captured statement");
1292
1293 // Copy initialization expressions.
1294 Stmt **Stored = getStoredStmts();
1295 for (unsigned I = 0, N = NumCaptures; I != N; ++I)
1296 *Stored++ = CaptureInits[I];
1297
1298 // Copy the statement being captured.
1299 *Stored = S;
1300
1301 // Copy all Capture objects.
1302 Capture *Buffer = getStoredCaptures();
1303 std::copy(Captures.begin(), Captures.end(), Buffer);
1304}
1305
1306CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
1307 : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001308 CapDeclAndKind(nullptr, CR_Default) {
Craig Topper36250ad2014-05-12 05:36:57 +00001309 getStoredStmts()[NumCaptures] = nullptr;
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001310}
1311
Craig Toppere6960e22013-08-22 05:28:54 +00001312CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
Wei Pan17fbf6e2013-05-04 03:59:06 +00001313 CapturedRegionKind Kind,
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001314 ArrayRef<Capture> Captures,
1315 ArrayRef<Expr *> CaptureInits,
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00001316 CapturedDecl *CD,
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001317 RecordDecl *RD) {
1318 // The layout is
1319 //
1320 // -----------------------------------------------------------
1321 // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture |
1322 // ----------------^-------------------^----------------------
1323 // getStoredStmts() getStoredCaptures()
1324 //
1325 // where S is the statement being captured.
1326 //
1327 assert(CaptureInits.size() == Captures.size() && "wrong number of arguments");
1328
1329 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1);
1330 if (!Captures.empty()) {
1331 // Realign for the following Capture array.
Benjamin Kramerc3f89252016-10-20 14:27:22 +00001332 Size = llvm::alignTo(Size, alignof(Capture));
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001333 Size += sizeof(Capture) * Captures.size();
1334 }
1335
1336 void *Mem = Context.Allocate(Size);
Wei Pan17fbf6e2013-05-04 03:59:06 +00001337 return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001338}
1339
Craig Toppere6960e22013-08-22 05:28:54 +00001340CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context,
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001341 unsigned NumCaptures) {
1342 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
1343 if (NumCaptures > 0) {
1344 // Realign for the following Capture array.
Benjamin Kramerc3f89252016-10-20 14:27:22 +00001345 Size = llvm::alignTo(Size, alignof(Capture));
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001346 Size += sizeof(Capture) * NumCaptures;
1347 }
1348
1349 void *Mem = Context.Allocate(Size);
1350 return new (Mem) CapturedStmt(EmptyShell(), NumCaptures);
1351}
1352
1353Stmt::child_range CapturedStmt::children() {
Simon Pilgrim2c518802017-03-30 14:13:19 +00001354 // Children are captured field initializers.
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00001355 return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001356}
1357
Bruno Ricci06186502019-04-12 15:36:02 +00001358Stmt::const_child_range CapturedStmt::children() const {
1359 return const_child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1360}
1361
Chandler Carruth21c90602015-12-30 03:24:14 +00001362CapturedDecl *CapturedStmt::getCapturedDecl() {
1363 return CapDeclAndKind.getPointer();
1364}
Eugene Zelenko1eab6c12017-11-14 23:35:42 +00001365
Chandler Carruth21c90602015-12-30 03:24:14 +00001366const CapturedDecl *CapturedStmt::getCapturedDecl() const {
1367 return CapDeclAndKind.getPointer();
1368}
1369
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001370/// Set the outlined function declaration.
Chandler Carruth21c90602015-12-30 03:24:14 +00001371void CapturedStmt::setCapturedDecl(CapturedDecl *D) {
1372 assert(D && "null CapturedDecl");
1373 CapDeclAndKind.setPointer(D);
1374}
1375
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001376/// Retrieve the captured region kind.
Chandler Carruth21c90602015-12-30 03:24:14 +00001377CapturedRegionKind CapturedStmt::getCapturedRegionKind() const {
1378 return CapDeclAndKind.getInt();
1379}
1380
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001381/// Set the captured region kind.
Chandler Carruth21c90602015-12-30 03:24:14 +00001382void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {
1383 CapDeclAndKind.setInt(Kind);
1384}
1385
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001386bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
Aaron Ballmanc656303a2014-03-14 18:08:33 +00001387 for (const auto &I : captures()) {
Alexey Bataev2c845412017-05-15 16:26:15 +00001388 if (!I.capturesVariable() && !I.capturesVariableByCopy())
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001389 continue;
Alexey Bataeve85de8f2017-09-20 20:11:31 +00001390 if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
Tareq A. Siraj24110cc2013-04-16 18:53:08 +00001391 return true;
1392 }
1393
1394 return false;
1395}