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
24 using namespace clang;
25 using namespace llvm::sys;
26
clang_getBuildSessionTimestamp(void)27 unsigned long long clang_getBuildSessionTimestamp(void) {
28 return llvm::sys::toTimeT(std::chrono::system_clock::now());
29 }
30
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::vfs::YAMLVFSWriter,CXVirtualFileOverlay)31 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::vfs::YAMLVFSWriter,
32 CXVirtualFileOverlay)
33
34 CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
35 return wrap(new llvm::vfs::YAMLVFSWriter());
36 }
37
38 enum CXErrorCode
clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,const char * virtualPath,const char * realPath)39 clang_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(virtualPath))
45 return CXError_InvalidArguments;
46 if (!path::is_absolute(realPath))
47 return CXError_InvalidArguments;
48
49 for (path::const_iterator
50 PI = path::begin(virtualPath),
51 PE = path::end(virtualPath); PI != PE; ++PI) {
52 StringRef Comp = *PI;
53 if (Comp == "." || Comp == "..")
54 return CXError_InvalidArguments;
55 }
56
57 unwrap(VFO)->addFileMapping(virtualPath, realPath);
58 return CXError_Success;
59 }
60
61 enum CXErrorCode
clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,int caseSensitive)62 clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
63 int caseSensitive) {
64 if (!VFO)
65 return CXError_InvalidArguments;
66 unwrap(VFO)->setCaseSensitivity(caseSensitive);
67 return CXError_Success;
68 }
69
70 enum CXErrorCode
clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO,unsigned,char ** out_buffer_ptr,unsigned * out_buffer_size)71 clang_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(VFO)->write(OS);
80
81 StringRef Data = OS.str();
82 *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Data.size()));
83 *out_buffer_size = Data.size();
84 memcpy(*out_buffer_ptr, Data.data(), Data.size());
85 return CXError_Success;
86 }
87
clang_free(void * buffer)88 void clang_free(void *buffer) {
89 free(buffer);
90 }
91
clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO)92 void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
93 delete unwrap(VFO);
94 }
95
96
97 struct CXModuleMapDescriptorImpl {
98 std::string ModuleName;
99 std::string UmbrellaHeader;
100 };
101
clang_ModuleMapDescriptor_create(unsigned)102 CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
103 return new CXModuleMapDescriptorImpl();
104 }
105
106 enum CXErrorCode
clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,const char * name)107 clang_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
116 enum CXErrorCode
clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,const char * name)117 clang_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
126 enum CXErrorCode
clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD,unsigned,char ** out_buffer_ptr,unsigned * out_buffer_size)127 clang_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(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(Data.size()));
145 *out_buffer_size = Data.size();
146 memcpy(*out_buffer_ptr, Data.data(), Data.size());
147 return CXError_Success;
148 }
149
clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD)150 void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
151 delete MMD;
152 }
153