35
35
#include " swift/Parse/Lexer.h"
36
36
#include " swift/Parse/Parser.h"
37
37
#include " swift/Config.h"
38
+ #include " swift/Strings.h"
38
39
#include " clang/AST/ASTContext.h"
39
40
#include " clang/AST/Mangle.h"
40
41
#include " clang/Basic/CharInfo.h"
@@ -123,9 +124,25 @@ namespace {
123
124
}
124
125
};
125
126
127
+ class PCHDeserializationCallbacks : public clang ::ASTDeserializationListener {
128
+ ClangImporter::Implementation &Impl;
129
+ public:
130
+ explicit PCHDeserializationCallbacks (ClangImporter::Implementation &impl)
131
+ : Impl(impl) {}
132
+ void ModuleImportRead (clang::serialization::SubmoduleID ID,
133
+ clang::SourceLocation ImportLoc) {
134
+ if (Impl.IsReadingBridgingPCH ) {
135
+ Impl.PCHImportedSubmodules .push_back (ID);
136
+ }
137
+ }
138
+ };
139
+
126
140
class HeaderParsingASTConsumer : public clang ::ASTConsumer {
127
141
SmallVector<clang::DeclGroupRef, 4 > DeclGroups;
142
+ PCHDeserializationCallbacks PCHCallbacks;
128
143
public:
144
+ explicit HeaderParsingASTConsumer (ClangImporter::Implementation &impl)
145
+ : PCHCallbacks(impl) {}
129
146
void
130
147
HandleTopLevelDeclInObjCContainer (clang::DeclGroupRef decls) override {
131
148
DeclGroups.push_back (decls);
@@ -135,15 +152,40 @@ namespace {
135
152
return DeclGroups;
136
153
}
137
154
155
+ clang::ASTDeserializationListener *GetASTDeserializationListener () override {
156
+ return &PCHCallbacks;
157
+ }
158
+
138
159
void reset () {
139
160
DeclGroups.clear ();
140
161
}
141
162
};
142
163
143
164
class ParsingAction : public clang ::ASTFrontendAction {
165
+ ASTContext &Ctx;
166
+ ClangImporter &Importer;
167
+ ClangImporter::Implementation &Impl;
168
+ public:
169
+ explicit ParsingAction (ASTContext &ctx,
170
+ ClangImporter &importer,
171
+ ClangImporter::Implementation &impl)
172
+ : Ctx(ctx), Importer(importer), Impl(impl) {}
144
173
std::unique_ptr<clang::ASTConsumer>
145
174
CreateASTConsumer (clang::CompilerInstance &CI, StringRef InFile) override {
146
- return llvm::make_unique<HeaderParsingASTConsumer>();
175
+ return llvm::make_unique<HeaderParsingASTConsumer>(Impl);
176
+ }
177
+ bool BeginSourceFileAction (CompilerInstance &CI,
178
+ StringRef Filename) override {
179
+ // Prefer frameworks over plain headers.
180
+ // We add search paths here instead of when building the initial invocation
181
+ // so that (a) we use the same code as search paths for imported modules,
182
+ // and (b) search paths are always added after -Xcc options.
183
+ SearchPathOptions &searchPathOpts = Ctx.SearchPathOpts ;
184
+ for (auto path : searchPathOpts.FrameworkSearchPaths )
185
+ Importer.addSearchPath (path, /* isFramework*/ true );
186
+ for (auto path : searchPathOpts.ImportSearchPaths )
187
+ Importer.addSearchPath (path, /* isFramework*/ false );
188
+ return true ;
147
189
}
148
190
};
149
191
@@ -318,6 +360,14 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
318
360
319
361
auto languageVersion = ctx.LangOpts .EffectiveLanguageVersion ;
320
362
363
+ if (llvm::sys::path::extension (importerOpts.BridgingHeader ).endswith (
364
+ PCH_EXTENSION)) {
365
+ invocationArgStrs.insert (
366
+ invocationArgStrs.end (),
367
+ { " -include-pch" , importerOpts.BridgingHeader }
368
+ );
369
+ }
370
+
321
371
// Construct the invocation arguments for the current target.
322
372
// Add target-independent options first.
323
373
invocationArgStrs.insert (
@@ -622,6 +672,11 @@ ClangImporter::create(ASTContext &ctx,
622
672
for (auto &argStr : invocationArgStrs)
623
673
invocationArgs.push_back (argStr.c_str ());
624
674
675
+ if (llvm::sys::path::extension (importerOpts.BridgingHeader ).endswith (
676
+ PCH_EXTENSION)) {
677
+ importer->Impl .IsReadingBridgingPCH = true ;
678
+ }
679
+
625
680
// FIXME: These can't be controlled from the command line.
626
681
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagnosticOpts{
627
682
new clang::DiagnosticOptions
@@ -681,7 +736,8 @@ ClangImporter::create(ASTContext &ctx,
681
736
instance.setInvocation (&*invocation);
682
737
683
738
// Create the associated action.
684
- importer->Impl .Action .reset (new ParsingAction);
739
+ importer->Impl .Action .reset (new ParsingAction (ctx, *importer,
740
+ importer->Impl ));
685
741
auto *action = importer->Impl .Action .get ();
686
742
687
743
// Execute the action. We effectively inline most of
@@ -736,16 +792,6 @@ ClangImporter::create(ASTContext &ctx,
736
792
importer->Impl .SwiftContext , importer->Impl .platformAvailability ,
737
793
importer->Impl .getClangSema (), importer->Impl .InferImportAsMember ));
738
794
739
- // Prefer frameworks over plain headers.
740
- // We add search paths here instead of when building the initial invocation
741
- // so that (a) we use the same code as search paths for imported modules,
742
- // and (b) search paths are always added after -Xcc options.
743
- SearchPathOptions &searchPathOpts = ctx.SearchPathOpts ;
744
- for (auto path : searchPathOpts.FrameworkSearchPaths )
745
- importer->addSearchPath (path, /* isFramework*/ true );
746
- for (auto path : searchPathOpts.ImportSearchPaths )
747
- importer->addSearchPath (path, /* isFramework*/ false );
748
-
749
795
// FIXME: These decls are not being parsed correctly since (a) some of the
750
796
// callbacks are still being added, and (b) the logic to parse them has
751
797
// changed.
@@ -792,6 +838,8 @@ ClangImporter::create(ASTContext &ctx,
792
838
new (ctx) ClangModuleUnit (*importedHeaderModule, *importer, nullptr );
793
839
importedHeaderModule->addFile (*importer->Impl .ImportedHeaderUnit );
794
840
841
+ importer->Impl .IsReadingBridgingPCH = false ;
842
+
795
843
return importer;
796
844
}
797
845
@@ -926,6 +974,19 @@ bool ClangImporter::importHeader(StringRef header, Module *adapter,
926
974
bool ClangImporter::importBridgingHeader (StringRef header, Module *adapter,
927
975
SourceLoc diagLoc,
928
976
bool trackParsedSymbols) {
977
+ if (llvm::sys::path::extension (header).endswith (PCH_EXTENSION)) {
978
+ // We already imported this with -include-pch above, so we should have
979
+ // collected a bunch of PCH-encoded module imports that we need to
980
+ // replay to the HeaderImportCallbacks for processing.
981
+ Impl.ImportedHeaderOwners .push_back (adapter);
982
+ clang::ASTReader &R = *Impl.Instance ->getModuleManager ();
983
+ HeaderImportCallbacks CB (*this , Impl);
984
+ for (auto ID : Impl.PCHImportedSubmodules ) {
985
+ CB.handleImport (R.getSubmodule (ID));
986
+ }
987
+ Impl.PCHImportedSubmodules .clear ();
988
+ return false ;
989
+ }
929
990
clang::FileManager &fileManager = Impl.Instance ->getFileManager ();
930
991
const clang::FileEntry *headerFile = fileManager.getFile (header,
931
992
/* OpenFile=*/ true );
@@ -1273,6 +1334,7 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx,
1273
1334
ImportForwardDeclarations(opts.ImportForwardDeclarations),
1274
1335
InferImportAsMember(opts.InferImportAsMember),
1275
1336
DisableSwiftBridgeAttr(opts.DisableSwiftBridgeAttr),
1337
+ IsReadingBridgingPCH(false ),
1276
1338
CurrentVersion(nameVersionFromOptions(ctx.LangOpts)),
1277
1339
BridgingHeaderLookupTable(new SwiftLookupTable(nullptr )),
1278
1340
platformAvailability(ctx.LangOpts),
0 commit comments