diff options
Diffstat (limited to 'source/20-codegen-compiler/CodegenModel.cpp')
-rw-r--r-- | source/20-codegen-compiler/CodegenModel.cpp | 106 |
1 files changed, 57 insertions, 49 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); |