blob: 8b2e35376bde0760c85b8ef7a9d139036c0f6465 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
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/ExprCXX.h"
Steve Narofff494b572008-05-29 21:12:08 +000016#include "clang/AST/ExprObjC.h"
Chris Lattner16f00492009-04-26 01:32:48 +000017#include "clang/AST/StmtCXX.h"
18#include "clang/AST/StmtObjC.h"
Sebastian Redl4b07b292008-12-22 19:15:10 +000019#include "clang/AST/Type.h"
Ted Kremenek11e5a7f2009-02-06 01:42:09 +000020#include "clang/AST/ASTContext.h"
Chris Lattner3182db12009-03-10 23:51:40 +000021#include "clang/AST/ASTDiagnostic.h"
Chris Lattner9bffb072010-04-23 16:29:58 +000022#include "clang/Basic/TargetInfo.h"
Chandler Carruthb43c8ec2011-07-04 06:13:27 +000023#include "llvm/Support/raw_ostream.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000024using namespace clang;
25
Reid Spencer5f016e22007-07-11 17:01:13 +000026static struct StmtClassNameTable {
Chris Lattner63381352007-08-25 01:42:24 +000027 const char *Name;
28 unsigned Counter;
29 unsigned Size;
Sean Hunt4bfe1962010-05-05 15:24:00 +000030} StmtClassInfo[Stmt::lastStmtConstant+1];
Chris Lattner63381352007-08-25 01:42:24 +000031
32static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
33 static bool Initialized = false;
34 if (Initialized)
35 return StmtClassInfo[E];
36
37 // Intialize the table on the first use.
38 Initialized = true;
Sean Hunt7381d5c2010-05-18 06:22:21 +000039#define ABSTRACT_STMT(STMT)
Douglas Gregorf2cad862008-11-14 12:46:07 +000040#define STMT(CLASS, PARENT) \
41 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
42 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
Sean Hunt4bfe1962010-05-05 15:24:00 +000043#include "clang/AST/StmtNodes.inc"
Nico Weber608b17f2008-08-05 23:15:29 +000044
Chris Lattner63381352007-08-25 01:42:24 +000045 return StmtClassInfo[E];
46}
47
Reid Spencer5f016e22007-07-11 17:01:13 +000048const char *Stmt::getStmtClassName() const {
John McCall8e6285a2010-10-26 08:39:16 +000049 return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
Reid Spencer5f016e22007-07-11 17:01:13 +000050}
51
52void Stmt::PrintStats() {
Chris Lattner63381352007-08-25 01:42:24 +000053 // Ensure the table is primed.
54 getStmtInfoTableEntry(Stmt::NullStmtClass);
Nico Weber608b17f2008-08-05 23:15:29 +000055
Reid Spencer5f016e22007-07-11 17:01:13 +000056 unsigned sum = 0;
Chandler Carruthb43c8ec2011-07-04 06:13:27 +000057 llvm::errs() << "\n*** Stmt/Expr Stats:\n";
Sean Hunt4bfe1962010-05-05 15:24:00 +000058 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
Chris Lattner63381352007-08-25 01:42:24 +000059 if (StmtClassInfo[i].Name == 0) continue;
60 sum += StmtClassInfo[i].Counter;
Reid Spencer5f016e22007-07-11 17:01:13 +000061 }
Chandler Carruthb43c8ec2011-07-04 06:13:27 +000062 llvm::errs() << " " << sum << " stmts/exprs total.\n";
Reid Spencer5f016e22007-07-11 17:01:13 +000063 sum = 0;
Sean Hunt4bfe1962010-05-05 15:24:00 +000064 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
Chris Lattner63381352007-08-25 01:42:24 +000065 if (StmtClassInfo[i].Name == 0) continue;
Douglas Gregordbe833d2009-05-26 14:40:08 +000066 if (StmtClassInfo[i].Counter == 0) continue;
Chandler Carruthb43c8ec2011-07-04 06:13:27 +000067 llvm::errs() << " " << StmtClassInfo[i].Counter << " "
68 << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
69 << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size
70 << " bytes)\n";
Chris Lattner63381352007-08-25 01:42:24 +000071 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
Reid Spencer5f016e22007-07-11 17:01:13 +000072 }
Chandler Carruthb43c8ec2011-07-04 06:13:27 +000073
74 llvm::errs() << "Total bytes = " << sum << "\n";
Reid Spencer5f016e22007-07-11 17:01:13 +000075}
76
77void Stmt::addStmtClass(StmtClass s) {
Chris Lattner63381352007-08-25 01:42:24 +000078 ++getStmtInfoTableEntry(s).Counter;
Reid Spencer5f016e22007-07-11 17:01:13 +000079}
80
81static bool StatSwitch = false;
82
Kovarththanan Rajaratnam2024f4d2009-11-29 14:54:35 +000083bool Stmt::CollectingStats(bool Enable) {
84 if (Enable) StatSwitch = true;
Chris Lattner63381352007-08-25 01:42:24 +000085 return StatSwitch;
Reid Spencer5f016e22007-07-11 17:01:13 +000086}
87
John McCall7e5e5f42011-07-07 06:58:02 +000088Stmt *Stmt::IgnoreImplicit() {
89 Stmt *s = this;
90
91 if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s))
92 s = ewc->getSubExpr();
93
94 while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s))
95 s = ice->getSubExpr();
96
97 return s;
98}
99
Chandler Carrutha1364be2011-09-10 00:02:34 +0000100/// \brief Strip off all label-like statements.
101///
102/// This will strip off label statements, case statements, and default
103/// statements recursively.
104const Stmt *Stmt::stripLabelLikeStatements() const {
105 const Stmt *S = this;
106 while (true) {
107 if (const LabelStmt *LS = dyn_cast<LabelStmt>(S))
108 S = LS->getSubStmt();
109 else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S))
110 S = SC->getSubStmt();
111 else
112 return S;
113 }
114}
115
John McCall63c00d72011-02-09 08:16:59 +0000116namespace {
117 struct good {};
118 struct bad {};
John McCallf8c7fdb2011-02-09 08:31:17 +0000119
120 // These silly little functions have to be static inline to suppress
121 // unused warnings, and they have to be defined to suppress other
122 // warnings.
Nick Lewycky086eb9f2011-02-09 08:42:57 +0000123 static inline good is_good(good) { return good(); }
John McCall63c00d72011-02-09 08:16:59 +0000124
125 typedef Stmt::child_range children_t();
Nick Lewycky086eb9f2011-02-09 08:42:57 +0000126 template <class T> good implements_children(children_t T::*) {
127 return good();
128 }
129 static inline bad implements_children(children_t Stmt::*) {
130 return bad();
131 }
John McCall63c00d72011-02-09 08:16:59 +0000132
133 typedef SourceRange getSourceRange_t() const;
Nick Lewycky086eb9f2011-02-09 08:42:57 +0000134 template <class T> good implements_getSourceRange(getSourceRange_t T::*) {
135 return good();
136 }
137 static inline bad implements_getSourceRange(getSourceRange_t Stmt::*) {
138 return bad();
139 }
John McCall63c00d72011-02-09 08:16:59 +0000140
141#define ASSERT_IMPLEMENTS_children(type) \
142 (void) sizeof(is_good(implements_children(&type::children)))
143#define ASSERT_IMPLEMENTS_getSourceRange(type) \
144 (void) sizeof(is_good(implements_getSourceRange(&type::getSourceRange)))
145}
146
147/// Check whether the various Stmt classes implement their member
148/// functions.
149static inline void check_implementations() {
150#define ABSTRACT_STMT(type)
151#define STMT(type, base) \
152 ASSERT_IMPLEMENTS_children(type); \
153 ASSERT_IMPLEMENTS_getSourceRange(type);
154#include "clang/AST/StmtNodes.inc"
155}
156
157Stmt::child_range Stmt::children() {
158 switch (getStmtClass()) {
159 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
160#define ABSTRACT_STMT(type)
161#define STMT(type, base) \
162 case Stmt::type##Class: \
163 return static_cast<type*>(this)->children();
164#include "clang/AST/StmtNodes.inc"
165 }
166 llvm_unreachable("unknown statement kind!");
John McCall63c00d72011-02-09 08:16:59 +0000167}
168
169SourceRange Stmt::getSourceRange() const {
170 switch (getStmtClass()) {
171 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
172#define ABSTRACT_STMT(type)
173#define STMT(type, base) \
174 case Stmt::type##Class: \
175 return static_cast<const type*>(this)->getSourceRange();
176#include "clang/AST/StmtNodes.inc"
177 }
178 llvm_unreachable("unknown statement kind!");
John McCall63c00d72011-02-09 08:16:59 +0000179}
180
Douglas Gregor025452f2009-04-17 00:04:06 +0000181void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
182 if (this->Body)
183 C.Deallocate(Body);
John McCall8e6285a2010-10-26 08:39:16 +0000184 this->CompoundStmtBits.NumStmts = NumStmts;
Douglas Gregor025452f2009-04-17 00:04:06 +0000185
186 Body = new (C) Stmt*[NumStmts];
187 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
188}
Reid Spencer5f016e22007-07-11 17:01:13 +0000189
Reid Spencer5f016e22007-07-11 17:01:13 +0000190const char *LabelStmt::getName() const {
Chris Lattnerad8dcf42011-02-17 07:39:24 +0000191 return getDecl()->getIdentifier()->getNameStart();
Reid Spencer5f016e22007-07-11 17:01:13 +0000192}
193
Steve Naroff507f2d52007-08-31 23:49:30 +0000194// This is defined here to avoid polluting Stmt.h with importing Expr.h
Nico Weber608b17f2008-08-05 23:15:29 +0000195SourceRange ReturnStmt::getSourceRange() const {
Steve Naroff507f2d52007-08-31 23:49:30 +0000196 if (RetExpr)
197 return SourceRange(RetLoc, RetExpr->getLocEnd());
198 else
199 return SourceRange(RetLoc);
200}
201
Ted Kremenekd48ade62007-10-01 16:34:52 +0000202bool Stmt::hasImplicitControlFlow() const {
John McCall8e6285a2010-10-26 08:39:16 +0000203 switch (StmtBits.sClass) {
Ted Kremenekd48ade62007-10-01 16:34:52 +0000204 default:
205 return false;
Nico Weber608b17f2008-08-05 23:15:29 +0000206
Ted Kremenekd48ade62007-10-01 16:34:52 +0000207 case CallExprClass:
208 case ConditionalOperatorClass:
209 case ChooseExprClass:
210 case StmtExprClass:
211 case DeclStmtClass:
Nico Weber608b17f2008-08-05 23:15:29 +0000212 return true;
213
Ted Kremenekd48ade62007-10-01 16:34:52 +0000214 case Stmt::BinaryOperatorClass: {
215 const BinaryOperator* B = cast<BinaryOperator>(this);
John McCall2de56d12010-08-25 11:45:40 +0000216 if (B->isLogicalOp() || B->getOpcode() == BO_Comma)
Ted Kremenekd48ade62007-10-01 16:34:52 +0000217 return true;
218 else
219 return false;
220 }
221 }
222}
223
Chris Lattnerb3277932009-03-10 04:59:06 +0000224Expr *AsmStmt::getOutputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000225 return cast<Expr>(Exprs[i]);
226}
Chris Lattnerb3277932009-03-10 04:59:06 +0000227
228/// getOutputConstraint - Return the constraint string for the specified
229/// output operand. All output constraints are known to be non-empty (either
230/// '=' or '+').
Chris Lattner5f9e2722011-07-23 10:55:15 +0000231StringRef AsmStmt::getOutputConstraint(unsigned i) const {
Anders Carlssonacb6bcb2010-01-30 20:38:10 +0000232 return getOutputConstraintLiteral(i)->getString();
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000233}
Chris Lattnerb3277932009-03-10 04:59:06 +0000234
Chris Lattner85759272009-03-11 00:23:13 +0000235/// getNumPlusOperands - Return the number of output operands that have a "+"
236/// constraint.
237unsigned AsmStmt::getNumPlusOperands() const {
238 unsigned Res = 0;
239 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
240 if (isOutputPlusConstraint(i))
241 ++Res;
242 return Res;
243}
244
Chris Lattnerb3277932009-03-10 04:59:06 +0000245Expr *AsmStmt::getInputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000246 return cast<Expr>(Exprs[i + NumOutputs]);
247}
Chris Lattner935f0f02011-02-21 22:09:29 +0000248void AsmStmt::setInputExpr(unsigned i, Expr *E) {
249 Exprs[i + NumOutputs] = E;
250}
251
Chris Lattnerb3277932009-03-10 04:59:06 +0000252
253/// getInputConstraint - Return the specified input constraint. Unlike output
254/// constraints, these can be empty.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000255StringRef AsmStmt::getInputConstraint(unsigned i) const {
Anders Carlssonacb6bcb2010-01-30 20:38:10 +0000256 return getInputConstraintLiteral(i)->getString();
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000257}
258
Chris Lattner10ca96a2009-03-10 06:33:24 +0000259
Anders Carlssonacb6bcb2010-01-30 20:38:10 +0000260void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
Anders Carlssonff93dbd2010-01-30 22:25:16 +0000261 IdentifierInfo **Names,
Anders Carlssonfdba9c02010-01-30 19:34:25 +0000262 StringLiteral **Constraints,
263 Stmt **Exprs,
264 unsigned NumOutputs,
Sean Huntc3021132010-05-05 15:23:54 +0000265 unsigned NumInputs,
Anders Carlssonfdba9c02010-01-30 19:34:25 +0000266 StringLiteral **Clobbers,
267 unsigned NumClobbers) {
Douglas Gregorcd7d5a92009-04-17 20:57:14 +0000268 this->NumOutputs = NumOutputs;
269 this->NumInputs = NumInputs;
Anders Carlsson966146e2010-01-30 23:19:41 +0000270 this->NumClobbers = NumClobbers;
271
272 unsigned NumExprs = NumOutputs + NumInputs;
Sean Huntc3021132010-05-05 15:23:54 +0000273
Anders Carlsson966146e2010-01-30 23:19:41 +0000274 C.Deallocate(this->Names);
275 this->Names = new (C) IdentifierInfo*[NumExprs];
276 std::copy(Names, Names + NumExprs, this->Names);
Sean Huntc3021132010-05-05 15:23:54 +0000277
Anders Carlsson966146e2010-01-30 23:19:41 +0000278 C.Deallocate(this->Exprs);
279 this->Exprs = new (C) Stmt*[NumExprs];
280 std::copy(Exprs, Exprs + NumExprs, this->Exprs);
Sean Huntc3021132010-05-05 15:23:54 +0000281
Anders Carlsson966146e2010-01-30 23:19:41 +0000282 C.Deallocate(this->Constraints);
283 this->Constraints = new (C) StringLiteral*[NumExprs];
284 std::copy(Constraints, Constraints + NumExprs, this->Constraints);
Sean Huntc3021132010-05-05 15:23:54 +0000285
Anders Carlsson966146e2010-01-30 23:19:41 +0000286 C.Deallocate(this->Clobbers);
287 this->Clobbers = new (C) StringLiteral*[NumClobbers];
288 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
Douglas Gregorcd7d5a92009-04-17 20:57:14 +0000289}
290
Chris Lattner10ca96a2009-03-10 06:33:24 +0000291/// getNamedOperand - Given a symbolic operand reference like %[foo],
292/// translate this into a numeric value needed to reference the same operand.
293/// This returns -1 if the operand name is invalid.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000294int AsmStmt::getNamedOperand(StringRef SymbolicName) const {
Chris Lattner10ca96a2009-03-10 06:33:24 +0000295 unsigned NumPlusOperands = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000296
Chris Lattner10ca96a2009-03-10 06:33:24 +0000297 // Check if this is an output operand.
298 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
299 if (getOutputName(i) == SymbolicName)
300 return i;
Chris Lattner10ca96a2009-03-10 06:33:24 +0000301 }
Mike Stump1eb44332009-09-09 15:08:12 +0000302
Chris Lattner10ca96a2009-03-10 06:33:24 +0000303 for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
304 if (getInputName(i) == SymbolicName)
305 return getNumOutputs() + NumPlusOperands + i;
306
307 // Not found.
308 return -1;
309}
310
Chris Lattner458cd9c2009-03-10 23:21:44 +0000311/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
312/// it into pieces. If the asm string is erroneous, emit errors and return
313/// true, otherwise return false.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000314unsigned AsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
Chris Lattnerfb5058e2009-03-10 23:41:04 +0000315 ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000316 StringRef Str = getAsmString()->getString();
Benjamin Kramer2f4eaef2010-08-17 12:54:38 +0000317 const char *StrStart = Str.begin();
318 const char *StrEnd = Str.end();
Chris Lattner3182db12009-03-10 23:51:40 +0000319 const char *CurPtr = StrStart;
Mike Stump1eb44332009-09-09 15:08:12 +0000320
Chris Lattner458cd9c2009-03-10 23:21:44 +0000321 // "Simple" inline asms have no constraints or operands, just convert the asm
322 // string to escape $'s.
323 if (isSimple()) {
324 std::string Result;
Chris Lattner3182db12009-03-10 23:51:40 +0000325 for (; CurPtr != StrEnd; ++CurPtr) {
326 switch (*CurPtr) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000327 case '$':
328 Result += "$$";
329 break;
330 default:
Chris Lattner3182db12009-03-10 23:51:40 +0000331 Result += *CurPtr;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000332 break;
333 }
334 }
335 Pieces.push_back(AsmStringPiece(Result));
Chris Lattner3182db12009-03-10 23:51:40 +0000336 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000337 }
338
339 // CurStringPiece - The current string that we are building up as we scan the
340 // asm string.
341 std::string CurStringPiece;
Mike Stump1eb44332009-09-09 15:08:12 +0000342
Douglas Gregorbcfd1f52011-09-02 00:18:52 +0000343 bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
Sean Huntc3021132010-05-05 15:23:54 +0000344
Chris Lattner458cd9c2009-03-10 23:21:44 +0000345 while (1) {
346 // Done with the string?
Chris Lattner3182db12009-03-10 23:51:40 +0000347 if (CurPtr == StrEnd) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000348 if (!CurStringPiece.empty())
349 Pieces.push_back(AsmStringPiece(CurStringPiece));
Chris Lattner3182db12009-03-10 23:51:40 +0000350 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000351 }
Mike Stump1eb44332009-09-09 15:08:12 +0000352
Chris Lattner3182db12009-03-10 23:51:40 +0000353 char CurChar = *CurPtr++;
Chris Lattner018b54e2010-04-05 18:44:00 +0000354 switch (CurChar) {
355 case '$': CurStringPiece += "$$"; continue;
Chris Lattner9bffb072010-04-23 16:29:58 +0000356 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
357 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
358 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
Chris Lattner018b54e2010-04-05 18:44:00 +0000359 case '%':
360 break;
361 default:
Chris Lattner458cd9c2009-03-10 23:21:44 +0000362 CurStringPiece += CurChar;
363 continue;
364 }
Sean Huntc3021132010-05-05 15:23:54 +0000365
Chris Lattner458cd9c2009-03-10 23:21:44 +0000366 // Escaped "%" character in asm string.
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000367 if (CurPtr == StrEnd) {
368 // % at end of string is invalid (no escape).
369 DiagOffs = CurPtr-StrStart-1;
370 return diag::err_asm_invalid_escape;
371 }
Mike Stump1eb44332009-09-09 15:08:12 +0000372
Chris Lattner3182db12009-03-10 23:51:40 +0000373 char EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000374 if (EscapedChar == '%') { // %% -> %
375 // Escaped percentage sign.
376 CurStringPiece += '%';
377 continue;
378 }
Mike Stump1eb44332009-09-09 15:08:12 +0000379
Chris Lattner458cd9c2009-03-10 23:21:44 +0000380 if (EscapedChar == '=') { // %= -> Generate an unique ID.
381 CurStringPiece += "${:uid}";
382 continue;
383 }
Mike Stump1eb44332009-09-09 15:08:12 +0000384
Chris Lattner458cd9c2009-03-10 23:21:44 +0000385 // Otherwise, we have an operand. If we have accumulated a string so far,
386 // add it to the Pieces list.
387 if (!CurStringPiece.empty()) {
388 Pieces.push_back(AsmStringPiece(CurStringPiece));
389 CurStringPiece.clear();
390 }
Mike Stump1eb44332009-09-09 15:08:12 +0000391
Chris Lattner458cd9c2009-03-10 23:21:44 +0000392 // Handle %x4 and %x[foo] by capturing x as the modifier character.
393 char Modifier = '\0';
394 if (isalpha(EscapedChar)) {
Benjamin Kramerbc57f3c2011-07-05 11:13:37 +0000395 if (CurPtr == StrEnd) { // Premature end.
396 DiagOffs = CurPtr-StrStart-1;
397 return diag::err_asm_invalid_escape;
398 }
Chris Lattner458cd9c2009-03-10 23:21:44 +0000399 Modifier = EscapedChar;
Chris Lattner3182db12009-03-10 23:51:40 +0000400 EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000401 }
Mike Stump1eb44332009-09-09 15:08:12 +0000402
Chris Lattner458cd9c2009-03-10 23:21:44 +0000403 if (isdigit(EscapedChar)) {
404 // %n - Assembler operand n
Chris Lattnercafc2222009-03-11 22:52:17 +0000405 unsigned N = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000406
Chris Lattnercafc2222009-03-11 22:52:17 +0000407 --CurPtr;
408 while (CurPtr != StrEnd && isdigit(*CurPtr))
Chris Lattner32a47ed2009-03-11 23:09:16 +0000409 N = N*10 + ((*CurPtr++)-'0');
Mike Stump1eb44332009-09-09 15:08:12 +0000410
Chris Lattner85759272009-03-11 00:23:13 +0000411 unsigned NumOperands =
412 getNumOutputs() + getNumPlusOperands() + getNumInputs();
413 if (N >= NumOperands) {
414 DiagOffs = CurPtr-StrStart-1;
415 return diag::err_asm_invalid_operand_number;
416 }
417
Chris Lattner458cd9c2009-03-10 23:21:44 +0000418 Pieces.push_back(AsmStringPiece(N, Modifier));
419 continue;
420 }
Mike Stump1eb44332009-09-09 15:08:12 +0000421
Chris Lattner458cd9c2009-03-10 23:21:44 +0000422 // Handle %[foo], a symbolic operand reference.
423 if (EscapedChar == '[') {
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000424 DiagOffs = CurPtr-StrStart-1;
Mike Stump1eb44332009-09-09 15:08:12 +0000425
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000426 // Find the ']'.
Chris Lattner3182db12009-03-10 23:51:40 +0000427 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000428 if (NameEnd == 0)
429 return diag::err_asm_unterminated_symbolic_operand_name;
430 if (NameEnd == CurPtr)
431 return diag::err_asm_empty_symbolic_operand_name;
Mike Stump1eb44332009-09-09 15:08:12 +0000432
Chris Lattner5f9e2722011-07-23 10:55:15 +0000433 StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
Mike Stump1eb44332009-09-09 15:08:12 +0000434
Chris Lattner458cd9c2009-03-10 23:21:44 +0000435 int N = getNamedOperand(SymbolicName);
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000436 if (N == -1) {
437 // Verify that an operand with that name exists.
438 DiagOffs = CurPtr-StrStart;
439 return diag::err_asm_unknown_symbolic_operand_name;
440 }
Chris Lattner458cd9c2009-03-10 23:21:44 +0000441 Pieces.push_back(AsmStringPiece(N, Modifier));
Mike Stump1eb44332009-09-09 15:08:12 +0000442
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000443 CurPtr = NameEnd+1;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000444 continue;
445 }
Mike Stump1eb44332009-09-09 15:08:12 +0000446
Chris Lattner2ff0f422009-03-10 23:57:07 +0000447 DiagOffs = CurPtr-StrStart-1;
Chris Lattner3182db12009-03-10 23:51:40 +0000448 return diag::err_asm_invalid_escape;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000449 }
450}
451
Sam Weinigb0e4cb62010-02-03 02:09:59 +0000452QualType CXXCatchStmt::getCaughtType() const {
453 if (ExceptionDecl)
454 return ExceptionDecl->getType();
455 return QualType();
456}
457
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000458//===----------------------------------------------------------------------===//
459// Constructors
460//===----------------------------------------------------------------------===//
461
Sean Huntc3021132010-05-05 15:23:54 +0000462AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
463 bool isvolatile, bool msasm,
Anders Carlsson966146e2010-01-30 23:19:41 +0000464 unsigned numoutputs, unsigned numinputs,
Anders Carlssonff93dbd2010-01-30 22:25:16 +0000465 IdentifierInfo **names, StringLiteral **constraints,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000466 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
467 StringLiteral **clobbers, SourceLocation rparenloc)
Anders Carlssonb235fc22007-11-22 01:36:19 +0000468 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
Mike Stump3b11fd32010-01-04 22:37:17 +0000469 , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
Anders Carlsson966146e2010-01-30 23:19:41 +0000470 , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
Nico Weber608b17f2008-08-05 23:15:29 +0000471
Anders Carlsson966146e2010-01-30 23:19:41 +0000472 unsigned NumExprs = NumOutputs +NumInputs;
Sean Huntc3021132010-05-05 15:23:54 +0000473
Anders Carlsson966146e2010-01-30 23:19:41 +0000474 Names = new (C) IdentifierInfo*[NumExprs];
475 std::copy(names, names + NumExprs, Names);
476
477 Exprs = new (C) Stmt*[NumExprs];
478 std::copy(exprs, exprs + NumExprs, Exprs);
479
480 Constraints = new (C) StringLiteral*[NumExprs];
481 std::copy(constraints, constraints + NumExprs, Constraints);
482
483 Clobbers = new (C) StringLiteral*[NumClobbers];
484 std::copy(clobbers, clobbers + NumClobbers, Clobbers);
Anders Carlssonb235fc22007-11-22 01:36:19 +0000485}
486
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000487ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
488 Stmt *Body, SourceLocation FCL,
Nico Weber608b17f2008-08-05 23:15:29 +0000489 SourceLocation RPL)
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000490: Stmt(ObjCForCollectionStmtClass) {
491 SubExprs[ELEM] = Elem;
492 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
493 SubExprs[BODY] = Body;
494 ForLoc = FCL;
495 RParenLoc = RPL;
496}
497
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000498ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
499 Stmt **CatchStmts, unsigned NumCatchStmts,
500 Stmt *atFinallyStmt)
501 : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
502 NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
503{
504 Stmt **Stmts = getStmts();
505 Stmts[0] = atTryStmt;
506 for (unsigned I = 0; I != NumCatchStmts; ++I)
507 Stmts[I + 1] = CatchStmts[I];
Sean Huntc3021132010-05-05 15:23:54 +0000508
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000509 if (HasFinally)
510 Stmts[NumCatchStmts + 1] = atFinallyStmt;
511}
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000512
Sean Huntc3021132010-05-05 15:23:54 +0000513ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context,
514 SourceLocation atTryLoc,
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000515 Stmt *atTryStmt,
Sean Huntc3021132010-05-05 15:23:54 +0000516 Stmt **CatchStmts,
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000517 unsigned NumCatchStmts,
518 Stmt *atFinallyStmt) {
Sean Huntc3021132010-05-05 15:23:54 +0000519 unsigned Size = sizeof(ObjCAtTryStmt) +
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000520 (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
Chris Lattner32488542010-10-30 05:14:06 +0000521 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000522 return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
523 atFinallyStmt);
524}
Ted Kremenekff981022008-02-01 21:28:59 +0000525
Sean Huntc3021132010-05-05 15:23:54 +0000526ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context,
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000527 unsigned NumCatchStmts,
528 bool HasFinally) {
Sean Huntc3021132010-05-05 15:23:54 +0000529 unsigned Size = sizeof(ObjCAtTryStmt) +
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000530 (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
Chris Lattner32488542010-10-30 05:14:06 +0000531 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
Sean Huntc3021132010-05-05 15:23:54 +0000532 return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000533}
Nico Weber608b17f2008-08-05 23:15:29 +0000534
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000535SourceRange ObjCAtTryStmt::getSourceRange() const {
536 SourceLocation EndLoc;
537 if (HasFinally)
538 EndLoc = getFinallyStmt()->getLocEnd();
539 else if (NumCatchStmts)
540 EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd();
541 else
542 EndLoc = getTryBody()->getLocEnd();
Sean Huntc3021132010-05-05 15:23:54 +0000543
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000544 return SourceRange(AtTryLoc, EndLoc);
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000545}
546
Sam Weiniga1a396d2010-02-03 03:56:39 +0000547CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
Sean Huntc3021132010-05-05 15:23:54 +0000548 Stmt *tryBlock, Stmt **handlers,
Sam Weiniga1a396d2010-02-03 03:56:39 +0000549 unsigned numHandlers) {
550 std::size_t Size = sizeof(CXXTryStmt);
551 Size += ((numHandlers + 1) * sizeof(Stmt));
552
Chris Lattner32488542010-10-30 05:14:06 +0000553 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
Sam Weiniga1a396d2010-02-03 03:56:39 +0000554 return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
555}
556
Argyrios Kyrtzidis7cb45e32010-07-22 16:03:56 +0000557CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
558 unsigned numHandlers) {
559 std::size_t Size = sizeof(CXXTryStmt);
560 Size += ((numHandlers + 1) * sizeof(Stmt));
561
Chris Lattner32488542010-10-30 05:14:06 +0000562 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
Argyrios Kyrtzidis7cb45e32010-07-22 16:03:56 +0000563 return new (Mem) CXXTryStmt(Empty, numHandlers);
564}
565
Sam Weiniga1a396d2010-02-03 03:56:39 +0000566CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
Sam Weinigb0e4cb62010-02-03 02:09:59 +0000567 Stmt **handlers, unsigned numHandlers)
568 : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
Sam Weiniga1a396d2010-02-03 03:56:39 +0000569 Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
Sam Weinigb0e4cb62010-02-03 02:09:59 +0000570 Stmts[0] = tryBlock;
571 std::copy(handlers, handlers + NumHandlers, Stmts + 1);
572}
573
Richard Smithad762fc2011-04-14 22:09:26 +0000574CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
575 Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
576 Stmt *Body, SourceLocation FL,
577 SourceLocation CL, SourceLocation RPL)
578 : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) {
579 SubExprs[RANGE] = Range;
580 SubExprs[BEGINEND] = BeginEndStmt;
581 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
582 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
583 SubExprs[LOOPVAR] = LoopVar;
584 SubExprs[BODY] = Body;
585}
586
587Expr *CXXForRangeStmt::getRangeInit() {
588 DeclStmt *RangeStmt = getRangeStmt();
589 VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
590 assert(RangeDecl &&& "for-range should have a single var decl");
591 return RangeDecl->getInit();
592}
593
594const Expr *CXXForRangeStmt::getRangeInit() const {
595 return const_cast<CXXForRangeStmt*>(this)->getRangeInit();
596}
597
598VarDecl *CXXForRangeStmt::getLoopVariable() {
599 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
600 assert(LV && "No loop variable in CXXForRangeStmt");
601 return cast<VarDecl>(LV);
602}
603
604const VarDecl *CXXForRangeStmt::getLoopVariable() const {
605 return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
606}
607
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000608IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
Argyrios Kyrtzidis44aa1f32010-11-20 02:04:01 +0000609 Stmt *then, SourceLocation EL, Stmt *elsev)
610 : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000611{
612 setConditionVariable(C, var);
613 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
614 SubExprs[THEN] = then;
615 SubExprs[ELSE] = elsev;
616}
617
618VarDecl *IfStmt::getConditionVariable() const {
619 if (!SubExprs[VAR])
620 return 0;
621
622 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
623 return cast<VarDecl>(DS->getSingleDecl());
624}
625
626void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
627 if (!V) {
628 SubExprs[VAR] = 0;
629 return;
630 }
631
632 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
633 V->getSourceRange().getBegin(),
634 V->getSourceRange().getEnd());
635}
636
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000637ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
638 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
639 SourceLocation RP)
640 : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
641{
642 SubExprs[INIT] = Init;
643 setConditionVariable(C, condVar);
644 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
645 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
646 SubExprs[BODY] = Body;
647}
648
649VarDecl *ForStmt::getConditionVariable() const {
650 if (!SubExprs[CONDVAR])
651 return 0;
652
653 DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
654 return cast<VarDecl>(DS->getSingleDecl());
655}
656
657void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
658 if (!V) {
659 SubExprs[CONDVAR] = 0;
660 return;
661 }
662
663 SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V),
664 V->getSourceRange().getBegin(),
665 V->getSourceRange().getEnd());
666}
667
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000668SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond)
Ted Kremenek780d8852010-09-09 00:06:01 +0000669 : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000670{
671 setConditionVariable(C, Var);
672 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
673 SubExprs[BODY] = NULL;
674}
675
676VarDecl *SwitchStmt::getConditionVariable() const {
677 if (!SubExprs[VAR])
678 return 0;
679
680 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
681 return cast<VarDecl>(DS->getSingleDecl());
682}
683
684void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
685 if (!V) {
686 SubExprs[VAR] = 0;
687 return;
688 }
689
690 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
691 V->getSourceRange().getBegin(),
692 V->getSourceRange().getEnd());
693}
694
John McCall63c00d72011-02-09 08:16:59 +0000695Stmt *SwitchCase::getSubStmt() {
Chris Lattnerc4002c72011-02-28 00:18:06 +0000696 if (isa<CaseStmt>(this))
697 return cast<CaseStmt>(this)->getSubStmt();
John McCall63c00d72011-02-09 08:16:59 +0000698 return cast<DefaultStmt>(this)->getSubStmt();
699}
700
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000701WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
702 SourceLocation WL)
Chris Lattnerc4002c72011-02-28 00:18:06 +0000703 : Stmt(WhileStmtClass) {
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000704 setConditionVariable(C, Var);
705 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
706 SubExprs[BODY] = body;
707 WhileLoc = WL;
708}
709
710VarDecl *WhileStmt::getConditionVariable() const {
711 if (!SubExprs[VAR])
712 return 0;
713
714 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
715 return cast<VarDecl>(DS->getSingleDecl());
716}
717
718void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
719 if (!V) {
720 SubExprs[VAR] = 0;
721 return;
722 }
723
724 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
725 V->getSourceRange().getBegin(),
726 V->getSourceRange().getEnd());
727}
728
Ted Kremenek82977772007-08-24 21:09:09 +0000729// IndirectGotoStmt
Chris Lattnerad8dcf42011-02-17 07:39:24 +0000730LabelDecl *IndirectGotoStmt::getConstantTarget() {
John McCall95c225d2010-10-28 08:53:48 +0000731 if (AddrLabelExpr *E =
732 dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
733 return E->getLabel();
734 return 0;
735}
Ted Kremenek82977772007-08-24 21:09:09 +0000736
Ted Kremenek82977772007-08-24 21:09:09 +0000737// ReturnStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000738const Expr* ReturnStmt::getRetValue() const {
739 return cast_or_null<Expr>(RetExpr);
740}
741Expr* ReturnStmt::getRetValue() {
742 return cast_or_null<Expr>(RetExpr);
Ted Kremenek82977772007-08-24 21:09:09 +0000743}
John Wiegley28bbe4b2011-04-28 01:08:34 +0000744
745SEHTryStmt::SEHTryStmt(bool IsCXXTry,
746 SourceLocation TryLoc,
747 Stmt *TryBlock,
748 Stmt *Handler)
749 : Stmt(SEHTryStmtClass),
750 IsCXXTry(IsCXXTry),
751 TryLoc(TryLoc)
752{
753 Children[TRY] = TryBlock;
754 Children[HANDLER] = Handler;
755}
756
757SEHTryStmt* SEHTryStmt::Create(ASTContext &C,
758 bool IsCXXTry,
759 SourceLocation TryLoc,
760 Stmt *TryBlock,
761 Stmt *Handler) {
762 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
763}
764
765SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
766 return dyn_cast<SEHExceptStmt>(getHandler());
767}
768
769SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
770 return dyn_cast<SEHFinallyStmt>(getHandler());
771}
772
773SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
774 Expr *FilterExpr,
775 Stmt *Block)
776 : Stmt(SEHExceptStmtClass),
777 Loc(Loc)
778{
779 Children[FILTER_EXPR] = reinterpret_cast<Stmt*>(FilterExpr);
780 Children[BLOCK] = Block;
781}
782
783SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C,
784 SourceLocation Loc,
785 Expr *FilterExpr,
786 Stmt *Block) {
787 return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
788}
789
790SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
791 Stmt *Block)
792 : Stmt(SEHFinallyStmtClass),
793 Loc(Loc),
794 Block(Block)
795{}
796
797SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C,
798 SourceLocation Loc,
799 Stmt *Block) {
800 return new(C)SEHFinallyStmt(Loc,Block);
801}