zcov: / lib/Sema/SemaStmt.cpp


Files: 1 Branches Taken: 85.0% 596 / 701
Generated: 2010-02-10 01:31 Branches Executed: 98.6% 691 / 701
Line Coverage: 96.1% 716 / 745


Programs: 2 Runs 3018


       1                 : //===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//
       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 semantic analysis for statements.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "Sema.h"
      15                 : #include "SemaInit.h"
      16                 : #include "clang/AST/APValue.h"
      17                 : #include "clang/AST/ASTContext.h"
      18                 : #include "clang/AST/DeclObjC.h"
      19                 : #include "clang/AST/ExprCXX.h"
      20                 : #include "clang/AST/ExprObjC.h"
      21                 : #include "clang/AST/StmtObjC.h"
      22                 : #include "clang/AST/StmtCXX.h"
      23                 : #include "clang/Lex/Preprocessor.h"
      24                 : #include "clang/Basic/TargetInfo.h"
      25                 : #include "llvm/ADT/STLExtras.h"
      26                 : #include "llvm/ADT/SmallVector.h"
      27                 : using namespace clang;
      28                 : 
      29             8726: Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
      30             8726:   Expr *E = expr->takeAs<Expr>();
                        0: branch 0 not taken
                     8726: branch 1 taken
      31             8726:   assert(E && "ActOnExprStmt(): missing expression");
                        1: branch 3 taken
                     8725: branch 4 taken
      32             8726:   if (E->getType()->isObjCInterfaceType()) {
                        1: branch 0 taken
                        0: branch 1 not taken
      33                1:     if (LangOpts.ObjCNonFragileABI)
      34                 :       Diag(E->getLocEnd(), diag::err_indirection_requires_nonfragile_object)
      35                1:              << E->getType();
      36                 :     else
      37                 :       Diag(E->getLocEnd(), diag::err_direct_interface_unsupported)
      38                0:              << E->getType();
      39                1:     return StmtError();
      40                 :   }
      41                 :   // C99 6.8.3p2: The expression in an expression statement is evaluated as a
      42                 :   // void expression for its side effects.  Conversion to void allows any
      43                 :   // operand, even incomplete types.
      44                 : 
      45                 :   // Same thing in for stmt first clause (when expr) and third clause.
      46             8725:   return Owned(static_cast<Stmt*>(E));
      47                 : }
      48                 : 
      49                 : 
      50              268: Sema::OwningStmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
                      268: branch 1 taken
                        0: branch 2 not taken
      51              268:   return Owned(new (Context) NullStmt(SemiLoc));
      52                 : }
      53                 : 
      54                 : Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
      55                 :                                            SourceLocation StartLoc,
      56             7090:                                            SourceLocation EndLoc) {
      57             7090:   DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
      58                 : 
      59                 :   // If we have an invalid decl, just return an error.
                       78: branch 1 taken
                     7012: branch 2 taken
      60             7090:   if (DG.isNull()) return StmtError();
      61                 : 
                     7012: branch 1 taken
                        0: branch 2 not taken
      62             7012:   return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
      63                 : }
      64                 : 
      65               30: void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
      66               30:   DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
      67                 :   
      68                 :   // If we have an invalid decl, just return.
                       30: branch 1 taken
                        0: branch 2 not taken
                        1: branch 4 taken
                       29: branch 5 taken
                       29: branch 6 taken
                        1: branch 7 taken
      69               30:   if (DG.isNull() || !DG.isSingleDecl()) return;
      70                 :   // suppress any potential 'unused variable' warning.
      71               29:   DG.getSingleDecl()->setUsed();
      72                 : }
      73                 : 
      74            25918: void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
      75            25918:   const Expr *E = dyn_cast_or_null<Expr>(S);
                    17226: branch 0 taken
                     8692: branch 1 taken
      76            25918:   if (!E)
      77            17226:     return;
      78                 : 
      79                 :   // Ignore expressions that have void type.
                     3124: branch 3 taken
                     5568: branch 4 taken
      80             8692:   if (E->getType()->isVoidType())
      81             3124:     return;
      82                 : 
      83             5568:   SourceLocation Loc;
      84             5568:   SourceRange R1, R2;
                     5446: branch 1 taken
                      122: branch 2 taken
      85             5568:   if (!E->isUnusedResultAWarning(Loc, R1, R2, Context))
      86             5446:     return;
      87                 : 
      88                 :   // Okay, we have an unused result.  Depending on what the base expression is,
      89                 :   // we might want to make a more specific diagnostic.  Check for one of these
      90                 :   // cases now.
      91              122:   unsigned DiagID = diag::warn_unused_expr;
      92              122:   E = E->IgnoreParens();
                        1: branch 1 taken
                      121: branch 2 taken
      93              122:   if (isa<ObjCImplicitSetterGetterRefExpr>(E))
      94                1:     DiagID = diag::warn_unused_property_expr;
      95                 :   
                       11: branch 1 taken
                      111: branch 2 taken
      96              122:   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
      97                 :     // If the callee has attribute pure, const, or warn_unused_result, warn with
      98                 :     // a more specific message to make it clear what is happening.
                       11: branch 1 taken
                        0: branch 2 not taken
      99               11:     if (const Decl *FD = CE->getCalleeDecl()) {
                        5: branch 1 taken
                        6: branch 2 taken
     100               11:       if (FD->getAttr<WarnUnusedResultAttr>()) {
     101                5:         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
     102                5:         return;
     103                 :       }
                        1: branch 1 taken
                        5: branch 2 taken
     104                6:       if (FD->getAttr<PureAttr>()) {
     105                1:         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
     106                1:         return;
     107                 :       }
                        5: branch 1 taken
                        0: branch 2 not taken
     108                5:       if (FD->getAttr<ConstAttr>()) {
     109                5:         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
     110                5:         return;
     111                 :       }
     112                 :     }        
     113                 :   }
     114                 : 
     115              111:   Diag(Loc, DiagID) << R1 << R2;
     116                 : }
     117                 : 
     118                 : Action::OwningStmtResult
     119                 : Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
     120            11121:                         MultiStmtArg elts, bool isStmtExpr) {
     121            11121:   unsigned NumElts = elts.size();
     122            11121:   Stmt **Elts = reinterpret_cast<Stmt**>(elts.release());
     123                 :   // If we're in C89 mode, check that we don't have any decls after stmts.  If
     124                 :   // so, emit an extension diagnostic.
                     4142: branch 1 taken
                     6979: branch 2 taken
                       56: branch 4 taken
                     4086: branch 5 taken
                       56: branch 6 taken
                    11065: branch 7 taken
     125            11121:   if (!getLangOptions().C99 && !getLangOptions().CPlusPlus) {
     126                 :     // Note that __extension__ can be around a decl.
     127               56:     unsigned i = 0;
     128                 :     // Skip over all declarations.
                       59: branch 0 taken
                       15: branch 1 taken
                       18: branch 3 taken
                       41: branch 4 taken
                       18: branch 5 taken
                       56: branch 6 taken
     129               56:     for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
     130                 :       /*empty*/;
     131                 : 
     132                 :     // We found the end of the list or a statement.  Scan for another declstmt.
                       51: branch 0 taken
                       53: branch 1 taken
                       48: branch 3 taken
                        3: branch 4 taken
                       48: branch 5 taken
                       56: branch 6 taken
     133               56:     for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
     134                 :       /*empty*/;
     135                 : 
                        3: branch 0 taken
                       53: branch 1 taken
     136               56:     if (i != NumElts) {
     137                3:       Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
     138                3:       Diag(D->getLocation(), diag::ext_mixed_decls_code);
     139                 :     }
     140                 :   }
     141                 :   // Warn about unused expressions in statements.
                    21921: branch 0 taken
                    11121: branch 1 taken
     142            33042:   for (unsigned i = 0; i != NumElts; ++i) {
     143                 :     // Ignore statements that are last in a statement expression.
                       72: branch 0 taken
                    21849: branch 1 taken
                       58: branch 2 taken
                       14: branch 3 taken
     144            21921:     if (isStmtExpr && i == NumElts - 1)
     145               58:       continue;
     146                 : 
     147            21863:     DiagnoseUnusedExprResult(Elts[i]);
     148                 :   }
     149                 : 
                    11121: branch 1 taken
                        0: branch 2 not taken
     150            11121:   return Owned(new (Context) CompoundStmt(Context, Elts, NumElts, L, R));
     151                 : }
     152                 : 
     153                 : Action::OwningStmtResult
     154                 : Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprArg lhsval,
     155                 :                     SourceLocation DotDotDotLoc, ExprArg rhsval,
     156              315:                     SourceLocation ColonLoc) {
                      315: branch 1 taken
                        0: branch 2 not taken
     157              315:   assert((lhsval.get() != 0) && "missing expression in case statement");
     158                 : 
     159                 :   // C99 6.8.4.2p3: The expression shall be an integer constant.
     160                 :   // However, GCC allows any evaluatable integer expression.
     161              315:   Expr *LHSVal = static_cast<Expr*>(lhsval.get());
                      315: branch 1 taken
                        0: branch 2 not taken
                      310: branch 4 taken
                        5: branch 5 taken
                        5: branch 7 taken
                      305: branch 8 taken
                        5: branch 9 taken
                      310: branch 10 taken
     162              630:   if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent() &&
     163                 :       VerifyIntegerConstantExpression(LHSVal))
     164                5:     return StmtError();
     165                 : 
     166                 :   // GCC extension: The expression shall be an integer constant.
     167                 : 
     168              310:   Expr *RHSVal = static_cast<Expr*>(rhsval.get());
                       42: branch 0 taken
                      268: branch 1 taken
                       42: branch 3 taken
                        0: branch 4 not taken
                       42: branch 6 taken
                        0: branch 7 not taken
                        2: branch 9 taken
                       40: branch 10 taken
                        2: branch 11 taken
                      308: branch 12 taken
     169              310:   if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent() &&
     170                 :       VerifyIntegerConstantExpression(RHSVal)) {
     171                2:     RHSVal = 0;  // Recover by just forgetting about it.
     172                2:     rhsval = 0;
     173                 :   }
     174                 : 
                        1: branch 2 taken
                      309: branch 3 taken
     175              310:   if (getSwitchStack().empty()) {
     176                1:     Diag(CaseLoc, diag::err_case_not_in_switch);
     177                1:     return StmtError();
     178                 :   }
     179                 : 
     180                 :   // Only now release the smart pointers.
     181              309:   lhsval.release();
     182              309:   rhsval.release();
     183                 :   CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
                      309: branch 1 taken
                        0: branch 2 not taken
     184              309:                                         ColonLoc);
     185              309:   getSwitchStack().back()->addSwitchCase(CS);
     186              309:   return Owned(CS);
     187                 : }
     188                 : 
     189                 : /// ActOnCaseStmtBody - This installs a statement as the body of a case.
     190              309: void Sema::ActOnCaseStmtBody(StmtTy *caseStmt, StmtArg subStmt) {
     191              309:   CaseStmt *CS = static_cast<CaseStmt*>(caseStmt);
     192              309:   Stmt *SubStmt = subStmt.takeAs<Stmt>();
     193              309:   CS->setSubStmt(SubStmt);
     194              309: }
     195                 : 
     196                 : Action::OwningStmtResult
     197                 : Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
     198               54:                        StmtArg subStmt, Scope *CurScope) {
     199               54:   Stmt *SubStmt = subStmt.takeAs<Stmt>();
     200                 : 
                        2: branch 2 taken
                       52: branch 3 taken
     201               54:   if (getSwitchStack().empty()) {
     202                2:     Diag(DefaultLoc, diag::err_default_not_in_switch);
     203                2:     return Owned(SubStmt);
     204                 :   }
     205                 : 
                       52: branch 1 taken
                        0: branch 2 not taken
     206               52:   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
     207               52:   getSwitchStack().back()->addSwitchCase(DS);
     208               52:   return Owned(DS);
     209                 : }
     210                 : 
     211                 : Action::OwningStmtResult
     212                 : Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
     213              152:                      SourceLocation ColonLoc, StmtArg subStmt) {
     214              152:   Stmt *SubStmt = subStmt.takeAs<Stmt>();
     215                 :   // Look up the record for this label identifier.
     216              152:   LabelStmt *&LabelDecl = getLabelMap()[II];
     217                 : 
     218                 :   // If not forward referenced or defined already, just create a new LabelStmt.
                       58: branch 0 taken
                       94: branch 1 taken
     219              152:   if (LabelDecl == 0)
                       58: branch 1 taken
                        0: branch 2 not taken
     220               58:     return Owned(LabelDecl = new (Context) LabelStmt(IdentLoc, II, SubStmt));
     221                 : 
                       94: branch 1 taken
                        0: branch 2 not taken
     222               94:   assert(LabelDecl->getID() == II && "Label mismatch!");
     223                 : 
     224                 :   // Otherwise, this label was either forward reference or multiply defined.  If
     225                 :   // multiply defined, reject it now.
                        0: branch 1 not taken
                       94: branch 2 taken
     226               94:   if (LabelDecl->getSubStmt()) {
     227                0:     Diag(IdentLoc, diag::err_redefinition_of_label) << LabelDecl->getID();
     228                0:     Diag(LabelDecl->getIdentLoc(), diag::note_previous_definition);
     229                0:     return Owned(SubStmt);
     230                 :   }
     231                 : 
     232                 :   // Otherwise, this label was forward declared, and we just found its real
     233                 :   // definition.  Fill in the forward definition and return it.
     234               94:   LabelDecl->setIdentLoc(IdentLoc);
     235               94:   LabelDecl->setSubStmt(SubStmt);
     236               94:   return Owned(LabelDecl);
     237                 : }
     238                 : 
     239                 : Action::OwningStmtResult
     240                 : Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
     241                 :                   StmtArg ThenVal, SourceLocation ElseLoc,
     242             1556:                   StmtArg ElseVal) {
     243             1556:   OwningExprResult CondResult(CondVal.release());
     244                 : 
     245             1556:   VarDecl *ConditionVar = 0;
                       25: branch 1 taken
                     1531: branch 2 taken
     246             1556:   if (CondVar.get()) {
     247               25:     ConditionVar = CondVar.getAs<VarDecl>();
     248               25:     CondResult = CheckConditionVariable(ConditionVar);
                        0: branch 1 not taken
                       25: branch 2 taken
     249               25:     if (CondResult.isInvalid())
     250                0:       return StmtError();
     251                 :   }
     252             1556:   Expr *ConditionExpr = CondResult.takeAs<Expr>();
                        0: branch 0 not taken
                     1556: branch 1 taken
     253             1556:   if (!ConditionExpr)
     254                0:     return StmtError();
     255                 :   
                        2: branch 1 taken
                     1554: branch 2 taken
     256             1556:   if (CheckBooleanCondition(ConditionExpr, IfLoc)) {
     257                2:     CondResult = ConditionExpr;
     258                2:     return StmtError();
     259                 :   }
     260                 : 
     261             1554:   Stmt *thenStmt = ThenVal.takeAs<Stmt>();
     262             1554:   DiagnoseUnusedExprResult(thenStmt);
     263                 : 
     264                 :   // Warn if the if block has a null body without an else value.
     265                 :   // this helps prevent bugs due to typos, such as
     266                 :   // if (condition);
     267                 :   //   do_stuff();
                     1352: branch 1 taken
                      202: branch 2 taken
     268             1554:   if (!ElseVal.get()) {
                        7: branch 1 taken
                     1345: branch 2 taken
     269             1352:     if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
     270                7:       Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
     271                 :   }
     272                 : 
     273             1554:   Stmt *elseStmt = ElseVal.takeAs<Stmt>();
     274             1554:   DiagnoseUnusedExprResult(elseStmt);
     275                 : 
     276             1554:   CondResult.release();
     277                 :   return Owned(new (Context) IfStmt(IfLoc, ConditionVar, ConditionExpr, 
                     1554: branch 1 taken
                        0: branch 2 not taken
     278             1554:                                     thenStmt, ElseLoc, elseStmt));
     279                 : }
     280                 : 
     281                 : Action::OwningStmtResult
     282              139: Sema::ActOnStartOfSwitchStmt(FullExprArg cond, DeclPtrTy CondVar) {
     283              139:   OwningExprResult CondResult(cond.release());
     284                 :   
     285              139:   VarDecl *ConditionVar = 0;
                        7: branch 1 taken
                      132: branch 2 taken
     286              139:   if (CondVar.get()) {
     287                7:     ConditionVar = CondVar.getAs<VarDecl>();
     288                7:     CondResult = CheckConditionVariable(ConditionVar);
                        0: branch 1 not taken
                        7: branch 2 taken
     289                7:     if (CondResult.isInvalid())
     290                0:       return StmtError();
     291                 :   }
     292                 :   SwitchStmt *SS = new (Context) SwitchStmt(ConditionVar, 
                      139: branch 2 taken
                        0: branch 3 not taken
     293              139:                                             CondResult.takeAs<Expr>());
     294              139:   getSwitchStack().push_back(SS);
     295              139:   return Owned(SS);
     296                 : }
     297                 : 
     298                 : /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
     299                 : /// the specified width and sign.  If an overflow occurs, detect it and emit
     300                 : /// the specified diagnostic.
     301                 : void Sema::ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &Val,
     302                 :                                               unsigned NewWidth, bool NewSign,
     303                 :                                               SourceLocation Loc,
     304              333:                                               unsigned DiagID) {
     305                 :   // Perform a conversion to the promoted condition type if needed.
                        1: branch 1 taken
                      332: branch 2 taken
     306              333:   if (NewWidth > Val.getBitWidth()) {
     307                 :     // If this is an extension, just do it.
     308                1:     llvm::APSInt OldVal(Val);
     309                1:     Val.extend(NewWidth);
     310                 : 
     311                 :     // If the input was signed and negative and the output is unsigned,
     312                 :     // warn.
                        0: branch 0 not taken
                        1: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        1: branch 9 taken
     313                1:     if (!NewSign && OldVal.isSigned() && OldVal.isNegative())
     314                0:       Diag(Loc, DiagID) << OldVal.toString(10) << Val.toString(10);
     315                 : 
     316                1:     Val.setIsSigned(NewSign);
                        9: branch 1 taken
                      323: branch 2 taken
     317              332:   } else if (NewWidth < Val.getBitWidth()) {
     318                 :     // If this is a truncation, check for overflow.
     319                9:     llvm::APSInt ConvVal(Val);
     320                9:     ConvVal.trunc(NewWidth);
     321                9:     ConvVal.setIsSigned(NewSign);
     322                9:     ConvVal.extend(Val.getBitWidth());
     323                9:     ConvVal.setIsSigned(Val.isSigned());
                        3: branch 1 taken
                        6: branch 2 taken
     324                9:     if (ConvVal != Val)
     325                3:       Diag(Loc, DiagID) << Val.toString(10) << ConvVal.toString(10);
     326                 : 
     327                 :     // Regardless of whether a diagnostic was emitted, really do the
     328                 :     // truncation.
     329                9:     Val.trunc(NewWidth);
     330                9:     Val.setIsSigned(NewSign);
                       60: branch 1 taken
                      263: branch 2 taken
     331              323:   } else if (NewSign != Val.isSigned()) {
     332                 :     // Convert the sign to match the sign of the condition.  This can cause
     333                 :     // overflow as well: unsigned(INTMIN)
     334               60:     llvm::APSInt OldVal(Val);
     335               60:     Val.setIsSigned(NewSign);
     336                 : 
                        1: branch 1 taken
                       59: branch 2 taken
     337               60:     if (Val.isNegative())  // Sign bit changes meaning.
     338                1:       Diag(Loc, DiagID) << OldVal.toString(10) << Val.toString(10);
     339                 :   }
     340              333: }
     341                 : 
     342                 : namespace {
     343                 :   struct CaseCompareFunctor {
     344                 :     bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
     345               28:                     const llvm::APSInt &RHS) {
     346               28:       return LHS.first < RHS;
     347                 :     }
     348                 :     bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
     349                 :                     const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
     350                 :       return LHS.first < RHS.first;
     351                 :     }
     352                 :     bool operator()(const llvm::APSInt &LHS,
     353               12:                     const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
     354               12:       return LHS < RHS.first;
     355                 :     }
     356                 :   };
     357                 : }
     358                 : 
     359                 : /// CmpCaseVals - Comparison predicate for sorting case values.
     360                 : ///
     361                 : static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
     362              230:                         const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
                      222: branch 1 taken
                        8: branch 2 taken
     363              230:   if (lhs.first < rhs.first)
     364              222:     return true;
     365                 : 
                        2: branch 1 taken
                        6: branch 2 taken
                        2: branch 7 taken
                        0: branch 8 not taken
                        2: branch 9 taken
                        6: branch 10 taken
     366                8:   if (lhs.first == rhs.first &&
     367                 :       lhs.second->getCaseLoc().getRawEncoding()
     368                 :        < rhs.second->getCaseLoc().getRawEncoding())
     369                2:     return true;
     370                6:   return false;
     371                 : }
     372                 : 
     373                 : /// CmpEnumVals - Comparison predicate for sorting enumeration values.
     374                 : ///
     375                 : static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
     376               47:                         const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
     377                 : {
     378               47:   return lhs.first < rhs.first;
     379                 : }
     380                 : 
     381                 : /// EqEnumVals - Comparison preficate for uniqing enumeration values.
     382                 : ///
     383                 : static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
     384               31:                        const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
     385                 : {
     386               31:   return lhs.first == rhs.first;
     387                 : }
     388                 : 
     389                 : /// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of
     390                 : /// potentially integral-promoted expression @p expr.
     391              137: static QualType GetTypeBeforeIntegralPromotion(const Expr* expr) {
     392                 :   const ImplicitCastExpr *ImplicitCast =
     393              137:       dyn_cast_or_null<ImplicitCastExpr>(expr);
                        0: branch 0 not taken
                      137: branch 1 taken
     394              137:   if (ImplicitCast != NULL) {
     395                0:     const Expr *ExprBeforePromotion = ImplicitCast->getSubExpr();
     396                0:     QualType TypeBeforePromotion = ExprBeforePromotion->getType();
                        0: branch 2 not taken
                        0: branch 3 not taken
     397                0:     if (TypeBeforePromotion->isIntegralType()) {
     398                0:       return TypeBeforePromotion;
     399                 :     }
     400                 :   }
     401              137:   return expr->getType();
     402                 : }
     403                 : 
     404                 : /// \brief Check (and possibly convert) the condition in a switch
     405                 : /// statement in C++.
     406                 : static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
     407               38:                                     Expr *&CondExpr) {
                        2: branch 1 taken
                       36: branch 2 taken
     408               38:   if (CondExpr->isTypeDependent())
     409                2:     return false;
     410                 : 
     411               36:   QualType CondType = CondExpr->getType();
     412                 : 
     413                 :   // C++ 6.4.2.p2:
     414                 :   // The condition shall be of integral type, enumeration type, or of a class
     415                 :   // type for which a single conversion function to integral or enumeration
     416                 :   // type exists (12.3). If the condition is of class type, the condition is
     417                 :   // converted by calling that conversion function, and the result of the
     418                 :   // conversion is used in place of the original condition for the remainder
     419                 :   // of this section. Integral promotions are performed.
     420                 : 
     421                 :   // Make sure that the condition expression has a complete type,
     422                 :   // otherwise we'll never find any conversions.
                        1: branch 10 taken
                       35: branch 11 taken
     423               36:   if (S.RequireCompleteType(SwitchLoc, CondType,
     424                 :                             PDiag(diag::err_switch_incomplete_class_type)
     425                 :                               << CondExpr->getSourceRange()))
     426                1:     return true;
     427                 : 
     428               35:   llvm::SmallVector<CXXConversionDecl *, 4> ViableConversions;
     429               35:   llvm::SmallVector<CXXConversionDecl *, 4> ExplicitConversions;
                        7: branch 2 taken
                       28: branch 3 taken
     430               35:   if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
     431                 :     const UnresolvedSetImpl *Conversions
     432                 :       = cast<CXXRecordDecl>(RecordTy->getDecl())
     433                7:                                              ->getVisibleConversionFunctions();
                        7: branch 3 taken
                        7: branch 4 taken
     434               21:     for (UnresolvedSetImpl::iterator I = Conversions->begin(),
     435                7:            E = Conversions->end(); I != E; ++I) {
                        7: branch 2 taken
                        0: branch 3 not taken
     436                7:       if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(*I))
                        7: branch 4 taken
                        0: branch 5 not taken
     437                7:         if (Conversion->getConversionType().getNonReferenceType()
     438                 :               ->isIntegralType()) {
                        2: branch 1 taken
                        5: branch 2 taken
     439                7:           if (Conversion->isExplicit())
     440                2:             ExplicitConversions.push_back(Conversion);
     441                 :           else
     442                5:           ViableConversions.push_back(Conversion);
     443                 :         }
     444                 :     }
     445                 : 
                        3: branch 1 taken
                        3: branch 2 taken
                        1: branch 3 taken
     446                7:     switch (ViableConversions.size()) {
     447                 :     case 0:
                        2: branch 1 taken
                        1: branch 2 taken
     448                3:       if (ExplicitConversions.size() == 1) {
     449                 :         // The user probably meant to invoke the given explicit
     450                 :         // conversion; use it.
     451                 :         QualType ConvTy
     452                 :           = ExplicitConversions[0]->getConversionType()
     453                2:                         .getNonReferenceType();
     454                2:         std::string TypeStr;
     455                2:         ConvTy.getAsStringInternal(TypeStr, S.Context.PrintingPolicy);
     456                 : 
     457                 :         S.Diag(SwitchLoc, diag::err_switch_explicit_conversion)
     458                 :           << CondType << ConvTy << CondExpr->getSourceRange()
     459                 :           << CodeModificationHint::CreateInsertion(CondExpr->getLocStart(),
     460                 :                                          "static_cast<" + TypeStr + ">(")
     461                 :           << CodeModificationHint::CreateInsertion(
     462                 :                             S.PP.getLocForEndOfToken(CondExpr->getLocEnd()),
     463                2:                                ")");
     464                 :         S.Diag(ExplicitConversions[0]->getLocation(),
     465                 :              diag::note_switch_conversion)
     466                2:           << ConvTy->isEnumeralType() << ConvTy;
     467                 : 
     468                 :         // If we aren't in a SFINAE context, build a call to the 
     469                 :         // explicit conversion function.
                        0: branch 1 not taken
                        2: branch 2 taken
     470                2:         if (S.isSFINAEContext())
     471                0:           return true;
     472                 : 
                        2: branch 3 taken
                        0: branch 4 not taken
     473                2:         CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ExplicitConversions[0]);
     474                 :       }
     475                 : 
     476                 :       // We'll complain below about a non-integral condition type.
     477                3:       break;
     478                 : 
     479                 :     case 1:
     480                 :       // Apply this conversion.
     481                3:       CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ViableConversions[0]);
     482                3:       break;
     483                 : 
     484                 :     default:
     485                 :       S.Diag(SwitchLoc, diag::err_switch_multiple_conversions)
     486                1:         << CondType << CondExpr->getSourceRange();
                        2: branch 1 taken
                        1: branch 2 taken
     487                3:       for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
     488                 :         QualType ConvTy
     489                2:           = ViableConversions[I]->getConversionType().getNonReferenceType();
     490                 :         S.Diag(ViableConversions[I]->getLocation(),
     491                 :              diag::note_switch_conversion)
     492                2:           << ConvTy->isEnumeralType() << ConvTy;
     493                 :       }
     494                1:       return true;
     495                 :     }
     496                 :   } 
     497                 : 
     498               34:   return false;
     499                 : }
     500                 : 
     501                 : /// ActOnSwitchBodyError - This is called if there is an error parsing the
     502                 : /// body of the switch stmt instead of ActOnFinishSwitchStmt.
     503                 : void Sema::ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
     504                2:                                 StmtArg Body) {
     505                 :   // Keep the switch stack balanced.
     506                 :   assert(getSwitchStack().back() == (SwitchStmt*)Switch.get() &&
                        2: branch 3 taken
                        0: branch 4 not taken
     507                2:          "switch stack missing push/pop!");
     508                2:   getSwitchStack().pop_back();
     509                2: }
     510                 : 
     511                 : Action::OwningStmtResult
     512                 : Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
     513              137:                             StmtArg Body) {
     514              137:   Stmt *BodyStmt = Body.takeAs<Stmt>();
     515                 : 
     516              137:   SwitchStmt *SS = getSwitchStack().back();
                      137: branch 1 taken
                        0: branch 2 not taken
     517              137:   assert(SS == (SwitchStmt*)Switch.get() && "switch stack missing push/pop!");
     518                 : 
     519              137:   SS->setBody(BodyStmt, SwitchLoc);
     520              137:   getSwitchStack().pop_back();
     521                 : 
                        0: branch 1 not taken
                      137: branch 2 taken
     522              137:   if (SS->getCond() == 0) {
     523                0:     SS->Destroy(Context);
     524                0:     return StmtError();
     525                 :   }
     526                 :     
     527              137:   Expr *CondExpr = SS->getCond();
     528                 :   QualType CondTypeBeforePromotion =
     529              137:       GetTypeBeforeIntegralPromotion(CondExpr);
     530                 : 
                       38: branch 1 taken
                       99: branch 2 taken
                        2: branch 4 taken
                       36: branch 5 taken
                        2: branch 6 taken
                      135: branch 7 taken
     531              137:   if (getLangOptions().CPlusPlus &&
     532                 :       CheckCXXSwitchCondition(*this, SwitchLoc, CondExpr))
     533                2:     return StmtError();
     534                 : 
     535                 :   // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
     536              135:   UsualUnaryConversions(CondExpr);
     537              135:   QualType CondType = CondExpr->getType();
     538              135:   SS->setCond(CondExpr);
     539                 : 
     540                 :   // C++ 6.4.2.p2:
     541                 :   // Integral promotions are performed (on the switch condition).
     542                 :   //
     543                 :   // A case value unrepresentable by the original switch condition
     544                 :   // type (before the promotion) doesn't make sense, even when it can
     545                 :   // be represented by the promoted type.  Therefore we need to find
     546                 :   // the pre-promotion type of the switch condition.
                      133: branch 1 taken
                        2: branch 2 taken
     547              135:   if (!CondExpr->isTypeDependent()) {
                        2: branch 2 taken
                      131: branch 3 taken
     548              133:     if (!CondType->isIntegerType()) { // C99 6.8.4.2p1
     549                 :       Diag(SwitchLoc, diag::err_typecheck_statement_requires_integer)
     550                2:           << CondType << CondExpr->getSourceRange();
     551                2:       return StmtError();
     552                 :     }
     553                 : 
                        2: branch 2 taken
                      129: branch 3 taken
     554              131:     if (CondTypeBeforePromotion->isBooleanType()) {
     555                 :       // switch(bool_expr) {...} is often a programmer error, e.g.
     556                 :       //   switch(n && mask) { ... }  // Doh - should be "n & mask".
     557                 :       // One can always use an if statement instead of switch(bool_expr).
     558                 :       Diag(SwitchLoc, diag::warn_bool_switch_condition)
     559                2:           << CondExpr->getSourceRange();
     560                 :     }
     561                 :   }
     562                 : 
     563                 :   // Get the bitwidth of the switched-on value before promotions.  We must
     564                 :   // convert the integer case values to this width before comparison.
     565                 :   bool HasDependentValue
                      131: branch 1 taken
                        2: branch 2 taken
                        0: branch 4 not taken
                      131: branch 5 taken
     566              133:     = CondExpr->isTypeDependent() || CondExpr->isValueDependent();
     567                 :   unsigned CondWidth
     568                 :     = HasDependentValue? 0
                        2: branch 0 taken
                      131: branch 1 taken
     569              133:       : static_cast<unsigned>(Context.getTypeSize(CondTypeBeforePromotion));
     570              133:   bool CondIsSigned = CondTypeBeforePromotion->isSignedIntegerType();
     571                 : 
     572                 :   // Accumulate all of the case values in a vector so that we can sort them
     573                 :   // and detect duplicates.  This vector contains the APInt for the case after
     574                 :   // it has been converted to the condition type.
     575                 :   typedef llvm::SmallVector<std::pair<llvm::APSInt, CaseStmt*>, 64> CaseValsTy;
     576              133:   CaseValsTy CaseVals;
     577                 : 
     578                 :   // Keep track of any GNU case ranges we see.  The APSInt is the low value.
     579                 :   typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
     580              133:   CaseRangesTy CaseRanges;
     581                 : 
     582              133:   DefaultStmt *TheDefaultStmt = 0;
     583                 : 
     584              133:   bool CaseListIsErroneous = false;
     585                 : 
                      346: branch 2 taken
                      130: branch 3 taken
                      344: branch 4 taken
                        2: branch 5 taken
     586              476:   for (SwitchCase *SC = SS->getSwitchCaseList(); SC && !HasDependentValue;
     587                 :        SC = SC->getNextSwitchCase()) {
     588                 : 
                       50: branch 1 taken
                      294: branch 2 taken
     589              344:     if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
                        1: branch 0 taken
                       49: branch 1 taken
     590               50:       if (TheDefaultStmt) {
     591                1:         Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
     592                1:         Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);
     593                 : 
     594                 :         // FIXME: Remove the default statement from the switch block so that
     595                 :         // we'll return a valid AST.  This requires recursing down the AST and
     596                 :         // finding it, not something we are set up to do right now.  For now,
     597                 :         // just lop the entire switch stmt out of the AST.
     598                1:         CaseListIsErroneous = true;
     599                 :       }
     600               50:       TheDefaultStmt = DS;
     601                 : 
     602                 :     } else {
     603              294:       CaseStmt *CS = cast<CaseStmt>(SC);
     604                 : 
     605                 :       // We already verified that the expression has a i-c-e value (C99
     606                 :       // 6.8.4.2p3) - get that value now.
     607              294:       Expr *Lo = CS->getLHS();
     608                 : 
                      294: branch 1 taken
                        0: branch 2 not taken
                        1: branch 4 taken
                      293: branch 5 taken
                        1: branch 6 taken
                      293: branch 7 taken
     609              294:       if (Lo->isTypeDependent() || Lo->isValueDependent()) {
     610                1:         HasDependentValue = true;
     611                1:         break;
     612                 :       }
     613                 : 
     614              293:       llvm::APSInt LoVal = Lo->EvaluateAsInt(Context);
     615                 : 
     616                 :       // Convert the value to the same width/sign as the condition.
     617                 :       ConvertIntegerToTypeWarnOnOverflow(LoVal, CondWidth, CondIsSigned,
     618                 :                                          CS->getLHS()->getLocStart(),
     619              293:                                          diag::warn_case_value_overflow);
     620                 : 
     621                 :       // If the LHS is not the same type as the condition, insert an implicit
     622                 :       // cast.
     623              293:       ImpCastExprToType(Lo, CondType, CastExpr::CK_IntegralCast);
     624              293:       CS->setLHS(Lo);
     625                 : 
     626                 :       // If this is a case range, remember it in CaseRanges, otherwise CaseVals.
                       40: branch 1 taken
                      253: branch 2 taken
     627              293:       if (CS->getRHS()) {
                       40: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       40: branch 7 taken
                        0: branch 8 not taken
                       40: branch 9 taken
     628               40:         if (CS->getRHS()->isTypeDependent() ||
     629                 :             CS->getRHS()->isValueDependent()) {
     630                0:           HasDependentValue = true;
     631                0:           break;
     632                 :         }
     633               40:         CaseRanges.push_back(std::make_pair(LoVal, CS));
     634                 :       } else
                      293: branch 6 taken
                        0: branch 7 not taken
     635              253:         CaseVals.push_back(std::make_pair(LoVal, CS));
     636                 :     }
     637                 :   }
     638                 : 
                      130: branch 0 taken
                        3: branch 1 taken
     639              133:   if (!HasDependentValue) {
     640                 :     // Sort all the scalar case values so we can easily detect duplicates.
     641              130:     std::stable_sort(CaseVals.begin(), CaseVals.end(), CmpCaseVals);
     642                 : 
                       95: branch 1 taken
                       35: branch 2 taken
     643              130:     if (!CaseVals.empty()) {
                      158: branch 1 taken
                       95: branch 2 taken
     644              253:       for (unsigned i = 0, e = CaseVals.size()-1; i != e; ++i) {
                        2: branch 3 taken
                      156: branch 4 taken
     645              158:         if (CaseVals[i].first == CaseVals[i+1].first) {
     646                 :           // If we have a duplicate, report it.
     647                 :           Diag(CaseVals[i+1].second->getLHS()->getLocStart(),
     648                2:                diag::err_duplicate_case) << CaseVals[i].first.toString(10);
     649                 :           Diag(CaseVals[i].second->getLHS()->getLocStart(),
     650                2:                diag::note_duplicate_case_prev);
     651                 :           // FIXME: We really want to remove the bogus case stmt from the
     652                 :           // substmt, but we have no way to do this right now.
     653                2:           CaseListIsErroneous = true;
     654                 :         }
     655                 :       }
     656                 :     }
     657                 : 
     658                 :     // Detect duplicate case ranges, which usually don't exist at all in
     659                 :     // the first place.
                       32: branch 1 taken
                       98: branch 2 taken
     660              130:     if (!CaseRanges.empty()) {
     661                 :       // Sort all the case ranges by their low value so we can easily detect
     662                 :       // overlaps between ranges.
     663               32:       std::stable_sort(CaseRanges.begin(), CaseRanges.end());
     664                 : 
     665                 :       // Scan the ranges, computing the high values and removing empty ranges.
     666               32:       std::vector<llvm::APSInt> HiVals;
                       35: branch 2 taken
                        5: branch 3 taken
                       40: branch 4 taken
                       32: branch 5 taken
     667              112:       for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
     668               40:         CaseStmt *CR = CaseRanges[i].second;
     669               40:         Expr *Hi = CR->getRHS();
     670               40:         llvm::APSInt HiVal = Hi->EvaluateAsInt(Context);
     671                 : 
     672                 :         // Convert the value to the same width/sign as the condition.
     673                 :         ConvertIntegerToTypeWarnOnOverflow(HiVal, CondWidth, CondIsSigned,
     674                 :                                            CR->getRHS()->getLocStart(),
     675               40:                                            diag::warn_case_value_overflow);
     676                 : 
     677                 :         // If the LHS is not the same type as the condition, insert an implicit
     678                 :         // cast.
     679               40:         ImpCastExprToType(Hi, CondType, CastExpr::CK_IntegralCast);
     680               40:         CR->setRHS(Hi);
     681                 : 
     682                 :         // If the low value is bigger than the high value, the case is empty.
                        5: branch 2 taken
                       35: branch 3 taken
     683               40:         if (CaseRanges[i].first > HiVal) {
     684                 :           Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range)
     685                 :             << SourceRange(CR->getLHS()->getLocStart(),
     686                5:                            CR->getRHS()->getLocEnd());
     687                5:           CaseRanges.erase(CaseRanges.begin()+i);
     688                5:           --i, --e;
     689                5:           continue;
     690                 :         }
     691               35:         HiVals.push_back(HiVal);
     692                 :       }
     693                 : 
     694                 :       // Rescan the ranges, looking for overlap with singleton values and other
     695                 :       // ranges.  Since the range list is sorted, we only need to compare case
     696                 :       // ranges with their neighbors.
                       35: branch 2 taken
                       32: branch 3 taken
     697               67:       for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
     698               35:         llvm::APSInt &CRLo = CaseRanges[i].first;
     699               35:         llvm::APSInt &CRHi = HiVals[i];
     700               35:         CaseStmt *CR = CaseRanges[i].second;
     701                 : 
     702                 :         // Check to see whether the case range overlaps with any
     703                 :         // singleton cases.
     704               35:         CaseStmt *OverlapStmt = 0;
     705               35:         llvm::APSInt OverlapVal(32);
     706                 : 
     707                 :         // Find the smallest value >= the lower bound.  If I is in the
     708                 :         // case range, then we have overlap.
     709                 :         CaseValsTy::iterator I = std::lower_bound(CaseVals.begin(),
     710                 :                                                   CaseVals.end(), CRLo,
     711               35:                                                   CaseCompareFunctor());
                        9: branch 1 taken
                       26: branch 2 taken
                        1: branch 4 taken
                        8: branch 5 taken
                        1: branch 6 taken
                       34: branch 7 taken
     712               35:         if (I != CaseVals.end() && I->first < CRHi) {
     713                1:           OverlapVal  = I->first;   // Found overlap with scalar.
     714                1:           OverlapStmt = I->second;
     715                 :         }
     716                 : 
     717                 :         // Find the smallest value bigger than the upper bound.
     718               35:         I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
                       17: branch 1 taken
                       18: branch 2 taken
                        1: branch 4 taken
                       16: branch 5 taken
                        1: branch 6 taken
                       34: branch 7 taken
     719               35:         if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
     720                1:           OverlapVal  = (I-1)->first;      // Found overlap with scalar.
     721                1:           OverlapStmt = (I-1)->second;
     722                 :         }
     723                 : 
     724                 :         // Check to see if this case stmt overlaps with the subsequent
     725                 :         // case range.
                        7: branch 0 taken
                       28: branch 1 taken
                        1: branch 4 taken
                        6: branch 5 taken
                        1: branch 6 taken
                       34: branch 7 taken
     726               35:         if (i && CRLo <= HiVals[i-1]) {
     727                1:           OverlapVal  = HiVals[i-1];       // Found overlap with range.
     728                1:           OverlapStmt = CaseRanges[i-1].second;
     729                 :         }
     730                 : 
                        2: branch 0 taken
                       33: branch 1 taken
     731               35:         if (OverlapStmt) {
     732                 :           // If we have a duplicate, report it.
     733                 :           Diag(CR->getLHS()->getLocStart(), diag::err_duplicate_case)
     734                2:             << OverlapVal.toString(10);
     735                 :           Diag(OverlapStmt->getLHS()->getLocStart(),
     736                2:                diag::note_duplicate_case_prev);
     737                 :           // FIXME: We really want to remove the bogus case stmt from the
     738                 :           // substmt, but we have no way to do this right now.
     739                2:           CaseListIsErroneous = true;
     740                 :         }
     741               32:       }
     742                 :     }
     743                 : 
     744                 :     // Check to see if switch is over an Enum and handles all of its 
     745                 :     // values  
     746              130:     const EnumType* ET = dyn_cast<EnumType>(CondTypeBeforePromotion);
     747                 :     // If switch has default case, then ignore it.
                      127: branch 0 taken
                        3: branch 1 taken
                       80: branch 2 taken
                       47: branch 3 taken
                       18: branch 4 taken
                       62: branch 5 taken
     748              130:     if (!CaseListIsErroneous && !TheDefaultStmt && ET) {
     749               18:       const EnumDecl *ED = ET->getDecl();
     750                 :       typedef llvm::SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64> EnumValsTy;
     751               18:       EnumValsTy EnumVals;
     752                 : 
     753                 :       // Gather all enum values, set their type and sort them, allowing easier comparison 
     754                 :       // with CaseVals.
                       49: branch 5 taken
                       18: branch 6 taken
     755               67:       for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(); EDI != ED->enumerator_end(); EDI++) {
     756               49:         llvm::APSInt Val = (*EDI)->getInitVal();
                        1: branch 1 taken
                       48: branch 2 taken
     757               49:         if(Val.getBitWidth() < CondWidth)
     758                1:           Val.extend(CondWidth);
     759               49:         Val.setIsSigned(CondIsSigned);
     760               49:         EnumVals.push_back(std::make_pair(Val, (*EDI)));
     761                 :       }
     762               18:       std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
     763               18:       EnumValsTy::iterator EIend = std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
     764                 :       // See which case values aren't in enum 
     765               18:       EnumValsTy::const_iterator EI = EnumVals.begin();
                       24: branch 2 taken
                       18: branch 3 taken
     766               42:       for (CaseValsTy::const_iterator CI = CaseVals.begin(); CI != CaseVals.end(); CI++) {
                       35: branch 0 taken
                        2: branch 1 taken
                       13: branch 3 taken
                       22: branch 4 taken
                       13: branch 5 taken
                       24: branch 6 taken
     767               61:         while (EI != EIend && EI->first < CI->first)
     768               13:           EI++;
                       22: branch 0 taken
                        2: branch 1 taken
                        2: branch 3 taken
                       20: branch 4 taken
                        4: branch 5 taken
                       20: branch 6 taken
     769               24:         if (EI == EIend || EI->first > CI->first)
     770                4:             Diag(CI->second->getLHS()->getExprLoc(), diag::not_in_enum) << ED->getDeclName();
     771                 :       }
     772                 :       // See which of case ranges aren't in enum
     773               18:       EI = EnumVals.begin();
                       10: branch 6 taken
                       18: branch 7 taken
                       10: branch 8 taken
                        0: branch 9 not taken
                       10: branch 10 taken
                       18: branch 11 taken
     774               28:       for (CaseRangesTy::const_iterator RI = CaseRanges.begin(); RI != CaseRanges.end() && EI != EIend; RI++) {
                       12: branch 0 taken
                        2: branch 1 taken
                        4: branch 4 taken
                        8: branch 5 taken
                        4: branch 6 taken
                       10: branch 7 taken
     775               24:         while (EI != EIend && EI->first < RI->first)
     776                4:           EI++;
     777                 :         
                        8: branch 0 taken
                        2: branch 1 taken
                        4: branch 4 taken
                        4: branch 5 taken
                        6: branch 6 taken
                        4: branch 7 taken
     778               10:         if (EI == EIend || EI->first != RI->first) {
     779                6:           Diag(RI->second->getLHS()->getExprLoc(), diag::not_in_enum) << ED->getDeclName();
     780                 :         }
     781                 : 
     782               10:         llvm::APSInt Hi = RI->second->getRHS()->EvaluateAsInt(Context);
                       14: branch 0 taken
                        4: branch 1 taken
                        8: branch 3 taken
                        6: branch 4 taken
                        8: branch 5 taken
                       10: branch 6 taken
     783               28:         while (EI != EIend && EI->first < Hi)
     784                8:           EI++;
                        6: branch 0 taken
                        4: branch 1 taken
                        2: branch 3 taken
                        4: branch 4 taken
                        6: branch 5 taken
                        4: branch 6 taken
     785               10:         if (EI == EIend || EI->first != Hi)
     786                6:           Diag(RI->second->getRHS()->getExprLoc(), diag::not_in_enum) << ED->getDeclName();
     787                 :       }
     788                 :       //Check which enum vals aren't in switch
     789               18:       CaseValsTy::const_iterator CI = CaseVals.begin();
     790               18:       CaseRangesTy::const_iterator RI = CaseRanges.begin();
     791               18:       EI = EnumVals.begin();
                       26: branch 1 taken
                       20: branch 2 taken
                       46: branch 3 taken
                       18: branch 4 taken
     792              110:       for (; EI != EIend; EI++) {
     793                 :         //Drop unneeded case values
     794               46:         llvm::APSInt CIVal;
                       36: branch 1 taken
                       24: branch 2 taken
                       14: branch 4 taken
                       22: branch 5 taken
                       14: branch 6 taken
                       46: branch 7 taken
     795              106:         while (CI != CaseVals.end() && CI->first < EI->first)
     796               14:           CI++;
     797                 :         
                       22: branch 1 taken
                       24: branch 2 taken
                       20: branch 4 taken
                        2: branch 5 taken
                       20: branch 6 taken
                       26: branch 7 taken
     798               46:         if (CI != CaseVals.end() && CI->first == EI->first)
     799               20:           continue;
     800                 : 
     801                 :         //Drop unneeded case ranges
                        3: branch 1 taken
                       12: branch 2 taken
                       15: branch 6 taken
                       14: branch 7 taken
     802               70:         for (; RI != CaseRanges.end(); RI++) {
     803               15:           llvm::APSInt Hi = RI->second->getRHS()->EvaluateAsInt(Context);
                       12: branch 1 taken
                        3: branch 2 taken
     804               15:           if (EI->first <= Hi)
     805               12:             break;
     806                 :         }
     807                 : 
                       12: branch 2 taken
                       14: branch 3 taken
                        0: branch 6 not taken
                       12: branch 7 taken
                       14: branch 8 taken
                       12: branch 9 taken
     808               26:         if (RI == CaseRanges.end() || EI->first < RI->first)
     809               14:           Diag(CondExpr->getExprLoc(), diag::warn_missing_cases) << EI->second->getDeclName();
     810               18:       }
     811                 :     }
     812                 :   }
     813                 : 
     814                 :   // FIXME: If the case list was broken is some way, we don't have a good system
     815                 :   // to patch it up.  Instead, just return the whole substmt as broken.
                        3: branch 0 taken
                      130: branch 1 taken
     816              133:   if (CaseListIsErroneous)
     817                3:     return StmtError();
     818                 : 
     819              130:   Switch.release();
     820              130:   return Owned(SS);
     821                 : }
     822                 : 
     823                 : Action::OwningStmtResult
     824                 : Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, 
     825              169:                      DeclPtrTy CondVar, StmtArg Body) {
     826              169:   OwningExprResult CondResult(Cond.release());
     827                 :   
     828              169:   VarDecl *ConditionVar = 0;
                       17: branch 1 taken
                      152: branch 2 taken
     829              169:   if (CondVar.get()) {
     830               17:     ConditionVar = CondVar.getAs<VarDecl>();
     831               17:     CondResult = CheckConditionVariable(ConditionVar);
                        1: branch 1 taken
                       16: branch 2 taken
     832               17:     if (CondResult.isInvalid())
     833                1:       return StmtError();
     834                 :   }
     835              168:   Expr *ConditionExpr = CondResult.takeAs<Expr>();
                        0: branch 0 not taken
                      168: branch 1 taken
     836              168:   if (!ConditionExpr)
     837                0:     return StmtError();
     838                 :   
                        3: branch 1 taken
                      165: branch 2 taken
     839              168:   if (CheckBooleanCondition(ConditionExpr, WhileLoc)) {
     840                3:     CondResult = ConditionExpr;
     841                3:     return StmtError();
     842                 :   }
     843                 : 
     844              165:   Stmt *bodyStmt = Body.takeAs<Stmt>();
     845              165:   DiagnoseUnusedExprResult(bodyStmt);
     846                 : 
     847              165:   CondResult.release();
     848                 :   return Owned(new (Context) WhileStmt(ConditionVar, ConditionExpr, bodyStmt, 
                      165: branch 1 taken
                        0: branch 2 not taken
     849              165:                                        WhileLoc));
     850                 : }
     851                 : 
     852                 : Action::OwningStmtResult
     853                 : Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
     854                 :                   SourceLocation WhileLoc, SourceLocation CondLParen,
     855               73:                   ExprArg Cond, SourceLocation CondRParen) {
     856               73:   Expr *condExpr = Cond.takeAs<Expr>();
                        0: branch 0 not taken
                       73: branch 1 taken
     857               73:   assert(condExpr && "ActOnDoStmt(): missing expression");
     858                 : 
                        2: branch 1 taken
                       71: branch 2 taken
     859               73:   if (CheckBooleanCondition(condExpr, DoLoc)) {
     860                2:     Cond = condExpr;
     861                2:     return StmtError();
     862                 :   }
     863                 : 
     864               71:   Stmt *bodyStmt = Body.takeAs<Stmt>();
     865               71:   DiagnoseUnusedExprResult(bodyStmt);
     866                 : 
     867               71:   Cond.release();
     868                 :   return Owned(new (Context) DoStmt(bodyStmt, condExpr, DoLoc,
                       71: branch 1 taken
                        0: branch 2 not taken
     869               71:                                     WhileLoc, CondRParen));
     870                 : }
     871                 : 
     872                 : Action::OwningStmtResult
     873                 : Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
     874                 :                    StmtArg first, FullExprArg second, DeclPtrTy secondVar,
     875                 :                    FullExprArg third,
     876              239:                    SourceLocation RParenLoc, StmtArg body) {
     877              239:   Stmt *First  = static_cast<Stmt*>(first.get());
     878                 : 
                      148: branch 1 taken
                       91: branch 2 taken
     879              239:   if (!getLangOptions().CPlusPlus) {
                       40: branch 1 taken
                      108: branch 2 taken
     880              148:     if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
     881                 :       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
     882                 :       // declare identifiers for objects having storage class 'auto' or
     883                 :       // 'register'.
                       40: branch 2 taken
                       40: branch 3 taken
     884               80:       for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
     885                 :            DI!=DE; ++DI) {
     886               40:         VarDecl *VD = dyn_cast<VarDecl>(*DI);
                       38: branch 0 taken
                        2: branch 1 taken
                       38: branch 3 taken
                        0: branch 4 not taken
                        1: branch 6 taken
                       37: branch 7 taken
                        1: branch 8 taken
                       39: branch 9 taken
     887               40:         if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage())
     888                1:           VD = 0;
                        3: branch 0 taken
                       37: branch 1 taken
     889               40:         if (VD == 0)
     890                3:           Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for);
     891                 :         // FIXME: mark decl erroneous!
     892                 :       }
     893                 :     }
     894                 :   }
     895                 : 
     896              239:   OwningExprResult SecondResult(second.release());
     897              239:   VarDecl *ConditionVar = 0;
                        8: branch 1 taken
                      231: branch 2 taken
     898              239:   if (secondVar.get()) {
     899                8:     ConditionVar = secondVar.getAs<VarDecl>();
     900                8:     SecondResult = CheckConditionVariable(ConditionVar);
                        0: branch 1 not taken
                        8: branch 2 taken
     901                8:     if (SecondResult.isInvalid())
     902                0:       return StmtError();
     903                 :   }
     904                 :   
     905              239:   Expr *Second = SecondResult.takeAs<Expr>();
                      204: branch 0 taken
                       35: branch 1 taken
                        2: branch 3 taken
                      202: branch 4 taken
                        2: branch 5 taken
                      237: branch 6 taken
     906              239:   if (Second && CheckBooleanCondition(Second, ForLoc)) {
     907                2:     SecondResult = Second;
     908                2:     return StmtError();
     909                 :   }
     910                 : 
     911              237:   Expr *Third  = third.release().takeAs<Expr>();
     912              237:   Stmt *Body  = static_cast<Stmt*>(body.get());
     913                 :   
     914              237:   DiagnoseUnusedExprResult(First);
     915              237:   DiagnoseUnusedExprResult(Third);
     916              237:   DiagnoseUnusedExprResult(Body);
     917                 : 
     918              237:   first.release();
     919              237:   body.release();
     920                 :   return Owned(new (Context) ForStmt(First, Second, ConditionVar, Third, Body, 
                      237: branch 1 taken
                        0: branch 2 not taken
     921              237:                                      ForLoc, LParenLoc, RParenLoc));
     922                 : }
     923                 : 
     924                 : Action::OwningStmtResult
     925                 : Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
     926                 :                                  SourceLocation LParenLoc,
     927                 :                                  StmtArg first, ExprArg second,
     928               54:                                  SourceLocation RParenLoc, StmtArg body) {
     929               54:   Stmt *First  = static_cast<Stmt*>(first.get());
     930               54:   Expr *Second = static_cast<Expr*>(second.get());
     931               54:   Stmt *Body  = static_cast<Stmt*>(body.get());
                       54: branch 0 taken
                        0: branch 1 not taken
     932               54:   if (First) {
     933               54:     QualType FirstType;
                       30: branch 1 taken
                       24: branch 2 taken
     934               54:     if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
                        1: branch 1 taken
                       29: branch 2 taken
     935               30:       if (!DS->isSingleDecl())
     936                 :         return StmtError(Diag((*DS->decl_begin())->getLocation(),
     937                1:                          diag::err_toomany_element_decls));
     938                 : 
     939               29:       Decl *D = DS->getSingleDecl();
     940               29:       FirstType = cast<ValueDecl>(D)->getType();
     941                 :       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
     942                 :       // declare identifiers for objects having storage class 'auto' or
     943                 :       // 'register'.
     944               29:       VarDecl *VD = cast<VarDecl>(D);
                       29: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                       29: branch 5 taken
                        0: branch 6 not taken
                       29: branch 7 taken
     945               29:       if (VD->isBlockVarDecl() && !VD->hasLocalStorage())
     946                 :         return StmtError(Diag(VD->getLocation(),
     947                0:                               diag::err_non_variable_decl_in_for));
     948                 :     } else {
                        2: branch 2 taken
                       22: branch 3 taken
     949               24:       if (cast<Expr>(First)->isLvalue(Context) != Expr::LV_Valid)
     950                 :         return StmtError(Diag(First->getLocStart(),
     951                 :                    diag::err_selector_element_not_lvalue)
     952                2:           << First->getSourceRange());
     953                 : 
     954               22:       FirstType = static_cast<Expr*>(First)->getType();
     955                 :     }
                        5: branch 2 taken
                       46: branch 3 taken
                        4: branch 6 taken
                        1: branch 7 taken
                        4: branch 8 taken
                       47: branch 9 taken
     956               51:     if (!FirstType->isObjCObjectPointerType() &&
     957                 :         !FirstType->isBlockPointerType())
     958                 :         Diag(ForLoc, diag::err_selector_element_type)
     959                4:           << FirstType << First->getSourceRange();
     960                 :   }
                       50: branch 0 taken
                        1: branch 1 taken
     961               51:   if (Second) {
     962               50:     DefaultFunctionArrayLvalueConversion(Second);
     963               50:     QualType SecondType = Second->getType();
                        2: branch 2 taken
                       48: branch 3 taken
     964               50:     if (!SecondType->isObjCObjectPointerType())
     965                 :       Diag(ForLoc, diag::err_collection_expr_type)
     966                2:         << SecondType << Second->getSourceRange();
     967                 :   }
     968               51:   first.release();
     969               51:   second.release();
     970               51:   body.release();
     971                 :   return Owned(new (Context) ObjCForCollectionStmt(First, Second, Body,
                       51: branch 1 taken
                        0: branch 2 not taken
     972               51:                                                    ForLoc, RParenLoc));
     973                 : }
     974                 : 
     975                 : Action::OwningStmtResult
     976                 : Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
     977              122:                     IdentifierInfo *LabelII) {
     978                 :   // Look up the record for this label identifier.
     979              122:   LabelStmt *&LabelDecl = getLabelMap()[LabelII];
     980                 : 
     981                 :   // If we haven't seen this label yet, create a forward reference.
                       71: branch 0 taken
                       51: branch 1 taken
     982              122:   if (LabelDecl == 0)
                       71: branch 1 taken
                        0: branch 2 not taken
     983               71:     LabelDecl = new (Context) LabelStmt(LabelLoc, LabelII, 0);
     984                 : 
                      122: branch 1 taken
                        0: branch 2 not taken
     985              122:   return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
     986                 : }
     987                 : 
     988                 : Action::OwningStmtResult
     989                 : Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
     990               34:                             ExprArg DestExp) {
     991                 :   // Convert operand to void*
     992               34:   Expr* E = DestExp.takeAs<Expr>();
                       33: branch 1 taken
                        1: branch 2 taken
     993               34:   if (!E->isTypeDependent()) {
     994               33:     QualType ETy = E->getType();
     995               33:     QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
     996                 :     AssignConvertType ConvTy =
     997               33:       CheckSingleAssignmentConstraints(DestTy, E);
                        2: branch 1 taken
                       31: branch 2 taken
     998               33:     if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
     999                2:       return StmtError();
    1000                 :   }
                       32: branch 1 taken
                        0: branch 2 not taken
    1001               32:   return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
    1002                 : }
    1003                 : 
    1004                 : Action::OwningStmtResult
    1005               30: Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
    1006               30:   Scope *S = CurScope->getContinueParent();
                        2: branch 0 taken
                       28: branch 1 taken
    1007               30:   if (!S) {
    1008                 :     // C99 6.8.6.2p1: A break shall appear only in or as a loop body.
    1009                2:     return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
    1010                 :   }
    1011                 : 
                       28: branch 1 taken
                        0: branch 2 not taken
    1012               28:   return Owned(new (Context) ContinueStmt(ContinueLoc));
    1013                 : }
    1014                 : 
    1015                 : Action::OwningStmtResult
    1016              257: Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
    1017              257:   Scope *S = CurScope->getBreakParent();
                        4: branch 0 taken
                      253: branch 1 taken
    1018              257:   if (!S) {
    1019                 :     // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
    1020                4:     return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
    1021                 :   }
    1022                 : 
                      253: branch 1 taken
                        0: branch 2 not taken
    1023              253:   return Owned(new (Context) BreakStmt(BreakLoc));
    1024                 : }
    1025                 : 
    1026                 : /// ActOnBlockReturnStmt - Utility routine to figure out block's return type.
    1027                 : ///
    1028                 : Action::OwningStmtResult
    1029               84: Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
    1030                 :   // If this is the first return we've seen in the block, infer the type of
    1031                 :   // the block from it.
                       62: branch 1 taken
                       22: branch 2 taken
    1032               84:   if (CurBlock->ReturnType.isNull()) {
                       58: branch 0 taken
                        4: branch 1 taken
    1033               62:     if (RetValExp) {
    1034                 :       // Don't call UsualUnaryConversions(), since we don't want to do
    1035                 :       // integer promotions here.
    1036               58:       DefaultFunctionArrayLvalueConversion(RetValExp);
    1037               58:       CurBlock->ReturnType = RetValExp->getType();
                        1: branch 1 taken
                       57: branch 2 taken
    1038               58:       if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(RetValExp)) {
    1039                 :         // We have to remove a 'const' added to copied-in variable which was
    1040                 :         // part of the implementation spec. and not the actual qualifier for
    1041                 :         // the variable.
                        0: branch 1 not taken
                        1: branch 2 taken
    1042                1:         if (CDRE->isConstQualAdded())
    1043                0:            CurBlock->ReturnType.removeConst();
    1044                 :       }
    1045                 :     } else
    1046                4:       CurBlock->ReturnType = Context.VoidTy;
    1047                 :   }
    1048               84:   QualType FnRetType = CurBlock->ReturnType;
    1049                 : 
                        2: branch 1 taken
                       82: branch 2 taken
    1050               84:   if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
    1051                 :     Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
    1052                2:       << getCurFunctionOrMethodDecl()->getDeclName();
    1053                2:     return StmtError();
    1054                 :   }
    1055                 : 
    1056                 :   // Otherwise, verify that this result type matches the previous one.  We are
    1057                 :   // pickier with blocks than for normal functions because we don't have GCC
    1058                 :   // compatibility to worry about here.
                        5: branch 2 taken
                       77: branch 3 taken
    1059               82:   if (CurBlock->ReturnType->isVoidType()) {
                        1: branch 0 taken
                        4: branch 1 taken
    1060                5:     if (RetValExp) {
    1061                1:       Diag(ReturnLoc, diag::err_return_block_has_expr);
    1062                1:       RetValExp->Destroy(Context);
    1063                1:       RetValExp = 0;
    1064                 :     }
                        5: branch 1 taken
                        0: branch 2 not taken
    1065                5:     return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
    1066                 :   }
    1067                 : 
                        1: branch 0 taken
                       76: branch 1 taken
    1068               77:   if (!RetValExp)
    1069                1:     return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
    1070                 : 
                       76: branch 2 taken
                        0: branch 3 not taken
                       76: branch 5 taken
                        0: branch 6 not taken
                       76: branch 7 taken
                        0: branch 8 not taken
    1071               76:   if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
    1072                 :     // we have a non-void block with an expression, continue checking
    1073                 : 
    1074                 :     // C99 6.8.6.4p3(136): The return statement is not an assignment. The
    1075                 :     // overlap restriction of subclause 6.5.16.1 does not apply to the case of
    1076                 :     // function return.
    1077                 : 
    1078                 :     // In C++ the return statement is handled via a copy initialization.
    1079                 :     // the C version of which boils down to CheckSingleAssignmentConstraints.
    1080                 :     OwningExprResult Res = PerformCopyInitialization(
    1081                 :                              InitializedEntity::InitializeResult(ReturnLoc, 
    1082                 :                                                                  FnRetType),
    1083                 :                              SourceLocation(),
    1084               76:                              Owned(RetValExp));
                        0: branch 1 not taken
                       76: branch 2 taken
    1085               76:     if (Res.isInvalid()) {
    1086                 :       // FIXME: Cleanup temporaries here, anyway?
    1087                0:       return StmtError();
    1088                 :     }
    1089                 :     
    1090               76:     RetValExp = Res.takeAs<Expr>();
                       76: branch 0 taken
                        0: branch 1 not taken
    1091               76:     if (RetValExp) 
                       76: branch 2 taken
                        0: branch 3 not taken
    1092               76:       CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
    1093                 :   }
    1094                 : 
                       76: branch 1 taken
                        0: branch 2 not taken
    1095               76:   return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
    1096                 : }
    1097                 : 
    1098                 : /// IsReturnCopyElidable - Whether returning @p RetExpr from a function that
    1099                 : /// returns a @p RetType fulfills the criteria for copy elision (C++0x 12.8p15).
    1100                 : static bool IsReturnCopyElidable(ASTContext &Ctx, QualType RetType,
    1101              103:                                  Expr *RetExpr) {
    1102              103:   QualType ExprType = RetExpr->getType();
    1103                 :   // - in a return statement in a function with ...
    1104                 :   // ... a class return type ...
                       93: branch 2 taken
                       10: branch 3 taken
    1105              103:   if (!RetType->isRecordType())
    1106               93:     return false;
    1107                 :   // ... the same cv-unqualified type as the function return type ...
                        3: branch 1 taken
                        7: branch 2 taken
    1108               10:   if (!Ctx.hasSameUnqualifiedType(RetType, ExprType))
    1109                3:     return false;
    1110                 :   // ... the expression is the name of a non-volatile automatic object ...
    1111                 :   // We ignore parentheses here.
    1112                 :   // FIXME: Is this compliant?
    1113                7:   const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetExpr->IgnoreParens());
                        1: branch 0 taken
                        6: branch 1 taken
    1114                7:   if (!DR)
    1115                1:     return false;
    1116                6:   const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
                        0: branch 0 not taken
                        6: branch 1 taken
    1117                6:   if (!VD)
    1118                0:     return false;
    1119                 :   return VD->hasLocalStorage() && !VD->getType()->isReferenceType()
                        2: branch 1 taken
                        4: branch 2 taken
                        1: branch 6 taken
                        1: branch 7 taken
                        1: branch 10 taken
                        0: branch 11 not taken
    1120                6:     && !VD->getType().isVolatileQualified();
    1121                 : }
    1122                 : 
    1123                 : Action::OwningStmtResult
    1124             4549: Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) {
    1125             4549:   Expr *RetValExp = rex.takeAs<Expr>();
                       84: branch 0 taken
                     4465: branch 1 taken
    1126             4549:   if (CurBlock)
    1127               84:     return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
    1128                 : 
    1129             4465:   QualType FnRetType;
                     3956: branch 1 taken
                      509: branch 2 taken
    1130             4465:   if (const FunctionDecl *FD = getCurFunctionDecl()) {
    1131             3956:     FnRetType = FD->getResultType();
                     3956: branch 1 taken
                        0: branch 2 not taken
                        3: branch 7 taken
                     3953: branch 8 taken
                        3: branch 9 taken
                     3953: branch 10 taken
    1132             3956:     if (FD->hasAttr<NoReturnAttr>() ||
    1133                 :         FD->getType()->getAs<FunctionType>()->getNoReturnAttr())
    1134                 :       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
    1135                3:         << getCurFunctionOrMethodDecl()->getDeclName();
                      508: branch 1 taken
                        1: branch 2 taken
    1136              509:   } else if (ObjCMethodDecl *MD = getCurMethodDecl())
    1137              508:     FnRetType = MD->getResultType();
    1138                 :   else // If we don't have a function/method context, bail.
    1139                1:     return StmtError();
    1140                 : 
                      304: branch 2 taken
                     4160: branch 3 taken
    1141             4464:   if (FnRetType->isVoidType()) {
                       19: branch 0 taken
                      285: branch 1 taken
                       17: branch 3 taken
                        2: branch 4 taken
                       17: branch 5 taken
                      287: branch 6 taken
    1142              304:     if (RetValExp && !RetValExp->isTypeDependent()) {
    1143                 :       // C99 6.8.6.4p1 (ext_ since GCC warns)
    1144               17:       unsigned D = diag::ext_return_has_expr;
                       11: branch 3 taken
                        6: branch 4 taken
    1145               17:       if (RetValExp->getType()->isVoidType())
    1146               11:         D = diag::ext_return_has_void_expr;
    1147                 : 
    1148                 :       // return (some void expression); is legal in C++.
                       11: branch 0 taken
                        6: branch 1 taken
                        6: branch 3 taken
                        5: branch 4 taken
                       12: branch 5 taken
                        5: branch 6 taken
    1149               17:       if (D != diag::ext_return_has_void_expr ||
    1150                 :           !getLangOptions().CPlusPlus) {
    1151               12:         NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
    1152                 :         Diag(ReturnLoc, D)
    1153                 :           << CurDecl->getDeclName() << isa<ObjCMethodDecl>(CurDecl)
    1154               12:           << RetValExp->getSourceRange();
    1155                 :       }
    1156                 : 
    1157               17:       RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
    1158                 :     }
                      304: branch 1 taken
                        0: branch 2 not taken
    1159              304:     return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
    1160                 :   }
    1161                 : 
                       14: branch 0 taken
                     4146: branch 1 taken
                       13: branch 4 taken
                        1: branch 5 taken
                       13: branch 6 taken
                     4147: branch 7 taken
    1162             4160:   if (!RetValExp && !FnRetType->isDependentType()) {
    1163               13:     unsigned DiagID = diag::warn_return_missing_expr;  // C90 6.6.6.4p4
    1164                 :     // C99 6.8.6.4p1 (ext_ since GCC warns)
                       12: branch 1 taken
                        1: branch 2 taken
    1165               13:     if (getLangOptions().C99) DiagID = diag::ext_return_missing_expr;
    1166                 : 
                       13: branch 1 taken
                        0: branch 2 not taken
    1167               13:     if (FunctionDecl *FD = getCurFunctionDecl())
    1168               13:       Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/;
    1169                 :     else
    1170                0:       Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
                       13: branch 1 taken
                        0: branch 2 not taken
    1171               13:     return Owned(new (Context) ReturnStmt(ReturnLoc, (Expr*)0));
    1172                 :   }
    1173                 : 
                     4052: branch 2 taken
                       95: branch 3 taken
                     4031: branch 5 taken
                       21: branch 6 taken
                     4031: branch 7 taken
                      116: branch 8 taken
    1174             4147:   if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
    1175                 :     // we have a non-void function with an expression, continue checking
    1176                 : 
    1177                 :     // C99 6.8.6.4p3(136): The return statement is not an assignment. The
    1178                 :     // overlap restriction of subclause 6.5.16.1 does not apply to the case of
    1179                 :     // function return.
    1180                 : 
    1181                 :     // C++0x 12.8p15: When certain criteria are met, an implementation is
    1182                 :     //   allowed to omit the copy construction of a class object, [...]
    1183                 :     //   - in a return statement in a function with a class return type, when
    1184                 :     //     the expression is the name of a non-volatile automatic object with
    1185                 :     //     the same cv-unqualified type as the function return type, the copy
    1186                 :     //     operation can be omitted [...]
    1187                 :     // C++0x 12.8p16: When the criteria for elision of a copy operation are met
    1188                 :     //   and the object to be copied is designated by an lvalue, overload
    1189                 :     //   resolution to select the constructor for the copy is first performed
    1190                 :     //   as if the object were designated by an rvalue.
    1191                 :     // Note that we only compute Elidable if we're in C++0x, since we don't
    1192                 :     // care otherwise.
    1193                 :     bool Elidable = getLangOptions().CPlusPlus0x ?
    1194                 :                       IsReturnCopyElidable(Context, FnRetType, RetValExp) :
                      103: branch 1 taken
                     3928: branch 2 taken
    1195             4031:                       false;
    1196                 :     // FIXME: Elidable
    1197                 :     (void)Elidable;
    1198                 : 
    1199                 :     // In C++ the return statement is handled via a copy initialization.
    1200                 :     // the C version of which boils down to CheckSingleAssignmentConstraints.
    1201                 :     OwningExprResult Res = PerformCopyInitialization(
    1202                 :                              InitializedEntity::InitializeResult(ReturnLoc, 
    1203                 :                                                                  FnRetType),
    1204                 :                              SourceLocation(),
    1205             4031:                              Owned(RetValExp));
                       27: branch 1 taken
                     4004: branch 2 taken
    1206             4031:     if (Res.isInvalid()) {
    1207                 :       // FIXME: Cleanup temporaries here, anyway?
    1208               27:       return StmtError();
    1209                 :     }
    1210                 : 
    1211             4004:     RetValExp = Res.takeAs<Expr>();
                     4004: branch 0 taken
                        0: branch 1 not taken
    1212             4004:     if (RetValExp) 
                     4004: branch 2 taken
                       27: branch 3 taken
    1213             4004:       CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
    1214                 :   }
    1215                 : 
                     4119: branch 0 taken
                        1: branch 1 taken
    1216             4120:   if (RetValExp)
    1217             4119:     RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
                     4120: branch 1 taken
                        0: branch 2 not taken
    1218             4120:   return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
    1219                 : }
    1220                 : 
    1221                 : /// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently
    1222                 : /// ignore "noop" casts in places where an lvalue is required by an inline asm.
    1223                 : /// We emulate this behavior when -fheinous-gnu-extensions is specified, but
    1224                 : /// provide a strong guidance to not use it.
    1225                 : ///
    1226                 : /// This method checks to see if the argument is an acceptable l-value and
    1227                 : /// returns false if it is a case we can handle.
    1228               44: static bool CheckAsmLValue(const Expr *E, Sema &S) {
    1229                 :   // Type dependent expressions will be checked during instantiation.
                        1: branch 1 taken
                       43: branch 2 taken
    1230               44:   if (E->isTypeDependent())
    1231                1:     return false;
    1232                 :   
                       35: branch 1 taken
                        8: branch 2 taken
    1233               43:   if (E->isLvalue(S.Context) == Expr::LV_Valid)
    1234               35:     return false;  // Cool, this is an lvalue.
    1235                 : 
    1236                 :   // Okay, this is not an lvalue, but perhaps it is the result of a cast that we
    1237                 :   // are supposed to allow.
    1238                8:   const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
                        4: branch 0 taken
                        4: branch 1 taken
                        4: branch 3 taken
                        0: branch 4 not taken
                        4: branch 5 taken
                        4: branch 6 taken
    1239                8:   if (E != E2 && E2->isLvalue(S.Context) == Expr::LV_Valid) {
                        2: branch 1 taken
                        2: branch 2 taken
    1240                4:     if (!S.getLangOptions().HeinousExtensions)
    1241                 :       S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
    1242                2:         << E->getSourceRange();
    1243                 :     else
    1244                 :       S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
    1245                2:         << E->getSourceRange();
    1246                 :     // Accept, even if we emitted an error diagnostic.
    1247                4:     return false;
    1248                 :   }
    1249                 : 
    1250                 :   // None of the above, just randomly invalid non-lvalue.
    1251                4:   return true;
    1252                 : }
    1253                 : 
    1254                 : 
    1255                 : Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
    1256                 :                                           bool IsSimple,
    1257                 :                                           bool IsVolatile,
    1258                 :                                           unsigned NumOutputs,
    1259                 :                                           unsigned NumInputs,
    1260                 :                                           IdentifierInfo **Names,
    1261                 :                                           MultiExprArg constraints,
    1262                 :                                           MultiExprArg exprs,
    1263                 :                                           ExprArg asmString,
    1264                 :                                           MultiExprArg clobbers,
    1265                 :                                           SourceLocation RParenLoc,
    1266              105:                                           bool MSAsm) {
    1267              105:   unsigned NumClobbers = clobbers.size();
    1268                 :   StringLiteral **Constraints =
    1269              105:     reinterpret_cast<StringLiteral**>(constraints.get());
    1270              105:   Expr **Exprs = reinterpret_cast<Expr **>(exprs.get());
    1271              105:   StringLiteral *AsmString = cast<StringLiteral>((Expr *)asmString.get());
    1272              105:   StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
    1273                 : 
    1274              105:   llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
    1275                 : 
    1276                 :   // The parser verifies that there is a string literal here.
                        1: branch 1 taken
                      104: branch 2 taken
    1277              105:   if (AsmString->isWide())
    1278                 :     return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character)
    1279                1:       << AsmString->getSourceRange());
    1280                 : 
                       34: branch 1 taken
                        2: branch 2 taken
                       37: branch 3 taken
                      101: branch 4 taken
    1281              140:   for (unsigned i = 0; i != NumOutputs; i++) {
    1282               37:     StringLiteral *Literal = Constraints[i];
                        1: branch 1 taken
                       36: branch 2 taken
    1283               37:     if (Literal->isWide())
    1284                 :       return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
    1285                1:         << Literal->getSourceRange());
    1286                 : 
    1287               36:     llvm::StringRef OutputName;
                        4: branch 0 taken
                       32: branch 1 taken
    1288               36:     if (Names[i])
    1289                4:       OutputName = Names[i]->getName();
    1290                 : 
    1291               36:     TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
                        0: branch 1 not taken
                       36: branch 2 taken
    1292               36:     if (!Context.Target.validateOutputConstraint(Info))
    1293                 :       return StmtError(Diag(Literal->getLocStart(),
    1294                 :                             diag::err_asm_invalid_output_constraint)
    1295                0:                        << Info.getConstraintStr());
    1296                 : 
    1297                 :     // Check that the output exprs are valid lvalues.
    1298               36:     Expr *OutputExpr = Exprs[i];
                        2: branch 1 taken
                       34: branch 2 taken
    1299               36:     if (CheckAsmLValue(OutputExpr, *this)) {
    1300                 :       return StmtError(Diag(OutputExpr->getLocStart(),
    1301                 :                   diag::err_asm_invalid_lvalue_in_output)
    1302                2:         << OutputExpr->getSourceRange());
    1303                 :     }
    1304                 : 
    1305               34:     OutputConstraintInfos.push_back(Info);
    1306                 :   }
    1307                 : 
    1308              101:   llvm::SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
    1309                 : 
                       42: branch 1 taken
                        8: branch 2 taken
                       50: branch 3 taken
                       93: branch 4 taken
    1310              151:   for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
    1311               50:     StringLiteral *Literal = Constraints[i];
                        0: branch 1 not taken
                       50: branch 2 taken
    1312               50:     if (Literal->isWide())
    1313                 :       return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
    1314                0:         << Literal->getSourceRange());
    1315                 : 
    1316               50:     llvm::StringRef InputName;
                        6: branch 0 taken
                       44: branch 1 taken
    1317               50:     if (Names[i])
    1318                6:       InputName = Names[i]->getName();
    1319                 : 
    1320               50:     TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
                        3: branch 2 taken
                       47: branch 3 taken
    1321               50:     if (!Context.Target.validateInputConstraint(OutputConstraintInfos.data(),
    1322                 :                                                 NumOutputs, Info)) {
    1323                 :       return StmtError(Diag(Literal->getLocStart(),
    1324                 :                             diag::err_asm_invalid_input_constraint)
    1325                3:                        << Info.getConstraintStr());
    1326                 :     }
    1327                 : 
    1328               47:     Expr *InputExpr = Exprs[i];
    1329                 : 
    1330                 :     // Only allow void types for memory constraints.
                       11: branch 1 taken
                       36: branch 2 taken
                        8: branch 4 taken
                        3: branch 5 taken
                        8: branch 6 taken
                       39: branch 7 taken
    1331               47:     if (Info.allowsMemory() && !Info.allowsRegister()) {
                        2: branch 1 taken
                        6: branch 2 taken
    1332                8:       if (CheckAsmLValue(InputExpr, *this))
    1333                 :         return StmtError(Diag(InputExpr->getLocStart(),
    1334                 :                               diag::err_asm_invalid_lvalue_in_input)
    1335                 :                          << Info.getConstraintStr()
    1336                2:                          << InputExpr->getSourceRange());
    1337                 :     }
    1338                 : 
                       28: branch 1 taken
                       17: branch 2 taken
    1339               45:     if (Info.allowsRegister()) {
                        3: branch 3 taken
                       25: branch 4 taken
    1340               28:       if (InputExpr->getType()->isVoidType()) {
    1341                 :         return StmtError(Diag(InputExpr->getLocStart(),
    1342                 :                               diag::err_asm_invalid_type_in_input)
    1343                 :           << InputExpr->getType() << Info.getConstraintStr()
    1344                3:           << InputExpr->getSourceRange());
    1345                 :       }
    1346                 :     }
    1347                 : 
    1348               42:     DefaultFunctionArrayLvalueConversion(Exprs[i]);
    1349                 : 
    1350               42:     InputConstraintInfos.push_back(Info);
    1351                 :   }
    1352                 : 
    1353                 :   // Check that the clobbers are valid.
                       55: branch 0 taken
                       89: branch 1 taken
    1354              144:   for (unsigned i = 0; i != NumClobbers; i++) {
    1355               55:     StringLiteral *Literal = Clobbers[i];
                        0: branch 1 not taken
                       55: branch 2 taken
    1356               55:     if (Literal->isWide())
    1357                 :       return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
    1358                0:         << Literal->getSourceRange());
    1359                 : 
    1360               55:     llvm::StringRef Clobber = Literal->getString();
    1361                 : 
                        4: branch 1 taken
                       51: branch 2 taken
    1362               55:     if (!Context.Target.isValidGCCRegisterName(Clobber))
    1363                 :       return StmtError(Diag(Literal->getLocStart(),
    1364                4:                   diag::err_asm_unknown_register_name) << Clobber);
    1365                 :   }
    1366                 : 
    1367               89:   constraints.release();
    1368               89:   exprs.release();
    1369               89:   asmString.release();
    1370               89:   clobbers.release();
    1371                 :   AsmStmt *NS =
    1372                 :     new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm, 
    1373                 :                           NumOutputs, NumInputs, Names, Constraints, Exprs, 
                       89: branch 1 taken
                        0: branch 2 not taken
    1374               89:                           AsmString, NumClobbers, Clobbers, RParenLoc);
    1375                 :   // Validate the asm string, ensuring it makes sense given the operands we
    1376                 :   // have.
    1377               89:   llvm::SmallVector<AsmStmt::AsmStringPiece, 8> Pieces;
    1378                 :   unsigned DiagOffs;
                        6: branch 1 taken
                       83: branch 2 taken
    1379               89:   if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
    1380                 :     Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
    1381                6:            << AsmString->getSourceRange();
    1382                6:     DeleteStmt(NS);
    1383                6:     return StmtError();
    1384                 :   }
    1385                 : 
    1386                 :   // Validate tied input operands for type mismatches.
                       38: branch 1 taken
                       82: branch 2 taken
    1387              120:   for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
    1388               38:     TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
    1389                 : 
    1390                 :     // If this is a tied constraint, verify that the output and input have
    1391                 :     // either exactly the same type, or that they are int/ptr operands with the
    1392                 :     // same size (int/long, int*/long, are ok etc).
                        6: branch 1 taken
                       32: branch 2 taken
    1393               38:     if (!Info.hasTiedOperand()) continue;
    1394                 : 
    1395                6:     unsigned TiedTo = Info.getTiedOperand();
    1396                6:     Expr *OutputExpr = Exprs[TiedTo];
    1397                6:     Expr *InputExpr = Exprs[i+NumOutputs];
    1398                6:     QualType InTy = InputExpr->getType();
    1399                6:     QualType OutTy = OutputExpr->getType();
                        5: branch 1 taken
                        1: branch 2 taken
    1400                6:     if (Context.hasSameType(InTy, OutTy))
    1401                1:       continue;  // All types can be tied to themselves.
    1402                 : 
    1403                 :     // Int/ptr operands have some special cases that we allow.
                        0: branch 2 not taken
                        5: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        1: branch 10 taken
                        4: branch 11 taken
                        1: branch 14 taken
                        0: branch 15 not taken
                        5: branch 16 taken
                        0: branch 17 not taken
    1404                5:     if ((OutTy->isIntegerType() || OutTy->isPointerType()) &&
    1405                 :         (InTy->isIntegerType() || InTy->isPointerType())) {
    1406                 : 
    1407                 :       // They are ok if they are the same size.  Tying void* to int is ok if
    1408                 :       // they are the same size, for example.  This also allows tying void* to
    1409                 :       // int*.
    1410                5:       uint64_t OutSize = Context.getTypeSize(OutTy);
    1411                5:       uint64_t InSize = Context.getTypeSize(InTy);
                        1: branch 0 taken
                        4: branch 1 taken
    1412                5:       if (OutSize == InSize)
    1413                1:         continue;
    1414                 : 
    1415                 :       // If the smaller input/output operand is not mentioned in the asm string,
    1416                 :       // then we can promote it and the asm string won't notice.  Check this
    1417                 :       // case now.
    1418                4:       bool SmallerValueMentioned = false;
                        6: branch 1 taken
                        3: branch 2 taken
    1419                9:       for (unsigned p = 0, e = Pieces.size(); p != e; ++p) {
    1420                6:         AsmStmt::AsmStringPiece &Piece = Pieces[p];
                        2: branch 1 taken
                        4: branch 2 taken
    1421                6:         if (!Piece.isOperand()) continue;
    1422                 : 
    1423                 :         // If this is a reference to the input and if the input was the smaller
    1424                 :         // one, then we have to reject this asm.
                        1: branch 1 taken
                        1: branch 2 taken
    1425                2:         if (Piece.getOperandNo() == i+NumOutputs) {
                        0: branch 0 not taken
                        1: branch 1 taken
    1426                1:           if (InSize < OutSize) {
    1427                0:             SmallerValueMentioned = true;
    1428                0:             break;
    1429                 :           }
    1430                 :         }
    1431                 : 
    1432                 :         // If this is a reference to the input and if the input was the smaller
    1433                 :         // one, then we have to reject this asm.
                        1: branch 1 taken
                        1: branch 2 taken
    1434                2:         if (Piece.getOperandNo() == TiedTo) {
                        1: branch 0 taken
                        0: branch 1 not taken
    1435                1:           if (InSize > OutSize) {
    1436                1:             SmallerValueMentioned = true;
    1437                1:             break;
    1438                 :           }
    1439                 :         }
    1440                 :       }
    1441                 : 
    1442                 :       // If the smaller value wasn't mentioned in the asm string, and if the
    1443                 :       // output was a register, just extend the shorter one to the size of the
    1444                 :       // larger one.
                        3: branch 0 taken
                        1: branch 1 taken
                        3: branch 4 taken
                        0: branch 5 not taken
                        3: branch 6 taken
                        1: branch 7 taken
    1445                4:       if (!SmallerValueMentioned &&
    1446                 :           OutputConstraintInfos[TiedTo].allowsRegister())
    1447                3:         continue;
    1448                 :     }
    1449                 : 
    1450                 :     Diag(InputExpr->getLocStart(),
    1451                 :          diag::err_asm_tying_incompatible_types)
    1452                 :       << InTy << OutTy << OutputExpr->getSourceRange()
    1453                1:       << InputExpr->getSourceRange();
    1454                1:     DeleteStmt(NS);
    1455                1:     return StmtError();
    1456                 :   }
    1457                 : 
    1458               82:   return Owned(NS);
    1459                 : }
    1460                 : 
    1461                 : Action::OwningStmtResult
    1462                 : Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
    1463                 :                            SourceLocation RParen, DeclPtrTy Parm,
    1464               66:                            StmtArg Body, StmtArg catchList) {
    1465               66:   Stmt *CatchList = catchList.takeAs<Stmt>();
    1466               66:   ParmVarDecl *PVD = cast_or_null<ParmVarDecl>(Parm.getAs<Decl>());
    1467                 : 
    1468                 :   // PVD == 0 implies @catch(...).
                       52: branch 0 taken
                       14: branch 1 taken
    1469               66:   if (PVD) {
    1470                 :     // If we already know the decl is invalid, reject it.
                        1: branch 1 taken
                       51: branch 2 taken
    1471               52:     if (PVD->isInvalidDecl())
    1472                1:       return StmtError();
    1473                 : 
                        7: branch 3 taken
                       44: branch 4 taken
    1474               51:     if (!PVD->getType()->isObjCObjectPointerType())
    1475                 :       return StmtError(Diag(PVD->getLocation(),
    1476                7:                        diag::err_catch_param_not_objc_type));
                        1: branch 3 taken
                       43: branch 4 taken
    1477               44:     if (PVD->getType()->isObjCQualifiedIdType())
    1478                 :       return StmtError(Diag(PVD->getLocation(),
    1479                1:                        diag::err_illegal_qualifiers_on_catch_parm));
    1480                 :   }
    1481                 : 
    1482                 :   ObjCAtCatchStmt *CS = new (Context) ObjCAtCatchStmt(AtLoc, RParen,
                       57: branch 2 taken
                        0: branch 3 not taken
    1483               57:     PVD, Body.takeAs<Stmt>(), CatchList);
                       20: branch 0 taken
                       37: branch 1 taken
    1484               57:   return Owned(CatchList ? CatchList : CS);
    1485                 : }
    1486                 : 
    1487                 : Action::OwningStmtResult
    1488               21: Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtArg Body) {
    1489                 :   return Owned(new (Context) ObjCAtFinallyStmt(AtLoc,
                       21: branch 2 taken
                        0: branch 3 not taken
    1490               21:                                            static_cast<Stmt*>(Body.release())));
    1491                 : }
    1492                 : 
    1493                 : Action::OwningStmtResult
    1494                 : Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc,
    1495               46:                          StmtArg Try, StmtArg Catch, StmtArg Finally) {
    1496               46:   CurFunctionNeedsScopeChecking = true;
    1497                 :   return Owned(new (Context) ObjCAtTryStmt(AtLoc, Try.takeAs<Stmt>(),
    1498                 :                                            Catch.takeAs<Stmt>(),
                       46: branch 4 taken
                        0: branch 5 not taken
    1499               46:                                            Finally.takeAs<Stmt>()));
    1500                 : }
    1501                 : 
    1502                 : Action::OwningStmtResult
    1503               30: Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr,Scope *CurScope) {
    1504               30:   Expr *ThrowExpr = expr.takeAs<Expr>();
                       12: branch 0 taken
                       18: branch 1 taken
    1505               30:   if (!ThrowExpr) {
    1506                 :     // @throw without an expression designates a rethrow (which much occur
    1507                 :     // in the context of an @catch clause).
    1508               12:     Scope *AtCatchParent = CurScope;
                       14: branch 0 taken
                        1: branch 1 taken
                        3: branch 3 taken
                       11: branch 4 taken
                        3: branch 5 taken
                       12: branch 6 taken
    1509               27:     while (AtCatchParent && !AtCatchParent->isAtCatchScope())
    1510                3:       AtCatchParent = AtCatchParent->getParent();
                        1: branch 0 taken
                       11: branch 1 taken
    1511               12:     if (!AtCatchParent)
    1512                1:       return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
    1513                 :   } else {
    1514               18:     QualType ThrowType = ThrowExpr->getType();
    1515                 :     // Make sure the expression type is an ObjC pointer or "void *".
                        9: branch 2 taken
                        9: branch 3 taken
    1516               18:     if (!ThrowType->isObjCObjectPointerType()) {
    1517                9:       const PointerType *PT = ThrowType->getAs<PointerType>();
                        5: branch 0 taken
                        4: branch 1 taken
                        1: branch 5 taken
                        4: branch 6 taken
                        5: branch 7 taken
                        4: branch 8 taken
    1518                9:       if (!PT || !PT->getPointeeType()->isVoidType())
    1519                 :         return StmtError(Diag(AtLoc, diag::error_objc_throw_expects_object)
    1520                5:                         << ThrowExpr->getType() << ThrowExpr->getSourceRange());
    1521                 :     }
    1522                 :   }
                       24: branch 1 taken
                        0: branch 2 not taken
    1523               24:   return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowExpr));
    1524                 : }
    1525                 : 
    1526                 : Action::OwningStmtResult
    1527                 : Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
    1528               22:                                   StmtArg SynchBody) {
    1529               22:   CurFunctionNeedsScopeChecking = true;
    1530                 : 
    1531                 :   // Make sure the expression type is an ObjC pointer or "void *".
    1532               22:   Expr *SyncExpr = static_cast<Expr*>(SynchExpr.get());
                        2: branch 3 taken
                       20: branch 4 taken
    1533               22:   if (!SyncExpr->getType()->isObjCObjectPointerType()) {
    1534                2:     const PointerType *PT = SyncExpr->getType()->getAs<PointerType>();
                        0: branch 0 not taken
                        2: branch 1 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        2: branch 7 taken
                        0: branch 8 not taken
    1535                2:     if (!PT || !PT->getPointeeType()->isVoidType())
    1536                 :       return StmtError(Diag(AtLoc, diag::error_objc_synchronized_expects_object)
    1537                2:                        << SyncExpr->getType() << SyncExpr->getSourceRange());
    1538                 :   }
    1539                 : 
    1540                 :   return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
    1541                 :                                                     SynchExpr.takeAs<Stmt>(),
                       20: branch 3 taken
                        0: branch 4 not taken
    1542               20:                                                     SynchBody.takeAs<Stmt>()));
    1543                 : }
    1544                 : 
    1545                 : /// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
    1546                 : /// and creates a proper catch handler from them.
    1547                 : Action::OwningStmtResult
    1548                 : Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, DeclPtrTy ExDecl,
    1549               38:                          StmtArg HandlerBlock) {
    1550                 :   // There's nothing to test that ActOnExceptionDecl didn't already test.
    1551                 :   return Owned(new (Context) CXXCatchStmt(CatchLoc,
    1552                 :                                   cast_or_null<VarDecl>(ExDecl.getAs<Decl>()),
                       38: branch 4 taken
                        0: branch 5 not taken
    1553               38:                                           HandlerBlock.takeAs<Stmt>()));
    1554                 : }
    1555                 : 
    1556               25: class TypeWithHandler {
    1557                 :   QualType t;
    1558                 :   CXXCatchStmt *stmt;
    1559                 : public:
    1560               25:   TypeWithHandler(const QualType &type, CXXCatchStmt *statement)
    1561               25:   : t(type), stmt(statement) {}
    1562                 : 
    1563                 :   // An arbitrary order is fine as long as it places identical
    1564                 :   // types next to each other.
    1565               19:   bool operator<(const TypeWithHandler &y) const {
                       13: branch 2 taken
                        6: branch 3 taken
    1566               19:     if (t.getAsOpaquePtr() < y.t.getAsOpaquePtr())
    1567               13:       return true;
                        5: branch 2 taken
                        1: branch 3 taken
    1568                6:     if (t.getAsOpaquePtr() > y.t.getAsOpaquePtr())
    1569                5:       return false;
    1570                 :     else
    1571                1:       return getTypeSpecStartLoc() < y.getTypeSpecStartLoc();
    1572                 :   }
    1573                 : 
    1574                8:   bool operator==(const TypeWithHandler& other) const {
    1575                8:     return t == other.t;
    1576                 :   }
    1577                 : 
    1578                 :   QualType getQualType() const { return t; }
    1579                2:   CXXCatchStmt *getCatchStmt() const { return stmt; }
    1580                4:   SourceLocation getTypeSpecStartLoc() const {
    1581                4:     return stmt->getExceptionDecl()->getTypeSpecStartLoc();
    1582                 :   }
    1583                 : };
    1584                 : 
    1585                 : /// ActOnCXXTryBlock - Takes a try compound-statement and a number of
    1586                 : /// handlers and creates a try statement from them.
    1587                 : Action::OwningStmtResult
    1588                 : Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
    1589               26:                        MultiStmtArg RawHandlers) {
    1590               26:   unsigned NumHandlers = RawHandlers.size();
    1591                 :   assert(NumHandlers > 0 &&
                        0: branch 0 not taken
                       26: branch 1 taken
    1592               26:          "The parser shouldn't call this if there are no handlers.");
    1593               26:   Stmt **Handlers = reinterpret_cast<Stmt**>(RawHandlers.get());
    1594                 : 
    1595               26:   llvm::SmallVector<TypeWithHandler, 8> TypesWithHandlers;
    1596                 : 
                       40: branch 0 taken
                       25: branch 1 taken
    1597               65:   for (unsigned i = 0; i < NumHandlers; ++i) {
    1598               40:     CXXCatchStmt *Handler = llvm::cast<CXXCatchStmt>(Handlers[i]);
                       15: branch 1 taken
                       25: branch 2 taken
    1599               40:     if (!Handler->getExceptionDecl()) {
                        1: branch 0 taken
                       14: branch 1 taken
    1600               15:       if (i < NumHandlers - 1)
    1601                 :         return StmtError(Diag(Handler->getLocStart(),
    1602                1:                               diag::err_early_catch_all));
    1603                 : 
    1604               14:       continue;
    1605                 :     }
    1606                 : 
    1607               25:     const QualType CaughtType = Handler->getCaughtType();
    1608               25:     const QualType CanonicalCaughtType = Context.getCanonicalType(CaughtType);
    1609               25:     TypesWithHandlers.push_back(TypeWithHandler(CanonicalCaughtType, Handler));
    1610                 :   }
    1611                 : 
    1612                 :   // Detect handlers for the same type as an earlier one.
                        7: branch 0 taken
                       18: branch 1 taken
    1613               25:   if (NumHandlers > 1) {
    1614                7:     llvm::array_pod_sort(TypesWithHandlers.begin(), TypesWithHandlers.end());
    1615                 : 
    1616                7:     TypeWithHandler prev = TypesWithHandlers[0];
                        8: branch 1 taken
                        7: branch 2 taken
    1617               15:     for (unsigned i = 1; i < TypesWithHandlers.size(); ++i) {
    1618                8:       TypeWithHandler curr = TypesWithHandlers[i];
    1619                 : 
                        1: branch 1 taken
                        7: branch 2 taken
    1620                8:       if (curr == prev) {
    1621                 :         Diag(curr.getTypeSpecStartLoc(),
    1622                 :              diag::warn_exception_caught_by_earlier_handler)
    1623                1:           << curr.getCatchStmt()->getCaughtType().getAsString();
    1624                 :         Diag(prev.getTypeSpecStartLoc(),
    1625                 :              diag::note_previous_exception_handler)
    1626                1:           << prev.getCatchStmt()->getCaughtType().getAsString();
    1627                 :       }
    1628                 : 
    1629                8:       prev = curr;
    1630                 :     }
    1631                 :   }
    1632                 : 
    1633                 :   // FIXME: We should detect handlers that cannot catch anything because an
    1634                 :   // earlier handler catches a superclass. Need to find a method that is not
    1635                 :   // quadratic for this.
    1636                 :   // Neither of these are explicitly forbidden, but every compiler detects them
    1637                 :   // and warns.
    1638                 : 
    1639               25:   CurFunctionNeedsScopeChecking = true;
    1640               25:   RawHandlers.release();
    1641                 :   return Owned(CXXTryStmt::Create(Context, TryLoc,
    1642                 :                                   static_cast<Stmt*>(TryBlock.release()),
    1643               25:                                   Handlers, NumHandlers));
    1644                 : }

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