[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