This commit is contained in:
parent
3823906c2d
commit
909f5599b8
|
|
@ -6,6 +6,6 @@ namespace PascalABCCompiler.PCU
|
|||
{
|
||||
public static class PCUFileFormatVersion
|
||||
{
|
||||
public static System.Int16 Version = 118;
|
||||
public static System.Int16 Version = 119;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,7 +313,13 @@ namespace PascalABCCompiler.PCU
|
|||
AddTypeSynonyms(pcu_file.interface_synonyms_offset, cun.scope);
|
||||
AddTypeSynonyms(pcu_file.implementation_synonyms_offset, cun.implementation_scope);
|
||||
//\ssyy
|
||||
|
||||
for (int i = 0; i < pcu_file.names.Length; i++)
|
||||
{
|
||||
if (pcu_file.names[i].always_restore)
|
||||
{
|
||||
cun.scope.Find(pcu_file.names[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
ChangeState(this, PCUReaderWriterState.EndReadTree, unit);
|
||||
return unit;
|
||||
|
|
@ -578,6 +584,7 @@ namespace PascalABCCompiler.PCU
|
|||
pcu_file.names[i].offset = br.ReadInt32();
|
||||
pcu_file.names[i].symbol_kind = (symbol_kind)br.ReadByte();
|
||||
pcu_file.names[i].special_scope = br.ReadByte();
|
||||
pcu_file.names[i].always_restore = br.ReadBoolean();
|
||||
}
|
||||
//ssyy
|
||||
num_names = br.ReadInt32();
|
||||
|
|
@ -588,6 +595,7 @@ namespace PascalABCCompiler.PCU
|
|||
pcu_file.implementation_names[i].offset = br.ReadInt32();
|
||||
pcu_file.implementation_names[i].symbol_kind = (symbol_kind)br.ReadByte();
|
||||
pcu_file.implementation_names[i].special_scope = br.ReadByte();
|
||||
pcu_file.implementation_names[i].always_restore = br.ReadBoolean();
|
||||
}
|
||||
//\ssyy
|
||||
int num_incl = br.ReadInt32();
|
||||
|
|
@ -2567,7 +2575,7 @@ namespace PascalABCCompiler.PCU
|
|||
|
||||
si.symbol_kind = (symbol_kind)br.ReadByte();
|
||||
si.semantic_node_type = (semantic_node_type)br.ReadByte();
|
||||
si.virtual_slot = br.ReadBoolean();
|
||||
si.always_restore = br.ReadBoolean();
|
||||
si.is_static = br.ReadBoolean();
|
||||
//Вроде это ненужно
|
||||
//SymbolInfo si2 = scope.FindWithoutCreation(name);
|
||||
|
|
|
|||
|
|
@ -189,7 +189,9 @@ namespace PascalABCCompiler.PCU
|
|||
{
|
||||
if (pcu_tsi == null)
|
||||
return true;
|
||||
if (pcu_tsi.semantic_node_type == semantic_node_type.common_method_node && pcu_tsi.virtual_slot)
|
||||
//if (pcu_tsi.semantic_node_type == semantic_node_type.common_method_node && pcu_tsi.virtual_slot)
|
||||
// return true;
|
||||
if (pcu_tsi.always_restore)
|
||||
return true;
|
||||
if (hasNotRestoreAttribute())
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace PascalABCCompiler.PCU
|
|||
public byte special_scope=0;//говорит о том что этот символ добавляется не в пространсво имен модуля
|
||||
public int index;//не сериализуется
|
||||
public semantic_node_type semantic_node_type;
|
||||
public bool virtual_slot;
|
||||
public bool always_restore;
|
||||
public bool is_static;
|
||||
|
||||
public NameRef(string name, int index, TreeConverter.access_level access_level, semantic_node_type semantic_node_type)
|
||||
|
|
@ -441,6 +441,7 @@ namespace PascalABCCompiler.PCU
|
|||
fbw.Write(pcu_file.names[i].offset);
|
||||
fbw.Write((byte)pcu_file.names[i].symbol_kind);
|
||||
fbw.Write(pcu_file.names[i].special_scope);
|
||||
fbw.Write(pcu_file.names[i].always_restore);
|
||||
}
|
||||
|
||||
//ssyy
|
||||
|
|
@ -451,6 +452,7 @@ namespace PascalABCCompiler.PCU
|
|||
fbw.Write(pcu_file.implementation_names[i].offset);
|
||||
fbw.Write((byte)pcu_file.implementation_names[i].symbol_kind);
|
||||
fbw.Write(pcu_file.implementation_names[i].special_scope);
|
||||
fbw.Write(pcu_file.implementation_names[i].always_restore);
|
||||
}
|
||||
//\ssyy
|
||||
|
||||
|
|
@ -812,6 +814,17 @@ namespace PascalABCCompiler.PCU
|
|||
return ctn.name;
|
||||
}
|
||||
//ssyy
|
||||
|
||||
private bool HasPCUAlwaysRestoreAttribute(definition_node dn)
|
||||
{
|
||||
foreach (var attr in dn.attributes)
|
||||
{
|
||||
if (attr.attribute_type.full_name == "PABCSystem.PCUAlwaysRestoreAttribute")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void FillNames(NameRef[] name_array, Dictionary<definition_node, NameRef> pools)
|
||||
{
|
||||
int j = 0, i = 0;
|
||||
|
|
@ -838,12 +851,16 @@ namespace PascalABCCompiler.PCU
|
|||
else
|
||||
name_array[i].symbol_kind = symbol_kind.sk_overload_procedure;
|
||||
}
|
||||
if (HasPCUAlwaysRestoreAttribute(cur_cnn.functions[i - j]))
|
||||
name_array[i].always_restore = true;
|
||||
pools[cur_cnn.functions[i - j]] = name_array[i];
|
||||
}
|
||||
j = i;
|
||||
for (i = j; i < cur_cnn.non_template_types.Count + j; i++)
|
||||
{
|
||||
name_array[i] = new NameRef(cur_cnn.non_template_types[i - j].name, i);
|
||||
if (HasPCUAlwaysRestoreAttribute(cur_cnn.non_template_types[i - j]))
|
||||
name_array[i].always_restore = true;
|
||||
pools[cur_cnn.non_template_types[i - j]] = name_array[i];
|
||||
}
|
||||
j = i;
|
||||
|
|
@ -864,6 +881,8 @@ namespace PascalABCCompiler.PCU
|
|||
for (i = j; i < cur_cnn.variables.Count + j; i++)
|
||||
{
|
||||
name_array[i] = new NameRef(cur_cnn.variables[i - j].name, i);
|
||||
if (HasPCUAlwaysRestoreAttribute(cur_cnn.variables[i - j]))
|
||||
name_array[i].always_restore = true;
|
||||
pools[cur_cnn.variables[i - j]] = name_array[i];
|
||||
}
|
||||
j = i;
|
||||
|
|
@ -2707,6 +2726,8 @@ namespace PascalABCCompiler.PCU
|
|||
names[i] = new NameRef(type.fields[i - j].name, i, convert_field_access_level(type.fields[i - j].field_access_level), type.fields[i - j].semantic_node_type);
|
||||
name_pool[type.fields[i - j]] = names[i];
|
||||
names[i].is_static = type.fields[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_static;
|
||||
if (HasPCUAlwaysRestoreAttribute(type.fields[i - j]))
|
||||
names[i].always_restore = true;
|
||||
size += names[i].Size;
|
||||
}
|
||||
j = i;
|
||||
|
|
@ -2715,6 +2736,8 @@ namespace PascalABCCompiler.PCU
|
|||
names[i] = new NameRef(type.properties[i - j].name, i, convert_field_access_level(type.properties[i - j].field_access_level), type.properties[i - j].semantic_node_type);
|
||||
name_pool[type.properties[i - j]] = names[i];
|
||||
names[i].is_static = type.properties[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_static;
|
||||
if (HasPCUAlwaysRestoreAttribute(type.properties[i - j]))
|
||||
names[i].always_restore = true;
|
||||
size += names[i].Size;
|
||||
}
|
||||
j = i;
|
||||
|
|
@ -2724,8 +2747,10 @@ namespace PascalABCCompiler.PCU
|
|||
name_pool[type.methods[i - j]] = names[i];
|
||||
if (type.methods[i - j].is_overload)
|
||||
names[i].symbol_kind = symbol_kind.sk_overload_function;
|
||||
names[i].virtual_slot = type.methods[i - j].newslot_awaited || type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_virtual || type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract || type.methods[i - j].is_constructor;
|
||||
names[i].always_restore = type.methods[i - j].newslot_awaited || type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_virtual || type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract || type.methods[i - j].is_constructor;
|
||||
names[i].is_static = type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_static && !type.methods[i - j].is_constructor;
|
||||
if (!names[i].always_restore && HasPCUAlwaysRestoreAttribute(type.methods[i - j]))
|
||||
names[i].always_restore = true;
|
||||
size += names[i].Size;
|
||||
}
|
||||
j = i;
|
||||
|
|
@ -2907,7 +2932,7 @@ namespace PascalABCCompiler.PCU
|
|||
bw.Write((byte)names[i].access_level);
|
||||
bw.Write((byte)names[i].symbol_kind);
|
||||
bw.Write((byte)names[i].semantic_node_type);
|
||||
bw.Write(names[i].virtual_slot);
|
||||
bw.Write(names[i].always_restore);
|
||||
bw.Write(names[i].is_static);
|
||||
}
|
||||
bw.BaseStream.Seek(tmp, SeekOrigin.Begin);
|
||||
|
|
|
|||
|
|
@ -2833,6 +2833,12 @@ type
|
|||
PCUNotRestoreAttribute = class(System.Attribute)
|
||||
public constructor := exit;
|
||||
end;
|
||||
|
||||
type
|
||||
[AttributeUsage(AttributeTargets.Class or AttributeTargets.Method or AttributeTargets.Property or AttributeTargets.Interface or AttributeTargets.Field or AttributeTargets.Struct)]
|
||||
PCUAlwaysRestoreAttribute = class(System.Attribute)
|
||||
public constructor := exit;
|
||||
end;
|
||||
|
||||
///--
|
||||
function InternalRange(l,r: integer): IntRange;
|
||||
|
|
|
|||
19
TestSuite/units/u_alwaysrestore.pas
Normal file
19
TestSuite/units/u_alwaysrestore.pas
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
unit u_alwaysrestore;
|
||||
interface
|
||||
|
||||
[PCUAlwaysRestore]
|
||||
function myfunc: integer;
|
||||
|
||||
type
|
||||
[PCUAlwaysRestore]
|
||||
MyClass = class
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
function myfunc: integer;
|
||||
begin
|
||||
|
||||
end;
|
||||
end.
|
||||
5
TestSuite/usesunits/use_alwaysrestore.pas
Normal file
5
TestSuite/usesunits/use_alwaysrestore.pas
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
uses u_alwaysrestore;
|
||||
begin
|
||||
assert(System.Type.GetType('u_alwaysrestore.MyClass') <> nil);
|
||||
assert(System.Type.GetType('u_alwaysrestore.u_alwaysrestore').GetMethod('myfunc') <> nil);
|
||||
end.
|
||||
|
|
@ -77,7 +77,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
private semantic_node_type _semantic_node_type;
|
||||
|
||||
private bool _virtual_slot;
|
||||
private bool _always_restore;
|
||||
|
||||
private bool _is_static;
|
||||
|
||||
|
|
@ -93,15 +93,15 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
}
|
||||
|
||||
public bool virtual_slot
|
||||
public bool always_restore
|
||||
{
|
||||
get
|
||||
{
|
||||
return _virtual_slot;
|
||||
return _always_restore;
|
||||
}
|
||||
set
|
||||
{
|
||||
_virtual_slot = value;
|
||||
_always_restore = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2833,6 +2833,12 @@ type
|
|||
PCUNotRestoreAttribute = class(System.Attribute)
|
||||
public constructor := exit;
|
||||
end;
|
||||
|
||||
type
|
||||
[AttributeUsage(AttributeTargets.Class or AttributeTargets.Method or AttributeTargets.Property or AttributeTargets.Interface or AttributeTargets.Field or AttributeTargets.Struct)]
|
||||
PCUAlwaysRestoreAttribute = class(System.Attribute)
|
||||
public constructor := exit;
|
||||
end;
|
||||
|
||||
///--
|
||||
function InternalRange(l,r: integer): IntRange;
|
||||
|
|
|
|||
Loading…
Reference in a new issue