From 6878183873d0f3ea467b034a5069b87bb898233f Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 21 Sep 2020 23:38:50 -0700 Subject: [PATCH] Support for static field exporting --- IDEHelper/Backend/BeCOFFObject.cpp | 11 +++++++++-- IDEHelper/Backend/BeIRCodeGen.cpp | 13 +++++++++++++ IDEHelper/Backend/BeModule.h | 2 ++ IDEHelper/Compiler/BfCompiler.cpp | 2 ++ IDEHelper/Compiler/BfCompiler.h | 4 ++-- IDEHelper/Compiler/BfIRBuilder.cpp | 6 ++++++ IDEHelper/Compiler/BfIRBuilder.h | 9 +++++++++ IDEHelper/Compiler/BfIRCodeGen.cpp | 7 +++++++ IDEHelper/Compiler/BfModule.cpp | 14 +++++++++++--- 9 files changed, 61 insertions(+), 7 deletions(-) diff --git a/IDEHelper/Backend/BeCOFFObject.cpp b/IDEHelper/Backend/BeCOFFObject.cpp index 93f52234..54896ff8 100644 --- a/IDEHelper/Backend/BeCOFFObject.cpp +++ b/IDEHelper/Backend/BeCOFFObject.cpp @@ -2057,8 +2057,15 @@ void BeCOFFObject::Generate(BeModule* module) mBSSSect.mSizeOverride = (mBSSSect.mSizeOverride + globalVar->mAlign - 1) & ~(globalVar->mAlign - 1); mBSSSect.mAlign = BF_MAX(mBSSSect.mAlign, globalVar->mAlign); sym->mValue = mBSSSect.mSizeOverride; - mBSSSect.mSizeOverride += globalVar->mType->mSize; - } + mBSSSect.mSizeOverride += globalVar->mType->mSize; + } + } + + if (globalVar->mStorageKind == BfIRStorageKind_Export) + { + mDirectives += " "; + mDirectives.Append("/EXPORT:"); + mDirectives.Append(globalVar->mName); } } diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 816e2027..66f8fe29 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -691,6 +691,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) globalVariable->mIsTLS = isTLS; globalVariable->mAlign = varType->mAlign; globalVariable->mUnnamedAddr = false; + globalVariable->mStorageKind = BfIRStorageKind_Normal; if (initializer != NULL) BF_ASSERT(varType->mAlign > 0); @@ -1782,6 +1783,7 @@ void BeIRCodeGen::HandleNextCmd() globalVariable->mName = name; globalVariable->mIsTLS = isTLS; globalVariable->mUnnamedAddr = false; + globalVariable->mStorageKind = BfIRStorageKind_Normal; if (initializer != NULL) { globalVariable->mAlign = varType->mAlign; @@ -1838,6 +1840,17 @@ void BeIRCodeGen::HandleNextCmd() } } break; + case BfIRCmd_GlobalVar_SetStorageKind: + { + CMD_PARAM(BeValue*, val); + CMD_PARAM(int, storageKind); + + BF_ASSERT(BeValueDynCast(val) != NULL); + + auto globalVariable = (BeGlobalVariable*)val; + globalVariable->mStorageKind = (BfIRStorageKind)storageKind; + } + break; case BfIRCmd_GlobalStringPtr: { CMD_PARAM(String, str); diff --git a/IDEHelper/Backend/BeModule.h b/IDEHelper/Backend/BeModule.h index f406f06b..b9359c83 100644 --- a/IDEHelper/Backend/BeModule.h +++ b/IDEHelper/Backend/BeModule.h @@ -415,6 +415,7 @@ public: String mName; BeConstant* mInitializer; BfIRLinkageType mLinkageType; + BfIRStorageKind mStorageKind; bool mIsConstant; bool mIsTLS; int mAlign; @@ -429,6 +430,7 @@ public: if (mInitializer != NULL) mInitializer->HashReference(hashCtx); hashCtx.Mixin(mLinkageType); + hashCtx.Mixin(mStorageKind); hashCtx.Mixin(mIsConstant); hashCtx.Mixin(mIsTLS); hashCtx.Mixin(mAlign); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index f92b513f..4b93745f 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -381,6 +381,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mClassVDataTypeDef = NULL; mCLinkAttributeTypeDef = NULL; mImportAttributeTypeDef = NULL; + mExportAttributeTypeDef = NULL; mCReprAttributeTypeDef = NULL; mUnderlyingArrayAttributeTypeDef = NULL; mAlignAttributeTypeDef = NULL; @@ -6422,6 +6423,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mClassVDataTypeDef = _GetRequiredType("System.ClassVData"); mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute"); mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute"); + mExportAttributeTypeDef = _GetRequiredType("System.ExportAttribute"); mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute"); mUnderlyingArrayAttributeTypeDef = _GetRequiredType("System.UnderlyingArrayAttribute"); mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 9f054caa..0719bf81 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -385,6 +385,7 @@ public: BfTypeDef* mInlineAttributeTypeDef; BfTypeDef* mCLinkAttributeTypeDef; BfTypeDef* mImportAttributeTypeDef; + BfTypeDef* mExportAttributeTypeDef; BfTypeDef* mCReprAttributeTypeDef; BfTypeDef* mUnderlyingArrayAttributeTypeDef; BfTypeDef* mAlignAttributeTypeDef; @@ -404,8 +405,7 @@ public: BfTypeDef* mErrorAttributeTypeDef; BfTypeDef* mWarnAttributeTypeDef; BfTypeDef* mIgnoreErrorsAttributeTypeDef; - BfTypeDef* mReflectAttributeTypeDef; - + BfTypeDef* mReflectAttributeTypeDef; int mCurTypeId; int mTypeInitCount; diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index ef51580e..32ee590c 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -4395,6 +4395,12 @@ void BfIRBuilder::GlobalVar_SetAlignment(BfIRValue globalVar, int alignment) NEW_CMD_INSERTED; } +void BfIRBuilder::GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind) +{ + BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetStorageKind, globalVar, (int)storageKind); + NEW_CMD_INSERTED; +} + BfIRValue BfIRBuilder::CreateGlobalStringPtr(const StringImpl& str) { BfIRValue retVal = WriteCmd(BfIRCmd_GlobalStringPtr, str); diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 6114606f..6ca8cb8d 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -233,6 +233,7 @@ enum BfIRCmd : uint8 BfIRCmd_GlobalVar_SetUnnamedAddr, BfIRCmd_GlobalVar_SetInitializer, BfIRCmd_GlobalVar_SetAlignment, + BfIRCmd_GlobalVar_SetStorageKind, BfIRCmd_GlobalStringPtr, BfIRCmd_CreateBlock, @@ -464,6 +465,13 @@ enum BfIRAtomicOrdering : uint8 BfIRAtomicOrdering_ReturnModified = 0x10 // Generally atomic instructions return original value, this overrides that }; +enum BfIRStorageKind : uint8 +{ + BfIRStorageKind_Normal, + BfIRStorageKind_Import, + BfIRStorageKind_Export +}; + //#define CHECK_CONSTHOLDER struct BfIRRawValue @@ -1164,6 +1172,7 @@ public: void GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr); void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal); void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment); + void GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind); BfIRValue CreateGlobalStringPtr(const StringImpl& str); BfIRBlock CreateBlock(const StringImpl& name, bool addNow = false); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index ff761d3c..0e99f6a5 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -2199,6 +2199,13 @@ void BfIRCodeGen::HandleNextCmd() ((llvm::GlobalVariable*)val)->setAlignment(alignment); } break; + case BfIRCmd_GlobalVar_SetStorageKind: + { + CMD_PARAM(llvm::Value*, val); + CMD_PARAM(int, storageKind); + ((llvm::GlobalVariable*)val)->setDLLStorageClass((llvm::GlobalValue::DLLStorageClassTypes)storageKind); + } + break; case BfIRCmd_GlobalStringPtr: { CMD_PARAM(String, str); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 183f5754..2895efa6 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -3508,7 +3508,13 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo fieldType = fieldType->GetUnderlyingType(); } - if (!field->mIsExtern) + BfIRStorageKind storageKind = BfIRStorageKind_Normal; + if ((fieldInstance->mCustomAttributes != NULL) && (fieldInstance->mCustomAttributes->Get(mCompiler->mExportAttributeTypeDef))) + storageKind = BfIRStorageKind_Export; + else if ((fieldInstance->mCustomAttributes != NULL) && (fieldInstance->mCustomAttributes->Get(mCompiler->mImportAttributeTypeDef))) + storageKind = BfIRStorageKind_Import; + + if ((!field->mIsExtern) && (storageKind != BfIRStorageKind_Import)) initValue = GetDefaultValue(fieldType); if (fieldInstance->mOwner->IsUnspecializedType()) @@ -3531,8 +3537,10 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo initValue, staticVarName, isThreadLocal); - mBfIRBuilder->GlobalVar_SetAlignment(globalVar, fieldType->mAlign); - + mBfIRBuilder->GlobalVar_SetAlignment(globalVar, fieldType->mAlign); + if (storageKind != BfIRStorageKind_Normal) + mBfIRBuilder->GlobalVar_SetStorageKind(globalVar, storageKind); + BF_ASSERT(globalVar); mStaticFieldRefs[fieldInstance] = globalVar; }