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

View file

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

View file

@ -3220,6 +3220,12 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
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());
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
{
@ -3261,7 +3267,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
{
if (fieldDef->mIsConst)
{
if (isDefiningModule)
if ((isDefiningModule) && (depth == 0))
{
if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
{
@ -3366,10 +3372,14 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
GlobalVar_SetAlignment(staticValue, useType->mAlign);
}
BfIRMDNode memberType;
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());
diFieldTypes.push_back(memberType);
}
if (fieldDef->mUsingProtection != BfProtection_Hidden)
{
@ -3378,7 +3388,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
diFieldTypes.push_back(memberType);
}
if (staticValue)
if ((staticValue) && (!fieldDef->mName.IsEmpty()))
{
String qualifiedName = DbgGetStaticFieldName(fieldInstance);
DbgCreateGlobalVariable(diForwardDecl, qualifiedName, staticVarName, fileDIScope, 0,
@ -3421,12 +3431,16 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
}
else if (fieldDef->mIsStatic)
{
if (isDefiningModule)
if ((isDefiningModule) && (depth == 0))
{
BfIRMDNode memberType;
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());
diFieldTypes.push_back(memberType);
}
if (fieldDef->mUsingProtection != BfProtection_Hidden)
{
@ -3437,7 +3451,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
if (!staticVarName.StartsWith('#'))
if ((!staticVarName.StartsWith('#')) && (!fieldDef->mName.IsEmpty()))
{
auto staticValue = mModule->ReferenceStaticField(fieldInstance);
if (staticValue.mValue)
@ -3457,28 +3471,31 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
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, fieldInstance->mDataOffset * 8,
fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, (byteOffset + 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)

View file

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

View file

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

View file

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

View file

@ -23,11 +23,11 @@ class Anonymous
struct StructB
{
[Union]
public using struct
public struct
{
public int mX;
public int mY;
} mCoords;
};
}
struct StructC

View file

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

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)
{
DbgEvaluationContext dbgEvaluationContext(this, dbgCompileUnit->mDbgModule, subExpr, formatInfo, contextTypedValue);
if (dbgEvaluationContext.mDbgExprEvaluator == NULL)
return DbgTypedValue();
dbgEvaluationContext.mDbgExprEvaluator->mDbgCompileUnit = dbgCompileUnit;
if (formatInfo != NULL)
{