mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +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());
|
Visit(strideOfExpr->ToBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfStructuralVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||||
|
{
|
||||||
|
Visit(offsetOfExpr->ToBase());
|
||||||
|
}
|
||||||
|
|
||||||
void BfStructuralVisitor::Visit(BfDefaultExpression* defaultExpr)
|
void BfStructuralVisitor::Visit(BfDefaultExpression* defaultExpr)
|
||||||
{
|
{
|
||||||
Visit(defaultExpr->ToBase());
|
Visit(defaultExpr->ToBase());
|
||||||
|
@ -1398,6 +1403,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return "null";
|
return "null";
|
||||||
case BfToken_Nullable:
|
case BfToken_Nullable:
|
||||||
return "nullable";
|
return "nullable";
|
||||||
|
case BfToken_OffsetOf:
|
||||||
|
return "offsetof";
|
||||||
case BfToken_Operator:
|
case BfToken_Operator:
|
||||||
return "operator";
|
return "operator";
|
||||||
case BfToken_Out:
|
case BfToken_Out:
|
||||||
|
|
|
@ -158,6 +158,7 @@ enum BfToken : uint8
|
||||||
BfToken_New,
|
BfToken_New,
|
||||||
BfToken_Null,
|
BfToken_Null,
|
||||||
BfToken_Nullable,
|
BfToken_Nullable,
|
||||||
|
BfToken_OffsetOf,
|
||||||
BfToken_Operator,
|
BfToken_Operator,
|
||||||
BfToken_Out,
|
BfToken_Out,
|
||||||
BfToken_Override,
|
BfToken_Override,
|
||||||
|
@ -367,6 +368,7 @@ class BfTypedValueExpression;
|
||||||
class BfTypeAttrExpression;
|
class BfTypeAttrExpression;
|
||||||
class BfSizeOfExpression;
|
class BfSizeOfExpression;
|
||||||
class BfAlignOfExpression;
|
class BfAlignOfExpression;
|
||||||
|
class BfOffsetOfExpression;
|
||||||
class BfStrideOfExpression;
|
class BfStrideOfExpression;
|
||||||
class BfDefaultExpression;
|
class BfDefaultExpression;
|
||||||
class BfUninitializedExpression;
|
class BfUninitializedExpression;
|
||||||
|
@ -490,6 +492,7 @@ public:
|
||||||
virtual void Visit(BfSizeOfExpression* sizeOfExpr);
|
virtual void Visit(BfSizeOfExpression* sizeOfExpr);
|
||||||
virtual void Visit(BfAlignOfExpression* alignOfExpr);
|
virtual void Visit(BfAlignOfExpression* alignOfExpr);
|
||||||
virtual void Visit(BfStrideOfExpression* strideOfExpr);
|
virtual void Visit(BfStrideOfExpression* strideOfExpr);
|
||||||
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
||||||
|
@ -2652,7 +2655,7 @@ public:
|
||||||
class BfAlignOfExpression : public BfTypeAttrExpression
|
class BfAlignOfExpression : public BfTypeAttrExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression);
|
BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression);
|
||||||
}; BF_AST_DECL(BfAlignOfExpression, BfTypeAttrExpression);
|
}; BF_AST_DECL(BfAlignOfExpression, BfTypeAttrExpression);
|
||||||
|
|
||||||
class BfStrideOfExpression : public BfTypeAttrExpression
|
class BfStrideOfExpression : public BfTypeAttrExpression
|
||||||
|
@ -2661,6 +2664,15 @@ public:
|
||||||
BF_AST_TYPE(BfStrideOfExpression, BfTypeAttrExpression);
|
BF_AST_TYPE(BfStrideOfExpression, BfTypeAttrExpression);
|
||||||
}; BF_AST_DECL(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
|
class BfDefaultExpression : public BfExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -987,11 +987,12 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn
|
||||||
|
|
||||||
bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter)
|
bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter)
|
||||||
{
|
{
|
||||||
|
bool isDot = (dotNode != NULL) && (dotNode->mToken == BfToken_Dot);
|
||||||
if (IsAutocompleteNode(nameNode))
|
if (IsAutocompleteNode(nameNode))
|
||||||
{
|
{
|
||||||
auto bfParser = nameNode->GetSourceData()->ToParser();
|
auto bfParser = nameNode->GetSourceData()->ToParser();
|
||||||
|
|
||||||
if (mIsGetDefinition)
|
if ((mIsGetDefinition) || (!isDot))
|
||||||
{
|
{
|
||||||
mInsertStartIdx = nameNode->GetSrcStart();
|
mInsertStartIdx = nameNode->GetSrcStart();
|
||||||
mInsertEndIdx = nameNode->GetSrcEnd();
|
mInsertEndIdx = nameNode->GetSrcEnd();
|
||||||
|
@ -1002,11 +1003,15 @@ bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, S
|
||||||
mInsertEndIdx = std::min(bfParser->mCursorIdx + 1, nameNode->GetSrcEnd());
|
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;
|
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();
|
mInsertStartIdx = dotNode->GetSrcEnd();
|
||||||
mInsertEndIdx = 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",
|
"alignof", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "default", "defer",
|
||||||
"delegate", "delete", "do", "else", "false", "finally",
|
"delegate", "delete", "do", "else", "false", "finally",
|
||||||
"fixed", "for", "function", "if", "implicit", "in", "internal", "is", "new", "mixin", "null",
|
"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",
|
"sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked",
|
||||||
"using", "var", "virtual", "volatile", "where", "while",
|
"using", "var", "virtual", "volatile", "where", "while",
|
||||||
"alloctype", "comptype", "decltype", "nullable",
|
"alloctype", "comptype", "decltype", "nullable",
|
||||||
|
|
|
@ -492,6 +492,16 @@ void BfElementVisitor::Visit(BfTypeAttrExpression* typeAttrExpr)
|
||||||
VisitChild(typeAttrExpr->mCloseParen);
|
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)
|
void BfElementVisitor::Visit(BfDefaultExpression* defaultExpr)
|
||||||
{
|
{
|
||||||
Visit(defaultExpr->ToBase());
|
Visit(defaultExpr->ToBase());
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
virtual void Visit(BfLocalMethodDeclaration* methodDecl);
|
virtual void Visit(BfLocalMethodDeclaration* methodDecl);
|
||||||
virtual void Visit(BfParameterDeclaration* paramDecl);
|
virtual void Visit(BfParameterDeclaration* paramDecl);
|
||||||
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
|
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
|
||||||
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
||||||
|
|
|
@ -10409,8 +10409,11 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
||||||
return true;
|
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);
|
auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete);
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -10433,6 +10436,72 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
|
||||||
default: break;
|
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;
|
bool isUndefVal = false;
|
||||||
|
|
||||||
if (type->IsGenericParam())
|
if (type->IsGenericParam())
|
||||||
|
@ -10458,17 +10527,22 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
|
void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
|
||||||
{
|
{
|
||||||
DoTypeIntAttr(sizeOfExpr->mTypeRef, BfToken_SizeOf);
|
DoTypeIntAttr(sizeOfExpr->mTypeRef, NULL, NULL, BfToken_SizeOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
|
void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
|
||||||
{
|
{
|
||||||
DoTypeIntAttr(alignOfExpr->mTypeRef, BfToken_AlignOf);
|
DoTypeIntAttr(alignOfExpr->mTypeRef, NULL, NULL, BfToken_AlignOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr)
|
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)
|
void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr)
|
||||||
|
|
|
@ -487,7 +487,7 @@ public:
|
||||||
void FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues);
|
void FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues);
|
||||||
void FinishDeferredEvals(BfResolvedArgs& argValues);
|
void FinishDeferredEvals(BfResolvedArgs& argValues);
|
||||||
bool LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName);
|
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(BfTupleExpression* createExpr, BfSizedArrayType* arrayType);
|
||||||
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
||||||
void CheckDotToken(BfTokenNode* tokenNode);
|
void CheckDotToken(BfTokenNode* tokenNode);
|
||||||
|
@ -518,6 +518,7 @@ public:
|
||||||
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
||||||
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
||||||
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
||||||
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||||
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
||||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
||||||
|
|
|
@ -3058,6 +3058,10 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
||||||
else if (SrcPtrHasToken("nullable"))
|
else if (SrcPtrHasToken("nullable"))
|
||||||
mToken = BfToken_Nullable;
|
mToken = BfToken_Nullable;
|
||||||
break;
|
break;
|
||||||
|
case TOKEN_HASH('o', 'f', 'f', 's'):
|
||||||
|
if (SrcPtrHasToken("offsetof"))
|
||||||
|
mToken = BfToken_OffsetOf;
|
||||||
|
break;
|
||||||
case TOKEN_HASH('o', 'p', 'e', 'r'):
|
case TOKEN_HASH('o', 'p', 'e', 'r'):
|
||||||
if (SrcPtrHasToken("operator"))
|
if (SrcPtrHasToken("operator"))
|
||||||
mToken = BfToken_Operator;
|
mToken = BfToken_Operator;
|
||||||
|
|
|
@ -1653,6 +1653,17 @@ void BfPrinter::Visit(BfSizeOfExpression* sizeOfExpr)
|
||||||
VisitChild(sizeOfExpr->mCloseParen);
|
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)
|
void BfPrinter::Visit(BfDefaultExpression* defaultExpr)
|
||||||
{
|
{
|
||||||
Visit(defaultExpr->ToBase());
|
Visit(defaultExpr->ToBase());
|
||||||
|
|
|
@ -168,6 +168,7 @@ public:
|
||||||
virtual void Visit(BfParameterDeclaration* paramDecl) override;
|
virtual void Visit(BfParameterDeclaration* paramDecl) override;
|
||||||
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
|
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
|
||||||
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
||||||
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
||||||
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;
|
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;
|
||||||
|
|
|
@ -1871,6 +1871,26 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
MEMBER_SET_CHECKED(typeAttrExpr, mCloseParen, tokenNode);
|
MEMBER_SET_CHECKED(typeAttrExpr, mCloseParen, tokenNode);
|
||||||
exprLeft = typeAttrExpr;
|
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)
|
else if (token == BfToken_Default)
|
||||||
{
|
{
|
||||||
auto defaultExpr = mAlloc->Alloc<BfDefaultExpression>();
|
auto defaultExpr = mAlloc->Alloc<BfDefaultExpression>();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue