mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Extracted ClassDeclaration.isAbstract to dsymbolsem (#21131)
This commit is contained in:
parent
d7dce783a7
commit
3106359a2b
8 changed files with 111 additions and 107 deletions
|
@ -293,7 +293,6 @@ public:
|
|||
virtual bool isCOMinterface() const;
|
||||
bool isCPPclass() const;
|
||||
virtual bool isCPPinterface() const;
|
||||
bool isAbstract();
|
||||
virtual int vtblOffset() const;
|
||||
const char *kind() const override;
|
||||
|
||||
|
|
|
@ -192,6 +192,12 @@ Dsymbol vtblSymbol(ClassDeclaration cd)
|
|||
return dmd.dsymbolsem.vtblSymbol(cd);
|
||||
}
|
||||
|
||||
bool isAbstract(ClassDeclaration cd)
|
||||
{
|
||||
import dmd.dsymbolsem;
|
||||
return dmd.dsymbolsem.isAbstract(cd);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* dtemplate.d
|
||||
*/
|
||||
|
|
|
@ -23,7 +23,7 @@ import dmd.gluelayer;
|
|||
import dmd.declaration;
|
||||
import dmd.dscope;
|
||||
import dmd.dsymbol;
|
||||
import dmd.dsymbolsem : dsymbolSemantic, addMember, setFieldOffset;
|
||||
import dmd.dsymbolsem : setFieldOffset;
|
||||
import dmd.errors;
|
||||
import dmd.func;
|
||||
import dmd.id;
|
||||
|
@ -33,7 +33,6 @@ import dmd.mtype;
|
|||
import dmd.objc;
|
||||
import dmd.root.rmem;
|
||||
import dmd.target;
|
||||
import dmd.typesem : covariant, immutableOf, sarrayOf;
|
||||
import dmd.visitor;
|
||||
|
||||
/***********************************************************
|
||||
|
@ -757,106 +756,6 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
|
|||
return false;
|
||||
}
|
||||
|
||||
/****************************************
|
||||
*/
|
||||
final bool isAbstract()
|
||||
{
|
||||
enum log = false;
|
||||
if (isabstract != ThreeState.none)
|
||||
return isabstract == ThreeState.yes;
|
||||
|
||||
if (log) printf("isAbstract(%s)\n", toChars());
|
||||
|
||||
bool no() { if (log) printf("no\n"); isabstract = ThreeState.no; return false; }
|
||||
bool yes() { if (log) printf("yes\n"); isabstract = ThreeState.yes; return true; }
|
||||
|
||||
if (storage_class & STC.abstract_ || _scope && _scope.stc & STC.abstract_)
|
||||
return yes();
|
||||
|
||||
if (errors)
|
||||
return no();
|
||||
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=11169
|
||||
* Resolve forward references to all class member functions,
|
||||
* and determine whether this class is abstract.
|
||||
*/
|
||||
static int func(Dsymbol s, void*)
|
||||
{
|
||||
auto fd = s.isFuncDeclaration();
|
||||
if (!fd)
|
||||
return 0;
|
||||
if (fd.storage_class & STC.static_)
|
||||
return 0;
|
||||
|
||||
if (fd.isAbstract())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// opaque class is not abstract if it is not declared abstract
|
||||
if (!members)
|
||||
return no();
|
||||
|
||||
for (size_t i = 0; i < members.length; i++)
|
||||
{
|
||||
auto s = (*members)[i];
|
||||
if (s.apply(&func, null))
|
||||
{
|
||||
return yes();
|
||||
}
|
||||
}
|
||||
|
||||
/* If the base class is not abstract, then this class cannot
|
||||
* be abstract.
|
||||
*/
|
||||
if (!isInterfaceDeclaration() && (!baseClass || !baseClass.isAbstract()))
|
||||
return no();
|
||||
|
||||
/* If any abstract functions are inherited, but not overridden,
|
||||
* then the class is abstract. Do this by checking the vtbl[].
|
||||
* Need to do semantic() on class to fill the vtbl[].
|
||||
*/
|
||||
this.dsymbolSemantic(null);
|
||||
|
||||
/* The next line should work, but does not because when ClassDeclaration.dsymbolSemantic()
|
||||
* is called recursively it can set PASS.semanticdone without finishing it.
|
||||
*/
|
||||
//if (semanticRun < PASS.semanticdone)
|
||||
{
|
||||
/* Could not complete semantic(). Try running semantic() on
|
||||
* each of the virtual functions,
|
||||
* which will fill in the vtbl[] overrides.
|
||||
*/
|
||||
static int virtualSemantic(Dsymbol s, void*)
|
||||
{
|
||||
auto fd = s.isFuncDeclaration();
|
||||
if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
|
||||
fd.dsymbolSemantic(null);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < members.length; i++)
|
||||
{
|
||||
auto s = (*members)[i];
|
||||
s.apply(&virtualSemantic,null);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, check the vtbl[]
|
||||
*/
|
||||
foreach (i; 1 .. vtbl.length)
|
||||
{
|
||||
auto fd = vtbl[i].isFuncDeclaration();
|
||||
//if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd.loc.toChars(), fd.toPrettyChars());
|
||||
if (!fd || fd.isAbstract())
|
||||
{
|
||||
return yes();
|
||||
}
|
||||
}
|
||||
|
||||
return no();
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Determine if slot 0 of the vtbl[] is reserved for something else.
|
||||
* For class objects, yes, this is where the classinfo ptr goes.
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace dmd
|
|||
PURE isPure(FuncDeclaration *f);
|
||||
FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
|
||||
FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
|
||||
bool isAbstract(ClassDeclaration *cd);
|
||||
}
|
||||
|
||||
//enum STC : ulong from astenums.d:
|
||||
|
|
|
@ -8210,3 +8210,101 @@ Dsymbol vtblSymbol(ClassDeclaration cd)
|
|||
}
|
||||
return cd.vtblsym;
|
||||
}
|
||||
|
||||
extern(C++) bool isAbstract(ClassDeclaration cd)
|
||||
{
|
||||
enum log = false;
|
||||
if (cd.isabstract != ThreeState.none)
|
||||
return cd.isabstract == ThreeState.yes;
|
||||
|
||||
if (log) printf("isAbstract(%s)\n", cd.toChars());
|
||||
|
||||
bool no() { if (log) printf("no\n"); cd.isabstract = ThreeState.no; return false; }
|
||||
bool yes() { if (log) printf("yes\n"); cd.isabstract = ThreeState.yes; return true; }
|
||||
|
||||
if (cd.storage_class & STC.abstract_ || cd._scope && cd._scope.stc & STC.abstract_)
|
||||
return yes();
|
||||
|
||||
if (cd.errors)
|
||||
return no();
|
||||
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=11169
|
||||
* Resolve forward references to all class member functions,
|
||||
* and determine whether this class is abstract.
|
||||
*/
|
||||
static int func(Dsymbol s, void*)
|
||||
{
|
||||
auto fd = s.isFuncDeclaration();
|
||||
if (!fd)
|
||||
return 0;
|
||||
if (fd.storage_class & STC.static_)
|
||||
return 0;
|
||||
|
||||
if (fd.isAbstract())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// opaque class is not abstract if it is not declared abstract
|
||||
if (!(cd.members))
|
||||
return no();
|
||||
|
||||
for (size_t i = 0; i < cd.members.length; i++)
|
||||
{
|
||||
auto s = (*(cd.members))[i];
|
||||
if (s.apply(&func, null))
|
||||
{
|
||||
return yes();
|
||||
}
|
||||
}
|
||||
|
||||
/* If the base class is not abstract, then this class cannot
|
||||
* be abstract.
|
||||
*/
|
||||
if (!cd.isInterfaceDeclaration() && (!cd.baseClass || !cd.baseClass.isAbstract()))
|
||||
return no();
|
||||
|
||||
/* If any abstract functions are inherited, but not overridden,
|
||||
* then the class is abstract. Do this by checking the vtbl[].
|
||||
* Need to do semantic() on class to fill the vtbl[].
|
||||
*/
|
||||
cd.dsymbolSemantic(null);
|
||||
|
||||
/* The next line should work, but does not because when ClassDeclaration.dsymbolSemantic()
|
||||
* is called recursively it can set PASS.semanticdone without finishing it.
|
||||
*/
|
||||
//if (semanticRun < PASS.semanticdone)
|
||||
{
|
||||
/* Could not complete semantic(). Try running semantic() on
|
||||
* each of the virtual functions,
|
||||
* which will fill in the vtbl[] overrides.
|
||||
*/
|
||||
static int virtualSemantic(Dsymbol s, void*)
|
||||
{
|
||||
auto fd = s.isFuncDeclaration();
|
||||
if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
|
||||
fd.dsymbolSemantic(null);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < cd.members.length; i++)
|
||||
{
|
||||
auto s = (*(cd.members))[i];
|
||||
s.apply(&virtualSemantic,null);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, check the vtbl[]
|
||||
*/
|
||||
foreach (i; 1 .. cd.vtbl.length)
|
||||
{
|
||||
auto fd = cd.vtbl[i].isFuncDeclaration();
|
||||
//if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd.loc.toChars(), fd.toPrettyChars());
|
||||
if (!fd || fd.isAbstract())
|
||||
{
|
||||
return yes();
|
||||
}
|
||||
}
|
||||
|
||||
return no();
|
||||
}
|
||||
|
|
|
@ -6707,7 +6707,6 @@ public:
|
|||
virtual bool isCOMinterface() const;
|
||||
bool isCPPclass() const;
|
||||
virtual bool isCPPinterface() const;
|
||||
bool isAbstract();
|
||||
virtual int32_t vtblOffset() const;
|
||||
const char* kind() const override;
|
||||
void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories) final override;
|
||||
|
@ -7569,6 +7568,8 @@ extern bool hasStaticCtorOrDtor(Dsymbol* d);
|
|||
|
||||
extern bool isFuncHidden(ClassDeclaration* cd, FuncDeclaration* fd);
|
||||
|
||||
extern bool isAbstract(ClassDeclaration* cd);
|
||||
|
||||
extern void lowerNonArrayAggregate(StaticForeach* sfe, Scope* sc);
|
||||
|
||||
extern int32_t include(Condition* c, Scope* sc);
|
||||
|
|
|
@ -35,7 +35,7 @@ import dmd.dmodule;
|
|||
import dmd.dscope;
|
||||
import dmd.dstruct;
|
||||
import dmd.dsymbol;
|
||||
import dmd.dsymbolsem : hasStaticCtorOrDtor, include, isFuncHidden;
|
||||
import dmd.dsymbolsem : hasStaticCtorOrDtor, include, isFuncHidden, isAbstract;
|
||||
import dmd.dtemplate;
|
||||
import dmd.errors;
|
||||
import dmd.errorsink;
|
||||
|
|
|
@ -1325,7 +1325,7 @@ public:
|
|||
for (size_t i = d->vtblOffset(); i < d->vtbl.length; i++)
|
||||
{
|
||||
FuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration();
|
||||
if (!fd || (!fd->fbody && d->isAbstract()))
|
||||
if (!fd || (!fd->fbody && dmd::isAbstract(d)))
|
||||
continue;
|
||||
if (!dmd::functionSemantic(fd))
|
||||
return;
|
||||
|
@ -1403,7 +1403,7 @@ public:
|
|||
for (size_t i = d->vtblOffset(); i < d->vtbl.length; i++)
|
||||
{
|
||||
FuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration();
|
||||
if (fd && (fd->fbody || !d->isAbstract()))
|
||||
if (fd && (fd->fbody || !dmd::isAbstract(d)))
|
||||
visitDeclaration(fd);
|
||||
}
|
||||
d->type->accept(this);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue