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; }
/// ValueEnumerator - Enumerate module-level information. ValueEnumerator::ValueEnumerator(const llvm::Module &M, bool ShouldPreserveUseListOrder) : HasMDString(false), HasDILocation(false), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) { assert(!ShouldPreserveUseListOrder && "not supported UseListOrders = predictUseListOrder(M)"); // Enumerate the global variables. for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) EnumerateValue(I); // Enumerate the functions. for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { EnumerateValue(I); EnumerateAttributes(cast<Function>(I)->getAttributes()); } // Enumerate the aliases. for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) EnumerateValue(I); // Remember what is the cutoff between globalvalue's and other constants. unsigned FirstConstant = Values.size(); // Enumerate the global variable initializers. for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (I->hasInitializer()) EnumerateValue(I->getInitializer()); // Enumerate the aliasees. for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) EnumerateValue(I->getAliasee()); // Enumerate the metadata type. // // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode // only encodes the metadata type when it's used as a value. EnumerateType(Type::getMetadataTy(M.getContext())); // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M.getValueSymbolTable()); EnumerateNamedMetadata(M); SmallVector<std::pair<unsigned, MDNode *>, 8> MDs; // Enumerate types used by function bodies and argument lists. for (const Function &F : M) { for (const Argument &A : F.args()) EnumerateType(A.getType()); for (const BasicBlock &BB : F) for (const Instruction &I : BB) { for (const Use &Op : I.operands()) { auto *MD = dyn_cast<MetadataAsValue>(&Op); if (!MD) { EnumerateOperandType(Op); continue; } // Local metadata is enumerated during function-incorporation. if (isa<LocalAsMetadata>(MD->getMetadata())) continue; EnumerateMetadata(MD->getMetadata()); } EnumerateType(I.getType()); if (const CallInst *CI = dyn_cast<CallInst>(&I)) EnumerateAttributes(CI->getAttributes()); else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) EnumerateAttributes(II->getAttributes()); // Enumerate metadata attached with this instruction. MDs.clear(); I.getAllMetadataOtherThanDebugLoc(MDs); for (unsigned i = 0, e = MDs.size(); i != e; ++i) EnumerateMetadata(MDs[i].second); #if LLVM_VERSION >= 37 if (I.getDebugLoc()) { MDNode* Scope = I.getDebugLoc().getScope(); if (Scope) EnumerateMetadata(Scope); DILocation *IA = I.getDebugLoc().getInlinedAt(); if (IA) EnumerateMetadata(IA); } #else if (!I.getDebugLoc().isUnknown()) { MDNode *Scope, *IA; I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext()); if (Scope) EnumerateMetadata(Scope); if (IA) EnumerateMetadata(IA); } #endif } } // Optimize constant ordering. OptimizeConstants(FirstConstant, Values.size()); }