1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Allow anonymous 'using' fields

This commit is contained in:
Brian Fiete 2025-01-05 08:55:17 -08:00
parent 613f9c743a
commit 854122cb46
9 changed files with 323 additions and 256 deletions

View file

@ -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();

View file

@ -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);

View file

@ -3220,6 +3220,12 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
diFieldTypes.push_back(memberType); diFieldTypes.push_back(memberType);
} }
std::function<void(BfType* type, int depth, int byteOffset)> _AddFields = [&](BfType* type, int depth, int byteOffset)
{
typeInstance = type->ToTypeInstance();
if (typeInstance == NULL)
return;
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive()); bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++) for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
{ {
@ -3261,7 +3267,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
{ {
if (fieldDef->mIsConst) if (fieldDef->mIsConst)
{ {
if (isDefiningModule) if ((isDefiningModule) && (depth == 0))
{ {
if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry())) if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
{ {
@ -3366,10 +3372,14 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
GlobalVar_SetAlignment(staticValue, useType->mAlign); GlobalVar_SetAlignment(staticValue, useType->mAlign);
} }
BfIRMDNode memberType;
int flags = 0; int flags = 0;
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0, if (!fieldDef->mName.IsEmpty())
{
memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
constDIType, flags, useIntConstant ? intConstant : BfIRValue()); constDIType, flags, useIntConstant ? intConstant : BfIRValue());
diFieldTypes.push_back(memberType); diFieldTypes.push_back(memberType);
}
if (fieldDef->mUsingProtection != BfProtection_Hidden) if (fieldDef->mUsingProtection != BfProtection_Hidden)
{ {
@ -3378,7 +3388,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
diFieldTypes.push_back(memberType); diFieldTypes.push_back(memberType);
} }
if (staticValue) if ((staticValue) && (!fieldDef->mName.IsEmpty()))
{ {
String qualifiedName = DbgGetStaticFieldName(fieldInstance); String qualifiedName = DbgGetStaticFieldName(fieldInstance);
DbgCreateGlobalVariable(diForwardDecl, qualifiedName, staticVarName, fileDIScope, 0, DbgCreateGlobalVariable(diForwardDecl, qualifiedName, staticVarName, fileDIScope, 0,
@ -3421,12 +3431,16 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
} }
else if (fieldDef->mIsStatic) else if (fieldDef->mIsStatic)
{ {
if (isDefiningModule) if ((isDefiningModule) && (depth == 0))
{ {
BfIRMDNode memberType;
int flags = 0; int flags = 0;
auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0, if (!fieldDef->mName.IsEmpty())
{
memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
resolvedFieldDIType, flags, BfIRValue()); resolvedFieldDIType, flags, BfIRValue());
diFieldTypes.push_back(memberType); diFieldTypes.push_back(memberType);
}
if (fieldDef->mUsingProtection != BfProtection_Hidden) if (fieldDef->mUsingProtection != BfProtection_Hidden)
{ {
@ -3437,7 +3451,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
StringT<128> staticVarName; StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance); BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
if (!staticVarName.StartsWith('#')) if ((!staticVarName.StartsWith('#')) && (!fieldDef->mName.IsEmpty()))
{ {
auto staticValue = mModule->ReferenceStaticField(fieldInstance); auto staticValue = mModule->ReferenceStaticField(fieldInstance);
if (staticValue.mValue) if (staticValue.mValue)
@ -3457,28 +3471,31 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
if (wantDIData) if (wantDIData)
{ {
if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (depth < 10))
{
_AddFields(fieldInstance->mResolvedType, depth + 1, byteOffset + fieldInstance->mDataOffset);
}
int lineNum = 0; int lineNum = 0;
int flags = 0; int flags = 0;
String fieldName = fieldDef->mName; String fieldName = fieldDef->mName;
if (!fieldDef->mName.IsEmpty())
{
if (fieldDef->mHasMultiDefs) if (fieldDef->mHasMultiDefs)
fieldName += "$" + fieldDef->mDeclaringType->mProject->mName; fieldName += "$" + fieldDef->mDeclaringType->mProject->mName;
auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum, auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8, fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, (byteOffset + fieldInstance->mDataOffset) * 8,
flags, resolvedFieldDIType); flags, resolvedFieldDIType);
diFieldTypes.push_back(memberType); diFieldTypes.push_back(memberType);
}
}
}
}
}
};
if (fieldDef->mUsingProtection != BfProtection_Hidden) _AddFields(typeInstance, 0, 0);
{
auto memberType = DbgCreateMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, lineNum,
fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
flags, resolvedFieldDIType);
diFieldTypes.push_back(memberType);
}
}
}
}
}
int dataPos = 0; int dataPos = 0;
if (typeInstance->mBaseType != NULL) if (typeInstance->mBaseType != NULL)

View file

@ -5473,8 +5473,21 @@ 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)
{ {

View file

@ -6310,10 +6310,12 @@ BfFieldDeclaration* BfReducer::CreateFieldDeclaration(BfTokenNode* tokenNode, Bf
{ {
ReplaceNode(typeRef, fieldDeclaration); ReplaceNode(typeRef, fieldDeclaration);
fieldDeclaration->mTypeRef = typeRef; fieldDeclaration->mTypeRef = typeRef;
fieldDeclaration->mNameNode = nameIdentifier;
fieldDeclaration->mInitializer = NULL; fieldDeclaration->mInitializer = NULL;
if (nameIdentifier != NULL)
{
fieldDeclaration->mNameNode = nameIdentifier;
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration); MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
//mVisitorPos.MoveNext(); }
} }
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))

View file

@ -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))

View file

@ -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

View file

@ -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);
} }
} }
} }

View file

@ -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)
{ {