Now handles forward declared structures correctly.
Issue #166 git-svn-id: http://picoc.googlecode.com/svn/trunk@583 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
35e64fa8c1
commit
9ec50b6e49
|
@ -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);
|
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 *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);
|
struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser, const char *StructName, int Size);
|
||||||
|
int TypeIsForwardDeclared(struct ParseState *Parser, struct ValueType *Typ);
|
||||||
|
|
||||||
/* heap.c */
|
/* heap.c */
|
||||||
void HeapInit(Picoc *pc, int StackSize);
|
void HeapInit(Picoc *pc, int StackSize);
|
||||||
|
|
18
tests/56_cross_structure.c
Normal file
18
tests/56_cross_structure.c
Normal file
|
@ -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
tests/56_cross_structure.expect
Normal file
1
tests/56_cross_structure.expect
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ok
|
|
@ -49,7 +49,8 @@ TESTS= 00_assignment.test \
|
||||||
51_static.test \
|
51_static.test \
|
||||||
52_unnamed_enum.test \
|
52_unnamed_enum.test \
|
||||||
54_goto.test \
|
54_goto.test \
|
||||||
55_array_initialiser.test
|
55_array_initialiser.test \
|
||||||
|
56_cross_structure.test
|
||||||
|
|
||||||
%.test: %.expect %.c
|
%.test: %.expect %.c
|
||||||
@echo Test: $*...
|
@echo Test: $*...
|
||||||
|
|
18
type.c
18
type.c
|
@ -198,15 +198,18 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
|
||||||
StructIdentifier = PlatformMakeTempName(pc, TempNameBuf);
|
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);
|
Token = LexGetToken(Parser, NULL, FALSE);
|
||||||
if (Token != TokenLeftBrace)
|
if (Token != TokenLeftBrace)
|
||||||
{
|
{
|
||||||
/* use the already defined structure */
|
/* use the already defined structure */
|
||||||
|
#if 0
|
||||||
if ((*Typ)->Members == NULL)
|
if ((*Typ)->Members == NULL)
|
||||||
ProgramFail(Parser, "structure '%s' isn't defined", LexValue->Val->Identifier);
|
ProgramFail(Parser, "structure '%s' isn't defined", LexValue->Val->Identifier);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,3 +530,14 @@ void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identif
|
||||||
TypeParseIdentPart(Parser, BasicType, Typ, Identifier);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -185,6 +185,10 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *
|
||||||
int DeclLine;
|
int DeclLine;
|
||||||
int DeclColumn;
|
int DeclColumn;
|
||||||
|
|
||||||
|
/* is the type a forward declaration? */
|
||||||
|
if (TypeIsForwardDeclared(Parser, Typ))
|
||||||
|
ProgramFail(Parser, "type '%t' isn't defined", Typ);
|
||||||
|
|
||||||
if (IsStatic)
|
if (IsStatic)
|
||||||
{
|
{
|
||||||
char MangledName[LINEBUFFER_MAX];
|
char MangledName[LINEBUFFER_MAX];
|
||||||
|
|
Loading…
Reference in a new issue