mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Define a base class for all AST nodes. (#947)
Also implement code-generation to manage the resulting boilerplate.
This commit is contained in:
@@ -31,14 +31,9 @@ class StaticScope;
|
||||
// every concrete derived class must have a corresponding enumerator
|
||||
// in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
|
||||
// details.
|
||||
class Declaration : public NamedEntityInterface {
|
||||
class Declaration : public virtual AstNode, public NamedEntity {
|
||||
public:
|
||||
enum class Kind {
|
||||
FunctionDeclaration,
|
||||
ClassDeclaration,
|
||||
ChoiceDeclaration,
|
||||
VariableDeclaration,
|
||||
};
|
||||
~Declaration() override = 0;
|
||||
|
||||
Declaration(const Member&) = delete;
|
||||
auto operator=(const Member&) -> Declaration& = delete;
|
||||
@@ -46,15 +41,15 @@ class Declaration : public NamedEntityInterface {
|
||||
void Print(llvm::raw_ostream& out) const;
|
||||
LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
|
||||
|
||||
// Returns the enumerator corresponding to the most-derived type of this
|
||||
// object.
|
||||
auto kind() const -> Kind { return kind_; }
|
||||
|
||||
auto named_entity_kind() const -> NamedEntityKind override {
|
||||
return NamedEntityKind::Declaration;
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromDeclaration(node->kind());
|
||||
}
|
||||
|
||||
auto source_loc() const -> SourceLocation override { return source_loc_; }
|
||||
// Returns the enumerator corresponding to the most-derived type of this
|
||||
// object.
|
||||
auto kind() const -> DeclarationKind {
|
||||
return static_cast<DeclarationKind>(root_kind());
|
||||
}
|
||||
|
||||
// The static type of the declared entity. Cannot be called before
|
||||
// typechecking.
|
||||
@@ -73,33 +68,30 @@ class Declaration : public NamedEntityInterface {
|
||||
// Constructs a Declaration representing syntax at the given line number.
|
||||
// `kind` must be the enumerator corresponding to the most-derived type being
|
||||
// constructed.
|
||||
Declaration(Kind kind, SourceLocation source_loc)
|
||||
: kind_(kind), source_loc_(source_loc) {}
|
||||
Declaration() = default;
|
||||
|
||||
private:
|
||||
const Kind kind_;
|
||||
SourceLocation source_loc_;
|
||||
std::optional<Nonnull<const Value*>> static_type_;
|
||||
};
|
||||
|
||||
// TODO: expand the kinds of things that can be deduced parameters.
|
||||
// For now, only generic parameters are supported.
|
||||
struct GenericBinding : public NamedEntityInterface {
|
||||
struct GenericBinding : public virtual AstNode, public NamedEntity {
|
||||
public:
|
||||
GenericBinding(SourceLocation source_loc, std::string name,
|
||||
Nonnull<Expression*> type)
|
||||
: source_loc_(source_loc), name_(std::move(name)), type_(type) {}
|
||||
: AstNode(AstNodeKind::GenericBinding, source_loc),
|
||||
name_(std::move(name)),
|
||||
type_(type) {}
|
||||
|
||||
auto named_entity_kind() const -> NamedEntityKind override {
|
||||
return NamedEntityKind::GenericBinding;
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromGenericBinding(node->kind());
|
||||
}
|
||||
|
||||
auto source_loc() const -> SourceLocation override { return source_loc_; }
|
||||
auto name() const -> const std::string& { return name_; }
|
||||
auto type() const -> const Expression& { return *type_; }
|
||||
|
||||
private:
|
||||
SourceLocation source_loc_;
|
||||
std::string name_;
|
||||
Nonnull<Expression*> type_;
|
||||
};
|
||||
@@ -190,15 +182,15 @@ class FunctionDeclaration : public Declaration {
|
||||
Nonnull<TuplePattern*> param_pattern,
|
||||
ReturnTerm return_term,
|
||||
std::optional<Nonnull<Block*>> body)
|
||||
: Declaration(Kind::FunctionDeclaration, source_loc),
|
||||
: AstNode(AstNodeKind::FunctionDeclaration, source_loc),
|
||||
name_(std::move(name)),
|
||||
deduced_parameters_(std::move(deduced_params)),
|
||||
param_pattern_(param_pattern),
|
||||
return_term_(return_term),
|
||||
body_(body) {}
|
||||
|
||||
static auto classof(const Declaration* decl) -> bool {
|
||||
return decl->kind() == Kind::FunctionDeclaration;
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromFunctionDeclaration(node->kind());
|
||||
}
|
||||
|
||||
void PrintDepth(int depth, llvm::raw_ostream& out) const;
|
||||
@@ -232,12 +224,12 @@ class ClassDeclaration : public Declaration {
|
||||
public:
|
||||
ClassDeclaration(SourceLocation source_loc, std::string name,
|
||||
std::vector<Nonnull<Member*>> members)
|
||||
: Declaration(Kind::ClassDeclaration, source_loc),
|
||||
: AstNode(AstNodeKind::ClassDeclaration, source_loc),
|
||||
name_(std::move(name)),
|
||||
members_(std::move(members)) {}
|
||||
|
||||
static auto classof(const Declaration* decl) -> bool {
|
||||
return decl->kind() == Kind::ClassDeclaration;
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromClassDeclaration(node->kind());
|
||||
}
|
||||
|
||||
auto name() const -> const std::string& { return name_; }
|
||||
@@ -253,42 +245,41 @@ class ClassDeclaration : public Declaration {
|
||||
StaticScope static_scope_;
|
||||
};
|
||||
|
||||
class ChoiceDeclaration : public Declaration {
|
||||
class AlternativeSignature : public virtual AstNode, public NamedEntity {
|
||||
public:
|
||||
class Alternative : public NamedEntityInterface {
|
||||
public:
|
||||
Alternative(SourceLocation source_loc, std::string name,
|
||||
Nonnull<Expression*> signature)
|
||||
: source_loc_(source_loc),
|
||||
name_(std::move(name)),
|
||||
signature_(signature) {}
|
||||
|
||||
auto named_entity_kind() const -> NamedEntityKind override {
|
||||
return NamedEntityKind::ChoiceDeclarationAlternative;
|
||||
}
|
||||
|
||||
auto source_loc() const -> SourceLocation override { return source_loc_; }
|
||||
auto name() const -> const std::string& { return name_; }
|
||||
auto signature() const -> const Expression& { return *signature_; }
|
||||
|
||||
private:
|
||||
SourceLocation source_loc_;
|
||||
std::string name_;
|
||||
Nonnull<Expression*> signature_;
|
||||
};
|
||||
|
||||
ChoiceDeclaration(SourceLocation source_loc, std::string name,
|
||||
std::vector<Nonnull<Alternative*>> alternatives)
|
||||
: Declaration(Kind::ChoiceDeclaration, source_loc),
|
||||
AlternativeSignature(SourceLocation source_loc, std::string name,
|
||||
Nonnull<Expression*> signature)
|
||||
: AstNode(AstNodeKind::AlternativeSignature, source_loc),
|
||||
name_(std::move(name)),
|
||||
alternatives_(std::move(alternatives)) {}
|
||||
signature_(signature) {}
|
||||
|
||||
static auto classof(const Declaration* decl) -> bool {
|
||||
return decl->kind() == Kind::ChoiceDeclaration;
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromAlternativeSignature(node->kind());
|
||||
}
|
||||
|
||||
auto name() const -> const std::string& { return name_; }
|
||||
auto alternatives() const -> llvm::ArrayRef<Nonnull<const Alternative*>> {
|
||||
auto signature() const -> const Expression& { return *signature_; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
Nonnull<Expression*> signature_;
|
||||
};
|
||||
|
||||
class ChoiceDeclaration : public Declaration {
|
||||
public:
|
||||
ChoiceDeclaration(SourceLocation source_loc, std::string name,
|
||||
std::vector<Nonnull<AlternativeSignature*>> alternatives)
|
||||
: AstNode(AstNodeKind::ChoiceDeclaration, source_loc),
|
||||
name_(std::move(name)),
|
||||
alternatives_(std::move(alternatives)) {}
|
||||
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromChoiceDeclaration(node->kind());
|
||||
}
|
||||
|
||||
auto name() const -> const std::string& { return name_; }
|
||||
auto alternatives() const
|
||||
-> llvm::ArrayRef<Nonnull<const AlternativeSignature*>> {
|
||||
return alternatives_;
|
||||
}
|
||||
|
||||
@@ -298,7 +289,7 @@ class ChoiceDeclaration : public Declaration {
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::vector<Nonnull<Alternative*>> alternatives_;
|
||||
std::vector<Nonnull<AlternativeSignature*>> alternatives_;
|
||||
StaticScope static_scope_;
|
||||
};
|
||||
|
||||
@@ -308,12 +299,12 @@ class VariableDeclaration : public Declaration {
|
||||
VariableDeclaration(SourceLocation source_loc,
|
||||
Nonnull<BindingPattern*> binding,
|
||||
Nonnull<Expression*> initializer)
|
||||
: Declaration(Kind::VariableDeclaration, source_loc),
|
||||
: AstNode(AstNodeKind::VariableDeclaration, source_loc),
|
||||
binding_(binding),
|
||||
initializer_(initializer) {}
|
||||
|
||||
static auto classof(const Declaration* decl) -> bool {
|
||||
return decl->kind() == Kind::VariableDeclaration;
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromVariableDeclaration(node->kind());
|
||||
}
|
||||
|
||||
auto binding() const -> const BindingPattern& { return *binding_; }
|
||||
|
||||
Reference in New Issue
Block a user