mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
272 lines
8.0 KiB
C++
272 lines
8.0 KiB
C++
//===--- Stmt.h - Swift Language Statement ASTs -----------------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the Stmt class and subclasses.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_AST_STMT_H
|
|
#define SWIFT_AST_STMT_H
|
|
|
|
#include "swift/AST/LLVM.h"
|
|
#include "swift/Basic/SourceLoc.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/PointerUnion.h"
|
|
|
|
namespace swift {
|
|
class ASTContext;
|
|
class Decl;
|
|
class Expr;
|
|
class ASTWalker;
|
|
|
|
enum class StmtKind {
|
|
#define STMT(ID, PARENT) ID,
|
|
#include "swift/AST/StmtNodes.def"
|
|
};
|
|
|
|
/// Stmt - Base class for all statements in swift.
|
|
class Stmt {
|
|
Stmt(const Stmt&) = delete;
|
|
void operator=(const Stmt&) = delete;
|
|
|
|
/// Kind - The subclass of Stmt that this is.
|
|
const StmtKind Kind;
|
|
|
|
public:
|
|
Stmt(StmtKind kind) : Kind(kind) {}
|
|
|
|
StmtKind getKind() const { return Kind; }
|
|
|
|
/// \brief Return the location of the start of the statement.
|
|
SourceLoc getStartLoc() const { return getSourceRange().Start; }
|
|
|
|
/// \brief Return the location of the end of the statement.
|
|
SourceLoc getEndLoc() const { return getSourceRange().End; }
|
|
|
|
SourceRange getSourceRange() const;
|
|
|
|
/// walk - This recursively walks the AST rooted at this statement.
|
|
Stmt *walk(ASTWalker &walker);
|
|
Stmt *walk(ASTWalker &&walker) { return walk(walker); }
|
|
|
|
|
|
void dump() const;
|
|
void print(raw_ostream &OS, unsigned Indent = 0) const;
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const Stmt *) { return true; }
|
|
|
|
enum { Alignment = 8 };
|
|
|
|
// Only allow allocation of Exprs using the allocator in ASTContext
|
|
// or by doing a placement new.
|
|
void *operator new(size_t Bytes, ASTContext &C,
|
|
unsigned Alignment = Stmt::Alignment);
|
|
|
|
// Make placement new and vanilla new/delete illegal for Exprs.
|
|
void *operator new(size_t Bytes) throw() = delete;
|
|
void operator delete(void *Data) throw() = delete;
|
|
void *operator new(size_t Bytes, void *Mem) throw() = delete;
|
|
|
|
};
|
|
|
|
/// ErrorStmt - Represents a semantically erroneous statement in the AST.
|
|
class ErrorStmt : public Stmt {
|
|
SourceRange Range;
|
|
public:
|
|
ErrorStmt(SourceRange Range) : Stmt(StmtKind::Error), Range(Range) {}
|
|
|
|
SourceRange getSourceRange() const { return Range; }
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const ErrorStmt *) { return true; }
|
|
static bool classof(const Stmt *S) {
|
|
return S->getKind() == StmtKind::Error;
|
|
}
|
|
};
|
|
|
|
|
|
/// SemiStmt - A semicolon, the noop statement: ";"
|
|
class SemiStmt : public Stmt {
|
|
SourceLoc Loc;
|
|
|
|
public:
|
|
SemiStmt(SourceLoc Loc) : Stmt(StmtKind::Semi), Loc(Loc) {}
|
|
|
|
SourceLoc getLoc() const { return Loc; }
|
|
|
|
SourceRange getSourceRange() const { return Loc; }
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const SemiStmt *) { return true; }
|
|
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Semi; }
|
|
};
|
|
|
|
/// AssignStmt - A value assignment, like "x = y".
|
|
class AssignStmt : public Stmt {
|
|
Expr *Dest;
|
|
Expr *Src;
|
|
SourceLoc EqualLoc;
|
|
|
|
public:
|
|
AssignStmt(Expr *Dest, SourceLoc EqualLoc, Expr *Src)
|
|
: Stmt(StmtKind::Assign), Dest(Dest), Src(Src), EqualLoc(EqualLoc) {}
|
|
|
|
Expr *getDest() const { return Dest; }
|
|
void setDest(Expr *e) { Dest = e; }
|
|
Expr *getSrc() const { return Src; }
|
|
void setSrc(Expr *e) { Src = e; }
|
|
|
|
SourceLoc getEqualLoc() const { return EqualLoc; }
|
|
|
|
SourceRange getSourceRange() const;
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const AssignStmt *) { return true; }
|
|
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Assign; }
|
|
};
|
|
|
|
|
|
/// BraceStmt - A brace enclosed sequence of expressions, stmts, or decls, like
|
|
/// { 4; 5 }.
|
|
class BraceStmt : public Stmt {
|
|
public:
|
|
typedef llvm::PointerUnion3<Expr*, Stmt*, Decl*> ExprStmtOrDecl;
|
|
|
|
private:
|
|
unsigned NumElements;
|
|
|
|
SourceLoc LBLoc;
|
|
SourceLoc RBLoc;
|
|
|
|
BraceStmt(SourceLoc lbloc, ArrayRef<ExprStmtOrDecl> elements,SourceLoc rbloc);
|
|
ExprStmtOrDecl *getElementsStorage() {
|
|
return reinterpret_cast<ExprStmtOrDecl*>(this + 1);
|
|
}
|
|
const ExprStmtOrDecl *getElementsStorage() const {
|
|
return const_cast<BraceStmt*>(this)->getElementsStorage();
|
|
}
|
|
|
|
public:
|
|
static BraceStmt *create(ASTContext &ctx, SourceLoc lbloc,
|
|
ArrayRef<ExprStmtOrDecl> elements,
|
|
SourceLoc rbloc);
|
|
|
|
SourceLoc getLBraceLoc() const { return LBLoc; }
|
|
SourceLoc getRBraceLoc() const { return RBLoc; }
|
|
|
|
SourceRange getSourceRange() const { return SourceRange(LBLoc, RBLoc); }
|
|
|
|
unsigned getNumElements() const { return NumElements; }
|
|
ArrayRef<ExprStmtOrDecl> getElements() const {
|
|
return ArrayRef<ExprStmtOrDecl>(getElementsStorage(), NumElements);
|
|
}
|
|
ExprStmtOrDecl getElement(unsigned i) const {
|
|
assert(i < NumElements && "index out of range!");
|
|
return getElementsStorage()[i];
|
|
}
|
|
void setElement(unsigned i, ExprStmtOrDecl elt) {
|
|
assert(i < NumElements && "index out of range!");
|
|
getElementsStorage()[i] = elt;
|
|
}
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const BraceStmt *) { return true; }
|
|
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Brace; }
|
|
};
|
|
|
|
/// ReturnStmt - A return statement. Return statements with no specified
|
|
/// subexpression are expanded into a return of the empty tuple in the parser.
|
|
/// return 42
|
|
class ReturnStmt : public Stmt {
|
|
SourceLoc ReturnLoc;
|
|
Expr *Result;
|
|
|
|
public:
|
|
ReturnStmt(SourceLoc ReturnLoc, Expr *Result)
|
|
: Stmt(StmtKind::Return), ReturnLoc(ReturnLoc), Result(Result) {}
|
|
|
|
SourceRange getSourceRange() const;
|
|
SourceLoc getReturnLoc() const { return ReturnLoc; }
|
|
|
|
Expr *getResult() const { return Result; }
|
|
void setResult(Expr *e) { Result = e; }
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const ReturnStmt *) { return true; }
|
|
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Return; }
|
|
};
|
|
|
|
/// IfStmt - if/then/else statement. If no 'else' is specified, then the
|
|
/// ElseLoc location is not specified and the Else statement is null. The
|
|
/// condition of the 'if' is required to have a __builtin_int1 type.
|
|
class IfStmt : public Stmt {
|
|
SourceLoc IfLoc;
|
|
SourceLoc ElseLoc;
|
|
Expr *Cond;
|
|
Stmt *Then;
|
|
Stmt *Else;
|
|
|
|
public:
|
|
IfStmt(SourceLoc IfLoc, Expr *Cond, Stmt *Then, SourceLoc ElseLoc,
|
|
Stmt *Else)
|
|
: Stmt(StmtKind::If),
|
|
IfLoc(IfLoc), ElseLoc(ElseLoc), Cond(Cond), Then(Then), Else(Else) {}
|
|
|
|
SourceLoc getIfLoc() const { return IfLoc; }
|
|
SourceLoc getElseLoc() const { return ElseLoc; }
|
|
|
|
SourceRange getSourceRange() const;
|
|
|
|
Expr *getCond() const { return Cond; }
|
|
void setCond(Expr *e) { Cond = e; }
|
|
|
|
Stmt *getThenStmt() const { return Then; }
|
|
void setThenStmt(Stmt *s) { Then = s; }
|
|
|
|
Stmt *getElseStmt() const { return Else; }
|
|
void setElseStmt(Stmt *s) { Else = s; }
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const IfStmt *) { return true; }
|
|
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::If; }
|
|
};
|
|
|
|
/// WhileStmt - while statement. The condition is required to have a
|
|
/// __builtin_int1 type.
|
|
class WhileStmt : public Stmt {
|
|
SourceLoc WhileLoc;
|
|
Expr *Cond;
|
|
Stmt *Body;
|
|
|
|
public:
|
|
WhileStmt(SourceLoc WhileLoc, Expr *Cond, Stmt *Body)
|
|
: Stmt(StmtKind::While),
|
|
WhileLoc(WhileLoc), Cond(Cond), Body(Body) {}
|
|
|
|
SourceRange getSourceRange() const;
|
|
|
|
Expr *getCond() const { return Cond; }
|
|
void setCond(Expr *e) { Cond = e; }
|
|
|
|
Stmt *getBody() const { return Body; }
|
|
void setBody(Stmt *s) { Body = s; }
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
static bool classof(const WhileStmt *) { return true; }
|
|
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::While; }
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|