aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/CompilationUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/CodeGen/CompilationUnit.cpp')
-rw-r--r--backend/lib/CodeGen/CompilationUnit.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/backend/lib/CodeGen/CompilationUnit.cpp b/backend/lib/CodeGen/CompilationUnit.cpp
index 1de6487..5ec54bc 100644
--- a/backend/lib/CodeGen/CompilationUnit.cpp
+++ b/backend/lib/CodeGen/CompilationUnit.cpp
@@ -28,6 +28,10 @@ Expected<MachineFunction *> CompilationUnit::createMachineFunction(std::string N
return makeUnexpected(ErrorCode::InvalidArgument,
"machine function name is already present in the compilation unit");
}
+ if (GlobalNameToIndex.contains(Name)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine function name conflicts with a global object");
+ }
auto StableID = FunctionIDGenerator.allocate();
if (!StableID)
@@ -43,6 +47,27 @@ Expected<MachineFunction *> CompilationUnit::createMachineFunction(std::string N
return Result;
}
+Expected<GlobalObjectDesc *> CompilationUnit::addGlobalObject(GlobalObjectDesc Object) {
+ auto Verification = Object.verify();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ if (FunctionNameToIndex.contains(Object.Symbol)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "global object symbol conflicts with a machine function");
+ }
+ if (GlobalNameToIndex.contains(Object.Symbol)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "global object symbol is already present in the compilation unit");
+ }
+
+ const std::size_t Index = GlobalObjects.size();
+ auto Storage = std::make_unique<GlobalObjectDesc>(std::move(Object));
+ GlobalObjectDesc *Result = Storage.get();
+ GlobalNameToIndex.emplace(Result->Symbol, Index);
+ GlobalObjects.push_back(std::move(Storage));
+ return Result;
+}
+
MachineFunction *CompilationUnit::functionAt(std::size_t Index) noexcept {
if (Index >= Functions.size())
return nullptr;
@@ -85,11 +110,33 @@ const MachineFunction *CompilationUnit::function(MachineFunctionStableID ID) con
return nullptr;
}
+GlobalObjectDesc *CompilationUnit::globalObjectAt(std::size_t Index) noexcept {
+ return Index < GlobalObjects.size() ? GlobalObjects[Index].get() : nullptr;
+}
+
+const GlobalObjectDesc *CompilationUnit::globalObjectAt(std::size_t Index) const noexcept {
+ return Index < GlobalObjects.size() ? GlobalObjects[Index].get() : nullptr;
+}
+
+GlobalObjectDesc *CompilationUnit::globalObject(std::string_view Name) noexcept {
+ const auto Position = GlobalNameToIndex.find(Name);
+ return Position == GlobalNameToIndex.end() ? nullptr : GlobalObjects[Position->second].get();
+}
+
+const GlobalObjectDesc *CompilationUnit::globalObject(std::string_view Name) const noexcept {
+ const auto Position = GlobalNameToIndex.find(Name);
+ return Position == GlobalNameToIndex.end() ? nullptr : GlobalObjects[Position->second].get();
+}
+
Expected<void> CompilationUnit::verify() const {
if (FunctionNameToIndex.size() != Functions.size()) {
return makeUnexpected(ErrorCode::VerificationError,
"compilation unit function name index has an inconsistent size");
}
+ if (GlobalNameToIndex.size() != GlobalObjects.size()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "compilation unit global object name index has an inconsistent size");
+ }
std::unordered_set<MachineFunctionStableID> StableIDs;
for (std::size_t Index = 0; Index < Functions.size(); ++Index) {
@@ -112,6 +159,30 @@ Expected<void> CompilationUnit::verify() const {
return makeUnexpected(ErrorCode::VerificationError,
"compilation unit function name index is inconsistent");
}
+ if (GlobalNameToIndex.contains(Function->name())) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "function name conflicts with a global object symbol");
+ }
+ }
+
+ for (std::size_t Index = 0; Index < GlobalObjects.size(); ++Index) {
+ const std::unique_ptr<GlobalObjectDesc> &Object = GlobalObjects[Index];
+ if (Object == nullptr) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "compilation unit contains a null global object");
+ }
+ auto ObjectVerification = Object->verify();
+ if (!ObjectVerification)
+ return std::unexpected(ObjectVerification.error());
+ const auto Position = GlobalNameToIndex.find(Object->Symbol);
+ if (Position == GlobalNameToIndex.end() || Position->second != Index) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "compilation unit global object name index is inconsistent");
+ }
+ if (FunctionNameToIndex.contains(Object->Symbol)) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "global object symbol conflicts with a function name");
+ }
}
return {};
}