mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Allow anonymous 'using' fields
This commit is contained in:
parent
613f9c743a
commit
854122cb46
9 changed files with 323 additions and 256 deletions
|
@ -782,6 +782,8 @@ void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl&
|
|||
|
||||
void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, BfFieldInstance* fieldInstance, const StringImpl& filter)
|
||||
{
|
||||
if (fieldDef->mName.IsEmpty())
|
||||
return;
|
||||
int wantPrefixCount = 0;
|
||||
const char* filterStr = filter.c_str();
|
||||
while (filterStr[0] == '@')
|
||||
|
@ -1662,6 +1664,8 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
|||
|
||||
for (auto field : showAttrTypeDef->mFields)
|
||||
{
|
||||
if (field->mName.IsEmpty())
|
||||
continue;
|
||||
if (auto entryAdded = AddEntry(AutoCompleteEntry("field", field->mName + "="), filter))
|
||||
{
|
||||
auto fieldDeclaration = field->GetFieldDeclaration();
|
||||
|
@ -3663,7 +3667,7 @@ void BfAutoComplete::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType,
|
|||
auto parser = typeInst->mTypeDef->GetDefinition()->mSource->ToParser();
|
||||
if (parser == NULL)
|
||||
return;
|
||||
|
||||
|
||||
String fullName = typeInst->mTypeDef->mFullName.ToString();
|
||||
String fieldStr;
|
||||
|
||||
|
|
|
@ -1202,6 +1202,10 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
|
|||
else
|
||||
fieldDef->mUsingProtection = fieldDef->mProtection;
|
||||
}
|
||||
else if (fieldDeclaration->mNameNode == NULL)
|
||||
{
|
||||
fieldDef->mUsingProtection = fieldDef->mProtection;
|
||||
}
|
||||
|
||||
fieldDef->mIsStatic = (fieldDeclaration->mStaticSpecifier != NULL) || fieldDef->mIsConst;
|
||||
fieldDef->mIsVolatile = (fieldDeclaration->mVolatileSpecifier != NULL);
|
||||
|
|
|
@ -3220,265 +3220,282 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
|
||||
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
|
||||
std::function<void(BfType* type, int depth, int byteOffset)> _AddFields = [&](BfType* type, int depth, int byteOffset)
|
||||
{
|
||||
auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
|
||||
if (!fieldInstance->mFieldIncluded)
|
||||
continue;
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
typeInstance = type->ToTypeInstance();
|
||||
if (typeInstance == NULL)
|
||||
return;
|
||||
|
||||
if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
|
||||
continue;
|
||||
|
||||
auto resolvedFieldType = fieldInstance->GetResolvedType();
|
||||
mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration);
|
||||
BfIRType resolvedFieldIRType = MapType(resolvedFieldType);
|
||||
BfIRMDNode resolvedFieldDIType;
|
||||
|
||||
if ((fieldDef != NULL) && (!fieldDef->mIsStatic) && (resolvedFieldType->IsStruct()))
|
||||
PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full);
|
||||
resolvedFieldDIType = DbgGetType(resolvedFieldType);
|
||||
|
||||
if (fieldInstance->IsAppendedObject())
|
||||
resolvedFieldDIType = DbgGetTypeInst(resolvedFieldType->ToTypeInstance());
|
||||
|
||||
if ((fieldDef == NULL) && (typeInstance->IsPayloadEnum()))
|
||||
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
|
||||
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
|
||||
{
|
||||
orderedFields.push_back(fieldInstance);
|
||||
auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
|
||||
if (!fieldInstance->mFieldIncluded)
|
||||
continue;
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
|
||||
int lineNum = 0;
|
||||
int flags = llvm::DINode::FlagPublic;
|
||||
auto fieldType = fieldInstance->mResolvedType;
|
||||
String fieldName = "__bftag";
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
|
||||
resolvedFieldType->mSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
|
||||
flags, resolvedFieldDIType);
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
|
||||
continue;
|
||||
|
||||
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
|
||||
{
|
||||
if (fieldDef->mIsConst)
|
||||
auto resolvedFieldType = fieldInstance->GetResolvedType();
|
||||
mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration);
|
||||
BfIRType resolvedFieldIRType = MapType(resolvedFieldType);
|
||||
BfIRMDNode resolvedFieldDIType;
|
||||
|
||||
if ((fieldDef != NULL) && (!fieldDef->mIsStatic) && (resolvedFieldType->IsStruct()))
|
||||
PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full);
|
||||
resolvedFieldDIType = DbgGetType(resolvedFieldType);
|
||||
|
||||
if (fieldInstance->IsAppendedObject())
|
||||
resolvedFieldDIType = DbgGetTypeInst(resolvedFieldType->ToTypeInstance());
|
||||
|
||||
if ((fieldDef == NULL) && (typeInstance->IsPayloadEnum()))
|
||||
{
|
||||
if (isDefiningModule)
|
||||
orderedFields.push_back(fieldInstance);
|
||||
|
||||
int lineNum = 0;
|
||||
int flags = llvm::DINode::FlagPublic;
|
||||
auto fieldType = fieldInstance->mResolvedType;
|
||||
String fieldName = "__bftag";
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
|
||||
resolvedFieldType->mSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
|
||||
flags, resolvedFieldDIType);
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
|
||||
{
|
||||
if (fieldDef->mIsConst)
|
||||
{
|
||||
if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
|
||||
if ((isDefiningModule) && (depth == 0))
|
||||
{
|
||||
auto payloadType = fieldInstance->mResolvedType;
|
||||
if (payloadType == NULL)
|
||||
payloadType = mModule->CreateTupleType(BfTypeVector(), Array<String>());
|
||||
|
||||
String fieldName = StrFormat("_%d_%s", -fieldInstance->mDataIdx - 1, fieldDef->mName.c_str());
|
||||
|
||||
int flags = 0;
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
BF_ALIGN(payloadType->mSize, payloadType->mAlign) * 8, payloadType->mAlign * 8, 0,
|
||||
flags, DbgGetType(payloadType));
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
else
|
||||
{
|
||||
BfConstant* constant = NULL;
|
||||
BfIRValue staticValue;
|
||||
|
||||
if (fieldInstance->mConstIdx != -1)
|
||||
if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
|
||||
{
|
||||
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
if (!resolvedFieldType->IsValuelessType())
|
||||
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
|
||||
}
|
||||
auto payloadType = fieldInstance->mResolvedType;
|
||||
if (payloadType == NULL)
|
||||
payloadType = mModule->CreateTupleType(BfTypeVector(), Array<String>());
|
||||
|
||||
if (fieldInstance->mResolvedType->IsComposite())
|
||||
PopulateType(fieldInstance->mResolvedType);
|
||||
|
||||
BfIRMDNode constDIType = DbgCreateConstType(resolvedFieldDIType);
|
||||
if ((fieldDef->mIsExtern) && (resolvedFieldType->IsPointer()))
|
||||
{
|
||||
auto underlyingType = resolvedFieldType->GetUnderlyingType();
|
||||
auto staticTypedValue = mModule->ReferenceStaticField(fieldInstance);
|
||||
staticValue = staticTypedValue.mValue;
|
||||
String fieldName = StrFormat("_%d_%s", -fieldInstance->mDataIdx - 1, fieldDef->mName.c_str());
|
||||
|
||||
int flags = 0;
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
|
||||
constDIType, flags, CreateConst(BfTypeCode_Int32, 0));
|
||||
diFieldTypes.push_back(memberType);
|
||||
|
||||
StringT<128> staticVarName;
|
||||
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
|
||||
if (!staticVarName.StartsWith("#"))
|
||||
{
|
||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
||||
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
|
||||
constDIType, false, staticValue, memberType);
|
||||
}
|
||||
}
|
||||
else if (resolvedFieldType->IsValuelessType())
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if ((resolvedFieldType->IsObjectOrInterface()) || (resolvedFieldType->IsPointer()) || (resolvedFieldType->IsSizedArray()))
|
||||
{
|
||||
bool useIntConstant = false;
|
||||
|
||||
bool wasMadeAddr = false;
|
||||
|
||||
StringT<128> staticVarName;
|
||||
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
|
||||
|
||||
String fieldName = fieldDef->mName;
|
||||
BfIRValue intConstant;
|
||||
if (constant != NULL)
|
||||
{
|
||||
// This constant debug info causes linking errors on Linux
|
||||
if (isOptimized)
|
||||
continue;
|
||||
|
||||
if ((constant->mConstType == BfConstType_Agg) ||
|
||||
(constant->mConstType == BfConstType_AggZero) ||
|
||||
(constant->mTypeCode == BfTypeCode_NullPtr))
|
||||
{
|
||||
staticValue = ConstToMemory(staticValue);
|
||||
wasMadeAddr = true;
|
||||
}
|
||||
else if (constant->mTypeCode == BfTypeCode_StringId)
|
||||
{
|
||||
int stringId = constant->mInt32;
|
||||
const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString;
|
||||
if (resolvedFieldType->IsPointer())
|
||||
staticValue = mModule->GetStringCharPtr(str);
|
||||
else
|
||||
staticValue = mModule->GetStringObjectValue(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ignore other types (for now)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!useIntConstant)
|
||||
{
|
||||
auto useType = resolvedFieldType;
|
||||
if (wasMadeAddr)
|
||||
useType = mModule->CreatePointerType(useType);
|
||||
staticValue = CreateGlobalVariable(mModule->mBfIRBuilder->MapType(useType), true, BfIRLinkageType_Internal, staticValue, staticVarName);
|
||||
GlobalVar_SetAlignment(staticValue, useType->mAlign);
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
constDIType, flags, useIntConstant ? intConstant : BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
|
||||
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||
{
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, 0,
|
||||
constDIType, flags, useIntConstant ? intConstant : BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
if (staticValue)
|
||||
{
|
||||
String qualifiedName = DbgGetStaticFieldName(fieldInstance);
|
||||
DbgCreateGlobalVariable(diForwardDecl, qualifiedName, staticVarName, fileDIScope, 0,
|
||||
constDIType, false, staticValue, memberType);
|
||||
}
|
||||
}
|
||||
else if (mModule->mCompiler->mOptions.IsCodeView())
|
||||
{
|
||||
int flags = 0;
|
||||
String fieldName = fieldDef->mName;
|
||||
if ((constant != NULL) &&
|
||||
((IsIntable(constant->mTypeCode)) || (IsFloat(constant->mTypeCode))))
|
||||
{
|
||||
int64 writeVal = constant->mInt64;
|
||||
if (constant->mTypeCode == BfTypeCode_Float)
|
||||
{
|
||||
// We need to do this because Singles are stored in mDouble, so we need to reduce here
|
||||
float floatVal = (float)constant->mDouble;
|
||||
writeVal = *(uint32*)&floatVal;
|
||||
}
|
||||
if (writeVal < 0)
|
||||
fieldName += StrFormat("$_%llu", -writeVal);
|
||||
else
|
||||
fieldName += StrFormat("$%llu", writeVal);
|
||||
}
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
constDIType, flags, staticValue);
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
BF_ALIGN(payloadType->mSize, payloadType->mAlign) * 8, payloadType->mAlign * 8, 0,
|
||||
flags, DbgGetType(payloadType));
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags = 0;
|
||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
constDIType, flags, staticValue);
|
||||
BfConstant* constant = NULL;
|
||||
BfIRValue staticValue;
|
||||
|
||||
if (fieldInstance->mConstIdx != -1)
|
||||
{
|
||||
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
if (!resolvedFieldType->IsValuelessType())
|
||||
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
|
||||
}
|
||||
|
||||
if (fieldInstance->mResolvedType->IsComposite())
|
||||
PopulateType(fieldInstance->mResolvedType);
|
||||
|
||||
BfIRMDNode constDIType = DbgCreateConstType(resolvedFieldDIType);
|
||||
if ((fieldDef->mIsExtern) && (resolvedFieldType->IsPointer()))
|
||||
{
|
||||
auto underlyingType = resolvedFieldType->GetUnderlyingType();
|
||||
auto staticTypedValue = mModule->ReferenceStaticField(fieldInstance);
|
||||
staticValue = staticTypedValue.mValue;
|
||||
|
||||
int flags = 0;
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
|
||||
constDIType, flags, CreateConst(BfTypeCode_Int32, 0));
|
||||
diFieldTypes.push_back(memberType);
|
||||
|
||||
StringT<128> staticVarName;
|
||||
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
|
||||
if (!staticVarName.StartsWith("#"))
|
||||
{
|
||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
||||
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
|
||||
constDIType, false, staticValue, memberType);
|
||||
}
|
||||
}
|
||||
else if (resolvedFieldType->IsValuelessType())
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if ((resolvedFieldType->IsObjectOrInterface()) || (resolvedFieldType->IsPointer()) || (resolvedFieldType->IsSizedArray()))
|
||||
{
|
||||
bool useIntConstant = false;
|
||||
|
||||
bool wasMadeAddr = false;
|
||||
|
||||
StringT<128> staticVarName;
|
||||
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
|
||||
|
||||
String fieldName = fieldDef->mName;
|
||||
BfIRValue intConstant;
|
||||
if (constant != NULL)
|
||||
{
|
||||
// This constant debug info causes linking errors on Linux
|
||||
if (isOptimized)
|
||||
continue;
|
||||
|
||||
if ((constant->mConstType == BfConstType_Agg) ||
|
||||
(constant->mConstType == BfConstType_AggZero) ||
|
||||
(constant->mTypeCode == BfTypeCode_NullPtr))
|
||||
{
|
||||
staticValue = ConstToMemory(staticValue);
|
||||
wasMadeAddr = true;
|
||||
}
|
||||
else if (constant->mTypeCode == BfTypeCode_StringId)
|
||||
{
|
||||
int stringId = constant->mInt32;
|
||||
const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString;
|
||||
if (resolvedFieldType->IsPointer())
|
||||
staticValue = mModule->GetStringCharPtr(str);
|
||||
else
|
||||
staticValue = mModule->GetStringObjectValue(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ignore other types (for now)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!useIntConstant)
|
||||
{
|
||||
auto useType = resolvedFieldType;
|
||||
if (wasMadeAddr)
|
||||
useType = mModule->CreatePointerType(useType);
|
||||
staticValue = CreateGlobalVariable(mModule->mBfIRBuilder->MapType(useType), true, BfIRLinkageType_Internal, staticValue, staticVarName);
|
||||
GlobalVar_SetAlignment(staticValue, useType->mAlign);
|
||||
}
|
||||
|
||||
BfIRMDNode memberType;
|
||||
int flags = 0;
|
||||
if (!fieldDef->mName.IsEmpty())
|
||||
{
|
||||
memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
constDIType, flags, useIntConstant ? intConstant : BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||
{
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, 0,
|
||||
constDIType, flags, useIntConstant ? intConstant : BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
if ((staticValue) && (!fieldDef->mName.IsEmpty()))
|
||||
{
|
||||
String qualifiedName = DbgGetStaticFieldName(fieldInstance);
|
||||
DbgCreateGlobalVariable(diForwardDecl, qualifiedName, staticVarName, fileDIScope, 0,
|
||||
constDIType, false, staticValue, memberType);
|
||||
}
|
||||
}
|
||||
else if (mModule->mCompiler->mOptions.IsCodeView())
|
||||
{
|
||||
int flags = 0;
|
||||
String fieldName = fieldDef->mName;
|
||||
if ((constant != NULL) &&
|
||||
((IsIntable(constant->mTypeCode)) || (IsFloat(constant->mTypeCode))))
|
||||
{
|
||||
int64 writeVal = constant->mInt64;
|
||||
if (constant->mTypeCode == BfTypeCode_Float)
|
||||
{
|
||||
// We need to do this because Singles are stored in mDouble, so we need to reduce here
|
||||
float floatVal = (float)constant->mDouble;
|
||||
writeVal = *(uint32*)&floatVal;
|
||||
}
|
||||
if (writeVal < 0)
|
||||
fieldName += StrFormat("$_%llu", -writeVal);
|
||||
else
|
||||
fieldName += StrFormat("$%llu", writeVal);
|
||||
}
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
constDIType, flags, staticValue);
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags = 0;
|
||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||
constDIType, flags, staticValue);
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fieldDef->mIsStatic)
|
||||
{
|
||||
if ((isDefiningModule) && (depth == 0))
|
||||
{
|
||||
BfIRMDNode memberType;
|
||||
int flags = 0;
|
||||
if (!fieldDef->mName.IsEmpty())
|
||||
{
|
||||
memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
|
||||
resolvedFieldDIType, flags, BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||
{
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldDef->mName, fileDIScope, 0,
|
||||
resolvedFieldDIType, flags, BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
StringT<128> staticVarName;
|
||||
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
|
||||
if ((!staticVarName.StartsWith('#')) && (!fieldDef->mName.IsEmpty()))
|
||||
{
|
||||
auto staticValue = mModule->ReferenceStaticField(fieldInstance);
|
||||
if (staticValue.mValue)
|
||||
{
|
||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
||||
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
|
||||
resolvedFieldDIType, false, staticValue.mValue, memberType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool useForUnion = false;
|
||||
|
||||
BF_ASSERT(!fieldInstance->mIsEnumPayloadCase);
|
||||
|
||||
if (wantDIData)
|
||||
{
|
||||
if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (depth < 10))
|
||||
{
|
||||
_AddFields(fieldInstance->mResolvedType, depth + 1, byteOffset + fieldInstance->mDataOffset);
|
||||
}
|
||||
|
||||
int lineNum = 0;
|
||||
|
||||
int flags = 0;
|
||||
String fieldName = fieldDef->mName;
|
||||
if (!fieldDef->mName.IsEmpty())
|
||||
{
|
||||
if (fieldDef->mHasMultiDefs)
|
||||
fieldName += "$" + fieldDef->mDeclaringType->mProject->mName;
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
|
||||
fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, (byteOffset + fieldInstance->mDataOffset) * 8,
|
||||
flags, resolvedFieldDIType);
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fieldDef->mIsStatic)
|
||||
{
|
||||
if (isDefiningModule)
|
||||
{
|
||||
int flags = 0;
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
|
||||
resolvedFieldDIType, flags, BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
|
||||
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||
{
|
||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldDef->mName, fileDIScope, 0,
|
||||
resolvedFieldDIType, flags, BfIRValue());
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
|
||||
StringT<128> staticVarName;
|
||||
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
|
||||
if (!staticVarName.StartsWith('#'))
|
||||
{
|
||||
auto staticValue = mModule->ReferenceStaticField(fieldInstance);
|
||||
if (staticValue.mValue)
|
||||
{
|
||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
||||
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
|
||||
resolvedFieldDIType, false, staticValue.mValue, memberType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool useForUnion = false;
|
||||
|
||||
BF_ASSERT(!fieldInstance->mIsEnumPayloadCase);
|
||||
|
||||
if (wantDIData)
|
||||
{
|
||||
int lineNum = 0;
|
||||
|
||||
int flags = 0;
|
||||
String fieldName = fieldDef->mName;
|
||||
if (fieldDef->mHasMultiDefs)
|
||||
fieldName += "$" + fieldDef->mDeclaringType->mProject->mName;
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
|
||||
fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
|
||||
flags, resolvedFieldDIType);
|
||||
diFieldTypes.push_back(memberType);
|
||||
|
||||
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||
{
|
||||
auto memberType = DbgCreateMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, lineNum,
|
||||
fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
|
||||
flags, resolvedFieldDIType);
|
||||
diFieldTypes.push_back(memberType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_AddFields(typeInstance, 0, 0);
|
||||
|
||||
int dataPos = 0;
|
||||
if (typeInstance->mBaseType != NULL)
|
||||
|
|
|
@ -5472,9 +5472,22 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
{
|
||||
auto resolvedFieldType = fieldInstance->GetResolvedType();
|
||||
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
|
||||
{
|
||||
if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsGenericParam()) && (!resolvedFieldType->IsObject()) && (!resolvedFieldType->IsStruct()))
|
||||
Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->GetFieldDeclaration()->mConstSpecifier);
|
||||
{
|
||||
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||
{
|
||||
auto fieldDecl = fieldDef->GetFieldDeclaration();
|
||||
BfAstNode* refNode = fieldDecl->mConstSpecifier;
|
||||
if (refNode == NULL)
|
||||
refNode = fieldDef->GetRefNode();
|
||||
if ((!resolvedFieldType->IsGenericParam()) && (!resolvedFieldType->IsObject()) && (!resolvedFieldType->IsStruct()))
|
||||
{
|
||||
Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), refNode);
|
||||
}
|
||||
else if ((fieldDecl->mConstSpecifier == NULL) && (!BfNodeIsA<BfInlineTypeReference>(fieldDecl->mTypeRef)))
|
||||
{
|
||||
Warn(0, "Field needs either a name or a 'using' declaration", refNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldInstance->mIsEnumPayloadCase)
|
||||
{
|
||||
|
|
|
@ -6309,11 +6309,13 @@ BfFieldDeclaration* BfReducer::CreateFieldDeclaration(BfTokenNode* tokenNode, Bf
|
|||
else
|
||||
{
|
||||
ReplaceNode(typeRef, fieldDeclaration);
|
||||
fieldDeclaration->mTypeRef = typeRef;
|
||||
fieldDeclaration->mNameNode = nameIdentifier;
|
||||
fieldDeclaration->mTypeRef = typeRef;
|
||||
fieldDeclaration->mInitializer = NULL;
|
||||
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
|
||||
//mVisitorPos.MoveNext();
|
||||
if (nameIdentifier != NULL)
|
||||
{
|
||||
fieldDeclaration->mNameNode = nameIdentifier;
|
||||
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
|
||||
}
|
||||
}
|
||||
CheckMultiuseAttributeTypeRef(fieldDeclaration->mTypeRef);
|
||||
|
||||
|
@ -7407,7 +7409,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
|||
}
|
||||
else if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||
{
|
||||
if (nextToken->GetToken() == BfToken_Operator)
|
||||
if (nextToken->mToken == BfToken_Operator)
|
||||
{
|
||||
auto operatorDecl = mAlloc->Alloc<BfOperatorDeclaration>();
|
||||
BfDeferredAstSizedArray<BfParameterDeclaration*> params(operatorDecl->mParams, mAlloc);
|
||||
|
@ -7493,7 +7495,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
|||
|
||||
return operatorDecl;
|
||||
}
|
||||
else if (nextToken->GetToken() == BfToken_LParen)
|
||||
else if (nextToken->mToken == BfToken_LParen)
|
||||
{
|
||||
Fail("Method return type expected", node);
|
||||
|
||||
|
@ -7505,6 +7507,10 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
|||
typeRef = NULL;
|
||||
}
|
||||
}
|
||||
else if (nextToken->mToken == BfToken_Semicolon)
|
||||
{
|
||||
forceIsMethod = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nameIdentifier != NULL) || (forceIsMethod) || (indexerThisToken != NULL))
|
||||
|
|
|
@ -679,6 +679,8 @@ public:
|
|||
{
|
||||
if (fieldDeclaration->mNameNode != NULL)
|
||||
return fieldDeclaration->mNameNode;
|
||||
if (fieldDeclaration->mTypeRef != NULL)
|
||||
return fieldDeclaration->mTypeRef;
|
||||
}
|
||||
|
||||
if (auto paramDeclaration = BfNodeDynCast<BfParameterDeclaration>(mFieldDeclaration))
|
||||
|
|
|
@ -23,11 +23,11 @@ class Anonymous
|
|||
struct StructB
|
||||
{
|
||||
[Union]
|
||||
public using struct
|
||||
public struct
|
||||
{
|
||||
public int mX;
|
||||
public int mY;
|
||||
} mCoords;
|
||||
};
|
||||
}
|
||||
|
||||
struct StructC
|
||||
|
@ -91,4 +91,4 @@ class Anonymous
|
|||
Test.Assert(sValA.x == 3);
|
||||
Test.Assert(sValA.y == 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,14 +48,25 @@ namespace Tests
|
|||
[Union]
|
||||
struct Vector2
|
||||
{
|
||||
public struct Coords
|
||||
{
|
||||
public float mX;
|
||||
public float mY;
|
||||
}
|
||||
public struct Coords : this(float mX, float mY);
|
||||
|
||||
public float[2] mValues;
|
||||
public using Coords mCoords;
|
||||
using public Coords mCoords;
|
||||
|
||||
public this(float x, float y)
|
||||
{
|
||||
mX = x;
|
||||
mY = y;
|
||||
}
|
||||
}
|
||||
|
||||
[Union]
|
||||
struct Vector2b
|
||||
{
|
||||
public struct Coords : this(float mX, float mY);
|
||||
|
||||
public float[2] mValues;
|
||||
public using Coords;
|
||||
|
||||
public this(float x, float y)
|
||||
{
|
||||
|
@ -80,8 +91,16 @@ namespace Tests
|
|||
Test.Assert(sizeof(Vector2) == 8);
|
||||
Test.Assert(vec.mX == 1.2f);
|
||||
Test.Assert(vec.mY == 2.3f);
|
||||
Test.Assert(vec.mCoords == .(1.2f, 2.3f));
|
||||
Test.Assert(vec.mValues[0] == 1.2f);
|
||||
Test.Assert(vec.mValues[1] == 2.3f);
|
||||
|
||||
Vector2b vecb = .(1.2f, 2.3f);
|
||||
Test.Assert(sizeof(Vector2b) == 8);
|
||||
Test.Assert(vecb.mX == 1.2f);
|
||||
Test.Assert(vecb.mY == 2.3f);
|
||||
Test.Assert(vecb.mValues[0] == 1.2f);
|
||||
Test.Assert(vecb.mValues[1] == 2.3f);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5991,6 +5991,8 @@ String WinDebugger::MaybeQuoteFormatInfoParam(const StringImpl& str)
|
|||
DbgTypedValue WinDebugger::EvaluateInContext(DbgCompileUnit* dbgCompileUnit, const DbgTypedValue& contextTypedValue, const StringImpl& subExpr, DwFormatInfo* formatInfo, String* outReferenceId, String* outErrors)
|
||||
{
|
||||
DbgEvaluationContext dbgEvaluationContext(this, dbgCompileUnit->mDbgModule, subExpr, formatInfo, contextTypedValue);
|
||||
if (dbgEvaluationContext.mDbgExprEvaluator == NULL)
|
||||
return DbgTypedValue();
|
||||
dbgEvaluationContext.mDbgExprEvaluator->mDbgCompileUnit = dbgCompileUnit;
|
||||
if (formatInfo != NULL)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue