================ @@ -911,6 +916,63 @@ static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) { Summary->setLive(true); } +// Return true if the User U is reachable from a non-vtable user +// through the use-def chain. +static bool hasNonVTableUsers(const User *U, CXXABI *ABI) { + LLVM_DEBUG(dbgs() << "Check if " << *U << "has vtable users\n"); + if (isa<Instruction>(U)) { + // If the type info is used in dynamic_cast or exception handling, + // its user must be the instruction. + return true; + } + + // The virtual table type is either a struct of arrays. For example: + // @vtable = constant { [3 x ptr] } { [3 x ptr] [ ptr null, ptr @rtti, ptr @vf] } + // + // In this case, the user of @rtti is an anonymous ConstantArray. + // Therefore, if the user of the type information is anonymous, + // we need to perform a depth-first search (DFS) to locate its named users. + // + // And we also need to iterate its users if the current user is the type + // info global variable itself. + StringRef Name = U->getName(); + if (Name.empty() || ABI->isTypeInfo(Name)) { + for (const User *It : U->users()) + if (hasNonVTableUsers(It, ABI)) + return true; + return false; + } + + if (!ABI->isVTable(Name)) + return true; + + return false; +} + +static void analyzeRTTIVars(ModuleSummaryIndex &Index, const Module &M) { + Triple TT(M.getTargetTriple()); + + std::unique_ptr<CXXABI> ABI = CXXABI::Create(TT); + if (!ABI) + return; + + for (const GlobalVariable &GV : M.globals()) { + if (!ABI->isTypeInfo(GV.getName())) + continue; + + if (hasNonVTableUsers(&GV, ABI.get())) { + std::string TypeName = + ABI->getTypeNameFromTypeInfo(GV.getName()); ---------------- teresajohnson wrote:
Perhaps we can centralize this somewhere, but in a slightly different way. As noted in another of my follow on comments in this reply, selecting the Itanium ABI just for Linux is too restrictive. A couple of possibilities: 1. Set the ABI in the front end on a module flag (i.e. Itanium or Microsoft), and query that in CXXABI::Create. I.e. see uses in Clang of Module::addModuleFlag. 2. Centralize somewhere the deduction like your getTypeNameFromTypeInfo, but hardcoded to the Itanium ABI conversion like we are doing in WPD - and something like a "hasKnownABI" (not sure that is the best name though) that checks if the prefix is recognized and expect users to guard the handling by that, and assert it is true in the conversion functions. This would be analogous to what is currently happening in WPD but refactored out of there as well. Doing 2 might be a temporary solution with a TODO to do 1. https://github.com/llvm/llvm-project/pull/126336 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits