]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/denum.c
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/enum.c
11 #include "root/dsystem.h"
12 #include "root/root.h"
20 #include "expression.h"
22 #include "declaration.h"
25 /********************************* EnumDeclaration ****************************/
27 EnumDeclaration::EnumDeclaration(Loc loc
, Identifier
*id
, Type
*memtype
)
30 //printf("EnumDeclaration() %s\n", toChars());
32 type
= new TypeEnum(this);
33 this->memtype
= memtype
;
39 protection
= Prot(Prot::undefined
);
45 Dsymbol
*EnumDeclaration::syntaxCopy(Dsymbol
*s
)
48 EnumDeclaration
*ed
= new EnumDeclaration(loc
, ident
,
49 memtype
? memtype
->syntaxCopy() : NULL
);
50 return ScopeDsymbol::syntaxCopy(ed
);
53 void EnumDeclaration::setScope(Scope
*sc
)
55 if (semanticRun
> PASSinit
)
57 ScopeDsymbol::setScope(sc
);
60 void EnumDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sds
)
62 /* Anonymous enum members get added to enclosing scope.
64 ScopeDsymbol
*scopesym
= isAnonymous() ? sds
: this;
68 ScopeDsymbol::addMember(sc
, sds
);
71 symtab
= new DsymbolTable();
76 for (size_t i
= 0; i
< members
->length
; i
++)
78 EnumMember
*em
= (*members
)[i
]->isEnumMember();
80 //printf("add %s to scope %s\n", em->toChars(), scopesym->toChars());
81 em
->addMember(sc
, isAnonymous() ? scopesym
: this);
87 /******************************
88 * Get the value of the .max/.min property as an Expression
90 * id Id::max or Id::min
93 Expression
*EnumDeclaration::getMaxMinValue(Loc loc
, Identifier
*id
)
95 //printf("EnumDeclaration::getMaxValue()\n");
98 Expression
**pval
= (id
== Id::max
) ? &maxval
: &minval
;
102 error(loc
, "recursive definition of .%s property", id
->toChars());
109 dsymbolSemantic(this, _scope
);
112 if (semanticRun
== PASSinit
|| !members
)
116 /* Allow these special enums to not need a member list
118 return memtype
->getProperty(loc
, id
, 0);
121 error("is forward referenced looking for .%s", id
->toChars());
124 if (!(memtype
&& memtype
->isintegral()))
126 error(loc
, "has no .%s property because base type %s is not an integral type",
128 memtype
? memtype
->toChars() : "");
132 for (size_t i
= 0; i
< members
->length
; i
++)
134 EnumMember
*em
= (*members
)[i
]->isEnumMember();
140 Expression
*e
= em
->value();
148 /* In order to work successfully with UDTs,
149 * build expressions to do the comparisons,
150 * and let the semantic analyzer and constant
151 * folder give us the result.
158 Expression
*ec
= new CmpExp(id
== Id::max
? TOKgt
: TOKlt
, em
->loc
, e
, *pval
);
160 ec
= expressionSemantic(ec
, em
->_scope
);
162 ec
= ec
->ctfeInterpret();
169 Expression
*e
= *pval
;
170 if (e
->op
!= TOKerror
)
179 *pval
= new ErrorExp();
184 * Determine if enum is a 'special' one.
188 bool EnumDeclaration::isSpecial() const
190 return (ident
== Id::__c_long
||
191 ident
== Id::__c_ulong
||
192 ident
== Id::__c_longlong
||
193 ident
== Id::__c_ulonglong
||
194 ident
== Id::__c_long_double
) && memtype
;
197 Expression
*EnumDeclaration::getDefaultValue(Loc loc
)
199 //printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
204 dsymbolSemantic(this, _scope
);
207 if (semanticRun
== PASSinit
|| !members
)
211 /* Allow these special enums to not need a member list
213 return memtype
->defaultInit(loc
);
216 error(loc
, "forward reference of %s.init", toChars());
220 for (size_t i
= 0; i
< members
->length
; i
++)
222 EnumMember
*em
= (*members
)[i
]->isEnumMember();
225 defaultval
= em
->value();
231 defaultval
= new ErrorExp();
235 Type
*EnumDeclaration::getMemtype(Loc loc
)
241 /* Enum is forward referenced. We don't need to resolve the whole thing,
245 memtype
= typeSemantic(memtype
, loc
, _scope
);
248 if (!isAnonymous() && members
)
249 memtype
= Type::tint32
;
254 if (!isAnonymous() && members
)
255 memtype
= Type::tint32
;
258 error(loc
, "is forward referenced looking for base type");
265 bool EnumDeclaration::oneMember(Dsymbol
**ps
, Identifier
*ident
)
268 return Dsymbol::oneMembers(members
, ps
, ident
);
269 return Dsymbol::oneMember(ps
, ident
);
272 Type
*EnumDeclaration::getType()
277 const char *EnumDeclaration::kind() const
282 bool EnumDeclaration::isDeprecated()
287 Prot
EnumDeclaration::prot()
292 Dsymbol
*EnumDeclaration::search(const Loc
&loc
, Identifier
*ident
, int flags
)
294 //printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars());
297 // Try one last time to resolve this enum
298 dsymbolSemantic(this, _scope
);
301 if (!members
|| !symtab
|| _scope
)
303 error("is forward referenced when looking for `%s`", ident
->toChars());
308 Dsymbol
*s
= ScopeDsymbol::search(loc
, ident
, flags
);
312 /********************************* EnumMember ****************************/
314 EnumMember::EnumMember(Loc loc
, Identifier
*id
, Expression
*value
, Type
*origType
)
315 : VarDeclaration(loc
, NULL
, id
? id
: Id::empty
, new ExpInitializer(loc
, value
))
318 this->origValue
= value
;
319 this->origType
= origType
;
322 EnumMember::EnumMember(Loc loc
, Identifier
*id
, Expression
*value
, Type
*memType
,
323 StorageClass stc
, UserAttributeDeclaration
*uad
, DeprecatedDeclaration
*dd
)
324 : VarDeclaration(loc
, NULL
, id
? id
: Id::empty
, new ExpInitializer(loc
, value
))
327 this->origValue
= value
;
328 this->origType
= memType
;
329 this->storage_class
= stc
;
330 this->userAttribDecl
= uad
;
334 Expression
*&EnumMember::value()
336 return ((ExpInitializer
*)_init
)->exp
;
339 Dsymbol
*EnumMember::syntaxCopy(Dsymbol
*s
)
342 return new EnumMember(loc
, ident
,
343 value() ? value()->syntaxCopy() : NULL
,
344 origType
? origType
->syntaxCopy() : NULL
);
347 const char *EnumMember::kind() const
349 return "enum member";
352 Expression
*EnumMember::getVarExp(Loc loc
, Scope
*sc
)
354 dsymbolSemantic(this, sc
);
356 return new ErrorExp();
357 checkDisabled(loc
, sc
);
359 if (depdecl
&& !depdecl
->_scope
)
360 depdecl
->_scope
= sc
;
361 checkDeprecated(loc
, sc
);
364 return new ErrorExp();
365 Expression
*e
= new VarExp(loc
, this);
366 return expressionSemantic(e
, sc
);