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 "clang/Basic/VirtualFileSystem.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/Support/CBindingWrapping.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/TimeValue.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 using namespace clang;
24 using namespace llvm::sys;
25 
clang_getBuildSessionTimestamp(void)26 unsigned long long clang_getBuildSessionTimestamp(void) {
27   return llvm::sys::TimeValue::now().toEpochTime();
28 }
29 
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::vfs::YAMLVFSWriter,CXVirtualFileOverlay)30 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::vfs::YAMLVFSWriter,
31                                    CXVirtualFileOverlay)
32 
33 CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
34   return wrap(new clang::vfs::YAMLVFSWriter());
35 }
36 
37 enum CXErrorCode
clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,const char * virtualPath,const char * realPath)38 clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
39                                         const char *virtualPath,
40                                         const char *realPath) {
41   if (!VFO || !virtualPath || !realPath)
42     return CXError_InvalidArguments;
43   if (!path::is_absolute(virtualPath))
44     return CXError_InvalidArguments;
45   if (!path::is_absolute(realPath))
46     return CXError_InvalidArguments;
47 
48   for (path::const_iterator
49          PI = path::begin(virtualPath),
50          PE = path::end(virtualPath); PI != PE; ++PI) {
51     StringRef Comp = *PI;
52     if (Comp == "." || Comp == "..")
53       return CXError_InvalidArguments;
54   }
55 
56   unwrap(VFO)->addFileMapping(virtualPath, realPath);
57   return CXError_Success;
58 }
59 
60 enum CXErrorCode
clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,int caseSensitive)61 clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
62                                             int caseSensitive) {
63   if (!VFO)
64     return CXError_InvalidArguments;
65   unwrap(VFO)->setCaseSensitivity(caseSensitive);
66   return CXError_Success;
67 }
68 
69 enum CXErrorCode
clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO,unsigned,char ** out_buffer_ptr,unsigned * out_buffer_size)70 clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
71                                        char **out_buffer_ptr,
72                                        unsigned *out_buffer_size) {
73   if (!VFO || !out_buffer_ptr || !out_buffer_size)
74     return CXError_InvalidArguments;
75 
76   llvm::SmallString<256> Buf;
77   llvm::raw_svector_ostream OS(Buf);
78   unwrap(VFO)->write(OS);
79 
80   StringRef Data = OS.str();
81   *out_buffer_ptr = (char*)malloc(Data.size());
82   *out_buffer_size = Data.size();
83   memcpy(*out_buffer_ptr, Data.data(), Data.size());
84   return CXError_Success;
85 }
86 
clang_free(void * buffer)87 void clang_free(void *buffer) {
88   free(buffer);
89 }
90 
clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO)91 void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
92   delete unwrap(VFO);
93 }
94 
95 
96 struct CXModuleMapDescriptorImpl {
97   std::string ModuleName;
98   std::string UmbrellaHeader;
99 };
100 
clang_ModuleMapDescriptor_create(unsigned)101 CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
102   return new CXModuleMapDescriptorImpl();
103 }
104 
105 enum CXErrorCode
clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,const char * name)106 clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
107                                                  const char *name) {
108   if (!MMD || !name)
109     return CXError_InvalidArguments;
110 
111   MMD->ModuleName = name;
112   return CXError_Success;
113 }
114 
115 enum CXErrorCode
clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,const char * name)116 clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
117                                             const char *name) {
118   if (!MMD || !name)
119     return CXError_InvalidArguments;
120 
121   MMD->UmbrellaHeader = name;
122   return CXError_Success;
123 }
124 
125 enum CXErrorCode
clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD,unsigned,char ** out_buffer_ptr,unsigned * out_buffer_size)126 clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
127                                        char **out_buffer_ptr,
128                                        unsigned *out_buffer_size) {
129   if (!MMD || !out_buffer_ptr || !out_buffer_size)
130     return CXError_InvalidArguments;
131 
132   llvm::SmallString<256> Buf;
133   llvm::raw_svector_ostream OS(Buf);
134   OS << "framework module " << MMD->ModuleName << " {\n";
135   OS << "  umbrella header \"";
136   OS.write_escaped(MMD->UmbrellaHeader) << "\"\n";
137   OS << '\n';
138   OS << "  export *\n";
139   OS << "  module * { export * }\n";
140   OS << "}\n";
141 
142   StringRef Data = OS.str();
143   *out_buffer_ptr = (char*)malloc(Data.size());
144   *out_buffer_size = Data.size();
145   memcpy(*out_buffer_ptr, Data.data(), Data.size());
146   return CXError_Success;
147 }
148 
clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD)149 void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
150   delete MMD;
151 }
152