void checkBaseTypes(ClassNode* classNode, std::vector<TypeNameNode*>& baseTypeNameNodes, std::vector<TypeNode*>& baseTypeNodes, TemplateArguments* templateArguments) { assert(baseTypeNameNodes.size() == baseTypeNodes.size()); size_t count = baseTypeNameNodes.size(); for(size_t i = 0; i < count; ++i) { TypeNameNode* typeNameNode = baseTypeNameNodes[i]; TypeNode* typeNode = baseTypeNodes[i]; if (0 == typeNode) { continue; } TypeCategory baseTypeCategory = typeNode->getTypeCategory(templateArguments); if(classNode->isValueType()) { if (value_type != baseTypeCategory) { char buf[512]; sprintf_s(buf, "\'%s\' : base type must be value type", typeNameNode->m_scopeNameList->m_scopeName->m_name->m_str.c_str()); ErrorList_AddItem_CurrentFile(typeNameNode->m_scopeNameList->m_scopeName->m_name->m_lineNo, typeNameNode->m_scopeNameList->m_scopeName->m_name->m_columnNo, semantic_error_base_type, buf); } } else { if (0 == i) { if (reference_type != baseTypeCategory) { char buf[512]; sprintf_s(buf, "\'%s\' : first base type must be reference type", typeNameNode->m_scopeNameList->m_scopeName->m_name->m_str.c_str()); ErrorList_AddItem_CurrentFile(typeNameNode->m_scopeNameList->m_scopeName->m_name->m_lineNo, typeNameNode->m_scopeNameList->m_scopeName->m_name->m_columnNo, semantic_error_base_type, buf); } } else { if (reference_type != baseTypeCategory && value_type != baseTypeCategory) { char buf[512]; sprintf_s(buf, "\'%s\' : base type must be reference type or value type", typeNameNode->m_scopeNameList->m_scopeName->m_name->m_str.c_str()); ErrorList_AddItem_CurrentFile(typeNameNode->m_scopeNameList->m_scopeName->m_name->m_lineNo, typeNameNode->m_scopeNameList->m_scopeName->m_name->m_columnNo, semantic_error_base_type, buf); } } } auto it = std::find(baseTypeNodes.begin(), baseTypeNodes.begin() + i, typeNode); if(it != baseTypeNodes.begin() + i) { size_t index = it - baseTypeNodes.begin(); char buf[512]; sprintf_s(buf, "\'%s\' : is already a direct base class, the previous declaration is at line %d, column %d", typeNameNode->m_scopeNameList->m_scopeName->m_name->m_str.c_str(), baseTypeNameNodes[index]->m_scopeNameList->m_scopeName->m_name->m_lineNo, baseTypeNameNodes[index]->m_scopeNameList->m_scopeName->m_name->m_columnNo); ErrorList_AddItem_CurrentFile(typeNameNode->m_scopeNameList->m_scopeName->m_name->m_lineNo, typeNameNode->m_scopeNameList->m_scopeName->m_name->m_columnNo, semantic_error_base_redeclared, buf); } } }
TypeCategory TemplateParameterTypeNode::getTypeCategory(TemplateArguments* templateArguments) { TypeNode* actualTypeNode = templateArguments->findTypeNode(m_name); return actualTypeNode->getTypeCategory(templateArguments); }