Skip to content

Commit

Permalink
move determineSize to dsymbolsem.d (#16969)
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilsonator authored Oct 8, 2024
1 parent 8ce08e9 commit e50f925
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 60 deletions.
62 changes: 2 additions & 60 deletions compiler/src/dmd/aggregate.d
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import dmd.declaration;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dsymbolsem : dsymbolSemantic, determineFields, search;
import dmd.dsymbolsem : dsymbolSemantic, determineFields, search, determineSize;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
Expand Down Expand Up @@ -187,70 +187,12 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
return fields.length - isNested() - (vthis2 !is null);
}

/***************************************
* Collect all instance fields, then determine instance size.
* Returns:
* false if failed to determine the size.
*/
extern (D) final bool determineSize(const ref Loc loc)
{
//printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok);

// The previous instance size finalizing had:
if (type.ty == Terror || errors)
return false; // failed already
if (sizeok == Sizeok.done)
return true; // succeeded

if (!members)
{
.error(loc, "%s `%s` unknown size", kind, toPrettyChars);
return false;
}

if (_scope)
dsymbolSemantic(this, null);

// Determine the instance size of base class first.
if (auto cd = isClassDeclaration())
{
cd = cd.baseClass;
if (cd && !cd.determineSize(loc))
goto Lfail;
}

// Determine instance fields when sizeok == Sizeok.none
if (!this.determineFields())
goto Lfail;
if (sizeok != Sizeok.done)
finalizeSize();

// this aggregate type has:
if (type.ty == Terror)
return false; // marked as invalid during the finalizing.
if (sizeok == Sizeok.done)
return true; // succeeded to calculate instance size.

Lfail:
// There's unresolvable forward reference.
if (type != Type.terror)
error(loc, "%s `%s` no size because of forward reference", kind, toPrettyChars);
// Don't cache errors from speculative semantic, might be resolvable later.
// https://issues.dlang.org/show_bug.cgi?id=16574
if (!global.gag)
{
type = Type.terror;
errors = true;
}
return false;
}

abstract void finalizeSize();

override final uinteger_t size(const ref Loc loc)
{
//printf("+AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
bool ok = determineSize(loc);
bool ok = determineSize(this, loc);
//printf("-AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
return ok ? structsize : SIZE_INVALID;
}
Expand Down
58 changes: 58 additions & 0 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -7647,3 +7647,61 @@ private Expression callScopeDtor(VarDeclaration vd, Scope* sc)
}
return e;
}

/***************************************
* Collect all instance fields, then determine instance size.
* Returns:
* false if failed to determine the size.
*/
bool determineSize(AggregateDeclaration ad, const ref Loc loc)
{
//printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok);

// The previous instance size finalizing had:
if (ad.type.ty == Terror || ad.errors)
return false; // failed already
if (ad.sizeok == Sizeok.done)
return true; // succeeded

if (!ad.members)
{
.error(loc, "%s `%s` unknown size", ad.kind, ad.toPrettyChars);
return false;
}

if (ad._scope)
dsymbolSemantic(ad, null);

// Determine the instance size of base class first.
if (auto cd = ad.isClassDeclaration())
{
cd = cd.baseClass;
if (cd && !cd.determineSize(loc))
goto Lfail;
}

// Determine instance fields when sizeok == Sizeok.none
if (!ad.determineFields())
goto Lfail;
if (ad.sizeok != Sizeok.done)
ad.finalizeSize();

// this aggregate type has:
if (ad.type.ty == Terror)
return false; // marked as invalid during the finalizing.
if (ad.sizeok == Sizeok.done)
return true; // succeeded to calculate instance size.

Lfail:
// There's unresolvable forward reference.
if (ad.type != Type.terror)
error(loc, "%s `%s` no size because of forward reference", ad.kind, ad.toPrettyChars);
// Don't cache errors from speculative semantic, might be resolvable later.
// https://issues.dlang.org/show_bug.cgi?id=16574
if (!global.gag)
{
ad.type = Type.terror;
ad.errors = true;
}
return false;
}
1 change: 1 addition & 0 deletions compiler/src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import dmd.dtemplate;
import dmd.enumsem;
import dmd.errors;
import dmd.expression;
import dmd.dsymbolsem : determineSize;
import dmd.globals;
import dmd.hdrgen;
import dmd.id;
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/safe.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import dmd.dcast : implicitConvTo;
import dmd.dclass;
import dmd.declaration;
import dmd.dscope;
import dmd.dsymbolsem : determineSize;
import dmd.errors;
import dmd.expression;
import dmd.func;
Expand Down

0 comments on commit e50f925

Please sign in to comment.