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