mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
offsetof
This commit is contained in:
parent
507fb82e4a
commit
4cda126188
11 changed files with 156 additions and 10 deletions
|
@ -346,6 +346,11 @@ void BfStructuralVisitor::Visit(BfStrideOfExpression* strideOfExpr)
|
|||
Visit(strideOfExpr->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||
{
|
||||
Visit(offsetOfExpr->ToBase());
|
||||
}
|
||||
|
||||
void BfStructuralVisitor::Visit(BfDefaultExpression* defaultExpr)
|
||||
{
|
||||
Visit(defaultExpr->ToBase());
|
||||
|
@ -1398,6 +1403,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
|||
return "null";
|
||||
case BfToken_Nullable:
|
||||
return "nullable";
|
||||
case BfToken_OffsetOf:
|
||||
return "offsetof";
|
||||
case BfToken_Operator:
|
||||
return "operator";
|
||||
case BfToken_Out:
|
||||
|
|
|
@ -158,6 +158,7 @@ enum BfToken : uint8
|
|||
BfToken_New,
|
||||
BfToken_Null,
|
||||
BfToken_Nullable,
|
||||
BfToken_OffsetOf,
|
||||
BfToken_Operator,
|
||||
BfToken_Out,
|
||||
BfToken_Override,
|
||||
|
@ -367,6 +368,7 @@ class BfTypedValueExpression;
|
|||
class BfTypeAttrExpression;
|
||||
class BfSizeOfExpression;
|
||||
class BfAlignOfExpression;
|
||||
class BfOffsetOfExpression;
|
||||
class BfStrideOfExpression;
|
||||
class BfDefaultExpression;
|
||||
class BfUninitializedExpression;
|
||||
|
@ -490,6 +492,7 @@ public:
|
|||
virtual void Visit(BfSizeOfExpression* sizeOfExpr);
|
||||
virtual void Visit(BfAlignOfExpression* alignOfExpr);
|
||||
virtual void Visit(BfStrideOfExpression* strideOfExpr);
|
||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
||||
|
@ -2652,7 +2655,7 @@ public:
|
|||
class BfAlignOfExpression : public BfTypeAttrExpression
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression);
|
||||
BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression);
|
||||
}; BF_AST_DECL(BfAlignOfExpression, BfTypeAttrExpression);
|
||||
|
||||
class BfStrideOfExpression : public BfTypeAttrExpression
|
||||
|
@ -2661,6 +2664,15 @@ public:
|
|||
BF_AST_TYPE(BfStrideOfExpression, BfTypeAttrExpression);
|
||||
}; BF_AST_DECL(BfStrideOfExpression, BfTypeAttrExpression);
|
||||
|
||||
class BfOffsetOfExpression : public BfTypeAttrExpression
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfOffsetOfExpression, BfTypeAttrExpression);
|
||||
|
||||
BfTokenNode* mCommaToken;
|
||||
BfIdentifierNode* mMemberName;
|
||||
}; BF_AST_DECL(BfOffsetOfExpression, BfTypeAttrExpression);
|
||||
|
||||
class BfDefaultExpression : public BfExpression
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -987,11 +987,12 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn
|
|||
|
||||
bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter)
|
||||
{
|
||||
bool isDot = (dotNode != NULL) && (dotNode->mToken == BfToken_Dot);
|
||||
if (IsAutocompleteNode(nameNode))
|
||||
{
|
||||
auto bfParser = nameNode->GetSourceData()->ToParser();
|
||||
|
||||
if (mIsGetDefinition)
|
||||
if ((mIsGetDefinition) || (!isDot))
|
||||
{
|
||||
mInsertStartIdx = nameNode->GetSrcStart();
|
||||
mInsertEndIdx = nameNode->GetSrcEnd();
|
||||
|
@ -1002,11 +1003,15 @@ bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, S
|
|||
mInsertEndIdx = std::min(bfParser->mCursorIdx + 1, nameNode->GetSrcEnd());
|
||||
}
|
||||
|
||||
filter.Append(bfParser->mSrc + mInsertStartIdx, mInsertEndIdx - mInsertStartIdx);
|
||||
filter.Append(bfParser->mSrc + nameNode->GetSrcStart(), mInsertEndIdx - nameNode->GetSrcStart());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((dotNode != NULL) && (IsAutocompleteNode(dotNode, 0, 1)))
|
||||
int lenAdd = 0;
|
||||
if (!isDot)
|
||||
lenAdd++;
|
||||
|
||||
if ((dotNode != NULL) && (IsAutocompleteNode(dotNode, lenAdd, 1)))
|
||||
{
|
||||
mInsertStartIdx = dotNode->GetSrcEnd();
|
||||
mInsertEndIdx = dotNode->GetSrcEnd();
|
||||
|
@ -1558,7 +1563,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
|||
"alignof", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "default", "defer",
|
||||
"delegate", "delete", "do", "else", "false", "finally",
|
||||
"fixed", "for", "function", "if", "implicit", "in", "internal", "is", "new", "mixin", "null",
|
||||
"out", "params", "ref", "rettype", "return",
|
||||
"offsetof", "out", "params", "ref", "rettype", "return",
|
||||
"sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked",
|
||||
"using", "var", "virtual", "volatile", "where", "while",
|
||||
"alloctype", "comptype", "decltype", "nullable",
|
||||
|
|
|
@ -492,6 +492,16 @@ void BfElementVisitor::Visit(BfTypeAttrExpression* typeAttrExpr)
|
|||
VisitChild(typeAttrExpr->mCloseParen);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||
{
|
||||
VisitChild(offsetOfExpr->mToken);
|
||||
VisitChild(offsetOfExpr->mOpenParen);
|
||||
VisitChild(offsetOfExpr->mTypeRef);
|
||||
VisitChild(offsetOfExpr->mCommaToken);
|
||||
VisitChild(offsetOfExpr->mMemberName);
|
||||
VisitChild(offsetOfExpr->mCloseParen);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfDefaultExpression* defaultExpr)
|
||||
{
|
||||
Visit(defaultExpr->ToBase());
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
virtual void Visit(BfLocalMethodDeclaration* methodDecl);
|
||||
virtual void Visit(BfParameterDeclaration* paramDecl);
|
||||
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
|
||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
||||
|
|
|
@ -10409,8 +10409,11 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
|||
return true;
|
||||
}
|
||||
|
||||
void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
|
||||
void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token)
|
||||
{
|
||||
auto autoComplete = GetAutoComplete();
|
||||
|
||||
|
||||
auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete);
|
||||
if (type == NULL)
|
||||
return;
|
||||
|
@ -10433,6 +10436,72 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
|
|||
default: break;
|
||||
}
|
||||
|
||||
if (token == BfToken_OffsetOf)
|
||||
{
|
||||
bool found = false;
|
||||
String findName;
|
||||
if (memberName != NULL)
|
||||
findName = memberName->ToString();
|
||||
|
||||
BfAstNode* refNode = typeRef;
|
||||
if (memberName != NULL)
|
||||
refNode = memberName;
|
||||
|
||||
auto checkTypeInst = typeInst;
|
||||
while (checkTypeInst != NULL)
|
||||
{
|
||||
checkTypeInst->mTypeDef->PopulateMemberSets();
|
||||
|
||||
String filter;
|
||||
if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(commaToken, memberName, filter)))
|
||||
{
|
||||
auto activeTypeDef = mModule->GetActiveTypeDef();
|
||||
mModule->PopulateType(checkTypeInst);
|
||||
|
||||
BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
|
||||
for (auto fieldDef : checkTypeInst->mTypeDef->mFields)
|
||||
{
|
||||
if (fieldDef->mIsStatic)
|
||||
continue;
|
||||
|
||||
if (!mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mDeclaringType->mProject, fieldDef->mProtection, typeInst))
|
||||
continue;
|
||||
|
||||
if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
|
||||
(!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
|
||||
continue;
|
||||
|
||||
auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
|
||||
autoComplete->AddField(checkTypeInst, fieldDef, &fieldInst, filter);
|
||||
}
|
||||
}
|
||||
|
||||
BfMemberSetEntry* memberSetEntry = NULL;
|
||||
if (checkTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
|
||||
{
|
||||
auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
|
||||
if (fieldDef != NULL)
|
||||
{
|
||||
if (fieldDef->mIsStatic)
|
||||
mModule->Fail(StrFormat("Cannot generate an offset from static field '%s.%s'", mModule->TypeToString(type).c_str(), fieldDef->mName.c_str()), refNode);
|
||||
|
||||
mModule->PopulateType(checkTypeInst);
|
||||
auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
|
||||
attrVal = fieldInst.mDataOffset;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
checkTypeInst = checkTypeInst->mBaseType;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
mModule->Fail(StrFormat("Unable to locate field '%s.%s'", mModule->TypeToString(type).c_str(), findName.c_str()), refNode);
|
||||
}
|
||||
}
|
||||
|
||||
bool isUndefVal = false;
|
||||
|
||||
if (type->IsGenericParam())
|
||||
|
@ -10458,17 +10527,22 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
|
|||
|
||||
void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
|
||||
{
|
||||
DoTypeIntAttr(sizeOfExpr->mTypeRef, BfToken_SizeOf);
|
||||
DoTypeIntAttr(sizeOfExpr->mTypeRef, NULL, NULL, BfToken_SizeOf);
|
||||
}
|
||||
|
||||
void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
|
||||
{
|
||||
DoTypeIntAttr(alignOfExpr->mTypeRef, BfToken_AlignOf);
|
||||
DoTypeIntAttr(alignOfExpr->mTypeRef, NULL, NULL, BfToken_AlignOf);
|
||||
}
|
||||
|
||||
void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr)
|
||||
{
|
||||
DoTypeIntAttr(strideOfExpr->mTypeRef, BfToken_StrideOf);
|
||||
DoTypeIntAttr(strideOfExpr->mTypeRef, NULL, NULL, BfToken_StrideOf);
|
||||
}
|
||||
|
||||
void BfExprEvaluator::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||
{
|
||||
DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf);
|
||||
}
|
||||
|
||||
void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr)
|
||||
|
|
|
@ -487,7 +487,7 @@ public:
|
|||
void FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues);
|
||||
void FinishDeferredEvals(BfResolvedArgs& argValues);
|
||||
bool LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName);
|
||||
void DoTypeIntAttr(BfTypeReference* typeRef, BfToken token);
|
||||
void DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token);
|
||||
//void InitializedSizedArray(BfTupleExpression* createExpr, BfSizedArrayType* arrayType);
|
||||
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
||||
void CheckDotToken(BfTokenNode* tokenNode);
|
||||
|
@ -518,6 +518,7 @@ public:
|
|||
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
||||
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
||||
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
||||
|
|
|
@ -3058,6 +3058,10 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
|||
else if (SrcPtrHasToken("nullable"))
|
||||
mToken = BfToken_Nullable;
|
||||
break;
|
||||
case TOKEN_HASH('o', 'f', 'f', 's'):
|
||||
if (SrcPtrHasToken("offsetof"))
|
||||
mToken = BfToken_OffsetOf;
|
||||
break;
|
||||
case TOKEN_HASH('o', 'p', 'e', 'r'):
|
||||
if (SrcPtrHasToken("operator"))
|
||||
mToken = BfToken_Operator;
|
||||
|
|
|
@ -1653,6 +1653,17 @@ void BfPrinter::Visit(BfSizeOfExpression* sizeOfExpr)
|
|||
VisitChild(sizeOfExpr->mCloseParen);
|
||||
}
|
||||
|
||||
void BfPrinter::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||
{
|
||||
VisitChild(offsetOfExpr->mToken);
|
||||
VisitChild(offsetOfExpr->mOpenParen);
|
||||
VisitChild(offsetOfExpr->mTypeRef);
|
||||
VisitChild(offsetOfExpr->mCommaToken);
|
||||
ExpectSpace();
|
||||
VisitChild(offsetOfExpr->mMemberName);
|
||||
VisitChild(offsetOfExpr->mCloseParen);
|
||||
}
|
||||
|
||||
void BfPrinter::Visit(BfDefaultExpression* defaultExpr)
|
||||
{
|
||||
Visit(defaultExpr->ToBase());
|
||||
|
|
|
@ -168,6 +168,7 @@ public:
|
|||
virtual void Visit(BfParameterDeclaration* paramDecl) override;
|
||||
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
|
||||
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
||||
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;
|
||||
|
|
|
@ -1871,6 +1871,26 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
|||
MEMBER_SET_CHECKED(typeAttrExpr, mCloseParen, tokenNode);
|
||||
exprLeft = typeAttrExpr;
|
||||
}
|
||||
else if (token == BfToken_OffsetOf)
|
||||
{
|
||||
BfOffsetOfExpression* typeAttrExpr = mAlloc->Alloc<BfOffsetOfExpression>();
|
||||
ReplaceNode(tokenNode, typeAttrExpr);
|
||||
typeAttrExpr->mToken = tokenNode;
|
||||
tokenNode = ExpectTokenAfter(typeAttrExpr, BfToken_LParen);
|
||||
MEMBER_SET_CHECKED(typeAttrExpr, mOpenParen, tokenNode);
|
||||
auto typeRef = CreateTypeRefAfter(typeAttrExpr);
|
||||
MEMBER_SET_CHECKED(typeAttrExpr, mTypeRef, typeRef);
|
||||
|
||||
tokenNode = ExpectTokenAfter(typeAttrExpr, BfToken_Comma);
|
||||
MEMBER_SET_CHECKED(typeAttrExpr, mCommaToken, tokenNode);
|
||||
|
||||
auto nameNode = ExpectIdentifierAfter(typeAttrExpr);
|
||||
MEMBER_SET_CHECKED(typeAttrExpr, mMemberName, nameNode);
|
||||
|
||||
tokenNode = ExpectTokenAfter(typeAttrExpr, BfToken_RParen);
|
||||
MEMBER_SET_CHECKED(typeAttrExpr, mCloseParen, tokenNode);
|
||||
exprLeft = typeAttrExpr;
|
||||
}
|
||||
else if (token == BfToken_Default)
|
||||
{
|
||||
auto defaultExpr = mAlloc->Alloc<BfDefaultExpression>();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue