diff --git a/BreakingChanges.md b/BreakingChanges.md index f113d64b3c..c149ab7c86 100644 --- a/BreakingChanges.md +++ b/BreakingChanges.md @@ -2,7 +2,10 @@ ## development HEAD -*None* +- Removed the CRTP-template `ProjectIRDBBase`. Use the concept `ProjectIRDB` instead. +- Remove `EdgeFunction::equals`. Use `operator==` instead. +- Remove ctor-overloads of `LLVMProjectIRDB` that use the `EnableOpaquePointers` parameter. LLVM is removing support for opaque pointers. Use the other ctors instead. +- Removed type-trait `has_getAsJson`, as it is not used in our codebase anymore. We switched from `getAsJson` to `printAsJson` a while ago. ## v2604 diff --git a/include/phasar/DB.h b/include/phasar/DB.h index 294b4e2bb6..430bd5786b 100644 --- a/include/phasar/DB.h +++ b/include/phasar/DB.h @@ -12,6 +12,5 @@ #include "phasar/Config/phasar-config.h" #include "phasar/DB/ProjectIRDB.h" -#include "phasar/DB/ProjectIRDBBase.h" #endif // PHASAR_DB_H diff --git a/include/phasar/DB/ProjectIRDB.h b/include/phasar/DB/ProjectIRDB.h index c630be0765..26e3f93d3d 100644 --- a/include/phasar/DB/ProjectIRDB.h +++ b/include/phasar/DB/ProjectIRDB.h @@ -111,4 +111,11 @@ concept ProjectIRDB = requires ProjectSymbolTable; }; + +// NOLINTNEXTLINE(readability-identifier-naming) +auto IRDBGetFunctionDef(const ProjectIRDB auto *IRDB) noexcept { + return [IRDB](llvm::StringRef Name) { + return IRDB->getFunctionDefinition(Name); + }; +} } // namespace psr diff --git a/include/phasar/DB/ProjectIRDBBase.h b/include/phasar/DB/ProjectIRDBBase.h index 0fccf84f0d..6c9becd8a8 100644 --- a/include/phasar/DB/ProjectIRDBBase.h +++ b/include/phasar/DB/ProjectIRDBBase.h @@ -181,14 +181,6 @@ class LLVM_DEPRECATED( } }; -template -// NOLINTNEXTLINE(readability-identifier-naming) -auto IRDBGetFunctionDef(const ProjectIRDBBase *IRDB) noexcept { - return [IRDB](llvm::StringRef Name) { - return IRDB->getFunctionDefinition(Name); - }; -} - } // namespace psr #endif // PHASAR_DB_PROJECTIRDBBASE_H diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h index 3f717759e1..4d64aee5de 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h @@ -412,15 +412,6 @@ class [[clang::trivial_abi]] EdgeFunction final : EdgeFunctionBase { LHS.VTAndHeapAlloc.getPointer()->equals(LHS.EF, RHS.EF); } - template - requires(!std::is_same_v>) - [[nodiscard]] PSR_DEPRECATED( - "With C++20, we do not need this helper anymore, use operator== instead", - "operator==") bool equals(EdgeFunctionRef Other) - const noexcept { - return *this == Other; - } - template requires(!std::is_same_v>) [[nodiscard]] bool diff --git a/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h b/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h index 3f1218d9dc..3fcc57683e 100644 --- a/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h +++ b/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h @@ -19,7 +19,6 @@ #include "phasar/Config/Configuration.h" #include "phasar/ControlFlow/SparseCFGProvider.h" -#include "phasar/DB/ProjectIRDBBase.h" #include "phasar/DataFlow/IfdsIde/EdgeFunction.h" #include "phasar/DataFlow/IfdsIde/EdgeFunctionStats.h" #include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h" diff --git a/include/phasar/Domain/AnalysisDomain.h b/include/phasar/Domain/AnalysisDomain.h index 6715ad0554..be0163e89b 100644 --- a/include/phasar/Domain/AnalysisDomain.h +++ b/include/phasar/Domain/AnalysisDomain.h @@ -72,7 +72,7 @@ struct AnalysisDomain { // Inter-procedural control flow --- Specifies the type of the // inter-procedural control-flow graph to be used. using i_t = void; - // The ProjectIRDB type to use. Must inherit from the ProjectIRDBBase CRTP + // The ProjectIRDB type to use. Must conform to the ProjectIRDB concept // template using db_t = void; // Lattice element --- Specifies the type of the underlying lattice; the value diff --git a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h index 337ac8ce64..cea6d7afbc 100644 --- a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h +++ b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h @@ -10,7 +10,6 @@ #ifndef PHASAR_PHASARLLVM_DB_LLVMPROJECTIRDB_H #define PHASAR_PHASARLLVM_DB_LLVMPROJECTIRDB_H -#include "phasar/DB/ProjectIRDBBase.h" #include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h" #include "phasar/Utils/MaybeUniquePtr.h" @@ -29,37 +28,21 @@ #include namespace psr { -class LLVMProjectIRDB; -template <> struct ProjectIRDBTraits { +/// \brief Project IR Database that manages a LLVM IR module. +class LLVMProjectIRDB { + +public: using n_t = const llvm::Instruction *; using f_t = const llvm::Function *; using m_t = const llvm::Module *; using g_t = const llvm::GlobalVariable *; -}; -/// \brief Project IR Database that manages a LLVM IR module. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -class LLVMProjectIRDB : public ProjectIRDBBase { -#pragma GCC diagnostic pop - friend ProjectIRDBBase; - -public: /// Reads and parses the given LLVM IR file and owns the resulting IR Module. /// If an error occurs, an error message is written to stderr and subsequent /// calls to isValid() return false. explicit LLVMProjectIRDB(const llvm::Twine &IRFileName); - /// Reads and parses the given LLVM IR file and owns the resulting IR Module. - /// If an error occurs, an error message is written to stderr and subsequent - /// calls to isValid() return false. - [[deprecated("When moving to the next LLVM version, opaque pointers support " - "is removed completely. Please use one of the other " - "constructors of LLVMProjectIRDB.")]] - explicit LLVMProjectIRDB(const llvm::Twine &IRFileName, - bool EnableOpaquePointers); - /// Initializes the new ProjectIRDB with the given IR Module _without_ taking /// ownership. The module is optionally being preprocessed. /// @@ -83,15 +66,6 @@ class LLVMProjectIRDB : public ProjectIRDBBase { /// calls to isValid() return false. explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf); - /// Parses the given LLVM IR file and owns the resulting IR Module. - /// If an error occurs, an error message is written to stderr and subsequent - /// calls to isValid() return false. - [[deprecated("When moving to the next LLVM version, opaque pointers support " - "is removed completely. Please use one of the other " - "constructors of LLVMProjectIRDB.")]] - explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf, - bool EnableOpaquePointers); - LLVMProjectIRDB(const LLVMProjectIRDB &) = delete; LLVMProjectIRDB &operator=(const LLVMProjectIRDB &) = delete; @@ -115,27 +89,37 @@ class LLVMProjectIRDB : public ProjectIRDBBase { [[nodiscard]] static LLVMProjectIRDB loadOrExit(const llvm::Twine &IRFileName, bool EnableOpaquePointers) = delete; - /// Also use the const overload - using ProjectIRDBBase::getFunction; /// Non-const overload [[nodiscard]] llvm::Function *getFunction(llvm::StringRef FunctionName) { + assert(isValid()); + return Mod->getFunction(FunctionName); + } + /// Returns the function if available, nullptr/nullopt otherwise. + [[nodiscard]] f_t getFunction(llvm::StringRef FunctionName) const { + assert(isValid()); return Mod->getFunction(FunctionName); } - /// Also use the const overload - using ProjectIRDBBase::getFunctionDefinition; - /// Non-const overload + /// Returns a mutable pointer to the function's definition if available, null + /// otherwise. [[nodiscard]] llvm::Function * getFunctionDefinition(llvm::StringRef FunctionName); - /// Also use the const overload - using ProjectIRDBBase::getModule; - /// Non-const overload + /// Returns the function's definition if available, null otherwise. + [[nodiscard]] f_t getFunctionDefinition(llvm::StringRef FunctionName) const; + + /// Returns the managed module [[nodiscard]] llvm::Module *getModule() noexcept { return Mod.get(); } + /// Returns the managed module + [[nodiscard]] const llvm::Module *getModule() const noexcept { + return Mod.get(); + } + /// Similar to getInstruction(size_t), but is also able to return global /// variables by id [[nodiscard]] const llvm::Value *getValueFromId(size_t Id) const noexcept { + assert(isValid()); return Id < IdToInst.size() ? IdToInst[Id] : nullptr; } @@ -167,48 +151,41 @@ class LLVMProjectIRDB : public ProjectIRDBBase { /// Returns a range of all global variables (and global constants, e.g, string /// literals) in the managed module [[nodiscard]] auto getAllGlobals() const { + assert(isValid()); return llvm::map_range(std::as_const(*Mod).globals(), Ref2PointerConverter{}); } explicit operator bool() const noexcept { return isValid(); } -private: - [[nodiscard]] m_t getModuleImpl() const noexcept { return Mod.get(); } - [[nodiscard]] bool debugInfoAvailableImpl() const; - [[nodiscard]] FunctionRange getAllFunctionsImpl() const { - return llvm::map_range(ProjectIRDBBase::getModule()->functions(), + [[nodiscard]] bool debugInfoAvailable() const; + [[nodiscard]] FunctionRange getAllFunctions() const { + return llvm::map_range(getModule()->functions(), Ref2PointerConverter{}); } - [[nodiscard]] f_t getFunctionImpl(llvm::StringRef FunctionName) const { - return Mod->getFunction(FunctionName); - } - [[nodiscard]] f_t - getFunctionDefinitionImpl(llvm::StringRef FunctionName) const; - [[nodiscard]] bool - hasFunctionImpl(llvm::StringRef FunctionName) const noexcept { + + [[nodiscard]] bool hasFunction(llvm::StringRef FunctionName) const noexcept { + assert(isValid()); return Mod->getFunction(FunctionName) != nullptr; } - [[nodiscard]] f_t getFunctionOfImpl(n_t Inst) const { - assert(Inst != nullptr); - return Inst->getFunction(); - } + [[nodiscard]] g_t getGlobalVariable(llvm::StringRef GlobalVariableName) const; [[nodiscard]] g_t - getGlobalVariableImpl(llvm::StringRef GlobalVariableName) const; - [[nodiscard]] g_t - getGlobalVariableDefinitionImpl(llvm::StringRef GlobalVariableName) const; - [[nodiscard]] size_t getNumInstructionsImpl() const noexcept { + getGlobalVariableDefinition(llvm::StringRef GlobalVariableName) const; + + [[nodiscard]] size_t getNumInstructions() const noexcept { return IdToInst.size() - IdOffset; } - [[nodiscard]] size_t getNumFunctionsImpl() const noexcept { + [[nodiscard]] size_t getNumFunctions() const noexcept { + assert(isValid()); return Mod->size(); } - [[nodiscard]] size_t getNumGlobalsImpl() const noexcept { + [[nodiscard]] size_t getNumGlobals() const noexcept { + assert(isValid()); return Mod->global_size(); } - [[nodiscard]] n_t getInstructionImpl(size_t Id) const noexcept { + [[nodiscard]] n_t getInstruction(size_t Id) const noexcept { // Effectively make use of integer overflow here... if (Id - IdOffset < IdToInst.size() - IdOffset) { return llvm::cast(IdToInst[Id]); @@ -216,21 +193,22 @@ class LLVMProjectIRDB : public ProjectIRDBBase { return n_t{}; } - [[nodiscard]] auto getAllInstructionsImpl() const noexcept { + [[nodiscard]] auto getAllInstructions() const noexcept { return llvm::map_range( llvm::ArrayRef(IdToInst).drop_front(IdOffset), [](const llvm::Value *V) { return llvm::cast(V); }); } - [[nodiscard]] size_t getInstructionIdImpl(n_t Inst) const { + [[nodiscard]] size_t getInstructionId(n_t Inst) const { auto It = InstToId.find(Inst); assert(It != InstToId.end()); return It->second; } - [[nodiscard]] bool isValidImpl() const noexcept; + [[nodiscard]] bool isValid() const noexcept; - void dumpImpl() const; + void dump() const; +private: void initInstructionIds(); /// XXX Later we might get rid of the metadata IDs entirely and therefore of /// the preprocessing as well @@ -250,7 +228,6 @@ class LLVMProjectIRDB : public ProjectIRDBBase { const llvm::Value *fromMetaDataId(const LLVMProjectIRDB &IRDB, llvm::StringRef Id); -extern template class ProjectIRDBBase; } // namespace psr #endif // PHASAR_PHASARLLVM_DB_LLVMPROJECTIRDB_H diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAllocSitesAwareIDEProblem.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAllocSitesAwareIDEProblem.h index bd0e9bb04e..0d67e364da 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAllocSitesAwareIDEProblem.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAllocSitesAwareIDEProblem.h @@ -94,7 +94,7 @@ class DefaultAllocSitesAwareIDEProblem /// \note It is useful to use an instance of FilteredAliasSet for the alias /// information to lower suprious aliases explicit DefaultAllocSitesAwareIDEProblem( - const ProjectIRDBBase *IRDB, LLVMAliasInfoRef AS, + const db_t *IRDB, LLVMAliasInfoRef AS, std::vector EntryPoints, std::optional ZeroValue) noexcept(std::is_nothrow_move_constructible_v) diff --git a/include/phasar/Utils/TypeTraits.h b/include/phasar/Utils/TypeTraits.h index 95c02db718..e81d94d42b 100644 --- a/include/phasar/Utils/TypeTraits.h +++ b/include/phasar/Utils/TypeTraits.h @@ -238,15 +238,6 @@ constexpr size_t variant_idx = detail::variant_idx::value; template using ElementType = typename detail::ElementType::type; -template -struct [[deprecated("getAsJson should not be used anymore. Use printAsJson " - "instead")]] has_getAsJson : std::false_type {}; // NOLINT -template -struct [[deprecated( - "getAsJson should not be used anymore. Use printAsJson " - "instead")]] has_getAsJson() - .getAsJson())>> - : std::true_type {}; // NOLINT struct TrueFn { template diff --git a/lib/DB/DB.cppm b/lib/DB/DB.cppm index 2705174b50..9c8513578a 100644 --- a/lib/DB/DB.cppm +++ b/lib/DB/DB.cppm @@ -7,8 +7,6 @@ export module phasar.db; export namespace psr { using psr::IRDBGetFunctionDef; using psr::ProjectIRDB; -using psr::ProjectIRDBBase; -using psr::ProjectIRDBTraits; using psr::ProjectSymbolTable; } // namespace psr diff --git a/lib/PhasarLLVM/DB/DB.cppm b/lib/PhasarLLVM/DB/DB.cppm index ec8a41b961..fb58a074c4 100644 --- a/lib/PhasarLLVM/DB/DB.cppm +++ b/lib/PhasarLLVM/DB/DB.cppm @@ -7,5 +7,4 @@ export module phasar.llvm.db; export namespace psr { using psr::fromMetaDataId; using psr::LLVMProjectIRDB; -using psr::ProjectIRDBTraits; } // namespace psr diff --git a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp index f6fe8de817..a44aa6a360 100644 --- a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp +++ b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp @@ -27,19 +27,6 @@ namespace psr { static_assert(ProjectIRDB); -[[deprecated]] -static void setOpaquePointersForCtx(llvm::LLVMContext &Ctx, bool Enable) { -#if LLVM_VERSION_MAJOR >= 15 && LLVM_VERSION_MAJOR < 17 - if (!Enable) { - Ctx.setOpaquePointers(false); - } -#elif LLVM_VERSION_MAJOR < 15 - if (Enable) { - Ctx.enableOpaquePointers(); - } -#endif -} - namespace { enum class IRDBParsingError { CouldNotParse = 1, @@ -153,25 +140,6 @@ LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName) preprocessModule(NonConst); } -LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName, - bool EnableOpaquePointers) - : Ctx(new llvm::LLVMContext()) { - setOpaquePointersForCtx(*Ctx, EnableOpaquePointers); - auto M = getParsedIRModuleOrErr(IRFileName, *Ctx); - - if (!M) { - llvm::WithColor::error() - << "Could not load LLVM-" << LLVM_VERSION_MAJOR << " IR file " - << IRFileName << ": " << M.getError().message() << '\n'; - return; - } - - auto *NonConst = M->get(); - Mod = std::move(M.get()); - ModulesToSlotTracker::setMSTForModule(Mod.get()); - preprocessModule(NonConst); -} - void LLVMProjectIRDB::initInstructionIds() { assert(Mod != nullptr); size_t Id = 0; @@ -271,23 +239,6 @@ LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf) ModulesToSlotTracker::setMSTForModule(Mod.get()); preprocessModule(NonConst); } -LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf, - bool EnableOpaquePointers) - : Ctx(new llvm::LLVMContext()) { - setOpaquePointersForCtx(*Ctx, EnableOpaquePointers); - auto M = getParsedIRModuleOrErr(Buf, *Ctx); - if (!M) { - llvm::WithColor::error() << "Could not load " << LLVM_VERSION_MAJOR - << " IR buffer: " << Buf.getBufferIdentifier() - << ": " << M.getError().message() << '\n'; - return; - } - - auto *NonConst = M->get(); - Mod = std::move(M.get()); - ModulesToSlotTracker::setMSTForModule(Mod.get()); - preprocessModule(NonConst); -} LLVMProjectIRDB::~LLVMProjectIRDB() { if (Mod) { @@ -305,29 +256,32 @@ internalGetFunctionDefinition(const llvm::Module &M, return nullptr; } -[[nodiscard]] bool LLVMProjectIRDB::debugInfoAvailableImpl() const { +[[nodiscard]] bool LLVMProjectIRDB::debugInfoAvailable() const { + assert(isValid()); return Mod->getNamedMetadata("llvm.dbg.cu") != nullptr; } /// Non-const overload [[nodiscard]] llvm::Function * LLVMProjectIRDB::getFunctionDefinition(llvm::StringRef FunctionName) { + assert(isValid()); return internalGetFunctionDefinition(*Mod, FunctionName); } [[nodiscard]] const llvm::Function * -LLVMProjectIRDB::getFunctionDefinitionImpl(llvm::StringRef FunctionName) const { +LLVMProjectIRDB::getFunctionDefinition(llvm::StringRef FunctionName) const { + assert(isValid()); return internalGetFunctionDefinition(*Mod, FunctionName); } [[nodiscard]] const llvm::GlobalVariable * -LLVMProjectIRDB::getGlobalVariableImpl( - llvm::StringRef GlobalVariableName) const { +LLVMProjectIRDB::getGlobalVariable(llvm::StringRef GlobalVariableName) const { + assert(isValid()); return Mod->getGlobalVariable(GlobalVariableName, true); } [[nodiscard]] const llvm::GlobalVariable * -LLVMProjectIRDB::getGlobalVariableDefinitionImpl( +LLVMProjectIRDB::getGlobalVariableDefinition( llvm::StringRef GlobalVariableName) const { const auto *G = getGlobalVariable(GlobalVariableName); if (G && !G->isDeclaration()) { @@ -336,9 +290,14 @@ LLVMProjectIRDB::getGlobalVariableDefinitionImpl( return nullptr; } -bool LLVMProjectIRDB::isValidImpl() const noexcept { return Mod != nullptr; } +bool LLVMProjectIRDB::isValid() const noexcept { return Mod != nullptr; } -void LLVMProjectIRDB::dumpImpl() const { +void LLVMProjectIRDB::dump() const { + if (!isValid()) { + llvm::dbgs() << "\n"; + llvm::dbgs().flush(); + return; + } llvm::dbgs() << *Mod; llvm::dbgs().flush(); } @@ -383,8 +342,6 @@ void LLVMProjectIRDB::insertFunction(llvm::Function *F, bool DoPreprocessing) { assert(InstToId.size() == IdToInst.size()); } -template class ProjectIRDBBase; - } // namespace psr const llvm::Value *psr::fromMetaDataId(const LLVMProjectIRDB &IRDB, diff --git a/lib/Utils/Utils.cppm b/lib/Utils/Utils.cppm index 42f1f1af2e..acc33da410 100644 --- a/lib/Utils/Utils.cppm +++ b/lib/Utils/Utils.cppm @@ -173,7 +173,6 @@ using psr::forward_like; using psr::getLibCSummary; using psr::has_adl_to_string_v; using psr::has_erase_iterator_v; -using psr::has_getAsJson; using psr::has_getHashCode; using psr::has_isInteresting_v; using psr::has_llvm_dense_map_info;