xref: /openbsd-src/gnu/llvm/clang/tools/libclang/BuildSystem.cpp (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
1*e5dd7070Spatrick //===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
2*e5dd7070Spatrick //
3*e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e5dd7070Spatrick //
7*e5dd7070Spatrick //===----------------------------------------------------------------------===//
8*e5dd7070Spatrick //
9*e5dd7070Spatrick // This file implements various utilities for use by build systems.
10*e5dd7070Spatrick //
11*e5dd7070Spatrick //===----------------------------------------------------------------------===//
12*e5dd7070Spatrick 
13*e5dd7070Spatrick #include "clang-c/BuildSystem.h"
14*e5dd7070Spatrick #include "CXString.h"
15*e5dd7070Spatrick #include "llvm/ADT/SmallString.h"
16*e5dd7070Spatrick #include "llvm/Support/CBindingWrapping.h"
17*e5dd7070Spatrick #include "llvm/Support/Chrono.h"
18*e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
19*e5dd7070Spatrick #include "llvm/Support/Path.h"
20*e5dd7070Spatrick #include "llvm/Support/VirtualFileSystem.h"
21*e5dd7070Spatrick #include "llvm/Support/raw_ostream.h"
22*e5dd7070Spatrick 
23*e5dd7070Spatrick using namespace clang;
24*e5dd7070Spatrick using namespace llvm::sys;
25*e5dd7070Spatrick 
26*e5dd7070Spatrick unsigned long long clang_getBuildSessionTimestamp(void) {
27*e5dd7070Spatrick   return llvm::sys::toTimeT(std::chrono::system_clock::now());
28*e5dd7070Spatrick }
29*e5dd7070Spatrick 
30*e5dd7070Spatrick DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::vfs::YAMLVFSWriter,
31*e5dd7070Spatrick                                    CXVirtualFileOverlay)
32*e5dd7070Spatrick 
33*e5dd7070Spatrick CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
34*e5dd7070Spatrick   return wrap(new llvm::vfs::YAMLVFSWriter());
35*e5dd7070Spatrick }
36*e5dd7070Spatrick 
37*e5dd7070Spatrick enum CXErrorCode
38*e5dd7070Spatrick clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
39*e5dd7070Spatrick                                         const char *virtualPath,
40*e5dd7070Spatrick                                         const char *realPath) {
41*e5dd7070Spatrick   if (!VFO || !virtualPath || !realPath)
42*e5dd7070Spatrick     return CXError_InvalidArguments;
43*e5dd7070Spatrick   if (!path::is_absolute(virtualPath))
44*e5dd7070Spatrick     return CXError_InvalidArguments;
45*e5dd7070Spatrick   if (!path::is_absolute(realPath))
46*e5dd7070Spatrick     return CXError_InvalidArguments;
47*e5dd7070Spatrick 
48*e5dd7070Spatrick   for (path::const_iterator
49*e5dd7070Spatrick          PI = path::begin(virtualPath),
50*e5dd7070Spatrick          PE = path::end(virtualPath); PI != PE; ++PI) {
51*e5dd7070Spatrick     StringRef Comp = *PI;
52*e5dd7070Spatrick     if (Comp == "." || Comp == "..")
53*e5dd7070Spatrick       return CXError_InvalidArguments;
54*e5dd7070Spatrick   }
55*e5dd7070Spatrick 
56*e5dd7070Spatrick   unwrap(VFO)->addFileMapping(virtualPath, realPath);
57*e5dd7070Spatrick   return CXError_Success;
58*e5dd7070Spatrick }
59*e5dd7070Spatrick 
60*e5dd7070Spatrick enum CXErrorCode
61*e5dd7070Spatrick clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
62*e5dd7070Spatrick                                             int caseSensitive) {
63*e5dd7070Spatrick   if (!VFO)
64*e5dd7070Spatrick     return CXError_InvalidArguments;
65*e5dd7070Spatrick   unwrap(VFO)->setCaseSensitivity(caseSensitive);
66*e5dd7070Spatrick   return CXError_Success;
67*e5dd7070Spatrick }
68*e5dd7070Spatrick 
69*e5dd7070Spatrick enum CXErrorCode
70*e5dd7070Spatrick clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
71*e5dd7070Spatrick                                        char **out_buffer_ptr,
72*e5dd7070Spatrick                                        unsigned *out_buffer_size) {
73*e5dd7070Spatrick   if (!VFO || !out_buffer_ptr || !out_buffer_size)
74*e5dd7070Spatrick     return CXError_InvalidArguments;
75*e5dd7070Spatrick 
76*e5dd7070Spatrick   llvm::SmallString<256> Buf;
77*e5dd7070Spatrick   llvm::raw_svector_ostream OS(Buf);
78*e5dd7070Spatrick   unwrap(VFO)->write(OS);
79*e5dd7070Spatrick 
80*e5dd7070Spatrick   StringRef Data = OS.str();
81*e5dd7070Spatrick   *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Data.size()));
82*e5dd7070Spatrick   *out_buffer_size = Data.size();
83*e5dd7070Spatrick   memcpy(*out_buffer_ptr, Data.data(), Data.size());
84*e5dd7070Spatrick   return CXError_Success;
85*e5dd7070Spatrick }
86*e5dd7070Spatrick 
87*e5dd7070Spatrick void clang_free(void *buffer) {
88*e5dd7070Spatrick   free(buffer);
89*e5dd7070Spatrick }
90*e5dd7070Spatrick 
91*e5dd7070Spatrick void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
92*e5dd7070Spatrick   delete unwrap(VFO);
93*e5dd7070Spatrick }
94*e5dd7070Spatrick 
95*e5dd7070Spatrick 
96*e5dd7070Spatrick struct CXModuleMapDescriptorImpl {
97*e5dd7070Spatrick   std::string ModuleName;
98*e5dd7070Spatrick   std::string UmbrellaHeader;
99*e5dd7070Spatrick };
100*e5dd7070Spatrick 
101*e5dd7070Spatrick CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
102*e5dd7070Spatrick   return new CXModuleMapDescriptorImpl();
103*e5dd7070Spatrick }
104*e5dd7070Spatrick 
105*e5dd7070Spatrick enum CXErrorCode
106*e5dd7070Spatrick clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
107*e5dd7070Spatrick                                                  const char *name) {
108*e5dd7070Spatrick   if (!MMD || !name)
109*e5dd7070Spatrick     return CXError_InvalidArguments;
110*e5dd7070Spatrick 
111*e5dd7070Spatrick   MMD->ModuleName = name;
112*e5dd7070Spatrick   return CXError_Success;
113*e5dd7070Spatrick }
114*e5dd7070Spatrick 
115*e5dd7070Spatrick enum CXErrorCode
116*e5dd7070Spatrick clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
117*e5dd7070Spatrick                                             const char *name) {
118*e5dd7070Spatrick   if (!MMD || !name)
119*e5dd7070Spatrick     return CXError_InvalidArguments;
120*e5dd7070Spatrick 
121*e5dd7070Spatrick   MMD->UmbrellaHeader = name;
122*e5dd7070Spatrick   return CXError_Success;
123*e5dd7070Spatrick }
124*e5dd7070Spatrick 
125*e5dd7070Spatrick enum CXErrorCode
126*e5dd7070Spatrick clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
127*e5dd7070Spatrick                                        char **out_buffer_ptr,
128*e5dd7070Spatrick                                        unsigned *out_buffer_size) {
129*e5dd7070Spatrick   if (!MMD || !out_buffer_ptr || !out_buffer_size)
130*e5dd7070Spatrick     return CXError_InvalidArguments;
131*e5dd7070Spatrick 
132*e5dd7070Spatrick   llvm::SmallString<256> Buf;
133*e5dd7070Spatrick   llvm::raw_svector_ostream OS(Buf);
134*e5dd7070Spatrick   OS << "framework module " << MMD->ModuleName << " {\n";
135*e5dd7070Spatrick   OS << "  umbrella header \"";
136*e5dd7070Spatrick   OS.write_escaped(MMD->UmbrellaHeader) << "\"\n";
137*e5dd7070Spatrick   OS << '\n';
138*e5dd7070Spatrick   OS << "  export *\n";
139*e5dd7070Spatrick   OS << "  module * { export * }\n";
140*e5dd7070Spatrick   OS << "}\n";
141*e5dd7070Spatrick 
142*e5dd7070Spatrick   StringRef Data = OS.str();
143*e5dd7070Spatrick   *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Data.size()));
144*e5dd7070Spatrick   *out_buffer_size = Data.size();
145*e5dd7070Spatrick   memcpy(*out_buffer_ptr, Data.data(), Data.size());
146*e5dd7070Spatrick   return CXError_Success;
147*e5dd7070Spatrick }
148*e5dd7070Spatrick 
149*e5dd7070Spatrick void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
150*e5dd7070Spatrick   delete MMD;
151*e5dd7070Spatrick }
152