Line 291... |
Line 291... |
const Specifier spec = typespec->GetType();
|
const Specifier spec = typespec->GetType();
|
|
|
assert(!(spec & SC_TYPEDEF));
|
assert(!(spec & SC_TYPEDEF));
|
assert(!(spec & SC_EXTERN));
|
assert(!(spec & SC_EXTERN));
|
|
|
const int size = typespec->GetSize(declarator);
|
|
const char * name = ::GetDeclaredName(declarator);
|
const char * name = ::GetDeclaredName(declarator);
|
assert(name);
|
assert(name);
|
|
|
Name::SetAutoPos(name, Backend::GetSP() - size);
|
int size = type.GetSize();
|
|
if (size < 0) // a[]
|
const int ret = typespec->GetSize(declarator);
|
|
if (ret < 0)
|
|
{
|
{
|
type.Print(stderr);
|
if (initializer == 0)
|
assert(0);
|
{
|
|
fprintf(stderr, "Can't use [] without initializer\n");
|
|
semantic_errors++;
|
|
size = 2;
|
}
|
}
|
|
else
|
|
{
|
|
TypeName * etype = type.GetElementType();
|
|
assert(etype);
|
|
size = initializer->ElementCount() * etype->GetSize();
|
|
assert(size > 0);
|
|
}
|
|
}
|
|
Name::SetAutoPos(name, Backend::GetSP() - size);
|
|
|
if (initializer) initializer->InitAutovar(out, type.GetSUW());
|
if (initializer) initializer->InitAutovar(out, &type);
|
else Backend::push_zero(ret);
|
else Backend::push_zero(size);
|
|
|
EmitEnd(out);
|
EmitEnd(out);
|
return ret;
|
return size;
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
void InitDeclarator::Allocate(FILE * out, TypeSpecifier * typespec)
|
void InitDeclarator::Allocate(FILE * out, TypeSpecifier * typespec)
|
{
|
{
|
const Specifier spec = typespec->GetType();
|
const Specifier spec = typespec->GetType();
|
Line 437... |
Line 446... |
EmitStart(out);
|
EmitStart(out);
|
if (decl_specs) decl_specs->Emit(out);
|
if (decl_specs) decl_specs->Emit(out);
|
EmitEnd(out);
|
EmitEnd(out);
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
int Initializer::ElementCount() const
|
|
{
|
|
if (skalar_value) return 1;
|
|
return InitializerList::Length(array_value);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
void Initializer::Emit(FILE * out)
|
void Initializer::Emit(FILE * out)
|
{
|
{
|
// debug only: must call EmitValue() or EmitAutovars()
|
// debug only: must call EmitValue() or EmitAutovars()
|
EmitStart(out);
|
EmitStart(out);
|
if (skalar_value) skalar_value->Emit(out);
|
if (skalar_value) skalar_value->Emit(out);
|
Line 448... |
Line 463... |
EmitEnd(out);
|
EmitEnd(out);
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
void Initializer::EmitValue(FILE * out, TypeName * tn)
|
void Initializer::EmitValue(FILE * out, TypeName * tn)
|
{
|
{
|
if (tn->IsUnion())
|
while (tn->IsUnion())
|
{
|
{
|
int union_size = tn->GetSize();
|
int union_size = tn->GetSize();
|
TypeName * first = tn->FirstUnionMember(union_size);
|
TypeName * first = tn->FirstUnionMember(union_size);
|
if (first) EmitValue(out, first);
|
assert(first);
|
return;
|
tn = first;
|
}
|
}
|
|
|
if (skalar_value)
|
if (skalar_value)
|
{
|
{
|
if (tn->IsArray()) // char x[] = "abc" ?
|
if (tn->IsArray()) // char x[] = "abc" ?
|
Line 624... |
Line 639... |
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
int Initializer::InitAutovar(FILE * out, SUW suw)
|
int Initializer::InitAutovar(FILE * out, TypeName * type)
|
{
|
{
|
int ret = 0;
|
int ret = 0;
|
|
|
assert( skalar_value || array_value);
|
|
assert(!skalar_value || !array_value);
|
|
|
|
EmitStart(out);
|
EmitStart(out);
|
|
|
|
while (type->IsUnion())
|
|
{
|
|
int union_size = type->GetSize();
|
|
TypeName * first = type->FirstUnionMember(union_size);
|
|
assert(first);
|
|
type = first;
|
|
}
|
|
|
if (skalar_value)
|
if (skalar_value)
|
{
|
{
|
|
assert(!array_value);
|
|
|
|
if (type->GetSize() > 2) // fixme: check for valid size
|
|
{
|
|
fprintf(stderr, "Initialization of compound type with skalar\n");
|
|
semantic_errors++;
|
|
return 2;
|
|
}
|
|
|
|
SUW suw = type->GetSUW();
|
ret = 1; if (suw == WO) ret = 2;
|
ret = 1; if (suw == WO) ret = 2;
|
|
|
if (skalar_value->IsNumericConstant())
|
if (skalar_value->IsNumericConstant())
|
{
|
{
|
int value = skalar_value->GetConstantNumericValue();
|
int value = skalar_value->GetConstantNumericValue();
|
Line 655... |
Line 685... |
else
|
else
|
{
|
{
|
skalar_value->Emit(out);
|
skalar_value->Emit(out);
|
Backend::push_rr(suw);
|
Backend::push_rr(suw);
|
}
|
}
|
|
EmitEnd(out);
|
|
return ret;
|
|
}
|
|
|
|
|
|
assert(array_value);
|
|
|
|
// array or struct...
|
|
// check for array
|
|
//
|
|
//
|
|
ret = type->GetSize();
|
|
InitializerList * arev = array_value->Reverse();
|
|
int alen = InitializerList::Length(arev);
|
|
|
|
if (type->IsArray())
|
|
{
|
|
TypeName * etype = type->GetElementType();
|
|
int esize = etype->GetSize();
|
|
Expression * lenexpr = type->ArrayLength();
|
|
int len = alen;
|
|
if (lenexpr) len = lenexpr->GetConstantNumericValue();
|
|
|
|
if (alen > len)
|
|
{
|
|
fprintf(stderr, "Too many array initializer\n");
|
|
semantic_errors++;
|
|
return ret;
|
}
|
}
|
else
|
|
|
for (; alen < len; len--)
|
{
|
{
|
fprintf(stderr, "TODO: aggregate initializer\r\n");
|
Backend::push_zero(esize);
|
|
}
|
|
|
|
for (; arev; arev = arev->Tail())
|
|
{
|
|
Initializer * ini = arev->Head();
|
|
assert(ini);
|
|
ini->InitAutovar(out, etype);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// struct...
|
|
//
|
|
if (!type->IsStruct())
|
|
{
|
|
fprintf(stderr, "Initialization of skalar type with array\n");
|
|
semantic_errors++;
|
|
return ret;
|
|
}
|
|
|
|
TypeSpecifier * ts = type->GetTypeSpecifier();
|
|
assert(ts);
|
|
|
|
const char * sname = ts->GetName();
|
|
if (sname == 0)
|
|
{
|
|
fprintf(stderr, "No struct name in struct initializer\n");
|
|
semantic_errors++;
|
|
return 2;
|
|
}
|
|
|
|
StructDeclarationList * sdl = StructName::Find(sname);
|
|
if (sdl == 0)
|
|
{
|
|
fprintf(stderr, "No struct %s defined\n", sname);
|
|
semantic_errors++;
|
|
return 2;
|
|
}
|
|
|
|
// compute member count...
|
|
//
|
|
int len = 0;
|
|
for (StructDeclarationList * s = sdl; s; s = s->Tail())
|
|
{
|
|
StructDeclaration * sd = s->Head();
|
|
assert(sd);
|
|
len += sd->GetDeclaratorCount();
|
|
}
|
|
|
|
if (alen > len)
|
|
{
|
|
fprintf(stderr, "Too many struct initializer\n");
|
|
semantic_errors++;
|
|
return ret;
|
|
}
|
|
|
|
while (alen < len) // uninitialized members
|
|
{
|
|
TypeName * tn = GetMemberType(sdl, --len);
|
|
assert(tn);
|
|
Backend::push_zero(tn->GetSize());
|
|
}
|
|
|
|
while (len) // uninitialized members
|
|
{
|
|
TypeName * tn = GetMemberType(sdl, --len);
|
|
assert(tn);
|
|
|
|
assert(arev);
|
|
Initializer * ini = arev->Head();
|
|
assert(ini);
|
|
arev = arev->Tail();
|
|
ini->InitAutovar(out, tn);
|
}
|
}
|
|
|
EmitEnd(out);
|
EmitEnd(out);
|
return ret;
|
return ret;
|
}
|
}
|
Line 737... |
Line 869... |
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
TypeName * StructDeclaration::GetMemberType(int pos)
|
|
{
|
|
for (StructDeclaratorList * sl = struct_decl_list; sl ; sl = sl->Tail())
|
|
{
|
|
StructDeclarator * sd = sl->Head();
|
|
assert(sd);
|
|
|
|
if (pos == 0) return new TypeName(decl_specifiers,
|
|
sd->GetDeclarator());
|
|
--pos;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
TypeName * StructDeclaration::FirstUnionMember(int union_size) const
|
TypeName * StructDeclaration::FirstUnionMember(int union_size) const
|
{
|
{
|
for (StructDeclaratorList * sl = struct_decl_list; sl ; sl = sl->Tail())
|
for (StructDeclaratorList * sl = struct_decl_list; sl ; sl = sl->Tail())
|
{
|
{
|
StructDeclarator * sd = sl->Head();
|
StructDeclarator * sd = sl->Head();
|
Line 1266... |
Line 1413... |
{
|
{
|
fprintf(stderr, "---- Size not 1 or 2:\n");
|
fprintf(stderr, "---- Size not 1 or 2:\n");
|
Emit(stderr);
|
Emit(stderr);
|
fprintf(stderr, "\n====\n");
|
fprintf(stderr, "\n====\n");
|
*(char*)0 = 0;
|
*(char*)0 = 0;
|
|
// for (;;) fprintf(stderr, "?");
|
fprintf(stderr, "\n====\n");
|
fprintf(stderr, "\n====\n");
|
}
|
}
|
assert(size == 1);
|
assert(size == 1);
|
if (IsUnsigned()) return UB;
|
if (IsUnsigned()) return UB;
|
return SB;
|
return SB;
|
Line 1689... |
Line 1837... |
|
|
fprintf(stderr, "Can't get parameters of undeclared function\n");
|
fprintf(stderr, "Can't get parameters of undeclared function\n");
|
return 0;
|
return 0;
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
TypeName * GetMemberType(StructDeclarationList * sdl, int pos)
|
|
{
|
|
for (; sdl; sdl = sdl->Tail())
|
|
{
|
|
StructDeclaration * sd = sdl->Head();
|
|
int count = sd->GetDeclaratorCount();
|
|
if (pos < count) return sd->GetMemberType(pos);
|
|
|
|
pos -= count;
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
No newline at end of file
|
No newline at end of file
|