Name Name::makeAbsolute(const Name& name) const{ assert(isAbsolute()); assert(!name.empty()); if(name.isAbsolute()) { return name.copy(); } else { return concat(name); } }
SEM::TypeInstance* AddTypeInstance(Context& context, const AST::Node<AST::TypeInstance>& astTypeInstanceNode, const SEM::ModuleScope& moduleScope) { const auto parentNamespace = context.scopeStack().back().nameSpace(); const auto& typeInstanceName = astTypeInstanceNode->name; const Name fullTypeName = parentNamespace->name() + typeInstanceName; // Check if there's anything with the same name. const auto iterator = parentNamespace->items().find(typeInstanceName); if (iterator != parentNamespace->items().end()) { const auto& existingTypeInstance = iterator->second.typeInstance(); const auto& debugInfo = *(existingTypeInstance.debugInfo()); throw ErrorException(makeString("Type instance name '%s', at position %s, clashes with existing name, at position %s.", fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str(), debugInfo.location.toString().c_str())); } const auto typeInstanceKind = ConvertTypeInstanceKind(astTypeInstanceNode->kind); // Create a placeholder type instance. std::unique_ptr<SEM::TypeInstance> semTypeInstance(new SEM::TypeInstance(context.semContext(), fullTypeName.copy(), typeInstanceKind, moduleScope.copy())); if (semTypeInstance->isPrimitive()) { semTypeInstance->setPrimitiveID(context.sharedMaps().primitiveIDMap().getPrimitiveID(typeInstanceName)); } switch (moduleScope.kind()) { case SEM::ModuleScope::INTERNAL: { if (semTypeInstance->isClassDecl()) { throw ErrorException(makeString("Definition required for internal class '%s', at location %s.", fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str())); } break; } case SEM::ModuleScope::IMPORT: { if (semTypeInstance->isClassDef()) { throw ErrorException(makeString("Implementation not allowed of imported class '%s', at location %s.", fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str())); } break; } case SEM::ModuleScope::EXPORT: { if (semTypeInstance->isClassDecl()) { throw ErrorException(makeString("Definition required for exported class '%s', at location %s.", fullTypeName.toString().c_str(), astTypeInstanceNode.location().toString().c_str())); } break; } } semTypeInstance->setDebugInfo(Debug::TypeInstanceInfo(astTypeInstanceNode.location())); // Add template variables. size_t templateVarIndex = 0; for (const auto& astTemplateVarNode: *(astTypeInstanceNode->templateVariables)) { const auto& templateVarName = astTemplateVarNode->name; // TODO! const bool isVirtual = (typeInstanceName == "__ref"); const auto semTemplateVar = new SEM::TemplateVar(context.semContext(), fullTypeName + templateVarName, templateVarIndex++, isVirtual); const auto templateVarIterator = semTypeInstance->namedTemplateVariables().find(templateVarName); if (templateVarIterator != semTypeInstance->namedTemplateVariables().end()) { throw ErrorException(makeString("More than one template variable shares name '%s' in type '%s', at location %s.", templateVarName.c_str(), fullTypeName.toString().c_str(), astTemplateVarNode.location().toString().c_str())); } semTemplateVar->setDebugInfo(makeTemplateVarInfo(astTemplateVarNode)); semTypeInstance->templateVariables().push_back(semTemplateVar); semTypeInstance->namedTemplateVariables().insert(std::make_pair(templateVarName, semTemplateVar)); } if (semTypeInstance->isUnionDatatype()) { for (auto& astVariantNode: *(astTypeInstanceNode->variants)) { const auto variantTypeInstance = AddTypeInstance(context, astVariantNode, moduleScope); variantTypeInstance->setParent(semTypeInstance.get()); variantTypeInstance->templateVariables() = semTypeInstance->templateVariables().copy(); variantTypeInstance->namedTemplateVariables() = semTypeInstance->namedTemplateVariables().copy(); semTypeInstance->variants().push_back(variantTypeInstance); } } if (!astTypeInstanceNode->noTagSet.isNull()) { SEM::TemplateVarArray noTagSet; for (const auto& astNoTagName: *(astTypeInstanceNode->noTagSet)) { const auto templateVarIterator = semTypeInstance->namedTemplateVariables().find(astNoTagName); if (templateVarIterator == semTypeInstance->namedTemplateVariables().end()) { throw ErrorException(makeString("Can't find template variable '%s' in notag() set in type '%s', at location %s.", astNoTagName.c_str(), fullTypeName.toString().c_str(), astTypeInstanceNode->noTagSet.location().toString().c_str())); } noTagSet.push_back(templateVarIterator->second); } semTypeInstance->setNoTagSet(std::move(noTagSet)); } const auto typeInstancePtr = semTypeInstance.get(); parentNamespace->items().insert(std::make_pair(typeInstanceName, SEM::NamespaceItem::TypeInstance(std::move(semTypeInstance)))); return typeInstancePtr; }