1 //===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements various utilities for use by build systems.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang-c/BuildSystem.h"
15 #include "CXString.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/Support/CBindingWrapping.h"
18 #include "llvm/Support/Chrono.h"
19 #include "llvm/Support/ErrorHandling.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