55#include < clang/Lex/Preprocessor.h>
66#include < clang/Tooling/Tooling.h>
77#include < iostream>
8+ #include < sstream>
89#include < llvm/ADT/StringSwitch.h>
910#include < llvm/Support/Path.h>
1011
1112using namespace clang ;
1213namespace path = llvm::sys::path;
1314namespace fs = llvm::sys::fs;
1415
15- static SmallVectorImpl< char >& operator +=(SmallVectorImpl< char > & includes, StringRef rhs )
16+ static std::error_code addHeaderInclude (StringRef headerName, std::vector<SmallString< 256 >> & includes)
1617{
17- includes.append (rhs.begin (), rhs.end ());
18- return includes;
19- }
20-
21- static std::error_code addHeaderInclude (StringRef headerName, SmallVectorImpl<char >& includes)
22- {
23- includes += " #import \" " ;
2418
2519 // Use an absolute path for the include; there's no reason to think whether a relative path will
2620 // work ('.' might not be on our include path) or that it will find the same file.
2721 if (path::is_absolute (headerName)) {
28- includes += headerName;
22+ includes. push_back ( headerName) ;
2923 }
3024 else {
3125 SmallString<256 > header = headerName;
3226 if (std::error_code err = fs::make_absolute (header))
3327 return err;
34- includes += header;
28+ includes. push_back ( header) ;
3529 }
3630
37- includes += " \"\n " ;
38-
3931 return std::error_code ();
4032}
4133
42- static std::error_code addHeaderInclude (const FileEntry* header, SmallVectorImpl< char >& includes)
34+ static std::error_code addHeaderInclude (const FileEntry* header, std::vector<SmallString< 256 > >& includes)
4335{
4436 return addHeaderInclude (header->getName (), includes);
4537}
4638
47- static std::error_code collectModuleHeaderIncludes (FileManager& fileMgr, ModuleMap& modMap, const Module* module , SmallVectorImpl< char >& includes)
39+ static std::error_code collectModuleHeaderIncludes (FileManager& fileMgr, ModuleMap& modMap, const Module* module , std::vector<SmallString< 256 > >& includes)
4840{
4941 // Don't collect any headers for unavailable modules.
5042 if (!module ->isAvailable ())
@@ -91,7 +83,7 @@ static std::error_code collectModuleHeaderIncludes(FileManager& fileMgr, ModuleM
9183 return std::error_code ();
9284}
9385
94- static std::error_code CreateUmbrellaHeaderForAmbientModules (const std::vector<std::string>& args, std::string* umbrellaHeaderContents , const std::vector<std::string>& moduleBlacklist, std::vector<std::string>& includePaths)
86+ static std::error_code CreateUmbrellaHeaderForAmbientModules (const std::vector<std::string>& args, std::vector<SmallString< 256 >>& umbrellaHeaders , const std::vector<std::string>& moduleBlacklist, std::vector<std::string>& includePaths)
9587{
9688 std::unique_ptr<clang::ASTUnit> ast = clang::tooling::buildASTFromCodeWithArgs (" " , args, " umbrella.h" );
9789 if (!ast)
@@ -106,7 +98,6 @@ static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<s
10698 ModuleMap& moduleMap = headerSearch.getModuleMap ();
10799 FileManager& fileManager = ast->getFileManager ();
108100
109- SmallString<256 > headerContents;
110101 std::function<void (const Module*)> collector = [&](const Module* module ) {
111102 // uncomment for debugging unavailable modules
112103// if (!module->isAvailable()) {
@@ -124,24 +115,41 @@ static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<s
124115 includePaths.push_back (includeString);
125116 }
126117
127- collectModuleHeaderIncludes (fileManager, moduleMap, module , headerContents );
118+ collectModuleHeaderIncludes (fileManager, moduleMap, module , umbrellaHeaders );
128119 std::for_each (module ->submodule_begin (), module ->submodule_end (), collector);
129120 };
130121
131122 std::for_each (modules.begin (), modules.end (), collector);
132123
133- if (umbrellaHeaderContents)
134- *umbrellaHeaderContents = headerContents.str ();
135-
136124 return std::error_code ();
137125}
138126
127+ // Sort headers so that -Swift headers come last (see https://github.com/NativeScript/ios-runtime/issues/1153)
128+ int headerPriority (SmallString<256 > h) {
129+ if (std::string::npos != h.find (" -Swift" )) {
130+ return 1 ;
131+ } else {
132+ return 0 ;
133+ }
134+ }
135+
136+
139137std::string CreateUmbrellaHeader (const std::vector<std::string>& clangArgs, std::vector<std::string>& includePaths)
140138{
141- std::string umbrellaHeaderContents;
142139 std::vector<std::string> moduleBlacklist;
143140
144141 // Generate umbrella header for all modules from the sdk
145- CreateUmbrellaHeaderForAmbientModules (clangArgs, &umbrellaHeaderContents, moduleBlacklist, includePaths);
146- return umbrellaHeaderContents;
142+ std::vector<SmallString<256 >> umbrellaHeaders;
143+ CreateUmbrellaHeaderForAmbientModules (clangArgs, umbrellaHeaders, moduleBlacklist, includePaths);
144+
145+ std::sort (umbrellaHeaders.begin (), umbrellaHeaders.end (), [](const SmallString<256 >& h1, const SmallString<256 >& h2) {
146+ return headerPriority (h1) < headerPriority (h2);
147+ });
148+
149+ std::stringstream umbrellaHeaderContents;
150+ for (auto & h : umbrellaHeaders) {
151+ umbrellaHeaderContents << " #import \" " << h.c_str () << " \" " << std::endl;
152+ }
153+
154+ return umbrellaHeaderContents.str ();
147155}
0 commit comments