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 static bool StatSwitch = false;
     82 
     83 bool Stmt::CollectingStats(bool Enable) {
     84   if (Enable) StatSwitch = true;
     85   return StatSwitch;
     86 }
     87 
     88 Stmt *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 
    100 namespace {
    101   struct good {};
    102   struct bad {};
    103 
    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.
    107   static inline good is_good(good) { return good(); }
    108 
    109   typedef Stmt::child_range children_t();
    110   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   }
    116 
    117   typedef SourceRange getSourceRange_t() const;
    118   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   }
    124 
    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.
    133 static 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 
    141 Stmt::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 
    154 SourceRange 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 
    167 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
    168   if (this->Body)
    169     C.Deallocate(Body);
    170   this->CompoundStmtBits.NumStmts = NumStmts;
    171 
    172   Body = new (C) Stmt*[NumStmts];
    173   memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
    174 }
    175 
    176 const char *LabelStmt::getName() const {
    177   return getDecl()->getIdentifier()->getNameStart();
    178 }
    179 
    180 // This is defined here to avoid polluting Stmt.h with importing Expr.h
    181 SourceRange ReturnStmt::getSourceRange() const {
    182   if (RetExpr)
    183     return SourceRange(RetLoc, RetExpr->getLocEnd());
    184   else
    185     return SourceRange(RetLoc);
    186 }
    187 
    188 bool Stmt::hasImplicitControlFlow() const {
    189   switch (StmtBits.sClass) {
    190     default:
    191       return false;
    192 
    193     case CallExprClass:
    194     case ConditionalOperatorClass:
    195     case ChooseExprClass:
    196     case StmtExprClass:
    197     case DeclStmtClass:
    198       return true;
    199 
    200     case Stmt::BinaryOperatorClass: {
    201       const BinaryOperator* B = cast<BinaryOperator>(this);
    202       if (B->isLogicalOp() || B->getOpcode() == BO_Comma)
    203         return true;
    204       else
    205         return false;
    206     }
    207   }
    208 }
    209 
    210 Expr *AsmStmt::getOutputExpr(unsigned i) {
    211   return cast<Expr>(Exprs[i]);
    212 }
    213 
    214 /// getOutputConstraint - Return the constraint string for the specified
    215 /// output operand.  All output constraints are known to be non-empty (either
    216 /// '=' or '+').
    217 llvm::StringRef AsmStmt::getOutputConstraint(unsigned i) const {
    218   return getOutputConstraintLiteral(i)->getString();
    219 }
    220 
    221 /// getNumPlusOperands - Return the number of output operands that have a "+"
    222 /// constraint.
    223 unsigned 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 
    231 Expr *AsmStmt::getInputExpr(unsigned i) {
    232   return cast<Expr>(Exprs[i + NumOutputs]);
    233 }
    234 void AsmStmt::setInputExpr(unsigned i, Expr *E) {
    235   Exprs[i + NumOutputs] = E;
    236 }
    237 
    238 
    239 /// getInputConstraint - Return the specified input constraint.  Unlike output
    240 /// constraints, these can be empty.
    241 llvm::StringRef AsmStmt::getInputConstraint(unsigned i) const {
    242   return getInputConstraintLiteral(i)->getString();
    243 }
    244 
    245 
    246 void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
    247                                              IdentifierInfo **Names,
    248                                              StringLiteral **Constraints,
    249                                              Stmt **Exprs,
    250                                              unsigned NumOutputs,
    251                                              unsigned NumInputs,
    252                                              StringLiteral **Clobbers,
    253                                              unsigned NumClobbers) {
    254   this->NumOutputs = NumOutputs;
    255   this->NumInputs = NumInputs;
    256   this->NumClobbers = NumClobbers;
    257 
    258   unsigned NumExprs = NumOutputs + NumInputs;
    259 
    260   C.Deallocate(this->Names);
    261   this->Names = new (C) IdentifierInfo*[NumExprs];
    262   std::copy(Names, Names + NumExprs, this->Names);
    263 
    264   C.Deallocate(this->Exprs);
    265   this->Exprs = new (C) Stmt*[NumExprs];
    266   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
    267 
    268   C.Deallocate(this->Constraints);
    269   this->Constraints = new (C) StringLiteral*[NumExprs];
    270   std::copy(Constraints, Constraints + NumExprs, this->Constraints);
    271 
    272   C.Deallocate(this->Clobbers);
    273   this->Clobbers = new (C) StringLiteral*[NumClobbers];
    274   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
    275 }
    276 
    277 /// 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.
    280 int AsmStmt::getNamedOperand(llvm::StringRef SymbolicName) const {
    281   unsigned NumPlusOperands = 0;
    282 
    283   // 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;
    287   }
    288 
    289   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 
    297 /// 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.
    300 unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
    301                                    ASTContext &C, unsigned &DiagOffs) const {
    302   llvm::StringRef Str = getAsmString()->getString();
    303   const char *StrStart = Str.begin();
    304   const char *StrEnd = Str.end();
    305   const char *CurPtr = StrStart;
    306 
    307   // "Simple" inline asms have no constraints or operands, just convert the asm
    308   // string to escape $'s.
    309   if (isSimple()) {
    310     std::string Result;
    311     for (; CurPtr != StrEnd; ++CurPtr) {
    312       switch (*CurPtr) {
    313       case '$':
    314         Result += "$$";
    315         break;
    316       default:
    317         Result += *CurPtr;
    318         break;
    319       }
    320     }
    321     Pieces.push_back(AsmStringPiece(Result));
    322     return 0;
    323   }
    324 
    325   // CurStringPiece - The current string that we are building up as we scan the
    326   // asm string.
    327   std::string CurStringPiece;
    328 
    329   bool HasVariants = !C.Target.hasNoAsmVariants();
    330 
    331   while (1) {
    332     // Done with the string?
    333     if (CurPtr == StrEnd) {
    334       if (!CurStringPiece.empty())
    335         Pieces.push_back(AsmStringPiece(CurStringPiece));
    336       return 0;
    337     }
    338 
    339     char CurChar = *CurPtr++;
    340     switch (CurChar) {
    341     case '$': CurStringPiece += "$$"; continue;
    342     case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
    343     case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
    344     case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
    345     case '%':
    346       break;
    347     default:
    348       CurStringPiece += CurChar;
    349       continue;
    350     }
    351 
    352     // Escaped "%" character in asm string.
    353     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     }
    358 
    359     char EscapedChar = *CurPtr++;
    360     if (EscapedChar == '%') {  // %% -> %
    361       // Escaped percentage sign.
    362       CurStringPiece += '%';
    363       continue;
    364     }
    365 
    366     if (EscapedChar == '=') {  // %= -> Generate an unique ID.
    367       CurStringPiece += "${:uid}";
    368       continue;
    369     }
    370 
    371     // 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     }
    377 
    378     // Handle %x4 and %x[foo] by capturing x as the modifier character.
    379     char Modifier = '\0';
    380     if (isalpha(EscapedChar)) {
    381       if (CurPtr == StrEnd) { // Premature end.
    382         DiagOffs = CurPtr-StrStart-1;
    383         return diag::err_asm_invalid_escape;
    384       }
    385       Modifier = EscapedChar;
    386       EscapedChar = *CurPtr++;
    387     }
    388 
    389     if (isdigit(EscapedChar)) {
    390       // %n - Assembler operand n
    391       unsigned N = 0;
    392 
    393       --CurPtr;
    394       while (CurPtr != StrEnd && isdigit(*CurPtr))
    395         N = N*10 + ((*CurPtr++)-'0');
    396 
    397       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 
    404       Pieces.push_back(AsmStringPiece(N, Modifier));
    405       continue;
    406     }
    407 
    408     // Handle %[foo], a symbolic operand reference.
    409     if (EscapedChar == '[') {
    410       DiagOffs = CurPtr-StrStart-1;
    411 
    412       // Find the ']'.
    413       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
    414       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;
    418 
    419       llvm::StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
    420 
    421       int N = getNamedOperand(SymbolicName);
    422       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       }
    427       Pieces.push_back(AsmStringPiece(N, Modifier));
    428 
    429       CurPtr = NameEnd+1;
    430       continue;
    431     }
    432 
    433     DiagOffs = CurPtr-StrStart-1;
    434     return diag::err_asm_invalid_escape;
    435   }
    436 }
    437 
    438 QualType CXXCatchStmt::getCaughtType() const {
    439   if (ExceptionDecl)
    440     return ExceptionDecl->getType();
    441   return QualType();
    442 }
    443 
    444 //===----------------------------------------------------------------------===//
    445 // Constructors
    446 //===----------------------------------------------------------------------===//
    447 
    448 AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
    449                  bool isvolatile, bool msasm,
    450                  unsigned numoutputs, unsigned numinputs,
    451                  IdentifierInfo **names, StringLiteral **constraints,
    452                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
    453                  StringLiteral **clobbers, SourceLocation rparenloc)
    454   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
    455   , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
    456   , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
    457 
    458   unsigned NumExprs = NumOutputs +NumInputs;
    459 
    460   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);
    471 }
    472 
    473 ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
    474                                              Stmt *Body,  SourceLocation FCL,
    475                                              SourceLocation RPL)
    476 : 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 
    484 ObjCAtTryStmt::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];
    494 
    495   if (HasFinally)
    496     Stmts[NumCatchStmts + 1] = atFinallyStmt;
    497 }
    498 
    499 ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context,
    500                                      SourceLocation atTryLoc,
    501                                      Stmt *atTryStmt,
    502                                      Stmt **CatchStmts,
    503                                      unsigned NumCatchStmts,
    504                                      Stmt *atFinallyStmt) {
    505   unsigned Size = sizeof(ObjCAtTryStmt) +
    506     (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
    507   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
    508   return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
    509                                  atFinallyStmt);
    510 }
    511 
    512 ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context,
    513                                                  unsigned NumCatchStmts,
    514                                                  bool HasFinally) {
    515   unsigned Size = sizeof(ObjCAtTryStmt) +
    516     (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
    517   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
    518   return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
    519 }
    520 
    521 SourceRange 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();
    529 
    530   return SourceRange(AtTryLoc, EndLoc);
    531 }
    532 
    533 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
    534                                Stmt *tryBlock, Stmt **handlers,
    535                                unsigned numHandlers) {
    536   std::size_t Size = sizeof(CXXTryStmt);
    537   Size += ((numHandlers + 1) * sizeof(Stmt));
    538 
    539   void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
    540   return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
    541 }
    542 
    543 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
    544                                unsigned numHandlers) {
    545   std::size_t Size = sizeof(CXXTryStmt);
    546   Size += ((numHandlers + 1) * sizeof(Stmt));
    547 
    548   void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
    549   return new (Mem) CXXTryStmt(Empty, numHandlers);
    550 }
    551 
    552 CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
    553                        Stmt **handlers, unsigned numHandlers)
    554   : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
    555   Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
    556   Stmts[0] = tryBlock;
    557   std::copy(handlers, handlers + NumHandlers, Stmts + 1);
    558 }
    559 
    560 CXXForRangeStmt::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 
    573 Expr *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 
    580 const Expr *CXXForRangeStmt::getRangeInit() const {
    581   return const_cast<CXXForRangeStmt*>(this)->getRangeInit();
    582 }
    583 
    584 VarDecl *CXXForRangeStmt::getLoopVariable() {
    585   Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
    586   assert(LV && "No loop variable in CXXForRangeStmt");
    587   return cast<VarDecl>(LV);
    588 }
    589 
    590 const VarDecl *CXXForRangeStmt::getLoopVariable() const {
    591   return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
    592 }
    593 
    594 IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
    595                Stmt *then, SourceLocation EL, Stmt *elsev)
    596   : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
    597 {
    598   setConditionVariable(C, var);
    599   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
    600   SubExprs[THEN] = then;
    601   SubExprs[ELSE] = elsev;
    602 }
    603 
    604 VarDecl *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 
    612 void 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 
    623 ForStmt::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 
    635 VarDecl *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 
    643 void 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 
    654 SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond)
    655   : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
    656 {
    657   setConditionVariable(C, Var);
    658   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
    659   SubExprs[BODY] = NULL;
    660 }
    661 
    662 VarDecl *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 
    670 void 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 
    681 Stmt *SwitchCase::getSubStmt() {
    682   if (isa<CaseStmt>(this))
    683     return cast<CaseStmt>(this)->getSubStmt();
    684   return cast<DefaultStmt>(this)->getSubStmt();
    685 }
    686 
    687 WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
    688                      SourceLocation WL)
    689   : Stmt(WhileStmtClass) {
    690   setConditionVariable(C, Var);
    691   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
    692   SubExprs[BODY] = body;
    693   WhileLoc = WL;
    694 }
    695 
    696 VarDecl *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 
    704 void 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 
    715 // IndirectGotoStmt
    716 LabelDecl *IndirectGotoStmt::getConstantTarget() {
    717   if (AddrLabelExpr *E =
    718         dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
    719     return E->getLabel();
    720   return 0;
    721 }
    722 
    723 // ReturnStmt
    724 const Expr* ReturnStmt::getRetValue() const {
    725   return cast_or_null<Expr>(RetExpr);
    726 }
    727 Expr* ReturnStmt::getRetValue() {
    728   return cast_or_null<Expr>(RetExpr);
    729 }
    730 
    731 SEHTryStmt::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 
    743 SEHTryStmt* 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 
    751 SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
    752   return dyn_cast<SEHExceptStmt>(getHandler());
    753 }
    754 
    755 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
    756   return dyn_cast<SEHFinallyStmt>(getHandler());
    757 }
    758 
    759 SEHExceptStmt::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 
    769 SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C,
    770                                      SourceLocation Loc,
    771                                      Expr *FilterExpr,
    772                                      Stmt *Block) {
    773   return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
    774 }
    775 
    776 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
    777                                Stmt *Block)
    778   : Stmt(SEHFinallyStmtClass),
    779     Loc(Loc),
    780     Block(Block)
    781 {}
    782 
    783 SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C,
    784                                        SourceLocation Loc,
    785                                        Stmt *Block) {
    786   return new(C)SEHFinallyStmt(Loc,Block);
    787 }
    788