static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) { if (Arg == "-") return true; for (llvm::StringSet<>::const_iterator I = Prefixes.begin(), E = Prefixes.end(); I != E; ++I) if (Arg.startswith(I->getKey())) return false; return true; }
static bool validateSymbolSet(DiagnosticEngine &diags, llvm::StringSet<> symbols, llvm::Module &IRModule, bool diagnoseExtraSymbolsInTBD) { auto error = false; // Diff the two sets of symbols, flagging anything outside their intersection. // Delay the emission of errors for things in the IR but not TBD, so we can // sort them to get a stable order. std::vector<StringRef> irNotTBD; for (auto &nameValue : IRModule.getValueSymbolTable()) { auto name = nameValue.getKey(); auto value = nameValue.getValue(); if (auto GV = dyn_cast<llvm::GlobalValue>(value)) { // Is this a symbol that should be listed? auto externallyVisible = GV->hasExternalLinkage() && !GV->hasHiddenVisibility(); if (!GV->isDeclaration() && externallyVisible) { // Is it listed? if (!symbols.erase(name)) irNotTBD.push_back(name); } } else { assert(symbols.find(name) == symbols.end() && "non-global value in value symbol table"); } } std::sort(irNotTBD.begin(), irNotTBD.end()); for (auto &name : irNotTBD) { diags.diagnose(SourceLoc(), diag::symbol_in_ir_not_in_tbd, name, Demangle::demangleSymbolAsString(name)); error = true; } if (diagnoseExtraSymbolsInTBD) { // Look for any extra symbols. for (auto &name : sortSymbols(symbols)) { diags.diagnose(SourceLoc(), diag::symbol_in_tbd_not_in_ir, name, Demangle::demangleSymbolAsString(name)); error = true; } } if (error) { diags.diagnose(SourceLoc(), diag::tbd_validation_failure); } return error; }