@@ -768,73 +768,53 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
768
768
return false ;
769
769
770
770
// FIXME: The following attempts to do an initial ReadAST invocation to verify
771
- // the PCH, without affecting the existing CompilerInstance.
771
+ // the PCH, without causing trouble for the existing CompilerInstance.
772
772
// Look into combining creating the ASTReader along with verification + update
773
773
// if necessary, so that we can create and use one ASTReader in the common case
774
774
// when there is no need for update.
775
+ clang::CompilerInstance CI (Impl.Instance ->getPCHContainerOperations (),
776
+ &Impl.Instance ->getModuleCache ());
777
+ auto invocation =
778
+ std::make_shared<clang::CompilerInvocation>(*Impl.Invocation );
779
+ invocation->getPreprocessorOpts ().DisablePCHValidation = false ;
780
+ invocation->getPreprocessorOpts ().AllowPCHWithCompilerErrors = false ;
781
+ invocation->getHeaderSearchOpts ().ModulesValidateSystemHeaders = true ;
782
+ invocation->getLangOpts ()->NeededByPCHOrCompilationUsesPCH = true ;
783
+ invocation->getLangOpts ()->CacheGeneratedPCH = true ;
775
784
776
- CompilerInstance &CI = *Impl.Instance ;
777
- auto clangDiags = CompilerInstance::createDiagnostics (
778
- new clang::DiagnosticOptions ());
785
+ // ClangImporter::create adds a remapped MemoryBuffer that we don't need
786
+ // here. Moreover, it's a raw pointer owned by the preprocessor options; if
787
+ // we don't clear the range then both the original and new CompilerInvocation
788
+ // will try to free it.
789
+ invocation->getPreprocessorOpts ().RemappedFileBuffers .clear ();
790
+
791
+ CI.setInvocation (std::move (invocation));
792
+ CI.setTarget (&Impl.Instance ->getTarget ());
793
+ CI.setDiagnostics (
794
+ &*CompilerInstance::createDiagnostics (new clang::DiagnosticOptions ()));
779
795
780
796
// Note: Reusing the file manager is safe; this is a component that's already
781
797
// reused when building PCM files for the module cache.
782
- clang::SourceManager clangSrcMgr (*clangDiags, CI.getFileManager ());
798
+ CI.createSourceManager (Impl.Instance ->getFileManager ());
799
+ auto &clangSrcMgr = CI.getSourceManager ();
783
800
auto FID = clangSrcMgr.createFileID (
784
801
llvm::make_unique<ZeroFilledMemoryBuffer>(1 , " <main>" ));
785
802
clangSrcMgr.setMainFileID (FID);
786
803
787
- // Note: Reusing the real HeaderSearch is dangerous, but it's not easy to
788
- // copy. We put in some effort to reset it to the way it was below.
789
- clang::HeaderSearch &headerSearchInfo =
790
- CI.getPreprocessor ().getHeaderSearchInfo ();
791
- assert (headerSearchInfo.getExternalLookup () == nullptr &&
792
- " already configured an ASTReader" );
793
-
794
- // Note: Reusing the PCM cache is safe because that's already shared when
795
- // building PCM files for the module cache. Using the top-level compiler
796
- // instance as a module loader does seem a little dangerous but does not
797
- // appear to cause problems at the moment.
798
- clang::Preprocessor PP (CI.getInvocation ().getPreprocessorOptsPtr (),
799
- *clangDiags,
800
- CI.getLangOpts (),
801
- clangSrcMgr,
802
- headerSearchInfo,
803
- (clang::ModuleLoader &)CI,
804
- /* IILookup=*/ nullptr ,
805
- /* OwnsHeaderSearch=*/ false );
806
- PP.Initialize (CI.getTarget ());
807
- clang::ASTContext ctx (CI.getLangOpts (), clangSrcMgr,
808
- PP.getIdentifierTable (), PP.getSelectorTable (),
809
- PP.getBuiltinInfo ());
810
-
811
- // Note: Reusing the PCHContainerReader or ModuleFileExtensions could be
812
- // dangerous.
813
- std::unique_ptr<clang::ASTReader> Reader (new clang::ASTReader (
814
- PP, CI.getModuleCache (), &ctx, CI.getPCHContainerReader (),
815
- CI.getFrontendOpts ().ModuleFileExtensions ,
816
- CI.getHeaderSearchOpts ().Sysroot ,
817
- /* DisableValidation*/ false ,
818
- /* AllowPCHWithCompilerErrors*/ false ,
819
- /* AllowConfigurationMismatch*/ false ,
820
- /* ValidateSystemInputs*/ true ));
821
- SWIFT_DEFER {
822
- assert (headerSearchInfo.getExternalLookup () == Reader.get () ||
823
- headerSearchInfo.getExternalLookup () == nullptr );
824
- headerSearchInfo.SetExternalLookup (nullptr );
825
- headerSearchInfo.SetExternalSource (nullptr );
826
- };
827
- ctx.InitBuiltinTypes (CI.getTarget ());
804
+ // Pass in TU_Complete, which is the default mode for the Preprocessor
805
+ // constructor and the right one for reading a PCH.
806
+ CI.createPreprocessor (clang::TU_Complete);
807
+ CI.createASTContext ();
808
+ CI.createModuleManager ();
809
+ clang::ASTReader &Reader = *CI.getModuleManager ();
828
810
829
811
auto failureCapabilities =
830
812
clang::ASTReader::ARR_Missing |
831
813
clang::ASTReader::ARR_OutOfDate |
832
814
clang::ASTReader::ARR_VersionMismatch;
833
815
834
- auto result = Reader->ReadAST (PCHFilename,
835
- clang::serialization::MK_PCH,
836
- clang::SourceLocation (),
837
- failureCapabilities);
816
+ auto result = Reader.ReadAST (PCHFilename, clang::serialization::MK_PCH,
817
+ clang::SourceLocation (), failureCapabilities);
838
818
switch (result) {
839
819
case clang::ASTReader::Success:
840
820
return true ;
@@ -1469,8 +1449,8 @@ std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
1469
1449
bool
1470
1450
ClangImporter::emitBridgingPCH (StringRef headerPath,
1471
1451
StringRef outputPCHPath) {
1472
- auto invocation = std::make_shared<clang::CompilerInvocation>
1473
- ( clang::CompilerInvocation (*Impl.Invocation ) );
1452
+ auto invocation =
1453
+ std::make_shared< clang::CompilerInvocation> (*Impl.Invocation );
1474
1454
invocation->getFrontendOpts ().DisableFree = false ;
1475
1455
invocation->getFrontendOpts ().Inputs .clear ();
1476
1456
invocation->getFrontendOpts ().Inputs .push_back (
0 commit comments