[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