5
5
#include < clang/Lex/Preprocessor.h>
6
6
#include < clang/Tooling/Tooling.h>
7
7
#include < iostream>
8
+ #include < sstream>
8
9
#include < llvm/ADT/StringSwitch.h>
9
10
#include < llvm/Support/Path.h>
10
11
11
12
using namespace clang ;
12
13
namespace path = llvm::sys::path;
13
14
namespace fs = llvm::sys::fs;
14
15
15
- static SmallVectorImpl< char >& operator +=(SmallVectorImpl< char > & includes, StringRef rhs )
16
+ static std::error_code addHeaderInclude (StringRef headerName, std::vector<SmallString< 256 >> & includes)
16
17
{
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 \" " ;
24
18
25
19
// Use an absolute path for the include; there's no reason to think whether a relative path will
26
20
// work ('.' might not be on our include path) or that it will find the same file.
27
21
if (path::is_absolute (headerName)) {
28
- includes += headerName;
22
+ includes. push_back ( headerName) ;
29
23
}
30
24
else {
31
25
SmallString<256 > header = headerName;
32
26
if (std::error_code err = fs::make_absolute (header))
33
27
return err;
34
- includes += header;
28
+ includes. push_back ( header) ;
35
29
}
36
30
37
- includes += " \"\n " ;
38
-
39
31
return std::error_code ();
40
32
}
41
33
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)
43
35
{
44
36
return addHeaderInclude (header->getName (), includes);
45
37
}
46
38
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)
48
40
{
49
41
// Don't collect any headers for unavailable modules.
50
42
if (!module ->isAvailable ())
@@ -91,7 +83,7 @@ static std::error_code collectModuleHeaderIncludes(FileManager& fileMgr, ModuleM
91
83
return std::error_code ();
92
84
}
93
85
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)
95
87
{
96
88
std::unique_ptr<clang::ASTUnit> ast = clang::tooling::buildASTFromCodeWithArgs (" " , args, " umbrella.h" );
97
89
if (!ast)
@@ -106,7 +98,6 @@ static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<s
106
98
ModuleMap& moduleMap = headerSearch.getModuleMap ();
107
99
FileManager& fileManager = ast->getFileManager ();
108
100
109
- SmallString<256 > headerContents;
110
101
std::function<void (const Module*)> collector = [&](const Module* module ) {
111
102
// uncomment for debugging unavailable modules
112
103
// if (!module->isAvailable()) {
@@ -124,24 +115,41 @@ static std::error_code CreateUmbrellaHeaderForAmbientModules(const std::vector<s
124
115
includePaths.push_back (includeString);
125
116
}
126
117
127
- collectModuleHeaderIncludes (fileManager, moduleMap, module , headerContents );
118
+ collectModuleHeaderIncludes (fileManager, moduleMap, module , umbrellaHeaders );
128
119
std::for_each (module ->submodule_begin (), module ->submodule_end (), collector);
129
120
};
130
121
131
122
std::for_each (modules.begin (), modules.end (), collector);
132
123
133
- if (umbrellaHeaderContents)
134
- *umbrellaHeaderContents = headerContents.str ();
135
-
136
124
return std::error_code ();
137
125
}
138
126
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
+
139
137
std::string CreateUmbrellaHeader (const std::vector<std::string>& clangArgs, std::vector<std::string>& includePaths)
140
138
{
141
- std::string umbrellaHeaderContents;
142
139
std::vector<std::string> moduleBlacklist;
143
140
144
141
// 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 ();
147
155
}
0 commit comments