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 27 unsigned long long clang_getBuildSessionTimestamp(void) { 28 return llvm::sys::toTimeT(std::chrono::system_clock::now()); 29 } 30 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 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 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 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 88 void clang_free(void *buffer) { 89 free(buffer); 90 } 91 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 102 CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) { 103 return new CXModuleMapDescriptorImpl(); 104 } 105 106 enum CXErrorCode 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 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 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 150 void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) { 151 delete MMD; 152 } 153