Handled struct members which are pointers to data with the type of the containing struct. ie struct foo { foo* Next; }
This commit is contained in:
parent
9d0e4149d9
commit
9a228d22ba
|
@ -1,3 +1,15 @@
|
|||
//
|
||||
// Usage
|
||||
//
|
||||
// GSMetaTag(<tag name>) to give commands to the meta layer
|
||||
//
|
||||
// Tag Values
|
||||
//
|
||||
// breakpoint
|
||||
// will cause the meta layer to break in the debugger when it reaches
|
||||
// that point in processing the file
|
||||
// TODO: specify which stage you want it to break at
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -354,7 +366,15 @@ ParseMetaTag(token_iter* Iter, gs_bucket<token*>* TagList)
|
|||
if (Iter->TokenAt->Type == Token_Identifier)
|
||||
{
|
||||
TagList->PushElementOnBucket(Iter->TokenAt);
|
||||
if (StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("breakpoint")))
|
||||
{
|
||||
// NOTE(Peter): This is not a temporary breakpoint. It is
|
||||
// used to be able to break the meta program at specific points
|
||||
// throughout execution
|
||||
__debugbreak();
|
||||
}
|
||||
NextToken(Iter);
|
||||
|
||||
if (TokenAtEquals(Iter, ")") &&
|
||||
TokenAtEquals(Iter, ";"))
|
||||
{
|
||||
|
@ -790,7 +810,7 @@ ParseStruct(token_iter* Iter, s32* StructTypeIndexOut, gs_bucket<token*>* TagLis
|
|||
if (TokenAtEquals(Iter, ";"))
|
||||
{
|
||||
Result = true;
|
||||
*StructTypeIndexOut = TypeTable->Types.PushElementOnBucket(StructDecl);
|
||||
*StructTypeIndexOut = PushTypeDefOnTypeTable(StructDecl, TypeTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +892,7 @@ ParseFunctionDeclaration (token_iter* Iter, token* Identifier, gs_bucket<token*>
|
|||
if (TokenAtEquals(Iter, ";"))
|
||||
{
|
||||
Result = true;
|
||||
TypeTable->Types.PushElementOnBucket(FunctionPtr);
|
||||
PushTypeDefOnTypeTable(FunctionPtr, TypeTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -934,17 +954,7 @@ ParseTypedef(token_iter* Iter, gs_bucket<token*>* TagList, type_table* TypeTable
|
|||
NextToken(Iter);
|
||||
|
||||
Result = true;
|
||||
|
||||
s32 ExistingUndeclaredTypeIndex = GetIndexOfType(NewType.Identifier, *TypeTable);
|
||||
if (ExistingUndeclaredTypeIndex < 0)
|
||||
{
|
||||
TypeTable->Types.PushElementOnBucket(NewType);
|
||||
}
|
||||
else
|
||||
{
|
||||
type_definition* ExistingTypeDef = TypeTable->Types.GetElementAtIndex(ExistingUndeclaredTypeIndex);
|
||||
*ExistingTypeDef = NewType;
|
||||
}
|
||||
PushTypeDefOnTypeTable(NewType, TypeTable);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1190,11 +1200,11 @@ int main(int ArgCount, char** ArgV)
|
|||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
|
||||
if (TypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(TypeDef, TypeTable);
|
||||
FixUpStructSize(i, TypeTable);
|
||||
}
|
||||
else if (TypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(TypeDef, TypeTable);
|
||||
FixUpUnionSize(i, TypeTable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,19 @@ struct type_table
|
|||
gs_bucket<type_definition> Types;
|
||||
};
|
||||
|
||||
internal void
|
||||
MetaTagBreakpoint(gs_bucket<meta_tag> Tags)
|
||||
{
|
||||
for (u32 i = 0; i < Tags.Used; i++)
|
||||
{
|
||||
meta_tag* Tag = Tags.GetElementAtIndex(i);
|
||||
if (StringsEqual(Tag->Identifier, MakeStringLiteral("breakpoint")))
|
||||
{
|
||||
__debugbreak();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
CopyMetaTagsAndClear(gs_bucket<token*>* Source, gs_bucket<meta_tag>* Dest)
|
||||
{
|
||||
|
@ -91,35 +104,6 @@ CopyMetaTagsAndClear(gs_bucket<token*>* Source, gs_bucket<meta_tag>* Dest)
|
|||
Source->Used = 0;
|
||||
}
|
||||
|
||||
internal type_definition*
|
||||
PushStructOnTypeTable(string Identifier, type_definition_type DeclType, gs_bucket<token*>* TagList, type_table* TypeTable)
|
||||
{
|
||||
Assert(DeclType == TypeDef_Struct || DeclType == TypeDef_Union);
|
||||
|
||||
type_definition* Result = TypeTable->Types.TakeElement();
|
||||
*Result = {0};
|
||||
|
||||
Result->Type = DeclType;
|
||||
Result->Identifier = Identifier;
|
||||
CopyMetaTagsAndClear(TagList, &Result->MetaTags);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal s32
|
||||
PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable)
|
||||
{
|
||||
s32 Index = -1;
|
||||
if (TypeDef.Type != TypeDef_BasicType)
|
||||
{
|
||||
printf("Invalid TypeDef: %.*s\n", StringExpand(TypeDef.Identifier));
|
||||
}
|
||||
else
|
||||
{
|
||||
Index = TypeTable->Types.PushElementOnBucket(TypeDef);
|
||||
}
|
||||
return Index;
|
||||
}
|
||||
|
||||
internal s32
|
||||
PushUndeclaredType (string Identifier, type_table* TypeTable)
|
||||
{
|
||||
|
@ -146,6 +130,26 @@ GetIndexOfType (string Identifier, type_table TypeTable)
|
|||
return Result;
|
||||
}
|
||||
|
||||
internal s32
|
||||
PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable)
|
||||
{
|
||||
s32 Index = -1;
|
||||
|
||||
s32 ExistingUndeclaredTypeIndex = GetIndexOfType(TypeDef.Identifier, *TypeTable);
|
||||
if (ExistingUndeclaredTypeIndex < 0)
|
||||
{
|
||||
Index = TypeTable->Types.PushElementOnBucket(TypeDef);
|
||||
}
|
||||
else
|
||||
{
|
||||
Index = ExistingUndeclaredTypeIndex;
|
||||
type_definition* ExistingTypeDef = TypeTable->Types.GetElementAtIndex(ExistingUndeclaredTypeIndex);
|
||||
*ExistingTypeDef = TypeDef;
|
||||
}
|
||||
|
||||
return Index;
|
||||
}
|
||||
|
||||
internal s32
|
||||
GetSizeOfType (s32 TypeIndex, type_table TypeTable)
|
||||
{
|
||||
|
@ -241,8 +245,8 @@ FindIndexOfMatchingType (type_definition Match, type_table TypeTable)
|
|||
return Result;
|
||||
}
|
||||
|
||||
internal void FixUpStructSize (type_definition* Struct, type_table TypeTable);
|
||||
internal void FixUpUnionSize (type_definition* Union, type_table TypeTable);
|
||||
internal void FixUpStructSize (s32 StructIndex, type_table TypeTable);
|
||||
internal void FixUpUnionSize (s32 UnionIndex, type_table TypeTable);
|
||||
|
||||
internal void
|
||||
FixupMemberType (variable_decl* Member, type_table TypeTable)
|
||||
|
@ -275,10 +279,13 @@ CalculateStructMemberSize (variable_decl Member, type_definition MemberType)
|
|||
}
|
||||
|
||||
internal void
|
||||
FixUpStructSize (type_definition* Struct, type_table TypeTable)
|
||||
FixUpStructSize (s32 StructIndex, type_table TypeTable)
|
||||
{
|
||||
type_definition* Struct = TypeTable.Types.GetElementAtIndex(StructIndex);
|
||||
Assert(Struct->Type == TypeDef_Struct);
|
||||
|
||||
MetaTagBreakpoint(Struct->MetaTags);
|
||||
|
||||
s32 SizeAcc = 0;
|
||||
for (u32 j = 0; j < Struct->Struct.MemberDecls.Used; j++)
|
||||
{
|
||||
|
@ -288,15 +295,23 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable)
|
|||
if (Member->TypeIndex >= 0)
|
||||
{
|
||||
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
||||
if (MemberTypeDef->Size == 0)
|
||||
|
||||
// NOTE(Peter): This signals a nested pointer to an address of the
|
||||
// same type as the one we are parsing now. In that case, the size
|
||||
// also hasn't been determined yet, but we know the size of the member
|
||||
// is just a pointer (32 or 64 bits).
|
||||
// For example, this would go into an infinite recursion without the case
|
||||
// of StructIndex != Member->TypeIndex:
|
||||
// struct foo { foo* Next; }
|
||||
if (MemberTypeDef->Size == 0 && StructIndex != Member->TypeIndex)
|
||||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(MemberTypeDef, TypeTable);
|
||||
FixUpStructSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else if (MemberTypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(MemberTypeDef, TypeTable);
|
||||
FixUpUnionSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -305,7 +320,7 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable)
|
|||
#if 0
|
||||
InvalidCodePath;
|
||||
#else
|
||||
printf("Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
|
||||
printf("Struct Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -327,14 +342,15 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable)
|
|||
#else
|
||||
if (Struct->Size == 0)
|
||||
{
|
||||
printf("Error: Struct Size = 0. %.*s\n", StringExpand(Struct->Identifier));
|
||||
printf("Struct Error: Struct Size = 0. %.*s\n", StringExpand(Struct->Identifier));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
FixUpUnionSize (type_definition* Union, type_table TypeTable)
|
||||
FixUpUnionSize (s32 UnionIndex, type_table TypeTable)
|
||||
{
|
||||
type_definition* Union = TypeTable.Types.GetElementAtIndex(UnionIndex);
|
||||
Assert(Union->Type == TypeDef_Union);
|
||||
|
||||
s32 BiggestMemberSize = 0;
|
||||
|
@ -350,11 +366,11 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable)
|
|||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(MemberTypeDef, TypeTable);
|
||||
FixUpStructSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else if(MemberTypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(MemberTypeDef, TypeTable);
|
||||
FixUpUnionSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -363,7 +379,7 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable)
|
|||
#if 0
|
||||
InvalidCodePath;
|
||||
#else
|
||||
printf("Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
|
||||
printf("Union Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +401,7 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable)
|
|||
#else
|
||||
if (Union->Size == 0)
|
||||
{
|
||||
printf("Error: Struct Size = 0. %.*s\n", StringExpand(Union->Identifier));
|
||||
printf("Union Error: Struct Size = 0. %.*s\n", StringExpand(Union->Identifier));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue