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)
|
void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, BfFieldInstance* fieldInstance, const StringImpl& filter)
|
||||||
{
|
{
|
||||||
|
if (fieldDef->mName.IsEmpty())
|
||||||
|
return;
|
||||||
int wantPrefixCount = 0;
|
int wantPrefixCount = 0;
|
||||||
const char* filterStr = filter.c_str();
|
const char* filterStr = filter.c_str();
|
||||||
while (filterStr[0] == '@')
|
while (filterStr[0] == '@')
|
||||||
|
@ -1662,6 +1664,8 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
||||||
|
|
||||||
for (auto field : showAttrTypeDef->mFields)
|
for (auto field : showAttrTypeDef->mFields)
|
||||||
{
|
{
|
||||||
|
if (field->mName.IsEmpty())
|
||||||
|
continue;
|
||||||
if (auto entryAdded = AddEntry(AutoCompleteEntry("field", field->mName + "="), filter))
|
if (auto entryAdded = AddEntry(AutoCompleteEntry("field", field->mName + "="), filter))
|
||||||
{
|
{
|
||||||
auto fieldDeclaration = field->GetFieldDeclaration();
|
auto fieldDeclaration = field->GetFieldDeclaration();
|
||||||
|
@ -3663,7 +3667,7 @@ void BfAutoComplete::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType,
|
||||||
auto parser = typeInst->mTypeDef->GetDefinition()->mSource->ToParser();
|
auto parser = typeInst->mTypeDef->GetDefinition()->mSource->ToParser();
|
||||||
if (parser == NULL)
|
if (parser == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String fullName = typeInst->mTypeDef->mFullName.ToString();
|
String fullName = typeInst->mTypeDef->mFullName.ToString();
|
||||||
String fieldStr;
|
String fieldStr;
|
||||||
|
|
||||||
|
|
|
@ -1202,6 +1202,10 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
|
||||||
else
|
else
|
||||||
fieldDef->mUsingProtection = fieldDef->mProtection;
|
fieldDef->mUsingProtection = fieldDef->mProtection;
|
||||||
}
|
}
|
||||||
|
else if (fieldDeclaration->mNameNode == NULL)
|
||||||
|
{
|
||||||
|
fieldDef->mUsingProtection = fieldDef->mProtection;
|
||||||
|
}
|
||||||
|
|
||||||
fieldDef->mIsStatic = (fieldDeclaration->mStaticSpecifier != NULL) || fieldDef->mIsConst;
|
fieldDef->mIsStatic = (fieldDeclaration->mStaticSpecifier != NULL) || fieldDef->mIsConst;
|
||||||
fieldDef->mIsVolatile = (fieldDeclaration->mVolatileSpecifier != NULL);
|
fieldDef->mIsVolatile = (fieldDeclaration->mVolatileSpecifier != NULL);
|
||||||
|
|
|
@ -3220,265 +3220,282 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
||||||
diFieldTypes.push_back(memberType);
|
diFieldTypes.push_back(memberType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
|
std::function<void(BfType* type, int depth, int byteOffset)> _AddFields = [&](BfType* type, int depth, int byteOffset)
|
||||||
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
|
|
||||||
{
|
{
|
||||||
auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
|
typeInstance = type->ToTypeInstance();
|
||||||
if (!fieldInstance->mFieldIncluded)
|
if (typeInstance == NULL)
|
||||||
continue;
|
return;
|
||||||
auto fieldDef = fieldInstance->GetFieldDef();
|
|
||||||
|
|
||||||
if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
|
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
|
||||||
continue;
|
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
|
||||||
|
|
||||||
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()))
|
|
||||||
{
|
{
|
||||||
orderedFields.push_back(fieldInstance);
|
auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
|
||||||
|
if (!fieldInstance->mFieldIncluded)
|
||||||
|
continue;
|
||||||
|
auto fieldDef = fieldInstance->GetFieldDef();
|
||||||
|
|
||||||
int lineNum = 0;
|
if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
|
||||||
int flags = llvm::DINode::FlagPublic;
|
continue;
|
||||||
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))
|
auto resolvedFieldType = fieldInstance->GetResolvedType();
|
||||||
{
|
mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration);
|
||||||
if (fieldDef->mIsConst)
|
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 ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
auto payloadType = fieldInstance->mResolvedType;
|
||||||
if (!resolvedFieldType->IsValuelessType())
|
if (payloadType == NULL)
|
||||||
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
|
payloadType = mModule->CreateTupleType(BfTypeVector(), Array<String>());
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldInstance->mResolvedType->IsComposite())
|
String fieldName = StrFormat("_%d_%s", -fieldInstance->mDataIdx - 1, fieldDef->mName.c_str());
|
||||||
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;
|
int flags = 0;
|
||||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
|
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
||||||
constDIType, flags, CreateConst(BfTypeCode_Int32, 0));
|
BF_ALIGN(payloadType->mSize, payloadType->mAlign) * 8, payloadType->mAlign * 8, 0,
|
||||||
diFieldTypes.push_back(memberType);
|
flags, DbgGetType(payloadType));
|
||||||
|
|
||||||
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);
|
|
||||||
diFieldTypes.push_back(memberType);
|
diFieldTypes.push_back(memberType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int flags = 0;
|
BfConstant* constant = NULL;
|
||||||
String fieldName = DbgGetStaticFieldName(fieldInstance);
|
BfIRValue staticValue;
|
||||||
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
|
|
||||||
constDIType, flags, 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);
|
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;
|
int dataPos = 0;
|
||||||
if (typeInstance->mBaseType != NULL)
|
if (typeInstance->mBaseType != NULL)
|
||||||
|
|
|
@ -5472,9 +5472,22 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
{
|
{
|
||||||
auto resolvedFieldType = fieldInstance->GetResolvedType();
|
auto resolvedFieldType = fieldInstance->GetResolvedType();
|
||||||
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
|
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
|
||||||
{
|
{
|
||||||
if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsGenericParam()) && (!resolvedFieldType->IsObject()) && (!resolvedFieldType->IsStruct()))
|
if (fieldDef->mUsingProtection != BfProtection_Hidden)
|
||||||
Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->GetFieldDeclaration()->mConstSpecifier);
|
{
|
||||||
|
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)
|
if (fieldInstance->mIsEnumPayloadCase)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6309,11 +6309,13 @@ BfFieldDeclaration* BfReducer::CreateFieldDeclaration(BfTokenNode* tokenNode, Bf
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReplaceNode(typeRef, fieldDeclaration);
|
ReplaceNode(typeRef, fieldDeclaration);
|
||||||
fieldDeclaration->mTypeRef = typeRef;
|
fieldDeclaration->mTypeRef = typeRef;
|
||||||
fieldDeclaration->mNameNode = nameIdentifier;
|
|
||||||
fieldDeclaration->mInitializer = NULL;
|
fieldDeclaration->mInitializer = NULL;
|
||||||
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
|
if (nameIdentifier != NULL)
|
||||||
//mVisitorPos.MoveNext();
|
{
|
||||||
|
fieldDeclaration->mNameNode = nameIdentifier;
|
||||||
|
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CheckMultiuseAttributeTypeRef(fieldDeclaration->mTypeRef);
|
CheckMultiuseAttributeTypeRef(fieldDeclaration->mTypeRef);
|
||||||
|
|
||||||
|
@ -7407,7 +7409,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
}
|
}
|
||||||
else if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
else if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||||
{
|
{
|
||||||
if (nextToken->GetToken() == BfToken_Operator)
|
if (nextToken->mToken == BfToken_Operator)
|
||||||
{
|
{
|
||||||
auto operatorDecl = mAlloc->Alloc<BfOperatorDeclaration>();
|
auto operatorDecl = mAlloc->Alloc<BfOperatorDeclaration>();
|
||||||
BfDeferredAstSizedArray<BfParameterDeclaration*> params(operatorDecl->mParams, mAlloc);
|
BfDeferredAstSizedArray<BfParameterDeclaration*> params(operatorDecl->mParams, mAlloc);
|
||||||
|
@ -7493,7 +7495,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
|
|
||||||
return operatorDecl;
|
return operatorDecl;
|
||||||
}
|
}
|
||||||
else if (nextToken->GetToken() == BfToken_LParen)
|
else if (nextToken->mToken == BfToken_LParen)
|
||||||
{
|
{
|
||||||
Fail("Method return type expected", node);
|
Fail("Method return type expected", node);
|
||||||
|
|
||||||
|
@ -7505,6 +7507,10 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
typeRef = NULL;
|
typeRef = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (nextToken->mToken == BfToken_Semicolon)
|
||||||
|
{
|
||||||
|
forceIsMethod = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nameIdentifier != NULL) || (forceIsMethod) || (indexerThisToken != NULL))
|
if ((nameIdentifier != NULL) || (forceIsMethod) || (indexerThisToken != NULL))
|
||||||
|
|
|
@ -679,6 +679,8 @@ public:
|
||||||
{
|
{
|
||||||
if (fieldDeclaration->mNameNode != NULL)
|
if (fieldDeclaration->mNameNode != NULL)
|
||||||
return fieldDeclaration->mNameNode;
|
return fieldDeclaration->mNameNode;
|
||||||
|
if (fieldDeclaration->mTypeRef != NULL)
|
||||||
|
return fieldDeclaration->mTypeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto paramDeclaration = BfNodeDynCast<BfParameterDeclaration>(mFieldDeclaration))
|
if (auto paramDeclaration = BfNodeDynCast<BfParameterDeclaration>(mFieldDeclaration))
|
||||||
|
|
|
@ -23,11 +23,11 @@ class Anonymous
|
||||||
struct StructB
|
struct StructB
|
||||||
{
|
{
|
||||||
[Union]
|
[Union]
|
||||||
public using struct
|
public struct
|
||||||
{
|
{
|
||||||
public int mX;
|
public int mX;
|
||||||
public int mY;
|
public int mY;
|
||||||
} mCoords;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StructC
|
struct StructC
|
||||||
|
@ -91,4 +91,4 @@ class Anonymous
|
||||||
Test.Assert(sValA.x == 3);
|
Test.Assert(sValA.x == 3);
|
||||||
Test.Assert(sValA.y == 4);
|
Test.Assert(sValA.y == 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,25 @@ namespace Tests
|
||||||
[Union]
|
[Union]
|
||||||
struct Vector2
|
struct Vector2
|
||||||
{
|
{
|
||||||
public struct Coords
|
public struct Coords : this(float mX, float mY);
|
||||||
{
|
|
||||||
public float mX;
|
|
||||||
public float mY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float[2] mValues;
|
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)
|
public this(float x, float y)
|
||||||
{
|
{
|
||||||
|
@ -80,8 +91,16 @@ namespace Tests
|
||||||
Test.Assert(sizeof(Vector2) == 8);
|
Test.Assert(sizeof(Vector2) == 8);
|
||||||
Test.Assert(vec.mX == 1.2f);
|
Test.Assert(vec.mX == 1.2f);
|
||||||
Test.Assert(vec.mY == 2.3f);
|
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[0] == 1.2f);
|
||||||
Test.Assert(vec.mValues[1] == 2.3f);
|
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)
|
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);
|
DbgEvaluationContext dbgEvaluationContext(this, dbgCompileUnit->mDbgModule, subExpr, formatInfo, contextTypedValue);
|
||||||
|
if (dbgEvaluationContext.mDbgExprEvaluator == NULL)
|
||||||
|
return DbgTypedValue();
|
||||||
dbgEvaluationContext.mDbgExprEvaluator->mDbgCompileUnit = dbgCompileUnit;
|
dbgEvaluationContext.mDbgExprEvaluator->mDbgCompileUnit = dbgCompileUnit;
|
||||||
if (formatInfo != NULL)
|
if (formatInfo != NULL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue