Skip to content

Commit 9a43405

Browse files
N2978 90% implemented. Only shared memory PCM files left.
1 parent 59b4074 commit 9a43405

34 files changed

+6163
-24
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9556,3 +9556,7 @@ def wasm_opt : Flag<["--"], "wasm-opt">,
95569556
Group<m_Group>,
95579557
HelpText<"Enable the wasm-opt optimizer (default)">,
95589558
MarshallingInfoNegativeFlag<LangOpts<"NoWasmOpt">>;
9559+
9560+
def no_scan_ipc : Flag<["-", "/"], "noScanIPC">,
9561+
Visibility<[ClangOption, CC1Option, CLOption]>,
9562+
HelpText<"Enable No scan IPC approach">;

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,11 @@ class CompilerInstance : public ModuleLoader {
944944

945945
bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
946946

947+
void makeModuleAndDependenciesVisible(serialization::ModuleFile *ModFile,
948+
Module *Mod);
949+
Module *loadIPCReceivedHeaderUnit(StringRef FileName,
950+
SourceLocation ImportLoc) override;
951+
947952
void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
948953
DependencyCollectors.push_back(std::move(Listener));
949954
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
#ifndef IPC_MANAGER_BS_HPP
3+
#define IPC_MANAGER_BS_HPP
4+
5+
#include "clang/IPC2978/Manager.hpp"
6+
#include "clang/IPC2978/Messages.hpp"
7+
8+
namespace N2978
9+
{
10+
11+
// IPC Manager BuildSystem
12+
class IPCManagerBS : Manager
13+
{
14+
friend tl::expected<IPCManagerBS, std::string> makeIPCManagerBS(std::string BMIIfHeaderUnitObjOtherwisePath);
15+
bool connectedToCompiler = false;
16+
17+
#ifdef _WIN32
18+
explicit IPCManagerBS(void *hPipe_);
19+
#else
20+
explicit IPCManagerBS(int fdSocket_);
21+
#endif
22+
23+
public:
24+
IPCManagerBS(const IPCManagerBS &) = default;
25+
IPCManagerBS &operator=(const IPCManagerBS &) = default;
26+
IPCManagerBS(IPCManagerBS &&) = default;
27+
IPCManagerBS &operator=(IPCManagerBS &&) = default;
28+
tl::expected<void, std::string> receiveMessage(char (&ctbBuffer)[320], CTB &messageType) const;
29+
[[nodiscard]] tl::expected<void, std::string> sendMessage(const BTCModule &moduleFile) const;
30+
[[nodiscard]] tl::expected<void, std::string> sendMessage(const BTCNonModule &nonModule) const;
31+
[[nodiscard]] tl::expected<void, std::string> sendMessage(const BTCLastMessage &lastMessage) const;
32+
static tl::expected<ProcessMappingOfBMIFile, std::string> createSharedMemoryBMIFile(const BMIFile &bmiFile);
33+
static tl::expected<void, std::string> closeBMIFileMapping(const ProcessMappingOfBMIFile &processMappingOfBMIFile);
34+
void closeConnection() const;
35+
};
36+
37+
tl::expected<IPCManagerBS, std::string> makeIPCManagerBS(std::string BMIIfHeaderUnitObjOtherwisePath);
38+
} // namespace N2978
39+
#endif // IPC_MANAGER_BS_HPP
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
2+
#ifndef IPC_MANAGER_COMPILER_HPP
3+
#define IPC_MANAGER_COMPILER_HPP
4+
5+
#include "clang/IPC2978/Manager.hpp"
6+
#include "clang/IPC2978/expected.hpp"
7+
8+
struct CompilerTest;
9+
namespace N2978
10+
{
11+
12+
enum class FileType : uint8_t
13+
{
14+
MODULE,
15+
HEADER_UNIT,
16+
HEADER_FILE
17+
};
18+
19+
struct Response
20+
{
21+
// if type == HEADER_FILE, then fileSize has no meaning
22+
BMIFile file;
23+
FileType type;
24+
bool user;
25+
Response(BMIFile file_, FileType type_, bool user_);
26+
};
27+
28+
// IPC Manager Compiler
29+
class IPCManagerCompiler : Manager
30+
{
31+
friend struct ::CompilerTest;
32+
template <typename T> tl::expected<T, std::string> receiveMessage() const;
33+
// This is not exposed. sendCTBLastMessage calls this.
34+
[[nodiscard]] tl::expected<void, std::string> receiveBTCLastMessage() const;
35+
[[nodiscard]] tl::expected<BTCModule, std::string> receiveBTCModule(const CTBModule &moduleName);
36+
[[nodiscard]] tl::expected<BTCNonModule, std::string> receiveBTCNonModule(const CTBNonModule &nonModule);
37+
38+
std::unordered_map<std::string, Response> responses;
39+
40+
public:
41+
CTBLastMessage lastMessage{};
42+
#ifdef _WIN32
43+
explicit IPCManagerCompiler(void *hPipe_);
44+
#else
45+
explicit IPCManagerCompiler(int fdSocket_);
46+
#endif
47+
48+
// For FileType::HEADER_FILE, it can return FileType::HEADER_UNIT, otherwise it will return the request
49+
// response. Either it will return from the cache or it will fetch it from the build-system
50+
[[nodiscard]] tl::expected<Response, std::string> findResponse(const std::string &logicalName, FileType type);
51+
[[nodiscard]] tl::expected<void, std::string> sendCTBLastMessage(const CTBLastMessage &lastMessage) const;
52+
[[nodiscard]] tl::expected<void, std::string> sendCTBLastMessage(const CTBLastMessage &lastMessage,
53+
const std::string &bmiFile,
54+
const std::string &filePath) const;
55+
static tl::expected<ProcessMappingOfBMIFile, std::string> readSharedMemoryBMIFile(const BMIFile &file);
56+
static tl::expected<void, std::string> closeBMIFileMapping(const ProcessMappingOfBMIFile &processMappingOfBMIFile);
57+
void closeConnection() const;
58+
};
59+
60+
template <typename T> tl::expected<T, std::string> IPCManagerCompiler::receiveMessage() const
61+
{
62+
// Read from the pipe.
63+
char buffer[BUFFERSIZE];
64+
uint32_t bytesRead;
65+
if (const auto &r = readInternal(buffer); !r)
66+
{
67+
return tl::unexpected(r.error());
68+
}
69+
else
70+
{
71+
bytesRead = *r;
72+
}
73+
74+
uint32_t bytesProcessed = 0;
75+
76+
if constexpr (std::is_same_v<T, BTCModule>)
77+
{
78+
const auto &r = readProcessMappingOfBMIFileFromPipe(buffer, bytesRead, bytesProcessed);
79+
if (!r)
80+
{
81+
return tl::unexpected(r.error());
82+
}
83+
84+
const auto &r2 = readBoolFromPipe(buffer, bytesRead, bytesProcessed);
85+
if (!r2)
86+
{
87+
return tl::unexpected(r2.error());
88+
}
89+
90+
const auto &r3 = readVectorOfModuleDepFromPipe(buffer, bytesRead, bytesProcessed);
91+
if (!r3)
92+
{
93+
return tl::unexpected(r3.error());
94+
}
95+
96+
BTCModule moduleFile;
97+
moduleFile.requested = *r;
98+
moduleFile.user = *r2;
99+
moduleFile.modDeps = *r3;
100+
101+
if (bytesRead == bytesProcessed)
102+
{
103+
return moduleFile;
104+
}
105+
}
106+
else if constexpr (std::is_same_v<T, BTCNonModule>)
107+
{
108+
const auto &r = readBoolFromPipe(buffer, bytesRead, bytesProcessed);
109+
if (!r)
110+
{
111+
return tl::unexpected(r.error());
112+
}
113+
114+
const auto &r2 = readBoolFromPipe(buffer, bytesRead, bytesProcessed);
115+
if (!r2)
116+
{
117+
return tl::unexpected(r2.error());
118+
}
119+
120+
const auto &r3 = readStringFromPipe(buffer, bytesRead, bytesProcessed);
121+
if (!r3)
122+
{
123+
return tl::unexpected(r3.error());
124+
}
125+
126+
const auto &r4 = readUInt32FromPipe(buffer, bytesRead, bytesProcessed);
127+
if (!r4)
128+
{
129+
return tl::unexpected(r4.error());
130+
}
131+
132+
const auto &r5 = readVectorOfStringFromPipe(buffer, bytesRead, bytesProcessed);
133+
if (!r5)
134+
{
135+
return tl::unexpected(r5.error());
136+
}
137+
138+
const auto &r6 = readVectorOfHeaderFileFromPipe(buffer, bytesRead, bytesProcessed);
139+
if (!r6)
140+
{
141+
return tl::unexpected(r6.error());
142+
}
143+
144+
const auto &r7 = readVectorOfHuDepFromPipe(buffer, bytesRead, bytesProcessed);
145+
if (!r7)
146+
{
147+
return tl::unexpected(r7.error());
148+
}
149+
150+
BTCNonModule nonModule;
151+
nonModule.isHeaderUnit = *r;
152+
nonModule.user = *r2;
153+
nonModule.filePath = *r3;
154+
nonModule.fileSize = *r4;
155+
nonModule.logicalNames = *r5;
156+
nonModule.headerFiles = *r6;
157+
nonModule.huDeps = *r7;
158+
159+
if (bytesRead == bytesProcessed)
160+
{
161+
return nonModule;
162+
}
163+
}
164+
else
165+
{
166+
static_assert(false && "Unknown type\n");
167+
}
168+
169+
if (bytesRead != bytesProcessed)
170+
{
171+
return tl::unexpected(getErrorString(bytesRead, bytesProcessed));
172+
}
173+
std::string str = __FILE__;
174+
str += ':';
175+
str += std::to_string(__LINE__);
176+
return tl::unexpected(getErrorString("N2978 IPC API internal error" + str));
177+
}
178+
[[nodiscard]] tl::expected<IPCManagerCompiler, std::string> makeIPCManagerCompiler(
179+
std::string BMIIfHeaderUnitObjOtherwisePath);
180+
inline IPCManagerCompiler *managerCompiler;
181+
} // namespace N2978
182+
#endif // IPC_MANAGER_COMPILER_HPP
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
2+
#ifndef MANAGER_HPP
3+
#define MANAGER_HPP
4+
5+
#include "clang/IPC2978/Messages.hpp"
6+
#include "clang/IPC2978/expected.hpp"
7+
8+
#include <string>
9+
#include <vector>
10+
11+
#define BUFFERSIZE 4096
12+
13+
#ifdef _WIN32
14+
// The following variable is used in CreateNamedFunction.
15+
#define PIPE_TIMEOUT 5000
16+
#endif
17+
18+
namespace tl
19+
{
20+
template <typename T, typename U> class expected;
21+
}
22+
23+
namespace N2978
24+
{
25+
26+
enum class ErrorCategory : uint8_t
27+
{
28+
NONE,
29+
30+
// error-category for API errors
31+
READ_FILE_ZERO_BYTES_READ,
32+
INCORRECT_BTC_LAST_MESSAGE,
33+
UNKNOWN_CTB_TYPE,
34+
};
35+
36+
std::string getErrorString();
37+
std::string getErrorString(uint32_t bytesRead_, uint32_t bytesProcessed_);
38+
std::string getErrorString(ErrorCategory errorCategory_);
39+
// to facilitate error propagation.
40+
inline std::string getErrorString(std::string err)
41+
{
42+
return err;
43+
}
44+
45+
struct ProcessMappingOfBMIFile
46+
{
47+
std::string_view file;
48+
#ifdef _WIN32
49+
void *mapping;
50+
void *view;
51+
#else
52+
void *mapping;
53+
uint32_t mappingSize;
54+
#endif
55+
};
56+
57+
class Manager
58+
{
59+
public:
60+
#ifdef _WIN32
61+
void *hPipe = nullptr;
62+
#else
63+
int fdSocket = 0;
64+
#endif
65+
66+
tl::expected<uint32_t, std::string> readInternal(char (&buffer)[BUFFERSIZE]) const;
67+
tl::expected<void, std::string> writeInternal(const std::vector<char> &buffer) const;
68+
69+
static std::vector<char> getBufferWithType(CTB type);
70+
static void writeUInt32(std::vector<char> &buffer, uint32_t value);
71+
static void writeString(std::vector<char> &buffer, const std::string &str);
72+
static void writeProcessMappingOfBMIFile(std::vector<char> &buffer, const BMIFile &file);
73+
static void writeModuleDep(std::vector<char> &buffer, const ModuleDep &dep);
74+
static void writeHuDep(std::vector<char> &buffer, const HuDep &dep);
75+
static void writeHeaderFile(std::vector<char> &buffer, const HeaderFile &dep);
76+
static void writeVectorOfStrings(std::vector<char> &buffer, const std::vector<std::string> &strs);
77+
static void writeVectorOfProcessMappingOfBMIFiles(std::vector<char> &buffer, const std::vector<BMIFile> &files);
78+
static void writeVectorOfModuleDep(std::vector<char> &buffer, const std::vector<ModuleDep> &deps);
79+
static void writeVectorOfHuDeps(std::vector<char> &buffer, const std::vector<HuDep> &deps);
80+
static void writeVectorOfHeaderFiles(std::vector<char> &buffer, const std::vector<HeaderFile> &headerFiles);
81+
82+
tl::expected<bool, std::string> readBoolFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead,
83+
uint32_t &bytesProcessed) const;
84+
tl::expected<uint32_t, std::string> readUInt32FromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead,
85+
uint32_t &bytesProcessed) const;
86+
tl::expected<std::string, std::string> readStringFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead,
87+
uint32_t &bytesProcessed) const;
88+
tl::expected<BMIFile, std::string> readProcessMappingOfBMIFileFromPipe(char (&buffer)[BUFFERSIZE],
89+
uint32_t &bytesRead,
90+
uint32_t &bytesProcessed) const;
91+
tl::expected<std::vector<std::string>, std::string> readVectorOfStringFromPipe(char (&buffer)[BUFFERSIZE],
92+
uint32_t &bytesRead,
93+
uint32_t &bytesProcessed) const;
94+
tl::expected<ModuleDep, std::string> readModuleDepFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead,
95+
uint32_t &bytesProcessed) const;
96+
tl::expected<std::vector<ModuleDep>, std::string> readVectorOfModuleDepFromPipe(char (&buffer)[BUFFERSIZE],
97+
uint32_t &bytesRead,
98+
uint32_t &bytesProcessed) const;
99+
tl::expected<HuDep, std::string> readHuDepFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead,
100+
uint32_t &bytesProcessed) const;
101+
tl::expected<std::vector<HuDep>, std::string> readVectorOfHuDepFromPipe(char (&buffer)[BUFFERSIZE],
102+
uint32_t &bytesRead,
103+
uint32_t &bytesProcessed) const;
104+
tl::expected<HeaderFile, std::string> readHeaderFileFromPipe(char (&buffer)[BUFFERSIZE], uint32_t &bytesRead,
105+
uint32_t &bytesProcessed) const;
106+
tl::expected<std::vector<HeaderFile>, std::string> readVectorOfHeaderFileFromPipe(char (&buffer)[BUFFERSIZE],
107+
uint32_t &bytesRead,
108+
uint32_t &bytesProcessed) const;
109+
tl::expected<void, std::string> readNumberOfBytes(char *output, uint32_t size, char (&buffer)[BUFFERSIZE],
110+
uint32_t &bytesRead, uint32_t &bytesProcessed) const;
111+
};
112+
113+
template <typename T, typename... Args> constexpr T *construct_at(T *p, Args &&...args)
114+
{
115+
return ::new (static_cast<void *>(p)) T(std::forward<Args>(args)...);
116+
}
117+
118+
template <typename T> T &getInitializedObjectFromBuffer(char (&buffer)[320])
119+
{
120+
T &t = reinterpret_cast<T &>(buffer);
121+
construct_at(&t);
122+
return t;
123+
}
124+
125+
inline std::string to16charHexString(const uint64_t v)
126+
{
127+
static auto lut = "0123456789abcdef";
128+
std::string out;
129+
out.resize(16);
130+
for (int i = 0; i < 8; ++i)
131+
{
132+
// extract byte in big-endian order:
133+
const auto byte = static_cast<uint8_t>(v >> ((7 - i) * 8));
134+
// high nibble:
135+
out[2 * i] = lut[byte >> 4];
136+
// low nibble:
137+
out[2 * i + 1] = lut[byte & 0xF];
138+
}
139+
return out;
140+
}
141+
142+
} // namespace N2978
143+
#endif // MANAGER_HPP

0 commit comments

Comments
 (0)