aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler
diff options
context:
space:
mode:
Diffstat (limited to 'source/20-codegen-compiler')
-rw-r--r--source/20-codegen-compiler/CodegenModel.cpp106
-rw-r--r--source/20-codegen-compiler/main.cpp17
2 files changed, 66 insertions, 57 deletions
diff --git a/source/20-codegen-compiler/CodegenModel.cpp b/source/20-codegen-compiler/CodegenModel.cpp
index 88439e8..e3fc810 100644
--- a/source/20-codegen-compiler/CodegenModel.cpp
+++ b/source/20-codegen-compiler/CodegenModel.cpp
@@ -294,53 +294,12 @@ COMMIT TRANSACTION;
return nsId;
}
- // TODO maybe merge with Utils::MakeFullName?
- std::string GetNamespaceFullName(int64_t nsId) {
- std::vector<std::string> namespaceNames;
- size_t fullnameLength = 0;
-
- 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);
-
- /* 0th column Id */
- int64_t parentNamespaceId = sqlite3_column_int64(stmt, 1);
- auto nameCstr = (const char*)sqlite3_column_text(stmt, 2);
-
- currentNsId = parentNamespaceId;
- std::string name(nameCstr);
- fullnameLength += name.size() + 2;
- namespaceNames.push_back(std::move(name));
-
- if (parentNamespaceId == kGlobalNamespaceId) {
- break;
- }
- }
- fullnameLength -= 2;
-
- std::string fullname;
- fullname.reserve(fullnameLength);
-
- for (auto it = namespaceNames.rbegin(); it != namespaceNames.rend(); ++it) {
- fullname.append(*it);
- if (std::next(it) != namespaceNames.rend()) {
- fullname.append("::");
- }
- }
-
- return fullname;
+ std::string GetNamespaceFullName(int64_t nsId) const {
+ return GetNamespaceFullNameImpl(nsId, nullptr, 0);
}
- std::string GetDeclFullName(int64_t nsId, std::string_view declName) {
- return GetNamespaceFullName(nsId).append(declName);
+ std::string GetDeclFullName(int64_t nsId, std::string_view declName) const {
+ return GetNamespaceFullNameImpl(nsId, declName.data(), declName.size());
}
/// \return Row ID of the file, or 0 if it currently doesn't exist.
@@ -391,6 +350,59 @@ COMMIT TRANSACTION;
}
private:
+ // TODO maybe merge with Utils::MakeFullName?
+ std::string GetNamespaceFullNameImpl(int64_t nsId, const char* append, size_t appendLength) const {
+ std::vector<std::string> namespaceNames;
+ size_t fullnameLength = 0;
+
+ 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);
+
+ /* 0th column Id */
+ int64_t parentNamespaceId = sqlite3_column_int64(stmt, 1);
+ auto nameCstr = (const char*)sqlite3_column_text(stmt, 2);
+
+ currentNsId = parentNamespaceId;
+ std::string name(nameCstr);
+ fullnameLength += name.size() + 2;
+ namespaceNames.push_back(std::move(name));
+
+ if (parentNamespaceId == kGlobalNamespaceId) {
+ break;
+ }
+ }
+ if (append) {
+ // Already has the '::' at the end
+ fullnameLength += appendLength;
+ } else {
+ fullnameLength -= 2;
+ }
+
+ std::string fullname;
+ fullname.reserve(fullnameLength);
+
+ for (auto it = namespaceNames.rbegin(); it != namespaceNames.rend(); ++it) {
+ fullname.append(*it);
+ if (!append && std::next(it) != namespaceNames.rend()) {
+ fullname.append("::");
+ }
+ }
+ if (append) {
+ fullname += std::string_view(append, appendLength);
+ }
+
+ return fullname;
+ }
+
int64_t FindNamespaceImpl(const DeclNamespace& ns) {
int64_t parentNsRowId;
if (ns.container) {
@@ -606,10 +618,6 @@ void CodegenModelArchive::Store(const CodegenModel& cgModel) {
m->BeginTransaction();
- // TODO why are some namepsaces not found in StoreStruct or StoreEnum calls, if we don't use FindOrStoreNamespace there?
- // since we store all currently scanned namespaces into the model here, does that mean the parser is not correctly picking some of those up?
- // but if the parser is failing, than the DeclThing objects should have a null `container` field?
- // [2022-07-15] I think this bug is fixed, it was caused by FindOrStoreNamespace() not calling sqlite3_reset(), causing a stmt execution state mixup between different namespaces
for (auto&& [DISCARD, ns] : cgm.namespaces) {
// This will insert the namespace if it doesn't exist, or no-op (fetches data) if it already exists
m->FindOrStoreNamespace(&ns);
diff --git a/source/20-codegen-compiler/main.cpp b/source/20-codegen-compiler/main.cpp
index 81b5d23..5350f8e 100644
--- a/source/20-codegen-compiler/main.cpp
+++ b/source/20-codegen-compiler/main.cpp
@@ -593,7 +593,6 @@ struct ParserState {
};
struct ParserOutput {
- CodegenModel model;
CodegenOutput headerOutput;
CodegenOutput sourceOutput;
CodegenOutput standaloneSourceOutput;
@@ -745,7 +744,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
break;
}
- po.currentNamespace = po.model.AddNamespace(DeclNamespace{
+ po.currentNamespace = as.model->AddNamespace(DeclNamespace{
.container = po.currentNamespace,
.name = tokens[idx].text,
});
@@ -817,7 +816,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
// TODO support namespace qualified names
auto baseClassFullname = Utils::MakeFullName(idenTok.text, po.currentNamespace);
- auto baseClassDecl = po.model.FindStruct(baseClassFullname);
+ auto baseClassDecl = as.model->FindStruct(baseClassFullname);
if (baseClassDecl) {
// We silently ignore a non-existent base class, because they may reside in a file that we didn't scan
structDecl.baseClasses.push_back(baseClassDecl);
@@ -844,7 +843,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
{
// Get a pointer to the decl inside CodegenInput's storage
- auto decl = po.model.AddStruct(std::move(fullname), std::move(structDecl));
+ auto decl = as.model->AddStruct(std::move(fullname), std::move(structDecl));
po.currentStruct = decl;
po.currentStructBraceDepth = po.currentBraceDepth;
}
@@ -946,7 +945,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
}
{
- auto decl = po.model.AddEnum(std::move(fullname), std::move(enumDecl));
+ auto decl = as.model->AddEnum(std::move(fullname), std::move(enumDecl));
po.currentEnum = decl;
po.currentEnumBraceDepth = po.currentBraceDepth;
}
@@ -1194,7 +1193,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
Utils::WriteOutputFile(po.standaloneSourceOutput, generatedCppName);
as.modelArchive->DeleteDeclsRelatedToFile(filenameStem);
- as.modelArchive->Store(po.model);
+ // as.modelArchive->Store(po.model);
}
void HandleInputFile(AppState& as, const fs::path& path) {
@@ -1360,10 +1359,10 @@ where --output-dir=<path>: the *directory* to write generated contents to. Thi
// - follow the file links in database, and propagate parsing to those files in the hierarchy
// - pretty much defeats the purpose of using an incremental parser: some classes like GameObject will have links throughout a very large portion of the project code
CodegenModel model;
- CodegenModelArchive archive(as.databaseFilePath);
+ CodegenModelArchive modelArchive(as.databaseFilePath);
as.model = &model;
- as.modelArchive = &archive;
+ as.modelArchive = &modelArchive;
// Positional argument pass
for (int i = 1; i < argc; ++i) {
@@ -1384,6 +1383,8 @@ where --output-dir=<path>: the *directory* to write generated contents to. Thi
}
}
+ modelArchive.Store(model);
+
return 0;
}