| 5125 | } |
| 5126 | |
| 5127 | BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute, addr_ce ceAttrAddr) |
| 5128 | { |
| 5129 | SetAndRestoreValue<bool> prevIgnoreWrites(module->mBfIRBuilder->mIgnoreWrites, true); |
| 5130 | |
| 5131 | module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType); |
| 5132 | if (ceAttrAddr == 0) |
| 5133 | ceAttrAddr = CeMallocZero(customAttribute->mType->mSize) - mMemory.mVals; |
| 5134 | BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr); |
| 5135 | BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType); |
| 5136 | |
| 5137 | auto ctorMethodInstance = module->GetRawMethodInstance(customAttribute->mType, customAttribute->mCtor); |
| 5138 | if (ctorMethodInstance == NULL) |
| 5139 | { |
| 5140 | module->Fail("Attribute ctor failed", targetSrc); |
| 5141 | return ceAttrVal; |
| 5142 | } |
| 5143 | |
| 5144 | SizedArray<BfIRValue, 8> ctorArgs; |
| 5145 | if (!customAttribute->mType->IsValuelessType()) |
| 5146 | ctorArgs.Add(ceAttrVal); |
| 5147 | int paramIdx = 0; |
| 5148 | for (auto& arg : customAttribute->mCtorArgs) |
| 5149 | { |
| 5150 | auto constant = constHolder->GetConstant(arg); |
| 5151 | if (!constant) |
| 5152 | { |
| 5153 | module->AssertErrorState(); |
| 5154 | return ceAttrVal; |
| 5155 | } |
| 5156 | auto paramType = ctorMethodInstance->GetParamType(paramIdx); |
| 5157 | ctorArgs.Add(module->ConstantToCurrent(constant, constHolder, paramType, true)); |
| 5158 | paramIdx++; |
| 5159 | } |
| 5160 | |
| 5161 | BfTypedValue retValue = Call(CeCallSource(targetSrc), module, ctorMethodInstance, ctorArgs, CeEvalFlags_None, NULL); |
| 5162 | if (!retValue) |
| 5163 | return ceAttrVal; |
| 5164 | |
| 5165 | for (auto& setProperty : customAttribute->mSetProperties) |
| 5166 | { |
| 5167 | BfExprEvaluator exprEvaluator(module); |
| 5168 | BfMethodDef* setMethodDef = exprEvaluator.GetPropertyMethodDef(setProperty.mPropertyRef, BfMethodType_PropertySetter, BfCheckedKind_NotSet, ceAttrTypedValue); |
| 5169 | BfMethodInstance* setMethodInstance = NULL; |
| 5170 | if (setMethodDef != NULL) |
| 5171 | setMethodInstance = module->GetRawMethodInstance(customAttribute->mType, setMethodDef); |
| 5172 | if ((setMethodInstance == NULL) || (!setProperty.mParam)) |
| 5173 | { |
| 5174 | module->Fail("Attribute prop failed", targetSrc); |
| 5175 | return ceAttrVal; |
| 5176 | } |
| 5177 | |
| 5178 | SizedArray<BfIRValue, 1> setArgs; |
| 5179 | if (!customAttribute->mType->IsValuelessType()) |
| 5180 | setArgs.Add(ceAttrVal); |
| 5181 | if (!setProperty.mParam.mType->IsValuelessType()) |
| 5182 | { |
| 5183 | auto constant = constHolder->GetConstant(setProperty.mParam.mValue); |
| 5184 | if (!constant) |
no test coverage detected