aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler/CodegenModel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/20-codegen-compiler/CodegenModel.cpp')
-rw-r--r--source/20-codegen-compiler/CodegenModel.cpp295
1 files changed, 85 insertions, 210 deletions
diff --git a/source/20-codegen-compiler/CodegenModel.cpp b/source/20-codegen-compiler/CodegenModel.cpp
index da7a5cc..303ad4e 100644
--- a/source/20-codegen-compiler/CodegenModel.cpp
+++ b/source/20-codegen-compiler/CodegenModel.cpp
@@ -1,6 +1,7 @@
#include "CodegenModel.hpp"
#include "CodegenUtils.hpp"
+#include "SQLiteHelper.hpp"
#include <Macros.hpp>
#include <ScopeGuard.hpp>
@@ -34,55 +35,6 @@ public:
#define CURRENT_DATABASE_VERSION 1
constexpr int64_t kGlobalNamespaceId = 1;
-struct SQLiteDatabase {
- sqlite3* database = nullptr;
-
- ~SQLiteDatabase() {
- // NOTE: calling with NULL is a harmless no-op
- int result = sqlite3_close(database);
- assert(result == SQLITE_OK);
- }
-
- operator sqlite3*() const { return database; }
- sqlite3** operator&() { return &database; }
-};
-
-struct SQLiteStatement {
- sqlite3_stmt* stmt = nullptr;
-
- SQLiteStatement(const SQLiteStatement&) = delete;
- SQLiteStatement& operator=(const SQLiteStatement&) = delete;
-
- SQLiteStatement() = default;
-
- SQLiteStatement(sqlite3* database, std::string_view sql) {
- Initialize(database, sql);
- }
-
- ~SQLiteStatement() {
- // NOTE: calling with NULL is a harmless no-op
- // NOTE: we don't care about the error code, because they are returned if the statement has errored in the most recent execution
- // but deleting it will succeeed anyways
- sqlite3_finalize(stmt);
- }
-
- operator sqlite3_stmt*() const { return stmt; }
- sqlite3_stmt** operator&() { return &stmt; }
-
- void Initialize(sqlite3* database, std::string_view sql) {
- int result = sqlite3_prepare(database, sql.data(), sql.size(), &stmt, nullptr);
- assert(result == SQLITE_OK);
- }
-
- bool InitializeLazily(sqlite3* database, std::string_view sql) {
- if (!stmt) {
- Initialize(database, sql);
- return true;
- }
- return false;
- }
-};
-
namespace {
void PrintErrMsgIfPresent(char*& errMsg) {
if (errMsg) {
@@ -273,19 +225,12 @@ COMMIT TRANSACTION;
return rowId;
}
- sqlite3_stmt* stmt = storeNamespaceStmt;
- int64_t parentRowId = FindOrStoreNamespace(ns->container);
- sqlite3_bind_int64(stmt, 1, parentRowId);
- sqlite3_bind_text(stmt, 2, ns->name.c_str(), ns->name.size(), nullptr);
+ SQLiteRunningStatement rt(storeNamespaceStmt);
+ rt.BindArguments(FindOrStoreNamespace(ns->container), ns->name);
- int result = sqlite3_step(stmt);
- DEFER {
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
- };
- assert(result == SQLITE_ROW);
+ rt.StepAndCheck(SQLITE_ROW);
- auto nsId = sqlite3_column_int64(stmt, 0);
+ auto [nsId] = rt.ResultColumns<int64_t>();
return nsId;
}
@@ -299,17 +244,13 @@ COMMIT TRANSACTION;
/// \return Row ID of the file, or 0 if it currently doesn't exist.
int64_t FindFile(std::string_view filename) {
- sqlite3_stmt* stmt = findFileStmt;
- sqlite3_bind_text(stmt, 1, filename.data(), filename.size(), nullptr);
+ SQLiteRunningStatement rt(findFileStmt);
+ rt.BindArguments(filename);
- int result = sqlite3_step(stmt);
- DEFER {
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
- };
+ int result = rt.Step();
if (result == SQLITE_ROW) {
- auto fileId = sqlite3_column_int64(stmt, 0);
+ auto [fileId] = rt.ResultColumns<int64_t>();
return fileId;
} else {
return 0;
@@ -322,17 +263,12 @@ COMMIT TRANSACTION;
return id;
}
- sqlite3_stmt* stmt = storeFileStmt;
- sqlite3_bind_text(stmt, 1, filename.data(), filename.size(), nullptr);
+ SQLiteRunningStatement rt(storeFileStmt);
+ rt.BindArguments(filename);
- int result = sqlite3_step(stmt);
- DEFER {
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
- };
- assert(result == SQLITE_ROW);
+ rt.StepAndCheck(SQLITE_ROW);
- auto fileId = sqlite3_column_int64(stmt, 0);
+ auto [fileId] = rt.ResultColumns<int64_t>();
return fileId;
}
@@ -353,21 +289,13 @@ private:
sqlite3_stmt* stmt = getNamespaceStmt;
int64_t currentNsId = nsId;
while (true) {
- sqlite3_bind_int64(stmt, 1, currentNsId);
-
- int result = sqlite3_step(stmt);
- DEFER {
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
- };
- assert(result == SQLITE_ROW);
+ SQLiteRunningStatement rt(getNamespaceStmt);
+ rt.BindArguments(currentNsId);
- /* 0th column Id */
- int64_t parentNamespaceId = sqlite3_column_int64(stmt, 1);
- auto nameCstr = (const char*)sqlite3_column_text(stmt, 2);
+ rt.StepAndCheck(SQLITE_ROW);
+ auto [id, parentNamespaceId, name] = rt.ResultColumns<int64_t, int64_t, std::string>();
currentNsId = parentNamespaceId;
- std::string name(nameCstr);
fullnameLength += name.size() + 2;
namespaceNames.push_back(std::move(name));
@@ -415,17 +343,12 @@ private:
int64_t FindNamespaceImpl(const DeclNamespace& ns, int64_t parentNsRowId) {
sqlite3_stmt* stmt = findNamespaceStmt;
- sqlite3_bind_int64(stmt, 1, parentNsRowId);
- sqlite3_bind_text(stmt, 2, ns.name.c_str(), ns.name.size(), nullptr);
-
- int result = sqlite3_step(stmt);
- DEFER {
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
- };
+ SQLiteRunningStatement rt(findNamespaceStmt);
+ rt.BindArguments(parentNsRowId, ns.name);
+ int result = rt.Step();
if (result == SQLITE_ROW) {
- int64_t nsId = sqlite3_column_int64(stmt, 0);
+ auto [nsId] = rt.ResultColumns<int64_t>();
return nsId;
} else {
return 0;
@@ -584,11 +507,9 @@ void CodegenArchiveModel::DeleteDeclsRelatedToFile(std::string_view filename) {
m->deleteEnumDeclByFilenameStmt.stmt,
};
for (auto& stmt : stmtList) {
- sqlite3_bind_text(stmt, 1, filename.data(), filename.size(), nullptr);
- int result = sqlite3_step(stmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
+ SQLiteRunningStatement rt(stmt);
+ rt.BindArguments(filename);
+ rt.StepUntilDone();
}
m->CommitTransaction();
}
@@ -638,91 +559,67 @@ CodegenRuntimeModel CodegenArchiveModel::Load() const {
robin_hood::unordered_map<int64_t, DeclMemberVariable*> propertiesById;
robin_hood::unordered_map<int64_t, DeclMemberFunction*> methodsById;
- // NOTE: this is basically { initializer; while(true) { body; } } in a short form
- // Load structs
- for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructs"sv);;) {
- int result = sqlite3_step(stmt);
- if (result == SQLITE_DONE) {
- break;
- }
+ { // Load structs
+ SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructs"sv);
+ SQLiteRunningStatement rt(stmt);
+ while (true) {
+ int result = rt.StepAndCheckError();
+ if (result == SQLITE_DONE) break;
+ assert(result == SQLITE_ROW);
- if (result == SQLITE_ROW) {
- int64_t id = sqlite3_column_int64(stmt, 9);
- int64_t fileId = sqlite3_column_int64(stmt, 1);
- int64_t nsId = sqlite3_column_int64(stmt, 2);
- std::string_view name((const char*)sqlite3_column_text(stmt, 3));
+ auto [id, fileId, nsId, name] = rt.ResultColumns<int64_t, int64_t, int64_t, std::string_view>();
auto decl = cgModel.AddStruct(m->GetDeclFullName(nsId, name), DeclStruct{});
structsById.try_emplace(id, decl);
-
- continue;
}
-
- // Executing the statement resulted in an error
- assert(false);
}
- // Load struct's base classes
- for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructBaseClassRelations");;) {
- int result = sqlite3_step(stmt);
- if (result == SQLITE_DONE) {
- break;
- }
+ { // Load struct's base classes
+ SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructBaseClassRelations");
+ SQLiteRunningStatement rt(stmt);
+ while (true) {
+ int result = rt.StepAndCheckError();
+ if (result == SQLITE_DONE) break;
+ assert(result == SQLITE_ROW);
- if (result == SQLITE_ROW) {
- int64_t structId = sqlite3_column_int64(stmt, 0);
- int64_t parentStructNsId = sqlite3_column_int64(stmt, 1);
- std::string_view parentStructName((const char*)sqlite3_column_text(stmt, 2));
+ auto [structId, parentStructNsId, parentStructName] = rt.ResultColumns<int64_t, int64_t, std::string_view>();
auto declThis = structsById.at(structId);
auto declParent = cgModel.FindStruct(parentStructName); // TODO namespace
declThis->baseClasses.push_back(declParent);
-
- continue;
}
-
- assert(false);
}
- // Load struct properties
- for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructProperties"sv);;) {
- int result = sqlite3_step(stmt);
- if (result == SQLITE_DONE) {
- break;
- }
+ { // Load struct properties
+ SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructProperties"sv);
+ SQLiteRunningStatement rt(stmt);
+ while (true) {
+ int result = rt.StepAndCheckError();
+ if (result == SQLITE_DONE) break;
+ assert(result == SQLITE_ROW);
- if (result == SQLITE_ROW) {
// TODO
- continue;
}
-
- assert(false);
}
- // Load struct methods
- for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethods"sv);;) {
- int result = sqlite3_step(stmt);
- if (result == SQLITE_DONE) {
- break;
- }
+ { // Load struct methods
+ SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethods"sv);
+ SQLiteRunningStatement rt(stmt);
+ while (true) {
+ int result = rt.StepAndCheckError();
+ if (result == SQLITE_DONE) break;
+ assert(result == SQLITE_ROW);
- if (result == SQLITE_ROW) {
// TODO
- continue;
}
-
- assert(false);
}
- // Load method params
- for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethodParameters"sv);;) {
- int result = sqlite3_step(stmt);
- if (result == SQLITE_DONE) {
- break;
- }
+ { // Load method params
+ SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethodParameters"sv);
+ SQLiteRunningStatement rt(stmt);
+ while (true) {
+ int result = rt.StepAndCheckError();
+ if (result == SQLITE_DONE) break;
+ assert(result == SQLITE_ROW);
- if (result == SQLITE_ROW) {
// TODO
- continue;
}
-
- assert(false);
}
return cgModel;
@@ -764,40 +661,28 @@ INSERT INTO DeclStructProperties(StructId, Name, Type, GetterName, SetterName, I
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
)"""sv);
- int result;
-
- sqlite3_bind_int64(m->storeStructStmt, 1, m->FindOrStoreNamespace(decl.container));
- sqlite3_bind_text(m->storeStructStmt, 2, decl.name.c_str(), decl.name.size(), nullptr);
- sqlite3_bind_int64(m->storeStructStmt, 3, m->FindOrStoreFile(decl.sourceFile));
- sqlite3_bind_int(m->storeStructStmt, 4, decl.generating);
- result = sqlite3_step(m->storeStructStmt);
- assert(result == SQLITE_ROW);
- int64_t structId = sqlite3_column_int64(m->storeStructStmt, 0);
- sqlite3_reset(m->storeStructStmt);
- sqlite3_clear_bindings(m->storeStructStmt);
+ SQLiteRunningStatement rt(m->storeStructStmt);
+ rt.BindArguments(m->FindOrStoreNamespace(decl.container), decl.name, m->FindOrStoreFile(decl.sourceFile), decl.generating);
+ rt.StepAndCheck(SQLITE_ROW);
+ auto [structId] = rt.ResultColumns<int64_t>();
for (auto& baseClass : decl.baseClasses) {
- sqlite3_bind_int64(m->storeStructBaseClassStmt, 1, structId);
- sqlite3_bind_int64(m->storeStructBaseClassStmt, 2, m->FindOrStoreNamespace(baseClass->container));
- sqlite3_bind_text(m->storeStructBaseClassStmt, 3, baseClass->name.c_str(), baseClass->name.size(), nullptr);
- int result = sqlite3_step(m->storeStructBaseClassStmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(m->storeStructBaseClassStmt);
- sqlite3_clear_bindings(m->storeStructBaseClassStmt);
+ SQLiteRunningStatement rt(m->storeStructBaseClassStmt);
+ rt.BindArguments(structId, m->FindOrStoreNamespace(baseClass->container), baseClass->name);
+ rt.StepUntilDone();
}
for (auto& property : decl.memberVariables) {
- sqlite3_bind_int64(m->storeStructPropertyStmt, 1, structId);
- sqlite3_bind_text(m->storeStructPropertyStmt, 2, property.name.c_str(), property.name.size(), nullptr);
- sqlite3_bind_text(m->storeStructPropertyStmt, 3, property.type.c_str(), property.type.size(), nullptr);
- sqlite3_bind_text(m->storeStructPropertyStmt, 4, property.getterName.c_str(), property.getterName.size(), nullptr);
- sqlite3_bind_text(m->storeStructPropertyStmt, 5, property.setterName.c_str(), property.setterName.size(), nullptr);
- // Since DeclMemberVariable entries currently only exist if it's marked BRUSSEL_PROPERTY
- sqlite3_bind_int(m->storeStructPropertyStmt, 6, true);
- int result = sqlite3_step(m->storeStructPropertyStmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(m->storeStructPropertyStmt);
- sqlite3_clear_bindings(m->storeStructPropertyStmt);
+ SQLiteRunningStatement rt(m->storeStructPropertyStmt);
+ rt.BindArguments(
+ structId,
+ property.name,
+ property.type,
+ property.getterName,
+ property.setterName,
+ // Since DeclMemberVariable entries currently only exist if it's marked BRUSSEL_PROPERTY
+ true);
+ rt.StepUntilDone();
}
for (auto& method : decl.memberFunctions) {
@@ -834,24 +719,14 @@ VALUES (?1, ?2, ?3)
ON CONFLICT DO UPDATE SET Value=?3
)"""sv);
- sqlite3_bind_int(m->storeEnumStmt, 1, m->FindOrStoreNamespace(decl.container));
- sqlite3_bind_text(m->storeEnumStmt, 2, decl.name.c_str(), decl.name.size(), nullptr);
- auto eutName = decl.GetUnderlyingTypeName();
- sqlite3_bind_text(m->storeEnumStmt, 3, eutName.data(), eutName.size(), nullptr);
- sqlite3_bind_int64(m->storeEnumStmt, 4, m->FindOrStoreFile(decl.sourceFile));
- int result = sqlite3_step(m->storeEnumStmt);
- assert(result == SQLITE_ROW);
- auto enumId = sqlite3_column_int64(m->storeEnumStmt, 0);
- sqlite3_reset(m->storeEnumStmt);
- sqlite3_clear_bindings(m->storeEnumStmt);
+ SQLiteRunningStatement rt(m->storeEnumStmt);
+ rt.BindArguments(m->FindOrStoreNamespace(decl.container), decl.name, decl.GetUnderlyingTypeName(), m->FindOrStoreFile(decl.sourceFile));
+ rt.StepAndCheck(SQLITE_ROW);
+ auto [enumId] = rt.ResultColumns<int64_t>();
for (auto& elm : decl.elements) {
- sqlite3_bind_int64(m->storeEnumElmStmt, 1, enumId);
- sqlite3_bind_text(m->storeEnumElmStmt, 2, elm.name.c_str(), elm.name.size(), nullptr);
- sqlite3_bind_int64(m->storeEnumElmStmt, 3, elm.value);
- int result = sqlite3_step(m->storeEnumElmStmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(m->storeEnumElmStmt);
- sqlite3_clear_bindings(m->storeEnumElmStmt);
+ SQLiteRunningStatement rt(m->storeEnumElmStmt);
+ rt.BindArguments(enumId, elm.name, elm.value);
+ rt.StepUntilDone();
}
}