clang API Documentation

Stmt.cpp
Go to the documentation of this file.
00001 //===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the Stmt class and statement subclasses.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/AST/Stmt.h"
00015 #include "clang/AST/ExprCXX.h"
00016 #include "clang/AST/ExprObjC.h"
00017 #include "clang/AST/StmtCXX.h"
00018 #include "clang/AST/StmtObjC.h"
00019 #include "clang/AST/Type.h"
00020 #include "clang/AST/ASTContext.h"
00021 #include "clang/AST/ASTDiagnostic.h"
00022 #include "clang/Basic/TargetInfo.h"
00023 #include "llvm/Support/raw_ostream.h"
00024 using namespace clang;
00025 
00026 static struct StmtClassNameTable {
00027   const char *Name;
00028   unsigned Counter;
00029   unsigned Size;
00030 } StmtClassInfo[Stmt::lastStmtConstant+1];
00031 
00032 static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
00033   static bool Initialized = false;
00034   if (Initialized)
00035     return StmtClassInfo[E];
00036 
00037   // Intialize the table on the first use.
00038   Initialized = true;
00039 #define ABSTRACT_STMT(STMT)
00040 #define STMT(CLASS, PARENT) \
00041   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS;    \
00042   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
00043 #include "clang/AST/StmtNodes.inc"
00044 
00045   return StmtClassInfo[E];
00046 }
00047 
00048 const char *Stmt::getStmtClassName() const {
00049   return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
00050 }
00051 
00052 void Stmt::PrintStats() {
00053   // Ensure the table is primed.
00054   getStmtInfoTableEntry(Stmt::NullStmtClass);
00055 
00056   unsigned sum = 0;
00057   llvm::errs() << "\n*** Stmt/Expr Stats:\n";
00058   for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
00059     if (StmtClassInfo[i].Name == 0) continue;
00060     sum += StmtClassInfo[i].Counter;
00061   }
00062   llvm::errs() << "  " << sum << " stmts/exprs total.\n";
00063   sum = 0;
00064   for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
00065     if (StmtClassInfo[i].Name == 0) continue;
00066     if (StmtClassInfo[i].Counter == 0) continue;
00067     llvm::errs() << "    " << StmtClassInfo[i].Counter << " "
00068                  << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
00069                  << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size
00070                  << " bytes)\n";
00071     sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
00072   }
00073 
00074   llvm::errs() << "Total bytes = " << sum << "\n";
00075 }
00076 
00077 void Stmt::addStmtClass(StmtClass s) {
00078   ++getStmtInfoTableEntry(s).Counter;
00079 }
00080 
00081 bool Stmt::StatisticsEnabled = false;
00082 void Stmt::EnableStatistics() {
00083   StatisticsEnabled = true;
00084 }
00085 
00086 Stmt *Stmt::IgnoreImplicit() {
00087   Stmt *s = this;
00088 
00089   if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s))
00090     s = ewc->getSubExpr();
00091 
00092   while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s))
00093     s = ice->getSubExpr();
00094 
00095   return s;
00096 }
00097 
00098 /// \brief Strip off all label-like statements.
00099 ///
00100 /// This will strip off label statements, case statements, attributed
00101 /// statements and default statements recursively.
00102 const Stmt *Stmt::stripLabelLikeStatements() const {
00103   const Stmt *S = this;
00104   while (true) {
00105     if (const LabelStmt *LS = dyn_cast<LabelStmt>(S))
00106       S = LS->getSubStmt();
00107     else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S))
00108       S = SC->getSubStmt();
00109     else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S))
00110       S = AS->getSubStmt();
00111     else
00112       return S;
00113   }
00114 }
00115 
00116 namespace {
00117   struct good {};
00118   struct bad {};
00119 
00120   // These silly little functions have to be static inline to suppress
00121   // unused warnings, and they have to be defined to suppress other
00122   // warnings.
00123   static inline good is_good(good) { return good(); }
00124 
00125   typedef Stmt::child_range children_t();
00126   template <class T> good implements_children(children_t T::*) {
00127     return good();
00128   }
00129   static inline bad implements_children(children_t Stmt::*) {
00130     return bad();
00131   }
00132 
00133   typedef SourceRange getSourceRange_t() const;
00134   template <class T> good implements_getSourceRange(getSourceRange_t T::*) {
00135     return good();
00136   }
00137   static inline bad implements_getSourceRange(getSourceRange_t Stmt::*) {
00138     return bad();
00139   }
00140 
00141 #define ASSERT_IMPLEMENTS_children(type) \
00142   (void) sizeof(is_good(implements_children(&type::children)))
00143 #define ASSERT_IMPLEMENTS_getSourceRange(type) \
00144   (void) sizeof(is_good(implements_getSourceRange(&type::getSourceRange)))
00145 }
00146 
00147 /// Check whether the various Stmt classes implement their member
00148 /// functions.
00149 static inline void check_implementations() {
00150 #define ABSTRACT_STMT(type)
00151 #define STMT(type, base) \
00152   ASSERT_IMPLEMENTS_children(type); \
00153   ASSERT_IMPLEMENTS_getSourceRange(type);
00154 #include "clang/AST/StmtNodes.inc"
00155 }
00156 
00157 Stmt::child_range Stmt::children() {
00158   switch (getStmtClass()) {
00159   case Stmt::NoStmtClass: llvm_unreachable("statement without class");
00160 #define ABSTRACT_STMT(type)
00161 #define STMT(type, base) \
00162   case Stmt::type##Class: \
00163     return static_cast<type*>(this)->children();
00164 #include "clang/AST/StmtNodes.inc"
00165   }
00166   llvm_unreachable("unknown statement kind!");
00167 }
00168 
00169 SourceRange Stmt::getSourceRange() const {
00170   switch (getStmtClass()) {
00171   case Stmt::NoStmtClass: llvm_unreachable("statement without class");
00172 #define ABSTRACT_STMT(type)
00173 #define STMT(type, base) \
00174   case Stmt::type##Class: \
00175     return static_cast<const type*>(this)->getSourceRange();
00176 #include "clang/AST/StmtNodes.inc"
00177   }
00178   llvm_unreachable("unknown statement kind!");
00179 }
00180 
00181 // Amusing macro metaprogramming hack: check whether a class provides
00182 // a more specific implementation of getLocStart() and getLocEnd().
00183 //
00184 // See also Expr.cpp:getExprLoc().
00185 namespace {
00186   /// This implementation is used when a class provides a custom
00187   /// implementation of getLocStart.
00188   template <class S, class T>
00189   SourceLocation getLocStartImpl(const Stmt *stmt,
00190                                  SourceLocation (T::*v)() const) {
00191     return static_cast<const S*>(stmt)->getLocStart();
00192   }
00193 
00194   /// This implementation is used when a class doesn't provide a custom
00195   /// implementation of getLocStart.  Overload resolution should pick it over
00196   /// the implementation above because it's more specialized according to
00197   /// function template partial ordering.
00198   template <class S>
00199   SourceLocation getLocStartImpl(const Stmt *stmt,
00200                                 SourceLocation (Stmt::*v)() const) {
00201     return static_cast<const S*>(stmt)->getSourceRange().getBegin();
00202   }
00203 
00204   /// This implementation is used when a class provides a custom
00205   /// implementation of getLocEnd.
00206   template <class S, class T>
00207   SourceLocation getLocEndImpl(const Stmt *stmt,
00208                                SourceLocation (T::*v)() const) {
00209     return static_cast<const S*>(stmt)->getLocEnd();
00210   }
00211 
00212   /// This implementation is used when a class doesn't provide a custom
00213   /// implementation of getLocEnd.  Overload resolution should pick it over
00214   /// the implementation above because it's more specialized according to
00215   /// function template partial ordering.
00216   template <class S>
00217   SourceLocation getLocEndImpl(const Stmt *stmt,
00218                                SourceLocation (Stmt::*v)() const) {
00219     return static_cast<const S*>(stmt)->getSourceRange().getEnd();
00220   }
00221 }
00222 
00223 SourceLocation Stmt::getLocStart() const {
00224   switch (getStmtClass()) {
00225   case Stmt::NoStmtClass: llvm_unreachable("statement without class");
00226 #define ABSTRACT_STMT(type)
00227 #define STMT(type, base) \
00228   case Stmt::type##Class: \
00229     return getLocStartImpl<type>(this, &type::getLocStart);
00230 #include "clang/AST/StmtNodes.inc"
00231   }
00232   llvm_unreachable("unknown statement kind");
00233 }
00234 
00235 SourceLocation Stmt::getLocEnd() const {
00236   switch (getStmtClass()) {
00237   case Stmt::NoStmtClass: llvm_unreachable("statement without class");
00238 #define ABSTRACT_STMT(type)
00239 #define STMT(type, base) \
00240   case Stmt::type##Class: \
00241     return getLocEndImpl<type>(this, &type::getLocEnd);
00242 #include "clang/AST/StmtNodes.inc"
00243   }
00244   llvm_unreachable("unknown statement kind");
00245 }
00246 
00247 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
00248   if (this->Body)
00249     C.Deallocate(Body);
00250   this->CompoundStmtBits.NumStmts = NumStmts;
00251 
00252   Body = new (C) Stmt*[NumStmts];
00253   memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
00254 }
00255 
00256 const char *LabelStmt::getName() const {
00257   return getDecl()->getIdentifier()->getNameStart();
00258 }
00259 
00260 // This is defined here to avoid polluting Stmt.h with importing Expr.h
00261 SourceRange ReturnStmt::getSourceRange() const {
00262   if (RetExpr)
00263     return SourceRange(RetLoc, RetExpr->getLocEnd());
00264   else
00265     return SourceRange(RetLoc);
00266 }
00267 
00268 bool Stmt::hasImplicitControlFlow() const {
00269   switch (StmtBits.sClass) {
00270     default:
00271       return false;
00272 
00273     case CallExprClass:
00274     case ConditionalOperatorClass:
00275     case ChooseExprClass:
00276     case StmtExprClass:
00277     case DeclStmtClass:
00278       return true;
00279 
00280     case Stmt::BinaryOperatorClass: {
00281       const BinaryOperator* B = cast<BinaryOperator>(this);
00282       if (B->isLogicalOp() || B->getOpcode() == BO_Comma)
00283         return true;
00284       else
00285         return false;
00286     }
00287   }
00288 }
00289 
00290 Expr *AsmStmt::getOutputExpr(unsigned i) {
00291   return cast<Expr>(Exprs[i]);
00292 }
00293 
00294 /// getOutputConstraint - Return the constraint string for the specified
00295 /// output operand.  All output constraints are known to be non-empty (either
00296 /// '=' or '+').
00297 StringRef AsmStmt::getOutputConstraint(unsigned i) const {
00298   return getOutputConstraintLiteral(i)->getString();
00299 }
00300 
00301 /// getNumPlusOperands - Return the number of output operands that have a "+"
00302 /// constraint.
00303 unsigned AsmStmt::getNumPlusOperands() const {
00304   unsigned Res = 0;
00305   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
00306     if (isOutputPlusConstraint(i))
00307       ++Res;
00308   return Res;
00309 }
00310 
00311 Expr *AsmStmt::getInputExpr(unsigned i) {
00312   return cast<Expr>(Exprs[i + NumOutputs]);
00313 }
00314 void AsmStmt::setInputExpr(unsigned i, Expr *E) {
00315   Exprs[i + NumOutputs] = E;
00316 }
00317 
00318 
00319 /// getInputConstraint - Return the specified input constraint.  Unlike output
00320 /// constraints, these can be empty.
00321 StringRef AsmStmt::getInputConstraint(unsigned i) const {
00322   return getInputConstraintLiteral(i)->getString();
00323 }
00324 
00325 
00326 void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
00327                                              IdentifierInfo **Names,
00328                                              StringLiteral **Constraints,
00329                                              Stmt **Exprs,
00330                                              unsigned NumOutputs,
00331                                              unsigned NumInputs,                                      
00332                                              StringLiteral **Clobbers,
00333                                              unsigned NumClobbers) {
00334   this->NumOutputs = NumOutputs;
00335   this->NumInputs = NumInputs;
00336   this->NumClobbers = NumClobbers;
00337 
00338   unsigned NumExprs = NumOutputs + NumInputs;
00339   
00340   C.Deallocate(this->Names);
00341   this->Names = new (C) IdentifierInfo*[NumExprs];
00342   std::copy(Names, Names + NumExprs, this->Names);
00343   
00344   C.Deallocate(this->Exprs);
00345   this->Exprs = new (C) Stmt*[NumExprs];
00346   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
00347   
00348   C.Deallocate(this->Constraints);
00349   this->Constraints = new (C) StringLiteral*[NumExprs];
00350   std::copy(Constraints, Constraints + NumExprs, this->Constraints);
00351   
00352   C.Deallocate(this->Clobbers);
00353   this->Clobbers = new (C) StringLiteral*[NumClobbers];
00354   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
00355 }
00356 
00357 /// getNamedOperand - Given a symbolic operand reference like %[foo],
00358 /// translate this into a numeric value needed to reference the same operand.
00359 /// This returns -1 if the operand name is invalid.
00360 int AsmStmt::getNamedOperand(StringRef SymbolicName) const {
00361   unsigned NumPlusOperands = 0;
00362 
00363   // Check if this is an output operand.
00364   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
00365     if (getOutputName(i) == SymbolicName)
00366       return i;
00367   }
00368 
00369   for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
00370     if (getInputName(i) == SymbolicName)
00371       return getNumOutputs() + NumPlusOperands + i;
00372 
00373   // Not found.
00374   return -1;
00375 }
00376 
00377 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
00378 /// it into pieces.  If the asm string is erroneous, emit errors and return
00379 /// true, otherwise return false.
00380 unsigned AsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
00381                                    ASTContext &C, unsigned &DiagOffs) const {
00382   StringRef Str = getAsmString()->getString();
00383   const char *StrStart = Str.begin();
00384   const char *StrEnd = Str.end();
00385   const char *CurPtr = StrStart;
00386 
00387   // "Simple" inline asms have no constraints or operands, just convert the asm
00388   // string to escape $'s.
00389   if (isSimple()) {
00390     std::string Result;
00391     for (; CurPtr != StrEnd; ++CurPtr) {
00392       switch (*CurPtr) {
00393       case '$':
00394         Result += "$$";
00395         break;
00396       default:
00397         Result += *CurPtr;
00398         break;
00399       }
00400     }
00401     Pieces.push_back(AsmStringPiece(Result));
00402     return 0;
00403   }
00404 
00405   // CurStringPiece - The current string that we are building up as we scan the
00406   // asm string.
00407   std::string CurStringPiece;
00408 
00409   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
00410   
00411   while (1) {
00412     // Done with the string?
00413     if (CurPtr == StrEnd) {
00414       if (!CurStringPiece.empty())
00415         Pieces.push_back(AsmStringPiece(CurStringPiece));
00416       return 0;
00417     }
00418 
00419     char CurChar = *CurPtr++;
00420     switch (CurChar) {
00421     case '$': CurStringPiece += "$$"; continue;
00422     case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
00423     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
00424     case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
00425     case '%':
00426       break;
00427     default:
00428       CurStringPiece += CurChar;
00429       continue;
00430     }
00431     
00432     // Escaped "%" character in asm string.
00433     if (CurPtr == StrEnd) {
00434       // % at end of string is invalid (no escape).
00435       DiagOffs = CurPtr-StrStart-1;
00436       return diag::err_asm_invalid_escape;
00437     }
00438 
00439     char EscapedChar = *CurPtr++;
00440     if (EscapedChar == '%') {  // %% -> %
00441       // Escaped percentage sign.
00442       CurStringPiece += '%';
00443       continue;
00444     }
00445 
00446     if (EscapedChar == '=') {  // %= -> Generate an unique ID.
00447       CurStringPiece += "${:uid}";
00448       continue;
00449     }
00450 
00451     // Otherwise, we have an operand.  If we have accumulated a string so far,
00452     // add it to the Pieces list.
00453     if (!CurStringPiece.empty()) {
00454       Pieces.push_back(AsmStringPiece(CurStringPiece));
00455       CurStringPiece.clear();
00456     }
00457 
00458     // Handle %x4 and %x[foo] by capturing x as the modifier character.
00459     char Modifier = '\0';
00460     if (isalpha(EscapedChar)) {
00461       if (CurPtr == StrEnd) { // Premature end.
00462         DiagOffs = CurPtr-StrStart-1;
00463         return diag::err_asm_invalid_escape;
00464       }
00465       Modifier = EscapedChar;
00466       EscapedChar = *CurPtr++;
00467     }
00468 
00469     if (isdigit(EscapedChar)) {
00470       // %n - Assembler operand n
00471       unsigned N = 0;
00472 
00473       --CurPtr;
00474       while (CurPtr != StrEnd && isdigit(*CurPtr))
00475         N = N*10 + ((*CurPtr++)-'0');
00476 
00477       unsigned NumOperands =
00478         getNumOutputs() + getNumPlusOperands() + getNumInputs();
00479       if (N >= NumOperands) {
00480         DiagOffs = CurPtr-StrStart-1;
00481         return diag::err_asm_invalid_operand_number;
00482       }
00483 
00484       Pieces.push_back(AsmStringPiece(N, Modifier));
00485       continue;
00486     }
00487 
00488     // Handle %[foo], a symbolic operand reference.
00489     if (EscapedChar == '[') {
00490       DiagOffs = CurPtr-StrStart-1;
00491 
00492       // Find the ']'.
00493       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
00494       if (NameEnd == 0)
00495         return diag::err_asm_unterminated_symbolic_operand_name;
00496       if (NameEnd == CurPtr)
00497         return diag::err_asm_empty_symbolic_operand_name;
00498 
00499       StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
00500 
00501       int N = getNamedOperand(SymbolicName);
00502       if (N == -1) {
00503         // Verify that an operand with that name exists.
00504         DiagOffs = CurPtr-StrStart;
00505         return diag::err_asm_unknown_symbolic_operand_name;
00506       }
00507       Pieces.push_back(AsmStringPiece(N, Modifier));
00508 
00509       CurPtr = NameEnd+1;
00510       continue;
00511     }
00512 
00513     DiagOffs = CurPtr-StrStart-1;
00514     return diag::err_asm_invalid_escape;
00515   }
00516 }
00517 
00518 QualType CXXCatchStmt::getCaughtType() const {
00519   if (ExceptionDecl)
00520     return ExceptionDecl->getType();
00521   return QualType();
00522 }
00523 
00524 //===----------------------------------------------------------------------===//
00525 // Constructors
00526 //===----------------------------------------------------------------------===//
00527 
00528 AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 
00529                  bool isvolatile, bool msasm, 
00530                  unsigned numoutputs, unsigned numinputs,
00531                  IdentifierInfo **names, StringLiteral **constraints,
00532                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
00533                  StringLiteral **clobbers, SourceLocation rparenloc)
00534   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
00535   , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
00536   , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
00537 
00538   unsigned NumExprs = NumOutputs +NumInputs;
00539     
00540   Names = new (C) IdentifierInfo*[NumExprs];
00541   std::copy(names, names + NumExprs, Names);
00542 
00543   Exprs = new (C) Stmt*[NumExprs];
00544   std::copy(exprs, exprs + NumExprs, Exprs);
00545 
00546   Constraints = new (C) StringLiteral*[NumExprs];
00547   std::copy(constraints, constraints + NumExprs, Constraints);
00548 
00549   Clobbers = new (C) StringLiteral*[NumClobbers];
00550   std::copy(clobbers, clobbers + NumClobbers, Clobbers);
00551 }
00552 
00553 ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
00554                                              Stmt *Body,  SourceLocation FCL,
00555                                              SourceLocation RPL)
00556 : Stmt(ObjCForCollectionStmtClass) {
00557   SubExprs[ELEM] = Elem;
00558   SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
00559   SubExprs[BODY] = Body;
00560   ForLoc = FCL;
00561   RParenLoc = RPL;
00562 }
00563 
00564 ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
00565                              Stmt **CatchStmts, unsigned NumCatchStmts,
00566                              Stmt *atFinallyStmt)
00567   : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
00568     NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
00569 {
00570   Stmt **Stmts = getStmts();
00571   Stmts[0] = atTryStmt;
00572   for (unsigned I = 0; I != NumCatchStmts; ++I)
00573     Stmts[I + 1] = CatchStmts[I];
00574   
00575   if (HasFinally)
00576     Stmts[NumCatchStmts + 1] = atFinallyStmt;
00577 }
00578 
00579 ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, 
00580                                      SourceLocation atTryLoc, 
00581                                      Stmt *atTryStmt,
00582                                      Stmt **CatchStmts, 
00583                                      unsigned NumCatchStmts,
00584                                      Stmt *atFinallyStmt) {
00585   unsigned Size = sizeof(ObjCAtTryStmt) + 
00586     (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
00587   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
00588   return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
00589                                  atFinallyStmt);
00590 }
00591 
00592 ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, 
00593                                                  unsigned NumCatchStmts,
00594                                                  bool HasFinally) {
00595   unsigned Size = sizeof(ObjCAtTryStmt) + 
00596     (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
00597   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
00598   return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);  
00599 }
00600 
00601 SourceRange ObjCAtTryStmt::getSourceRange() const {
00602   SourceLocation EndLoc;
00603   if (HasFinally)
00604     EndLoc = getFinallyStmt()->getLocEnd();
00605   else if (NumCatchStmts)
00606     EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd();
00607   else
00608     EndLoc = getTryBody()->getLocEnd();
00609   
00610   return SourceRange(AtTryLoc, EndLoc);
00611 }
00612 
00613 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
00614                                Stmt *tryBlock, Stmt **handlers, 
00615                                unsigned numHandlers) {
00616   std::size_t Size = sizeof(CXXTryStmt);
00617   Size += ((numHandlers + 1) * sizeof(Stmt));
00618 
00619   void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
00620   return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
00621 }
00622 
00623 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
00624                                unsigned numHandlers) {
00625   std::size_t Size = sizeof(CXXTryStmt);
00626   Size += ((numHandlers + 1) * sizeof(Stmt));
00627 
00628   void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
00629   return new (Mem) CXXTryStmt(Empty, numHandlers);
00630 }
00631 
00632 CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
00633                        Stmt **handlers, unsigned numHandlers)
00634   : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
00635   Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
00636   Stmts[0] = tryBlock;
00637   std::copy(handlers, handlers + NumHandlers, Stmts + 1);
00638 }
00639 
00640 CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
00641                                  Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
00642                                  Stmt *Body, SourceLocation FL,
00643                                  SourceLocation CL, SourceLocation RPL)
00644   : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) {
00645   SubExprs[RANGE] = Range;
00646   SubExprs[BEGINEND] = BeginEndStmt;
00647   SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
00648   SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
00649   SubExprs[LOOPVAR] = LoopVar;
00650   SubExprs[BODY] = Body;
00651 }
00652 
00653 Expr *CXXForRangeStmt::getRangeInit() {
00654   DeclStmt *RangeStmt = getRangeStmt();
00655   VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
00656   assert(RangeDecl &&& "for-range should have a single var decl");
00657   return RangeDecl->getInit();
00658 }
00659 
00660 const Expr *CXXForRangeStmt::getRangeInit() const {
00661   return const_cast<CXXForRangeStmt*>(this)->getRangeInit();
00662 }
00663 
00664 VarDecl *CXXForRangeStmt::getLoopVariable() {
00665   Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
00666   assert(LV && "No loop variable in CXXForRangeStmt");
00667   return cast<VarDecl>(LV);
00668 }
00669 
00670 const VarDecl *CXXForRangeStmt::getLoopVariable() const {
00671   return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
00672 }
00673 
00674 IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 
00675                Stmt *then, SourceLocation EL, Stmt *elsev)
00676   : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
00677 {
00678   setConditionVariable(C, var);
00679   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
00680   SubExprs[THEN] = then;
00681   SubExprs[ELSE] = elsev;  
00682 }
00683 
00684 VarDecl *IfStmt::getConditionVariable() const {
00685   if (!SubExprs[VAR])
00686     return 0;
00687   
00688   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
00689   return cast<VarDecl>(DS->getSingleDecl());
00690 }
00691 
00692 void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
00693   if (!V) {
00694     SubExprs[VAR] = 0;
00695     return;
00696   }
00697   
00698   SourceRange VarRange = V->getSourceRange();
00699   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
00700                                    VarRange.getEnd());
00701 }
00702 
00703 ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, 
00704                  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, 
00705                  SourceLocation RP)
00706   : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP) 
00707 {
00708   SubExprs[INIT] = Init;
00709   setConditionVariable(C, condVar);
00710   SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
00711   SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
00712   SubExprs[BODY] = Body;
00713 }
00714 
00715 VarDecl *ForStmt::getConditionVariable() const {
00716   if (!SubExprs[CONDVAR])
00717     return 0;
00718   
00719   DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
00720   return cast<VarDecl>(DS->getSingleDecl());
00721 }
00722 
00723 void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
00724   if (!V) {
00725     SubExprs[CONDVAR] = 0;
00726     return;
00727   }
00728   
00729   SourceRange VarRange = V->getSourceRange();
00730   SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
00731                                        VarRange.getEnd());
00732 }
00733 
00734 SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond) 
00735   : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0) 
00736 {
00737   setConditionVariable(C, Var);
00738   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
00739   SubExprs[BODY] = NULL;
00740 }
00741 
00742 VarDecl *SwitchStmt::getConditionVariable() const {
00743   if (!SubExprs[VAR])
00744     return 0;
00745   
00746   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
00747   return cast<VarDecl>(DS->getSingleDecl());
00748 }
00749 
00750 void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
00751   if (!V) {
00752     SubExprs[VAR] = 0;
00753     return;
00754   }
00755   
00756   SourceRange VarRange = V->getSourceRange();
00757   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
00758                                    VarRange.getEnd());
00759 }
00760 
00761 Stmt *SwitchCase::getSubStmt() {
00762   if (isa<CaseStmt>(this))
00763     return cast<CaseStmt>(this)->getSubStmt();
00764   return cast<DefaultStmt>(this)->getSubStmt();
00765 }
00766 
00767 WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 
00768                      SourceLocation WL)
00769   : Stmt(WhileStmtClass) {
00770   setConditionVariable(C, Var);
00771   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
00772   SubExprs[BODY] = body;
00773   WhileLoc = WL;
00774 }
00775 
00776 VarDecl *WhileStmt::getConditionVariable() const {
00777   if (!SubExprs[VAR])
00778     return 0;
00779   
00780   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
00781   return cast<VarDecl>(DS->getSingleDecl());
00782 }
00783 
00784 void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
00785   if (!V) {
00786     SubExprs[VAR] = 0;
00787     return;
00788   }
00789 
00790   SourceRange VarRange = V->getSourceRange();
00791   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
00792                                    VarRange.getEnd());
00793 }
00794 
00795 // IndirectGotoStmt
00796 LabelDecl *IndirectGotoStmt::getConstantTarget() {
00797   if (AddrLabelExpr *E =
00798         dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
00799     return E->getLabel();
00800   return 0;
00801 }
00802 
00803 // ReturnStmt
00804 const Expr* ReturnStmt::getRetValue() const {
00805   return cast_or_null<Expr>(RetExpr);
00806 }
00807 Expr* ReturnStmt::getRetValue() {
00808   return cast_or_null<Expr>(RetExpr);
00809 }
00810 
00811 SEHTryStmt::SEHTryStmt(bool IsCXXTry,
00812                        SourceLocation TryLoc,
00813                        Stmt *TryBlock,
00814                        Stmt *Handler)
00815   : Stmt(SEHTryStmtClass),
00816     IsCXXTry(IsCXXTry),
00817     TryLoc(TryLoc)
00818 {
00819   Children[TRY]     = TryBlock;
00820   Children[HANDLER] = Handler;
00821 }
00822 
00823 SEHTryStmt* SEHTryStmt::Create(ASTContext &C,
00824                                bool IsCXXTry,
00825                                SourceLocation TryLoc,
00826                                Stmt *TryBlock,
00827                                Stmt *Handler) {
00828   return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
00829 }
00830 
00831 SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
00832   return dyn_cast<SEHExceptStmt>(getHandler());
00833 }
00834 
00835 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
00836   return dyn_cast<SEHFinallyStmt>(getHandler());
00837 }
00838 
00839 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
00840                              Expr *FilterExpr,
00841                              Stmt *Block)
00842   : Stmt(SEHExceptStmtClass),
00843     Loc(Loc)
00844 {
00845   Children[FILTER_EXPR] = reinterpret_cast<Stmt*>(FilterExpr);
00846   Children[BLOCK]       = Block;
00847 }
00848 
00849 SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C,
00850                                      SourceLocation Loc,
00851                                      Expr *FilterExpr,
00852                                      Stmt *Block) {
00853   return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
00854 }
00855 
00856 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
00857                                Stmt *Block)
00858   : Stmt(SEHFinallyStmtClass),
00859     Loc(Loc),
00860     Block(Block)
00861 {}
00862 
00863 SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C,
00864                                        SourceLocation Loc,
00865                                        Stmt *Block) {
00866   return new(C)SEHFinallyStmt(Loc,Block);
00867 }