zcov: / lib/AST/Stmt.cpp


Files: 1 Branches Taken: 82.0% 91 / 111
Generated: 2010-02-10 01:31 Branches Executed: 86.5% 96 / 111
Line Coverage: 90.4% 310 / 343


Programs: 2 Runs 3018


       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 <cstdio>
      23                 : using namespace clang;
      24                 : 
      25                 : static struct StmtClassNameTable {
      26                 :   const char *Name;
      27                 :   unsigned Counter;
      28                 :   unsigned Size;
      29                 : } StmtClassInfo[Stmt::lastExprConstant+1];
      30                 : 
      31              356: static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
      32                 :   static bool Initialized = false;
                      350: branch 0 taken
                        6: branch 1 taken
      33              356:   if (Initialized)
      34              350:     return StmtClassInfo[E];
      35                 : 
      36                 :   // Intialize the table on the first use.
      37                6:   Initialized = true;
      38                 : #define ABSTRACT_EXPR(CLASS, PARENT)
      39                 : #define STMT(CLASS, PARENT) \
      40                 :   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS;    \
      41                 :   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
      42                 : #include "clang/AST/StmtNodes.def"
      43                 : 
      44                6:   return StmtClassInfo[E];
      45                 : }
      46                 : 
      47              354: const char *Stmt::getStmtClassName() const {
      48              354:   return getStmtInfoTableEntry((StmtClass)sClass).Name;
      49                 : }
      50                 : 
      51                2: void Stmt::PrintStats() {
      52                 :   // Ensure the table is primed.
      53                2:   getStmtInfoTableEntry(Stmt::NullStmtClass);
      54                 : 
      55                2:   unsigned sum = 0;
      56                2:   fprintf(stderr, "*** Stmt/Expr Stats:\n");
                      198: branch 0 taken
                        2: branch 1 taken
      57              200:   for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
                      196: branch 0 taken
                        2: branch 1 taken
      58              198:     if (StmtClassInfo[i].Name == 0) continue;
      59              196:     sum += StmtClassInfo[i].Counter;
      60                 :   }
      61                2:   fprintf(stderr, "  %d stmts/exprs total.\n", sum);
      62                2:   sum = 0;
                      198: branch 0 taken
                        2: branch 1 taken
      63              200:   for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
                      196: branch 0 taken
                        2: branch 1 taken
      64              198:     if (StmtClassInfo[i].Name == 0) continue;
                        0: branch 0 not taken
                      196: branch 1 taken
      65              196:     if (StmtClassInfo[i].Counter == 0) continue;
      66                 :     fprintf(stderr, "    %d %s, %d each (%d bytes)\n",
      67                 :             StmtClassInfo[i].Counter, StmtClassInfo[i].Name,
      68                 :             StmtClassInfo[i].Size,
      69                0:             StmtClassInfo[i].Counter*StmtClassInfo[i].Size);
      70                0:     sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
      71                 :   }
      72                2:   fprintf(stderr, "Total bytes = %d\n", sum);
      73                2: }
      74                 : 
      75                0: void Stmt::addStmtClass(StmtClass s) {
      76                0:   ++getStmtInfoTableEntry(s).Counter;
      77                0: }
      78                 : 
      79                 : static bool StatSwitch = false;
      80                 : 
      81           177104: bool Stmt::CollectingStats(bool Enable) {
                        2: branch 0 taken
                   177102: branch 1 taken
      82           177104:   if (Enable) StatSwitch = true;
      83           177104:   return StatSwitch;
      84                 : }
      85                 : 
      86               43: void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
                        3: branch 0 taken
                       40: branch 1 taken
      87               43:   if (this->Body)
      88                3:     C.Deallocate(Body);
      89               43:   this->NumStmts = NumStmts;
      90                 : 
      91               43:   Body = new (C) Stmt*[NumStmts];
      92               43:   memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
      93               43: }
      94                 : 
      95               45: const char *LabelStmt::getName() const {
      96               45:   return getID()->getNameStart();
      97                 : }
      98                 : 
      99                 : // This is defined here to avoid polluting Stmt.h with importing Expr.h
     100             4263: SourceRange ReturnStmt::getSourceRange() const {
                     3581: branch 0 taken
                      682: branch 1 taken
     101             4263:   if (RetExpr)
     102             3581:     return SourceRange(RetLoc, RetExpr->getLocEnd());
     103                 :   else
     104              682:     return SourceRange(RetLoc);
     105                 : }
     106                 : 
     107                0: bool Stmt::hasImplicitControlFlow() const {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
     108                0:   switch (sClass) {
     109                 :     default:
     110                0:       return false;
     111                 : 
     112                 :     case CallExprClass:
     113                 :     case ConditionalOperatorClass:
     114                 :     case ChooseExprClass:
     115                 :     case StmtExprClass:
     116                 :     case DeclStmtClass:
     117                0:       return true;
     118                 : 
     119                 :     case Stmt::BinaryOperatorClass: {
     120                0:       const BinaryOperator* B = cast<BinaryOperator>(this);
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     121                0:       if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
     122                0:         return true;
     123                 :       else
     124                0:         return false;
     125                 :     }
     126                 :   }
     127                 : }
     128                 : 
     129               37: Expr *AsmStmt::getOutputExpr(unsigned i) {
     130               37:   return cast<Expr>(Exprs[i]);
     131                 : }
     132                 : 
     133                 : /// getOutputConstraint - Return the constraint string for the specified
     134                 : /// output operand.  All output constraints are known to be non-empty (either
     135                 : /// '=' or '+').
     136               58: llvm::StringRef AsmStmt::getOutputConstraint(unsigned i) const {
     137               58:   return getOutputConstraintLiteral(i)->getString();
     138                 : }
     139                 : 
     140                 : /// getNumPlusOperands - Return the number of output operands that have a "+"
     141                 : /// constraint.
     142               17: unsigned AsmStmt::getNumPlusOperands() const {
     143               17:   unsigned Res = 0;
                       16: branch 1 taken
                       17: branch 2 taken
     144               33:   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
                        6: branch 1 taken
                       10: branch 2 taken
     145               16:     if (isOutputPlusConstraint(i))
     146                6:       ++Res;
     147               17:   return Res;
     148                 : }
     149                 : 
     150               31: Expr *AsmStmt::getInputExpr(unsigned i) {
     151               31:   return cast<Expr>(Exprs[i + NumOutputs]);
     152                 : }
     153                 : 
     154                 : /// getInputConstraint - Return the specified input constraint.  Unlike output
     155                 : /// constraints, these can be empty.
     156               46: llvm::StringRef AsmStmt::getInputConstraint(unsigned i) const {
     157               46:   return getInputConstraintLiteral(i)->getString();
     158                 : }
     159                 : 
     160                 : 
     161                 : void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
     162                 :                                              IdentifierInfo **Names,
     163                 :                                              StringLiteral **Constraints,
     164                 :                                              Stmt **Exprs,
     165                 :                                              unsigned NumOutputs,
     166                 :                                              unsigned NumInputs,                                      
     167                 :                                              StringLiteral **Clobbers,
     168                5:                                              unsigned NumClobbers) {
     169                5:   this->NumOutputs = NumOutputs;
     170                5:   this->NumInputs = NumInputs;
     171                5:   this->NumClobbers = NumClobbers;
     172                 : 
     173                5:   unsigned NumExprs = NumOutputs + NumInputs;
     174                 :   
     175                5:   C.Deallocate(this->Names);
     176                5:   this->Names = new (C) IdentifierInfo*[NumExprs];
     177                5:   std::copy(Names, Names + NumExprs, this->Names);
     178                 :   
     179                5:   C.Deallocate(this->Exprs);
     180                5:   this->Exprs = new (C) Stmt*[NumExprs];
     181                5:   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
     182                 :   
     183                5:   C.Deallocate(this->Constraints);
     184                5:   this->Constraints = new (C) StringLiteral*[NumExprs];
     185                5:   std::copy(Constraints, Constraints + NumExprs, this->Constraints);
     186                 :   
     187                5:   C.Deallocate(this->Clobbers);
     188                5:   this->Clobbers = new (C) StringLiteral*[NumClobbers];
     189                5:   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
     190                5: }
     191                 : 
     192                 : /// getNamedOperand - Given a symbolic operand reference like %[foo],
     193                 : /// translate this into a numeric value needed to reference the same operand.
     194                 : /// This returns -1 if the operand name is invalid.
     195               14: int AsmStmt::getNamedOperand(llvm::StringRef SymbolicName) const {
     196               14:   unsigned NumPlusOperands = 0;
     197                 : 
     198                 :   // Check if this is an output operand.
                       10: branch 1 taken
                       12: branch 2 taken
     199               22:   for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
                        2: branch 2 taken
                        8: branch 3 taken
     200               10:     if (getOutputName(i) == SymbolicName)
     201                2:       return i;
     202                 :   }
     203                 : 
                       18: branch 1 taken
                        1: branch 2 taken
     204               19:   for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
                       11: branch 2 taken
                        7: branch 3 taken
     205               18:     if (getInputName(i) == SymbolicName)
     206               11:       return getNumOutputs() + NumPlusOperands + i;
     207                 : 
     208                 :   // Not found.
     209                1:   return -1;
     210                 : }
     211                 : 
     212                 : /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
     213                 : /// it into pieces.  If the asm string is erroneous, emit errors and return
     214                 : /// true, otherwise return false.
     215                 : unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     216              124:                                    ASTContext &C, unsigned &DiagOffs) const {
     217              124:   const char *StrStart = getAsmString()->getStrData();
     218              124:   const char *StrEnd = StrStart + getAsmString()->getByteLength();
     219              124:   const char *CurPtr = StrStart;
     220                 : 
     221                 :   // "Simple" inline asms have no constraints or operands, just convert the asm
     222                 :   // string to escape $'s.
                       34: branch 1 taken
                       90: branch 2 taken
     223              124:   if (isSimple()) {
     224               34:     std::string Result;
                      168: branch 0 taken
                       34: branch 1 taken
     225              202:     for (; CurPtr != StrEnd; ++CurPtr) {
                        0: branch 0 not taken
                      168: branch 1 taken
     226              168:       switch (*CurPtr) {
     227                 :       case '$':
     228                0:         Result += "$$";
     229                0:         break;
     230                 :       default:
     231              168:         Result += *CurPtr;
     232                 :         break;
     233                 :       }
     234                 :     }
     235               34:     Pieces.push_back(AsmStringPiece(Result));
     236               34:     return 0;
     237                 :   }
     238                 : 
     239                 :   // CurStringPiece - The current string that we are building up as we scan the
     240                 :   // asm string.
     241               90:   std::string CurStringPiece;
     242                 : 
     243              398:   while (1) {
     244                 :     // Done with the string?
                       84: branch 0 taken
                      404: branch 1 taken
     245              488:     if (CurPtr == StrEnd) {
                       50: branch 1 taken
                       34: branch 2 taken
     246               84:       if (!CurStringPiece.empty())
     247               50:         Pieces.push_back(AsmStringPiece(CurStringPiece));
     248               84:       return 0;
     249                 :     }
     250                 : 
     251              404:     char CurChar = *CurPtr++;
                        0: branch 0 not taken
                      404: branch 1 taken
     252              404:     if (CurChar == '$') {
     253                0:       CurStringPiece += "$$";
     254                0:       continue;
                      369: branch 0 taken
                       35: branch 1 taken
     255              404:     } else if (CurChar != '%') {
     256              369:       CurStringPiece += CurChar;
     257              369:       continue;
     258                 :     }
     259                 : 
     260                 :     // Escaped "%" character in asm string.
                        1: branch 0 taken
                       34: branch 1 taken
     261               35:     if (CurPtr == StrEnd) {
     262                 :       // % at end of string is invalid (no escape).
     263                1:       DiagOffs = CurPtr-StrStart-1;
     264                1:       return diag::err_asm_invalid_escape;
     265                 :     }
     266                 : 
     267               34:     char EscapedChar = *CurPtr++;
                        0: branch 0 not taken
                       34: branch 1 taken
     268               34:     if (EscapedChar == '%') {  // %% -> %
     269                 :       // Escaped percentage sign.
     270                0:       CurStringPiece += '%';
     271                0:       continue;
     272                 :     }
     273                 : 
                        0: branch 0 not taken
                       34: branch 1 taken
     274               34:     if (EscapedChar == '=') {  // %= -> Generate an unique ID.
     275                0:       CurStringPiece += "${:uid}";
     276                0:       continue;
     277                 :     }
     278                 : 
     279                 :     // Otherwise, we have an operand.  If we have accumulated a string so far,
     280                 :     // add it to the Pieces list.
                       25: branch 1 taken
                        9: branch 2 taken
     281               34:     if (!CurStringPiece.empty()) {
     282               25:       Pieces.push_back(AsmStringPiece(CurStringPiece));
     283               25:       CurStringPiece.clear();
     284                 :     }
     285                 : 
     286                 :     // Handle %x4 and %x[foo] by capturing x as the modifier character.
     287               34:     char Modifier = '\0';
                        2: branch 1 taken
                       32: branch 2 taken
     288               34:     if (isalpha(EscapedChar)) {
     289                2:       Modifier = EscapedChar;
     290                2:       EscapedChar = *CurPtr++;
     291                 :     }
     292                 : 
                       17: branch 0 taken
                       17: branch 1 taken
     293               34:     if (isdigit(EscapedChar)) {
     294                 :       // %n - Assembler operand n
     295               17:       unsigned N = 0;
     296                 : 
     297               17:       --CurPtr;
                       22: branch 0 taken
                       12: branch 1 taken
                       17: branch 2 taken
                        5: branch 3 taken
     298               51:       while (CurPtr != StrEnd && isdigit(*CurPtr))
     299               17:         N = N*10 + ((*CurPtr++)-'0');
     300                 : 
     301                 :       unsigned NumOperands =
     302               17:         getNumOutputs() + getNumPlusOperands() + getNumInputs();
                        1: branch 0 taken
                       16: branch 1 taken
     303               17:       if (N >= NumOperands) {
     304                1:         DiagOffs = CurPtr-StrStart-1;
     305                1:         return diag::err_asm_invalid_operand_number;
     306                 :       }
     307                 : 
     308               16:       Pieces.push_back(AsmStringPiece(N, Modifier));
     309               16:       continue;
     310                 :     }
     311                 : 
     312                 :     // Handle %[foo], a symbolic operand reference.
                       16: branch 0 taken
                        1: branch 1 taken
     313               17:     if (EscapedChar == '[') {
     314               16:       DiagOffs = CurPtr-StrStart-1;
     315                 : 
     316                 :       // Find the ']'.
     317               16:       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
                        1: branch 0 taken
                       15: branch 1 taken
     318               16:       if (NameEnd == 0)
     319                1:         return diag::err_asm_unterminated_symbolic_operand_name;
                        1: branch 0 taken
                       14: branch 1 taken
     320               15:       if (NameEnd == CurPtr)
     321                1:         return diag::err_asm_empty_symbolic_operand_name;
     322                 : 
     323               14:       llvm::StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
     324                 : 
     325               14:       int N = getNamedOperand(SymbolicName);
                        1: branch 0 taken
                       13: branch 1 taken
     326               14:       if (N == -1) {
     327                 :         // Verify that an operand with that name exists.
     328                1:         DiagOffs = CurPtr-StrStart;
     329                1:         return diag::err_asm_unknown_symbolic_operand_name;
     330                 :       }
     331               13:       Pieces.push_back(AsmStringPiece(N, Modifier));
     332                 : 
     333               13:       CurPtr = NameEnd+1;
     334               13:       continue;
     335                 :     }
     336                 : 
     337                1:     DiagOffs = CurPtr-StrStart-1;
     338                1:     return diag::err_asm_invalid_escape;
     339               90:   }
     340                 : }
     341                 : 
     342               28: QualType CXXCatchStmt::getCaughtType() const {
                       28: branch 0 taken
                        0: branch 1 not taken
     343               28:   if (ExceptionDecl)
     344               28:     return ExceptionDecl->getType();
     345                0:   return QualType();
     346                 : }
     347                 : 
     348                 : //===----------------------------------------------------------------------===//
     349                 : // Constructors
     350                 : //===----------------------------------------------------------------------===//
     351                 : 
     352                 : AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 
     353                 :                  bool isvolatile, bool msasm, 
     354                 :                  unsigned numoutputs, unsigned numinputs,
     355                 :                  IdentifierInfo **names, StringLiteral **constraints,
     356                 :                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
     357               89:                  StringLiteral **clobbers, SourceLocation rparenloc)
     358                 :   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
     359                 :   , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
     360               89:   , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
     361                 : 
     362               89:   unsigned NumExprs = NumOutputs +NumInputs;
     363                 :     
     364               89:   Names = new (C) IdentifierInfo*[NumExprs];
     365               89:   std::copy(names, names + NumExprs, Names);
     366                 : 
     367               89:   Exprs = new (C) Stmt*[NumExprs];
     368               89:   std::copy(exprs, exprs + NumExprs, Exprs);
     369                 : 
     370               89:   Constraints = new (C) StringLiteral*[NumExprs];
     371               89:   std::copy(constraints, constraints + NumExprs, Constraints);
     372                 : 
     373               89:   Clobbers = new (C) StringLiteral*[NumClobbers];
     374               89:   std::copy(clobbers, clobbers + NumClobbers, Clobbers);
     375               89: }
     376                 : 
     377                 : ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
     378                 :                                              Stmt *Body,  SourceLocation FCL,
     379               51:                                              SourceLocation RPL)
     380               51: : Stmt(ObjCForCollectionStmtClass) {
     381               51:   SubExprs[ELEM] = Elem;
     382               51:   SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
     383               51:   SubExprs[BODY] = Body;
     384               51:   ForLoc = FCL;
     385               51:   RParenLoc = RPL;
     386               51: }
     387                 : 
     388                 : 
     389                 : ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
     390                 :                                  SourceLocation rparenloc,
     391                 :                                  ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
     392               57:                                  Stmt *atCatchList)
     393               57: : Stmt(ObjCAtCatchStmtClass) {
     394               57:   ExceptionDecl = catchVarDecl;
     395               57:   SubExprs[BODY] = atCatchStmt;
     396               57:   SubExprs[NEXT_CATCH] = NULL;
     397                 :   // FIXME: O(N^2) in number of catch blocks.
                       57: branch 0 taken
                       57: branch 1 taken
                       20: branch 2 taken
                       37: branch 3 taken
     398               57:   if (atCatchList) {
     399               20:     ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
     400                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
                        5: branch 4 taken
                       20: branch 5 taken
     401               30:     while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
     402                5:       AtCatchList = NextCatch;
     403                 : 
     404               20:     AtCatchList->SubExprs[NEXT_CATCH] = this;
     405                 :   }
     406               57:   AtCatchLoc = atCatchLoc;
     407               57:   RParenLoc = rparenloc;
     408               57: }
     409                 : 
     410                 : CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
     411                 :                                Stmt *tryBlock, Stmt **handlers, 
     412               25:                                unsigned numHandlers) {
     413               25:   std::size_t Size = sizeof(CXXTryStmt);
     414               25:   Size += ((numHandlers + 1) * sizeof(Stmt));
     415                 : 
     416               25:   void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>());
                       25: branch 1 taken
                        0: branch 2 not taken
     417               25:   return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
     418                 : }
     419                 : 
     420                 : CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
     421               25:                        Stmt **handlers, unsigned numHandlers)
     422               25:   : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
     423               25:   Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
     424               25:   Stmts[0] = tryBlock;
     425               25:   std::copy(handlers, handlers + NumHandlers, Stmts + 1);
     426               25: }
     427                 : 
     428                 : //===----------------------------------------------------------------------===//
     429                 : // AST Destruction.
     430                 : //===----------------------------------------------------------------------===//
     431                 : 
     432             3767: void Stmt::DestroyChildren(ASTContext &C) {
                     2172: branch 3 taken
                     3767: branch 4 taken
     433             9706:   for (child_iterator I = child_begin(), E = child_end(); I !=E; )
                     1503: branch 2 taken
                      669: branch 3 taken
     434             2172:     if (Stmt* Child = *I++) Child->Destroy(C);
     435             3767: }
     436                 : 
     437                 : static void BranchDestroy(ASTContext &C, Stmt *S, Stmt **SubExprs,
     438               15:                           unsigned NumExprs) {
     439                 :   // We do not use child_iterator here because that will include
     440                 :   // the expressions referenced by the condition variable.
                       31: branch 0 taken
                       15: branch 1 taken
     441               46:   for (Stmt **I = SubExprs, **E = SubExprs + NumExprs; I != E; ++I)
                       27: branch 0 taken
                        4: branch 1 taken
     442               31:     if (Stmt *Child = *I) Child->Destroy(C);
     443                 :   
     444               15:   S->~Stmt();
     445               15:   C.Deallocate((void *) S);
     446               15: }
     447                 : 
     448             3446: void Stmt::DoDestroy(ASTContext &C) {
     449             3446:   DestroyChildren(C);
     450             3446:   this->~Stmt();
     451             3446:   C.Deallocate((void *)this);
     452             3446: }
     453                 : 
     454                0: void CXXCatchStmt::DoDestroy(ASTContext& C) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     455                0:   if (ExceptionDecl)
     456                0:     ExceptionDecl->Destroy(C);
     457                0:   Stmt::DoDestroy(C);
     458                0: }
     459                 : 
     460               25: void DeclStmt::DoDestroy(ASTContext &C) {
     461                 :   // Don't use StmtIterator to iterate over the Decls, as that can recurse
     462                 :   // into VLA size expressions (which are owned by the VLA).  Further, Decls
     463                 :   // are owned by the DeclContext, and will be destroyed with them.
                        5: branch 1 taken
                       20: branch 2 taken
     464               25:   if (DG.isDeclGroup())
     465                5:     DG.getDeclGroup().Destroy(C);
     466               25: }
     467                 : 
     468                1: void IfStmt::DoDestroy(ASTContext &C) {
     469                1:   BranchDestroy(C, this, SubExprs, END_EXPR);
     470                1: }
     471                 : 
     472                0: void ForStmt::DoDestroy(ASTContext &C) {
     473                0:   BranchDestroy(C, this, SubExprs, END_EXPR);
     474                0: }
     475                 : 
     476               14: void SwitchStmt::DoDestroy(ASTContext &C) {
     477                 :   // Destroy the SwitchCase statements in this switch. In the normal
     478                 :   // case, this loop will merely decrement the reference counts from
     479                 :   // the Retain() calls in addSwitchCase();
     480               14:   SwitchCase *SC = FirstCase;
                       17: branch 0 taken
                       14: branch 1 taken
     481               45:   while (SC) {
     482               17:     SwitchCase *Next = SC->getNextSwitchCase();
     483               17:     SC->Destroy(C);
     484               17:     SC = Next;
     485                 :   }
     486                 :   
     487               14:   BranchDestroy(C, this, SubExprs, END_EXPR);
     488               14: }
     489                 : 
     490                0: void WhileStmt::DoDestroy(ASTContext &C) {
     491                0:   BranchDestroy(C, this, SubExprs, END_EXPR);
     492                0: }
     493                 : 
     494                7: void AsmStmt::DoDestroy(ASTContext &C) {
     495                7:   DestroyChildren(C);
     496                 :   
     497                7:   C.Deallocate(Names);
     498                7:   C.Deallocate(Constraints);
     499                7:   C.Deallocate(Exprs);
     500                7:   C.Deallocate(Clobbers);
     501                 :   
     502                7:   this->~AsmStmt();
     503                7:   C.Deallocate((void *)this);
     504                7: }
     505                 : 
     506                 : //===----------------------------------------------------------------------===//
     507                 : //  Child Iterators for iterating over subexpressions/substatements
     508                 : //===----------------------------------------------------------------------===//
     509                 : 
     510                 : // DeclStmt
     511             3729: Stmt::child_iterator DeclStmt::child_begin() {
     512             3729:   return StmtIterator(DG.begin(), DG.end());
     513                 : }
     514                 : 
     515             3729: Stmt::child_iterator DeclStmt::child_end() {
     516             3729:   return StmtIterator(DG.end(), DG.end());
     517                 : }
     518                 : 
     519                 : // NullStmt
     520               79: Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
     521               79: Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
     522                 : 
     523                 : // CompoundStmt
     524             2559: Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
     525             2559: Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
     526                 : 
     527                 : // CaseStmt
     528              129: Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
     529              129: Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
     530                 : 
     531                 : // DefaultStmt
     532               15: Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
     533               15: Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
     534                 : 
     535                 : // LabelStmt
     536               54: Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
     537               54: Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
     538                 : 
     539                 : // IfStmt
     540              379: Stmt::child_iterator IfStmt::child_begin() {
     541              379:   return child_iterator(Var, &SubExprs[0]);
     542                 : }
     543              379: Stmt::child_iterator IfStmt::child_end() {
     544              379:   return child_iterator(0, &SubExprs[0]+END_EXPR);
     545                 : }
     546                 : 
     547                 : // SwitchStmt
     548               26: Stmt::child_iterator SwitchStmt::child_begin() {
     549               26:   return child_iterator(Var, &SubExprs[0]);
     550                 : }
     551               26: Stmt::child_iterator SwitchStmt::child_end() {
     552               26:   return child_iterator(0, &SubExprs[0]+END_EXPR);
     553                 : }
     554                 : 
     555                 : // WhileStmt
     556               38: Stmt::child_iterator WhileStmt::child_begin() {
     557               38:   return child_iterator(Var, &SubExprs[0]);
     558                 : }
     559               38: Stmt::child_iterator WhileStmt::child_end() {
     560               38:   return child_iterator(0, &SubExprs[0]+END_EXPR);
     561                 : }
     562                 : 
     563                 : // DoStmt
     564               24: Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
     565               24: Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
     566                 : 
     567                 : // ForStmt
     568               43: Stmt::child_iterator ForStmt::child_begin() {
     569               43:   return child_iterator(CondVar, &SubExprs[0]);
     570                 : }
     571               43: Stmt::child_iterator ForStmt::child_end() {
     572               43:   return child_iterator(0, &SubExprs[0]+END_EXPR);
     573                 : }
     574                 : 
     575                 : // ObjCForCollectionStmt
     576               64: Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
     577               64:   return &SubExprs[0];
     578                 : }
     579               64: Stmt::child_iterator ObjCForCollectionStmt::child_end() {
     580               64:   return &SubExprs[0]+END_EXPR;
     581                 : }
     582                 : 
     583                 : // GotoStmt
     584               74: Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
     585               74: Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
     586                 : 
     587                 : // IndirectGotoStmt
     588               61: Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
     589               12: const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
     590                 : 
     591                4: Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
     592                4: Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
     593                 : 
     594                 : // ContinueStmt
     595               12: Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
     596               12: Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
     597                 : 
     598                 : // BreakStmt
     599              147: Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
     600              147: Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
     601                 : 
     602                 : // ReturnStmt
     603             4579: const Expr* ReturnStmt::getRetValue() const {
     604             4579:   return cast_or_null<Expr>(RetExpr);
     605                 : }
     606             2927: Expr* ReturnStmt::getRetValue() {
     607             2927:   return cast_or_null<Expr>(RetExpr);
     608                 : }
     609                 : 
     610            11564: Stmt::child_iterator ReturnStmt::child_begin() {
     611            11564:   return &RetExpr;
     612                 : }
     613            11564: Stmt::child_iterator ReturnStmt::child_end() {
                     9978: branch 0 taken
                     1586: branch 1 taken
     614            11564:   return RetExpr ? &RetExpr+1 : &RetExpr;
     615                 : }
     616                 : 
     617                 : // AsmStmt
     618               18: Stmt::child_iterator AsmStmt::child_begin() {
                       13: branch 0 taken
                        5: branch 1 taken
     619               18:   return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0];
     620                 : }
     621               18: Stmt::child_iterator AsmStmt::child_end() {
                       13: branch 0 taken
                        5: branch 1 taken
     622               18:   return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0] + NumOutputs + NumInputs;
     623                 : }
     624                 : 
     625                 : // ObjCAtCatchStmt
     626               15: Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
     627               15: Stmt::child_iterator ObjCAtCatchStmt::child_end() {
     628               15:   return &SubExprs[0]+END_EXPR;
     629                 : }
     630                 : 
     631                 : // ObjCAtFinallyStmt
     632               30: Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
     633               30: Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
     634                 : 
     635                 : // ObjCAtTryStmt
     636               18: Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
     637               18: Stmt::child_iterator ObjCAtTryStmt::child_end()   {
     638               18:   return &SubStmts[0]+END_EXPR;
     639                 : }
     640                 : 
     641                 : // ObjCAtThrowStmt
     642               30: Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
     643               30:   return &Throw;
     644                 : }
     645                 : 
     646               30: Stmt::child_iterator ObjCAtThrowStmt::child_end() {
     647               30:   return &Throw+1;
     648                 : }
     649                 : 
     650                 : // ObjCAtSynchronizedStmt
     651               11: Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
     652               11:   return &SubStmts[0];
     653                 : }
     654                 : 
     655               11: Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
     656               11:   return &SubStmts[0]+END_EXPR;
     657                 : }
     658                 : 
     659                 : // CXXCatchStmt
     660               18: Stmt::child_iterator CXXCatchStmt::child_begin() {
     661               18:   return &HandlerBlock;
     662                 : }
     663                 : 
     664               18: Stmt::child_iterator CXXCatchStmt::child_end() {
     665               18:   return &HandlerBlock + 1;
     666                 : }
     667                 : 
     668                 : // CXXTryStmt
     669               10: Stmt::child_iterator CXXTryStmt::child_begin() {
     670               10:   return reinterpret_cast<Stmt **>(this + 1);
     671                 : }
     672                 : 
     673               10: Stmt::child_iterator CXXTryStmt::child_end() {
     674               10:   return reinterpret_cast<Stmt **>(this + 1) + NumHandlers + 1;
     675                 : }

Generated: 2010-02-10 01:31 by zcov