mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-25 06:10:14 +01:00
Sorry about the big change, this is hard to split. ParenContents is used by both, templated, and expects the same pointer type. While I could duplicate ParenContents with some ExpressionParenContents or PatternParenContents, that seems a little kludgy versus a single large change handling both. The worst of it is that Expression is already pretty sweeping, Pattern is really just incrementally adding. That said, I believe this includes a couple fixes I found with incorrect use of dyn_cast in typecheck.cpp (checked nullptr at the wrong step in 2 code locations). There's also a missing `*` in member.cpp this caught. I adjust passing of expressions for Return due to nullness (I felt adding another constructor was the best solution). I add a `.Release()` to BisonWrap due to things like `$3.first` needing some way to work through BIsonWrap. I felt this was better than `operator->`, but feel free to comment if you prefer the other path (`.Release()` conveniently lets me do pair unwrapping, so it felt a better solution). I do add a TODO to think about better Ptr-to-Ptr cast<> support too, though, as that doesn't work cleanly with LLVM's infra. But so far it seems to only come up in one spot, so I'm not prioritizing it.
147 lines
4.6 KiB
C++
147 lines
4.6 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
|
|
#define EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
|
|
|
|
#include <list>
|
|
#include <string>
|
|
|
|
#include "common/ostream.h"
|
|
#include "executable_semantics/ast/class_definition.h"
|
|
#include "executable_semantics/ast/function_definition.h"
|
|
#include "executable_semantics/ast/member.h"
|
|
#include "executable_semantics/ast/pattern.h"
|
|
#include "executable_semantics/ast/source_location.h"
|
|
#include "executable_semantics/common/ptr.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
|
|
namespace Carbon {
|
|
|
|
// Abstract base class of all AST nodes representing patterns.
|
|
//
|
|
// Declaration and its derived classes support LLVM-style RTTI, including
|
|
// llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
|
|
// class derived from Declaration must provide a `classof` operation, and
|
|
// every concrete derived class must have a corresponding enumerator
|
|
// in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
|
|
// details.
|
|
class Declaration {
|
|
public:
|
|
enum class Kind {
|
|
FunctionDeclaration,
|
|
ClassDeclaration,
|
|
ChoiceDeclaration,
|
|
VariableDeclaration,
|
|
};
|
|
|
|
Declaration(const Member&) = delete;
|
|
Declaration& operator=(const Member&) = delete;
|
|
|
|
// Returns the enumerator corresponding to the most-derived type of this
|
|
// object.
|
|
auto Tag() const -> Kind { return tag; }
|
|
|
|
auto SourceLoc() const -> SourceLocation { return loc; }
|
|
|
|
void Print(llvm::raw_ostream& out) const;
|
|
|
|
protected:
|
|
// Constructs a Declaration representing syntax at the given line number.
|
|
// `tag` must be the enumerator corresponding to the most-derived type being
|
|
// constructed.
|
|
Declaration(Kind tag, SourceLocation loc) : tag(tag), loc(loc) {}
|
|
|
|
private:
|
|
const Kind tag;
|
|
SourceLocation loc;
|
|
};
|
|
|
|
class FunctionDeclaration : public Declaration {
|
|
public:
|
|
FunctionDeclaration(Ptr<const FunctionDefinition> definition)
|
|
: Declaration(Kind::FunctionDeclaration, definition->source_location),
|
|
definition(definition) {}
|
|
|
|
static auto classof(const Declaration* decl) -> bool {
|
|
return decl->Tag() == Kind::FunctionDeclaration;
|
|
}
|
|
|
|
auto Definition() const -> const FunctionDefinition& { return *definition; }
|
|
|
|
private:
|
|
Ptr<const FunctionDefinition> definition;
|
|
};
|
|
|
|
class ClassDeclaration : public Declaration {
|
|
public:
|
|
ClassDeclaration(SourceLocation loc, std::string name,
|
|
std::list<Ptr<Member>> members)
|
|
: Declaration(Kind::ClassDeclaration, loc),
|
|
definition({.loc = loc,
|
|
.name = std::move(name),
|
|
.members = std::move(members)}) {}
|
|
|
|
static auto classof(const Declaration* decl) -> bool {
|
|
return decl->Tag() == Kind::ClassDeclaration;
|
|
}
|
|
|
|
auto Definition() const -> const ClassDefinition& { return definition; }
|
|
|
|
private:
|
|
ClassDefinition definition;
|
|
};
|
|
|
|
class ChoiceDeclaration : public Declaration {
|
|
public:
|
|
ChoiceDeclaration(
|
|
SourceLocation loc, std::string name,
|
|
std::list<std::pair<std::string, Ptr<const Expression>>> alternatives)
|
|
: Declaration(Kind::ChoiceDeclaration, loc),
|
|
name(std::move(name)),
|
|
alternatives(std::move(alternatives)) {}
|
|
|
|
static auto classof(const Declaration* decl) -> bool {
|
|
return decl->Tag() == Kind::ChoiceDeclaration;
|
|
}
|
|
|
|
auto Name() const -> const std::string& { return name; }
|
|
auto Alternatives() const
|
|
-> const std::list<std::pair<std::string, Ptr<const Expression>>>& {
|
|
return alternatives;
|
|
}
|
|
|
|
private:
|
|
std::string name;
|
|
std::list<std::pair<std::string, Ptr<const Expression>>> alternatives;
|
|
};
|
|
|
|
// Global variable definition implements the Declaration concept.
|
|
class VariableDeclaration : public Declaration {
|
|
public:
|
|
VariableDeclaration(SourceLocation loc, Ptr<const BindingPattern> binding,
|
|
Ptr<const Expression> initializer)
|
|
: Declaration(Kind::VariableDeclaration, loc),
|
|
binding(binding),
|
|
initializer(initializer) {}
|
|
|
|
static auto classof(const Declaration* decl) -> bool {
|
|
return decl->Tag() == Kind::VariableDeclaration;
|
|
}
|
|
|
|
auto Binding() const -> Ptr<const BindingPattern> { return binding; }
|
|
auto Initializer() const -> Ptr<const Expression> { return initializer; }
|
|
|
|
private:
|
|
// TODO: split this into a non-optional name and a type, initialized by
|
|
// a constructor that takes a BindingPattern and handles errors like a
|
|
// missing name.
|
|
Ptr<const BindingPattern> binding;
|
|
Ptr<const Expression> initializer;
|
|
};
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
|