aboutsummaryrefslogtreecommitdiff
path: root/src/brussel.codegen.comp/CodegenDecl.hpp
blob: f1ac5b110448e8ceb9468aec5152b0a6c723ee5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once

#include "CodegenOutput.hpp"

#include <string>
#include <vector>

// TODO replace std::string name with std::string_view into the token storage?

struct SourceFile {
	std::string filename;
	CodegenOutput preHeaderOutput;
	CodegenOutput postHeaderOutput;
	CodegenOutput postSourceOutput;
	CodegenOutput tuOutput; // "tu" = Translation Unit, produces a separately compiled .cpp file
	bool header = false;
	/// Whether this file is being reprocessed in this invocation of codegen.exe or not.
	bool reprocessing = false;
};

struct DeclNamespace {
	// NOTE: namespace doesn't have a source file field, because the same namespace can be "reopened" in multipled files

	DeclNamespace* container = nullptr;
	std::string name;
	const std::string* fullname = nullptr; // View into storage map key
};

struct DeclStruct;
struct DeclMemberVariable {
	DeclStruct* containerStruct = nullptr;
	std::string name;
	std::string type;
	std::string getterName;
	std::string setterName;
	bool isGetterGenerated = false;
	bool isSetterGenerated = false;
};
struct DeclMemberFunction {
	DeclStruct* containerStruct = nullptr;
	// TODO
};

// Structs or classes
struct DeclStruct {
	SourceFile* sourceFile = nullptr;
	DeclNamespace* container = nullptr;
	std::vector<const DeclStruct*> baseClasses;
	std::vector<DeclMemberVariable> memberVariables;
	std::vector<DeclMemberVariable> generatedVariables;
	std::vector<DeclMemberFunction> memberFunctions;
	std::vector<DeclMemberFunction> generatedFunctions;
	std::string name;
	mutable std::string mangledName;
	const std::string* fullname = nullptr; // View into storage map key

	// Scanned generation options
	bool generating : 1 = false;
	bool generatingInheritanceHiearchy : 1 = false;

	const std::string& GetName() const { return name; }
	const std::string& GetFullName() const { return *fullname; }
	const std::string& GetMangledName() const;
};

struct DeclXGlobalVar {
	std::string name;
	bool hasCtor = false;
	bool hasDtor = false;

	static std::string MangleCtorName(std::string_view targetName);
	std::string GetMangledCtorName() const { return MangleCtorName(name); }
	static std::string MangleDtorName(std::string_view targetName);
	std::string GetMangledDtorName() const { return MangleDtorName(name); }
};

enum EnumUnderlyingType {
	EUT_Int8,
	EUT_Int16,
	EUT_Int32,
	EUT_Int64,
	EUT_Uint8,
	EUT_Uint16,
	EUT_Uint32,
	EUT_Uint64,
	EUT_COUNT,
};

enum EnumValuePattern {
	// The numbers cover n..m with no gaps
	EVP_Continuous,
	// The numbers cover for i in n..m, 1 << i
	// e.g. [0] = 1 << 0,
	//      [1] = 1 << 1.
	//      [2] = 1 << 2. etc.
	EVP_Bits,
	// The numbesr don't have a particular pattern
	EVP_Random,
	EVP_COUNT,
};

struct DeclEnumElement {
	std::string name;
	// TODO support int64_t, etc. enum underlying types
	uint64_t value;
};

struct DeclEnum {
	SourceFile* sourceFile = nullptr;
	DeclNamespace* container = nullptr;
	std::string name;
	mutable std::string mangledName;
	const std::string* fullname = nullptr; // View into storage map key
	std::vector<DeclEnumElement> elements;
	EnumUnderlyingType underlyingType;
	// Start with invalid value, calculate on demand
	mutable EnumValuePattern pattern = EVP_COUNT;

	// TODO replace this with a regex?
	std::string generateRemovingPrefix;
	std::string generatingAddingPrefix;
	// NOTE: this flag acts as a gate for every specific generating option, must be enabled for them to work
	bool generating : 1 = false;
	bool generateToString : 1 = false;
	bool generateFromString : 1 = false;
	// NOTE: see GenerateForEnum() for the exact heuristics
	bool generateExcludeUseHeuristics : 1 = false;

	const std::string& GetName() const { return name; }
	const std::string& GetFullName() const { return *fullname; }
	const std::string& GetMangledName() const;

	std::string_view GetUnderlyingTypeName() const;

	EnumValuePattern CalcPattern() const;
	EnumValuePattern GetPattern() const;
};

struct DeclFunctionArgument {
	std::string type;
	std::string name;
};

struct DeclFunction {
	SourceFile* sourceFile = nullptr;
	DeclNamespace* container = nullptr;
	// Things like extern, static, etc. that gets written before the function return type
	std::string prefix;
	std::string name;
	const std::string* fullname = nullptr; // View into storage map key
	std::string returnType;
	std::vector<DeclFunctionArgument> arguments;
	std::string body;
};