#include "CGContext.h"
#include "CGContextImpl.h"
#include "CGModule.h"
#include "cangjie/Option/Option.h"
namespace Cangjie {
namespace CodeGen {
#ifdef CANGJIE_CODEGEN_CJNATIVE_BACKEND
CGContext::CGContext(const SubCHIRPackage& subCHIRPackage, CGPkgContext& cgPkgContext)
: cgPkgContext(cgPkgContext), subCHIRPackage(subCHIRPackage), llvmContext(nullptr)
{
llvmContext = new llvm::LLVMContext();
llvmContext->setOpaquePointers(cgPkgContext.GetGlobalOptions().enableOpaque);
impl = std::make_unique<CGContextImpl>();
}
#endif
CGContext::~CGContext() = default;
llvm::StructType* CGContext::GetCjStringType() const
{
auto p1i8Type = llvm::Type::getInt8PtrTy(*llvmContext, 1u);
auto int32Type = llvm::Type::getInt32Ty(*llvmContext);
const std::string stringTypeStr = "record.std.core:String";
if (auto stringType = llvm::StructType::getTypeByName(*llvmContext, stringTypeStr)) {
return stringType;
} else {
return llvm::StructType::create(*llvmContext, {p1i8Type, int32Type, int32Type}, stringTypeStr);
}
}
void CGContext::Add2CGTypePool(CGType* cgType)
{
impl->cgTypePool.emplace_back(cgType);
}
void CGContext::Clear()
{
impl->Clear();
cjStrings.clear();
generatedStructType.clear();
globalsOfCompileUnit.clear();
#ifdef CANGJIE_CODEGEN_CJNATIVE_BACKEND
llvmUsedGVs.clear();
subCHIRPackage.Clear();
callBasesToInline.clear();
callBasesToReplace.clear();
debugLocOfRetExpr.clear();
virtualCallInfo4LICMMap.clear();
#endif
}
#ifdef CANGJIE_CODEGEN_CJNATIVE_BACKEND
llvm::Value* CGContext::GetBasePtrOf(llvm::Value* val) const
{
if (auto it = impl->valueAndBasePtrMap.find(val); it != impl->valueAndBasePtrMap.end()) {
return it->second;
}
return nullptr;
}
void CGContext::SetBasePtr(const llvm::Value* val, llvm::Value* basePtr)
{
impl->valueAndBasePtrMap[val] = basePtr;
}
#endif
void CGContext::PushUnwindBlockStack(llvm::BasicBlock* unwindBlock)
{
unwindBlockStack.push(unwindBlock);
}
std::optional<llvm::BasicBlock*> CGContext::TopUnwindBlockStack() const
{
if (unwindBlockStack.empty() || unwindBlockStack.top() == nullptr) {
return std::nullopt;
} else {
return unwindBlockStack.top();
}
}
void CGContext::PopUnwindBlockStack()
{
if (!unwindBlockStack.empty()) {
unwindBlockStack.pop();
}
}
void CGContext::AddGeneratedStructType(const std::string& structTypeName)
{
CJC_ASSERT(!structTypeName.empty());
generatedStructType.emplace(structTypeName);
}
const std::set<std::string>& CGContext::GetGeneratedStructType() const
{
return generatedStructType;
}
bool CGContext::IsGeneratedStructType(const std::string& structTypeName)
{
return generatedStructType.find(structTypeName) != generatedStructType.end();
}
void CGContext::AddGlobalsOfCompileUnit(const std::string& globalsName)
{
globalsOfCompileUnit.emplace(globalsName);
}
bool CGContext::IsGlobalsOfCompileUnit(const std::string& globalsName)
{
return globalsOfCompileUnit.find(globalsName) != globalsOfCompileUnit.end();
}
#ifdef CANGJIE_CODEGEN_CJNATIVE_BACKEND
void CGContext::AddNullableReference(llvm::Value* value)
{
(void)impl->nullableReference.emplace(value);
}
#endif
}
}