| 5110 | } |
| 5111 | |
| 5112 | void TypeInstanceGeneric(const char* pos, TypeInfo* base, unsigned aliases, bool genericTemp) |
| 5113 | { |
| 5114 | Lexeme *start = CodeInfo::lexStart + base->genericInfo->start; |
| 5115 | NodeZeroOP **aliasType = &CodeInfo::nodeList[CodeInfo::nodeList.size() - aliases]; |
| 5116 | |
| 5117 | // Generate instance name |
| 5118 | char tempName[NULLC_MAX_VARIABLE_NAME_LENGTH]; |
| 5119 | char *namePos = tempName; |
| 5120 | namePos += SafeSprintf(namePos, NULLC_MAX_VARIABLE_NAME_LENGTH - int(namePos - tempName), "%s<", base->name); |
| 5121 | for(unsigned i = 0; i < aliases; i++) |
| 5122 | namePos += SafeSprintf(namePos, NULLC_MAX_VARIABLE_NAME_LENGTH - int(namePos - tempName), "%s%s", aliasType[i]->typeInfo->GetFullTypeName(), i == aliases - 1 ? "" : ", "); |
| 5123 | namePos += SafeSprintf(namePos, NULLC_MAX_VARIABLE_NAME_LENGTH - int(namePos - tempName), ">"); |
| 5124 | |
| 5125 | // Check name length |
| 5126 | if(NULLC_MAX_VARIABLE_NAME_LENGTH - int(namePos - tempName) == 0) |
| 5127 | ThrowError(pos, "ERROR: generated generic type name exceeds maximum type length '%d'", NULLC_MAX_VARIABLE_NAME_LENGTH); |
| 5128 | |
| 5129 | AliasInfo *aliasList = NULL; |
| 5130 | |
| 5131 | unsigned aliasID = 0; |
| 5132 | // We are reparsing original class definition |
| 5133 | do |
| 5134 | { |
| 5135 | currType = aliasType[aliasID]->typeInfo; |
| 5136 | assert(start->type == lex_string); // This was already checked during parsing |
| 5137 | |
| 5138 | InplaceStr aliasName = InplaceStr(start->pos, start->length); |
| 5139 | AliasInfo *info = TypeInfo::CreateAlias(aliasName, currType); |
| 5140 | info->next = aliasList; |
| 5141 | aliasList = info; |
| 5142 | CodeInfo::classMap.insert(info->nameHash, currType); |
| 5143 | |
| 5144 | start++; |
| 5145 | aliasID++; |
| 5146 | }while(start->type == lex_comma ? !!start++ : false); |
| 5147 | if(aliasID > aliases) |
| 5148 | ThrowError(pos, "ERROR: there where only '%d' argument(s) to a generic type that expects '%d'", aliases, aliasID); |
| 5149 | else if(aliasID < aliases) |
| 5150 | ThrowError(pos, "ERROR: type has only '%d' generic argument(s) while '%d' specified", aliasID, aliases); |
| 5151 | assert(start->type == lex_greater); |
| 5152 | start++; |
| 5153 | |
| 5154 | base->genericInfo->aliasCount = aliases; |
| 5155 | |
| 5156 | // Remove type nodes used to instance class |
| 5157 | for(unsigned i = 0; i < aliases; i++) |
| 5158 | CodeInfo::nodeList.pop_back(); |
| 5159 | |
| 5160 | // Search if the type was already defined |
| 5161 | if(TypeInfo **lastType = CodeInfo::classMap.find(GetStringHash(tempName, namePos))) |
| 5162 | { |
| 5163 | while(aliasList) |
| 5164 | { |
| 5165 | CodeInfo::classMap.remove(aliasList->nameHash, aliasList->type); |
| 5166 | aliasList = aliasList->next; |
| 5167 | } |
| 5168 | currType = *lastType; |
| 5169 | return; |
no test coverage detected