diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-09-10 02:17:11 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-09-10 02:17:11 +0000 |
commit | 5921093cf1c2e9a8bd1a22b6f612e551bae7476b (patch) | |
tree | b54ba8c21a434e454adc83be86194e58a0656af7 /lib/Sema/SemaStmt.cpp | |
parent | 4189a76f55a9d5bb6fb3e63a491724b4dc2a7c45 (diff) |
Implement Sema support for the 'condition' part of C++ selection-statements and iteration-statements (if/switch/while/for).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56044 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 98efc8a907..706bcddff2 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -185,7 +185,10 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal, DefaultFunctionArrayConversion(condExpr); QualType condType = condExpr->getType(); - if (!condType->isScalarType()) // C99 6.8.4.1p1 + if (getLangOptions().CPlusPlus) { + if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4 + return true; + } else if (!condType->isScalarType()) // C99 6.8.4.1p1 return Diag(IfLoc, diag::err_typecheck_statement_requires_scalar, condType.getAsString(), condExpr->getSourceRange()); @@ -205,8 +208,30 @@ Action::StmtResult Sema::ActOnStartOfSwitchStmt(ExprTy *cond) { Expr *Cond = static_cast<Expr*>(cond); - // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr. - UsualUnaryConversions(Cond); + if (getLangOptions().CPlusPlus) { + // C++ 6.4.2.p2: + // The condition shall be of integral type, enumeration type, or of a class + // type for which a single conversion function to integral or enumeration + // type exists (12.3). If the condition is of class type, the condition is + // converted by calling that conversion function, and the result of the + // conversion is used in place of the original condition for the remainder + // of this section. Integral promotions are performed. + + QualType Ty = Cond->getType(); + + // FIXME: Handle class types. + + // If the type is wrong a diagnostic will be emitted later at + // ActOnFinishSwitchStmt. + if (Ty->isIntegralType() || Ty->isEnumeralType()) { + // Integral promotions are performed. + // FIXME: Integral promotions for C++ are not complete. + UsualUnaryConversions(Cond); + } + } else { + // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr. + UsualUnaryConversions(Cond); + } SwitchStmt *SS = new SwitchStmt(Cond); SwitchStack.push_back(SS); @@ -486,7 +511,10 @@ Sema::ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, StmtTy *Body) { DefaultFunctionArrayConversion(condExpr); QualType condType = condExpr->getType(); - if (!condType->isScalarType()) // C99 6.8.5p2 + if (getLangOptions().CPlusPlus) { + if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4 + return true; + } else if (!condType->isScalarType()) // C99 6.8.5p2 return Diag(WhileLoc, diag::err_typecheck_statement_requires_scalar, condType.getAsString(), condExpr->getSourceRange()); @@ -518,24 +546,29 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Expr *Third = static_cast<Expr*>(third); Stmt *Body = static_cast<Stmt*>(body); - if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) { - // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare - // identifiers for objects having storage class 'auto' or 'register'. - for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end(); - DI!=DE; ++DI) { - VarDecl *VD = dyn_cast<VarDecl>(*DI); - if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage()) - VD = 0; - if (VD == 0) - Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for); - // FIXME: mark decl erroneous! + if (!getLangOptions().CPlusPlus) { + if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) { + // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare + // identifiers for objects having storage class 'auto' or 'register'. + for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end(); + DI!=DE; ++DI) { + VarDecl *VD = dyn_cast<VarDecl>(*DI); + if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage()) + VD = 0; + if (VD == 0) + Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for); + // FIXME: mark decl erroneous! + } } } if (Second) { DefaultFunctionArrayConversion(Second); QualType SecondType = Second->getType(); - if (!SecondType->isScalarType()) // C99 6.8.5p2 + if (getLangOptions().CPlusPlus) { + if (CheckCXXBooleanCondition(Second)) // C++ 6.4p4 + return true; + } else if (!SecondType->isScalarType()) // C99 6.8.5p2 return Diag(ForLoc, diag::err_typecheck_statement_requires_scalar, SecondType.getAsString(), Second->getSourceRange()); } |