[cfe-commits] r39989 - in /cfe/trunk: Parse/ParseStmt.cpp Sema/Sema.h Sema/SemaStmt.cpp include/clang/AST/Stmt.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/Scope.h
Chris Lattner
sabre at nondot.org
Tue Jul 17 19:28:47 PDT 2007
Author: lattner
Date: Tue Jul 17 21:28:47 2007
New Revision: 39989
URL: http://llvm.org/viewvc/llvm-project?rev=39989&view=rev
Log:
Add initial switch stmt support, patch by Anders Carlsson!
Modified:
cfe/trunk/Parse/ParseStmt.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaStmt.cpp
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Scope.h
Modified: cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseStmt.cpp?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/Parse/ParseStmt.cpp Tue Jul 17 21:28:47 2007
@@ -338,7 +338,7 @@
return true;
// TODO: look up enclosing switch stmt.
- return Actions.ParseDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val);
+ return Actions.ParseDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val, CurScope);
}
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Tue Jul 17 21:28:47 2007
@@ -167,7 +167,8 @@
SourceLocation DotDotDotLoc, ExprTy *RHSVal,
SourceLocation ColonLoc, StmtTy *SubStmt);
virtual StmtResult ParseDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc, StmtTy *SubStmt);
+ SourceLocation ColonLoc, StmtTy *SubStmt,
+ Scope *CurScope);
virtual StmtResult ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
SourceLocation ColonLoc, StmtTy *SubStmt);
virtual StmtResult ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
Modified: cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaStmt.cpp?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/Sema/SemaStmt.cpp Tue Jul 17 21:28:47 2007
@@ -51,7 +51,7 @@
Action::StmtResult
Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
- SourceLocation DotDotDotLoc, ExprTy *RHSVal,
+ SourceLocation DotDotDotLoc, ExprTy *rhsval,
SourceLocation ColonLoc, StmtTy *SubStmt) {
Expr *LHSVal = ((Expr *)lhsval);
assert((LHSVal != 0) && "missing expression in case statement");
@@ -62,15 +62,34 @@
return Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
LHSVal->getSourceRange());
- // FIXME: SEMA for RHS of case range.
+ // GCC extension: The expression shall be an integer constant.
+ Expr *RHSVal = ((Expr *)rhsval);
+ if (RHSVal) {
+ if (!RHSVal->isIntegerConstantExpr(Context, &ExpLoc))
+ return Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
+ RHSVal->getSourceRange());
+ }
return new CaseStmt(LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
}
Action::StmtResult
-Sema::ParseDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc, StmtTy *SubStmt) {
- return new DefaultStmt((Stmt*)SubStmt);
+Sema::ParseDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
+ StmtTy *SubStmt, Scope *CurScope) {
+ Scope *S = CurScope->getBreakParent();
+
+ if (S->getDefaultStmt()) {
+ Diag(DefaultLoc, diag::err_multiple_default_labels_defined);
+ Diag(((DefaultStmt *)S->getDefaultStmt())->getDefaultLoc(),
+ diag::err_first_label);
+
+ return true;
+ }
+
+ DefaultStmt *DS = new DefaultStmt(DefaultLoc, (Stmt*)SubStmt);
+ S->setDefaultStmt(DS);
+
+ return DS;
}
Action::StmtResult
@@ -119,6 +138,14 @@
Action::StmtResult
Sema::ParseSwitchStmt(SourceLocation SwitchLoc, ExprTy *Cond, StmtTy *Body) {
+ Expr *condExpr = (Expr *)Cond;
+
+ QualType condType = condExpr->getType();
+
+ if (!condType->isIntegerType()) // C99 6.8.4.2p1
+ return Diag(SwitchLoc, diag::err_typecheck_statement_requires_integer,
+ condType.getAsString(), condExpr->getSourceRange());
+
return new SwitchStmt((Expr*)Cond, (Stmt*)Body);
}
@@ -205,7 +232,6 @@
return true;
}
- // FIXME: Remember that this continue goes with this loop.
return new ContinueStmt();
}
@@ -218,7 +244,6 @@
return true;
}
- // FIXME: Remember that this break goes with this loop/switch.
return new BreakStmt();
}
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Jul 17 21:28:47 2007
@@ -23,6 +23,7 @@
class Decl;
class IdentifierInfo;
class StmtVisitor;
+ class SwitchStmt;
/// Stmt - This represents one statement.
///
@@ -127,9 +128,11 @@
Expr *LHSVal;
Expr *RHSVal; // Non-null for GNU "case 1 ... 4" extension
Stmt *SubStmt;
+ SwitchStmt *Switch;
public:
CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt)
- : Stmt(CaseStmtClass), LHSVal(lhs), RHSVal(rhs), SubStmt(substmt) {}
+ : Stmt(CaseStmtClass), LHSVal(lhs), RHSVal(rhs), SubStmt(substmt),
+ Switch(0) {}
Expr *getLHS() { return LHSVal; }
Expr *getRHS() { return RHSVal; }
@@ -143,10 +146,13 @@
};
class DefaultStmt : public Stmt {
+ SourceLocation DefaultLoc;
Stmt *SubStmt;
public:
- DefaultStmt(Stmt *substmt) : Stmt(DefaultStmtClass), SubStmt(substmt) {}
+ DefaultStmt(SourceLocation DL, Stmt *substmt) : Stmt(DefaultStmtClass),
+ DefaultLoc(DL), SubStmt(substmt) {}
+ SourceLocation getDefaultLoc() const { return DefaultLoc; }
Stmt *getSubStmt() { return SubStmt; }
virtual void visit(StmtVisitor &Visitor);
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Tue Jul 17 21:28:47 2007
@@ -464,6 +464,8 @@
"previous definition is here")
DIAG(err_previous_use, ERROR,
"previous use is here")
+DIAG(err_first_label, ERROR,
+ "first label is here")
DIAG(err_unexpected_typedef, ERROR,
"unexpected type name '%0': expected expression")
@@ -659,6 +661,10 @@
"returning '%1' from function expecting '%0' discards qualifiers")
DIAG(err_typecheck_statement_requires_scalar, ERROR,
"statement requires expression of scalar type ('%0' invalid)")
+DIAG(err_typecheck_statement_requires_integer, ERROR,
+ "statement requires expression of integer type ('%0' invalid)")
+DIAG(err_multiple_default_labels_defined, ERROR,
+ "multiple default labels in one switch")
DIAG(warn_return_missing_expr, WARNING,
"non-void function '%0' should return a value")
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jul 17 21:28:47 2007
@@ -204,7 +204,8 @@
return 0;
}
virtual StmtResult ParseDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc, StmtTy *SubStmt){
+ SourceLocation ColonLoc, StmtTy *SubStmt,
+ Scope *CurScope){
return 0;
}
Modified: cfe/trunk/include/clang/Parse/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Scope.h?rev=39989&r1=39988&r2=39989&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Scope.h (original)
+++ cfe/trunk/include/clang/Parse/Scope.h Tue Jul 17 21:28:47 2007
@@ -78,6 +78,10 @@
/// implement these semantics.
typedef llvm::SmallPtrSet<Action::DeclTy*, 32> DeclSetTy;
DeclSetTy DeclsInScope;
+
+ /// DefaultStmt - when parsing the body of a switch statement, this keeps
+ /// track of the statement with the default label.
+ Action::StmtTy *DefaultStmt;
public:
Scope(Scope *Parent, unsigned ScopeFlags) {
Init(Parent, ScopeFlags);
@@ -114,6 +118,8 @@
return DeclsInScope.count(D) != 0;
}
+ void setDefaultStmt(Action::StmtTy *S) { DefaultStmt = S; }
+ Action::StmtTy *getDefaultStmt() const { return DefaultStmt; }
/// Init - This is used by the parser to implement scope caching.
///
@@ -132,6 +138,8 @@
FnParent = BreakParent = ContinueParent = 0;
}
+ DefaultStmt = 0;
+
// If this scope is a function or contains breaks/continues, remember it.
if (Flags & FnScope) FnParent = this;
if (Flags & BreakScope) BreakParent = this;
More information about the cfe-commits
mailing list