8 #include "diagnostics/Location.h"
9 #include "parsetree/ParseTree.h"
10 #include "utils/BumpAllocator.h"
11 #include "utils/DotPrinter.h"
12 #include "utils/Generator.h"
13 #include "utils/Utils.h"
17 using utils::DotPrinter;
20 using pmr_vector = std::pmr::vector<T>;
22 using array_ref = std::pmr::vector<T>&;
23 using std::string_view;
44 AstNode(
const AstNode&) =
delete;
50 std::ostream& printDot(std::ostream& os)
const {
59 virtual std::ostream& print(std::ostream& os,
int indentation = 0)
const = 0;
60 virtual ~AstNode() =
default;
61 virtual int printDotNode(DotPrinter& dp)
const = 0;
77 static std::string
indent(
int indentation) {
78 return std::string(indentation * 2,
' ');
89 Decl(BumpAllocator& alloc, std::string_view name)
noexcept
90 : canonicalName_{alloc}, name_{name, alloc}, parent_{
nullptr} {}
93 std::string_view
name()
const {
return name_; }
98 assert(parent_ ==
nullptr);
104 assert(hasCanonicalName() &&
"Does not have a canonical name.");
105 assert(parent_ !=
nullptr &&
"Canonical name requires a non-null parent.");
106 return canonicalName_;
114 virtual DeclContext const* asDeclContext()
const {
return nullptr; }
117 std::pmr::string canonicalName_;
120 std::pmr::string name_;
134 if(
auto decl = dyn_cast_or_null<
Decl>(child)) {
135 assert(decl->parent() ==
this &&
136 "child declaration of this context has wrong the parent!");
143 virtual Decl const* asDecl()
const {
return nullptr; }
150 class UnresolvedType;
155 virtual void ResolveType(UnresolvedType* type) = 0;
162 virtual string_view toString()
const = 0;
163 virtual std::ostream& print(std::ostream& os,
164 int indentation = 0)
const override = 0;
165 int printDotNode(DotPrinter& dp)
const override {
175 virtual bool operator==(
const Type&)
const = 0;
176 virtual bool operator!=(
const Type& other) {
return !(*
this == other); }
184 virtual bool isInvalid()
const {
return false; }
185 virtual bool isNumeric()
const {
return false; }
186 virtual bool isBoolean()
const {
return false; }
187 virtual bool isNull()
const {
return false; }
188 virtual bool isString()
const {
return false; }
189 virtual bool isArray()
const {
return false; }
190 virtual bool isPrimitive()
const {
return false; }
191 virtual bool isReference()
const {
return false; }
193 virtual ast::
Decl const* getAsDecl()
const {
return nullptr; }
213 for(
auto const* expr :
exprs())
co_yield const_cast<
Expr*>(expr);
222 std::ostream& operator<<(std::ostream& os,
const AstNode& astNode);
234 template <std::ranges::range Range>
235 requires std::is_convertible_v<std::ranges::range_value_t<Range>, ast::AstNode*>
236 int printDotNodeList(DotPrinter& dp, Range&& range) {
237 int childIdFirst = -1;
238 int childIdLast = -1;
239 for(
auto p : range) {
240 int childId = p->printDotNode(dp);
241 if(childIdLast != -1)
244 childIdFirst = childId;
245 childIdLast = childId;
259 std::pair<
int,
int> printStmtSubgraph(utils::
DotPrinter& dp, ast::
Stmt* stmt);
287 bool wasSet = test(modifiers, target);
288 modifiers |= (1 << (uint8_t)target);
297 for(
int i = 0; i < (
int)Type::NumModifiers; i++) {
298 if(test(target.modifiers, (Type)i)) {
299 wasSet |=
set((Type)i
);
309 auto masked = target.modifiers & modifiers;
310 return std::views::iota(0, (
int)Type::NumModifiers) |
312 [masked](
int i) {
return (masked & (1 << i)) != 0; }) |
313 std::views::transform([
this](
int i) {
return modifierLocations[i]; });
319 return modifierLocations[(
int)modifier];
322 bool isPublic()
const {
return test(modifiers, Type::Public); }
323 bool isProtected()
const {
return test(modifiers, Type::Protected); }
324 bool isStatic()
const {
return test(modifiers, Type::Static); }
325 bool isFinal()
const {
return test(modifiers, Type::Final); }
326 bool isAbstract()
const {
return test(modifiers, Type::Abstract); }
327 bool isNative()
const {
return test(modifiers, Type::Native); }
329 std::string toString()
const;
332 SourceRange modifierLocations[(
int)Type::NumModifiers];
333 uint8_t modifiers = 0;
335 static constexpr int test(uint8_t value, Type bit) {
336 return (value & (1 << (uint8_t)bit)) != 0;
349 class ScopeID
final {
351 ScopeID(ScopeID
const* parent,
int pos) : parent_{parent}, pos_{pos} {}
361 ScopeID
const*
next(BumpAllocator& alloc, ScopeID
const* parent)
const {
362 void* mem = alloc.allocate_bytes(
sizeof(ScopeID),
alignof(ScopeID));
363 return new(mem) ScopeID{parent, pos_ + 1};
371 bool canView(ScopeID
const* other)
const;
373 const ScopeID* parent()
const {
return parent_; }
375 static const ScopeID* New(BumpAllocator& alloc) {
376 void* mem = alloc.allocate_bytes(
sizeof(ScopeID),
alignof(ScopeID));
377 return new(mem) ScopeID{
nullptr, 0};
381 std::string toString()
const;
382 std::ostream& print(std::ostream& os)
const;
384 friend std::ostream& operator<<(std::ostream& os,
const ScopeID& id) {
385 return os << id.toString();
389 const ScopeID*
const parent_;