Home | History | Annotate | Download | only in AST
      1 //===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the Stmt class and statement subclasses.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/AST/Stmt.h"
     15 #include "clang/AST/ExprCXX.h"
     16 #include "clang/AST/ExprObjC.h"
     17 #include "clang/AST/StmtCXX.h"
     18 #include "clang/AST/StmtObjC.h"
     19 #include "clang/AST/Type.h"
     20 #include "clang/AST/ASTContext.h"
     21 #include "clang/AST/ASTDiagnostic.h"
     22 #include "clang/Basic/TargetInfo.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 using namespace clang;
     25 
     26 static struct StmtClassNameTable {
     27   const char *Name;
     28   unsigned Counter;
     29   unsigned Size;
     30 } StmtClassInfo[Stmt::lastStmtConstant+1];
     31 
     32 static 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;
     39 #define ABSTRACT_STMT(STMT)
     40 #define STMT(CLASS, PARENT) \
     41   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS;    \
     42   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
     43 #include "clang/AST/StmtNodes.inc"
     44 
     45   return StmtClassInfo[E];
     46 }
     47 
     48 const char *Stmt::getStmtClassName() const {
     49   return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
     50 }
     51 
     52 void Stmt::PrintStats() {
     53   // Ensure the table is primed.
     54   getStmtInfoTableEntry(Stmt::NullStmtClass);
     55 
     56   unsigned sum = 0;
     57   llvm::errs() << "\n*** Stmt/Expr Stats:\n";
     58   for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
     59     if (StmtClassInfo[i].Name == 0) continue;
     60     sum += StmtClassInfo[i].Counter;
     61   }
     62   llvm::errs() << "  " << sum << " stmts/exprs total.\n";
     63   sum = 0;
     64   for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
     65     if (StmtClassInfo[i].Name == 0) continue;
     66     if (StmtClassInfo[i].Counter == 0) continue;
     67     llvm::errs() << "    " << StmtClassInfo[i].Counter << " "
     68                  << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
     69                  << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size
     70                  << " bytes)\n";
     71     sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
     72   }
     73 
     74   llvm::errs() << "Total bytes = " << sum << "\n";
     75 }
     76 
     77 void Stmt::addStmtClass(StmtClass s) {
     78   ++getStmtInfoTableEntry(s).Counter;
     79 }
     80 
     81 bool Stmt::StatisticsEnabled = false;
     82 void Stmt::EnableStatistics() {
     83   StatisticsEnabled = true;
     84 }
     85 
     86 Stmt *Stmt::IgnoreImplicit() {
     87   Stmt *s = this;
     88 
     89   if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s))
     90     s = ewc->getSubExpr();
     91 
     92   while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s))
     93     s = ice->getSubExpr();
     94 
     95   return s;
     96 }
     97 
     98 /// \brief Strip off all label-like statements.
     99 ///
    100 /// This will strip off label statements, case statements, attributed
    101 /// statements and default statements recursively.
    102 const Stmt *Stmt::stripLabelLikeStatements() const {
    103   const Stmt *S = this;
    104   while (true) {
    105     if (const LabelStmt *LS = dyn_cast<LabelStmt>(S))
    106       S = LS->getSubStmt();
    107     else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S))
    108       S = SC->getSubStmt();
    109     else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S))
    110       S = AS->getSubStmt();
    111     else
    112       return S;
    113   }
    114 }
    115 
    116 namespace {
    117   struct good {};
    118   struct bad {};
    119 
    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.
    123   static inline good is_good(good) { return good(); }
    124 
    125   typedef Stmt::child_range children_t();
    126   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   }
    132 
    133   typedef SourceRange getSourceRange_t() const;
    134   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   }
    140 
    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.
    149 static 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 
    157 Stmt::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!");
    167 }
    168 
    169 SourceRange 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!");
    179 }
    180 
    181 // Amusing macro metaprogramming hack: check whether a class provides
    182 // a more specific implementation of getLocStart() and getLocEnd().
    183 //
    184 // See also Expr.cpp:getExprLoc().
    185 namespace {
    186   /// This implementation is used when a class provides a custom
    187   /// implementation of getLocStart.
    188   template <class S, class T>
    189   SourceLocation getLocStartImpl(const Stmt *stmt,
    190                                  SourceLocation (T::*v)() const) {
    191     return static_cast<const S*>(stmt)->getLocStart();
    192   }
    193 
    194   /// This implementation is used when a class doesn't provide a custom
    195   /// implementation of getLocStart.  Overload resolution should pick it over
    196   /// the implementation above because it's more specialized according to
    197   /// function template partial ordering.
    198   template <class S>
    199   SourceLocation getLocStartImpl(const Stmt *stmt,
    200                                 SourceLocation (Stmt::*v)() const) {
    201     return static_cast<const S*>(stmt)->getSourceRange().getBegin();
    202   }
    203 
    204   /// This implementation is used when a class provides a custom
    205   /// implementation of getLocEnd.
    206   template <class S, class T>
    207   SourceLocation getLocEndImpl(const Stmt *stmt,
    208                                SourceLocation (T::*v)() const) {
    209     return static_cast<const S*>(stmt)->getLocEnd();
    210   }
    211 
    212   /// This implementation is used when a class doesn't provide a custom
    213   /// implementation of getLocEnd.  Overload resolution should pick it over
    214   /// the implementation above because it's more specialized according to
    215   /// function template partial ordering.
    216   template <class S>
    217   SourceLocation getLocEndImpl(const Stmt *stmt,
    218                                SourceLocation (Stmt::*v)() const) {
    219     return static_cast<const S*>(stmt)->getSourceRange().getEnd();
    220   }
    221 }
    222 
    223 SourceLocation Stmt::getLocStart() const {
    224   switch (getStmtClass()) {
    225   case Stmt::NoStmtClass: llvm_unreachable("statement without class");
    226 #define ABSTRACT_STMT(type)
    227 #define STMT(type, base) \
    228   case Stmt::type##Class: \
    229     return getLocStartImpl<type>(this, &type::getLocStart);
    230 #include "clang/AST/StmtNodes.inc"
    231   }
    232   llvm_unreachable("unknown statement kind");
    233 }
    234 
    235 SourceLocation Stmt::getLocEnd() const {
    236   switch (getStmtClass()) {
    237   case Stmt::NoStmtClass: llvm_unreachable("statement without class");
    238 #define ABSTRACT_STMT(type)
    239 #define STMT(type, base) \
    240   case Stmt::type##Class: \
    241     return getLocEndImpl<type>(this, &type::getLocEnd);
    242 #include "clang/AST/StmtNodes.inc"
    243   }
    244   llvm_unreachable("unknown statement kind");
    245 }
    246 
    247 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
    248   if (this->Body)
    249     C.Deallocate(Body);
    250   this->CompoundStmtBits.NumStmts = NumStmts;
    251 
    252   Body = new (C) Stmt*[NumStmts];
    253   memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
    254 }
    255 
    256 const char *LabelStmt::getName() const {
    257   return getDecl()->getIdentifier()->getNameStart();
    258 }
    259 
    260 // This is defined here to avoid polluting Stmt.h with importing Expr.h
    261 SourceRange ReturnStmt::getSourceRange() const {
    262   if (RetExpr)
    263     return SourceRange(RetLoc, RetExpr->getLocEnd());
    264   else
    265     return SourceRange(RetLoc);
    266 }
    267 
    268 bool Stmt::hasImplicitControlFlow() const {
    269   switch (StmtBits.sClass) {
    270     default:
    271       return false;
    272 
    273     case CallExprClass:
    274     case ConditionalOperatorClass:
    275     case ChooseExprClass:
    276     case StmtExprClass:
    277     case DeclStmtClass:
    278       return true;
    279 
    280     case Stmt::BinaryOperatorClass: {
    281       const BinaryOperator* B = cast<BinaryOperator>(this);
    282       if (B->isLogicalOp() || B->getOpcode() == BO_Comma)
    283         return true;
    284       else
    285         return false;
    286     }
    287   }
    288 }
    289 
    290 Expr *AsmStmt::getOutputExpr(unsigned i) {
    291   return cast<Expr>(Exprs[i]);
    292 }
    293 
    294 /// getOutputConstraint - Return the constraint string for the specified
    295 /// output operand.  All output constraints are known to be non-empty (either
    296 /// '=' or '+').
    297 StringRef AsmStmt::getOutputConstraint(unsigned i) const {
    298   return getOutputConstraintLiteral(i)->getString();
    299 }
    300 
    301 /// getNumPlusOperands - Return the number of output operands that have a "+"
    302 /// constraint.
    303 unsigned AsmStmt::getNumPlusOperands() const {
    304   unsigned Res = 0;
    305   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
    306     if (isOutputPlusConstraint(i))
    307       ++Res;
    308   return Res;
    309 }
    310 
    311 Expr *AsmStmt::getInputExpr(unsigned i) {
    312   return cast<Expr>(Exprs[i + NumOutputs]);
    313 }
    314 void AsmStmt::setInputExpr(unsigned i, Expr *E) {
    315   Exprs[i + NumOutputs] = E;
    316 }
    317 
    318 
    319 /// getInputConstraint - Return the specified input constraint.  Unlike output
    320 /// constraints, these can be empty.
    321 StringRef AsmStmt::getInputConstraint(unsigned i) const {
    322   return getInputConstraintLiteral(i)->getString();
    323 }
    324 
    325 
    326 void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
    327                                              IdentifierInfo **Names,
    328                                              StringLiteral **Constraints,
    329                                              Stmt **Exprs,
    330                                              unsigned NumOutputs,
    331                                              unsigned NumInputs,
    332                                              StringLiteral **Clobbers,
    333                                              unsigned NumClobbers) {
    334   this->NumOutputs = NumOutputs;
    335   this->NumInputs = NumInputs;
    336   this->NumClobbers = NumClobbers;
    337 
    338   unsigned NumExprs = NumOutputs + NumInputs;
    339 
    340   C.Deallocate(this->Names);
    341   this->Names = new (C) IdentifierInfo*[NumExprs];
    342   std::copy(Names, Names + NumExprs, this->Names);
    343 
    344   C.Deallocate(this->Exprs);
    345   this->Exprs = new (C) Stmt*[NumExprs];
    346   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
    347 
    348   C.Deallocate(this->Constraints);
    349   this->Constraints = new (C) StringLiteral*[NumExprs];
    350   std::copy(Constraints, Constraints + NumExprs, this->Constraints);
    351 
    352   C.Deallocate(this->Clobbers);
    353   this->Clobbers = new (C) StringLiteral*[NumClobbers];
    354   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
    355 }
    356 
    357 /// getNamedOperand - Given a symbolic operand reference like %[foo],
    358 /// translate this into a numeric value needed to reference the same operand.
    359 /// This returns -1 if the operand name is invalid.
    360 int AsmStmt::getNamedOperand(StringRef SymbolicName) const {
    361   unsigned NumPlusOperands = 0;
    362 
    363   // Check if this is an output operand.
    364   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
    365     if (getOutputName(i) == SymbolicName)
    366       return i;
    367   }
    368 
    369   for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
    370     if (getInputName(i) == SymbolicName)
    371       return getNumOutputs() + NumPlusOperands + i;
    372 
    373   // Not found.
    374   return -1;
    375 }
    376 
    377 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
    378 /// it into pieces.  If the asm string is erroneous, emit errors and return
    379 /// true, otherwise return false.
    380 unsigned AsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
    381                                    ASTContext &C, unsigned &DiagOffs) const {
    382   StringRef Str = getAsmString()->getString();
    383   const char *StrStart = Str.begin();
    384   const char *StrEnd = Str.end();
    385   const char *CurPtr = StrStart;
    386 
    387   // "Simple" inline asms have no constraints or operands, just convert the asm
    388   // string to escape $'s.
    389   if (isSimple()) {
    390     std::string Result;
    391     for (; CurPtr != StrEnd; ++CurPtr) {
    392       switch (*CurPtr) {
    393       case '$':
    394         Result += "$$";
    395         break;
    396       default:
    397         Result += *CurPtr;
    398         break;
    399       }
    400     }
    401     Pieces.push_back(AsmStringPiece(Result));
    402     return 0;
    403   }
    404 
    405   // CurStringPiece - The current string that we are building up as we scan the
    406   // asm string.
    407   std::string CurStringPiece;
    408 
    409   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
    410 
    411   while (1) {
    412     // Done with the string?
    413     if (CurPtr == StrEnd) {
    414       if (!CurStringPiece.empty())
    415         Pieces.push_back(AsmStringPiece(CurStringPiece));
    416       return 0;
    417     }
    418 
    419     char CurChar = *CurPtr++;
    420     switch (CurChar) {
    421     case '$': CurStringPiece += "$$"; continue;
    422     case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
    423     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
    424     case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
    425     case '%':
    426       break;
    427     default:
    428       CurStringPiece += CurChar;
    429       continue;
    430     }
    431 
    432     // Escaped "%" character in asm string.
    433     if (CurPtr == StrEnd) {
    434       // % at end of string is invalid (no escape).
    435       DiagOffs = CurPtr-StrStart-1;
    436       return diag::err_asm_invalid_escape;
    437     }
    438 
    439     char EscapedChar = *CurPtr++;
    440     if (EscapedChar == '%') {  // %% -> %
    441       // Escaped percentage sign.
    442       CurStringPiece += '%';
    443       continue;
    444     }
    445 
    446     if (EscapedChar == '=') {  // %= -> Generate an unique ID.
    447       CurStringPiece += "${:uid}";
    448       continue;
    449     }
    450 
    451     // Otherwise, we have an operand.  If we have accumulated a string so far,
    452     // add it to the Pieces list.
    453     if (!CurStringPiece.empty()) {
    454       Pieces.push_back(AsmStringPiece(CurStringPiece));
    455       CurStringPiece.clear();
    456     }
    457 
    458     // Handle %x4 and %x[foo] by capturing x as the modifier character.
    459     char Modifier = '\0';
    460     if (isalpha(EscapedChar)) {
    461       if (CurPtr == StrEnd) { // Premature end.
    462         DiagOffs = CurPtr-StrStart-1;
    463         return diag::err_asm_invalid_escape;
    464       }
    465       Modifier = EscapedChar;
    466       EscapedChar = *CurPtr++;
    467     }
    468 
    469     if (isdigit(EscapedChar)) {
    470       // %n - Assembler operand n
    471       unsigned N = 0;
    472 
    473       --CurPtr;
    474       while (CurPtr != StrEnd && isdigit(*CurPtr))
    475         N = N*10 + ((*CurPtr++)-'0');
    476 
    477       unsigned NumOperands =
    478         getNumOutputs() + getNumPlusOperands() + getNumInputs();
    479       if (N >= NumOperands) {
    480         DiagOffs = CurPtr-StrStart-1;
    481         return diag::err_asm_invalid_operand_number;
    482       }
    483 
    484       Pieces.push_back(AsmStringPiece(N, Modifier));
    485       continue;
    486     }
    487 
    488     // Handle %[foo], a symbolic operand reference.
    489     if (EscapedChar == '[') {
    490       DiagOffs = CurPtr-StrStart-1;
    491 
    492       // Find the ']'.
    493       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
    494       if (NameEnd == 0)
    495         return diag::err_asm_unterminated_symbolic_operand_name;
    496       if (NameEnd == CurPtr)
    497         return diag::err_asm_empty_symbolic_operand_name;
    498 
    499       StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
    500 
    501       int N = getNamedOperand(SymbolicName);
    502       if (N == -1) {
    503         // Verify that an operand with that name exists.
    504         DiagOffs = CurPtr-StrStart;
    505         return diag::err_asm_unknown_symbolic_operand_name;
    506       }
    507       Pieces.push_back(AsmStringPiece(N, Modifier));
    508 
    509       CurPtr = NameEnd+1;
    510       continue;
    511     }
    512 
    513     DiagOffs = CurPtr-StrStart-1;
    514     return diag::err_asm_invalid_escape;
    515   }
    516 }
    517 
    518 QualType CXXCatchStmt::getCaughtType() const {
    519   if (ExceptionDecl)
    520     return ExceptionDecl->getType();
    521   return QualType();
    522 }
    523 
    524 //===----------------------------------------------------------------------===//
    525 // Constructors
    526 //===----------------------------------------------------------------------===//
    527 
    528 AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
    529                  bool isvolatile, bool msasm,
    530                  unsigned numoutputs, unsigned numinputs,
    531                  IdentifierInfo **names, StringLiteral **constraints,
    532                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
    533                  StringLiteral **clobbers, SourceLocation rparenloc)
    534   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
    535   , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
    536   , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
    537 
    538   unsigned NumExprs = NumOutputs +NumInputs;
    539 
    540   Names = new (C) IdentifierInfo*[NumExprs];
    541   std::copy(names, names + NumExprs, Names);
    542 
    543   Exprs = new (C) Stmt*[NumExprs];
    544   std::copy(exprs, exprs + NumExprs, Exprs);
    545 
    546   Constraints = new (C) StringLiteral*[NumExprs];
    547   std::copy(constraints, constraints + NumExprs, Constraints);
    548 
    549   Clobbers = new (C) StringLiteral*[NumClobbers];
    550   std::copy(clobbers, clobbers + NumClobbers, Clobbers);
    551 }
    552 
    553 ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
    554                                              Stmt *Body,  SourceLocation FCL,
    555                                              SourceLocation RPL)
    556 : Stmt(ObjCForCollectionStmtClass) {
    557   SubExprs[ELEM] = Elem;
    558   SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
    559   SubExprs[BODY] = Body;
    560   ForLoc = FCL;
    561   RParenLoc = RPL;
    562 }
    563 
    564 ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
    565                              Stmt **CatchStmts, unsigned NumCatchStmts,
    566                              Stmt *atFinallyStmt)
    567   : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
    568     NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
    569 {
    570   Stmt **Stmts = getStmts();
    571   Stmts[0] = atTryStmt;
    572   for (unsigned I = 0; I != NumCatchStmts; ++I)
    573     Stmts[I + 1] = CatchStmts[I];
    574 
    575   if (HasFinally)
    576     Stmts[NumCatchStmts + 1] = atFinallyStmt;
    577 }
    578 
    579 ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context,
    580                                      SourceLocation atTryLoc,
    581                                      Stmt *atTryStmt,
    582                                      Stmt **CatchStmts,
    583                                      unsigned NumCatchStmts,
    584                                      Stmt *atFinallyStmt) {
    585   unsigned Size = sizeof(ObjCAtTryStmt) +
    586     (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
    587   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
    588   return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
    589                                  atFinallyStmt);
    590 }
    591 
    592 ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context,
    593                                                  unsigned NumCatchStmts,
    594                                                  bool HasFinally) {
    595   unsigned Size = sizeof(ObjCAtTryStmt) +
    596     (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
    597   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
    598   return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
    599 }
    600 
    601 SourceRange ObjCAtTryStmt::getSourceRange() const {
    602   SourceLocation EndLoc;
    603   if (HasFinally)
    604     EndLoc = getFinallyStmt()->getLocEnd();
    605   else if (NumCatchStmts)
    606     EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd();
    607   else
    608     EndLoc = getTryBody()->getLocEnd();
    609 
    610   return SourceRange(AtTryLoc, EndLoc);
    611 }
    612 
    613 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
    614                                Stmt *tryBlock, Stmt **handlers,
    615                                unsigned numHandlers) {
    616   std::size_t Size = sizeof(CXXTryStmt);
    617   Size += ((numHandlers + 1) * sizeof(Stmt));
    618 
    619   void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
    620   return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
    621 }
    622 
    623 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
    624                                unsigned numHandlers) {
    625   std::size_t Size = sizeof(CXXTryStmt);
    626   Size += ((numHandlers + 1) * sizeof(Stmt));
    627 
    628   void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
    629   return new (Mem) CXXTryStmt(Empty, numHandlers);
    630 }
    631 
    632 CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
    633                        Stmt **handlers, unsigned numHandlers)
    634   : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
    635   Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
    636   Stmts[0] = tryBlock;
    637   std::copy(handlers, handlers + NumHandlers, Stmts + 1);
    638 }
    639 
    640 CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
    641                                  Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
    642                                  Stmt *Body, SourceLocation FL,
    643                                  SourceLocation CL, SourceLocation RPL)
    644   : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) {
    645   SubExprs[RANGE] = Range;
    646   SubExprs[BEGINEND] = BeginEndStmt;
    647   SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
    648   SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
    649   SubExprs[LOOPVAR] = LoopVar;
    650   SubExprs[BODY] = Body;
    651 }
    652 
    653 Expr *CXXForRangeStmt::getRangeInit() {
    654   DeclStmt *RangeStmt = getRangeStmt();
    655   VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
    656   assert(RangeDecl &&& "for-range should have a single var decl");
    657   return RangeDecl->getInit();
    658 }
    659 
    660 const Expr *CXXForRangeStmt::getRangeInit() const {
    661   return const_cast<CXXForRangeStmt*>(this)->getRangeInit();
    662 }
    663 
    664 VarDecl *CXXForRangeStmt::getLoopVariable() {
    665   Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
    666   assert(LV && "No loop variable in CXXForRangeStmt");
    667   return cast<VarDecl>(LV);
    668 }
    669 
    670 const VarDecl *CXXForRangeStmt::getLoopVariable() const {
    671   return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
    672 }
    673 
    674 IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
    675                Stmt *then, SourceLocation EL, Stmt *elsev)
    676   : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
    677 {
    678   setConditionVariable(C, var);
    679   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
    680   SubExprs[THEN] = then;
    681   SubExprs[ELSE] = elsev;
    682 }
    683 
    684 VarDecl *IfStmt::getConditionVariable() const {
    685   if (!SubExprs[VAR])
    686     return 0;
    687 
    688   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
    689   return cast<VarDecl>(DS->getSingleDecl());
    690 }
    691 
    692 void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
    693   if (!V) {
    694     SubExprs[VAR] = 0;
    695     return;
    696   }
    697 
    698   SourceRange VarRange = V->getSourceRange();
    699   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
    700                                    VarRange.getEnd());
    701 }
    702 
    703 ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
    704                  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
    705                  SourceLocation RP)
    706   : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
    707 {
    708   SubExprs[INIT] = Init;
    709   setConditionVariable(C, condVar);
    710   SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
    711   SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
    712   SubExprs[BODY] = Body;
    713 }
    714 
    715 VarDecl *ForStmt::getConditionVariable() const {
    716   if (!SubExprs[CONDVAR])
    717     return 0;
    718 
    719   DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
    720   return cast<VarDecl>(DS->getSingleDecl());
    721 }
    722 
    723 void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
    724   if (!V) {
    725     SubExprs[CONDVAR] = 0;
    726     return;
    727   }
    728 
    729   SourceRange VarRange = V->getSourceRange();
    730   SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
    731                                        VarRange.getEnd());
    732 }
    733 
    734 SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond)
    735   : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
    736 {
    737   setConditionVariable(C, Var);
    738   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
    739   SubExprs[BODY] = NULL;
    740 }
    741 
    742 VarDecl *SwitchStmt::getConditionVariable() const {
    743   if (!SubExprs[VAR])
    744     return 0;
    745 
    746   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
    747   return cast<VarDecl>(DS->getSingleDecl());
    748 }
    749 
    750 void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
    751   if (!V) {
    752     SubExprs[VAR] = 0;
    753     return;
    754   }
    755 
    756   SourceRange VarRange = V->getSourceRange();
    757   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
    758                                    VarRange.getEnd());
    759 }
    760 
    761 Stmt *SwitchCase::getSubStmt() {
    762   if (isa<CaseStmt>(this))
    763     return cast<CaseStmt>(this)->getSubStmt();
    764   return cast<DefaultStmt>(this)->getSubStmt();
    765 }
    766 
    767 WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
    768                      SourceLocation WL)
    769   : Stmt(WhileStmtClass) {
    770   setConditionVariable(C, Var);
    771   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
    772   SubExprs[BODY] = body;
    773   WhileLoc = WL;
    774 }
    775 
    776 VarDecl *WhileStmt::getConditionVariable() const {
    777   if (!SubExprs[VAR])
    778     return 0;
    779 
    780   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
    781   return cast<VarDecl>(DS->getSingleDecl());
    782 }
    783 
    784 void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
    785   if (!V) {
    786     SubExprs[VAR] = 0;
    787     return;
    788   }
    789 
    790   SourceRange VarRange = V->getSourceRange();
    791   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
    792                                    VarRange.getEnd());
    793 }
    794 
    795 // IndirectGotoStmt
    796 LabelDecl *IndirectGotoStmt::getConstantTarget() {
    797   if (AddrLabelExpr *E =
    798         dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
    799     return E->getLabel();
    800   return 0;
    801 }
    802 
    803 // ReturnStmt
    804 const Expr* ReturnStmt::getRetValue() const {
    805   return cast_or_null<Expr>(RetExpr);
    806 }
    807 Expr* ReturnStmt::getRetValue() {
    808   return cast_or_null<Expr>(RetExpr);
    809 }
    810 
    811 SEHTryStmt::SEHTryStmt(bool IsCXXTry,
    812                        SourceLocation TryLoc,
    813                        Stmt *TryBlock,
    814                        Stmt *Handler)
    815   : Stmt(SEHTryStmtClass),
    816     IsCXXTry(IsCXXTry),
    817     TryLoc(TryLoc)
    818 {
    819   Children[TRY]     = TryBlock;
    820   Children[HANDLER] = Handler;
    821 }
    822 
    823 SEHTryStmt* SEHTryStmt::Create(ASTContext &C,
    824                                bool IsCXXTry,
    825                                SourceLocation TryLoc,
    826                                Stmt *TryBlock,
    827                                Stmt *Handler) {
    828   return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
    829 }
    830 
    831 SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
    832   return dyn_cast<SEHExceptStmt>(getHandler());
    833 }
    834 
    835 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
    836   return dyn_cast<SEHFinallyStmt>(getHandler());
    837 }
    838 
    839 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
    840                              Expr *FilterExpr,
    841                              Stmt *Block)
    842   : Stmt(SEHExceptStmtClass),
    843     Loc(Loc)
    844 {
    845   Children[FILTER_EXPR] = reinterpret_cast<Stmt*>(FilterExpr);
    846   Children[BLOCK]       = Block;
    847 }
    848 
    849 SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C,
    850                                      SourceLocation Loc,
    851                                      Expr *FilterExpr,
    852                                      Stmt *Block) {
    853   return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
    854 }
    855 
    856 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
    857                                Stmt *Block)
    858   : Stmt(SEHFinallyStmtClass),
    859     Loc(Loc),
    860     Block(Block)
    861 {}
    862 
    863 SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C,
    864                                        SourceLocation Loc,
    865                                        Stmt *Block) {
    866   return new(C)SEHFinallyStmt(Loc,Block);
    867 }
    868