Files
carbon-lang/executable_semantics/ast/member.h
T
Jon Meow fd89bcb4aa Convert Pattern and Expression to Ptr (#787)
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.
2021-08-27 09:16:20 -07:00

73 lines
2.2 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_MEMBER_H_
#define EXECUTABLE_SEMANTICS_AST_MEMBER_H_
#include <string>
#include "common/ostream.h"
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/pattern.h"
#include "executable_semantics/ast/source_location.h"
#include "llvm/Support/Compiler.h"
namespace Carbon {
// Abstract base class of all AST nodes representing patterns.
//
// Member and its derived classes support LLVM-style RTTI, including
// llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
// class derived from Member 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 Member {
public:
enum class Kind { FieldMember };
Member(const Member&) = delete;
Member& 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 Member representing syntax at the given line number.
// `tag` must be the enumerator corresponding to the most-derived type being
// constructed.
Member(Kind tag, SourceLocation loc) : tag(tag), loc(loc) {}
private:
const Kind tag;
SourceLocation loc;
};
class FieldMember : public Member {
public:
FieldMember(SourceLocation loc, Ptr<const BindingPattern> binding)
: Member(Kind::FieldMember, loc), binding(binding) {}
static auto classof(const Member* member) -> bool {
return member->Tag() == Kind::FieldMember;
}
auto Binding() const -> Ptr<const BindingPattern> { return binding; }
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;
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_MEMBER_H_