0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
compilation_database.cc
Go to the documentation of this file.
1/**
2 * @file src/common/compilation_database.cc
3 *
4 * Copyright (c) 2021-2024 Bartek Kryza <bkryza@gmail.com>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
20#include "util/error.h"
22
23namespace clanguml::common {
24
25std::unique_ptr<compilation_database>
27 const clanguml::config::config &cfg)
28{
29 std::string error_message;
30 auto res = clang::tooling::CompilationDatabase::autoDetectFromDirectory(
31 cfg.compilation_database_dir(), error_message);
32
33 if (!error_message.empty())
34 throw error::compilation_database_error(error_message);
35
36 return std::make_unique<compilation_database>(std::move(res), cfg);
37}
38
40 std::unique_ptr<clang::tooling::CompilationDatabase> base,
41 const clanguml::config::config &cfg)
42 : base_{std::move(base)}
43 , config_{cfg}
44{
45}
46
48{
49 return config_;
50}
51
52const clang::tooling::CompilationDatabase &compilation_database::base() const
53{
54 return *base_;
55}
56
57std::vector<std::string> compilation_database::getAllFiles() const
58{
59 return base().getAllFiles();
60}
61
62std::vector<clang::tooling::CompileCommand>
63compilation_database::getCompileCommands(clang::StringRef FilePath) const
64{
65 auto commands = base().getCompileCommands(FilePath);
66
68
69 return commands;
70}
71
72std::vector<clang::tooling::CompileCommand>
74{
75 auto commands = base().getAllCompileCommands();
76
78
79 return commands;
80}
81
83 const std::string &filename) const
84{
85 if (util::ends_with(filename, std::string{".c"}))
86 return "c";
87
88 return "c++";
89}
90
92 const std::vector<std::string> &files) const
93{
94 auto result{0L};
95
96 auto commands = base().getAllCompileCommands();
97
98 for (const auto &command : commands) {
99 result += std::count_if(
100 files.begin(), files.end(), [&command](const auto &file) {
101 return (command.Filename == file) ||
102 (std::filesystem::weakly_canonical(command.Filename)
103 .string() == file);
104 });
105 }
106
107 return result;
108}
109
111 std::vector<clang::tooling::CompileCommand> &commands) const
112{
113#if !defined(_WIN32)
114 if (config().query_driver && !config().query_driver().empty()) {
115 for (auto &compile_command : commands) {
116 auto argv0 = config().query_driver() == "."
117 ? compile_command.CommandLine.at(0)
118 : config().query_driver();
119
121 argv0, guess_language_from_filename(compile_command.Filename)};
122
123 extractor.execute();
124
125 std::vector<std::string> system_header_args;
126 for (const auto &path : extractor.system_include_paths()) {
127 system_header_args.emplace_back("-isystem");
128 system_header_args.emplace_back(path);
129 }
130
131 compile_command.CommandLine.insert(
132 compile_command.CommandLine.begin() + 1,
133 system_header_args.begin(), system_header_args.end());
134
135 if (!extractor.target().empty()) {
136 compile_command.CommandLine.insert(
137 compile_command.CommandLine.begin() + 1,
138 fmt::format("--target={}", extractor.target()));
139 }
140 }
141 }
142#endif
143
144 if (config().add_compile_flags && !config().add_compile_flags().empty()) {
145 for (auto &compile_command : commands) {
146 compile_command.CommandLine.insert(
147 // Add flags after argv[0]
148 compile_command.CommandLine.begin() + 1,
149 config().add_compile_flags().begin(),
150 config().add_compile_flags().end());
151 }
152 }
153
155 !config().remove_compile_flags().empty()) {
156 for (auto &compile_command : commands) {
157 for (const auto &flag : config().remove_compile_flags()) {
158 util::erase_if(compile_command.CommandLine,
159 [&flag](const auto &arg) { return flag == arg; });
160 }
161 }
162 }
163}
164
165} // namespace clanguml::common