mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28: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
|
@ -25,6 +25,7 @@ namespace System
|
||||||
GenericParameter = 0x8000,
|
GenericParameter = 0x8000,
|
||||||
Invocation = 0x10000,
|
Invocation = 0x10000,
|
||||||
MemberAccess = 0x20000,
|
MemberAccess = 0x20000,
|
||||||
|
Alloc = 0x40000,
|
||||||
|
|
||||||
All = Assembly | Module | Class | Struct | Enum | Constructor |
|
All = Assembly | Module | Class | Struct | Enum | Constructor |
|
||||||
Method | Property | Field | StaticField | Interface | Parameter |
|
Method | Property | Field | StaticField | Interface | Parameter |
|
||||||
|
@ -57,7 +58,7 @@ namespace System
|
||||||
|
|
||||||
public sealed struct AttributeUsageAttribute : Attribute
|
public sealed struct AttributeUsageAttribute : Attribute
|
||||||
{
|
{
|
||||||
internal AttributeTargets mAttributeTarget = AttributeTargets.All;
|
internal AttributeTargets mAttributeTarget = .All;
|
||||||
internal AttributeFlags mAttributeFlags = .None;
|
internal AttributeFlags mAttributeFlags = .None;
|
||||||
internal ReflectKind mReflectUser = .None;
|
internal ReflectKind mReflectUser = .None;
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.All)]
|
[AttributeUsage(.All)]
|
||||||
public struct ReflectAttribute : Attribute
|
public struct ReflectAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(ReflectKind reflectKind = .All)
|
public this(ReflectKind reflectKind = .All)
|
||||||
|
@ -101,13 +102,13 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*1*/ | .Invocation | .Property)]
|
[AttributeUsage(.Method /*1*/ | .Invocation | .Property)]
|
||||||
public struct InlineAttribute : Attribute
|
public struct InlineAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Invocation)]
|
[AttributeUsage(.Invocation)]
|
||||||
public struct UnboundAttribute : Attribute
|
public struct UnboundAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -125,13 +126,13 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.MemberAccess)]
|
[AttributeUsage(.MemberAccess)]
|
||||||
public struct FriendAttribute : Attribute
|
public struct FriendAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.MemberAccess)]
|
[AttributeUsage(.MemberAccess)]
|
||||||
public struct SkipAccessCheckAttribute : Attribute
|
public struct SkipAccessCheckAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -143,13 +144,13 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/ | AttributeTargets.StaticField)]
|
[AttributeUsage(.Method /*2*/ | .StaticField)]
|
||||||
public struct CLinkAttribute : Attribute
|
public struct CLinkAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/ | AttributeTargets.StaticField)]
|
[AttributeUsage(.Method /*2*/ | .StaticField)]
|
||||||
public struct LinkNameAttribute : Attribute
|
public struct LinkNameAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(String linkName)
|
public this(String linkName)
|
||||||
|
@ -158,31 +159,31 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method | .Delegate | .Function)]
|
[AttributeUsage(.Method | .Delegate | .Function)]
|
||||||
public struct StdCallAttribute : Attribute
|
public struct StdCallAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct CVarArgsAttribute : Attribute
|
public struct CVarArgsAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct NoReturnAttribute : Attribute
|
public struct NoReturnAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct SkipCallAttribute : Attribute
|
public struct SkipCallAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct IntrinsicAttribute : Attribute
|
public struct IntrinsicAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(String intrinName)
|
public this(String intrinName)
|
||||||
|
@ -191,7 +192,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct /*2*/)]
|
[AttributeUsage(.Class | .Struct /*2*/)]
|
||||||
public struct StaticInitPriorityAttribute : Attribute
|
public struct StaticInitPriorityAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(int priority)
|
public this(int priority)
|
||||||
|
@ -200,7 +201,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class /*2*/ | AttributeTargets.Struct /*2*/)]
|
[AttributeUsage(.Class /*2*/ | .Struct /*2*/)]
|
||||||
public struct StaticInitAfterAttribute : Attribute
|
public struct StaticInitAfterAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this()
|
public this()
|
||||||
|
@ -214,50 +215,59 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
[AttributeUsage(.Struct)]
|
||||||
public struct ForceAddrAttribute : Attribute
|
public struct ForceAddrAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This attribute is required on constructors that include 'append' allocations.
|
/// This attribute is required on constructors that include 'append' allocations.
|
||||||
[AttributeUsage(AttributeTargets.Constructor)]
|
[AttributeUsage(.Constructor)]
|
||||||
public struct AllowAppendAttribute : Attribute
|
public struct AllowAppendAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct PackedAttribute : Attribute
|
public struct PackedAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct | .Alloc)]
|
||||||
|
public struct AlignAttribute : Attribute
|
||||||
|
{
|
||||||
|
public this(int align)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct UnionAttribute : Attribute
|
public struct UnionAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct CReprAttribute : Attribute
|
public struct CReprAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct OrderedAttribute : Attribute
|
public struct OrderedAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field | .Method /*2*/)]
|
[AttributeUsage(.Field | .Method /*2*/)]
|
||||||
public struct NoShowAttribute : Attribute
|
public struct NoShowAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field | .Method /*2*/)]
|
[AttributeUsage(.Field | .Method /*2*/)]
|
||||||
public struct HideAttribute : Attribute
|
public struct HideAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -269,7 +279,7 @@ namespace System
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method/*, AlwaysIncludeTarget=true*/)]
|
[AttributeUsage(.Method/*, AlwaysIncludeTarget=true*/)]
|
||||||
public struct TestAttribute : Attribute
|
public struct TestAttribute : Attribute
|
||||||
{
|
{
|
||||||
public bool ShouldFail;
|
public bool ShouldFail;
|
||||||
|
@ -289,7 +299,7 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.StaticField | AttributeTargets.Field, .NotInherited)]
|
[AttributeUsage(.StaticField | .Field, .NotInherited)]
|
||||||
public struct ThreadStaticAttribute : Attribute
|
public struct ThreadStaticAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this()
|
public this()
|
||||||
|
@ -321,7 +331,7 @@ namespace System
|
||||||
|
|
||||||
/// Generally used as a per-method optimization, [DisableObjectAccessChecks] will avoid the runtime per-object-access
|
/// Generally used as a per-method optimization, [DisableObjectAccessChecks] will avoid the runtime per-object-access
|
||||||
/// checks which by default are only applied in debug builds anyway.
|
/// checks which by default are only applied in debug builds anyway.
|
||||||
[AttributeUsage(AttributeTargets.Method/*, AlwaysIncludeTarget=true*/)]
|
[AttributeUsage(.Method/*, AlwaysIncludeTarget=true*/)]
|
||||||
public struct DisableObjectAccessChecksAttribute : Attribute
|
public struct DisableObjectAccessChecksAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace System
|
||||||
GenericParameter = 0x8000,
|
GenericParameter = 0x8000,
|
||||||
Invocation = 0x10000,
|
Invocation = 0x10000,
|
||||||
MemberAccess = 0x20000,
|
MemberAccess = 0x20000,
|
||||||
|
Alloc = 0x40000,
|
||||||
|
|
||||||
All = Assembly | Module | Class | Struct | Enum | Constructor |
|
All = Assembly | Module | Class | Struct | Enum | Constructor |
|
||||||
Method | Property | Field | StaticField | Interface | Parameter |
|
Method | Property | Field | StaticField | Interface | Parameter |
|
||||||
|
@ -93,7 +94,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.All)]
|
[AttributeUsage(.All)]
|
||||||
public struct ReflectAttribute : Attribute
|
public struct ReflectAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(ReflectKind reflectKind = .All)
|
public this(ReflectKind reflectKind = .All)
|
||||||
|
@ -101,13 +102,13 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*1*/ | .Invocation | .Property)]
|
[AttributeUsage(.Method /*1*/ | .Invocation | .Property)]
|
||||||
public struct InlineAttribute : Attribute
|
public struct InlineAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Invocation)]
|
[AttributeUsage(.Invocation)]
|
||||||
public struct UnboundAttribute : Attribute
|
public struct UnboundAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -125,13 +126,13 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.MemberAccess)]
|
[AttributeUsage(.MemberAccess)]
|
||||||
public struct FriendAttribute : Attribute
|
public struct FriendAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.MemberAccess)]
|
[AttributeUsage(.MemberAccess)]
|
||||||
public struct SkipAccessCheckAttribute : Attribute
|
public struct SkipAccessCheckAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -143,13 +144,13 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/ | AttributeTargets.StaticField)]
|
[AttributeUsage(.Method /*2*/ | .StaticField)]
|
||||||
public struct CLinkAttribute : Attribute
|
public struct CLinkAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/ | AttributeTargets.StaticField)]
|
[AttributeUsage(.Method /*2*/ | .StaticField)]
|
||||||
public struct LinkNameAttribute : Attribute
|
public struct LinkNameAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(String linkName)
|
public this(String linkName)
|
||||||
|
@ -158,31 +159,31 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method | .Delegate | .Function)]
|
[AttributeUsage(.Method | .Delegate | .Function)]
|
||||||
public struct StdCallAttribute : Attribute
|
public struct StdCallAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct CVarArgsAttribute : Attribute
|
public struct CVarArgsAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct NoReturnAttribute : Attribute
|
public struct NoReturnAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct SkipCallAttribute : Attribute
|
public struct SkipCallAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method /*2*/)]
|
[AttributeUsage(.Method /*2*/)]
|
||||||
public struct IntrinsicAttribute : Attribute
|
public struct IntrinsicAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(String intrinName)
|
public this(String intrinName)
|
||||||
|
@ -206,7 +207,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct /*2*/)]
|
[AttributeUsage(.Class | .Struct /*2*/)]
|
||||||
public struct StaticInitPriorityAttribute : Attribute
|
public struct StaticInitPriorityAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this(int priority)
|
public this(int priority)
|
||||||
|
@ -215,7 +216,7 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class /*2*/ | AttributeTargets.Struct /*2*/)]
|
[AttributeUsage(.Class /*2*/ | .Struct /*2*/)]
|
||||||
public struct StaticInitAfterAttribute : Attribute
|
public struct StaticInitAfterAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this()
|
public this()
|
||||||
|
@ -229,49 +230,58 @@ namespace System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
[AttributeUsage(.Struct)]
|
||||||
public struct ForceAddrAttribute : Attribute
|
public struct ForceAddrAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Constructor)]
|
[AttributeUsage(.Constructor)]
|
||||||
public struct AllowAppendAttribute : Attribute
|
public struct AllowAppendAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct PackedAttribute : Attribute
|
public struct PackedAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct | .Alloc)]
|
||||||
|
public struct AlignAttribute : Attribute
|
||||||
|
{
|
||||||
|
public this(int align)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct UnionAttribute : Attribute
|
public struct UnionAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct CReprAttribute : Attribute
|
public struct CReprAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
[AttributeUsage(.Class | .Struct)]
|
||||||
public struct OrderedAttribute : Attribute
|
public struct OrderedAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field | .Method /*2*/)]
|
[AttributeUsage(.Field | .Method /*2*/)]
|
||||||
public struct NoShowAttribute : Attribute
|
public struct NoShowAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field | .Method /*2*/)]
|
[AttributeUsage(.Field | .Method /*2*/)]
|
||||||
public struct HideAttribute : Attribute
|
public struct HideAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -283,7 +293,7 @@ namespace System
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method/*, AlwaysIncludeTarget=true*/)]
|
[AttributeUsage(.Method/*, AlwaysIncludeTarget=true*/)]
|
||||||
public struct TestAttribute : Attribute
|
public struct TestAttribute : Attribute
|
||||||
{
|
{
|
||||||
public bool ShouldFail;
|
public bool ShouldFail;
|
||||||
|
@ -303,7 +313,7 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.StaticField | AttributeTargets.Field, .NotInherited)]
|
[AttributeUsage(.StaticField | .Field, .NotInherited)]
|
||||||
public struct ThreadStaticAttribute : Attribute
|
public struct ThreadStaticAttribute : Attribute
|
||||||
{
|
{
|
||||||
public this()
|
public this()
|
||||||
|
@ -327,7 +337,7 @@ namespace System
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method/*, AlwaysIncludeTarget=true*/)]
|
[AttributeUsage(.Method/*, AlwaysIncludeTarget=true*/)]
|
||||||
public struct DisableObjectAccessChecksAttribute : Attribute
|
public struct DisableObjectAccessChecksAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace IDE
|
||||||
IDEUtils.FixFilePath(llvmDir);
|
IDEUtils.FixFilePath(llvmDir);
|
||||||
llvmDir.Append("llvm/");
|
llvmDir.Append("llvm/");
|
||||||
#else
|
#else
|
||||||
String llvmDir = "";
|
//String llvmDir = "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//String error = scope String();
|
//String error = scope String();
|
||||||
|
|
|
@ -1386,7 +1386,10 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
{
|
{
|
||||||
BF_ASSERT(!((BeStructType*)type)->mIsOpaque);
|
BF_ASSERT(!((BeStructType*)type)->mIsOpaque);
|
||||||
}
|
}
|
||||||
SetResult(curId, mBeModule->CreateAlloca(type));
|
|
||||||
|
auto allocaInst = mBeModule->CreateAlloca(type);
|
||||||
|
allocaInst->mAlign = type->mAlign;
|
||||||
|
SetResult(curId, allocaInst);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BfIRCmd_AllocaArray:
|
case BfIRCmd_AllocaArray:
|
||||||
|
@ -1396,6 +1399,7 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
|
|
||||||
auto allocaInst = mBeModule->AllocInst<BeAllocaInst>();
|
auto allocaInst = mBeModule->AllocInst<BeAllocaInst>();
|
||||||
allocaInst->mType = type;
|
allocaInst->mType = type;
|
||||||
|
allocaInst->mAlign = type->mAlign;
|
||||||
allocaInst->mArraySize = arraySize;
|
allocaInst->mArraySize = arraySize;
|
||||||
|
|
||||||
SetResult(curId, allocaInst);
|
SetResult(curId, allocaInst);
|
||||||
|
@ -1406,6 +1410,8 @@ void BeIRCodeGen::HandleNextCmd()
|
||||||
CMD_PARAM(BeValue*, val);
|
CMD_PARAM(BeValue*, val);
|
||||||
CMD_PARAM(int, alignment);
|
CMD_PARAM(int, alignment);
|
||||||
auto inst = BeValueDynCast<BeAllocaInst>(val);
|
auto inst = BeValueDynCast<BeAllocaInst>(val);
|
||||||
|
|
||||||
|
inst->mAlign = alignment;
|
||||||
//TODO: Implement
|
//TODO: Implement
|
||||||
/*inst->setAlignment(alignment);*/
|
/*inst->setAlignment(alignment);*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -2941,6 +2941,8 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp
|
||||||
|
|
||||||
SizedArray<_ShadowReg, 8> shadowRegs;
|
SizedArray<_ShadowReg, 8> shadowRegs;
|
||||||
|
|
||||||
|
BF_ASSERT(mMaxCallParamCount >= argCount);
|
||||||
|
|
||||||
mMaxCallParamCount = BF_MAX(mMaxCallParamCount, argCount);
|
mMaxCallParamCount = BF_MAX(mMaxCallParamCount, argCount);
|
||||||
for (int argIdx = args.size() - 1; argIdx >= 0; argIdx--)
|
for (int argIdx = args.size() - 1; argIdx >= 0; argIdx--)
|
||||||
{
|
{
|
||||||
|
@ -3651,6 +3653,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe
|
||||||
int vregIdx = (int)mVRegInfo.size();
|
int vregIdx = (int)mVRegInfo.size();
|
||||||
BeMCVRegInfo* vregInfo = mAlloc.Alloc<BeMCVRegInfo>();
|
BeMCVRegInfo* vregInfo = mAlloc.Alloc<BeMCVRegInfo>();
|
||||||
vregInfo->mType = type;
|
vregInfo->mType = type;
|
||||||
|
vregInfo->mAlign = type->mAlign;
|
||||||
vregInfo->mRefCount = refCount;
|
vregInfo->mRefCount = refCount;
|
||||||
vregInfo->mForceReg = mustBeReg;
|
vregInfo->mForceReg = mustBeReg;
|
||||||
mVRegInfo.push_back(vregInfo);
|
mVRegInfo.push_back(vregInfo);
|
||||||
|
@ -3661,7 +3664,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe
|
||||||
|
|
||||||
if (mDebugging)
|
if (mDebugging)
|
||||||
{
|
{
|
||||||
if (mcOperand.mVRegIdx == 31)
|
if (mcOperand.mVRegIdx == 3)
|
||||||
{
|
{
|
||||||
NOP;
|
NOP;
|
||||||
}
|
}
|
||||||
|
@ -7902,12 +7905,6 @@ void BeMCContext::DoFrameObjPass()
|
||||||
// we need for calls with more than 4 params.
|
// we need for calls with more than 4 params.
|
||||||
// If we're doing UseBP, we have to allocate these at call time
|
// If we're doing UseBP, we have to allocate these at call time
|
||||||
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
|
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
|
||||||
for (int homeVRegIdx : mDeferredHomeSizeOffsets)
|
|
||||||
{
|
|
||||||
auto vregInfo = mVRegInfo[homeVRegIdx];
|
|
||||||
BF_ASSERT(vregInfo->mRelOffset.mImmediate == -1);
|
|
||||||
vregInfo->mRelOffset.mImmediate = BF_ALIGN(homeSize, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
mStackSize = 0;
|
mStackSize = 0;
|
||||||
|
|
||||||
|
@ -7947,12 +7944,13 @@ void BeMCContext::DoFrameObjPass()
|
||||||
|
|
||||||
if ((vregInfo->mRefCount > 0) && (!vregInfo->mIsExpr) && (vregInfo->mReg == X64Reg_None) && (vregInfo->mFrameOffset == INT_MIN))
|
if ((vregInfo->mRefCount > 0) && (!vregInfo->mIsExpr) && (vregInfo->mReg == X64Reg_None) && (vregInfo->mFrameOffset == INT_MIN))
|
||||||
{
|
{
|
||||||
int align = BF_MAX(vregInfo->mType->mAlign, 1);
|
BF_ASSERT(vregInfo->mAlign != -1);
|
||||||
|
int align = BF_MAX(vregInfo->mAlign, 1);
|
||||||
int alignOffset = regStackOffset + 8;
|
int alignOffset = regStackOffset + 8;
|
||||||
int alignedPosition = (mStackSize + alignOffset + (align - 1)) & ~(align - 1);
|
int alignedPosition = (mStackSize + alignOffset + (align - 1)) & ~(align - 1);
|
||||||
mStackSize = alignedPosition - alignOffset;
|
mStackSize = alignedPosition - alignOffset;
|
||||||
//vregInfo->mFrameOffset = -mStackSize - regStackOffset - 8;
|
//vregInfo->mFrameOffset = -mStackSize - regStackOffset - 8;
|
||||||
mStackSize += BF_ALIGN(vregInfo->mType->mSize, vregInfo->mType->mAlign);
|
mStackSize += BF_ALIGN(vregInfo->mType->mSize, vregInfo->mAlign);
|
||||||
vregInfo->mFrameOffset = -mStackSize - regStackOffset;
|
vregInfo->mFrameOffset = -mStackSize - regStackOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8893,6 +8891,7 @@ bool BeMCContext::DoLegalization()
|
||||||
auto relVRegInfo = mVRegInfo[relVRegIdx];
|
auto relVRegInfo = mVRegInfo[relVRegIdx];
|
||||||
setInst->mKind = BeMCInstKind_MovSX;
|
setInst->mKind = BeMCInstKind_MovSX;
|
||||||
relVRegInfo->mType = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64);
|
relVRegInfo->mType = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64);
|
||||||
|
relVRegInfo->mAlign = relVRegInfo->mType->mAlign;
|
||||||
if (debugging)
|
if (debugging)
|
||||||
OutputDebugStrF(" Def MovSX\n");
|
OutputDebugStrF(" Def MovSX\n");
|
||||||
isFinalRun = false;
|
isFinalRun = false;
|
||||||
|
@ -14693,7 +14692,7 @@ String BeMCContext::ToString(bool showVRegFlags, bool showVRegDetails)
|
||||||
{
|
{
|
||||||
str += " ";
|
str += " ";
|
||||||
str += ToString(BeMCOperand::FromVReg(vregIdx));
|
str += ToString(BeMCOperand::FromVReg(vregIdx));
|
||||||
str += StrFormat(": size=%d, align=%d, at ", vregInfo->mType->mSize, vregInfo->mType->mAlign);
|
str += StrFormat(": size=%d, align=%d, at ", vregInfo->mType->mSize, vregInfo->mAlign);
|
||||||
|
|
||||||
X64CPURegister reg;
|
X64CPURegister reg;
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -14840,7 +14839,9 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
||||||
|
|
||||||
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
||||||
//mDebugging = function->mName == "?DoResolveConfigString@IDEApp@IDE@bf@@QEAA_NPEAVString@System@3@PEAVOptions@Workspace@23@PEAVProject@23@PEAVOptions@823@UStringView@53@00@Z";
|
mDebugging = function->mName ==
|
||||||
|
//"?TestPrimitives@Nullable@Tests@bf@@SAXXZ"
|
||||||
|
"?TestAlloc@Blurg@bf@@SAXXZ";
|
||||||
//"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z";
|
//"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z";
|
||||||
|
|
||||||
//"?Hey@Blurg@bf@@SAXXZ";
|
//"?Hey@Blurg@bf@@SAXXZ";
|
||||||
|
@ -14875,6 +14876,7 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
SizedArray<int, 64> stackSaveVRegs;
|
SizedArray<int, 64> stackSaveVRegs;
|
||||||
|
|
||||||
// Scan pass
|
// Scan pass
|
||||||
|
mMaxCallParamCount = 4;
|
||||||
for (int blockIdx = 0; blockIdx < (int)function->mBlocks.size(); blockIdx++)
|
for (int blockIdx = 0; blockIdx < (int)function->mBlocks.size(); blockIdx++)
|
||||||
{
|
{
|
||||||
auto beBlock = function->mBlocks[blockIdx];
|
auto beBlock = function->mBlocks[blockIdx];
|
||||||
|
@ -14889,7 +14891,8 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
{
|
{
|
||||||
case BeAllocaInst::TypeId:
|
case BeAllocaInst::TypeId:
|
||||||
{
|
{
|
||||||
if (!inHeadAlloca)
|
auto castedInst = (BeAllocaInst*)inst;
|
||||||
|
if ((!inHeadAlloca) || (castedInst->mAlign > 16))
|
||||||
mUseBP = true;
|
mUseBP = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -14902,6 +14905,12 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
stackSaveVRegs.push_back(stackVReg.mVRegIdx);
|
stackSaveVRegs.push_back(stackVReg.mVRegIdx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BeCallInst::TypeId:
|
||||||
|
{
|
||||||
|
auto castedInst = (BeCallInst*)inst;
|
||||||
|
mMaxCallParamCount = BF_MAX(mMaxCallParamCount, (int)castedInst->mArgs.size());
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
inHeadAlloca = false;
|
inHeadAlloca = false;
|
||||||
break;
|
break;
|
||||||
|
@ -15361,9 +15370,16 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
break;
|
break;
|
||||||
case BeAllocaInst::TypeId:
|
case BeAllocaInst::TypeId:
|
||||||
{
|
{
|
||||||
|
if (mDebugging)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
|
||||||
auto castedInst = (BeAllocaInst*)inst;
|
auto castedInst = (BeAllocaInst*)inst;
|
||||||
auto mcSize = BeMCOperand::FromImmediate(castedInst->mType->mSize);
|
auto mcSize = BeMCOperand::FromImmediate(castedInst->mType->mSize);
|
||||||
bool isAligned16 = false;
|
bool isAligned16 = false;
|
||||||
|
int align = castedInst->mAlign;
|
||||||
BeType* allocType = castedInst->mType;
|
BeType* allocType = castedInst->mType;
|
||||||
bool preservedVolatiles = false;
|
bool preservedVolatiles = false;
|
||||||
bool doPtrCast = false;
|
bool doPtrCast = false;
|
||||||
|
@ -15395,10 +15411,12 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inHeadAlloca)
|
// The stack is 16-byte aligned on entry - we have to manually adjust for any alignment greater than that
|
||||||
|
if ((inHeadAlloca) && (align <= 16))
|
||||||
{
|
{
|
||||||
result = AllocVirtualReg(allocType);
|
result = AllocVirtualReg(allocType);
|
||||||
auto vregInfo = mVRegInfo[result.mVRegIdx];
|
auto vregInfo = mVRegInfo[result.mVRegIdx];
|
||||||
|
vregInfo->mAlign = castedInst->mAlign;
|
||||||
vregInfo->mHasDynLife = true;
|
vregInfo->mHasDynLife = true;
|
||||||
if (castedInst->mForceMem)
|
if (castedInst->mForceMem)
|
||||||
vregInfo->mForceMem = true;
|
vregInfo->mForceMem = true;
|
||||||
|
@ -15416,6 +15434,7 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
vregInfo->mIsExpr = true;
|
vregInfo->mIsExpr = true;
|
||||||
vregInfo->mRelTo = result;
|
vregInfo->mRelTo = result;
|
||||||
vregInfo->mType = resultType;
|
vregInfo->mType = resultType;
|
||||||
|
vregInfo->mAlign = resultType->mSize;
|
||||||
CreateDefineVReg(ptrResult);
|
CreateDefineVReg(ptrResult);
|
||||||
|
|
||||||
result = ptrResult;
|
result = ptrResult;
|
||||||
|
@ -15438,6 +15457,8 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stackAlign = BF_MAX(align, 16);
|
||||||
|
|
||||||
BeMCOperand mcFunc;
|
BeMCOperand mcFunc;
|
||||||
mcFunc.mKind = BeMCOperandKind_SymbolAddr;
|
mcFunc.mKind = BeMCOperandKind_SymbolAddr;
|
||||||
mcFunc.mSymbolIdx = mCOFFObject->GetSymbolRef("__chkstk")->mIdx;
|
mcFunc.mSymbolIdx = mCOFFObject->GetSymbolRef("__chkstk")->mIdx;
|
||||||
|
@ -15494,7 +15515,6 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromReg(X64Reg_RAX));
|
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromReg(X64Reg_RAX));
|
||||||
|
|
||||||
if (doFastChkStk)
|
if (doFastChkStk)
|
||||||
{
|
{
|
||||||
AllocInst(BeMCInstKind_FastCheckStack, BeMCOperand::FromReg(X64Reg_RSP));
|
AllocInst(BeMCInstKind_FastCheckStack, BeMCOperand::FromReg(X64Reg_RSP));
|
||||||
|
@ -15514,8 +15534,7 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
auto vregInfo = mVRegInfo[ptrValue.mVRegIdx];
|
auto vregInfo = mVRegInfo[ptrValue.mVRegIdx];
|
||||||
vregInfo->mIsExpr = true;
|
vregInfo->mIsExpr = true;
|
||||||
vregInfo->mRelTo = BeMCOperand::FromReg(X64Reg_RSP);
|
vregInfo->mRelTo = BeMCOperand::FromReg(X64Reg_RSP);
|
||||||
vregInfo->mRelOffset = BeMCOperand::FromImmediate(-1);
|
vregInfo->mRelOffset = BeMCOperand::FromImmediate(homeSize);
|
||||||
mDeferredHomeSizeOffsets.Add(ptrValue.mVRegIdx);
|
|
||||||
CreateDefineVReg(ptrValue);
|
CreateDefineVReg(ptrValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -15530,6 +15549,14 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
|
|
||||||
AllocInst(BeMCInstKind_Mov, result, ptrValue);
|
AllocInst(BeMCInstKind_Mov, result, ptrValue);
|
||||||
|
|
||||||
|
if (stackAlign > 16)
|
||||||
|
{
|
||||||
|
// We have to align after everything - note that we always have to keep the 'homeSize' space available from RSP for calls,
|
||||||
|
// so the ANDing for alignment must be done here
|
||||||
|
AllocInst(BeMCInstKind_And, result, BeMCOperand::FromImmediate(~(stackAlign - 1)));
|
||||||
|
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromImmediate(stackAlign - 16));
|
||||||
|
}
|
||||||
|
|
||||||
BF_ASSERT(mUseBP);
|
BF_ASSERT(mUseBP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16037,6 +16064,7 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
auto vregInfo = GetVRegInfo(castedTarget);
|
auto vregInfo = GetVRegInfo(castedTarget);
|
||||||
vregInfo->mMustExist = true;
|
vregInfo->mMustExist = true;
|
||||||
vregInfo->mType = valType;
|
vregInfo->mType = valType;
|
||||||
|
vregInfo->mAlign = valType->mAlign;
|
||||||
vregInfo->mIsExpr = true;
|
vregInfo->mIsExpr = true;
|
||||||
vregInfo->mRelTo = mcTarget;
|
vregInfo->mRelTo = mcTarget;
|
||||||
CreateDefineVReg(castedTarget);
|
CreateDefineVReg(castedTarget);
|
||||||
|
|
|
@ -715,6 +715,7 @@ public:
|
||||||
X64CPURegister mReg;
|
X64CPURegister mReg;
|
||||||
X64CPURegister mNaturalReg; // From param
|
X64CPURegister mNaturalReg; // From param
|
||||||
BeType* mType;
|
BeType* mType;
|
||||||
|
int mAlign;
|
||||||
int mFrameOffset; // 0 = 'RBP' (probably first local var or saved RBP), 8 means retAddr
|
int mFrameOffset; // 0 = 'RBP' (probably first local var or saved RBP), 8 means retAddr
|
||||||
bool mRegNumPinned;
|
bool mRegNumPinned;
|
||||||
bool mHasDynLife;
|
bool mHasDynLife;
|
||||||
|
@ -756,6 +757,7 @@ public:
|
||||||
public:
|
public:
|
||||||
BeMCVRegInfo()
|
BeMCVRegInfo()
|
||||||
{
|
{
|
||||||
|
mAlign = -1;
|
||||||
mRegNumPinned = false;
|
mRegNumPinned = false;
|
||||||
mReg = X64Reg_None;
|
mReg = X64Reg_None;
|
||||||
mNaturalReg = X64Reg_None;
|
mNaturalReg = X64Reg_None;
|
||||||
|
@ -1257,7 +1259,6 @@ public:
|
||||||
BeVTrackingList* mCurVRegsLive;
|
BeVTrackingList* mCurVRegsLive;
|
||||||
Array<int> mTextRelocs;
|
Array<int> mTextRelocs;
|
||||||
Array<BeMCSwitchEntry> mSwitchEntries;
|
Array<BeMCSwitchEntry> mSwitchEntries;
|
||||||
Array<int> mDeferredHomeSizeOffsets;
|
|
||||||
|
|
||||||
Dictionary<int, X64CPURegister> mDbgPreferredRegs;
|
Dictionary<int, X64CPURegister> mDbgPreferredRegs;
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,9 @@ void BeInliner::Visit(BeAllocaInst* allocaInst)
|
||||||
auto destAllocInst = AllocInst(allocaInst);
|
auto destAllocInst = AllocInst(allocaInst);
|
||||||
destAllocInst->mType = allocaInst->mType;
|
destAllocInst->mType = allocaInst->mType;
|
||||||
destAllocInst->mArraySize = Remap(allocaInst->mArraySize);
|
destAllocInst->mArraySize = Remap(allocaInst->mArraySize);
|
||||||
|
destAllocInst->mAlign = allocaInst->mAlign;
|
||||||
|
destAllocInst->mNoChkStk = allocaInst->mNoChkStk;
|
||||||
|
destAllocInst->mForceMem = allocaInst->mForceMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BeInliner::Visit(BeAliasValueInst* aliasValueInst)
|
void BeInliner::Visit(BeAliasValueInst* aliasValueInst)
|
||||||
|
@ -1525,7 +1528,9 @@ String BeDumpContext::ToString(BeDbgFunction* dbgFunction)
|
||||||
|
|
||||||
void BeDumpContext::ToString(StringImpl& str, int val)
|
void BeDumpContext::ToString(StringImpl& str, int val)
|
||||||
{
|
{
|
||||||
str += StrFormat("%d", val);
|
char iStr[32];
|
||||||
|
sprintf(iStr, "%d", val);
|
||||||
|
str += iStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
String BeDumpContext::ToString(int val)
|
String BeDumpContext::ToString(int val)
|
||||||
|
@ -2146,6 +2151,8 @@ String BeModule::ToString(BeFunction* wantFunc)
|
||||||
str += ", ";
|
str += ", ";
|
||||||
dc.ToString(str, castedInst->mArraySize);
|
dc.ToString(str, castedInst->mArraySize);
|
||||||
}
|
}
|
||||||
|
str += ", align ";
|
||||||
|
dc.ToString(str, castedInst->mAlign);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
DISPLAY_INST1(BeAliasValueInst, "aliasvalue", mPtr);
|
DISPLAY_INST1(BeAliasValueInst, "aliasvalue", mPtr);
|
||||||
|
@ -2672,6 +2679,9 @@ void BeModule::DoInlining(BeFunction* func)
|
||||||
auto destAlloca = mAlloc.Alloc<BeAllocaInst>();
|
auto destAlloca = mAlloc.Alloc<BeAllocaInst>();
|
||||||
destAlloca->mType = allocaInst->mType;
|
destAlloca->mType = allocaInst->mType;
|
||||||
destAlloca->mArraySize = allocaInst->mArraySize;
|
destAlloca->mArraySize = allocaInst->mArraySize;
|
||||||
|
destAlloca->mAlign = allocaInst->mAlign;
|
||||||
|
destAlloca->mNoChkStk = allocaInst->mNoChkStk;
|
||||||
|
destAlloca->mForceMem = allocaInst->mForceMem;
|
||||||
destAlloca->mName = allocaInst->mName;
|
destAlloca->mName = allocaInst->mName;
|
||||||
|
|
||||||
auto destBlock = func->mBlocks[0];
|
auto destBlock = func->mBlocks[0];
|
||||||
|
|
|
@ -811,6 +811,7 @@ public:
|
||||||
|
|
||||||
BeType* mType;
|
BeType* mType;
|
||||||
BeValue* mArraySize;
|
BeValue* mArraySize;
|
||||||
|
int mAlign;
|
||||||
bool mNoChkStk;
|
bool mNoChkStk;
|
||||||
bool mForceMem;
|
bool mForceMem;
|
||||||
|
|
||||||
|
@ -823,6 +824,7 @@ public:
|
||||||
mType->HashReference(hashCtx);
|
mType->HashReference(hashCtx);
|
||||||
if (mArraySize != NULL)
|
if (mArraySize != NULL)
|
||||||
mArraySize->HashReference(hashCtx);
|
mArraySize->HashReference(hashCtx);
|
||||||
|
hashCtx.Mixin(mAlign);
|
||||||
hashCtx.Mixin(mNoChkStk);
|
hashCtx.Mixin(mNoChkStk);
|
||||||
hashCtx.Mixin(mForceMem);
|
hashCtx.Mixin(mForceMem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -956,6 +956,15 @@ void BfAstNode::ToString(StringImpl& str)
|
||||||
str.Append(source->mSrc + GetSrcStart(), srcLen);
|
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)
|
void BfBlock::Init(const SizedArrayImpl<BfAstNode*>& vec, BfAstAllocator* alloc)
|
||||||
|
|
|
@ -1022,6 +1022,7 @@ public:
|
||||||
String ToString();
|
String ToString();
|
||||||
StringView ToStringView();
|
StringView ToStringView();
|
||||||
void ToString(StringImpl& str);
|
void ToString(StringImpl& str);
|
||||||
|
bool Equals(const StringImpl& str);
|
||||||
void Init(BfParser* bfParser);
|
void Init(BfParser* bfParser);
|
||||||
void Accept(BfStructuralVisitor* bfVisitor);
|
void Accept(BfStructuralVisitor* bfVisitor);
|
||||||
static void ClassAccept(BfAstNode* node, BfStructuralVisitor* bfVisitor) { bfVisitor->Visit(node); }
|
static void ClassAccept(BfAstNode* node, BfStructuralVisitor* bfVisitor) { bfVisitor->Visit(node); }
|
||||||
|
@ -1733,6 +1734,7 @@ public:
|
||||||
BfTokenNode* mScopeToken;
|
BfTokenNode* mScopeToken;
|
||||||
BfTokenNode* mColonToken;
|
BfTokenNode* mColonToken;
|
||||||
BfAstNode* mTargetNode; // . : or identifier
|
BfAstNode* mTargetNode; // . : or identifier
|
||||||
|
BfAttributeDirective* mAttributes;
|
||||||
}; BF_AST_DECL(BfScopeNode, BfAstNode);
|
}; BF_AST_DECL(BfScopeNode, BfAstNode);
|
||||||
|
|
||||||
class BfNewNode : public BfAstNode
|
class BfNewNode : public BfAstNode
|
||||||
|
@ -1743,6 +1745,7 @@ public:
|
||||||
BfTokenNode* mNewToken;
|
BfTokenNode* mNewToken;
|
||||||
BfTokenNode* mColonToken;
|
BfTokenNode* mColonToken;
|
||||||
BfAstNode* mAllocNode; // Expression or BfScopedInvocationTarget
|
BfAstNode* mAllocNode; // Expression or BfScopedInvocationTarget
|
||||||
|
BfAttributeDirective* mAttributes;
|
||||||
}; BF_AST_DECL(BfNewNode, BfAstNode);
|
}; BF_AST_DECL(BfNewNode, BfAstNode);
|
||||||
|
|
||||||
enum BfCommentKind
|
enum BfCommentKind
|
||||||
|
@ -1849,7 +1852,7 @@ public:
|
||||||
|
|
||||||
ASTREF(BfTokenNode*) mAttrOpenToken; // [ @ ,
|
ASTREF(BfTokenNode*) mAttrOpenToken; // [ @ ,
|
||||||
ASTREF(BfTokenNode*) mAttrCloseToken;
|
ASTREF(BfTokenNode*) mAttrCloseToken;
|
||||||
ASTREF(BfAttributeTargetSpecifier*) mAttributeTargetSpecifier;
|
ASTREF(BfAstNode*) mAttributeTargetSpecifier;
|
||||||
|
|
||||||
ASTREF(BfTypeReference*) mAttributeTypeRef;
|
ASTREF(BfTypeReference*) mAttributeTypeRef;
|
||||||
ASTREF(BfTokenNode*) mCtorOpenParen;
|
ASTREF(BfTokenNode*) mCtorOpenParen;
|
||||||
|
@ -2534,23 +2537,12 @@ public:
|
||||||
BfGenericArgumentsNode* mGenericArgs;
|
BfGenericArgumentsNode* mGenericArgs;
|
||||||
}; BF_AST_DECL(BfDelegateBindExpression, BfMethodBoundExpression);
|
}; 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
|
class BfLambdaBindExpression : public BfExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BF_AST_TYPE(BfLambdaBindExpression, BfExpression);
|
BF_AST_TYPE(BfLambdaBindExpression, BfExpression);
|
||||||
|
|
||||||
BfAstNode* mNewToken;
|
BfAstNode* mNewToken;
|
||||||
BfLambdaCapture* mLambdaCapture;
|
|
||||||
BfTokenNode* mOpenParen;
|
BfTokenNode* mOpenParen;
|
||||||
BfTokenNode* mCloseParen;
|
BfTokenNode* mCloseParen;
|
||||||
BfSizedArray<ASTREF(BfIdentifierNode*)> mParams;
|
BfSizedArray<ASTREF(BfIdentifierNode*)> mParams;
|
||||||
|
|
|
@ -380,6 +380,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mClassVDataTypeDef = NULL;
|
mClassVDataTypeDef = NULL;
|
||||||
mCLinkAttributeTypeDef = NULL;
|
mCLinkAttributeTypeDef = NULL;
|
||||||
mCReprAttributeTypeDef = NULL;
|
mCReprAttributeTypeDef = NULL;
|
||||||
|
mAlignAttributeTypeDef = NULL;
|
||||||
mNoDiscardAttributeTypeDef = NULL;
|
mNoDiscardAttributeTypeDef = NULL;
|
||||||
mDisableObjectAccessChecksAttributeTypeDef = NULL;
|
mDisableObjectAccessChecksAttributeTypeDef = NULL;
|
||||||
mDbgRawAllocDataTypeDef = NULL;
|
mDbgRawAllocDataTypeDef = NULL;
|
||||||
|
@ -5832,6 +5833,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
||||||
mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
|
mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
|
||||||
mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
|
mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
|
||||||
|
mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
|
||||||
mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");
|
mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");
|
||||||
mDisableObjectAccessChecksAttributeTypeDef = _GetRequiredType("System.DisableObjectAccessChecksAttribute");
|
mDisableObjectAccessChecksAttributeTypeDef = _GetRequiredType("System.DisableObjectAccessChecksAttribute");
|
||||||
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
|
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
|
||||||
|
|
|
@ -378,6 +378,7 @@ public:
|
||||||
BfTypeDef* mInlineAttributeTypeDef;
|
BfTypeDef* mInlineAttributeTypeDef;
|
||||||
BfTypeDef* mCLinkAttributeTypeDef;
|
BfTypeDef* mCLinkAttributeTypeDef;
|
||||||
BfTypeDef* mCReprAttributeTypeDef;
|
BfTypeDef* mCReprAttributeTypeDef;
|
||||||
|
BfTypeDef* mAlignAttributeTypeDef;
|
||||||
BfTypeDef* mNoDiscardAttributeTypeDef;
|
BfTypeDef* mNoDiscardAttributeTypeDef;
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
|
|
|
@ -143,7 +143,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
||||||
isConst = false;
|
isConst = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isConst)
|
if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
|
||||||
{
|
{
|
||||||
mModule->Fail("Expression does not evaluate to a constant value", expr);
|
mModule->Fail("Expression does not evaluate to a constant value", expr);
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ void BfElementVisitor::Visit(BfScopeNode* scopeNode)
|
||||||
VisitChild(scopeNode->mScopeToken);
|
VisitChild(scopeNode->mScopeToken);
|
||||||
VisitChild(scopeNode->mColonToken);
|
VisitChild(scopeNode->mColonToken);
|
||||||
VisitChild(scopeNode->mTargetNode);
|
VisitChild(scopeNode->mTargetNode);
|
||||||
|
VisitChild(scopeNode->mAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfNewNode* newNode)
|
void BfElementVisitor::Visit(BfNewNode* newNode)
|
||||||
|
@ -141,6 +142,7 @@ void BfElementVisitor::Visit(BfNewNode* newNode)
|
||||||
VisitChild(newNode->mNewToken);
|
VisitChild(newNode->mNewToken);
|
||||||
VisitChild(newNode->mColonToken);
|
VisitChild(newNode->mColonToken);
|
||||||
VisitChild(newNode->mAllocNode);
|
VisitChild(newNode->mAllocNode);
|
||||||
|
VisitChild(newNode->mAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfLabeledBlock* labeledBlock)
|
void BfElementVisitor::Visit(BfLabeledBlock* labeledBlock)
|
||||||
|
@ -532,12 +534,6 @@ void BfElementVisitor::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
||||||
Visit(lambdaBindExpr->ToBase());
|
Visit(lambdaBindExpr->ToBase());
|
||||||
|
|
||||||
VisitChild(lambdaBindExpr->mNewToken);
|
VisitChild(lambdaBindExpr->mNewToken);
|
||||||
if (lambdaBindExpr->mLambdaCapture != NULL)
|
|
||||||
{
|
|
||||||
VisitChild(lambdaBindExpr->mLambdaCapture->mOpenBracket);
|
|
||||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCaptureToken);
|
|
||||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCloseBracket);
|
|
||||||
}
|
|
||||||
|
|
||||||
VisitChild(lambdaBindExpr->mOpenParen);
|
VisitChild(lambdaBindExpr->mOpenParen);
|
||||||
VisitChild(lambdaBindExpr->mCloseParen);
|
VisitChild(lambdaBindExpr->mCloseParen);
|
||||||
|
|
|
@ -2818,6 +2818,11 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
||||||
varSkipCount--;
|
varSkipCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (varDecl->mNotCaptured)
|
||||||
|
{
|
||||||
|
mModule->Fail("Local variable is not captured", refNode);
|
||||||
|
}
|
||||||
|
|
||||||
if ((varSkipCount == 0) && (varDecl != NULL))
|
if ((varSkipCount == 0) && (varDecl != NULL))
|
||||||
{
|
{
|
||||||
if ((closureTypeInst != NULL) && (wantName == "this"))
|
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();
|
auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
|
||||||
BfLambdaInstance* lambdaInstance = NULL;
|
BfLambdaInstance* lambdaInstance = NULL;
|
||||||
|
@ -9527,8 +9532,11 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
return NULL;
|
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)
|
if (lambdaBindExpr->mDtor != NULL)
|
||||||
{
|
{
|
||||||
mModule->Fail("Valueless method reference cannot contain destructor. Consider either removing destructor or using an allocated lambda.", lambdaBindExpr->mDtor->mTildeToken);
|
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;
|
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();
|
BfClosureInstanceInfo* closureInstanceInfo = new BfClosureInstanceInfo();
|
||||||
|
|
||||||
auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
||||||
|
@ -9704,6 +9795,9 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
|
|
||||||
VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor);
|
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 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))
|
if ((methodState.mPrevMethodState->mClosureState != NULL) && (methodState.mPrevMethodState->mClosureState->mCapturing))
|
||||||
{
|
{
|
||||||
|
@ -9731,18 +9825,27 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
prevIgnoreWrites.Restore();
|
prevIgnoreWrites.Restore();
|
||||||
mModule->mBfIRBuilder->RestoreDebugLocation();
|
mModule->mBfIRBuilder->RestoreDebugLocation();
|
||||||
|
|
||||||
BfCaptureType captureType = BfCaptureType_Value;
|
auto _GetCaptureType = [&](const StringImpl& str)
|
||||||
if ((lambdaBindExpr->mLambdaCapture != NULL) && (lambdaBindExpr->mLambdaCapture->mCaptureToken != NULL))
|
|
||||||
{
|
{
|
||||||
if (lambdaBindExpr->mLambdaCapture->mCaptureToken->GetToken() == BfToken_Ampersand)
|
if (allocTarget.mCaptureInfo.mCaptures.IsEmpty())
|
||||||
captureType = BfCaptureType_Reference;
|
return BfCaptureType_Copy;
|
||||||
else
|
|
||||||
captureType = 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;
|
Array<BfClosureCapturedEntry> capturedEntries;
|
||||||
|
|
||||||
bool copyOuterCaptures = false;
|
bool copyOuterCaptures = false;
|
||||||
|
//
|
||||||
{
|
{
|
||||||
auto varMethodState = methodState.mPrevMethodState;
|
auto varMethodState = methodState.mPrevMethodState;
|
||||||
|
|
||||||
|
@ -9771,6 +9874,11 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
auto capturedType = outerLocal->mResolvedType;
|
auto capturedType = outerLocal->mResolvedType;
|
||||||
bool captureByRef = false;
|
bool captureByRef = false;
|
||||||
|
|
||||||
|
auto captureType = _GetCaptureType(localVar->mName);
|
||||||
|
if (captureType == BfCaptureType_None)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!capturedType->IsRef())
|
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)
|
for (auto copyField : closureState.mReferencedOuterClosureMembers)
|
||||||
{
|
{
|
||||||
auto fieldDef = copyField->GetFieldDef();
|
auto fieldDef = copyField->GetFieldDef();
|
||||||
|
auto captureType = _GetCaptureType(fieldDef->mName);
|
||||||
|
|
||||||
BfClosureCapturedEntry capturedEntry;
|
BfClosureCapturedEntry capturedEntry;
|
||||||
capturedEntry.mName = fieldDef->mName;
|
capturedEntry.mName = fieldDef->mName;
|
||||||
capturedEntry.mType = copyField->mResolvedType;
|
capturedEntry.mType = copyField->mResolvedType;
|
||||||
|
@ -10200,7 +10316,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr);
|
BfLambdaInstance* lambdaInstance = GetLambdaInstance(lambdaBindExpr, allocTarget);
|
||||||
if (lambdaInstance == NULL)
|
if (lambdaInstance == NULL)
|
||||||
return;
|
return;
|
||||||
BfTypeInstance* delegateTypeInstance = lambdaInstance->mDelegateTypeInstance;
|
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);
|
arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, false), ptrType);
|
||||||
else
|
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);
|
_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);
|
arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
|
||||||
else
|
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)
|
if (isScopeAlloc)
|
||||||
{
|
{
|
||||||
|
@ -11538,6 +11654,7 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
|
||||||
BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenNode*& newToken)
|
BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenNode*& newToken)
|
||||||
{
|
{
|
||||||
auto autoComplete = GetAutoComplete();
|
auto autoComplete = GetAutoComplete();
|
||||||
|
BfAttributeDirective* attributeDirective = NULL;
|
||||||
|
|
||||||
BfAllocTarget allocTarget;
|
BfAllocTarget allocTarget;
|
||||||
allocTarget.mRefNode = allocNode;
|
allocTarget.mRefNode = allocNode;
|
||||||
|
@ -11555,6 +11672,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
||||||
if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
|
if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
|
||||||
autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken);
|
autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken);
|
||||||
}
|
}
|
||||||
|
attributeDirective = scopeNode->mAttributes;
|
||||||
}
|
}
|
||||||
if (auto newNode = BfNodeDynCast<BfNewNode>(allocNode))
|
if (auto newNode = BfNodeDynCast<BfNewNode>(allocNode))
|
||||||
{
|
{
|
||||||
|
@ -11568,6 +11686,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
||||||
{
|
{
|
||||||
allocTarget.mScopedInvocationTarget = scopedInvocationTarget;
|
allocTarget.mScopedInvocationTarget = scopedInvocationTarget;
|
||||||
}
|
}
|
||||||
|
attributeDirective = newNode->mAttributes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (newToken->GetToken() == BfToken_Scope)
|
else if (newToken->GetToken() == BfToken_Scope)
|
||||||
|
@ -11580,6 +11699,38 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
||||||
if (mModule->mCurMethodState != NULL)
|
if (mModule->mCurMethodState != NULL)
|
||||||
allocTarget.mScopeData = &mModule->mCurMethodState->mHeadScope;
|
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;
|
return allocTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -378,7 +378,7 @@ public:
|
||||||
BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType);
|
BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType);
|
||||||
void ConstResolve(BfExpression* expr);
|
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);
|
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 VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor);
|
||||||
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
||||||
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken);
|
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken);
|
||||||
|
|
|
@ -7521,7 +7521,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
}
|
}
|
||||||
if (!isDynAlloc)
|
if (!isDynAlloc)
|
||||||
mBfIRBuilder->ClearDebugLocation(allocaInst);
|
mBfIRBuilder->ClearDebugLocation(allocaInst);
|
||||||
mBfIRBuilder->SetAllocaAlignment(allocaInst, type->mAlign);
|
mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign);
|
||||||
if (!isDynAlloc)
|
if (!isDynAlloc)
|
||||||
mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
||||||
auto typedVal = BfTypedValue(result, type, BfTypedValueKind_Addr);
|
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);
|
auto allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(byteType), sizeValue);
|
||||||
if (!isDynAlloc)
|
if (!isDynAlloc)
|
||||||
mBfIRBuilder->ClearDebugLocation(allocaInst);
|
mBfIRBuilder->ClearDebugLocation(allocaInst);
|
||||||
mBfIRBuilder->SetAllocaAlignment(allocaInst, arrayType->mAlign);
|
mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign);
|
||||||
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(arrayType)), arrayType);
|
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(arrayType)), arrayType);
|
||||||
mBfIRBuilder->ClearDebugLocation_Last();
|
mBfIRBuilder->ClearDebugLocation_Last();
|
||||||
if (!isDynAlloc)
|
if (!isDynAlloc)
|
||||||
|
@ -9214,6 +9214,7 @@ static String GetAttributesTargetListString(BfAttributeTargets attrTarget)
|
||||||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_GenericParameter, resultStr, "generic parameters");
|
AddAttributeTargetName(flagsLeft, BfAttributeTargets_GenericParameter, resultStr, "generic parameters");
|
||||||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_Invocation, resultStr, "invocations");
|
AddAttributeTargetName(flagsLeft, BfAttributeTargets_Invocation, resultStr, "invocations");
|
||||||
AddAttributeTargetName(flagsLeft, BfAttributeTargets_MemberAccess, resultStr, "member access");
|
AddAttributeTargetName(flagsLeft, BfAttributeTargets_MemberAccess, resultStr, "member access");
|
||||||
|
AddAttributeTargetName(flagsLeft, BfAttributeTargets_Alloc, resultStr, "allocations");
|
||||||
if (resultStr.IsEmpty())
|
if (resultStr.IsEmpty())
|
||||||
return "<nothing>";
|
return "<nothing>";
|
||||||
return resultStr;
|
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) &&
|
if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) &&
|
||||||
(attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != 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)
|
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);
|
BfAutoParentNodeEntry autoParentNodeEntry(this, attributesDirective);
|
||||||
|
|
||||||
BfCustomAttribute customAttribute;
|
BfCustomAttribute customAttribute;
|
||||||
|
@ -9510,6 +9531,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
customAttribute.mType = attrTypeInst;
|
customAttribute.mType = attrTypeInst;
|
||||||
|
|
||||||
BfConstResolver constResolver(this);
|
BfConstResolver constResolver(this);
|
||||||
|
if (allowNonConstArgs)
|
||||||
|
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
||||||
|
|
||||||
bool inPropSet = false;
|
bool inPropSet = false;
|
||||||
SizedArray<BfResolvedArg, 2> argValues;
|
SizedArray<BfResolvedArg, 2> argValues;
|
||||||
|
@ -9775,6 +9798,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
// Move all those to the constHolder
|
// Move all those to the constHolder
|
||||||
for (auto& ctorArg : customAttribute.mCtorArgs)
|
for (auto& ctorArg : customAttribute.mCtorArgs)
|
||||||
{
|
{
|
||||||
|
if (ctorArg.IsConst())
|
||||||
CurrentAddToConstHolder(ctorArg);
|
CurrentAddToConstHolder(ctorArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9835,10 +9859,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
ValidateCustomAttributes(customAttributes, attrTarget);
|
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();
|
BfCustomAttributes* customAttributes = new BfCustomAttributes();
|
||||||
GetCustomAttributes(customAttributes, attributesDirective, attrType);
|
GetCustomAttributes(customAttributes, attributesDirective, attrType, allowNonConstArgs, captureInfo);
|
||||||
return customAttributes;
|
return customAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,8 @@ enum BfEvalExprFlags
|
||||||
BfEvalExprFlags_AllowOutExpr = 0x1000,
|
BfEvalExprFlags_AllowOutExpr = 0x1000,
|
||||||
BfEvalExprFlags_FieldInitializer = 0x2000,
|
BfEvalExprFlags_FieldInitializer = 0x2000,
|
||||||
BfEvalExprFlags_VariableDeclaration = 0x4000,
|
BfEvalExprFlags_VariableDeclaration = 0x4000,
|
||||||
BfEvalExprFlags_NoAutoComplete = 0x8000
|
BfEvalExprFlags_NoAutoComplete = 0x8000,
|
||||||
|
BfEvalExprFlags_AllowNonConst = 0x10000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfCastFlags
|
enum BfCastFlags
|
||||||
|
@ -146,6 +147,7 @@ public:
|
||||||
bool mAllowAddr;
|
bool mAllowAddr;
|
||||||
bool mIsShadow;
|
bool mIsShadow;
|
||||||
bool mUsedImplicitly; // Passed implicitly to a local method, capture by ref if we can
|
bool mUsedImplicitly; // Passed implicitly to a local method, capture by ref if we can
|
||||||
|
bool mNotCaptured;
|
||||||
BfLocalVariable* mShadowedLocal;
|
BfLocalVariable* mShadowedLocal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -172,6 +174,7 @@ public:
|
||||||
mAllowAddr = false;
|
mAllowAddr = false;
|
||||||
mIsShadow = false;
|
mIsShadow = false;
|
||||||
mUsedImplicitly = false;
|
mUsedImplicitly = false;
|
||||||
|
mNotCaptured = false;
|
||||||
mShadowedLocal = NULL;
|
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
|
class BfAllocTarget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -448,6 +472,8 @@ public:
|
||||||
BfAstNode* mRefNode;
|
BfAstNode* mRefNode;
|
||||||
BfTypedValue mCustomAllocator;
|
BfTypedValue mCustomAllocator;
|
||||||
BfScopedInvocationTarget* mScopedInvocationTarget;
|
BfScopedInvocationTarget* mScopedInvocationTarget;
|
||||||
|
int mAlignOverride;
|
||||||
|
BfCaptureInfo mCaptureInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfAllocTarget()
|
BfAllocTarget()
|
||||||
|
@ -456,6 +482,7 @@ public:
|
||||||
mRefNode = NULL;
|
mRefNode = NULL;
|
||||||
mCustomAllocator = NULL;
|
mCustomAllocator = NULL;
|
||||||
mScopedInvocationTarget = NULL;
|
mScopedInvocationTarget = NULL;
|
||||||
|
mAlignOverride = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfAllocTarget(BfScopeData* scopeData)
|
BfAllocTarget(BfScopeData* scopeData)
|
||||||
|
@ -464,6 +491,7 @@ public:
|
||||||
mRefNode = NULL;
|
mRefNode = NULL;
|
||||||
mCustomAllocator = NULL;
|
mCustomAllocator = NULL;
|
||||||
mScopedInvocationTarget = NULL;
|
mScopedInvocationTarget = NULL;
|
||||||
|
mAlignOverride = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfAllocTarget(const BfTypedValue& customAllocator, BfAstNode* refNode)
|
BfAllocTarget(const BfTypedValue& customAllocator, BfAstNode* refNode)
|
||||||
|
@ -472,6 +500,7 @@ public:
|
||||||
mCustomAllocator = customAllocator;
|
mCustomAllocator = customAllocator;
|
||||||
mRefNode = NULL;
|
mRefNode = NULL;
|
||||||
mScopedInvocationTarget = NULL;
|
mScopedInvocationTarget = NULL;
|
||||||
|
mAlignOverride = -1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1409,8 +1438,8 @@ public:
|
||||||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||||
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
||||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType);
|
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType);
|
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||||
void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered);
|
void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered);
|
||||||
void ProcessCustomAttributeData();
|
void ProcessCustomAttributeData();
|
||||||
bool TryGetConstString(BfIRConstHolder* constHolder, BfIRValue irValue, StringImpl& str);
|
bool TryGetConstString(BfIRConstHolder* constHolder, BfIRValue irValue, StringImpl& str);
|
||||||
|
|
|
@ -588,6 +588,35 @@ void BfPrinter::Visit(BfErrorNode* errorNode)
|
||||||
VisitChild(errorNode->mRefNode);
|
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)
|
void BfPrinter::Visit(BfExpression* expr)
|
||||||
{
|
{
|
||||||
Visit(expr->ToBase());
|
Visit(expr->ToBase());
|
||||||
|
@ -699,14 +728,19 @@ void BfPrinter::Visit(BfAttributeDirective* attributeDirective)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
||||||
{
|
{
|
||||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mTargetToken);
|
if (auto attributeTargetSpecifier = BfNodeDynCast<BfAttributeTargetSpecifier>(attributeDirective->mAttributeTargetSpecifier))
|
||||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mColonToken);
|
{
|
||||||
|
VisitChild(attributeTargetSpecifier->mTargetToken);
|
||||||
|
VisitChild(attributeTargetSpecifier->mColonToken);
|
||||||
ExpectSpace();
|
ExpectSpace();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VisitChild(attributeDirective->mAttributeTargetSpecifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VisitChild(attributeDirective->mAttributeTypeRef);
|
VisitChild(attributeDirective->mAttributeTypeRef);
|
||||||
VisitChild(attributeDirective->mCtorOpenParen);
|
VisitChild(attributeDirective->mCtorOpenParen);
|
||||||
|
@ -1227,12 +1261,6 @@ void BfPrinter::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
||||||
|
|
||||||
VisitChild(lambdaBindExpr->mNewToken);
|
VisitChild(lambdaBindExpr->mNewToken);
|
||||||
ExpectSpace();
|
ExpectSpace();
|
||||||
if (lambdaBindExpr->mLambdaCapture != NULL)
|
|
||||||
{
|
|
||||||
VisitChild(lambdaBindExpr->mLambdaCapture->mOpenBracket);
|
|
||||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCaptureToken);
|
|
||||||
VisitChild(lambdaBindExpr->mLambdaCapture->mCloseBracket);
|
|
||||||
}
|
|
||||||
VisitChild(lambdaBindExpr->mOpenParen);
|
VisitChild(lambdaBindExpr->mOpenParen);
|
||||||
for (int i = 0; i < (int)lambdaBindExpr->mParams.size(); i++)
|
for (int i = 0; i < (int)lambdaBindExpr->mParams.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,8 @@ public:
|
||||||
|
|
||||||
virtual void Visit(BfAstNode* bfAstNode) override;
|
virtual void Visit(BfAstNode* bfAstNode) override;
|
||||||
virtual void Visit(BfErrorNode* bfErrorNode) 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(BfExpression* expr) override;
|
||||||
virtual void Visit(BfExpressionStatement* exprStmt) override;
|
virtual void Visit(BfExpressionStatement* exprStmt) override;
|
||||||
virtual void Visit(BfAttributedExpression* attribExpr) override;
|
virtual void Visit(BfAttributedExpression* attribExpr) override;
|
||||||
|
|
|
@ -5105,6 +5105,8 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
||||||
ReplaceNode(startToken, attributeDirective);
|
ReplaceNode(startToken, attributeDirective);
|
||||||
attributeDirective->mAttrOpenToken = startToken;
|
attributeDirective->mAttrOpenToken = startToken;
|
||||||
|
|
||||||
|
bool isHandled = false;
|
||||||
|
|
||||||
auto nextNode = mVisitorPos.GetNext();
|
auto nextNode = mVisitorPos.GetNext();
|
||||||
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
||||||
if (tokenNode != NULL)
|
if (tokenNode != NULL)
|
||||||
|
@ -5114,15 +5116,31 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
||||||
auto attributeTargetSpecifier = mAlloc->Alloc<BfAttributeTargetSpecifier>();
|
auto attributeTargetSpecifier = mAlloc->Alloc<BfAttributeTargetSpecifier>();
|
||||||
ReplaceNode(tokenNode, attributeTargetSpecifier);
|
ReplaceNode(tokenNode, attributeTargetSpecifier);
|
||||||
MEMBER_SET(attributeDirective, mAttributeTargetSpecifier, attributeTargetSpecifier);
|
MEMBER_SET(attributeDirective, mAttributeTargetSpecifier, attributeTargetSpecifier);
|
||||||
attributeDirective->mAttributeTargetSpecifier->mTargetToken = tokenNode;
|
attributeTargetSpecifier->mTargetToken = tokenNode;
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_Colon);
|
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_Colon);
|
||||||
if (tokenNode != NULL)
|
if (tokenNode != NULL)
|
||||||
MEMBER_SET(attributeDirective->mAttributeTargetSpecifier, mColonToken, tokenNode);
|
MEMBER_SET(attributeTargetSpecifier, mColonToken, tokenNode);
|
||||||
attributeDirective->SetSrcEnd(attributeDirective->mAttributeTargetSpecifier->GetSrcEnd());
|
attributeDirective->SetSrcEnd(attributeDirective->mAttributeTargetSpecifier->GetSrcEnd());
|
||||||
}
|
}
|
||||||
|
else if ((tokenNode->mToken == BfToken_Ampersand) || (tokenNode->mToken == BfToken_AssignEquals))
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
nextNode = mVisitorPos.GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isHandled)
|
||||||
|
{
|
||||||
auto typeRef = CreateTypeRefAfter(attributeDirective);
|
auto typeRef = CreateTypeRefAfter(attributeDirective);
|
||||||
if (typeRef == NULL)
|
if (typeRef == NULL)
|
||||||
{
|
{
|
||||||
|
@ -5140,6 +5158,8 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
||||||
return attributeDirective;
|
return attributeDirective;
|
||||||
}
|
}
|
||||||
MEMBER_SET(attributeDirective, mAttributeTypeRef, typeRef);
|
MEMBER_SET(attributeDirective, mAttributeTypeRef, typeRef);
|
||||||
|
}
|
||||||
|
|
||||||
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_LParen, BfToken_RBracket, BfToken_Comma);
|
tokenNode = ExpectTokenAfter(attributeDirective, BfToken_LParen, BfToken_RBracket, BfToken_Comma);
|
||||||
if (tokenNode == NULL)
|
if (tokenNode == NULL)
|
||||||
return attributeDirective;
|
return attributeDirective;
|
||||||
|
@ -5160,7 +5180,6 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
|
||||||
if (tokenNode == NULL)
|
if (tokenNode == NULL)
|
||||||
return attributeDirective;
|
return attributeDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
Do_RBracket:
|
Do_RBracket:
|
||||||
if (tokenNode->GetToken() == BfToken_RBracket)
|
if (tokenNode->GetToken() == BfToken_RBracket)
|
||||||
{
|
{
|
||||||
|
@ -5173,7 +5192,6 @@ Do_RBracket:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has another one- chain it
|
// Has another one- chain it
|
||||||
//mVisitorPos.MoveNext();
|
|
||||||
auto nextAttribute = CreateAttributeDirective(tokenNode);
|
auto nextAttribute = CreateAttributeDirective(tokenNode);
|
||||||
if (nextAttribute != NULL)
|
if (nextAttribute != NULL)
|
||||||
{
|
{
|
||||||
|
@ -6810,41 +6828,10 @@ BfLambdaBindExpression* BfReducer::CreateLambdaBindExpression(BfAstNode* allocNo
|
||||||
ReplaceNode(parenToken, lambdaBindExpr);
|
ReplaceNode(parenToken, lambdaBindExpr);
|
||||||
tokenNode = parenToken;
|
tokenNode = parenToken;
|
||||||
}
|
}
|
||||||
//auto tokenNode = ExpectTokenAfter(lambdaBindExpr, BfToken_LParen, BfToken_LBracket);
|
|
||||||
if (tokenNode == NULL)
|
if (tokenNode == NULL)
|
||||||
return lambdaBindExpr;
|
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);
|
MEMBER_SET_CHECKED(lambdaBindExpr, mOpenParen, tokenNode);
|
||||||
|
|
||||||
for (int paramIdx = 0; true; paramIdx++)
|
for (int paramIdx = 0; true; paramIdx++)
|
||||||
|
@ -7051,11 +7038,17 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
if (allocToken->GetToken() == BfToken_Scope)
|
if (allocToken->GetToken() == BfToken_Scope)
|
||||||
{
|
{
|
||||||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||||
if ((nextToken != NULL) && (nextToken->GetToken() == BfToken_Colon))
|
if (nextToken == NULL)
|
||||||
{
|
return allocToken;
|
||||||
|
if ((nextToken->mToken != BfToken_Colon) && (nextToken->mToken != BfToken_LBracket))
|
||||||
|
return allocToken;
|
||||||
|
|
||||||
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
||||||
ReplaceNode(allocToken, scopeNode);
|
ReplaceNode(allocToken, scopeNode);
|
||||||
scopeNode->mScopeToken = allocToken;
|
scopeNode->mScopeToken = allocToken;
|
||||||
|
|
||||||
|
if (nextToken->mToken == BfToken_Colon)
|
||||||
|
{
|
||||||
MEMBER_SET(scopeNode, mColonToken, nextToken);
|
MEMBER_SET(scopeNode, mColonToken, nextToken);
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
||||||
|
@ -7077,19 +7070,36 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
{
|
{
|
||||||
FailAfter("Expected scope name", scopeNode);
|
FailAfter("Expected scope name", 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;
|
return scopeNode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (allocToken->GetToken() == BfToken_New)
|
if (allocToken->GetToken() == BfToken_New)
|
||||||
{//
|
{
|
||||||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||||
if ((nextToken != NULL) && (nextToken->GetToken() == BfToken_Colon))
|
|
||||||
{ //
|
if (nextToken == NULL)
|
||||||
|
return allocToken;
|
||||||
|
if ((nextToken->mToken != BfToken_Colon) && (nextToken->mToken != BfToken_LBracket))
|
||||||
|
return allocToken;
|
||||||
|
|
||||||
auto newNode = mAlloc->Alloc<BfNewNode>();
|
auto newNode = mAlloc->Alloc<BfNewNode>();
|
||||||
ReplaceNode(allocToken, newNode);
|
ReplaceNode(allocToken, newNode);
|
||||||
newNode->mNewToken = allocToken;
|
newNode->mNewToken = allocToken;
|
||||||
|
|
||||||
|
if (nextToken->mToken == BfToken_Colon)
|
||||||
|
{
|
||||||
MEMBER_SET(newNode, mColonToken, nextToken);
|
MEMBER_SET(newNode, mColonToken, nextToken);
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
||||||
|
@ -7168,14 +7178,6 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
mVisitorPos.MoveNext();
|
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,10 +7185,20 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
{
|
{
|
||||||
FailAfter("Expected allocator expression", newNode);
|
FailAfter("Expected allocator expression", 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 newNode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return allocToken;
|
return allocToken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1411,6 +1411,7 @@ enum BfAttributeTargets : int32
|
||||||
BfAttributeTargets_GenericParameter = 0x8000,
|
BfAttributeTargets_GenericParameter = 0x8000,
|
||||||
BfAttributeTargets_Invocation = 0x10000,
|
BfAttributeTargets_Invocation = 0x10000,
|
||||||
BfAttributeTargets_MemberAccess = 0x20000,
|
BfAttributeTargets_MemberAccess = 0x20000,
|
||||||
|
BfAttributeTargets_Alloc = 0x40000,
|
||||||
BfAttributeTargets_All = 0x3FFFF
|
BfAttributeTargets_All = 0x3FFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1879,9 +1880,9 @@ public:
|
||||||
|
|
||||||
enum BfCaptureType
|
enum BfCaptureType
|
||||||
{
|
{
|
||||||
BfCaptureType_Value,
|
BfCaptureType_None,
|
||||||
|
BfCaptureType_Copy,
|
||||||
BfCaptureType_Reference,
|
BfCaptureType_Reference,
|
||||||
BfCaptureType_Copy
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfClosureType : public BfTypeInstance
|
class BfClosureType : public BfTypeInstance
|
||||||
|
|
|
@ -206,8 +206,15 @@ void BfSourceClassifier::Visit(BfAttributeDirective* attributeDirective)
|
||||||
|
|
||||||
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
||||||
{
|
{
|
||||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mTargetToken);
|
if (auto attributeTargetSpecifier = BfNodeDynCast<BfAttributeTargetSpecifier>(attributeDirective->mAttributeTargetSpecifier))
|
||||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mColonToken);
|
{
|
||||||
|
VisitChild(attributeTargetSpecifier->mTargetToken);
|
||||||
|
VisitChild(attributeTargetSpecifier->mColonToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VisitChild(attributeDirective->mAttributeTargetSpecifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitChild(attributeDirective->mAttributeTypeRef);
|
VisitChild(attributeDirective->mAttributeTypeRef);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue