Dsymbol *DsymbolTable::update(Dsymbol *s) { Identifier *ident = s->ident; Dsymbol **ps = (Dsymbol **)dmd_aaGet(&tab, (void *)ident); *ps = s; return s; }
/** * Collects all unit test functions from the given array of symbols. * * This is a helper function used by the implementation of __traits(getUnitTests). * * Input: * symbols array of symbols to collect the functions from * uniqueUnitTests an associative array (should actually be a set) to * keep track of already collected functions. We're * using an AA here to avoid doing a linear search of unitTests * * Output: * unitTests array of DsymbolExp's of the collected unit test functions * uniqueUnitTests updated with symbols from unitTests[ ] */ static void collectUnitTests(Dsymbols *symbols, AA *uniqueUnitTests, Expressions *unitTests) { if (!symbols) return; for (size_t i = 0; i < symbols->dim; i++) { Dsymbol *symbol = (*symbols)[i]; UnitTestDeclaration *unitTest = symbol->isUnitTestDeclaration(); if (unitTest) { if (!dmd_aaGetRvalue(uniqueUnitTests, (void *)unitTest)) { FuncAliasDeclaration* alias = new FuncAliasDeclaration(unitTest, 0); alias->protection = unitTest->protection; Expression* e = new DsymbolExp(Loc(), alias); unitTests->push(e); bool* value = (bool*) dmd_aaGet(&uniqueUnitTests, (void *)unitTest); *value = true; } } else { AttribDeclaration *attrDecl = symbol->isAttribDeclaration(); if (attrDecl) { Dsymbols *decl = attrDecl->include(NULL, NULL); collectUnitTests(decl, uniqueUnitTests, unitTests); } } } }
Dsymbol *DsymbolTable::insert(Identifier *ident, Dsymbol *s) { //printf("DsymbolTable::insert()\n"); Dsymbol **ps = (Dsymbol **)dmd_aaGet(&tab, (void *)ident); if (*ps) return NULL; // already in table *ps = s; return s; }
Dsymbol *DsymbolTable::insert(Dsymbol *s) { //printf("DsymbolTable::insert(this = %p, '%s')\n", this, s->ident->toChars()); Identifier *ident = s->ident; Dsymbol **ps = (Dsymbol **)dmd_aaGet(&tab, (void *)ident); if (*ps) return NULL; // already in table *ps = s; return s; }
static Label *getLabel(IRState *irs, Blockx *blx, Statement *s) { Label **slot = (Label **)dmd_aaGet(irs->labels, (void *)s); if (*slot == NULL) { Label *label = new Label(); label->lblock = blx ? block_calloc(blx) : block_calloc(); label->fwdrefs = NULL; *slot = label; } return *slot; }
Expression *arrayOp(BinExp *e, Scope *sc) { //printf("BinExp::arrayOp() %s\n", toChars()); Type *tb = e->type->toBasetype(); assert(tb->ty == Tarray || tb->ty == Tsarray); Type *tbn = tb->nextOf()->toBasetype(); if (tbn->ty == Tvoid) { e->error("cannot perform array operations on void[] arrays"); return new ErrorExp(); } if (!isArrayOpValid(e)) { e->error("invalid array operation %s (possible missing [])", e->toChars()); return new ErrorExp(); } Expressions *arguments = new Expressions(); /* The expression to generate an array operation for is mangled * into a name to use as the array operation function name. * Mangle in the operands and operators in RPN order, and type. */ OutBuffer buf; buf.writestring("_array"); buildArrayIdent(e, &buf, arguments); buf.writeByte('_'); /* Append deco of array element type */ buf.writestring(e->type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco); char *name = buf.peekString(); Identifier *ident = Identifier::idPool(name); FuncDeclaration **pFd = (FuncDeclaration **)dmd_aaGet(&arrayfuncs, (void *)ident); FuncDeclaration *fd = *pFd; if (!fd) fd = buildArrayOp(ident, e, sc); if (fd && fd->errors) { const char *fmt; if (tbn->ty == Tstruct || tbn->ty == Tclass) fmt = "invalid array operation '%s' because %s doesn't support necessary arithmetic operations"; else if (!tbn->isscalar()) fmt = "invalid array operation '%s' because %s is not a scalar type"; else fmt = "invalid array operation '%s' for element type %s"; e->error(fmt, e->toChars(), tbn->toChars()); return new ErrorExp(); } *pFd = fd; Expression *ev = new VarExp(e->loc, fd); Expression *ec = new CallExp(e->loc, ev, arguments); return semantic(ec, sc); }