142{
143 static int static_symbol;
144
145 std::vector<std::string> absolute_tu_paths;
148 auto absolute_tu_path =
149 clang::tooling::getAbsolutePath(*
overlay_fs_, source_path);
150 if (!absolute_tu_path) {
152 LOG_WARN(
"Skipping file {} in diagram {}. Could not resolve "
153 "absolute path for translation unit: {}",
155 llvm::toString(absolute_tu_path.takeError()));
156 }
157 continue;
158 }
159 absolute_tu_paths.emplace_back(std::move(*absolute_tu_path));
160 }
161
162
163 std::string initial_workdir;
164 if (
auto current_workdir =
overlay_fs_->getCurrentWorkingDirectory()) {
165 initial_workdir = std::move(*current_workdir);
166 }
167 else {
169 LOG_ERROR(
"Could not get current working directory when generating "
170 "diagram '{}': {}",
172 }
173
174 for (const auto &file : absolute_tu_paths) {
176 LOG_INFO(
"Processing diagram '{}' translation unit: {}",
178
180
181 if (compile_commands_for_file.empty()) {
184 "Skipping file {} for diagram '{}'. Compilation command "
185 "not found.",
187 continue;
188 }
189
190 if (compile_commands_for_file.size() > 1 &&
192 LOG_WARN(
"Multiple compile commands detected for file '{}' in "
193 "diagram '{}' - using only the first one...",
195 }
196
197 for (auto &compile_command : compile_commands_for_file) {
199 compile_command.Directory))
200 llvm::report_fatal_error("Cannot chdir into \"" +
201 Twine(compile_command.Directory) + "\"!");
202
203
204
205
207 .second) {
208 for (const auto &[file_name, file_content] :
210 if (!llvm::sys::path::is_absolute(file_name))
212 llvm::MemoryBuffer::getMemBuffer(file_content));
213 }
214
215 auto command_line = compile_command.CommandLine;
217 command_line =
219
220 assert(!command_line.empty());
221
222 inject_resource_dir(command_line, "clang_tool", &static_symbol);
223
224 ToolInvocation invocation(std::move(command_line), Action,
227#if LLVM_VERSION_MAJOR > 13
228 invocation.setDiagnosticOptions(
diag_opts_.get());
229#endif
230
232 if (!initial_workdir.empty()) {
233 if (
const auto ec =
overlay_fs_->setCurrentWorkingDirectory(
234 initial_workdir);
235 ec)
237 LOG_ERROR(
"Error when trying to restore working "
238 "directory: {}",
239 ec.message());
240 }
241
247 }
248
251 }
252
253 throw std::runtime_error(
254 fmt::format("Unknown error while processing {}", file));
255 }
256
258 break;
259 }
260 }
261
262 if (!initial_workdir.empty()) {
263 if (const auto ec =
264 overlay_fs_->setCurrentWorkingDirectory(initial_workdir))
266 LOG_ERROR(
"Error when trying to restore working dir: {}",
267 ec.message());
268 }
269}