Skip to content

Commit

Permalink
Now handles forward declared structures correctly.
Browse files Browse the repository at this point in the history
Issue #166
  • Loading branch information
zik.saleeba committed Sep 23, 2012
1 parent 0df62f0 commit 53c5153
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 3 deletions.
1 change: 1 addition & 0 deletions interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s
void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic);
struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates);
struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser, const char *StructName, int Size);
int TypeIsForwardDeclared(struct ParseState *Parser, struct ValueType *Typ);

/* heap.c */
void HeapInit(Picoc *pc, int StackSize);
Expand Down
18 changes: 18 additions & 0 deletions tests/56_cross_structure.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdio.h>

struct s1;

struct s2
{
struct s1 *s;
};

struct s1
{
struct s2 *s;
};

void main()
{
printf("ok\n");
}
1 change: 1 addition & 0 deletions tests/56_cross_structure.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ok
3 changes: 2 additions & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ TESTS= 00_assignment.test \
51_static.test \
52_unnamed_enum.test \
54_goto.test \
55_array_initialiser.test
55_array_initialiser.test \
56_cross_structure.test

%.test: %.expect %.c
@echo Test: $*...
Expand Down
18 changes: 16 additions & 2 deletions type.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,18 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
StructIdentifier = PlatformMakeTempName(pc, TempNameBuf);
}

*Typ = TypeGetMatching(pc, Parser, &Parser->pc->UberType, IsStruct ? TypeStruct : TypeUnion, 0, StructIdentifier, Token != TokenLeftBrace);
*Typ = TypeGetMatching(pc, Parser, &Parser->pc->UberType, IsStruct ? TypeStruct : TypeUnion, 0, StructIdentifier, TRUE);
if (Token == TokenLeftBrace && (*Typ)->Members != NULL)
ProgramFail(Parser, "data type '%t' is already defined", *Typ);

Token = LexGetToken(Parser, NULL, FALSE);
if (Token != TokenLeftBrace)
{
/* use the already defined structure */
#if 0
if ((*Typ)->Members == NULL)
ProgramFail(Parser, "structure '%s' isn't defined", LexValue->Val->Identifier);

#endif
return;
}

Expand Down Expand Up @@ -527,3 +530,14 @@ void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identif
TypeParseIdentPart(Parser, BasicType, Typ, Identifier);
}

/* check if a type has been fully defined - otherwise it's just a forward declaration */
int TypeIsForwardDeclared(struct ParseState *Parser, struct ValueType *Typ)
{
if (Typ->Base == TypeArray)
return TypeIsForwardDeclared(Parser, Typ->FromType);

if ( (Typ->Base == TypeStruct || Typ->Base == TypeUnion) && Typ->Members == NULL)
return TRUE;

return FALSE;
}
4 changes: 4 additions & 0 deletions variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *
int DeclLine;
int DeclColumn;

/* is the type a forward declaration? */
if (TypeIsForwardDeclared(Parser, Typ))
ProgramFail(Parser, "type '%t' isn't defined", Typ);

if (IsStatic)
{
char MangledName[LINEBUFFER_MAX];
Expand Down

0 comments on commit 53c5153

Please sign in to comment.