mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Alloc allign attributes, lambda captures
This commit is contained in:
parent
79ccb33586
commit
12e5b525ad
23 changed files with 540 additions and 219 deletions
|
@ -938,7 +938,7 @@ StringView BfAstNode::ToStringView()
|
|||
return StringView();
|
||||
}
|
||||
|
||||
auto source = GetSourceData();
|
||||
auto source = GetSourceData();
|
||||
return StringView(source->mSrc + GetSrcStart(), srcLen);
|
||||
}
|
||||
|
||||
|
@ -956,6 +956,15 @@ void BfAstNode::ToString(StringImpl& str)
|
|||
str.Append(source->mSrc + GetSrcStart(), srcLen);
|
||||
}
|
||||
|
||||
bool BfAstNode::Equals(const StringImpl& str)
|
||||
{
|
||||
int len = mSrcEnd - mSrcStart;
|
||||
if (len != str.mLength)
|
||||
return false;
|
||||
auto source = GetSourceData();
|
||||
return strncmp(str.GetPtr(), source->mSrc + mSrcStart, len) == 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BfBlock::Init(const SizedArrayImpl<BfAstNode*>& vec, BfAstAllocator* alloc)
|
||||
|
|
|
@ -1022,6 +1022,7 @@ public:
|
|||
String ToString();
|
||||
StringView ToStringView();
|
||||
void ToString(StringImpl& str);
|
||||
bool Equals(const StringImpl& str);
|
||||
void Init(BfParser* bfParser);
|
||||
void Accept(BfStructuralVisitor* bfVisitor);
|
||||
static void ClassAccept(BfAstNode* node, BfStructuralVisitor* bfVisitor) { bfVisitor->Visit(node); }
|
||||
|
@ -1733,6 +1734,7 @@ public:
|
|||
BfTokenNode* mScopeToken;
|
||||
BfTokenNode* mColonToken;
|
||||
BfAstNode* mTargetNode; // . : or identifier
|
||||
BfAttributeDirective* mAttributes;
|
||||
}; BF_AST_DECL(BfScopeNode, BfAstNode);
|
||||
|
||||
class BfNewNode : public BfAstNode
|
||||
|
@ -1743,6 +1745,7 @@ public:
|
|||
BfTokenNode* mNewToken;
|
||||
BfTokenNode* mColonToken;
|
||||
BfAstNode* mAllocNode; // Expression or BfScopedInvocationTarget
|
||||
BfAttributeDirective* mAttributes;
|
||||
}; BF_AST_DECL(BfNewNode, BfAstNode);
|
||||
|
||||
enum BfCommentKind
|
||||
|
@ -1849,7 +1852,7 @@ public:
|
|||
|
||||
ASTREF(BfTokenNode*) mAttrOpenToken; // [ @ ,
|
||||
ASTREF(BfTokenNode*) mAttrCloseToken;
|
||||
ASTREF(BfAttributeTargetSpecifier*) mAttributeTargetSpecifier;
|
||||
ASTREF(BfAstNode*) mAttributeTargetSpecifier;
|
||||
|
||||
ASTREF(BfTypeReference*) mAttributeTypeRef;
|
||||
ASTREF(BfTokenNode*) mCtorOpenParen;
|
||||
|
@ -2534,23 +2537,12 @@ public:
|
|||
BfGenericArgumentsNode* mGenericArgs;
|
||||
}; BF_AST_DECL(BfDelegateBindExpression, BfMethodBoundExpression);
|
||||
|
||||
class BfLambdaCapture : public BfAstNode
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfLambdaCapture, BfAstNode);
|
||||
|
||||
BfTokenNode* mOpenBracket;
|
||||
BfTokenNode* mCloseBracket;
|
||||
BfTokenNode* mCaptureToken;
|
||||
}; BF_AST_DECL(BfLambdaCapture, BfAstNode);
|
||||
|
||||
class BfLambdaBindExpression : public BfExpression
|
||||
{
|
||||
public:
|
||||
BF_AST_TYPE(BfLambdaBindExpression, BfExpression);
|
||||
|
||||
BfAstNode* mNewToken;
|
||||
BfLambdaCapture* mLambdaCapture;
|
||||
BfAstNode* mNewToken;
|
||||
BfTokenNode* mOpenParen;
|
||||
BfTokenNode* mCloseParen;
|
||||
BfSizedArray<ASTREF(BfIdentifierNode*)> mParams;
|
||||
|
|
|
@ -380,6 +380,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mClassVDataTypeDef = NULL;
|
||||
mCLinkAttributeTypeDef = NULL;
|
||||
mCReprAttributeTypeDef = NULL;
|
||||
mAlignAttributeTypeDef = NULL;
|
||||
mNoDiscardAttributeTypeDef = NULL;
|
||||
mDisableObjectAccessChecksAttributeTypeDef = NULL;
|
||||
mDbgRawAllocDataTypeDef = NULL;
|
||||
|
@ -5832,6 +5833,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
||||
mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
|
||||
mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
|
||||
mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
|
||||
mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");
|
||||
mDisableObjectAccessChecksAttributeTypeDef = _GetRequiredType("System.DisableObjectAccessChecksAttribute");
|
||||
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
|
||||
|
|
|
@ -378,6 +378,7 @@ public:
|
|||
BfTypeDef* mInlineAttributeTypeDef;
|
||||
BfTypeDef* mCLinkAttributeTypeDef;
|
||||
BfTypeDef* mCReprAttributeTypeDef;
|
||||
BfTypeDef* mAlignAttributeTypeDef;
|
||||
BfTypeDef* mNoDiscardAttributeTypeDef;
|
||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||
BfTypeDef* mFriendAttributeTypeDef;
|
||||
|
|
|
@ -143,8 +143,8 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
isConst = false;
|
||||
}
|
||||
|
||||
if (!isConst)
|
||||
{
|
||||
if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
|
||||
{
|
||||
mModule->Fail("Expression does not evaluate to a constant value", expr);
|
||||
|
||||
if (wantType != NULL)
|
||||
|
|
|
@ -132,6 +132,7 @@ void BfElementVisitor::Visit(BfScopeNode* scopeNode)
|
|||
VisitChild(scopeNode->mScopeToken);
|
||||
VisitChild(scopeNode->mColonToken);
|
||||
VisitChild(scopeNode->mTargetNode);
|
||||
VisitChild(scopeNode->mAttributes);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfNewNode* newNode)
|
||||
|
@ -141,6 +142,7 @@ void BfElementVisitor::Visit(BfNewNode* newNode)
|
|||
VisitChild(newNode->mNewToken);
|
||||
VisitChild(newNode->mColonToken);
|
||||
VisitChild(newNode->mAllocNode);
|
||||
VisitChild(newNode->mAttributes);
|
||||
}
|
||||
|
||||
void BfElementVisitor::Visit(BfLabeledBlock* labeledBlock)
|
||||
|
@ -532,12 +534,6 @@ void BfElementVisitor::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|||
Visit(lambdaBindExpr->ToBase());
|
||||
|
||||
VisitChild(lambdaBindExpr->mNewToken);
|
||||
if (lambdaBindExpr->mLambdaCapture != NULL)
|
||||
{
|
||||
VisitChild(lambdaBindExpr->mLambdaCapture->mOpenBracket);
|
||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCaptureToken);
|
||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCloseBracket);
|
||||
}
|
||||
|
||||
VisitChild(lambdaBindExpr->mOpenParen);
|
||||
VisitChild(lambdaBindExpr->mCloseParen);
|
||||
|
|
|
@ -2818,6 +2818,11 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
|||
varSkipCount--;
|
||||
}
|
||||
|
||||
if (varDecl->mNotCaptured)
|
||||
{
|
||||
mModule->Fail("Local variable is not captured", refNode);
|
||||
}
|
||||
|
||||
if ((varSkipCount == 0) && (varDecl != NULL))
|
||||
{
|
||||
if ((closureTypeInst != NULL) && (wantName == "this"))
|
||||
|
@ -9376,7 +9381,7 @@ void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration*
|
|||
}
|
||||
}
|
||||
|
||||
BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr)
|
||||
BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget)
|
||||
{
|
||||
auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
|
||||
BfLambdaInstance* lambdaInstance = NULL;
|
||||
|
@ -9527,8 +9532,11 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (lambdaBindExpr->mNewToken == NULL)
|
||||
if ((lambdaBindExpr->mNewToken == NULL) || (isFunctionBind))
|
||||
{
|
||||
if ((lambdaBindExpr->mNewToken != NULL) && (isFunctionBind))
|
||||
mModule->Fail("Binds to functions should do not require allocations.", lambdaBindExpr->mNewToken);
|
||||
|
||||
if (lambdaBindExpr->mDtor != NULL)
|
||||
{
|
||||
mModule->Fail("Valueless method reference cannot contain destructor. Consider either removing destructor or using an allocated lambda.", lambdaBindExpr->mDtor->mTildeToken);
|
||||
|
@ -9695,6 +9703,89 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
methodDef->mBody = lambdaBindExpr->mBody;
|
||||
///
|
||||
|
||||
auto varMethodState = methodState.mPrevMethodState;
|
||||
bool hasExplicitCaptureNames = false;
|
||||
|
||||
for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures)
|
||||
{
|
||||
if (captureEntry.mNameNode == NULL)
|
||||
{
|
||||
hasExplicitCaptureNames = false;
|
||||
break;
|
||||
}
|
||||
|
||||
hasExplicitCaptureNames = true;
|
||||
}
|
||||
|
||||
auto _SetNotCapturedFlag = [&](bool notCaptured)
|
||||
{
|
||||
auto varMethodState = methodState.mPrevMethodState;
|
||||
while (varMethodState != NULL)
|
||||
{
|
||||
for (int localIdx = 0; localIdx < varMethodState->mLocals.size(); localIdx++)
|
||||
{
|
||||
auto localVar = varMethodState->mLocals[localIdx];
|
||||
localVar->mNotCaptured = notCaptured;
|
||||
}
|
||||
|
||||
varMethodState = varMethodState->mPrevMethodState;
|
||||
if (varMethodState == NULL)
|
||||
break;
|
||||
if (varMethodState->mMixinState != NULL)
|
||||
break;
|
||||
if (varMethodState->mClosureState != NULL)
|
||||
{
|
||||
if (!varMethodState->mClosureState->mCapturing)
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (hasExplicitCaptureNames)
|
||||
{
|
||||
_SetNotCapturedFlag(true);
|
||||
|
||||
auto varMethodState = methodState.mPrevMethodState;
|
||||
while (varMethodState != NULL)
|
||||
{
|
||||
for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures)
|
||||
{
|
||||
if (captureEntry.mNameNode != NULL)
|
||||
{
|
||||
StringT<64> captureName;
|
||||
captureEntry.mNameNode->ToString(captureName);
|
||||
BfLocalVarEntry* entry;
|
||||
if (varMethodState->mLocalVarSet.TryGetWith<StringImpl&>(captureName, &entry))
|
||||
{
|
||||
auto localVar = entry->mLocalVar;
|
||||
while (localVar != NULL)
|
||||
{
|
||||
if (autoComplete != NULL)
|
||||
autoComplete->CheckLocalRef(captureEntry.mNameNode, localVar);
|
||||
if (((mModule->mCurMethodState->mClosureState == NULL) || (mModule->mCurMethodState->mClosureState->mCapturing)) &&
|
||||
(mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL))
|
||||
mModule->mCompiler->mResolvePassData->HandleLocalReference(captureEntry.mNameNode, localVar->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVar->mLocalVarId);
|
||||
|
||||
localVar->mNotCaptured = false;
|
||||
localVar = localVar->mShadowedLocal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
varMethodState = varMethodState->mPrevMethodState;
|
||||
if (varMethodState == NULL)
|
||||
break;
|
||||
if (varMethodState->mMixinState != NULL)
|
||||
break;
|
||||
if (varMethodState->mClosureState != NULL)
|
||||
{
|
||||
if (!varMethodState->mClosureState->mCapturing)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BfClosureInstanceInfo* closureInstanceInfo = new BfClosureInstanceInfo();
|
||||
|
||||
auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
|
@ -9704,6 +9795,9 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
|
||||
VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
|
||||
|
||||
if (hasExplicitCaptureNames)
|
||||
_SetNotCapturedFlag(false);
|
||||
|
||||
// If we ended up being called by a method with a lower captureStartAccessId, propagate that to whoever is calling us, too...
|
||||
if ((methodState.mPrevMethodState->mClosureState != NULL) && (methodState.mPrevMethodState->mClosureState->mCapturing))
|
||||
{
|
||||
|
@ -9731,18 +9825,27 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
prevIgnoreWrites.Restore();
|
||||
mModule->mBfIRBuilder->RestoreDebugLocation();
|
||||
|
||||
BfCaptureType captureType = BfCaptureType_Value;
|
||||
if ((lambdaBindExpr->mLambdaCapture != NULL) && (lambdaBindExpr->mLambdaCapture->mCaptureToken != NULL))
|
||||
auto _GetCaptureType = [&](const StringImpl& str)
|
||||
{
|
||||
if (lambdaBindExpr->mLambdaCapture->mCaptureToken->GetToken() == BfToken_Ampersand)
|
||||
captureType = BfCaptureType_Reference;
|
||||
else
|
||||
captureType = BfCaptureType_Copy;
|
||||
}
|
||||
if (allocTarget.mCaptureInfo.mCaptures.IsEmpty())
|
||||
return BfCaptureType_Copy;
|
||||
|
||||
for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures)
|
||||
{
|
||||
if ((captureEntry.mNameNode == NULL) || (captureEntry.mNameNode->Equals(str)))
|
||||
{
|
||||
captureEntry.mUsed = true;
|
||||
return captureEntry.mCaptureType;
|
||||
}
|
||||
}
|
||||
|
||||
return BfCaptureType_None;
|
||||
};
|
||||
|
||||
Array<BfClosureCapturedEntry> capturedEntries;
|
||||
|
||||
bool copyOuterCaptures = false;
|
||||
//
|
||||
{
|
||||
auto varMethodState = methodState.mPrevMethodState;
|
||||
|
||||
|
@ -9771,6 +9874,11 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
auto capturedType = outerLocal->mResolvedType;
|
||||
bool captureByRef = false;
|
||||
|
||||
auto captureType = _GetCaptureType(localVar->mName);
|
||||
if (captureType == BfCaptureType_None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!capturedType->IsRef())
|
||||
{
|
||||
|
@ -9823,9 +9931,17 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
}
|
||||
}
|
||||
|
||||
for (auto& captureEntry : allocTarget.mCaptureInfo.mCaptures)
|
||||
{
|
||||
if ((!captureEntry.mUsed) && (captureEntry.mNameNode != NULL))
|
||||
mModule->Warn(0, "Capture specifier not used", captureEntry.mNameNode);
|
||||
}
|
||||
|
||||
for (auto copyField : closureState.mReferencedOuterClosureMembers)
|
||||
{
|
||||
auto fieldDef = copyField->GetFieldDef();
|
||||
auto captureType = _GetCaptureType(fieldDef->mName);
|
||||
|
||||
BfClosureCapturedEntry capturedEntry;
|
||||
capturedEntry.mName = fieldDef->mName;
|
||||
capturedEntry.mType = copyField->mResolvedType;
|
||||
|
@ -10200,7 +10316,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|||
return;
|
||||
}
|
||||
|
||||
BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr);
|
||||
BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr, allocTarget);
|
||||
if (lambdaInstance == NULL)
|
||||
return;
|
||||
BfTypeInstance* delegateTypeInstance = lambdaInstance->mDelegateTypeInstance;
|
||||
|
@ -11052,7 +11168,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
|||
arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, false), ptrType);
|
||||
else
|
||||
{
|
||||
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags), ptrType);
|
||||
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), ptrType);
|
||||
}
|
||||
|
||||
_HandleInitExprs(arrayValue.mValue, 0, objCreateExpr->mArguments);
|
||||
|
@ -11071,7 +11187,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
|||
arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
|
||||
else
|
||||
{
|
||||
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags), arrayType);
|
||||
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), arrayType);
|
||||
|
||||
if (isScopeAlloc)
|
||||
{
|
||||
|
@ -11538,6 +11654,7 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
|
|||
BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenNode*& newToken)
|
||||
{
|
||||
auto autoComplete = GetAutoComplete();
|
||||
BfAttributeDirective* attributeDirective = NULL;
|
||||
|
||||
BfAllocTarget allocTarget;
|
||||
allocTarget.mRefNode = allocNode;
|
||||
|
@ -11555,6 +11672,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
|||
if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
|
||||
autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken);
|
||||
}
|
||||
attributeDirective = scopeNode->mAttributes;
|
||||
}
|
||||
if (auto newNode = BfNodeDynCast<BfNewNode>(allocNode))
|
||||
{
|
||||
|
@ -11568,6 +11686,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
|||
{
|
||||
allocTarget.mScopedInvocationTarget = scopedInvocationTarget;
|
||||
}
|
||||
attributeDirective = newNode->mAttributes;
|
||||
}
|
||||
}
|
||||
else if (newToken->GetToken() == BfToken_Scope)
|
||||
|
@ -11580,6 +11699,38 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
|||
if (mModule->mCurMethodState != NULL)
|
||||
allocTarget.mScopeData = &mModule->mCurMethodState->mHeadScope;
|
||||
}
|
||||
|
||||
if (attributeDirective != NULL)
|
||||
{
|
||||
auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, true, &allocTarget.mCaptureInfo);
|
||||
if (customAttrs != NULL)
|
||||
{
|
||||
for (auto& attrib : customAttrs->mAttributes)
|
||||
{
|
||||
if (attrib.mType->mTypeDef == mModule->mCompiler->mAlignAttributeTypeDef)
|
||||
{
|
||||
allocTarget.mAlignOverride = 16; // System conservative default
|
||||
|
||||
if (!attrib.mCtorArgs.IsEmpty())
|
||||
{
|
||||
BfIRConstHolder* constHolder = mModule->mCurTypeInstance->mConstHolder;
|
||||
auto constant = constHolder->GetConstant(attrib.mCtorArgs[0]);
|
||||
if (constant != NULL)
|
||||
{
|
||||
int alignOverride = (int)BF_MAX(1, constant->mInt64);
|
||||
if ((alignOverride & (alignOverride - 1)) == 0)
|
||||
allocTarget.mAlignOverride = alignOverride;
|
||||
else
|
||||
mModule->Fail("Alignment must be a power of 2", attrib.mRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete customAttrs;
|
||||
}
|
||||
}
|
||||
|
||||
return allocTarget;
|
||||
}
|
||||
|
||||
|
|
|
@ -378,7 +378,7 @@ public:
|
|||
BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType);
|
||||
void ConstResolve(BfExpression* expr);
|
||||
void ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl<int64>& dimLengths, int dim, bool& hasFailed);
|
||||
BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr);
|
||||
BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget);
|
||||
void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor);
|
||||
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
||||
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken);
|
||||
|
|
|
@ -7521,7 +7521,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
}
|
||||
if (!isDynAlloc)
|
||||
mBfIRBuilder->ClearDebugLocation(allocaInst);
|
||||
mBfIRBuilder->SetAllocaAlignment(allocaInst, type->mAlign);
|
||||
mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign);
|
||||
if (!isDynAlloc)
|
||||
mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
||||
auto typedVal = BfTypedValue(result, type, BfTypedValueKind_Addr);
|
||||
|
@ -7606,7 +7606,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
auto allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(byteType), sizeValue);
|
||||
if (!isDynAlloc)
|
||||
mBfIRBuilder->ClearDebugLocation(allocaInst);
|
||||
mBfIRBuilder->SetAllocaAlignment(allocaInst, arrayType->mAlign);
|
||||
mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign);
|
||||
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(arrayType)), arrayType);
|
||||
mBfIRBuilder->ClearDebugLocation_Last();
|
||||
if (!isDynAlloc)
|
||||
|
@ -9214,6 +9214,7 @@ static String GetAttributesTargetListString(BfAttributeTargets attrTarget)
|
|||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_GenericParameter, resultStr, "generic parameters");
|
||||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_Invocation, resultStr, "invocations");
|
||||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_MemberAccess, resultStr, "member access");
|
||||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_Alloc, resultStr, "allocations");
|
||||
if (resultStr.IsEmpty())
|
||||
return "<nothing>";
|
||||
return resultStr;
|
||||
|
@ -9377,7 +9378,7 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf
|
|||
}
|
||||
}
|
||||
|
||||
void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget)
|
||||
void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, bool allowNonConstArgs, BfCaptureInfo* captureInfo)
|
||||
{
|
||||
if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) &&
|
||||
(attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL))
|
||||
|
@ -9398,6 +9399,26 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
|
||||
for (; attributesDirective != NULL; attributesDirective = attributesDirective->mNextAttribute)
|
||||
{
|
||||
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(attributesDirective->mAttributeTargetSpecifier))
|
||||
{
|
||||
if (captureInfo == NULL)
|
||||
{
|
||||
Fail("Capture specifiers can only be used in lambda allocations", attributesDirective);
|
||||
continue;
|
||||
}
|
||||
|
||||
BfCaptureInfo::Entry captureEntry;
|
||||
captureEntry.mCaptureType = (tokenNode->mToken == BfToken_Ampersand) ? BfCaptureType_Reference : BfCaptureType_Copy;
|
||||
if (!attributesDirective->mArguments.IsEmpty())
|
||||
{
|
||||
captureEntry.mNameNode = BfNodeDynCast<BfIdentifierNode>(attributesDirective->mArguments[0]);
|
||||
if ((captureEntry.mNameNode != NULL) && (autoComplete != NULL))
|
||||
autoComplete->CheckIdentifier(captureEntry.mNameNode);
|
||||
}
|
||||
captureInfo->mCaptures.Add(captureEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
BfAutoParentNodeEntry autoParentNodeEntry(this, attributesDirective);
|
||||
|
||||
BfCustomAttribute customAttribute;
|
||||
|
@ -9509,7 +9530,9 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
|
||||
customAttribute.mType = attrTypeInst;
|
||||
|
||||
BfConstResolver constResolver(this);
|
||||
BfConstResolver constResolver(this);
|
||||
if (allowNonConstArgs)
|
||||
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
||||
|
||||
bool inPropSet = false;
|
||||
SizedArray<BfResolvedArg, 2> argValues;
|
||||
|
@ -9775,7 +9798,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
// Move all those to the constHolder
|
||||
for (auto& ctorArg : customAttribute.mCtorArgs)
|
||||
{
|
||||
CurrentAddToConstHolder(ctorArg);
|
||||
if (ctorArg.IsConst())
|
||||
CurrentAddToConstHolder(ctorArg);
|
||||
}
|
||||
|
||||
if (attributesDirective->mAttributeTargetSpecifier != NULL)
|
||||
|
@ -9835,10 +9859,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
ValidateCustomAttributes(customAttributes, attrTarget);
|
||||
}
|
||||
|
||||
BfCustomAttributes* BfModule::GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType)
|
||||
BfCustomAttributes* BfModule::GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs, BfCaptureInfo* captureInfo)
|
||||
{
|
||||
BfCustomAttributes* customAttributes = new BfCustomAttributes();
|
||||
GetCustomAttributes(customAttributes, attributesDirective, attrType);
|
||||
GetCustomAttributes(customAttributes, attributesDirective, attrType, allowNonConstArgs, captureInfo);
|
||||
return customAttributes;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,8 @@ enum BfEvalExprFlags
|
|||
BfEvalExprFlags_AllowOutExpr = 0x1000,
|
||||
BfEvalExprFlags_FieldInitializer = 0x2000,
|
||||
BfEvalExprFlags_VariableDeclaration = 0x4000,
|
||||
BfEvalExprFlags_NoAutoComplete = 0x8000
|
||||
BfEvalExprFlags_NoAutoComplete = 0x8000,
|
||||
BfEvalExprFlags_AllowNonConst = 0x10000
|
||||
};
|
||||
|
||||
enum BfCastFlags
|
||||
|
@ -146,6 +147,7 @@ public:
|
|||
bool mAllowAddr;
|
||||
bool mIsShadow;
|
||||
bool mUsedImplicitly; // Passed implicitly to a local method, capture by ref if we can
|
||||
bool mNotCaptured;
|
||||
BfLocalVariable* mShadowedLocal;
|
||||
|
||||
public:
|
||||
|
@ -172,6 +174,7 @@ public:
|
|||
mAllowAddr = false;
|
||||
mIsShadow = false;
|
||||
mUsedImplicitly = false;
|
||||
mNotCaptured = false;
|
||||
mShadowedLocal = NULL;
|
||||
}
|
||||
|
||||
|
@ -441,6 +444,27 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct BfCaptureInfo
|
||||
{
|
||||
public:
|
||||
struct Entry
|
||||
{
|
||||
BfCaptureType mCaptureType;
|
||||
bool mUsed;
|
||||
BfIdentifierNode* mNameNode;
|
||||
|
||||
Entry()
|
||||
{
|
||||
mCaptureType = BfCaptureType_Copy;
|
||||
mUsed = false;
|
||||
mNameNode = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
Array<Entry> mCaptures;
|
||||
};
|
||||
|
||||
class BfAllocTarget
|
||||
{
|
||||
public:
|
||||
|
@ -448,6 +472,8 @@ public:
|
|||
BfAstNode* mRefNode;
|
||||
BfTypedValue mCustomAllocator;
|
||||
BfScopedInvocationTarget* mScopedInvocationTarget;
|
||||
int mAlignOverride;
|
||||
BfCaptureInfo mCaptureInfo;
|
||||
|
||||
public:
|
||||
BfAllocTarget()
|
||||
|
@ -456,6 +482,7 @@ public:
|
|||
mRefNode = NULL;
|
||||
mCustomAllocator = NULL;
|
||||
mScopedInvocationTarget = NULL;
|
||||
mAlignOverride = -1;
|
||||
}
|
||||
|
||||
BfAllocTarget(BfScopeData* scopeData)
|
||||
|
@ -464,6 +491,7 @@ public:
|
|||
mRefNode = NULL;
|
||||
mCustomAllocator = NULL;
|
||||
mScopedInvocationTarget = NULL;
|
||||
mAlignOverride = -1;
|
||||
}
|
||||
|
||||
BfAllocTarget(const BfTypedValue& customAllocator, BfAstNode* refNode)
|
||||
|
@ -472,6 +500,7 @@ public:
|
|||
mCustomAllocator = customAllocator;
|
||||
mRefNode = NULL;
|
||||
mScopedInvocationTarget = NULL;
|
||||
mAlignOverride = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1409,8 +1438,8 @@ public:
|
|||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType);
|
||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType);
|
||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||
void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered);
|
||||
void ProcessCustomAttributeData();
|
||||
bool TryGetConstString(BfIRConstHolder* constHolder, BfIRValue irValue, StringImpl& str);
|
||||
|
|
|
@ -588,6 +588,35 @@ void BfPrinter::Visit(BfErrorNode* errorNode)
|
|||
VisitChild(errorNode->mRefNode);
|
||||
}
|
||||
|
||||
void BfPrinter::Visit(BfScopeNode* scopeNode)
|
||||
{
|
||||
Visit(scopeNode->ToBase());
|
||||
|
||||
VisitChild(scopeNode->mScopeToken);
|
||||
VisitChild(scopeNode->mColonToken);
|
||||
VisitChild(scopeNode->mTargetNode);
|
||||
if (scopeNode->mAttributes != NULL)
|
||||
{
|
||||
ExpectSpace();
|
||||
VisitChild(scopeNode->mAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
void BfPrinter::Visit(BfNewNode* newNode)
|
||||
{
|
||||
Visit(newNode->ToBase());
|
||||
|
||||
VisitChild(newNode->mNewToken);
|
||||
VisitChild(newNode->mColonToken);
|
||||
VisitChild(newNode->mAllocNode);
|
||||
if (newNode->mAttributes != NULL)
|
||||
{
|
||||
ExpectSpace();
|
||||
VisitChild(newNode->mAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BfPrinter::Visit(BfExpression* expr)
|
||||
{
|
||||
Visit(expr->ToBase());
|
||||
|
@ -698,14 +727,19 @@ void BfPrinter::Visit(BfAttributeDirective* attributeDirective)
|
|||
VisitChild(attributeDirective->mAttrOpenToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
||||
{
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mTargetToken);
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mColonToken);
|
||||
ExpectSpace();
|
||||
if (auto attributeTargetSpecifier = BfNodeDynCast<BfAttributeTargetSpecifier>(attributeDirective->mAttributeTargetSpecifier))
|
||||
{
|
||||
VisitChild(attributeTargetSpecifier->mTargetToken);
|
||||
VisitChild(attributeTargetSpecifier->mColonToken);
|
||||
ExpectSpace();
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier);
|
||||
}
|
||||
}
|
||||
|
||||
VisitChild(attributeDirective->mAttributeTypeRef);
|
||||
|
@ -1226,13 +1260,7 @@ void BfPrinter::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|||
Visit(lambdaBindExpr->ToBase());
|
||||
|
||||
VisitChild(lambdaBindExpr->mNewToken);
|
||||
ExpectSpace();
|
||||
if (lambdaBindExpr->mLambdaCapture != NULL)
|
||||
{
|
||||
VisitChild(lambdaBindExpr->mLambdaCapture->mOpenBracket);
|
||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCaptureToken);
|
||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCloseBracket);
|
||||
}
|
||||
ExpectSpace();
|
||||
VisitChild(lambdaBindExpr->mOpenParen);
|
||||
for (int i = 0; i < (int)lambdaBindExpr->mParams.size(); i++)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,8 @@ public:
|
|||
|
||||
virtual void Visit(BfAstNode* bfAstNode) override;
|
||||
virtual void Visit(BfErrorNode* bfErrorNode) override;
|
||||
virtual void Visit(BfScopeNode * scopeNode) override;
|
||||
virtual void Visit(BfNewNode * newNode) override;
|
||||
virtual void Visit(BfExpression* expr) override;
|
||||
virtual void Visit(BfExpressionStatement* exprStmt) override;
|
||||
virtual void Visit(BfAttributedExpression* attribExpr) override;
|
||||
|
|
|
@ -5105,6 +5105,8 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
|||
ReplaceNode(startToken, attributeDirective);
|
||||
attributeDirective->mAttrOpenToken = startToken;
|
||||
|
||||
bool isHandled = false;
|
||||
|
||||
auto nextNode = mVisitorPos.GetNext();
|
||||
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
||||
if (tokenNode != NULL)
|
||||
|
@ -5114,32 +5116,50 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
|||
auto attributeTargetSpecifier = mAlloc->Alloc<BfAttributeTargetSpecifier>();
|
||||
ReplaceNode(tokenNode, attributeTargetSpecifier);
|
||||
MEMBER_SET(attributeDirective, mAttributeTargetSpecifier, attributeTargetSpecifier);
|
||||
attributeDirective->mAttributeTargetSpecifier->mTargetToken = tokenNode;
|
||||
attributeTargetSpecifier->mTargetToken = tokenNode;
|
||||
mVisitorPos.MoveNext();
|
||||
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_Colon);
|
||||
if (tokenNode != NULL)
|
||||
MEMBER_SET(attributeDirective->mAttributeTargetSpecifier, mColonToken, tokenNode);
|
||||
MEMBER_SET(attributeTargetSpecifier, mColonToken, tokenNode);
|
||||
attributeDirective->SetSrcEnd(attributeDirective->mAttributeTargetSpecifier->GetSrcEnd());
|
||||
}
|
||||
}
|
||||
|
||||
auto typeRef = CreateTypeRefAfter(attributeDirective);
|
||||
if (typeRef == NULL)
|
||||
{
|
||||
auto nextNode = mVisitorPos.GetNext();
|
||||
if (BfTokenNode* endToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||
else if ((tokenNode->mToken == BfToken_Ampersand) || (tokenNode->mToken == BfToken_AssignEquals))
|
||||
{
|
||||
if (endToken->GetToken() == BfToken_RBracket)
|
||||
MEMBER_SET(attributeDirective, mAttributeTargetSpecifier, tokenNode);
|
||||
mVisitorPos.MoveNext();
|
||||
isHandled = true;
|
||||
nextNode = mVisitorPos.GetNext();
|
||||
if (auto identiferNode = BfNodeDynCast<BfIdentifierNode>(nextNode))
|
||||
{
|
||||
attributeDirective->SetSrcEnd(identiferNode->GetSrcEnd());
|
||||
arguments.push_back(identiferNode);
|
||||
mVisitorPos.MoveNext();
|
||||
MEMBER_SET(attributeDirective, mCtorCloseParen, endToken);
|
||||
return attributeDirective;
|
||||
nextNode = mVisitorPos.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
return attributeDirective;
|
||||
}
|
||||
MEMBER_SET(attributeDirective, mAttributeTypeRef, typeRef);
|
||||
|
||||
if (!isHandled)
|
||||
{
|
||||
auto typeRef = CreateTypeRefAfter(attributeDirective);
|
||||
if (typeRef == NULL)
|
||||
{
|
||||
auto nextNode = mVisitorPos.GetNext();
|
||||
if (BfTokenNode* endToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||
{
|
||||
if (endToken->GetToken() == BfToken_RBracket)
|
||||
{
|
||||
mVisitorPos.MoveNext();
|
||||
MEMBER_SET(attributeDirective, mCtorCloseParen, endToken);
|
||||
return attributeDirective;
|
||||
}
|
||||
}
|
||||
|
||||
return attributeDirective;
|
||||
}
|
||||
MEMBER_SET(attributeDirective, mAttributeTypeRef, typeRef);
|
||||
}
|
||||
|
||||
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_LParen, BfToken_RBracket, BfToken_Comma);
|
||||
if (tokenNode == NULL)
|
||||
return attributeDirective;
|
||||
|
@ -5159,8 +5179,7 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
|||
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_RBracket, BfToken_Comma);
|
||||
if (tokenNode == NULL)
|
||||
return attributeDirective;
|
||||
}
|
||||
|
||||
}
|
||||
Do_RBracket:
|
||||
if (tokenNode->GetToken() == BfToken_RBracket)
|
||||
{
|
||||
|
@ -5171,9 +5190,8 @@ Do_RBracket:
|
|||
return attributeDirective;
|
||||
mVisitorPos.MoveNext();
|
||||
}
|
||||
|
||||
// Has another one- chain it
|
||||
//mVisitorPos.MoveNext();
|
||||
|
||||
// Has another one- chain it
|
||||
auto nextAttribute = CreateAttributeDirective(tokenNode);
|
||||
if (nextAttribute != NULL)
|
||||
{
|
||||
|
@ -6810,41 +6828,10 @@ BfLambdaBindExpression* BfReducer::CreateLambdaBindExpression(BfAstNode* allocNo
|
|||
ReplaceNode(parenToken, lambdaBindExpr);
|
||||
tokenNode = parenToken;
|
||||
}
|
||||
//auto tokenNode = ExpectTokenAfter(lambdaBindExpr, BfToken_LParen, BfToken_LBracket);
|
||||
|
||||
if (tokenNode == NULL)
|
||||
return lambdaBindExpr;
|
||||
|
||||
if (tokenNode->GetToken() == BfToken_LBracket)
|
||||
{
|
||||
auto lambdaCapture = mAlloc->Alloc<BfLambdaCapture>();
|
||||
ReplaceNode(tokenNode, lambdaCapture);
|
||||
|
||||
MEMBER_SET(lambdaBindExpr, mLambdaCapture, lambdaCapture);
|
||||
MEMBER_SET(lambdaCapture, mOpenBracket, tokenNode);
|
||||
|
||||
while (true)
|
||||
{
|
||||
tokenNode = ExpectTokenAfter(lambdaBindExpr, BfToken_Ampersand, BfToken_AssignEquals, BfToken_RBracket);
|
||||
if (tokenNode == NULL)
|
||||
return lambdaBindExpr;
|
||||
|
||||
if ((tokenNode->GetToken() == BfToken_Ampersand) || (tokenNode->GetToken() == BfToken_AssignEquals))
|
||||
{
|
||||
MEMBER_SET(lambdaCapture, mCaptureToken, tokenNode);
|
||||
lambdaBindExpr->SetSrcEnd(lambdaCapture->GetSrcEnd());
|
||||
}
|
||||
|
||||
if (tokenNode->GetToken() == BfToken_RBracket)
|
||||
{
|
||||
MEMBER_SET(lambdaCapture, mCloseBracket, tokenNode);
|
||||
lambdaBindExpr->SetSrcEnd(lambdaCapture->GetSrcEnd());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tokenNode = ExpectTokenAfter(lambdaBindExpr, BfToken_LParen);
|
||||
}
|
||||
|
||||
MEMBER_SET_CHECKED(lambdaBindExpr, mOpenParen, tokenNode);
|
||||
|
||||
for (int paramIdx = 0; true; paramIdx++)
|
||||
|
@ -7051,11 +7038,17 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
if (allocToken->GetToken() == BfToken_Scope)
|
||||
{
|
||||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if ((nextToken != NULL) && (nextToken->GetToken() == BfToken_Colon))
|
||||
{
|
||||
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
||||
ReplaceNode(allocToken, scopeNode);
|
||||
scopeNode->mScopeToken = allocToken;
|
||||
if (nextToken == NULL)
|
||||
return allocToken;
|
||||
if ((nextToken->mToken != BfToken_Colon) && (nextToken->mToken != BfToken_LBracket))
|
||||
return allocToken;
|
||||
|
||||
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
||||
ReplaceNode(allocToken, scopeNode);
|
||||
scopeNode->mScopeToken = allocToken;
|
||||
|
||||
if (nextToken->mToken == BfToken_Colon)
|
||||
{
|
||||
MEMBER_SET(scopeNode, mColonToken, nextToken);
|
||||
mVisitorPos.MoveNext();
|
||||
|
||||
|
@ -7077,19 +7070,36 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
{
|
||||
FailAfter("Expected scope name", scopeNode);
|
||||
}
|
||||
|
||||
return scopeNode;
|
||||
}
|
||||
|
||||
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if (nextToken == NULL)
|
||||
return scopeNode;
|
||||
if (nextToken->mToken != BfToken_LBracket)
|
||||
return scopeNode;
|
||||
|
||||
mVisitorPos.MoveNext();
|
||||
auto attributeDirective = CreateAttributeDirective(nextToken);
|
||||
MEMBER_SET(scopeNode, mAttributes, attributeDirective);
|
||||
|
||||
return scopeNode;
|
||||
}
|
||||
|
||||
if (allocToken->GetToken() == BfToken_New)
|
||||
{//
|
||||
{
|
||||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if ((nextToken != NULL) && (nextToken->GetToken() == BfToken_Colon))
|
||||
{ //
|
||||
auto newNode = mAlloc->Alloc<BfNewNode>();
|
||||
ReplaceNode(allocToken, newNode);
|
||||
newNode->mNewToken = allocToken;
|
||||
|
||||
if (nextToken == NULL)
|
||||
return allocToken;
|
||||
if ((nextToken->mToken != BfToken_Colon) && (nextToken->mToken != BfToken_LBracket))
|
||||
return allocToken;
|
||||
|
||||
auto newNode = mAlloc->Alloc<BfNewNode>();
|
||||
ReplaceNode(allocToken, newNode);
|
||||
newNode->mNewToken = allocToken;
|
||||
|
||||
if (nextToken->mToken == BfToken_Colon)
|
||||
{
|
||||
MEMBER_SET(newNode, mColonToken, nextToken);
|
||||
mVisitorPos.MoveNext();
|
||||
|
||||
|
@ -7166,15 +7176,7 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
{
|
||||
MEMBER_SET(newNode, mAllocNode, identifier);
|
||||
mVisitorPos.MoveNext();
|
||||
}
|
||||
|
||||
// This causes parse ambiguities
|
||||
/*mVisitorPos.mReadPos = nodeIdx;
|
||||
auto allocExpr = CreateExpressionAfter(newNode, BfReducer::CreateExprFlags_NoCast);
|
||||
if (allocExpr != NULL)
|
||||
{
|
||||
MEMBER_SET(newNode, mAllocNode, allocExpr);
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -7183,9 +7185,19 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
{
|
||||
FailAfter("Expected allocator expression", newNode);
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if (nextToken == NULL)
|
||||
return newNode;
|
||||
if (nextToken->mToken != BfToken_LBracket)
|
||||
return newNode;
|
||||
|
||||
mVisitorPos.MoveNext();
|
||||
auto attributeDirective = CreateAttributeDirective(nextToken);
|
||||
MEMBER_SET(newNode, mAttributes, attributeDirective);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
return allocToken;
|
||||
|
|
|
@ -1411,6 +1411,7 @@ enum BfAttributeTargets : int32
|
|||
BfAttributeTargets_GenericParameter = 0x8000,
|
||||
BfAttributeTargets_Invocation = 0x10000,
|
||||
BfAttributeTargets_MemberAccess = 0x20000,
|
||||
BfAttributeTargets_Alloc = 0x40000,
|
||||
BfAttributeTargets_All = 0x3FFFF
|
||||
};
|
||||
|
||||
|
@ -1879,9 +1880,9 @@ public:
|
|||
|
||||
enum BfCaptureType
|
||||
{
|
||||
BfCaptureType_Value,
|
||||
BfCaptureType_Reference,
|
||||
BfCaptureType_Copy
|
||||
BfCaptureType_None,
|
||||
BfCaptureType_Copy,
|
||||
BfCaptureType_Reference,
|
||||
};
|
||||
|
||||
class BfClosureType : public BfTypeInstance
|
||||
|
|
|
@ -206,8 +206,15 @@ void BfSourceClassifier::Visit(BfAttributeDirective* attributeDirective)
|
|||
|
||||
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
||||
{
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mTargetToken);
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mColonToken);
|
||||
if (auto attributeTargetSpecifier = BfNodeDynCast<BfAttributeTargetSpecifier>(attributeDirective->mAttributeTargetSpecifier))
|
||||
{
|
||||
VisitChild(attributeTargetSpecifier->mTargetToken);
|
||||
VisitChild(attributeTargetSpecifier->mColonToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier);
|
||||
}
|
||||
}
|
||||
|
||||
VisitChild(attributeDirective->mAttributeTypeRef);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue