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