mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Extract Dsymbol.oneMember to a visitor in dsymbolsem (#20915)
This commit is contained in:
parent
53a1cc8d13
commit
996acb0528
12 changed files with 134 additions and 121 deletions
|
@ -109,12 +109,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol
|
|||
return "attribute";
|
||||
}
|
||||
|
||||
override bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
Dsymbols* d = this.include(null);
|
||||
return Dsymbol.oneMembers(d, ps, ident);
|
||||
}
|
||||
|
||||
override final bool hasPointers()
|
||||
{
|
||||
return this.include(null).foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
|
||||
|
@ -170,32 +164,6 @@ extern (C++) class StorageClassDeclaration : AttribDeclaration
|
|||
return new StorageClassDeclaration(stc, Dsymbol.arraySyntaxCopy(decl));
|
||||
}
|
||||
|
||||
override final bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
bool t = Dsymbol.oneMembers(decl, ps, ident);
|
||||
if (t && ps)
|
||||
{
|
||||
/* This is to deal with the following case:
|
||||
* struct Tick {
|
||||
* template to(T) { const T to() { ... } }
|
||||
* }
|
||||
* For eponymous function templates, the 'const' needs to get attached to 'to'
|
||||
* before the semantic analysis of 'to', so that template overloading based on the
|
||||
* 'this' pointer can be successful.
|
||||
*/
|
||||
if (FuncDeclaration fd = ps.isFuncDeclaration())
|
||||
{
|
||||
/* Use storage_class2 instead of storage_class otherwise when we do .di generation
|
||||
* we'll wind up with 'const const' rather than 'const'.
|
||||
*/
|
||||
/* Don't think we need to worry about mutually exclusive storage classes here
|
||||
*/
|
||||
fd.storage_class2 |= stc;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
override inout(StorageClassDeclaration) isStorageClassDeclaration() inout
|
||||
{
|
||||
return this;
|
||||
|
@ -591,22 +559,6 @@ extern (C++) class ConditionalDeclaration : AttribDeclaration
|
|||
return new ConditionalDeclaration(loc, condition.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl), Dsymbol.arraySyntaxCopy(elsedecl));
|
||||
}
|
||||
|
||||
override final bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc);
|
||||
if (condition.inc != Include.notComputed)
|
||||
{
|
||||
Dsymbols* d = condition.include(null) ? decl : elsedecl;
|
||||
return Dsymbol.oneMembers(d, ps, ident);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool res = (Dsymbol.oneMembers(decl, ps, ident) && ps is null && Dsymbol.oneMembers(elsedecl, ps, ident) && ps is null);
|
||||
ps = null;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
override void accept(Visitor v)
|
||||
{
|
||||
v.visit(this);
|
||||
|
@ -687,21 +639,6 @@ extern (C++) final class StaticForeachDeclaration : AttribDeclaration
|
|||
Dsymbol.arraySyntaxCopy(decl));
|
||||
}
|
||||
|
||||
override bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
// Required to support IFTI on a template that contains a
|
||||
// `static foreach` declaration. `super.oneMember` calls
|
||||
// include with a `null` scope. As `static foreach` requires
|
||||
// the scope for expansion, `oneMember` can only return a
|
||||
// precise result once `static foreach` has been expanded.
|
||||
if (cached)
|
||||
{
|
||||
return super.oneMember(ps, ident);
|
||||
}
|
||||
ps = null; // a `static foreach` declaration may in general expand to multiple symbols
|
||||
return false;
|
||||
}
|
||||
|
||||
override const(char)* kind() const
|
||||
{
|
||||
return "static foreach";
|
||||
|
|
|
@ -29,7 +29,6 @@ class AttribDeclaration : public Dsymbol
|
|||
public:
|
||||
Dsymbols *decl; // array of Dsymbol's
|
||||
const char *kind() const override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
bool hasPointers() override final;
|
||||
bool hasStaticCtorOrDtor() override final;
|
||||
AttribDeclaration *isAttribDeclaration() override { return this; }
|
||||
|
@ -43,7 +42,6 @@ public:
|
|||
StorageClass stc;
|
||||
|
||||
StorageClassDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override final;
|
||||
StorageClassDeclaration *isStorageClassDeclaration() override { return this; }
|
||||
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
|
@ -142,7 +140,6 @@ public:
|
|||
Dsymbols *elsedecl; // array of Dsymbol's for else block
|
||||
|
||||
ConditionalDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override final;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
||||
|
@ -169,7 +166,6 @@ public:
|
|||
Dsymbols *cache;
|
||||
|
||||
StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
const char *kind() const override;
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
};
|
||||
|
|
|
@ -81,13 +81,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
|
|||
return ed;
|
||||
}
|
||||
|
||||
override bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
if (isAnonymous())
|
||||
return Dsymbol.oneMembers(members, ps, ident);
|
||||
return Dsymbol.oneMember(ps, ident);
|
||||
}
|
||||
|
||||
override Type getType()
|
||||
{
|
||||
return type;
|
||||
|
|
|
@ -51,6 +51,7 @@ import dmd.statement;
|
|||
import dmd.staticassert;
|
||||
import dmd.tokens;
|
||||
import dmd.visitor;
|
||||
import dmd.dsymbolsem;
|
||||
|
||||
import dmd.common.outbuffer;
|
||||
|
||||
|
@ -820,20 +821,6 @@ extern (C++) class Dsymbol : ASTNode
|
|||
assert(0);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Determine if this symbol is only one.
|
||||
* Returns:
|
||||
* false, ps = null: There are 2 or more symbols
|
||||
* true, ps = null: There are zero symbols
|
||||
* true, ps = symbol: The one and only one symbol
|
||||
*/
|
||||
bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
//printf("Dsymbol::oneMember()\n");
|
||||
ps = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Same as Dsymbol::oneMember(), but look at an array of Dsymbols.
|
||||
*/
|
||||
|
@ -850,7 +837,7 @@ extern (C++) class Dsymbol : ASTNode
|
|||
for (size_t i = 0; i < members.length; i++)
|
||||
{
|
||||
Dsymbol sx = (*members)[i];
|
||||
bool x = sx.oneMember(ps, ident);
|
||||
bool x = sx.oneMember(ps, ident); //MYTODO: this temporarily creates a new dependency to dsymbolsem, will need to extract oneMembers() later
|
||||
//printf("\t[%d] kind %s = %d, s = %p\n", i, sx.kind(), x, *ps);
|
||||
if (!x)
|
||||
{
|
||||
|
|
|
@ -237,7 +237,6 @@ public:
|
|||
virtual bool needThis(); // need a 'this' pointer?
|
||||
virtual Visibility visible();
|
||||
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
virtual bool oneMember(Dsymbol *&ps, Identifier *ident);
|
||||
virtual bool hasPointers();
|
||||
virtual bool hasStaticCtorOrDtor();
|
||||
virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { }
|
||||
|
@ -433,4 +432,5 @@ namespace dmd
|
|||
void setScope(Dsymbol *d, Scope *sc);
|
||||
void importAll(Dsymbol *d, Scope *sc);
|
||||
void addComment(Dsymbol *d, const char *comment);
|
||||
bool oneMember(Dsymbol *d, Dsymbol *&ps, Identifier *ident);
|
||||
}
|
||||
|
|
|
@ -7967,3 +7967,134 @@ private extern(C++) class CheckCtorConstInitVisitor : Visitor
|
|||
|
||||
override void visit(Dsymbol d){}
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Determine if this symbol is only one.
|
||||
* Returns:
|
||||
* false, ps = null: There are 2 or more symbols
|
||||
* true, ps = null: There are zero symbols
|
||||
* true, ps = symbol: The one and only one symbol
|
||||
*/
|
||||
bool oneMember(Dsymbol d, out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
scope v = new OneMemberVisitor(ps, ident);
|
||||
d.accept(v);
|
||||
return v.result;
|
||||
}
|
||||
|
||||
private extern(C++) class OneMemberVisitor : Visitor
|
||||
{
|
||||
alias visit = Visitor.visit;
|
||||
|
||||
Dsymbol* ps;
|
||||
Identifier ident;
|
||||
bool result;
|
||||
|
||||
this(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
this.ps = &ps;
|
||||
this.ident = ident;
|
||||
}
|
||||
|
||||
override void visit(AttribDeclaration atb)
|
||||
{
|
||||
Dsymbols* d = atb.include(null);
|
||||
result = Dsymbol.oneMembers(d, *ps, ident);
|
||||
}
|
||||
|
||||
override void visit(StaticForeachDeclaration sfd)
|
||||
{
|
||||
// Required to support IFTI on a template that contains a
|
||||
// `static foreach` declaration. `super.oneMember` calls
|
||||
// include with a `null` scope. As `static foreach` requires
|
||||
// the scope for expansion, `oneMember` can only return a
|
||||
// precise result once `static foreach` has been expanded.
|
||||
if (sfd.cached)
|
||||
{
|
||||
this.visit(cast(AttribDeclaration) sfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ps = null; // a `static foreach` declaration may in general expand to multiple symbols
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
override void visit(StorageClassDeclaration scd)
|
||||
{
|
||||
bool t = Dsymbol.oneMembers(scd.decl, *ps, ident);
|
||||
if (t && *ps)
|
||||
{
|
||||
/* This is to deal with the following case:
|
||||
* struct Tick {
|
||||
* template to(T) { const T to() { ... } }
|
||||
* }
|
||||
* For eponymous function templates, the 'const' needs to get attached to 'to'
|
||||
* before the semantic analysis of 'to', so that template overloading based on the
|
||||
* 'this' pointer can be successful.
|
||||
*/
|
||||
if (FuncDeclaration fd = (*ps).isFuncDeclaration())
|
||||
{
|
||||
/* Use storage_class2 instead of storage_class otherwise when we do .di generation
|
||||
* we'll wind up with 'const const' rather than 'const'.
|
||||
*/
|
||||
/* Don't think we need to worry about mutually exclusive storage classes here
|
||||
*/
|
||||
fd.storage_class2 |= scd.stc;
|
||||
}
|
||||
}
|
||||
result = t;
|
||||
}
|
||||
|
||||
override void visit(ConditionalDeclaration cd)
|
||||
{
|
||||
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc);
|
||||
if (cd.condition.inc != Include.notComputed)
|
||||
{
|
||||
Dsymbols* d = cd.condition.include(null) ? cd.decl : cd.elsedecl;
|
||||
result = Dsymbol.oneMembers(d, *ps, ident);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool res = (Dsymbol.oneMembers(cd.decl, *ps, ident) && *ps is null && Dsymbol.oneMembers(cd.elsedecl, *ps, ident) && *ps is null);
|
||||
*ps = null;
|
||||
result = res;
|
||||
}
|
||||
}
|
||||
|
||||
override void visit(ScopeDsymbol sd)
|
||||
{
|
||||
if (sd.isAnonymous())
|
||||
result = Dsymbol.oneMembers(sd.members, *ps, ident);
|
||||
else {
|
||||
// visit(Dsymbol dsym)
|
||||
*ps = sd;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
override void visit(StaticAssert sa)
|
||||
{
|
||||
//printf("StaticAssert::oneMember())\n");
|
||||
*ps = null;
|
||||
result = true;
|
||||
}
|
||||
|
||||
override void visit(TemplateInstance ti)
|
||||
{
|
||||
*ps = null;
|
||||
result = true;
|
||||
}
|
||||
|
||||
override void visit(TemplateMixin tm)
|
||||
{
|
||||
*ps = tm;
|
||||
result = true;
|
||||
}
|
||||
|
||||
override void visit(Dsymbol dsym)
|
||||
{
|
||||
*ps = dsym;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3823,12 +3823,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol
|
|||
return "template instance";
|
||||
}
|
||||
|
||||
override bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
ps = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
override final const(char)* toPrettyCharsHelper()
|
||||
{
|
||||
OutBuffer buf;
|
||||
|
@ -5505,11 +5499,6 @@ extern (C++) final class TemplateMixin : TemplateInstance
|
|||
return "mixin";
|
||||
}
|
||||
|
||||
override bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
return Dsymbol.oneMember(ps, ident);
|
||||
}
|
||||
|
||||
override bool hasPointers()
|
||||
{
|
||||
//printf("TemplateMixin.hasPointers() %s\n", toChars());
|
||||
|
|
|
@ -52,7 +52,6 @@ public:
|
|||
bool inuse(bool v);
|
||||
|
||||
EnumDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
Type *getType() override;
|
||||
const char *kind() const override;
|
||||
bool isDeprecated() const override; // is Dsymbol deprecated?
|
||||
|
|
|
@ -510,7 +510,6 @@ public:
|
|||
virtual bool needThis();
|
||||
virtual Visibility visible();
|
||||
virtual Dsymbol* syntaxCopy(Dsymbol* s);
|
||||
virtual bool oneMember(Dsymbol*& ps, Identifier* ident);
|
||||
virtual bool hasPointers();
|
||||
virtual bool hasStaticCtorOrDtor();
|
||||
virtual void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories);
|
||||
|
@ -1632,7 +1631,6 @@ public:
|
|||
TemplateInstance* syntaxCopy(Dsymbol* s) override;
|
||||
Dsymbol* toAlias() final override;
|
||||
const char* kind() const override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) override;
|
||||
const char* toPrettyCharsHelper() final override;
|
||||
Identifier* getIdent() final override;
|
||||
bool equalsx(TemplateInstance* ti);
|
||||
|
@ -1657,7 +1655,6 @@ public:
|
|||
TypeQualified* tqual;
|
||||
TemplateInstance* syntaxCopy(Dsymbol* s) override;
|
||||
const char* kind() const override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) override;
|
||||
bool hasPointers() override;
|
||||
TemplateMixin* isTemplateMixin() override;
|
||||
void accept(Visitor* v) override;
|
||||
|
@ -5378,7 +5375,6 @@ public:
|
|||
Expression* exp;
|
||||
Array<Expression* >* msgs;
|
||||
StaticAssert* syntaxCopy(Dsymbol* s) override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) override;
|
||||
const char* kind() const override;
|
||||
StaticAssert* isStaticAssert() override;
|
||||
void accept(Visitor* v) override;
|
||||
|
@ -6330,7 +6326,6 @@ class AttribDeclaration : public Dsymbol
|
|||
public:
|
||||
Array<Dsymbol* >* decl;
|
||||
const char* kind() const override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) override;
|
||||
bool hasPointers() final override;
|
||||
bool hasStaticCtorOrDtor() final override;
|
||||
void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories) final override;
|
||||
|
@ -6343,7 +6338,6 @@ class StorageClassDeclaration : public AttribDeclaration
|
|||
public:
|
||||
StorageClass stc;
|
||||
StorageClassDeclaration* syntaxCopy(Dsymbol* s) override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) final override;
|
||||
StorageClassDeclaration* isStorageClassDeclaration() override;
|
||||
void accept(Visitor* v) override;
|
||||
};
|
||||
|
@ -6433,7 +6427,6 @@ public:
|
|||
Condition* condition;
|
||||
Array<Dsymbol* >* elsedecl;
|
||||
ConditionalDeclaration* syntaxCopy(Dsymbol* s) override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) final override;
|
||||
void accept(Visitor* v) override;
|
||||
};
|
||||
|
||||
|
@ -6458,7 +6451,6 @@ public:
|
|||
bool cached;
|
||||
Array<Dsymbol* >* cache;
|
||||
StaticForeachDeclaration* syntaxCopy(Dsymbol* s) override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) override;
|
||||
const char* kind() const override;
|
||||
void accept(Visitor* v) override;
|
||||
};
|
||||
|
@ -7011,7 +7003,6 @@ private:
|
|||
public:
|
||||
Symbol* sinit;
|
||||
EnumDeclaration* syntaxCopy(Dsymbol* s) override;
|
||||
bool oneMember(Dsymbol*& ps, Identifier* ident) override;
|
||||
Type* getType() override;
|
||||
const char* kind() const override;
|
||||
bool isDeprecated() const override;
|
||||
|
|
|
@ -49,13 +49,6 @@ extern (C++) final class StaticAssert : Dsymbol
|
|||
return new StaticAssert(loc, exp.syntaxCopy(), msgs ? Expression.arraySyntaxCopy(msgs) : null);
|
||||
}
|
||||
|
||||
override bool oneMember(out Dsymbol ps, Identifier ident)
|
||||
{
|
||||
//printf("StaticAssert::oneMember())\n");
|
||||
ps = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
override const(char)* kind() const
|
||||
{
|
||||
return "static assert";
|
||||
|
|
|
@ -21,7 +21,6 @@ public:
|
|||
Expressions *msg;
|
||||
|
||||
StaticAssert *syntaxCopy(Dsymbol *s) override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
const char *kind() const override;
|
||||
StaticAssert *isStaticAssert() override { return this; }
|
||||
void accept(Visitor *v) override { v->visit(this); }
|
||||
|
|
|
@ -270,7 +270,6 @@ public:
|
|||
TemplateInstance *syntaxCopy(Dsymbol *) override;
|
||||
Dsymbol *toAlias() override final; // resolve real symbol
|
||||
const char *kind() const override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
const char* toPrettyCharsHelper() override final;
|
||||
Identifier *getIdent() override final;
|
||||
|
||||
|
@ -288,7 +287,6 @@ public:
|
|||
|
||||
TemplateMixin *syntaxCopy(Dsymbol *s) override;
|
||||
const char *kind() const override;
|
||||
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
|
||||
bool hasPointers() override;
|
||||
|
||||
TemplateMixin *isTemplateMixin() override { return this; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue