150{
151 static int static_symbol;
152
153 std::vector<std::string> absolute_tu_paths;
156 auto absolute_tu_path =
157 clang::tooling::getAbsolutePath(*
overlay_fs_, source_path);
158 if (!absolute_tu_path) {
160 LOG_WARN(
"Skipping file {} in diagram {}. Could not resolve "
161 "absolute path for translation unit: {}",
163 llvm::toString(absolute_tu_path.takeError()));
164 }
165 continue;
166 }
167 absolute_tu_paths.emplace_back(std::move(*absolute_tu_path));
168 }
169
170
171 std::string initial_workdir;
172 if (
auto current_workdir =
overlay_fs_->getCurrentWorkingDirectory()) {
173 initial_workdir = std::move(*current_workdir);
174 }
175 else {
177 LOG_ERROR(
"Could not get current working directory when generating "
178 "diagram '{}': {}",
180 }
181
182 for (const auto &file : absolute_tu_paths) {
184 LOG_INFO(
"Processing diagram '{}' translation unit: {}",
186
188
189 if (compile_commands_for_file.empty()) {
192 "Skipping file {} for diagram '{}'. Compilation command "
193 "not found.",
195 continue;
196 }
197
198 if (compile_commands_for_file.size() > 1 &&
200 LOG_WARN(
"Multiple compile commands detected for file '{}' in "
201 "diagram '{}' - using only the first one...",
203 }
204
205 for (auto &compile_command : compile_commands_for_file) {
207 compile_command.Directory))
208 llvm::report_fatal_error("Cannot chdir into \"" +
209 Twine(compile_command.Directory) + "\"!");
210
211
212
213
215 .second) {
216 for (const auto &[file_name, file_content] :
218 if (!llvm::sys::path::is_absolute(file_name))
220 llvm::MemoryBuffer::getMemBuffer(file_content));
221 }
222
223 auto command_line = compile_command.CommandLine;
225 command_line =
227
228 assert(!command_line.empty());
229
230 inject_resource_dir(command_line, "clang_tool", &static_symbol);
231
232 ToolInvocation invocation(std::move(command_line), Action,
235#if LLVM_VERSION_MAJOR > 13
236 invocation.setDiagnosticOptions(
diag_opts_.get());
237#endif
238
240 if (!initial_workdir.empty()) {
241 if (
const auto ec =
overlay_fs_->setCurrentWorkingDirectory(
242 initial_workdir);
243 ec)
245 LOG_ERROR(
"Error when trying to restore working "
246 "directory: {}",
247 ec.message());
248 }
249
255 }
256
259 }
260
261 throw std::runtime_error(
262 fmt::format("Unknown error while processing {}", file));
263 }
264
266 break;
267 }
268 }
269
270 if (!initial_workdir.empty()) {
271 if (const auto ec =
272 overlay_fs_->setCurrentWorkingDirectory(initial_workdir))
274 LOG_ERROR(
"Error when trying to restore working dir: {}",
275 ec.message());
276 }
277}