示例#1
0
文件: typinf.cpp 项目: wilzbach/ldc
  void visit(TypeInfoEnumDeclaration *decl) override {
    IF_LOG Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s",
                           decl->toChars());
    LOG_SCOPE;

    RTTIBuilder b(getEnumTypeInfoType());

    assert(decl->tinfo->ty == Tenum);
    TypeEnum *tc = static_cast<TypeEnum *>(decl->tinfo);
    EnumDeclaration *sd = tc->sym;

    // TypeInfo base
    b.push_typeinfo(sd->memtype);

    // char[] name
    b.push_string(sd->toPrettyChars());

    // void[] init
    // the array is null if the default initializer is zero
    if (!sd->members || decl->tinfo->isZeroInit(decl->loc)) {
      b.push_null_void_array();
    }
    // otherwise emit a void[] with the default initializer
    else {
      Expression *defaultval = sd->getDefaultValue(decl->loc);
      LLConstant *c = toConstElem(defaultval, gIR);
      b.push_void_array(c, sd->memtype, sd);
    }

    // finish
    b.finalize(gvar);
  }
示例#2
0
文件: typinf.cpp 项目: nrTQgc/ldc
  void visit(TypeInfoEnumDeclaration *decl) override {
    IF_LOG Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s",
                           decl->toChars());
    LOG_SCOPE;

    RTTIBuilder b(Type::typeinfoenum);

    assert(decl->tinfo->ty == Tenum);
    TypeEnum *tc = static_cast<TypeEnum *>(decl->tinfo);
    EnumDeclaration *sd = tc->sym;

    // TypeInfo base
    b.push_typeinfo(sd->memtype);

    // char[] name
    b.push_string(sd->toPrettyChars());

    // void[] init
    // emit void[] with the default initialier, the array is null if the default
    // initializer is zero
    if (!sd->members || decl->tinfo->isZeroInit(decl->loc)) {
      b.push_null_void_array();
    }
    // otherwise emit a void[] with the default initializer
    else {
      Type *memtype = sd->memtype;
      LLType *memty = DtoType(memtype);
      LLConstant *C;
      Expression *defaultval = sd->getDefaultValue(decl->loc);
      if (memtype->isintegral()) {
        C = LLConstantInt::get(memty, defaultval->toInteger(),
                               !isLLVMUnsigned(memtype));
      } else if (memtype->isString()) {
        C = DtoConstString(
            static_cast<const char *>(defaultval->toStringExp()->string));
      } else if (memtype->isfloating()) {
        C = LLConstantFP::get(memty, defaultval->toReal());
      } else {
        llvm_unreachable("Unsupported type");
      }

      b.push_void_array(C, memtype, sd);
    }

    // finish
    b.finalize(getIrGlobal(decl));
  }
示例#3
0
文件: typinf.c 项目: NativeAPI/dmd
    void visit(TypeInfoEnumDeclaration *d)
    {
        //printf("TypeInfoEnumDeclaration::toDt()\n");
        verifyStructSize(Type::typeinfoenum, 7 * Target::ptrsize);

        dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0); // vtbl for TypeInfo_Enum
        dtsize_t(pdt, 0);                        // monitor

        assert(d->tinfo->ty == Tenum);

        TypeEnum *tc = (TypeEnum *)d->tinfo;
        EnumDeclaration *sd = tc->sym;

        /* Put out:
         *  TypeInfo base;
         *  char[] name;
         *  void[] m_init;
         */

        if (sd->memtype)
        {
            sd->memtype->genTypeInfo(NULL);
            dtxoff(pdt, toSymbol(sd->memtype->vtinfo), 0);        // TypeInfo for enum members
        }
        else
            dtsize_t(pdt, 0);

        const char *name = sd->toPrettyChars();
        size_t namelen = strlen(name);
        dtsize_t(pdt, namelen);
        dtabytes(pdt, 0, namelen + 1, name);

        // void[] init;
        if (!sd->members || d->tinfo->isZeroInit())
        {
            // 0 initializer, or the same as the base type
            dtsize_t(pdt, 0);        // init.length
            dtsize_t(pdt, 0);        // init.ptr
        }
        else
        {
            dtsize_t(pdt, sd->type->size()); // init.length
            dtxoff(pdt, sd->toInitializer(), 0);    // init.ptr
        }
    }
示例#4
0
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoEnumDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
    dtdword(pdt, 0);			    // monitor

    assert(tinfo->ty == Tenum);

    TypeEnum *tc = (TypeEnum *)tinfo;
    EnumDeclaration *sd = tc->sym;

    /* Put out:
     *	TypeInfo base;
     *	char[] name;
     *	void[] m_init;
     */

    if (sd->memtype)
    {	sd->memtype->getTypeInfo(NULL);
	dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr);	// TypeInfo for enum members
    }
    else
	dtdword(pdt, 0);

    char *name = sd->toPrettyChars();
    size_t namelen = strlen(name);
    dtdword(pdt, namelen);
    dtabytes(pdt, TYnptr, 0, namelen + 1, name);

    // void[] init;
    if (!sd->defaultval || tinfo->isZeroInit())
    {	// 0 initializer, or the same as the base type
	dtdword(pdt, 0);	// init.length
	dtdword(pdt, 0);	// init.ptr
    }
    else
    {
	dtdword(pdt, sd->type->size());	// init.length
	dtxoff(pdt, sd->toInitializer(), 0, TYnptr);	// init.ptr
    }
}
示例#5
0
文件: typinf.cpp 项目: alexrp/ldc
void TypeInfoEnumDeclaration::llvmDefine()
{
    Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
    LOG_SCOPE;

    RTTIBuilder b(Type::typeinfoenum);

    assert(tinfo->ty == Tenum);
    TypeEnum *tc = static_cast<TypeEnum *>(tinfo);
    EnumDeclaration *sd = tc->sym;

    // TypeInfo base
    b.push_typeinfo(sd->memtype);

    // char[] name
    b.push_string(sd->toPrettyChars());

    // void[] init
    // emit void[] with the default initialier, the array is null if the default
    // initializer is zero
    if (!sd->defaultval || tinfo->isZeroInit(0))
    {
        b.push_null_void_array();
    }
    // otherwise emit a void[] with the default initializer
    else
    {
        LLType* memty = DtoType(sd->memtype);
#if DMDV2
        LLConstant* C = LLConstantInt::get(memty, sd->defaultval->toInteger(), !isLLVMUnsigned(sd->memtype));
#else
        LLConstant* C = LLConstantInt::get(memty, sd->defaultval, !isLLVMUnsigned(sd->memtype));
#endif
        b.push_void_array(C, sd->memtype, sd);
    }

    // finish
    b.finalize(ir.irGlobal);
}
示例#6
0
文件: enum.c 项目: alekseysidorov/ldc
void EnumDeclaration::semantic(Scope *sc)
{
    uinteger_t number;
    Type *t;
    Scope *sce;

    //printf("EnumDeclaration::semantic(sd = %p, '%s')\n", sc->scopesym, sc->scopesym->toChars());
    if (!memtype)
        memtype = Type::tint32;

    if (symtab)                 // if already done
    {   if (isdone || !scope)
            return;             // semantic() already completed
    }
    else
        symtab = new DsymbolTable();

    Scope *scx = NULL;
    if (scope)
    {   sc = scope;
        scx = scope;            // save so we don't make redundant copies
        scope = NULL;
    }

    unsigned dprogress_save = Module::dprogress;

    if (sc->stc & STCdeprecated)
        isdeprecated = 1;

    parent = sc->scopesym;
    memtype = memtype->semantic(loc, sc);

    /* Check to see if memtype is forward referenced
     */
    if (memtype->ty == Tenum)
    {   EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc);
        if (!sym->memtype)
        {
            error("base enum %s is forward referenced", sym->toChars());
            memtype = Type::tint32;
        }
    }

    if (!memtype->isintegral())
    {   error("base type must be of integral type, not %s", memtype->toChars());
        memtype = Type::tint32;
    }

    isdone = 1;
    Module::dprogress++;

    t = isAnonymous() ? memtype : type;
    symtab = new DsymbolTable();
    sce = sc->push(this);
    sce->parent = this;
    number = 0;
    if (!members)               // enum ident;
        return;
    if (members->dim == 0)
        error("enum %s must have at least one member", toChars());
    int first = 1;
    for (size_t i = 0; i < members->dim; i++)
    {
        EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
        Expression *e;

        if (!em)
            /* The e->semantic(sce) can insert other symbols, such as
             * template instances and function literals.
             */
            continue;

        //printf("Enum member '%s'\n",em->toChars());
        e = em->value;
        if (e)
        {
            assert(e->dyncast() == DYNCAST_EXPRESSION);
            e = e->semantic(sce);
            e = e->optimize(WANTvalue);
            // Need to copy it because we're going to change the type
            e = e->copy();
            e = e->implicitCastTo(sc, memtype);
            e = e->optimize(WANTvalue);
            number = e->toInteger();
            e->type = t;
        }
        else
        {   // Default is the previous number plus 1

            // Check for overflow
            if (!first)
            {
                switch (t->toBasetype()->ty)
                {
                    case Tbool:
                        if (number == 2)        goto Loverflow;
                        break;

                    case Tint8:
                        if (number == 128) goto Loverflow;
                        break;

                    case Tchar:
                    case Tuns8:
                        if (number == 256) goto Loverflow;
                        break;

                    case Tint16:
                        if (number == 0x8000) goto Loverflow;
                        break;

                    case Twchar:
                    case Tuns16:
                        if (number == 0x10000) goto Loverflow;
                        break;

                    case Tint32:
                        if (number == 0x80000000) goto Loverflow;
                        break;

                    case Tdchar:
                    case Tuns32:
                        if (number == 0x100000000LL) goto Loverflow;
                        break;

                    case Tint64:
                        if (number == 0x8000000000000000LL) goto Loverflow;
                        break;

                    case Tuns64:
                        if (number == 0) goto Loverflow;
                        break;

                    Loverflow:
                        error("overflow of enum value");
                        break;

                    default:
                        assert(0);
                }
            }
            e = new IntegerExp(em->loc, number, t);
        }
        em->value = e;

        // Add to symbol table only after evaluating 'value'
        if (isAnonymous())
        {
            //sce->enclosing->insert(em);
            for (Scope *sct = sce->enclosing; sct; sct = sct->enclosing)
            {
                if (sct->scopesym)
                {
                    if (!sct->scopesym->symtab)
                        sct->scopesym->symtab = new DsymbolTable();
                    em->addMember(sce, sct->scopesym, 1);
                    break;
                }
            }
        }
        else
            em->addMember(sc, this, 1);

        if (first)
        {   first = 0;
            defaultval = number;
            minval = number;
            maxval = number;
        }
        else if (memtype->isunsigned())
        {
            if (number < minval)
                minval = number;
            if (number > maxval)
                maxval = number;
        }
        else
        {
            if ((sinteger_t)number < (sinteger_t)minval)
                minval = number;
            if ((sinteger_t)number > (sinteger_t)maxval)
                maxval = number;
        }

        number++;
    }
    //printf("defaultval = %lld\n", defaultval);

    sce->pop();
    //members->print();
}
示例#7
0
文件: dsymbol.c 项目: andralex/dmd
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
{
    //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
    //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0;

    // Look in symbols declared in this module
    Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
    //printf("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0);
    if (s)
    {
        //printf("\ts = '%s.%s'\n",toChars(),s->toChars());
    }
    else if (imports)
    {
        OverloadSet *a = NULL;

        // Look in imported modules
        for (size_t i = 0; i < imports->dim; i++)
        {   Dsymbol *ss = (*imports)[i];
            Dsymbol *s2;

            // If private import, don't search it
            if (flags & 1 && prots[i] == PROTprivate)
                continue;

            //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport());
            /* Don't find private members if ss is a module
             */
            s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0);
            if (!s)
                s = s2;
            else if (s2 && s != s2)
            {
                if (s->toAlias() == s2->toAlias() ||
                    s->getType() == s2->getType() && s->getType())
                {
                    /* After following aliases, we found the same
                     * symbol, so it's not an ambiguity.  But if one
                     * alias is deprecated or less accessible, prefer
                     * the other.
                     */
                    if (s->isDeprecated() ||
                        s2->prot() > s->prot() && s2->prot() != PROTnone)
                        s = s2;
                }
                else
                {
                    /* Two imports of the same module should be regarded as
                     * the same.
                     */
                    Import *i1 = s->isImport();
                    Import *i2 = s2->isImport();
                    if (!(i1 && i2 &&
                          (i1->mod == i2->mod ||
                           (!i1->parent->isImport() && !i2->parent->isImport() &&
                            i1->ident->equals(i2->ident))
                          )
                         )
                       )
                    {
                        /* Bugzilla 8668:
                         * Public selective import adds AliasDeclaration in module.
                         * To make an overload set, resolve aliases in here and
                         * get actual overload roots which accessible via s and s2.
                         */
                        s = s->toAlias();
                        s2 = s2->toAlias();

                        /* If both s2 and s are overloadable (though we only
                         * need to check s once)
                         */
                        if (s2->isOverloadable() && (a || s->isOverloadable()))
                        {   if (!a)
                                a = new OverloadSet(s->ident);
                            /* Don't add to a[] if s2 is alias of previous sym
                             */
                            for (size_t j = 0; j < a->a.dim; j++)
                            {   Dsymbol *s3 = a->a[j];
                                if (s2->toAlias() == s3->toAlias())
                                {
                                    if (s3->isDeprecated() ||
                                        s2->prot() > s3->prot() && s2->prot() != PROTnone)
                                        a->a[j] = s2;
                                    goto Lcontinue;
                                }
                            }
                            a->push(s2);
                        Lcontinue:
                            continue;
                        }
                        if (flags & 4)          // if return NULL on ambiguity
                            return NULL;
                        if (!(flags & 2))
                            ScopeDsymbol::multiplyDefined(loc, s, s2);
                        break;
                    }
                }
            }
        }

        /* Build special symbol if we had multiple finds
         */
        if (a)
        {   assert(s);
            a->push(s);
            s = a;
        }

        if (s)
        {
            if (!(flags & 2))
            {   Declaration *d = s->isDeclaration();
                if (d && d->protection == PROTprivate &&
                    !d->parent->isTemplateMixin())
                    error(loc, "%s is private", d->toPrettyChars());

                AggregateDeclaration *ad = s->isAggregateDeclaration();
                if (ad && ad->protection == PROTprivate &&
                    !ad->parent->isTemplateMixin())
                    error(loc, "%s is private", ad->toPrettyChars());

                EnumDeclaration *ed = s->isEnumDeclaration();
                if (ed && ed->protection == PROTprivate &&
                    !ed->parent->isTemplateMixin())
                    error(loc, "%s is private", ed->toPrettyChars());

                TemplateDeclaration *td = s->isTemplateDeclaration();
                if (td && td->protection == PROTprivate &&
                    !td->parent->isTemplateMixin())
                    error(loc, "%s is private", td->toPrettyChars());
            }
        }
    }
    return s;
}