blob: 6e4d52bf47207a82dbc9e41d77e8fc91c07a2753 [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
John McCall63c00d72011-02-09 08:16:59 +0000100namespace {
101 struct good {};
102 struct bad {};
John McCallf8c7fdb2011-02-09 08:31:17 +0000103
104 // These silly little functions have to be static inline to suppress
105 // unused warnings, and they have to be defined to suppress other
106 // warnings.
Nick Lewycky086eb9f2011-02-09 08:42:57 +0000107 static inline good is_good(good) { return good(); }
John McCall63c00d72011-02-09 08:16:59 +0000108
109 typedef Stmt::child_range children_t();
Nick Lewycky086eb9f2011-02-09 08:42:57 +0000110 template <class T> good implements_children(children_t T::*) {
111 return good();
112 }
113 static inline bad implements_children(children_t Stmt::*) {
114 return bad();
115 }
John McCall63c00d72011-02-09 08:16:59 +0000116
117 typedef SourceRange getSourceRange_t() const;
Nick Lewycky086eb9f2011-02-09 08:42:57 +0000118 template <class T> good implements_getSourceRange(getSourceRange_t T::*) {
119 return good();
120 }
121 static inline bad implements_getSourceRange(getSourceRange_t Stmt::*) {
122 return bad();
123 }
John McCall63c00d72011-02-09 08:16:59 +0000124
125#define ASSERT_IMPLEMENTS_children(type) \
126 (void) sizeof(is_good(implements_children(&type::children)))
127#define ASSERT_IMPLEMENTS_getSourceRange(type) \
128 (void) sizeof(is_good(implements_getSourceRange(&type::getSourceRange)))
129}
130
131/// Check whether the various Stmt classes implement their member
132/// functions.
133static inline void check_implementations() {
134#define ABSTRACT_STMT(type)
135#define STMT(type, base) \
136 ASSERT_IMPLEMENTS_children(type); \
137 ASSERT_IMPLEMENTS_getSourceRange(type);
138#include "clang/AST/StmtNodes.inc"
139}
140
141Stmt::child_range Stmt::children() {
142 switch (getStmtClass()) {
143 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
144#define ABSTRACT_STMT(type)
145#define STMT(type, base) \
146 case Stmt::type##Class: \
147 return static_cast<type*>(this)->children();
148#include "clang/AST/StmtNodes.inc"
149 }
150 llvm_unreachable("unknown statement kind!");
151 return child_range();
152}
153
154SourceRange Stmt::getSourceRange() const {
155 switch (getStmtClass()) {
156 case Stmt::NoStmtClass: llvm_unreachable("statement without class");
157#define ABSTRACT_STMT(type)
158#define STMT(type, base) \
159 case Stmt::type##Class: \
160 return static_cast<const type*>(this)->getSourceRange();
161#include "clang/AST/StmtNodes.inc"
162 }
163 llvm_unreachable("unknown statement kind!");
164 return SourceRange();
165}
166
Douglas Gregor025452f2009-04-17 00:04:06 +0000167void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
168 if (this->Body)
169 C.Deallocate(Body);
John McCall8e6285a2010-10-26 08:39:16 +0000170 this->CompoundStmtBits.NumStmts = NumStmts;
Douglas Gregor025452f2009-04-17 00:04:06 +0000171
172 Body = new (C) Stmt*[NumStmts];
173 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
174}
Reid Spencer5f016e22007-07-11 17:01:13 +0000175
Reid Spencer5f016e22007-07-11 17:01:13 +0000176const char *LabelStmt::getName() const {
Chris Lattnerad8dcf42011-02-17 07:39:24 +0000177 return getDecl()->getIdentifier()->getNameStart();
Reid Spencer5f016e22007-07-11 17:01:13 +0000178}
179
Steve Naroff507f2d52007-08-31 23:49:30 +0000180// This is defined here to avoid polluting Stmt.h with importing Expr.h
Nico Weber608b17f2008-08-05 23:15:29 +0000181SourceRange ReturnStmt::getSourceRange() const {
Steve Naroff507f2d52007-08-31 23:49:30 +0000182 if (RetExpr)
183 return SourceRange(RetLoc, RetExpr->getLocEnd());
184 else
185 return SourceRange(RetLoc);
186}
187
Ted Kremenekd48ade62007-10-01 16:34:52 +0000188bool Stmt::hasImplicitControlFlow() const {
John McCall8e6285a2010-10-26 08:39:16 +0000189 switch (StmtBits.sClass) {
Ted Kremenekd48ade62007-10-01 16:34:52 +0000190 default:
191 return false;
Nico Weber608b17f2008-08-05 23:15:29 +0000192
Ted Kremenekd48ade62007-10-01 16:34:52 +0000193 case CallExprClass:
194 case ConditionalOperatorClass:
195 case ChooseExprClass:
196 case StmtExprClass:
197 case DeclStmtClass:
Nico Weber608b17f2008-08-05 23:15:29 +0000198 return true;
199
Ted Kremenekd48ade62007-10-01 16:34:52 +0000200 case Stmt::BinaryOperatorClass: {
201 const BinaryOperator* B = cast<BinaryOperator>(this);
John McCall2de56d12010-08-25 11:45:40 +0000202 if (B->isLogicalOp() || B->getOpcode() == BO_Comma)
Ted Kremenekd48ade62007-10-01 16:34:52 +0000203 return true;
204 else
205 return false;
206 }
207 }
208}
209
Chris Lattnerb3277932009-03-10 04:59:06 +0000210Expr *AsmStmt::getOutputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000211 return cast<Expr>(Exprs[i]);
212}
Chris Lattnerb3277932009-03-10 04:59:06 +0000213
214/// getOutputConstraint - Return the constraint string for the specified
215/// output operand. All output constraints are known to be non-empty (either
216/// '=' or '+').
Chris Lattner5f9e2722011-07-23 10:55:15 +0000217StringRef AsmStmt::getOutputConstraint(unsigned i) const {
Anders Carlssonacb6bcb2010-01-30 20:38:10 +0000218 return getOutputConstraintLiteral(i)->getString();
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000219}
Chris Lattnerb3277932009-03-10 04:59:06 +0000220
Chris Lattner85759272009-03-11 00:23:13 +0000221/// getNumPlusOperands - Return the number of output operands that have a "+"
222/// constraint.
223unsigned AsmStmt::getNumPlusOperands() const {
224 unsigned Res = 0;
225 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
226 if (isOutputPlusConstraint(i))
227 ++Res;
228 return Res;
229}
230
Chris Lattnerb3277932009-03-10 04:59:06 +0000231Expr *AsmStmt::getInputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000232 return cast<Expr>(Exprs[i + NumOutputs]);
233}
Chris Lattner935f0f02011-02-21 22:09:29 +0000234void AsmStmt::setInputExpr(unsigned i, Expr *E) {
235 Exprs[i + NumOutputs] = E;
236}
237
Chris Lattnerb3277932009-03-10 04:59:06 +0000238
239/// getInputConstraint - Return the specified input constraint. Unlike output
240/// constraints, these can be empty.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000241StringRef AsmStmt::getInputConstraint(unsigned i) const {
Anders Carlssonacb6bcb2010-01-30 20:38:10 +0000242 return getInputConstraintLiteral(i)->getString();
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000243}
244
Chris Lattner10ca96a2009-03-10 06:33:24 +0000245
Anders Carlssonacb6bcb2010-01-30 20:38:10 +0000246void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
Anders Carlssonff93dbd2010-01-30 22:25:16 +0000247 IdentifierInfo **Names,
Anders Carlssonfdba9c02010-01-30 19:34:25 +0000248 StringLiteral **Constraints,
249 Stmt **Exprs,
250 unsigned NumOutputs,
Sean Huntc3021132010-05-05 15:23:54 +0000251 unsigned NumInputs,
Anders Carlssonfdba9c02010-01-30 19:34:25 +0000252 StringLiteral **Clobbers,
253 unsigned NumClobbers) {
Douglas Gregorcd7d5a92009-04-17 20:57:14 +0000254 this->NumOutputs = NumOutputs;
255 this->NumInputs = NumInputs;
Anders Carlsson966146e2010-01-30 23:19:41 +0000256 this->NumClobbers = NumClobbers;
257
258 unsigned NumExprs = NumOutputs + NumInputs;
Sean Huntc3021132010-05-05 15:23:54 +0000259
Anders Carlsson966146e2010-01-30 23:19:41 +0000260 C.Deallocate(this->Names);
261 this->Names = new (C) IdentifierInfo*[NumExprs];
262 std::copy(Names, Names + NumExprs, this->Names);
Sean Huntc3021132010-05-05 15:23:54 +0000263
Anders Carlsson966146e2010-01-30 23:19:41 +0000264 C.Deallocate(this->Exprs);
265 this->Exprs = new (C) Stmt*[NumExprs];
266 std::copy(Exprs, Exprs + NumExprs, this->Exprs);
Sean Huntc3021132010-05-05 15:23:54 +0000267
Anders Carlsson966146e2010-01-30 23:19:41 +0000268 C.Deallocate(this->Constraints);
269 this->Constraints = new (C) StringLiteral*[NumExprs];
270 std::copy(Constraints, Constraints + NumExprs, this->Constraints);
Sean Huntc3021132010-05-05 15:23:54 +0000271
Anders Carlsson966146e2010-01-30 23:19:41 +0000272 C.Deallocate(this->Clobbers);
273 this->Clobbers = new (C) StringLiteral*[NumClobbers];
274 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
Douglas Gregorcd7d5a92009-04-17 20:57:14 +0000275}
276
Chris Lattner10ca96a2009-03-10 06:33:24 +0000277/// getNamedOperand - Given a symbolic operand reference like %[foo],
278/// translate this into a numeric value needed to reference the same operand.
279/// This returns -1 if the operand name is invalid.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000280int AsmStmt::getNamedOperand(StringRef SymbolicName) const {
Chris Lattner10ca96a2009-03-10 06:33:24 +0000281 unsigned NumPlusOperands = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000282
Chris Lattner10ca96a2009-03-10 06:33:24 +0000283 // Check if this is an output operand.
284 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
285 if (getOutputName(i) == SymbolicName)
286 return i;
Chris Lattner10ca96a2009-03-10 06:33:24 +0000287 }
Mike Stump1eb44332009-09-09 15:08:12 +0000288
Chris Lattner10ca96a2009-03-10 06:33:24 +0000289 for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
290 if (getInputName(i) == SymbolicName)
291 return getNumOutputs() + NumPlusOperands + i;
292
293 // Not found.
294 return -1;
295}
296
Chris Lattner458cd9c2009-03-10 23:21:44 +0000297/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
298/// it into pieces. If the asm string is erroneous, emit errors and return
299/// true, otherwise return false.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000300unsigned AsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
Chris Lattnerfb5058e2009-03-10 23:41:04 +0000301 ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000302 StringRef Str = getAsmString()->getString();
Benjamin Kramer2f4eaef2010-08-17 12:54:38 +0000303 const char *StrStart = Str.begin();
304 const char *StrEnd = Str.end();
Chris Lattner3182db12009-03-10 23:51:40 +0000305 const char *CurPtr = StrStart;
Mike Stump1eb44332009-09-09 15:08:12 +0000306
Chris Lattner458cd9c2009-03-10 23:21:44 +0000307 // "Simple" inline asms have no constraints or operands, just convert the asm
308 // string to escape $'s.
309 if (isSimple()) {
310 std::string Result;
Chris Lattner3182db12009-03-10 23:51:40 +0000311 for (; CurPtr != StrEnd; ++CurPtr) {
312 switch (*CurPtr) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000313 case '$':
314 Result += "$$";
315 break;
316 default:
Chris Lattner3182db12009-03-10 23:51:40 +0000317 Result += *CurPtr;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000318 break;
319 }
320 }
321 Pieces.push_back(AsmStringPiece(Result));
Chris Lattner3182db12009-03-10 23:51:40 +0000322 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000323 }
324
325 // CurStringPiece - The current string that we are building up as we scan the
326 // asm string.
327 std::string CurStringPiece;
Mike Stump1eb44332009-09-09 15:08:12 +0000328
Chris Lattner9bffb072010-04-23 16:29:58 +0000329 bool HasVariants = !C.Target.hasNoAsmVariants();
Sean Huntc3021132010-05-05 15:23:54 +0000330
Chris Lattner458cd9c2009-03-10 23:21:44 +0000331 while (1) {
332 // Done with the string?
Chris Lattner3182db12009-03-10 23:51:40 +0000333 if (CurPtr == StrEnd) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000334 if (!CurStringPiece.empty())
335 Pieces.push_back(AsmStringPiece(CurStringPiece));
Chris Lattner3182db12009-03-10 23:51:40 +0000336 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000337 }
Mike Stump1eb44332009-09-09 15:08:12 +0000338
Chris Lattner3182db12009-03-10 23:51:40 +0000339 char CurChar = *CurPtr++;
Chris Lattner018b54e2010-04-05 18:44:00 +0000340 switch (CurChar) {
341 case '$': CurStringPiece += "$$"; continue;
Chris Lattner9bffb072010-04-23 16:29:58 +0000342 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
343 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
344 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
Chris Lattner018b54e2010-04-05 18:44:00 +0000345 case '%':
346 break;
347 default:
Chris Lattner458cd9c2009-03-10 23:21:44 +0000348 CurStringPiece += CurChar;
349 continue;
350 }
Sean Huntc3021132010-05-05 15:23:54 +0000351
Chris Lattner458cd9c2009-03-10 23:21:44 +0000352 // Escaped "%" character in asm string.
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000353 if (CurPtr == StrEnd) {
354 // % at end of string is invalid (no escape).
355 DiagOffs = CurPtr-StrStart-1;
356 return diag::err_asm_invalid_escape;
357 }
Mike Stump1eb44332009-09-09 15:08:12 +0000358
Chris Lattner3182db12009-03-10 23:51:40 +0000359 char EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000360 if (EscapedChar == '%') { // %% -> %
361 // Escaped percentage sign.
362 CurStringPiece += '%';
363 continue;
364 }
Mike Stump1eb44332009-09-09 15:08:12 +0000365
Chris Lattner458cd9c2009-03-10 23:21:44 +0000366 if (EscapedChar == '=') { // %= -> Generate an unique ID.
367 CurStringPiece += "${:uid}";
368 continue;
369 }
Mike Stump1eb44332009-09-09 15:08:12 +0000370
Chris Lattner458cd9c2009-03-10 23:21:44 +0000371 // Otherwise, we have an operand. If we have accumulated a string so far,
372 // add it to the Pieces list.
373 if (!CurStringPiece.empty()) {
374 Pieces.push_back(AsmStringPiece(CurStringPiece));
375 CurStringPiece.clear();
376 }
Mike Stump1eb44332009-09-09 15:08:12 +0000377
Chris Lattner458cd9c2009-03-10 23:21:44 +0000378 // Handle %x4 and %x[foo] by capturing x as the modifier character.
379 char Modifier = '\0';
380 if (isalpha(EscapedChar)) {
Benjamin Kramerbc57f3c2011-07-05 11:13:37 +0000381 if (CurPtr == StrEnd) { // Premature end.
382 DiagOffs = CurPtr-StrStart-1;
383 return diag::err_asm_invalid_escape;
384 }
Chris Lattner458cd9c2009-03-10 23:21:44 +0000385 Modifier = EscapedChar;
Chris Lattner3182db12009-03-10 23:51:40 +0000386 EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000387 }
Mike Stump1eb44332009-09-09 15:08:12 +0000388
Chris Lattner458cd9c2009-03-10 23:21:44 +0000389 if (isdigit(EscapedChar)) {
390 // %n - Assembler operand n
Chris Lattnercafc2222009-03-11 22:52:17 +0000391 unsigned N = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000392
Chris Lattnercafc2222009-03-11 22:52:17 +0000393 --CurPtr;
394 while (CurPtr != StrEnd && isdigit(*CurPtr))
Chris Lattner32a47ed2009-03-11 23:09:16 +0000395 N = N*10 + ((*CurPtr++)-'0');
Mike Stump1eb44332009-09-09 15:08:12 +0000396
Chris Lattner85759272009-03-11 00:23:13 +0000397 unsigned NumOperands =
398 getNumOutputs() + getNumPlusOperands() + getNumInputs();
399 if (N >= NumOperands) {
400 DiagOffs = CurPtr-StrStart-1;
401 return diag::err_asm_invalid_operand_number;
402 }
403
Chris Lattner458cd9c2009-03-10 23:21:44 +0000404 Pieces.push_back(AsmStringPiece(N, Modifier));
405 continue;
406 }
Mike Stump1eb44332009-09-09 15:08:12 +0000407
Chris Lattner458cd9c2009-03-10 23:21:44 +0000408 // Handle %[foo], a symbolic operand reference.
409 if (EscapedChar == '[') {
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000410 DiagOffs = CurPtr-StrStart-1;
Mike Stump1eb44332009-09-09 15:08:12 +0000411
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000412 // Find the ']'.
Chris Lattner3182db12009-03-10 23:51:40 +0000413 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000414 if (NameEnd == 0)
415 return diag::err_asm_unterminated_symbolic_operand_name;
416 if (NameEnd == CurPtr)
417 return diag::err_asm_empty_symbolic_operand_name;
Mike Stump1eb44332009-09-09 15:08:12 +0000418
Chris Lattner5f9e2722011-07-23 10:55:15 +0000419 StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
Mike Stump1eb44332009-09-09 15:08:12 +0000420
Chris Lattner458cd9c2009-03-10 23:21:44 +0000421 int N = getNamedOperand(SymbolicName);
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000422 if (N == -1) {
423 // Verify that an operand with that name exists.
424 DiagOffs = CurPtr-StrStart;
425 return diag::err_asm_unknown_symbolic_operand_name;
426 }
Chris Lattner458cd9c2009-03-10 23:21:44 +0000427 Pieces.push_back(AsmStringPiece(N, Modifier));
Mike Stump1eb44332009-09-09 15:08:12 +0000428
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000429 CurPtr = NameEnd+1;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000430 continue;
431 }
Mike Stump1eb44332009-09-09 15:08:12 +0000432
Chris Lattner2ff0f422009-03-10 23:57:07 +0000433 DiagOffs = CurPtr-StrStart-1;
Chris Lattner3182db12009-03-10 23:51:40 +0000434 return diag::err_asm_invalid_escape;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000435 }
436}
437
Sam Weinigb0e4cb62010-02-03 02:09:59 +0000438QualType CXXCatchStmt::getCaughtType() const {
439 if (ExceptionDecl)
440 return ExceptionDecl->getType();
441 return QualType();
442}
443
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000444//===----------------------------------------------------------------------===//
445// Constructors
446//===----------------------------------------------------------------------===//
447
Sean Huntc3021132010-05-05 15:23:54 +0000448AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
449 bool isvolatile, bool msasm,
Anders Carlsson966146e2010-01-30 23:19:41 +0000450 unsigned numoutputs, unsigned numinputs,
Anders Carlssonff93dbd2010-01-30 22:25:16 +0000451 IdentifierInfo **names, StringLiteral **constraints,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000452 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
453 StringLiteral **clobbers, SourceLocation rparenloc)
Anders Carlssonb235fc22007-11-22 01:36:19 +0000454 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
Mike Stump3b11fd32010-01-04 22:37:17 +0000455 , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
Anders Carlsson966146e2010-01-30 23:19:41 +0000456 , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
Nico Weber608b17f2008-08-05 23:15:29 +0000457
Anders Carlsson966146e2010-01-30 23:19:41 +0000458 unsigned NumExprs = NumOutputs +NumInputs;
Sean Huntc3021132010-05-05 15:23:54 +0000459
Anders Carlsson966146e2010-01-30 23:19:41 +0000460 Names = new (C) IdentifierInfo*[NumExprs];
461 std::copy(names, names + NumExprs, Names);
462
463 Exprs = new (C) Stmt*[NumExprs];
464 std::copy(exprs, exprs + NumExprs, Exprs);
465
466 Constraints = new (C) StringLiteral*[NumExprs];
467 std::copy(constraints, constraints + NumExprs, Constraints);
468
469 Clobbers = new (C) StringLiteral*[NumClobbers];
470 std::copy(clobbers, clobbers + NumClobbers, Clobbers);
Anders Carlssonb235fc22007-11-22 01:36:19 +0000471}
472
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000473ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
474 Stmt *Body, SourceLocation FCL,
Nico Weber608b17f2008-08-05 23:15:29 +0000475 SourceLocation RPL)
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000476: Stmt(ObjCForCollectionStmtClass) {
477 SubExprs[ELEM] = Elem;
478 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
479 SubExprs[BODY] = Body;
480 ForLoc = FCL;
481 RParenLoc = RPL;
482}
483
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000484ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
485 Stmt **CatchStmts, unsigned NumCatchStmts,
486 Stmt *atFinallyStmt)
487 : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
488 NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
489{
490 Stmt **Stmts = getStmts();
491 Stmts[0] = atTryStmt;
492 for (unsigned I = 0; I != NumCatchStmts; ++I)
493 Stmts[I + 1] = CatchStmts[I];
Sean Huntc3021132010-05-05 15:23:54 +0000494
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000495 if (HasFinally)
496 Stmts[NumCatchStmts + 1] = atFinallyStmt;
497}
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000498
Sean Huntc3021132010-05-05 15:23:54 +0000499ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context,
500 SourceLocation atTryLoc,
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000501 Stmt *atTryStmt,
Sean Huntc3021132010-05-05 15:23:54 +0000502 Stmt **CatchStmts,
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000503 unsigned NumCatchStmts,
504 Stmt *atFinallyStmt) {
Sean Huntc3021132010-05-05 15:23:54 +0000505 unsigned Size = sizeof(ObjCAtTryStmt) +
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000506 (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
Chris Lattner32488542010-10-30 05:14:06 +0000507 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000508 return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
509 atFinallyStmt);
510}
Ted Kremenekff981022008-02-01 21:28:59 +0000511
Sean Huntc3021132010-05-05 15:23:54 +0000512ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context,
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000513 unsigned NumCatchStmts,
514 bool HasFinally) {
Sean Huntc3021132010-05-05 15:23:54 +0000515 unsigned Size = sizeof(ObjCAtTryStmt) +
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000516 (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
Chris Lattner32488542010-10-30 05:14:06 +0000517 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
Sean Huntc3021132010-05-05 15:23:54 +0000518 return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000519}
Nico Weber608b17f2008-08-05 23:15:29 +0000520
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000521SourceRange ObjCAtTryStmt::getSourceRange() const {
522 SourceLocation EndLoc;
523 if (HasFinally)
524 EndLoc = getFinallyStmt()->getLocEnd();
525 else if (NumCatchStmts)
526 EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd();
527 else
528 EndLoc = getTryBody()->getLocEnd();
Sean Huntc3021132010-05-05 15:23:54 +0000529
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +0000530 return SourceRange(AtTryLoc, EndLoc);
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000531}
532
Sam Weiniga1a396d2010-02-03 03:56:39 +0000533CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
Sean Huntc3021132010-05-05 15:23:54 +0000534 Stmt *tryBlock, Stmt **handlers,
Sam Weiniga1a396d2010-02-03 03:56:39 +0000535 unsigned numHandlers) {
536 std::size_t Size = sizeof(CXXTryStmt);
537 Size += ((numHandlers + 1) * sizeof(Stmt));
538
Chris Lattner32488542010-10-30 05:14:06 +0000539 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
Sam Weiniga1a396d2010-02-03 03:56:39 +0000540 return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
541}
542
Argyrios Kyrtzidis7cb45e32010-07-22 16:03:56 +0000543CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
544 unsigned numHandlers) {
545 std::size_t Size = sizeof(CXXTryStmt);
546 Size += ((numHandlers + 1) * sizeof(Stmt));
547
Chris Lattner32488542010-10-30 05:14:06 +0000548 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
Argyrios Kyrtzidis7cb45e32010-07-22 16:03:56 +0000549 return new (Mem) CXXTryStmt(Empty, numHandlers);
550}
551
Sam Weiniga1a396d2010-02-03 03:56:39 +0000552CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
Sam Weinigb0e4cb62010-02-03 02:09:59 +0000553 Stmt **handlers, unsigned numHandlers)
554 : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
Sam Weiniga1a396d2010-02-03 03:56:39 +0000555 Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
Sam Weinigb0e4cb62010-02-03 02:09:59 +0000556 Stmts[0] = tryBlock;
557 std::copy(handlers, handlers + NumHandlers, Stmts + 1);
558}
559
Richard Smithad762fc2011-04-14 22:09:26 +0000560CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
561 Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
562 Stmt *Body, SourceLocation FL,
563 SourceLocation CL, SourceLocation RPL)
564 : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) {
565 SubExprs[RANGE] = Range;
566 SubExprs[BEGINEND] = BeginEndStmt;
567 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
568 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
569 SubExprs[LOOPVAR] = LoopVar;
570 SubExprs[BODY] = Body;
571}
572
573Expr *CXXForRangeStmt::getRangeInit() {
574 DeclStmt *RangeStmt = getRangeStmt();
575 VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
576 assert(RangeDecl &&& "for-range should have a single var decl");
577 return RangeDecl->getInit();
578}
579
580const Expr *CXXForRangeStmt::getRangeInit() const {
581 return const_cast<CXXForRangeStmt*>(this)->getRangeInit();
582}
583
584VarDecl *CXXForRangeStmt::getLoopVariable() {
585 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
586 assert(LV && "No loop variable in CXXForRangeStmt");
587 return cast<VarDecl>(LV);
588}
589
590const VarDecl *CXXForRangeStmt::getLoopVariable() const {
591 return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
592}
593
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000594IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
Argyrios Kyrtzidis44aa1f32010-11-20 02:04:01 +0000595 Stmt *then, SourceLocation EL, Stmt *elsev)
596 : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000597{
598 setConditionVariable(C, var);
599 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
600 SubExprs[THEN] = then;
601 SubExprs[ELSE] = elsev;
602}
603
604VarDecl *IfStmt::getConditionVariable() const {
605 if (!SubExprs[VAR])
606 return 0;
607
608 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
609 return cast<VarDecl>(DS->getSingleDecl());
610}
611
612void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
613 if (!V) {
614 SubExprs[VAR] = 0;
615 return;
616 }
617
618 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
619 V->getSourceRange().getBegin(),
620 V->getSourceRange().getEnd());
621}
622
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000623ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
624 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
625 SourceLocation RP)
626 : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
627{
628 SubExprs[INIT] = Init;
629 setConditionVariable(C, condVar);
630 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
631 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
632 SubExprs[BODY] = Body;
633}
634
635VarDecl *ForStmt::getConditionVariable() const {
636 if (!SubExprs[CONDVAR])
637 return 0;
638
639 DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
640 return cast<VarDecl>(DS->getSingleDecl());
641}
642
643void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
644 if (!V) {
645 SubExprs[CONDVAR] = 0;
646 return;
647 }
648
649 SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V),
650 V->getSourceRange().getBegin(),
651 V->getSourceRange().getEnd());
652}
653
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000654SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond)
Ted Kremenek780d8852010-09-09 00:06:01 +0000655 : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000656{
657 setConditionVariable(C, Var);
658 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
659 SubExprs[BODY] = NULL;
660}
661
662VarDecl *SwitchStmt::getConditionVariable() const {
663 if (!SubExprs[VAR])
664 return 0;
665
666 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
667 return cast<VarDecl>(DS->getSingleDecl());
668}
669
670void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
671 if (!V) {
672 SubExprs[VAR] = 0;
673 return;
674 }
675
676 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
677 V->getSourceRange().getBegin(),
678 V->getSourceRange().getEnd());
679}
680
John McCall63c00d72011-02-09 08:16:59 +0000681Stmt *SwitchCase::getSubStmt() {
Chris Lattnerc4002c72011-02-28 00:18:06 +0000682 if (isa<CaseStmt>(this))
683 return cast<CaseStmt>(this)->getSubStmt();
John McCall63c00d72011-02-09 08:16:59 +0000684 return cast<DefaultStmt>(this)->getSubStmt();
685}
686
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000687WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
688 SourceLocation WL)
Chris Lattnerc4002c72011-02-28 00:18:06 +0000689 : Stmt(WhileStmtClass) {
Douglas Gregor43dec6b2010-06-21 23:44:13 +0000690 setConditionVariable(C, Var);
691 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
692 SubExprs[BODY] = body;
693 WhileLoc = WL;
694}
695
696VarDecl *WhileStmt::getConditionVariable() const {
697 if (!SubExprs[VAR])
698 return 0;
699
700 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
701 return cast<VarDecl>(DS->getSingleDecl());
702}
703
704void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
705 if (!V) {
706 SubExprs[VAR] = 0;
707 return;
708 }
709
710 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
711 V->getSourceRange().getBegin(),
712 V->getSourceRange().getEnd());
713}
714
Ted Kremenek82977772007-08-24 21:09:09 +0000715// IndirectGotoStmt
Chris Lattnerad8dcf42011-02-17 07:39:24 +0000716LabelDecl *IndirectGotoStmt::getConstantTarget() {
John McCall95c225d2010-10-28 08:53:48 +0000717 if (AddrLabelExpr *E =
718 dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
719 return E->getLabel();
720 return 0;
721}
Ted Kremenek82977772007-08-24 21:09:09 +0000722
Ted Kremenek82977772007-08-24 21:09:09 +0000723// ReturnStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000724const Expr* ReturnStmt::getRetValue() const {
725 return cast_or_null<Expr>(RetExpr);
726}
727Expr* ReturnStmt::getRetValue() {
728 return cast_or_null<Expr>(RetExpr);
Ted Kremenek82977772007-08-24 21:09:09 +0000729}
John Wiegley28bbe4b2011-04-28 01:08:34 +0000730
731SEHTryStmt::SEHTryStmt(bool IsCXXTry,
732 SourceLocation TryLoc,
733 Stmt *TryBlock,
734 Stmt *Handler)
735 : Stmt(SEHTryStmtClass),
736 IsCXXTry(IsCXXTry),
737 TryLoc(TryLoc)
738{
739 Children[TRY] = TryBlock;
740 Children[HANDLER] = Handler;
741}
742
743SEHTryStmt* SEHTryStmt::Create(ASTContext &C,
744 bool IsCXXTry,
745 SourceLocation TryLoc,
746 Stmt *TryBlock,
747 Stmt *Handler) {
748 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
749}
750
751SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
752 return dyn_cast<SEHExceptStmt>(getHandler());
753}
754
755SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
756 return dyn_cast<SEHFinallyStmt>(getHandler());
757}
758
759SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
760 Expr *FilterExpr,
761 Stmt *Block)
762 : Stmt(SEHExceptStmtClass),
763 Loc(Loc)
764{
765 Children[FILTER_EXPR] = reinterpret_cast<Stmt*>(FilterExpr);
766 Children[BLOCK] = Block;
767}
768
769SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C,
770 SourceLocation Loc,
771 Expr *FilterExpr,
772 Stmt *Block) {
773 return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
774}
775
776SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
777 Stmt *Block)
778 : Stmt(SEHFinallyStmtClass),
779 Loc(Loc),
780 Block(Block)
781{}
782
783SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C,
784 SourceLocation Loc,
785 Stmt *Block) {
786 return new(C)SEHFinallyStmt(Loc,Block);
787}