mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 03:36:06 +00:00
Bug #:
Submitted by: Reviewed by: Implement some FIXME's that stand in the way of fully typechecking "for" statements. This involved: - Adding a DeclStmt AST node (with statement visitor). The DeclStmt printer is preliminary. - Added a ParseDeclStmt action, called from Parser::ParseForStatement() and Parser::ParseStatementOrDeclaration(). DID NOT add to Parser::ParseIdentifierStatement()...probably could have, however didn't really understand the context of this rule (will speak with Chris). - Removed ParseExprStmt (and it's clients)...it was vestigial. llvm-svn: 39518
This commit is contained in:
parent
6f49f5df03
commit
2a8ad18e71
@ -109,6 +109,18 @@ void StmtPrinter::VisitNullStmt(NullStmt *Node) {
|
||||
Indent() << ";\n";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
|
||||
// FIXME: Need to complete/beautify this...this code simply shows the
|
||||
// nodes are where they need to be.
|
||||
if (BlockVarDecl *localVar = dyn_cast<BlockVarDecl>(Node->getDecl())) {
|
||||
Indent() << localVar->getType().getAsString();
|
||||
OS << " " << localVar->getName() << ";\n";
|
||||
} else if (TypedefDecl *localType = dyn_cast<TypedefDecl>(Node->getDecl())) {
|
||||
Indent() << "typedef " << localType->getUnderlyingType().getAsString();
|
||||
OS << " " << localType->getName() << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
|
||||
Indent();
|
||||
PrintRawCompoundStmt(Node);
|
||||
|
@ -86,9 +86,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||
default:
|
||||
if (!OnlyStatement && isDeclarationSpecifier()) {
|
||||
// TODO: warn/disable if declaration is in the middle of a block and !C99.
|
||||
ParseDeclaration(Declarator::BlockContext);
|
||||
// FIXME: Make a DeclStmt node!
|
||||
return 0;
|
||||
return Actions.ParseDeclStmt(ParseDeclaration(Declarator::BlockContext));
|
||||
} else if (Tok.getKind() == tok::r_brace) {
|
||||
Diag(Tok, diag::err_expected_statement);
|
||||
return true;
|
||||
@ -102,7 +100,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||
SkipUntil(tok::semi);
|
||||
return true;
|
||||
} else {
|
||||
return Actions.ParseExprStmt(Res.Val);
|
||||
return Res.Val;
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,7 +248,7 @@ Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) {
|
||||
return true;
|
||||
} else {
|
||||
ConsumeToken();
|
||||
return Actions.ParseExprStmt(Res.Val);
|
||||
return Res.Val;
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,19 +584,12 @@ Parser::StmtResult Parser::ParseForStatement() {
|
||||
// Parse declaration, which eats the ';'.
|
||||
if (!getLang().C99) // Use of C99-style for loops in C90 mode?
|
||||
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
|
||||
ParseDeclaration(Declarator::ForContext);
|
||||
// FIXME: Turn declaration into a stmt ast node.
|
||||
FirstPart = 0;
|
||||
DeclTy *aBlockVarDecl = ParseDeclaration(Declarator::ForContext);
|
||||
StmtResult stmtResult = Actions.ParseDeclStmt(aBlockVarDecl);
|
||||
FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
|
||||
} else {
|
||||
Value = ParseExpression();
|
||||
|
||||
// Turn the expression into a stmt.
|
||||
if (!Value.isInvalid) {
|
||||
StmtResult R = Actions.ParseExprStmt(Value.Val);
|
||||
if (!R.isInvalid)
|
||||
FirstPart = R.Val;
|
||||
}
|
||||
|
||||
if (Tok.getKind() == tok::semi) {
|
||||
ConsumeToken();
|
||||
} else {
|
||||
|
@ -143,9 +143,7 @@ public:
|
||||
virtual StmtResult ParseNullStmt(SourceLocation SemiLoc);
|
||||
virtual StmtResult ParseCompoundStmt(SourceLocation L, SourceLocation R,
|
||||
StmtTy **Elts, unsigned NumElts);
|
||||
virtual StmtResult ParseExprStmt(ExprTy *Expr) {
|
||||
return Expr; // Exprs are Stmts.
|
||||
}
|
||||
virtual StmtResult ParseDeclStmt(DeclTy *Decl);
|
||||
virtual StmtResult ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
|
||||
SourceLocation DotDotDotLoc, ExprTy *RHSVal,
|
||||
SourceLocation ColonLoc, StmtTy *SubStmt);
|
||||
|
@ -25,6 +25,9 @@ Sema::StmtResult Sema::ParseNullStmt(SourceLocation SemiLoc) {
|
||||
return new NullStmt(SemiLoc);
|
||||
}
|
||||
|
||||
Sema::StmtResult Sema::ParseDeclStmt(DeclTy *decl) {
|
||||
return decl ? new DeclStmt(static_cast<Decl *>(decl)) : 0;
|
||||
}
|
||||
|
||||
Action::StmtResult
|
||||
Sema::ParseCompoundStmt(SourceLocation L, SourceLocation R,
|
||||
|
@ -21,6 +21,7 @@
|
||||
namespace llvm {
|
||||
namespace clang {
|
||||
class Expr;
|
||||
class Decl;
|
||||
class IdentifierInfo;
|
||||
class StmtVisitor;
|
||||
|
||||
@ -62,6 +63,25 @@ public:
|
||||
static bool classof(const Stmt *) { return true; }
|
||||
};
|
||||
|
||||
/// DeclStmt - Adaptor class for mixing declarations with statements and
|
||||
/// expressions. For example, CompoundStmt mixes statements, expressions
|
||||
/// and declarations (variables, types). Another example is ForStmt, where
|
||||
/// the first statement can be an expression or a declaration.
|
||||
///
|
||||
class DeclStmt : public Stmt {
|
||||
Decl *BlockVarOrTypedefDecl;
|
||||
public:
|
||||
DeclStmt(Decl *D) : Stmt(DeclStmtClass), BlockVarOrTypedefDecl(D) {}
|
||||
|
||||
Decl *getDecl() const { return BlockVarOrTypedefDecl; }
|
||||
|
||||
virtual void visit(StmtVisitor &Visitor);
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == DeclStmtClass;
|
||||
}
|
||||
static bool classof(const DeclStmt *) { return true; }
|
||||
};
|
||||
|
||||
/// NullStmt - This is the null statement ";": C99 6.8.3p3.
|
||||
///
|
||||
class NullStmt : public Stmt {
|
||||
|
@ -38,7 +38,8 @@ STMT(12, IndirectGotoStmt, Stmt)
|
||||
STMT(13, ContinueStmt , Stmt)
|
||||
STMT(14, BreakStmt , Stmt)
|
||||
STMT(15, ReturnStmt , Stmt)
|
||||
LAST_STMT(15)
|
||||
STMT(16, DeclStmt , Stmt)
|
||||
LAST_STMT(16)
|
||||
|
||||
FIRST_EXPR(32)
|
||||
// Expressions.
|
||||
|
@ -180,7 +180,7 @@ public:
|
||||
StmtTy **Elts, unsigned NumElts) {
|
||||
return 0;
|
||||
}
|
||||
virtual StmtResult ParseExprStmt(ExprTy *Expr) {
|
||||
virtual StmtResult ParseDeclStmt(DeclTy *Decl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user