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 "llvm/ADT/SmallString.h"
16#include "llvm/Support/CBindingWrapping.h"
17#include "llvm/Support/Chrono.h"
18#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/MemAlloc.h"
20#include "llvm/Support/Path.h"
21#include "llvm/Support/VirtualFileSystem.h"
22#include "llvm/Support/raw_ostream.h"
23
24using namespace clang;
25using namespace llvm::sys;
26
27unsigned long long clang_getBuildSessionTimestamp(void) {
28 return llvm::sys::toTimeT(TP: std::chrono::system_clock::now());
29}
30
31DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::vfs::YAMLVFSWriter,
32 CXVirtualFileOverlay)
33
34CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
35 return wrap(P: new llvm::vfs::YAMLVFSWriter());
36}
37
38enum CXErrorCode
39clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
40 const char *virtualPath,
41 const char *realPath) {
42 if (!VFO || !virtualPath || !realPath)
43 return CXError_InvalidArguments;
44 if (!path::is_absolute(path: virtualPath))
45 return CXError_InvalidArguments;
46 if (!path::is_absolute(path: realPath))
47 return CXError_InvalidArguments;
48
49 for (path::const_iterator
50 PI = path::begin(path: virtualPath),
51 PE = path::end(path: virtualPath); PI != PE; ++PI) {
52 StringRef Comp = *PI;
53 if (Comp == "." || Comp == "..")
54 return CXError_InvalidArguments;
55 }
56
57 unwrap(P: VFO)->addFileMapping(VirtualPath: virtualPath, RealPath: realPath);
58 return CXError_Success;
59}
60
61enum CXErrorCode
62clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
63 int caseSensitive) {
64 if (!VFO)
65 return CXError_InvalidArguments;
66 unwrap(P: VFO)->setCaseSensitivity(caseSensitive);
67 return CXError_Success;
68}
69
70enum CXErrorCode
71clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
72 char **out_buffer_ptr,
73 unsigned *out_buffer_size) {
74 if (!VFO || !out_buffer_ptr || !out_buffer_size)
75 return CXError_InvalidArguments;
76
77 llvm::SmallString<256> Buf;
78 llvm::raw_svector_ostream OS(Buf);
79 unwrap(P: VFO)->write(OS);
80
81 StringRef Data = OS.str();
82 *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Sz: Data.size()));
83 *out_buffer_size = Data.size();
84 memcpy(dest: *out_buffer_ptr, src: Data.data(), n: Data.size());
85 return CXError_Success;
86}
87
88void clang_free(void *buffer) {
89 free(ptr: buffer);
90}
91
92void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
93 delete unwrap(P: VFO);
94}
95
96
97struct CXModuleMapDescriptorImpl {
98 std::string ModuleName;
99 std::string UmbrellaHeader;
100};
101
102CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
103 return new CXModuleMapDescriptorImpl();
104}
105
106enum CXErrorCode
107clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
108 const char *name) {
109 if (!MMD || !name)
110 return CXError_InvalidArguments;
111
112 MMD->ModuleName = name;
113 return CXError_Success;
114}
115
116enum CXErrorCode
117clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
118 const char *name) {
119 if (!MMD || !name)
120 return CXError_InvalidArguments;
121
122 MMD->UmbrellaHeader = name;
123 return CXError_Success;
124}
125
126enum CXErrorCode
127clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
128 char **out_buffer_ptr,
129 unsigned *out_buffer_size) {
130 if (!MMD || !out_buffer_ptr || !out_buffer_size)
131 return CXError_InvalidArguments;
132
133 llvm::SmallString<256> Buf;
134 llvm::raw_svector_ostream OS(Buf);
135 OS << "framework module " << MMD->ModuleName << " {\n";
136 OS << " umbrella header \"";
137 OS.write_escaped(Str: MMD->UmbrellaHeader) << "\"\n";
138 OS << '\n';
139 OS << " export *\n";
140 OS << " module * { export * }\n";
141 OS << "}\n";
142
143 StringRef Data = OS.str();
144 *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Sz: Data.size()));
145 *out_buffer_size = Data.size();
146 memcpy(dest: *out_buffer_ptr, src: Data.data(), n: Data.size());
147 return CXError_Success;
148}
149
150void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
151 delete MMD;
152}
153