void C2Sema::ActOnImport(const char* moduleName_, SourceLocation loc, Token& aliasTok, bool isLocal) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: import " << moduleName_ << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif std::string moduleName = moduleName_; // check if importing own module if (ast.getModuleName() == moduleName) { Diag(loc, diag::err_import_own_module) << moduleName_; return; } // check for duplicate import of module const ImportDecl* old = findModule(moduleName); if (old) { Diag(loc, diag::err_duplicate_import) << moduleName; Diag(old->getLocation(), diag::note_previous_import); return; } std::string name = moduleName; if (aliasTok.is(tok::identifier)) { name = aliasTok.getIdentifierInfo()->getNameStart(); // check if same as normal module name if (name == moduleName) { Diag(aliasTok.getLocation(), diag::err_alias_same_as_module); return; } } ImportDecl* U = new ImportDecl(name, loc, isLocal, moduleName, aliasTok.getLocation()); U->setType(typeContext.getModuleType(U)); ast.addImport(U); addSymbol(U); }
void C2Sema::ActOnModule(const char* name, SourceLocation loc) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA << "SEMA: module " << name << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif if (name[0] == '_' && name[1] == '_') { Diag(loc, diag::err_invalid_symbol_name) << name; return; } if (!islower(name[0]) && !ast.isInterface()) { Diag(loc, diag::err_module_casing); return; } if (strcmp(name, "c2") == 0) { Diag(loc, diag::err_module_c2); return; } if (strcmp(name, "main") == 0) { Diag(loc, diag::err_module_invalid_name) << name; return; } ast.setName(name, loc); ImportDecl* U = new ImportDecl(name, loc, true, name, SourceLocation()); U->setType(typeContext.getModuleType(U)); U->setUsed(); ast.addImport(U); addSymbol(U); }
const C2::ImportDecl* C2Sema::findModule(const std::string& name) const { for (unsigned i=0; i<ast.numImports(); i++) { ImportDecl* D = ast.getImport(i); if (D->getModuleName() == name) return D; } return 0; }
bool C2Builder::checkModuleImports(ParseHelper& helper, Component* component, Module* module, ImportsQueue& queue, const LibInfo* lib) { if (!module->isLoaded()) { assert(lib); if (options.verbose) log(COL_VERBOSE, "parsing (%s) %s", component->getName().c_str(), lib->c2file.c_str()); if (!helper.parse(*component, module, lib->c2file, (options.printAST0 && options.printASTLib))) { return false; } } if (options.verbose) log(COL_VERBOSE, "checking imports for module (%s) %s", component->getName().c_str(), module->getName().c_str()); bool ok = true; const AstList& files = module->getFiles(); for (unsigned a=0; a<files.size(); a++) { AST* ast = files[a]; for (unsigned u=1; u<ast->numImports(); u++) { // NOTE: first import is module decl ImportDecl* D = ast->getImport(u); const std::string& targetModuleName = D->getModuleName(); // handle c2 pseudo-module if (targetModuleName == "c2") { createC2Module(); D->setModule(c2Mod); continue; } const LibInfo* target = libLoader.findModuleLib(targetModuleName); if (!target) { helper.Diags.Report(D->getLocation(), clang::diag::err_unknown_module) << targetModuleName; ok = false; continue; } D->setModule(target->module); if (target->component != component) { // check that imports are in directly dependent component (no indirect component) if (!component->hasDep(target->component)) { helper.Diags.Report(D->getLocation(), clang::diag::err_indirect_component) << component->getName() << target->component->getName() << targetModuleName; ok = false; continue; } } if (target->module->isLoaded()) continue; queue.push_back(targetModuleName); } } return ok; }