[cfe-commits] r40465 - in /cfe/trunk: AST/StmtPrinter.cpp Parse/ParseExpr.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/Expr.h include/clang/AST/Stmt.h include/clang/AST/StmtNodes.def include/clang/Parse/Action.h test/Sema/stmt_exprs.c

Chris Lattner sabre at nondot.org
Tue Jul 24 09:58:17 PDT 2007


Author: lattner
Date: Tue Jul 24 11:58:17 2007
New Revision: 40465

URL: http://llvm.org/viewvc/llvm-project?rev=40465&view=rev
Log:
implement ast building and trivial semantic analysis of stmt exprs.
This implements test/Sema/stmt_exprs.c


Added:
    cfe/trunk/test/Sema/stmt_exprs.c
Modified:
    cfe/trunk/AST/StmtPrinter.cpp
    cfe/trunk/Parse/ParseExpr.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/Parse/Action.h

Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Tue Jul 24 11:58:17 2007
@@ -468,9 +468,15 @@
 
 void StmtPrinter::VisitAddrLabel(AddrLabel *Node) {
   OS << "&&" << Node->getLabel()->getName();
-  
 }
 
+void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
+  OS << "(";
+  PrintRawCompoundStmt(E->getSubStmt());
+  OS << ")";
+}
+
+
 // C++
 
 void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {

Modified: cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseExpr.cpp?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/Parse/ParseExpr.cpp Tue Jul 24 11:58:17 2007
@@ -539,7 +539,7 @@
   case tok::kw___real:     // unary-expression: '__real' cast-expression [GNU]
   case tok::kw___imag:     // unary-expression: '__imag' cast-expression [GNU]
   case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
-    // FIXME: Extension not handled correctly here!
+    // FIXME: Extension should silence extwarns in subexpressions.
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false);
     if (!Res.isInvalid)
@@ -853,15 +853,19 @@
                                                 SourceLocation &RParenLoc) {
   assert(Tok.getKind() == tok::l_paren && "Not a paren expr!");
   SourceLocation OpenLoc = ConsumeParen();
-  ExprResult Result(false);
+  ExprResult Result(true);
   CastTy = 0;
   
   if (ExprType >= CompoundStmt && Tok.getKind() == tok::l_brace &&
       !getLang().NoExtensions) {
     Diag(Tok, diag::ext_gnu_statement_expr);
-    ParseCompoundStatement();
+    Parser::StmtResult Stmt = ParseCompoundStatement();
     ExprType = CompoundStmt;
-    // TODO: Build AST for GNU compound stmt.
+    
+    // If the substmt parsed correctly, build the AST node.
+    if (!Stmt.isInvalid && Tok.getKind() == tok::r_paren)
+      Result = Actions.ParseStmtExpr(OpenLoc, Stmt.Val, Tok.getLocation());
+    
   } else if (ExprType >= CompoundLiteral && isTypeSpecifierQualifier()) {
     // Otherwise, this is a compound literal expression or cast expression.
     TypeTy *Ty = ParseTypeName();

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Tue Jul 24 11:58:17 2007
@@ -271,6 +271,9 @@
   virtual ExprResult ParseAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
                                     IdentifierInfo *LabelII);
   
+  virtual ExprResult ParseStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
+                                   SourceLocation RPLoc); // "({..})"
+  
   /// ParseCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
   virtual ExprResult ParseCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
                                    SourceLocation LAngleBracketLoc, TypeTy *Ty,

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Tue Jul 24 11:58:17 2007
@@ -1476,3 +1476,26 @@
                        Context.getPointerType(Context.VoidTy));
 }
 
+Sema::ExprResult Sema::ParseStmtExpr(SourceLocation LPLoc, StmtTy *substmt,
+                                     SourceLocation RPLoc) { // "({..})"
+  Stmt *SubStmt = static_cast<Stmt*>(substmt);
+  assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
+  CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
+
+  // FIXME: there are a variety of strange constraints to enforce here, for
+  // example, it is not possible to goto into a stmt expression apparently.
+  // More semantic analysis is needed.
+  
+  // FIXME: the last statement in the compount stmt has its value used.  We
+  // should not warn about it being unused.
+
+  // If there are sub stmts in the compound stmt, take the type of the last one
+  // as the type of the stmtexpr.
+  QualType Ty = Context.VoidTy;
+  
+  if (!Compound->body_empty())
+    if (Expr *LastExpr = dyn_cast<Expr>(Compound->body_back()))
+      Ty = LastExpr->getType();
+  
+  return new StmtExpr(Compound, Ty, LPLoc, RPLoc);
+}

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Jul 24 11:58:17 2007
@@ -134,7 +134,7 @@
   static bool classof(const DeclRefExpr *) { return true; }
 };
 
-// PreDefinedExpr - [C99 6.4.2.2] - A pre-defined identifier such as __func__
+/// PreDefinedExpr - [C99 6.4.2.2] - A pre-defined identifier such as __func__.
 class PreDefinedExpr : public Expr {
 public:
   enum IdentType {
@@ -661,7 +661,33 @@
   }
   static bool classof(const AddrLabel *) { return true; }
 };
+
+/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
+/// The StmtExpr contains a single CompoundStmt node, which it evaluates and
+/// takes the value of the last subexpression.
+class StmtExpr : public Expr {
+  CompoundStmt *SubStmt;
+  SourceLocation LParenLoc, RParenLoc;
+public:
+    StmtExpr(CompoundStmt *substmt, QualType T,
+             SourceLocation lp, SourceLocation rp)
+    : Expr(StmtExprClass, T), SubStmt(substmt),  LParenLoc(lp), RParenLoc(rp) {
+    }
+  
+  CompoundStmt *getSubStmt() { return SubStmt; }
+  const CompoundStmt *getSubStmt() const { return SubStmt; }
+  
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(LParenLoc, RParenLoc);
+  }
   
+  virtual void visit(StmtVisitor &Visitor);
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == StmtExprClass; 
+  }
+  static bool classof(const StmtExpr *) { return true; }
+};
+
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Jul 24 11:58:17 2007
@@ -107,13 +107,17 @@
   CompoundStmt(Stmt **StmtStart, unsigned NumStmts)
     : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {}
   
+  bool body_empty() const { return Body.empty(); }
+  
   typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
   body_iterator body_begin() { return Body.begin(); }
   body_iterator body_end() { return Body.end(); }
+  Stmt *body_back() { return Body.back(); }
 
   typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
   const_body_iterator body_begin() const { return Body.begin(); }
   const_body_iterator body_end() const { return Body.end(); }
+  const Stmt *body_back() const { return Body.back(); }
   
   void push_back(Stmt *S) { Body.push_back(S); }
     

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Tue Jul 24 11:58:17 2007
@@ -65,11 +65,12 @@
 
 // GNU Extensions.
 STMT(49, AddrLabel            , Expr)
+STMT(50, StmtExpr             , Expr)
 
 // C++ Expressions.
-STMT(50, CXXCastExpr          , Expr)
-STMT(51, CXXBoolLiteralExpr   , Expr)
-LAST_EXPR(51)
+STMT(51, CXXCastExpr          , Expr)
+STMT(52, CXXBoolLiteralExpr   , Expr)
+LAST_EXPR(52)
 
 #undef STMT
 #undef FIRST_STMT

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=40465&r1=40464&r2=40465&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jul 24 11:58:17 2007
@@ -364,11 +364,19 @@
     return 0;
   }
   
+  //===---------------------- GNU Extension Expressions -------------------===//
+
   virtual ExprResult ParseAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
                                     IdentifierInfo *LabelII) { // "&&foo"
     return 0;
   }
   
+  virtual ExprResult ParseStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
+                                   SourceLocation RPLoc) { // "({..})"
+    return 0;
+  }
+
+  //===------------------------- C++ Expressions --------------------------===//
   
   /// ParseCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
   virtual ExprResult ParseCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,

Added: cfe/trunk/test/Sema/stmt_exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/stmt_exprs.c?rev=40465&view=auto

==============================================================================
--- cfe/trunk/test/Sema/stmt_exprs.c (added)
+++ cfe/trunk/test/Sema/stmt_exprs.c Tue Jul 24 11:58:17 2007
@@ -0,0 +1,12 @@
+// clang %s -fsyntax-only
+
+typedef unsigned __uint32_t;
+
+#define __byte_swap_int_var(x) \
+__extension__ ({ register __uint32_t __X = (x); \
+   __asm ("bswap %0" : "+r" (__X)); \
+   __X; })
+
+int test(int _x) {
+ return (__byte_swap_int_var(_x));
+}





More information about the cfe-commits mailing list