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