llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Hassan Sajjad (HassanSajjad-302) <details> <summary>Changes</summary> This WIP pull request adds partial support for my draft [N2978](https://htmlpreview.github.io/?https://github.com/HassanSajjad-302/iso-papers/blob/main/generated/my-paper.html). This paper allows for building C++20 modules and header-units without the need to scan them first. This allows for improved compilation support. In my paper, I have referred to a sample implementation of the paper, a library [ipc2978api](https://github.com/HassanSajjad-302/ipc2978api), that compiler and build-systems can use to achieve non-scanning builds. ipc2978api has a complete cross-platform implementation of my paper with error-handling. The code coverage is 100%. In it, I define a type `IPCManagerCompiler` that the compiler can use to manage the interaction with the build-system. It has seven public methods that are to be used by the compiler. ```cpp // IPCManagerCompiler class functions [[nodiscard]] tl::expected<BTCModule, string> receiveBTCModule(const CTBModule &moduleName) const; [[nodiscard]] tl::expected<BTCNonModule, string> receiveBTCNonModule(const CTBNonModule &nonModule) const; [[nodiscard]] tl::expected<void, string> sendCTBLastMessage(const CTBLastMessage &lastMessage) const; [[nodiscard]] tl::expected<void, string> sendCTBLastMessage(const CTBLastMessage &lastMessage, const string &bmiFile, const string &filePath) const; static tl::expected<ProcessMappingOfBMIFile, string> readSharedMemoryBMIFile(const BMIFile &file); static tl::expected<void, string> closeBMIFileMapping(const ProcessMappingOfBMIFile &processMappingOfBMIFile); void closeConnection() const; // A global function [[nodiscard]] tl::expected<IPCManagerCompiler, string> makeIPCManagerCompiler(string BMIIfHeaderUnitObjOtherwisePath); ``` `tl::expected` is of this [library](https://github.com/TartanLlama/expected). It is basically `std::expected` for C++17 which is used for LLVM. While `CTB` and `BTC` mean compiler to build-system and build-system to compiler respectively. These are used to designate the message-type in the communication. This is mentioned in my paper. 1) The First function is to get module from build-system. 2) The Second is to get non-module(header-unit/header-file). 3) The Third and Fourth send the last-message. These include fields like exit-status, header-files, output string, logical-name (If the module-compilation had any) and file output. 4) This is to be used if a PCM file is to be shared. This will create a shared memory file. So other processes don't have to read from the disk. 5) This is to be used to read the received PCM files. 6) The above function returns a `ProcessMappingOfBMIFile` that can be passed to this function to close the mapping. 7) This is for closing the connection. Calling Six and Seven isn't necessary since OS closes descriptors on process exit. Calling `closeBMIFileMapping` will not close the mapping even if it is the only compilation currently referencing it. Since build-system will have it open anyway. Build-system will close its mapping once all compilations that might require the mapping have concluded. `makeIPCManagerCompiler` function can be used to create `IPCManagerCompiler`. PCM file-path is to be passed if header-unit is being compiled. And object file-path is to be passed otherwise. The build-system is required to pass the requisite options to the compiler. Of these seven functions, I have added support for the first one in this pull-request. This does few modifications to the source-code. Instead, it compiles the ipc2978api as part of the Clang source code. It has a `ClangTest.cpp` which is copied to the LLVM repo as the unit test. This WIP test will test the Clang support for my paper. Currently, it only tests the first function. It invokes the compilation of a `main.cpp` with `noScanIPC` flag. This `main.cpp` file depends on `mod.cppm`, `mod1.cppm`, and `mod2.cppm`. These modules are already compiled and are passed to the compiler by the test using `IPCManagerBS`. After compilation completion, it tests for the existence of the `main.o` which marks the successful completion of the test. Test automatically executes in `build-dir/bin` directory where the clang binary exists. `clang/IPC2978/lib/setup.py` copies the test, source-files and header-files from ipc2978api to the LLVM repo. ipc2978api and LLVM repo should be in the same directory. `setup.py` adjusts the includes in ipc2978api source-files to point to ipc2978api headers in the LLVM repo. This also uncomments a definition in `ClangTest.cpp` that allows it to integrate with gtest. I opened this half-baked pull-request to request assistance and feedback to expedite the completion. Once this is completed, I expect to very quickly add support for this in my software [HMake](https://github.com/HassanSajjad-302/HMake). And then compile Boost with Big header-units without scanning. Big header-units will be my software feature built on top of this. It will allow amalgamating all header-files in a directory in a single heder-unit. I already compiled 25 Boost libraries with header-units with scanning with MSVC. HMake will also support Clang's 2-phase compilation with this approach. Compilation will share the Fat PCM which will be passed to other compilations if free threads are available. And this compilation will be signaled to produce the object-file. So only one process is needed instead of three (scanning, Fat PCM, object-file). HMake will also support [this](https://isocpp.org/files/papers/P3057R0.html#hash-of-declarations-solution) proposed by @<!-- -->ChuanqiXu9 and [this](https://lists.isocpp.org/sg15/2023/11/2106.php) as-well. While ipc2978api currently does not support 2-phase compilation and declaration hashing, I can add this first. It is just fill in the blanks since the challenging work of a connection establishment, memory-mapped files, error-handling, etc is all complete. And can prioritize this with C++20 modules support before C++20 header-units support in HMake. No other build-system can support C++20 modules the way HMake can. HMake has a next-gen build algorithm that allows for dynamic nodes and edges. Even with all this stuff, due to its next-gen architecture, it would still be extremely fast and memory efficient. It can exploit missed parallelization opportunities in the LLVM build(if any). Due to these reasons, in the future, I would like to propose it for LLVM as well. @<!-- -->vgvassilev @<!-- -->Bigcheese --- Patch is 183.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147682.diff 25 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+10) - (modified) clang/include/clang/Frontend/CompilerInstance.h (+5) - (added) clang/include/clang/IPC2978/.clang-format-ignore (+1) - (added) clang/include/clang/IPC2978/IPCManagerBS.hpp (+39) - (added) clang/include/clang/IPC2978/IPCManagerCompiler.hpp (+129) - (added) clang/include/clang/IPC2978/Manager.hpp (+135) - (added) clang/include/clang/IPC2978/Messages.hpp (+122) - (added) clang/include/clang/IPC2978/expected.hpp (+2444) - (added) clang/include/clang/IPC2978/rapidhash.h (+574) - (modified) clang/include/clang/Lex/HeaderSearchOptions.h (+5) - (modified) clang/lib/CMakeLists.txt (+1) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CMakeLists.txt (+1) - (modified) clang/lib/Frontend/CompilerInstance.cpp (+26) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+5) - (added) clang/lib/IPC2978/.clang-format-ignore (+1) - (added) clang/lib/IPC2978/CMakeLists.txt (+6) - (added) clang/lib/IPC2978/IPCManagerBS.cpp (+352) - (added) clang/lib/IPC2978/IPCManagerCompiler.cpp (+347) - (added) clang/lib/IPC2978/Manager.cpp (+444) - (added) clang/lib/IPC2978/setup.py (+58) - (modified) clang/unittests/CMakeLists.txt (+6-1) - (added) clang/unittests/IPC2978/.clang-format-ignore (+1) - (added) clang/unittests/IPC2978/CMakeLists.txt (+5) - (added) clang/unittests/IPC2978/IPC2978Test.cpp (+320) ``````````diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 77379f1130149..6a6010b4baa44 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -9416,3 +9416,13 @@ def wasm_opt : Flag<["--"], "wasm-opt">, Group<m_Group>, HelpText<"Enable the wasm-opt optimizer (default)">, MarshallingInfoNegativeFlag<LangOpts<"NoWasmOpt">>; + +def no_scan_ipc : Flag<["-"], "noScanIPC">, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Enable No scan IPC approach">; +def translate_include : Flag<["-"], "translateInclude">, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Consider header includes as header-units">; +def find_include : Flag<["-"], "findIncludes">, + Visibility<[ClangOption, CC1Option]>, + HelpText<"In No Scan IPC approach, compiler will relay the finding includes responsibility to the build-system">; diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 0ae490f0e8073..84a524a549e02 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -16,6 +16,7 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PCHContainerOperations.h" #include "clang/Frontend/Utils.h" +#include "clang/IPC2978/IPCManagerCompiler.hpp" #include "clang/Lex/DependencyDirectivesScanner.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/ModuleLoader.h" @@ -180,6 +181,10 @@ class CompilerInstance : public ModuleLoader { /// The stream for verbose output. raw_ostream *VerboseOutputStream = &llvm::errs(); + /// Pointer for managing communication with build-system if noScan flag is + /// set. + N2978::IPCManagerCompiler *ipcManager = nullptr; + /// Holds information about the output file. /// /// If TempFilename is not empty we must rename it to Filename at the end. diff --git a/clang/include/clang/IPC2978/.clang-format-ignore b/clang/include/clang/IPC2978/.clang-format-ignore new file mode 100644 index 0000000000000..f59ec20aabf58 --- /dev/null +++ b/clang/include/clang/IPC2978/.clang-format-ignore @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/clang/include/clang/IPC2978/IPCManagerBS.hpp b/clang/include/clang/IPC2978/IPCManagerBS.hpp new file mode 100644 index 0000000000000..f9222a55f3fc4 --- /dev/null +++ b/clang/include/clang/IPC2978/IPCManagerBS.hpp @@ -0,0 +1,39 @@ + +#ifndef IPC_MANAGER_BS_HPP +#define IPC_MANAGER_BS_HPP + +#include "clang/IPC2978/Manager.hpp" +#include "clang/IPC2978/Messages.hpp" + +namespace N2978 +{ + +// IPC Manager BuildSystem +class IPCManagerBS : Manager +{ + friend tl::expected<IPCManagerBS, string> makeIPCManagerBS(string BMIIfHeaderUnitObjOtherwisePath); + bool connectedToCompiler = false; + +#ifdef _WIN32 + explicit IPCManagerBS(void *hPipe_); +#else + explicit IPCManagerBS(int fdSocket_); +#endif + + public: + IPCManagerBS(const IPCManagerBS &) = default; + IPCManagerBS &operator=(const IPCManagerBS &) = default; + IPCManagerBS(IPCManagerBS &&) = default; + IPCManagerBS &operator=(IPCManagerBS &&) = default; + tl::expected<void, string> receiveMessage(char (&ctbBuffer)[320], CTB &messageType) const; + [[nodiscard]] tl::expected<void, string> sendMessage(const BTCModule &moduleFile) const; + [[nodiscard]] tl::expected<void, string> sendMessage(const BTCNonModule &nonModule) const; + [[nodiscard]] tl::expected<void, string> sendMessage(const BTCLastMessage &lastMessage) const; + static tl::expected<ProcessMappingOfBMIFile, string> createSharedMemoryBMIFile(const BMIFile &bmiFile); + static tl::expected<void, string> closeBMIFileMapping(const ProcessMappingOfBMIFile &processMappingOfBMIFile); + void closeConnection() const; +}; + +tl::expected<IPCManagerBS, string> makeIPCManagerBS(string BMIIfHeaderUnitObjOtherwisePath); +} // namespace N2978 +#endif // IPC_MANAGER_BS_HPP diff --git a/clang/include/clang/IPC2978/IPCManagerCompiler.hpp b/clang/include/clang/IPC2978/IPCManagerCompiler.hpp new file mode 100644 index 0000000000000..6aba39822d5ac --- /dev/null +++ b/clang/include/clang/IPC2978/IPCManagerCompiler.hpp @@ -0,0 +1,129 @@ + +#ifndef IPC_MANAGER_COMPILER_HPP +#define IPC_MANAGER_COMPILER_HPP + +#include "clang/IPC2978/Manager.hpp" +#include "clang/IPC2978/expected.hpp" + +using std::string_view; +namespace N2978 +{ + +// IPC Manager Compiler +class IPCManagerCompiler : Manager +{ + template <typename T> tl::expected<T, string> receiveMessage() const; + // This is not exposed. sendCTBLastMessage calls this. + [[nodiscard]] tl::expected<void, string> receiveBTCLastMessage() const; + + public: +#ifdef _WIN32 + explicit IPCManagerCompiler(void *hPipe_); +#else + explicit IPCManagerCompiler(int fdSocket_); +#endif + [[nodiscard]] tl::expected<BTCModule, string> receiveBTCModule(const CTBModule &moduleName) const; + [[nodiscard]] tl::expected<BTCNonModule, string> receiveBTCNonModule(const CTBNonModule &nonModule) const; + [[nodiscard]] tl::expected<void, string> sendCTBLastMessage(const CTBLastMessage &lastMessage) const; + [[nodiscard]] tl::expected<void, string> sendCTBLastMessage(const CTBLastMessage &lastMessage, + const string &bmiFile, const string &filePath) const; + static tl::expected<ProcessMappingOfBMIFile, string> readSharedMemoryBMIFile(const BMIFile &file); + static tl::expected<void, string> closeBMIFileMapping(const ProcessMappingOfBMIFile &processMappingOfBMIFile); + void closeConnection() const; +}; + +template <typename T> tl::expected<T, string> IPCManagerCompiler::receiveMessage() const +{ + // Read from the pipe. + char buffer[BUFFERSIZE]; + uint32_t bytesRead; + if (const auto &r = readInternal(buffer); !r) + { + return tl::unexpected(r.error()); + } + else + { + bytesRead = *r; + } + + uint32_t bytesProcessed = 0; + + if constexpr (std::is_same_v<T, BTCModule>) + { + const auto &r = readProcessMappingOfBMIFileFromPipe(buffer, bytesRead, bytesProcessed); + if (!r) + { + return tl::unexpected(r.error()); + } + + const auto &r2 = readVectorOfModuleDepFromPipe(buffer, bytesRead, bytesProcessed); + if (!r2) + { + return tl::unexpected(r2.error()); + } + + BTCModule moduleFile; + moduleFile.requested = *r; + moduleFile.deps = *r2; + if (bytesRead == bytesProcessed) + { + return moduleFile; + } + } + else if constexpr (std::is_same_v<T, BTCNonModule>) + { + const auto &r = readBoolFromPipe(buffer, bytesRead, bytesProcessed); + if (!r) + { + return tl::unexpected(r.error()); + } + + const auto &r2 = readStringFromPipe(buffer, bytesRead, bytesProcessed); + if (!r2) + { + return tl::unexpected(r2.error()); + } + + const auto &r3 = readBoolFromPipe(buffer, bytesRead, bytesProcessed); + if (!r3) + { + return tl::unexpected(r3.error()); + } + + const auto &r4 = readUInt32FromPipe(buffer, bytesRead, bytesProcessed); + if (!r4) + { + return tl::unexpected(r4.error()); + } + + const auto &r5 = readVectorOfHuDepFromPipe(buffer, bytesRead, bytesProcessed); + if (!r5) + { + return tl::unexpected(r5.error()); + } + + BTCNonModule nonModule; + nonModule.isHeaderUnit = *r; + nonModule.filePath = *r2; + nonModule.angled = *r3; + nonModule.fileSize = *r4; + nonModule.deps = *r5; + + if (bytesRead == bytesProcessed) + { + return nonModule; + } + } + else + { + static_assert(false && "Unknown type\n"); + } + + if (bytesRead != bytesProcessed) + { + return tl::unexpected(getErrorString(bytesRead, bytesProcessed)); + } +} +[[nodiscard]] tl::expected<IPCManagerCompiler, string> makeIPCManagerCompiler(string BMIIfHeaderUnitObjOtherwisePath); +} // namespace N2978 +#endif // IPC_MANAGER_COMPILER_HPP diff --git a/clang/include/clang/IPC2978/Manager.hpp b/clang/include/clang/IPC2978/Manager.hpp new file mode 100644 index 0000000000000..580e1878b3ef3 --- /dev/null +++ b/clang/include/clang/IPC2978/Manager.hpp @@ -0,0 +1,135 @@ + +#ifndef MANAGER_HPP +#define MANAGER_HPP + +#include "clang/IPC2978/Messages.hpp" +#include "clang/IPC2978/expected.hpp" + +#include <string> +#include <vector> + +using std::string, std::vector, std::string_view; + +#define BUFFERSIZE 4096 + +#ifdef _WIN32 +// The following variable is used in CreateNamedFunction. +#define PIPE_TIMEOUT 5000 +#endif + +namespace tl +{ +template <typename T, typename U> class expected; +} + +namespace N2978 +{ + +enum class ErrorCategory : uint8_t +{ + NONE, + + // error-category for API errors + READ_FILE_ZERO_BYTES_READ, + INCORRECT_BTC_LAST_MESSAGE, + UNKNOWN_CTB_TYPE, +}; + +string getErrorString(); +string getErrorString(uint32_t bytesRead_, uint32_t bytesProcessed_); +string getErrorString(ErrorCategory errorCategory_); +// to facilitate error propagation. +inline string getErrorString(string err) +{ + return err; +} + +struct ProcessMappingOfBMIFile +{ + string_view file; +#ifdef _WIN32 + void *mapping; + void *view; +#else + void *mapping; + uint32_t mappingSize; +#endif +}; + +class Manager +{ + public: +#ifdef _WIN32 + void *hPipe = nullptr; +#else + int fdSocket = 0; +#endif + + tl::expected<uint32_t, string> readInternal(char (&buffer)[BUFFERSIZE]) const; + tl::expected<void, string> writeInternal(const vector<char> &buffer) const; + + static vector<char> getBufferWithType(CTB type); + static void writeUInt32(vector<char> &buffer, uint32_t value); + static void writeString(vector<char> &buffer, const string &str); + static void writeProcessMappingOfBMIFile(vector<char> &buffer, const BMIFile &file); + static void writeModuleDep(vector<char> &buffer, const ModuleDep &dep); + static void writeHuDep(vector<char> &buffer, const HuDep &dep); + static void writeVectorOfStrings(vector<char> &buffer, const vector<string> &strs); + static void writeVectorOfProcessMappingOfBMIFiles(vector<char> &buffer, const vector<BMIFile> &files); + static void writeVectorOfModuleDep(vector<char> &buffer, const vector<ModuleDep> &deps); + static void writeVectorOfHuDep(vector<char> &buffer, const vector<HuDep> &deps); + + tl::expected<bool, string> readBoolFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<uint32_t, string> readUInt32FromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<string, string> readStringFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<BMIFile, string> readProcessMappingOfBMIFileFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<vector<string>, string> readVectorOfStringFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<ModuleDep, string> readModuleDepFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<vector<ModuleDep>, string> readVectorOfModuleDepFromPipe(char (&buffer)[BUFFERSIZE], + uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<HuDep, string> readHuDepFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<vector<HuDep>, string> readVectorOfHuDepFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead, + uint32_t &bytesProcessed) const; + tl::expected<void, string> readNumberOfBytes(char *output, uint32_t size, char (&buffer)[BUFFERSIZE], + uint32_t &bytesRead, uint32_t &bytesProcessed) const; +}; + +template <typename T, typename... Args> constexpr T *construct_at(T *p, Args &&...args) +{ + return ::new (static_cast<void *>(p)) T(std::forward<Args>(args)...); +} + +template <typename T> T &getInitializedObjectFromBuffer(char (&buffer)[320]) +{ + T &t = reinterpret_cast<T &>(buffer); + construct_at(&t); + return t; +} + +inline std::string to16charHexString(const uint64_t v) +{ + static auto lut = "0123456789abcdef"; + std::string out; + out.resize(16); + for (int i = 0; i < 8; ++i) + { + // extract byte in big-endian order: + const auto byte = static_cast<uint8_t>(v >> ((7 - i) * 8)); + // high nibble: + out[2 * i] = lut[byte >> 4]; + // low nibble: + out[2 * i + 1] = lut[byte & 0xF]; + } + return out; +} + +} // namespace N2978 +#endif // MANAGER_HPP diff --git a/clang/include/clang/IPC2978/Messages.hpp b/clang/include/clang/IPC2978/Messages.hpp new file mode 100644 index 0000000000000..c575e2b3fe09d --- /dev/null +++ b/clang/include/clang/IPC2978/Messages.hpp @@ -0,0 +1,122 @@ +#ifndef MESSAGES_HPP +#define MESSAGES_HPP + +#include <cstdint> +#include <signal.h> +#include <string> +#include <vector> + +using std::string, std::vector; + +namespace N2978 +{ + +// CTB --> Compiler to Build-System +// BTC --> Build-System to Compiler + +// string is 4 bytes that hold the size of the char array, followed by the array. +// vector is 4 bytes that hold the size of the array, followed by the array. +// All fields are sent in declaration order, even if meaningless. + +// Compiler to Build System +// This is the first byte of the compiler to build-system message. +enum class CTB : uint8_t +{ + MODULE = 0, + NON_MODULE = 1, + LAST_MESSAGE = 2, +}; + +// This is sent when the compiler needs a module. +struct CTBModule +{ + string moduleName; +}; + +// This is sent when the compiler needs something else than a module. +// isHeaderUnit is set when the compiler knows that it is a header-unit. +// If findInclude flag is provided, then the compiler sends logicalName, +// Otherwise the compiler sends the full path. +struct CTBNonModule +{ + bool isHeaderUnit = false; + string str; +}; + +// This is the last message sent by the compiler. +struct CTBLastMessage +{ + // Whether the compilation succeeded or failed. + bool exitStatus = false; + // Following fields are meaningless if the compilation failed. + // header-includes discovered during compilation. + vector<string> headerFiles; + // compiler output + string output; + // compiler error output. + // Any IPC related error output should be reported on stderr. + string errorOutput; + // exported module name if any. + string logicalName; + // This is communicated because the receiving process has no + // way to learn the shared memory file size on both Windows + // and Linux without a filesystem call. + // Meaningless if the file compiled is not a module interface unit + // or a header-unit. + uint32_t fileSize = UINT32_MAX; +}; + +// Build System to Compiler +// Unlike CTB, this is not written as the first byte +// since the compiler knows what message it will receive. +enum class BTC : uint8_t +{ + MODULE = 0, + NON_MODULE = 1, + LAST_MESSAGE = 2, +}; + +struct BMIFile +{ + string filePath; + uint32_t fileSize = UINT32_MAX; +}; + +struct ModuleDep +{ + BMIFile file; + string logicalName; +}; + +// Reply for CTBModule +struct BTCModule +{ + BMIFile requested; + vector<ModuleDep> deps; +}; + +struct HuDep +{ + BMIFile file; + string logicalName; + bool angled = false; +}; + +// Reply for CTBNonModule +struct BTCNonModule +{ + bool isHeaderUnit = false; + string filePath; + // if isHeaderUnit == false, the following three are meaning-less. + bool angled = false; + // if isHeaderUnit == true, fileSize of the requested file. + uint32_t fileSize; + vector<HuDep> deps; +}; + +// Reply for CTBLastMessage if the compilation succeeded. +struct BTCLastMessage +{ +}; +} // namespace N2978 +#endif // MESSAGES_HPP diff --git a/clang/include/clang/IPC2978/expected.hpp b/clang/include/clang/IPC2978/expected.hpp new file mode 100644 index 0000000000000..1f92b6b3cd85a --- /dev/null +++ b/clang/include/clang/IPC2978/expected.hpp @@ -0,0 +1,2444 @@ +/// +// expected - An implementation of std::expected with extensions +// Written in 2017 by Sy Brand (tartanll...@gmail.com, @TartanLlama) +// +// Documentation available at http://tl.tartanllama.xyz/ +// +// To the extent possible under law, the author(s) have dedicated all +// copyright and related and neighboring rights to this software to the +// public domain worldwide. This software is distributed without any warranty. +// +// You should have received a copy of the CC0 Public Domain Dedication +// along with this software. If not, see +// <http://creativecommons.org/publicdomain/zero/1.0/>. +/// + +#ifndef TL_EXPECTED_HPP +#define TL_EXPECTED_HPP + +#define TL_EXPECTED_VERSION_MAJOR 1 +#define TL_EXPECTED_VERSION_MINOR 1 +#define TL_EXPECTED_VERSION_PATCH 0 + +#include <exception> +#include <functional> +#include <type_traits> +#include <utility> + +#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) +#define TL_EXPECTED_EXCEPTIONS_ENABLED +#endif + +#if (defined(_MSC_VER) && _MSC_VER == 1900) +#define TL_EXPECTED_MSVC2015 +#define TL_EXPECTED_MSVC2015_CONSTEXPR +#else +#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr +#endif + +#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ + !defined(__clang__)) +#define TL_EXPECTED_GCC49 +#endif + +#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \ + !defined(__clang__)) +#define TL_EXPECTED_GCC54 +#endif + +#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \ + !defined(__clang__)) +#define TL_EXPECTED_GCC55 +#endif + +#if !defined(TL_ASSERT) +//can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug +#if (__cplusplus > 201103L) && !defined(TL_EXPECTED_GCC49) +#include <cassert> +#define TL_ASSERT(x) assert(x) +#else +#define TL_ASSERT(x) +#endif +#endif + +#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ + !defined(__clang__)) +// GCC < 5 doesn't support overloading on const&& for member functions + +#define TL_EXPECTED_NO_CONSTRR +// GCC < 5 doesn't support some standard C++11 type traits +#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + std::has_trivial_copy_constructor<T> +#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::has_trivial_copy_assign<T> + +// This one will be different for GCC 5.7 if it's ever supported +#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ + std::is_trivially_destructible<T> + +// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks +// std::vector for non-copyable types +#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)) +#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +namespace tl { +namespace detail { +template <class T> +struct is_trivially_copy_constructible + : std::is_trivially_copy_constructible<T> {}; +#ifdef _GLIBCXX_VECTOR +template <class T, class A> +struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {}; +#endif +} // namespace detail +} // namespace tl +#endif + +#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + tl::detail::is_trivially_copy_constructible<T> +#define TL_EXPECT... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/147682 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits