Mercurial > projects > ldc
diff gen/typinf.c @ 58:2c3cd3596187 trunk
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
Added initial support for CatExp aka 'a ~ b'
Fixed global constant static arrays initialized with string literals
Fixed casting any dynamic array to void*
Fixed new expression with temporary storage
Fixed alias declarations in function scope
Fixed relational comparisons of pointers
author | lindquist |
---|---|
date | Thu, 25 Oct 2007 09:02:55 +0200 |
parents | a9d29e9f1fed |
children | d4a678905d5e |
line wrap: on
line diff
--- a/gen/typinf.c Thu Oct 25 02:39:53 2007 +0200 +++ b/gen/typinf.c Thu Oct 25 09:02:55 2007 +0200 @@ -246,12 +246,13 @@ Logger::println("typeinfo mangle: %s", mangle()); + // this is a declaration of a builtin __initZ var if (tinfo->builtinTypeInfo()) { - // this is a declaration of a builtin __initZ var llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle()); assert(llvmValue); Logger::cout() << "Got typeinfo var:" << '\n' << *llvmValue << '\n'; } + // custom typedef else { toDt(NULL); // this is a specialized typeinfo @@ -265,8 +266,16 @@ void TypeInfoDeclaration::toDt(dt_t **pdt) { assert(0 && "TypeInfoDeclaration"); + + /* + //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); + dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo + dtdword(pdt, 0); // monitor + */ } +/* ========================================================================= */ + void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) { Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); @@ -354,116 +363,59 @@ */ } -void TypeInfoEnumDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoEnumDeclaration"); -} - -void TypeInfoPointerDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoPointerDeclaration"); -} - -void TypeInfoArrayDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoArrayDeclaration"); -} - -void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoStaticArrayDeclaration"); -} - -void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoAssociativeArrayDeclaration"); -} - -void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoFunctionDeclaration"); -} - -void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoDelegateDeclaration"); -} - -void TypeInfoStructDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoStructDeclaration"); -} - -void TypeInfoClassDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoClassDeclaration"); -} - -void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoInterfaceDeclaration"); -} - -void TypeInfoTupleDeclaration::toDt(dt_t **pdt) -{ - assert(0 && "TypeInfoTupleDeclaration"); -} - -// original dmdfe toDt code for reference - -#if 0 - -void TypeInfoDeclaration::toDt(dt_t **pdt) -{ - //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); - dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo - dtdword(pdt, 0); // monitor -} - -void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) -{ - //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars()); - - dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef - dtdword(pdt, 0); // monitor - - assert(tinfo->ty == Ttypedef); - - TypeTypedef *tc = (TypeTypedef *)tinfo; - TypedefDeclaration *sd = tc->sym; - //printf("basetype = %s\n", sd->basetype->toChars()); - - /* Put out: - * TypeInfo base; - * char[] name; - * void[] m_init; - */ - - sd->basetype = sd->basetype->merge(); - sd->basetype->getTypeInfo(NULL); // generate vtinfo - assert(sd->basetype->vtinfo); - dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype - - char *name = sd->toPrettyChars(); - size_t namelen = strlen(name); - dtdword(pdt, namelen); - dtabytes(pdt, TYnptr, 0, namelen + 1, name); - - // void[] init; - if (tinfo->isZeroInit() || !sd->init) - { // 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 - } -} +/* ========================================================================= */ void TypeInfoEnumDeclaration::toDt(dt_t **pdt) { + Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); + LOG_SCOPE; + + ClassDeclaration* base = Type::typeinfoenum; + base->toObjFile(); + + llvm::Constant* initZ = base->llvmInitZ; + assert(initZ); + const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType()); + + std::vector<llvm::Constant*> sinits; + sinits.push_back(initZ->getOperand(0)); + + assert(tinfo->ty == Tenum); + TypeEnum *tc = (TypeEnum *)tinfo; + EnumDeclaration *sd = tc->sym; + + // TypeInfo base + //const llvm::PointerType* basept = llvm::cast<llvm::PointerType>(initZ->getOperand(1)->getType()); + //sinits.push_back(llvm::ConstantPointerNull::get(basept)); + Logger::println("generating base typeinfo"); + //sd->basetype = sd->basetype->merge(); + sd->memtype->getTypeInfo(NULL); // generate vtinfo + assert(sd->memtype->vtinfo); + if (!sd->memtype->vtinfo->llvmValue) + sd->memtype->vtinfo->toObjFile(); + assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue)); + llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue); + castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType()); + sinits.push_back(castbase); + + // char[] name + char *name = sd->toPrettyChars(); + sinits.push_back(LLVM_DtoConstString(name)); + assert(sinits.back()->getType() == initZ->getOperand(2)->getType()); + + // void[] init + //const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty); + //sinits.push_back(LLVM_DtoConstantSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); + sinits.push_back(initZ->getOperand(3)); + + // create the symbol + llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); + llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module); + + llvmValue = gvar; + + /* + //printf("TypeInfoEnumDeclaration::toDt()\n"); dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum dtdword(pdt, 0); // monitor @@ -473,11 +425,10 @@ TypeEnum *tc = (TypeEnum *)tinfo; EnumDeclaration *sd = tc->sym; - /* Put out: - * TypeInfo base; - * char[] name; - * void[] m_init; - */ + // Put out: + // TypeInfo base; + // char[] name; + // void[] m_init; sd->memtype->getTypeInfo(NULL); dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members @@ -498,38 +449,75 @@ dtdword(pdt, sd->type->size()); // init.length dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr } + + */ } +/* ========================================================================= */ + +static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) +{ + ClassDeclaration* base = cd; + base->toObjFile(); + + llvm::Constant* initZ = base->llvmInitZ; + assert(initZ); + const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType()); + + std::vector<llvm::Constant*> sinits; + sinits.push_back(initZ->getOperand(0)); + + // TypeInfo base + Logger::println("generating base typeinfo"); + basetype->getTypeInfo(NULL); + assert(basetype->vtinfo); + if (!basetype->vtinfo->llvmValue) + basetype->vtinfo->toObjFile(); + assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue)); + llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue); + castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType()); + sinits.push_back(castbase); + + // create the symbol + llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); + llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,tid->toChars(),gIR->module); + + tid->llvmValue = gvar; +} + +/* ========================================================================= */ + void TypeInfoPointerDeclaration::toDt(dt_t **pdt) { - //printf("TypeInfoPointerDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer - dtdword(pdt, 0); // monitor + Logger::println("TypeInfoPointerDeclaration::toDt() %s", toChars()); + LOG_SCOPE; assert(tinfo->ty == Tpointer); - TypePointer *tc = (TypePointer *)tinfo; - tc->next->getTypeInfo(NULL); - dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to + LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfopointer); } +/* ========================================================================= */ + void TypeInfoArrayDeclaration::toDt(dt_t **pdt) { - //printf("TypeInfoArrayDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array - dtdword(pdt, 0); // monitor + Logger::println("TypeInfoArrayDeclaration::toDt() %s", toChars()); + LOG_SCOPE; assert(tinfo->ty == Tarray); - TypeDArray *tc = (TypeDArray *)tinfo; - tc->next->getTypeInfo(NULL); - dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type + LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfoarray); } +/* ========================================================================= */ + void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) { + assert(0 && "TypeInfoStaticArrayDeclaration"); + + /* //printf("TypeInfoStaticArrayDeclaration::toDt()\n"); dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray dtdword(pdt, 0); // monitor @@ -542,10 +530,16 @@ dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type dtdword(pdt, tc->dim->toInteger()); // length + */ } +/* ========================================================================= */ + void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) { + assert(0 && "TypeInfoAssociativeArrayDeclaration"); + + /* //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n"); dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray dtdword(pdt, 0); // monitor @@ -559,38 +553,42 @@ tc->index->getTypeInfo(NULL); dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type + */ } +/* ========================================================================= */ + void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) { - //printf("TypeInfoFunctionDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function - dtdword(pdt, 0); // monitor + Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars()); + LOG_SCOPE; assert(tinfo->ty == Tfunction); - TypeFunction *tc = (TypeFunction *)tinfo; - tc->next->getTypeInfo(NULL); - dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value + LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfofunction); } +/* ========================================================================= */ + void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) { - //printf("TypeInfoDelegateDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate - dtdword(pdt, 0); // monitor + Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars()); + LOG_SCOPE; assert(tinfo->ty == Tdelegate); - TypeDelegate *tc = (TypeDelegate *)tinfo; - tc->next->next->getTypeInfo(NULL); - dtxoff(pdt, tc->next->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value + LLVM_D_Create_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate); } +/* ========================================================================= */ + void TypeInfoStructDeclaration::toDt(dt_t **pdt) { + assert(0 && "TypeInfoStructDeclaration"); + + /* //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); unsigned offset = Type::typeinfostruct->structsize; @@ -603,17 +601,17 @@ TypeStruct *tc = (TypeStruct *)tinfo; StructDeclaration *sd = tc->sym; - /* Put out: - * char[] name; - * void[] init; - * hash_t function(void*) xtoHash; - * int function(void*,void*) xopEquals; - * int function(void*,void*) xopCmp; - * char[] function(void*) xtoString; - * uint m_flags; - * - * name[] - */ +// Put out: +// char[] name; +// void[] init; +// hash_t function(void*) xtoHash; +// int function(void*,void*) xopEquals; +// int function(void*,void*) xopCmp; +// char[] function(void*) xtoString; +// uint m_flags; +// +// name[] +// char *name = sd->toPrettyChars(); size_t namelen = strlen(name); @@ -723,10 +721,16 @@ // name[] dtnbytes(pdt, namelen + 1, name); + */ } +/* ========================================================================= */ + void TypeInfoClassDeclaration::toDt(dt_t **pdt) { + assert(0 && "TypeInfoClassDeclaration"); + + /* //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars()); dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass dtdword(pdt, 0); // monitor @@ -740,10 +744,16 @@ tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); s = tc->sym->vclassinfo->toSymbol(); dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo + */ } +/* ========================================================================= */ + void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) { + assert(0 && "TypeInfoInterfaceDeclaration"); + + /* //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars()); dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface dtdword(pdt, 0); // monitor @@ -757,10 +767,16 @@ tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); s = tc->sym->vclassinfo->toSymbol(); dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo + */ } +/* ========================================================================= */ + void TypeInfoTupleDeclaration::toDt(dt_t **pdt) { + assert(0 && "TypeInfoTupleDeclaration"); + + /* //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars()); dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface dtdword(pdt, 0); // monitor @@ -786,46 +802,5 @@ outdata(s); dtxoff(pdt, s, 0, TYnptr); // elements.ptr + */ } - -void TypeInfoDeclaration::toObjFile() -{ - Symbol *s; - unsigned sz; - Dsymbol *parent; - - //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection); - - s = toSymbol(); - sz = type->size(); - - parent = this->toParent(); - s->Sclass = SCcomdat; - s->Sfl = FLdata; - - toDt(&s->Sdt); - - dt_optimize(s->Sdt); - - // See if we can convert a comdat to a comdef, - // which saves on exe file space. - if (s->Sclass == SCcomdat && - s->Sdt->dt == DT_azeros && - s->Sdt->DTnext == NULL) - { - s->Sclass = SCglobal; - s->Sdt->dt = DT_common; - } - -#if ELFOBJ // Burton - if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL) - s->Sseg = UDATA; - else - s->Sseg = DATA; -#endif /* ELFOBJ */ - outdata(s); - if (isExport()) - obj_export(s,0); -} - -#endif