LILAC
Language to language Interop LAyer Compiler
Loading...
Searching...
No Matches
main.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024 Yeong-won Seo
3 *
4 * This file is part of LILAC.
5 *
6 * LILAC is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3, or (at your option) any later
9 * version.
10 *
11 * LILAC is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "pch.h"
21#include "pluginaction.h"
22#include "shared/frontend.h"
23#include "shared/version.h"
24
25#if __unix__
26#include <glob.h>
27#endif
28
30{
31public:
33 : FrontendAction(lilac::shared::F_CXX, "c++", "C++ frontend module")
34 {
35 }
36
37 [[nodiscard]]
38 int Run(std::string output, std::vector<std::string> argv) const override
39 {
40 llvm::cl::SetVersionPrinter([](llvm::raw_ostream& ost)
41 {
42 ost << "lilac-cxx (LILAC C++) " << LILAC_DATE << '\n' << LILAC_SHORT_LICENSE;
43 });
44
45 std::vector<const char*> buffer(argv.size() + 1);
46 buffer[0] = "lilac-cxx";
47 for (int i = 0; i < argv.size(); ++i)
48 buffer[i + 1] = argv[i].c_str();
49
50#if __unix__
51 // NOTE: clang couldn't find `stddef.h` on UNIXen
52
53 // Find candidates of clang with glob
54 glob_t glob{};
55 if (auto ret = ::glob("/usr/lib/clang/*/include", GLOB_TILDE, nullptr, &glob))
56 {
57 globfree(&glob);
58 llvm::errs()
59 << "glob() failed with return value: " << ret << '\n'
60 << "is Clang installed with proper directory?";
61 return 1;
62 }
63
64 std::vector<std::string> candidates(glob.gl_pathc);
65 for (auto i = 0; i < glob.gl_pathc; ++i)
66 {
67 llvm::outs() << "Found candidate Clang installation: " << glob.gl_pathv[i] << '\n';
68 candidates[i] = glob.gl_pathv[i];
69 }
70
71 // Use latest version of clang
72 struct
73 {
74 static constexpr long int GetIndex(const std::string& t)
75 {
76 return strtol(t.data() + 15, nullptr, 10);
77 }
78
79 constexpr bool operator()(const std::string& lhs, const std::string& rhs) const
80 {
81 return GetIndex(lhs) > GetIndex(rhs);
82 }
83 } comp;
84 std::ranges::sort(candidates, comp);
85
86 llvm::outs() << "Selected Clang installation: " << candidates[0] << '\n';
87
88 // Add include path
89 buffer.push_back("--");
90 buffer.push_back("-I");
91 buffer.push_back(candidates[0].data());
92
93 globfree(&glob);
94#endif
95
96 int argc = buffer.size();
97
98 auto expectedParser = clang::tooling::CommonOptionsParser::create(argc, buffer.data(), llvm::cl::getGeneralCategory());
99 if (!expectedParser)
100 {
101 llvm::errs() << expectedParser.takeError();
102 return 1;
103 }
104
105 auto& parser = expectedParser.get();
106
107 clang::tooling::ClangTool tool(parser.getCompilations(), parser.getSourcePathList());
108 if (const auto ret = tool.run(clang::tooling::newFrontendActionFactory<lilac::cxx::LilacAction>().get()))
109 return ret;
110
111 auto& root = lilac::cxx::GetDOMRoot();
112
113 std::ofstream ofs(output);
114 ofs << static_cast<std::string>(frxml::doc{ root });
115
116 return 0;
117 }
118};
119
120[[maybe_unused]]
121static CXXFrontendAction _;
int Run(std::string output, std::vector< std::string > argv) const override
Definition main.cxx:38
An action that generates interface representation from codes.
Definition frontend.h:36
FrontendAction(FrontendKind kind, std::string name, std::string desc)
Definition frontend.cxx:25
frxml::dom & GetDOMRoot()
#define LILAC_DATE
Definition version.h:51
#define LILAC_SHORT_LICENSE
Definition version.h:53