From 1d4cff185f201ea5c98c7433f008fe34b285d9e1 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Mon, 3 Mar 2014 07:41:45 +0000 Subject: [PATCH] [libclang] Introduce APIs that assist in constructing a simple module.map file for a user framework. rdar://16092858 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202681 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang-c/BuildSystem.h | 49 ++++++++++++++++++++++++ tools/libclang/BuildSystem.cpp | 58 +++++++++++++++++++++++++++++ tools/libclang/libclang.exports | 5 +++ unittests/libclang/LibclangTest.cpp | 23 ++++++++++++ 4 files changed, 135 insertions(+) diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h index a1f243fd48..3d65c536f5 100644 --- a/include/clang-c/BuildSystem.h +++ b/include/clang-c/BuildSystem.h @@ -77,6 +77,55 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options, */ CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay); +/** + * \brief Object encapsulating information about a module.map file. + */ +typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor; + +/** + * \brief Create a \c CXModuleMapDescriptor object. + * Must be disposed with \c clang_ModuleMapDescriptor_dispose(). + * + * \param options is reserved, always pass 0. + */ +CINDEX_LINKAGE CXModuleMapDescriptor +clang_ModuleMapDescriptor_create(unsigned options); + +/** + * \brief Sets the framework module name that the module.map describes. + * \returns 0 for success, non-zero to indicate an error. + */ +CINDEX_LINKAGE enum CXErrorCode +clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor, + const char *name); + +/** + * \brief Sets the umbrealla header name that the module.map describes. + * \returns 0 for success, non-zero to indicate an error. + */ +CINDEX_LINKAGE enum CXErrorCode +clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor, + const char *name); + +/** + * \brief Write out the \c CXModuleMapDescriptor object to a char buffer. + * + * \param options is reserved, always pass 0. + * \param out_buffer_ptr pointer to receive the buffer pointer, which should be + * disposed using \c free(). + * \param out_buffer_size pointer to receive the buffer size. + * \returns 0 for success, non-zero to indicate an error. + */ +CINDEX_LINKAGE enum CXErrorCode +clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options, + char **out_buffer_ptr, + unsigned *out_buffer_size); + +/** + * \brief Dispose a \c CXModuleMapDescriptor object. + */ +CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor); + /** * @} */ diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp index 5fd95b0a85..ce3762b5be 100644 --- a/tools/libclang/BuildSystem.cpp +++ b/tools/libclang/BuildSystem.cpp @@ -197,3 +197,61 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) { delete VFO; } + + +struct CXModuleMapDescriptorImpl { + std::string ModuleName; + std::string UmbrellaHeader; +}; + +CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) { + return new CXModuleMapDescriptorImpl(); +} + +enum CXErrorCode +clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD, + const char *name) { + if (!MMD || !name) + return CXError_InvalidArguments; + + MMD->ModuleName = name; + return CXError_Success; +} + +enum CXErrorCode +clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD, + const char *name) { + if (!MMD || !name) + return CXError_InvalidArguments; + + MMD->UmbrellaHeader = name; + return CXError_Success; +} + +enum CXErrorCode +clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned, + char **out_buffer_ptr, + unsigned *out_buffer_size) { + if (!MMD || !out_buffer_ptr || !out_buffer_size) + return CXError_InvalidArguments; + + llvm::SmallString<256> Buf; + llvm::raw_svector_ostream OS(Buf); + OS << "framework module " << MMD->ModuleName << " {\n"; + OS << " umbrella header \""; + OS.write_escaped(MMD->UmbrellaHeader) << "\"\n"; + OS << '\n'; + OS << " export *\n"; + OS << " module * { export * }\n"; + OS << "}\n"; + + StringRef Data = OS.str(); + *out_buffer_ptr = (char*)malloc(Data.size()); + *out_buffer_size = Data.size(); + memcpy(*out_buffer_ptr, Data.data(), Data.size()); + return CXError_Success; +} + +void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) { + delete MMD; +} diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index dfee253ba1..bbfe046c59 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -286,6 +286,11 @@ clang_CompileCommand_getNumArgs clang_CompileCommand_getArg clang_visitChildren clang_visitChildrenWithBlock +clang_ModuleMapDescriptor_create +clang_ModuleMapDescriptor_dispose +clang_ModuleMapDescriptor_setFrameworkModuleName +clang_ModuleMapDescriptor_setUmbrellaHeader +clang_ModuleMapDescriptor_writeToBuffer clang_VirtualFileOverlay_addFileMapping clang_VirtualFileOverlay_create clang_VirtualFileOverlay_dispose diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp index 3809c1ce88..09d51b2168 100644 --- a/unittests/libclang/LibclangTest.cpp +++ b/unittests/libclang/LibclangTest.cpp @@ -141,3 +141,26 @@ TEST(libclang, VirtualFileOverlay) { T.map("/path/virtual/dir/in/subdir/foo4.h", "/real/foo4.h"); } } + +TEST(libclang, ModuleMapDescriptor) { + const char *Contents = + "framework module TestFrame {\n" + " umbrella header \"TestFrame.h\"\n" + "\n" + " export *\n" + " module * { export * }\n" + "}\n"; + + CXModuleMapDescriptor MMD = clang_ModuleMapDescriptor_create(0); + + clang_ModuleMapDescriptor_setFrameworkModuleName(MMD, "TestFrame"); + clang_ModuleMapDescriptor_setUmbrellaHeader(MMD, "TestFrame.h"); + + char *BufPtr; + unsigned BufSize; + clang_ModuleMapDescriptor_writeToBuffer(MMD, 0, &BufPtr, &BufSize); + std::string BufStr(BufPtr, BufSize); + EXPECT_STREQ(Contents, BufStr.c_str()); + free(BufPtr); + clang_ModuleMapDescriptor_dispose(MMD); +} -- 2.40.0