mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Cache Code Completion results from PCH files
- Add CompilerInvocation::getPCHHash
This will be used when creating a unique filename for a persistent
precompiled bridging header.
- Automatically generate and use a precompiled briding header
When we're given both -import-objc-header and -pch-output-dir
arguments, we will try to:
- Validate what we think the PCH filename should be for the bridging
header, based on the Swift PCH hash and the clang module hash.
- If we're successful, we'll just use it.
- If it's out of date or something else is wrong, we'll try to
emit it.
- This gives us a single filename which we can `stat` to check for the
validity of our code completion cache, which is keyed off of module
name, module filename, and module file age.
- Cache code completion results from imported modules
If we just have a single .PCH file imported, we can use that file as
part of the key used to cache declarations in a module. Because
multiple files can contribute to the __ObjC module, we've always given
it the phony filename "<imports>", which never exists, so `stat`-ing it
always fails and we never cache declarations in it.
This is extremely problematic for projects with huge bridging headers.
In the case where we have a single PCH import, this can bring warm code
completion times down to about 500ms from over 2-3s, so it can provide a
nice performance win for IDEs.
- Add a new test that performs two code-completion requests with a bridging header.
- Add some -pch-output-dir flags to existing SourceKit tests that import a bridging
header.
rdar://problem/31198982
This commit is contained in:
@@ -209,6 +209,12 @@ public:
|
|||||||
return OutputKind == IRGenOutputKind::LLVMAssembly;
|
return OutputKind == IRGenOutputKind::LLVMAssembly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
return llvm::hash_value(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#define SWIFT_AST_SILOPTIONS_H
|
#define SWIFT_AST_SILOPTIONS_H
|
||||||
|
|
||||||
#include "swift/Basic/Sanitizers.h"
|
#include "swift/Basic/Sanitizers.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
@@ -147,6 +148,11 @@ public:
|
|||||||
|
|
||||||
SILOptions() : Sanitize(SanitizerKind::None) {}
|
SILOptions() : Sanitize(SanitizerKind::None) {}
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
return llvm::hash_value(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#ifndef SWIFT_AST_SEARCHPATHOPTIONS_H
|
#ifndef SWIFT_AST_SEARCHPATHOPTIONS_H
|
||||||
#define SWIFT_AST_SEARCHPATHOPTIONS_H
|
#define SWIFT_AST_SEARCHPATHOPTIONS_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -67,6 +69,26 @@ public:
|
|||||||
|
|
||||||
/// Don't look in for compiler-provided modules.
|
/// Don't look in for compiler-provided modules.
|
||||||
bool SkipRuntimeLibraryImportPath = false;
|
bool SkipRuntimeLibraryImportPath = false;
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
using llvm::hash_value;
|
||||||
|
using llvm::hash_combine;
|
||||||
|
auto Code = hash_value(SDKPath);
|
||||||
|
for (auto Import : ImportSearchPaths) {
|
||||||
|
Code = hash_combine(Code, Import);
|
||||||
|
}
|
||||||
|
for (const auto &FrameworkPath : FrameworkSearchPaths) {
|
||||||
|
Code = hash_combine(Code, FrameworkPath.Path);
|
||||||
|
}
|
||||||
|
for (auto LibraryPath : LibrarySearchPaths) {
|
||||||
|
Code = hash_combine(Code, LibraryPath);
|
||||||
|
}
|
||||||
|
Code = hash_combine(Code, RuntimeResourcePath);
|
||||||
|
Code = hash_combine(Code, RuntimeLibraryImportPath);
|
||||||
|
return Code;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ public:
|
|||||||
|
|
||||||
/// Treat all warnings as errors
|
/// Treat all warnings as errors
|
||||||
bool WarningsAsErrors = false;
|
bool WarningsAsErrors = false;
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
// Nothing here that contributes anything significant when emitting the PCH.
|
||||||
|
return llvm::hash_value(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -22,9 +22,12 @@
|
|||||||
#include "swift/Basic/Version.h"
|
#include "swift/Basic/Version.h"
|
||||||
#include "clang/Basic/VersionTuple.h"
|
#include "clang/Basic/VersionTuple.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -278,6 +281,17 @@ namespace swift {
|
|||||||
PlatformConditionKind Kind, StringRef Value,
|
PlatformConditionKind Kind, StringRef Value,
|
||||||
std::vector<StringRef> &suggestions);
|
std::vector<StringRef> &suggestions);
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
auto code = llvm::hash_value(Target.str());
|
||||||
|
SmallString<16> Scratch;
|
||||||
|
llvm::raw_svector_ostream OS(Scratch);
|
||||||
|
OS << EffectiveLanguageVersion;
|
||||||
|
code = llvm::hash_combine(code, OS.str());
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>,
|
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>,
|
||||||
NumPlatformConditionKind>
|
NumPlatformConditionKind>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace clang {
|
|||||||
class CodeGenOptions;
|
class CodeGenOptions;
|
||||||
class Decl;
|
class Decl;
|
||||||
class DependencyCollector;
|
class DependencyCollector;
|
||||||
|
class DiagnosticConsumer;
|
||||||
class EnumConstantDecl;
|
class EnumConstantDecl;
|
||||||
class EnumDecl;
|
class EnumDecl;
|
||||||
class MacroInfo;
|
class MacroInfo;
|
||||||
@@ -44,6 +45,7 @@ namespace clang {
|
|||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
|
class CompilerInvocation;
|
||||||
class ClangImporterOptions;
|
class ClangImporterOptions;
|
||||||
class ClangModuleUnit;
|
class ClangModuleUnit;
|
||||||
class ClangNode;
|
class ClangNode;
|
||||||
@@ -78,14 +80,19 @@ public:
|
|||||||
/// \param ctx The ASTContext into which the module will be imported.
|
/// \param ctx The ASTContext into which the module will be imported.
|
||||||
/// The ASTContext's SearchPathOptions will be used for the Clang importer.
|
/// The ASTContext's SearchPathOptions will be used for the Clang importer.
|
||||||
///
|
///
|
||||||
/// \param clangImporterOpts The options to use for the Clang importer.
|
/// \param importerOpts The options to use for the Clang importer.
|
||||||
|
///
|
||||||
|
/// \param swiftPCHHash A hash of Swift's various options in a compiler
|
||||||
|
/// invocation, used to create a unique Bridging PCH if requested.
|
||||||
///
|
///
|
||||||
/// \param tracker The object tracking files this compilation depends on.
|
/// \param tracker The object tracking files this compilation depends on.
|
||||||
///
|
///
|
||||||
/// \returns a new Clang module importer, or null (with a diagnostic) if
|
/// \returns a new Clang module importer, or null (with a diagnostic) if
|
||||||
/// an error occurred.
|
/// an error occurred.
|
||||||
static std::unique_ptr<ClangImporter>
|
static std::unique_ptr<ClangImporter>
|
||||||
create(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
|
create(ASTContext &ctx,
|
||||||
|
const ClangImporterOptions &importerOpts,
|
||||||
|
std::string swiftPCHHash = "",
|
||||||
DependencyTracker *tracker = nullptr);
|
DependencyTracker *tracker = nullptr);
|
||||||
|
|
||||||
ClangImporter(const ClangImporter &) = delete;
|
ClangImporter(const ClangImporter &) = delete;
|
||||||
@@ -234,7 +241,14 @@ public:
|
|||||||
/// replica.
|
/// replica.
|
||||||
///
|
///
|
||||||
/// \sa clang::GeneratePCHAction
|
/// \sa clang::GeneratePCHAction
|
||||||
bool emitBridgingPCH(StringRef headerPath, StringRef outputPCHPath);
|
bool emitBridgingPCH(StringRef headerPath,
|
||||||
|
StringRef outputPCHPath,
|
||||||
|
clang::DiagnosticConsumer *Diags = nullptr);
|
||||||
|
|
||||||
|
/// Returns true if a clang CompilerInstance can successfully read in a PCH,
|
||||||
|
/// assuming it exists, with the current options. This can be used to find out
|
||||||
|
/// if we need to persist a PCH for later reuse.
|
||||||
|
bool canReadPCH(StringRef PCHFilename);
|
||||||
|
|
||||||
const clang::Module *getClangOwningModule(ClangNode Node) const;
|
const clang::Module *getClangOwningModule(ClangNode Node) const;
|
||||||
bool hasTypedef(const clang::Decl *typeDecl) const;
|
bool hasTypedef(const clang::Decl *typeDecl) const;
|
||||||
@@ -291,6 +305,13 @@ public:
|
|||||||
|
|
||||||
DeclName importName(const clang::NamedDecl *D,
|
DeclName importName(const clang::NamedDecl *D,
|
||||||
clang::DeclarationName givenName);
|
clang::DeclarationName givenName);
|
||||||
|
|
||||||
|
Optional<std::string>
|
||||||
|
getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
|
||||||
|
const std::string &SwiftPCHHash);
|
||||||
|
Optional<std::string>
|
||||||
|
getPCHFilename(const ClangImporterOptions &ImporterOptions,
|
||||||
|
const std::string &SwiftPCHHash);
|
||||||
};
|
};
|
||||||
|
|
||||||
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,
|
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#ifndef SWIFT_CLANGIMPORTER_CLANGIMPORTEROPTIONS_H
|
#ifndef SWIFT_CLANGIMPORTER_CLANGIMPORTEROPTIONS_H
|
||||||
#define SWIFT_CLANGIMPORTER_CLANGIMPORTEROPTIONS_H
|
#define SWIFT_CLANGIMPORTER_CLANGIMPORTEROPTIONS_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -43,7 +45,7 @@ public:
|
|||||||
std::string PrecompiledHeaderOutputDir;
|
std::string PrecompiledHeaderOutputDir;
|
||||||
|
|
||||||
/// \see Mode
|
/// \see Mode
|
||||||
enum class Modes {
|
enum class Modes : uint8_t {
|
||||||
/// Set up Clang for importing modules into Swift and generating IR from
|
/// Set up Clang for importing modules into Swift and generating IR from
|
||||||
/// Swift code.
|
/// Swift code.
|
||||||
Normal,
|
Normal,
|
||||||
@@ -84,6 +86,28 @@ public:
|
|||||||
|
|
||||||
/// When set, don't look for or load adapter modules.
|
/// When set, don't look for or load adapter modules.
|
||||||
bool DisableAdapterModules = false;
|
bool DisableAdapterModules = false;
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
using llvm::hash_value;
|
||||||
|
using llvm::hash_combine;
|
||||||
|
|
||||||
|
auto Code = hash_value(ModuleCachePath);
|
||||||
|
// ExtraArgs ignored - already considered in Clang's module hashing.
|
||||||
|
Code = hash_combine(Code, OverrideResourceDir);
|
||||||
|
Code = hash_combine(Code, TargetCPU);
|
||||||
|
Code = hash_combine(Code, BridgingHeader);
|
||||||
|
Code = hash_combine(Code, PrecompiledHeaderOutputDir);
|
||||||
|
Code = hash_combine(Code, static_cast<uint8_t>(Mode));
|
||||||
|
Code = hash_combine(Code, DetailedPreprocessingRecord);
|
||||||
|
Code = hash_combine(Code, ImportForwardDeclarations);
|
||||||
|
Code = hash_combine(Code, InferImportAsMember);
|
||||||
|
Code = hash_combine(Code, DisableSwiftBridgeAttr);
|
||||||
|
Code = hash_combine(Code, DisableModulesValidateSystemHeaders);
|
||||||
|
Code = hash_combine(Code, DisableAdapterModules);
|
||||||
|
return Code;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -292,6 +292,11 @@ public:
|
|||||||
bool isDelayedFunctionBodyParsing() const {
|
bool isDelayedFunctionBodyParsing() const {
|
||||||
return FrontendOpts.DelayedFunctionBodyParsing;
|
return FrontendOpts.DelayedFunctionBodyParsing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve a module hash string that is suitable for uniquely
|
||||||
|
/// identifying the conditions under which the module was built, for use
|
||||||
|
/// in generating a cached PCH file for the bridging header.
|
||||||
|
std::string getPCHHash() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A class which manages the state and execution of the compiler.
|
/// A class which manages the state and execution of the compiler.
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
|
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
|
||||||
|
|
||||||
#include "swift/AST/Module.h"
|
#include "swift/AST/Module.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -305,6 +306,12 @@ public:
|
|||||||
OutputFilenames.clear();
|
OutputFilenames.clear();
|
||||||
OutputFilenames.push_back(FileName);
|
OutputFilenames.push_back(FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a hash code of any components from these options that should
|
||||||
|
/// contribute to a Swift Bridging PCH hash.
|
||||||
|
llvm::hash_code getPCHHashComponents() const {
|
||||||
|
return llvm::hash_value(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "swift/Basic/LangOptions.h"
|
#include "swift/Basic/LangOptions.h"
|
||||||
#include "swift/Basic/Range.h"
|
#include "swift/Basic/Range.h"
|
||||||
#include "swift/Config.h"
|
#include "swift/Config.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|||||||
@@ -145,27 +145,44 @@ namespace {
|
|||||||
ASTContext &Ctx;
|
ASTContext &Ctx;
|
||||||
ClangImporter &Importer;
|
ClangImporter &Importer;
|
||||||
ClangImporter::Implementation &Impl;
|
ClangImporter::Implementation &Impl;
|
||||||
|
const ClangImporterOptions &ImporterOpts;
|
||||||
|
std::string SwiftPCHHash;
|
||||||
public:
|
public:
|
||||||
explicit ParsingAction(ASTContext &ctx,
|
explicit ParsingAction(ASTContext &ctx,
|
||||||
ClangImporter &importer,
|
ClangImporter &importer,
|
||||||
ClangImporter::Implementation &impl)
|
ClangImporter::Implementation &impl,
|
||||||
: Ctx(ctx), Importer(importer), Impl(impl) {}
|
const ClangImporterOptions &importerOpts,
|
||||||
|
std::string swiftPCHHash)
|
||||||
|
: Ctx(ctx), Importer(importer), Impl(impl), ImporterOpts(importerOpts),
|
||||||
|
SwiftPCHHash(swiftPCHHash) {}
|
||||||
std::unique_ptr<clang::ASTConsumer>
|
std::unique_ptr<clang::ASTConsumer>
|
||||||
CreateASTConsumer(clang::CompilerInstance &CI, StringRef InFile) override {
|
CreateASTConsumer(clang::CompilerInstance &CI, StringRef InFile) override {
|
||||||
return llvm::make_unique<HeaderParsingASTConsumer>(Impl);
|
return llvm::make_unique<HeaderParsingASTConsumer>(Impl);
|
||||||
}
|
}
|
||||||
bool BeginSourceFileAction(CompilerInstance &CI,
|
bool BeginSourceFileAction(clang::CompilerInstance &CI,
|
||||||
StringRef Filename) override {
|
StringRef Filename) override {
|
||||||
// Prefer frameworks over plain headers.
|
// Prefer frameworks over plain headers.
|
||||||
// We add search paths here instead of when building the initial invocation
|
// We add search paths here instead of when building the initial invocation
|
||||||
// so that (a) we use the same code as search paths for imported modules,
|
// so that (a) we use the same code as search paths for imported modules,
|
||||||
// and (b) search paths are always added after -Xcc options.
|
// and (b) search paths are always added after -Xcc options.
|
||||||
SearchPathOptions &searchPathOpts = Ctx.SearchPathOpts;
|
SearchPathOptions &searchPathOpts = Ctx.SearchPathOpts;
|
||||||
for (const auto &framepath : searchPathOpts.FrameworkSearchPaths)
|
for (const auto &framepath : searchPathOpts.FrameworkSearchPaths) {
|
||||||
Importer.addSearchPath(framepath.Path, /*isFramework*/true,
|
Importer.addSearchPath(framepath.Path, /*isFramework*/true,
|
||||||
framepath.IsSystem);
|
framepath.IsSystem);
|
||||||
for (auto path : searchPathOpts.ImportSearchPaths)
|
}
|
||||||
|
|
||||||
|
for (auto path : searchPathOpts.ImportSearchPaths) {
|
||||||
Importer.addSearchPath(path, /*isFramework*/false, /*isSystem=*/false);
|
Importer.addSearchPath(path, /*isFramework*/false, /*isSystem=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PCH = Importer.getOrCreatePCH(ImporterOpts, SwiftPCHHash);
|
||||||
|
if (PCH.hasValue()) {
|
||||||
|
Impl.getClangInstance()->getPreprocessorOpts().ImplicitPCHInclude =
|
||||||
|
PCH.getValue();
|
||||||
|
Impl.IsReadingBridgingPCH = true;
|
||||||
|
Impl.setSinglePCHImport(PCH.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -692,11 +709,73 @@ addCommonInvocationArguments(std::vector<std::string> &invocationArgStrs,
|
|||||||
llvm::itostr(ctx.LangOpts.EffectiveLanguageVersion[0]));
|
llvm::itostr(ctx.LangOpts.EffectiveLanguageVersion[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClangImporter::canReadPCH(StringRef PCHFilename) {
|
||||||
|
return clang::ASTReader::isAcceptableASTFile(PCHFilename,
|
||||||
|
Impl.Instance->getFileManager(),
|
||||||
|
Impl.Instance->getPCHContainerReader(),
|
||||||
|
Impl.Instance->getLangOpts(),
|
||||||
|
Impl.Instance->getTargetOpts(),
|
||||||
|
Impl.Instance->getPreprocessorOpts(),
|
||||||
|
Impl.Instance->getSpecificModuleCachePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<std::string>
|
||||||
|
ClangImporter::getPCHFilename(const ClangImporterOptions &ImporterOptions,
|
||||||
|
const std::string &SwiftPCHHash) {
|
||||||
|
if (llvm::sys::path::extension(ImporterOptions.BridgingHeader)
|
||||||
|
.endswith(PCH_EXTENSION)) {
|
||||||
|
return ImporterOptions.BridgingHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &BridgingHeader = ImporterOptions.BridgingHeader;
|
||||||
|
const auto &PCHOutputDir = ImporterOptions.PrecompiledHeaderOutputDir;
|
||||||
|
if (SwiftPCHHash.empty() || BridgingHeader.empty() || PCHOutputDir.empty()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallString<256> PCHBasename { llvm::sys::path::filename(BridgingHeader) };
|
||||||
|
llvm::sys::path::replace_extension(PCHBasename, "");
|
||||||
|
PCHBasename.append("-swift_");
|
||||||
|
PCHBasename.append(SwiftPCHHash);
|
||||||
|
PCHBasename.append("-clang_");
|
||||||
|
PCHBasename.append(getClangModuleHash());
|
||||||
|
llvm::sys::path::replace_extension(PCHBasename, ".pch");
|
||||||
|
SmallString<256> PCHFilename { PCHOutputDir };
|
||||||
|
llvm::sys::path::append(PCHFilename, PCHBasename);
|
||||||
|
return PCHFilename.str().str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Optional<std::string>
|
||||||
|
ClangImporter::getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
|
||||||
|
const std::string &SwiftPCHHash) {
|
||||||
|
auto PCHFilename = getPCHFilename(ImporterOptions, SwiftPCHHash);
|
||||||
|
if (!PCHFilename.hasValue()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if (!canReadPCH(PCHFilename.getValue())) {
|
||||||
|
SmallString<256> Message;
|
||||||
|
llvm::raw_svector_ostream OS(Message);
|
||||||
|
auto Diags = new clang::TextDiagnosticPrinter {
|
||||||
|
llvm::errs(),
|
||||||
|
&Impl.Instance->getDiagnosticOpts()
|
||||||
|
};
|
||||||
|
auto FailedToEmit = emitBridgingPCH(ImporterOptions.BridgingHeader,
|
||||||
|
PCHFilename.getValue(),
|
||||||
|
Diags);
|
||||||
|
if (FailedToEmit) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PCHFilename.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ClangImporter>
|
std::unique_ptr<ClangImporter>
|
||||||
ClangImporter::create(ASTContext &ctx,
|
ClangImporter::create(ASTContext &ctx,
|
||||||
const ClangImporterOptions &importerOpts,
|
const ClangImporterOptions &importerOpts,
|
||||||
|
std::string swiftPCHHash,
|
||||||
DependencyTracker *tracker) {
|
DependencyTracker *tracker) {
|
||||||
|
|
||||||
std::unique_ptr<ClangImporter> importer{
|
std::unique_ptr<ClangImporter> importer{
|
||||||
new ClangImporter(ctx, importerOpts, tracker)
|
new ClangImporter(ctx, importerOpts, tracker)
|
||||||
};
|
};
|
||||||
@@ -731,6 +810,7 @@ ClangImporter::create(ASTContext &ctx,
|
|||||||
|
|
||||||
if (llvm::sys::path::extension(importerOpts.BridgingHeader).endswith(
|
if (llvm::sys::path::extension(importerOpts.BridgingHeader).endswith(
|
||||||
PCH_EXTENSION)) {
|
PCH_EXTENSION)) {
|
||||||
|
importer->Impl.setSinglePCHImport(importerOpts.BridgingHeader);
|
||||||
importer->Impl.IsReadingBridgingPCH = true;
|
importer->Impl.IsReadingBridgingPCH = true;
|
||||||
if (tracker) {
|
if (tracker) {
|
||||||
// Currently ignoring dependency on bridging .pch files because they are
|
// Currently ignoring dependency on bridging .pch files because they are
|
||||||
@@ -751,7 +831,8 @@ ClangImporter::create(ASTContext &ctx,
|
|||||||
new ClangDiagnosticConsumer(importer->Impl, *diagnosticOpts,
|
new ClangDiagnosticConsumer(importer->Impl, *diagnosticOpts,
|
||||||
importerOpts.DumpClangDiagnostics)
|
importerOpts.DumpClangDiagnostics)
|
||||||
};
|
};
|
||||||
auto clangDiags = CompilerInstance::createDiagnostics(diagnosticOpts.get(),
|
auto clangDiags =
|
||||||
|
clang::CompilerInstance::createDiagnostics(diagnosticOpts.get(),
|
||||||
diagClient.release());
|
diagClient.release());
|
||||||
|
|
||||||
// Create a new Clang compiler invocation.
|
// Create a new Clang compiler invocation.
|
||||||
@@ -794,7 +875,8 @@ ClangImporter::create(ASTContext &ctx,
|
|||||||
llvm::make_unique<clang::ObjectFilePCHContainerWriter>());
|
llvm::make_unique<clang::ObjectFilePCHContainerWriter>());
|
||||||
PCHContainerOperations->registerReader(
|
PCHContainerOperations->registerReader(
|
||||||
llvm::make_unique<clang::ObjectFilePCHContainerReader>());
|
llvm::make_unique<clang::ObjectFilePCHContainerReader>());
|
||||||
importer->Impl.Instance.reset(new CompilerInstance(PCHContainerOperations));
|
importer->Impl.Instance.reset(
|
||||||
|
new clang::CompilerInstance(PCHContainerOperations));
|
||||||
auto &instance = *importer->Impl.Instance;
|
auto &instance = *importer->Impl.Instance;
|
||||||
if (tracker)
|
if (tracker)
|
||||||
instance.addDependencyCollector(tracker->getClangCollector());
|
instance.addDependencyCollector(tracker->getClangCollector());
|
||||||
@@ -804,7 +886,9 @@ ClangImporter::create(ASTContext &ctx,
|
|||||||
|
|
||||||
// Create the associated action.
|
// Create the associated action.
|
||||||
importer->Impl.Action.reset(new ParsingAction(ctx, *importer,
|
importer->Impl.Action.reset(new ParsingAction(ctx, *importer,
|
||||||
importer->Impl));
|
importer->Impl,
|
||||||
|
importerOpts,
|
||||||
|
swiftPCHHash));
|
||||||
auto *action = importer->Impl.Action.get();
|
auto *action = importer->Impl.Action.get();
|
||||||
|
|
||||||
// Execute the action. We effectively inline most of
|
// Execute the action. We effectively inline most of
|
||||||
@@ -934,6 +1018,7 @@ bool ClangImporter::Implementation::importHeader(
|
|||||||
bool trackParsedSymbols,
|
bool trackParsedSymbols,
|
||||||
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer,
|
||||||
bool implicitImport) {
|
bool implicitImport) {
|
||||||
|
|
||||||
// Don't even try to load the bridging header if the Clang AST is in a bad
|
// Don't even try to load the bridging header if the Clang AST is in a bad
|
||||||
// state. It could cause a crash.
|
// state. It could cause a crash.
|
||||||
auto &clangDiags = getClangASTContext().getDiagnostics();
|
auto &clangDiags = getClangASTContext().getDiagnostics();
|
||||||
@@ -1061,6 +1146,11 @@ bool ClangImporter::importHeader(StringRef header, ModuleDecl *adapter,
|
|||||||
return importBridgingHeader(header, adapter, diagLoc, false, true);
|
return importBridgingHeader(header, adapter, diagLoc, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we've made it to here, this is some header other than the bridging
|
||||||
|
// header, which means we can no longer rely on one file's modification time
|
||||||
|
// to invalid code completion caches. :-(
|
||||||
|
Impl.setSinglePCHImport(None);
|
||||||
|
|
||||||
if (!cachedContents.empty() && cachedContents.back() == '\0')
|
if (!cachedContents.empty() && cachedContents.back() == '\0')
|
||||||
cachedContents = cachedContents.drop_back();
|
cachedContents = cachedContents.drop_back();
|
||||||
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer{
|
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer{
|
||||||
@@ -1082,6 +1172,7 @@ bool ClangImporter::importBridgingHeader(StringRef header, ModuleDecl *adapter,
|
|||||||
Impl.handleDeferredImports();
|
Impl.handleDeferredImports();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
clang::FileManager &fileManager = Impl.Instance->getFileManager();
|
clang::FileManager &fileManager = Impl.Instance->getFileManager();
|
||||||
const clang::FileEntry *headerFile = fileManager.getFile(header,
|
const clang::FileEntry *headerFile = fileManager.getFile(header,
|
||||||
/*OpenFile=*/true);
|
/*OpenFile=*/true);
|
||||||
@@ -1152,7 +1243,8 @@ std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
ClangImporter::emitBridgingPCH(StringRef headerPath,
|
ClangImporter::emitBridgingPCH(StringRef headerPath,
|
||||||
StringRef outputPCHPath) {
|
StringRef outputPCHPath,
|
||||||
|
clang::DiagnosticConsumer *Diags) {
|
||||||
auto invocation = std::make_shared<clang::CompilerInvocation>
|
auto invocation = std::make_shared<clang::CompilerInvocation>
|
||||||
(clang::CompilerInvocation(*Impl.Invocation));
|
(clang::CompilerInvocation(*Impl.Invocation));
|
||||||
invocation->getFrontendOpts().DisableFree = false;
|
invocation->getFrontendOpts().DisableFree = false;
|
||||||
@@ -1165,8 +1257,12 @@ ClangImporter::emitBridgingPCH(StringRef headerPath,
|
|||||||
clang::CompilerInstance emitInstance(
|
clang::CompilerInstance emitInstance(
|
||||||
Impl.Instance->getPCHContainerOperations());
|
Impl.Instance->getPCHContainerOperations());
|
||||||
emitInstance.setInvocation(std::move(invocation));
|
emitInstance.setInvocation(std::move(invocation));
|
||||||
emitInstance.createDiagnostics(&Impl.Instance->getDiagnosticClient(),
|
|
||||||
false);
|
auto ReusingDiags = Diags == nullptr;
|
||||||
|
if (ReusingDiags) {
|
||||||
|
Diags = &Impl.Instance->getDiagnosticClient();
|
||||||
|
}
|
||||||
|
emitInstance.createDiagnostics(Diags, /*ShouldOwnDiags=*/!ReusingDiags);
|
||||||
|
|
||||||
clang::FileManager &fileManager = Impl.Instance->getFileManager();
|
clang::FileManager &fileManager = Impl.Instance->getFileManager();
|
||||||
emitInstance.setFileManager(&fileManager);
|
emitInstance.setFileManager(&fileManager);
|
||||||
@@ -2446,8 +2542,14 @@ void ClangModuleUnit::collectLinkLibraries(
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringRef ClangModuleUnit::getFilename() const {
|
StringRef ClangModuleUnit::getFilename() const {
|
||||||
if (!clangModule)
|
if (!clangModule) {
|
||||||
|
auto SinglePCH = owner.getSinglePCHImport();
|
||||||
|
if (SinglePCH.hasValue()) {
|
||||||
|
return SinglePCH.getValue();
|
||||||
|
} else {
|
||||||
return "<imports>";
|
return "<imports>";
|
||||||
|
}
|
||||||
|
}
|
||||||
if (const clang::FileEntry *F = clangModule->getASTFile())
|
if (const clang::FileEntry *F = clangModule->getASTFile())
|
||||||
if (!F->getName().empty())
|
if (!F->getName().empty())
|
||||||
return F->getName();
|
return F->getName();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "swift/AST/Type.h"
|
#include "swift/AST/Type.h"
|
||||||
#include "swift/AST/ForeignErrorConvention.h"
|
#include "swift/AST/ForeignErrorConvention.h"
|
||||||
#include "swift/Basic/StringExtras.h"
|
#include "swift/Basic/StringExtras.h"
|
||||||
|
#include "swift/Strings.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/AST/DeclVisitor.h"
|
#include "clang/AST/DeclVisitor.h"
|
||||||
#include "clang/Basic/IdentifierTable.h"
|
#include "clang/Basic/IdentifierTable.h"
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
#include "llvm/ADT/SmallBitVector.h"
|
#include "llvm/ADT/SmallBitVector.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/ADT/TinyPtrVector.h"
|
#include "llvm/ADT/TinyPtrVector.h"
|
||||||
|
#include "llvm/Support/Path.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@@ -386,6 +388,10 @@ public:
|
|||||||
llvm::DenseMap<std::pair<ObjCSelector, char>, unsigned>
|
llvm::DenseMap<std::pair<ObjCSelector, char>, unsigned>
|
||||||
ActiveSelectors;
|
ActiveSelectors;
|
||||||
|
|
||||||
|
clang::CompilerInstance *getClangInstance() {
|
||||||
|
return Instance.get();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \brief Generation number that is used for crude versioning.
|
/// \brief Generation number that is used for crude versioning.
|
||||||
///
|
///
|
||||||
@@ -532,6 +538,11 @@ private:
|
|||||||
/// after having set up a suitable Clang instance.
|
/// after having set up a suitable Clang instance.
|
||||||
std::unique_ptr<importer::NameImporter> nameImporter = nullptr;
|
std::unique_ptr<importer::NameImporter> nameImporter = nullptr;
|
||||||
|
|
||||||
|
/// If there is a single .PCH file imported into the __ObjC module, this
|
||||||
|
/// is the filename of that PCH. When other files are imported, this should
|
||||||
|
/// be llvm::None.
|
||||||
|
Optional<std::string> SinglePCHImport = None;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
importer::NameImporter &getNameImporter() {
|
importer::NameImporter &getNameImporter() {
|
||||||
assert(nameImporter && "haven't finished initialization");
|
assert(nameImporter && "haven't finished initialization");
|
||||||
@@ -1158,6 +1169,22 @@ public:
|
|||||||
|
|
||||||
/// Dump the Swift-specific name lookup tables we generate.
|
/// Dump the Swift-specific name lookup tables we generate.
|
||||||
void dumpSwiftLookupTables();
|
void dumpSwiftLookupTables();
|
||||||
|
|
||||||
|
void setSinglePCHImport(Optional<std::string> PCHFilename) {
|
||||||
|
if (PCHFilename.hasValue()) {
|
||||||
|
assert(llvm::sys::path::extension(PCHFilename.getValue())
|
||||||
|
.endswith(PCH_EXTENSION) &&
|
||||||
|
"Single PCH imported filename doesn't have .pch extension!");
|
||||||
|
}
|
||||||
|
SinglePCHImport = PCHFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If there was is a single .pch bridging header without other imported
|
||||||
|
/// files, we can provide the PCH filename for declaration caching,
|
||||||
|
/// especially in code completion. If there are other
|
||||||
|
Optional<std::string> getSinglePCHImport() const {
|
||||||
|
return SinglePCHImport;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace importer {
|
namespace importer {
|
||||||
|
|||||||
@@ -1583,7 +1583,6 @@ bool CompilerInvocation::parseArgs(ArrayRef<const char *> Args,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
serialization::Status
|
serialization::Status
|
||||||
CompilerInvocation::loadFromSerializedAST(StringRef data) {
|
CompilerInvocation::loadFromSerializedAST(StringRef data) {
|
||||||
serialization::ExtendedValidationInfo extendedInfo;
|
serialization::ExtendedValidationInfo extendedInfo;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "swift/Parse/Lexer.h"
|
#include "swift/Parse/Lexer.h"
|
||||||
#include "swift/SIL/SILModule.h"
|
#include "swift/SIL/SILModule.h"
|
||||||
#include "swift/Serialization/SerializedModuleLoader.h"
|
#include "swift/Serialization/SerializedModuleLoader.h"
|
||||||
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
@@ -35,6 +36,22 @@
|
|||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
|
std::string CompilerInvocation::getPCHHash() const {
|
||||||
|
using llvm::hash_code;
|
||||||
|
using llvm::hash_value;
|
||||||
|
using llvm::hash_combine;
|
||||||
|
|
||||||
|
auto Code = hash_value(LangOpts.getPCHHashComponents());
|
||||||
|
Code = hash_combine(Code, FrontendOpts.getPCHHashComponents());
|
||||||
|
Code = hash_combine(Code, ClangImporterOpts.getPCHHashComponents());
|
||||||
|
Code = hash_combine(Code, SearchPathOpts.getPCHHashComponents());
|
||||||
|
Code = hash_combine(Code, DiagnosticOpts.getPCHHashComponents());
|
||||||
|
Code = hash_combine(Code, SILOpts.getPCHHashComponents());
|
||||||
|
Code = hash_combine(Code, IRGenOpts.getPCHHashComponents());
|
||||||
|
|
||||||
|
return llvm::APInt(64, Code).toString(36, /*Signed=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerInstance::createSILModule(bool WholeModule) {
|
void CompilerInstance::createSILModule(bool WholeModule) {
|
||||||
assert(MainModule && "main module not created yet");
|
assert(MainModule && "main module not created yet");
|
||||||
TheSILModule = SILModule::createEmptyModule(getMainModule(),
|
TheSILModule = SILModule::createEmptyModule(getMainModule(),
|
||||||
@@ -103,6 +120,7 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
|
|||||||
// knowledge.
|
// knowledge.
|
||||||
auto clangImporter =
|
auto clangImporter =
|
||||||
ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
|
ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
|
||||||
|
Invocation.getPCHHash(),
|
||||||
DepTracker);
|
DepTracker);
|
||||||
if (!clangImporter) {
|
if (!clangImporter) {
|
||||||
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
|
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
|
||||||
|
|||||||
@@ -367,7 +367,8 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
|
|||||||
auto clangImporter = static_cast<ClangImporter *>(
|
auto clangImporter = static_cast<ClangImporter *>(
|
||||||
Instance->getASTContext().getClangModuleLoader());
|
Instance->getASTContext().getClangModuleLoader());
|
||||||
return clangImporter->emitBridgingPCH(
|
return clangImporter->emitBridgingPCH(
|
||||||
Invocation.getInputFilenames()[0], opts.getSingleOutputFilename());
|
Invocation.getInputFilenames()[0],
|
||||||
|
opts.getSingleOutputFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
IRGenOptions &IRGenOpts = Invocation.getIRGenOptions();
|
IRGenOptions &IRGenOpts = Invocation.getIRGenOptions();
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TOP -import-objc-header %S/Inputs/header.h | %FileCheck %s -check-prefix=CHECK-TOP
|
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TOP -import-objc-header %S/Inputs/header.h | %FileCheck %s -check-prefix=CHECK-TOP
|
||||||
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE -import-objc-header %S/Inputs/header.h | %FileCheck %s -check-prefix=CHECK-TYPE
|
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE -import-objc-header %S/Inputs/header.h | %FileCheck %s -check-prefix=CHECK-TYPE
|
||||||
|
// RUN: rm -rf %t && mkdir -p %t
|
||||||
|
// RUN: %target-swift-ide-test -code-completion -pch-output-dir %t -source-filename %s -code-completion-token=TOP -import-objc-header %S/Inputs/header.h | %FileCheck %s -check-prefix=CHECK-TOP
|
||||||
|
// RUN: %target-swift-ide-test -code-completion -pch-output-dir %t -source-filename %s -code-completion-token=TYPE -import-objc-header %S/Inputs/header.h | %FileCheck %s -check-prefix=CHECK-TYPE
|
||||||
|
// RUN: stat %t/*.pch
|
||||||
|
|
||||||
// REQUIRES: objc_interop
|
// REQUIRES: objc_interop
|
||||||
|
|
||||||
|
|||||||
13
test/SourceKit/Mixed/complete_twice_bridging_header.swift
Normal file
13
test/SourceKit/Mixed/complete_twice_bridging_header.swift
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// REQUIRES: objc_interop
|
||||||
|
// RUN: rm -rf %t && mkdir -p %t
|
||||||
|
// RUN: %sourcekitd-test -req=complete -pos=8:5 %s -- %s -module-name Mixed -pch-output-dir %t -import-objc-header %S/Inputs/header.h == -req=complete -pos=8:5 %s -- %s -module-name Mixed -pch-output-dir %t -import-objc-header %S/Inputs/header.h | %FileCheck %s --check-prefix=CHECK-MEMBERS
|
||||||
|
// RUN: %sourcekitd-test -req=complete -pos=9:1 %s -- %s -module-name Mixed -pch-output-dir %t -import-objc-header %S/Inputs/header.h == -req=complete -pos=9:1 %s -- %s -module-name Mixed -pch-output-dir %t -import-objc-header %S/Inputs/header.h | %FileCheck %s --check-prefix=CHECK-GLOBALS
|
||||||
|
// RUN: stat %t/*.pch
|
||||||
|
|
||||||
|
func foo(x: BaseInHead) {
|
||||||
|
x.
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-GLOBALS: doSomethingInHead(:)
|
||||||
|
// CHECK-GLOBALS: test1(:)
|
||||||
|
// CHECK-MEMBERS: doIt(:)
|
||||||
@@ -10,6 +10,10 @@ func test(_ b : BaseInHead) {
|
|||||||
|
|
||||||
// RUN: %sourcekitd-test -req=cursor -pos=3:7 %s -- %s %mcp_opt -module-name Mixed -import-objc-header %S/Inputs/header.h | %FileCheck %s
|
// RUN: %sourcekitd-test -req=cursor -pos=3:7 %s -- %s %mcp_opt -module-name Mixed -import-objc-header %S/Inputs/header.h | %FileCheck %s
|
||||||
|
|
||||||
|
// RUN: rm -rf %t && mkdir -p %t
|
||||||
|
// RUN: %sourcekitd-test -req=cursor -pos=3:7 %s -- %s %mcp_opt -module-name Mixed -pch-output-dir %t -import-objc-header %S/Inputs/header.h | %FileCheck %s
|
||||||
|
// RUN: stat %t/*.pch
|
||||||
|
|
||||||
// CHECK: source.lang.swift.ref.function.method.instance ({{.*}}Inputs/header.h:4:9-4:23)
|
// CHECK: source.lang.swift.ref.function.method.instance ({{.*}}Inputs/header.h:4:9-4:23)
|
||||||
// CHECK: doIt(_:)
|
// CHECK: doIt(_:)
|
||||||
// CHECK: c:objc(cs)BaseInHead(im)doIt:
|
// CHECK: c:objc(cs)BaseInHead(im)doIt:
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/Mutex.h"
|
#include "llvm/Support/Mutex.h"
|
||||||
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <xpc/xpc.h>
|
#include <xpc/xpc.h>
|
||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
@@ -250,6 +251,11 @@ static void handleInterruptedConnection(xpc_object_t event, xpc_connection_t con
|
|||||||
void sourcekitd::initialize() {
|
void sourcekitd::initialize() {
|
||||||
initializeTracing();
|
initializeTracing();
|
||||||
|
|
||||||
|
llvm::InitializeAllTargets();
|
||||||
|
llvm::InitializeAllTargetMCs();
|
||||||
|
llvm::InitializeAllAsmPrinters();
|
||||||
|
llvm::InitializeAllAsmParsers();
|
||||||
|
|
||||||
assert(!GlobalConn);
|
assert(!GlobalConn);
|
||||||
GlobalConn = xpc_connection_create(SOURCEKIT_XPCSERVICE_IDENTIFIER, nullptr);
|
GlobalConn = xpc_connection_create(SOURCEKIT_XPCSERVICE_IDENTIFIER, nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
// FIXME: Portability.
|
// FIXME: Portability.
|
||||||
@@ -149,6 +150,11 @@ static void onDocumentUpdateNotification(StringRef DocumentName) {
|
|||||||
static SourceKit::Context *GlobalCtx = nullptr;
|
static SourceKit::Context *GlobalCtx = nullptr;
|
||||||
|
|
||||||
void sourcekitd::initialize() {
|
void sourcekitd::initialize() {
|
||||||
|
llvm::InitializeAllTargets();
|
||||||
|
llvm::InitializeAllTargetMCs();
|
||||||
|
llvm::InitializeAllAsmPrinters();
|
||||||
|
llvm::InitializeAllAsmParsers();
|
||||||
|
|
||||||
GlobalCtx = new SourceKit::Context(sourcekitd::getRuntimeLibPath(),
|
GlobalCtx = new SourceKit::Context(sourcekitd::getRuntimeLibPath(),
|
||||||
SourceKit::createSwiftLangSupport);
|
SourceKit::createSwiftLangSupport);
|
||||||
GlobalCtx->getNotificationCenter().addDocumentUpdateNotificationReceiver(
|
GlobalCtx->getNotificationCenter().addDocumentUpdateNotificationReceiver(
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
|
|||||||
LangOpts.Target = Invocation.getTargetTriple();
|
LangOpts.Target = Invocation.getTargetTriple();
|
||||||
ASTContext ASTCtx(LangOpts, SearchPathOpts, SrcMgr, Instance.getDiags());
|
ASTContext ASTCtx(LangOpts, SearchPathOpts, SrcMgr, Instance.getDiags());
|
||||||
ClangImporterOptions ClangImporterOpts;
|
ClangImporterOptions ClangImporterOpts;
|
||||||
ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, ClangImporterOpts),
|
ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, ClangImporterOpts, ""),
|
||||||
true);
|
true);
|
||||||
ModuleDecl *M = ModuleDecl::create(ASTCtx.getIdentifier("swiftmodule"), ASTCtx);
|
ModuleDecl *M = ModuleDecl::create(ASTCtx.getIdentifier("swiftmodule"), ASTCtx);
|
||||||
SILOptions SILOpts;
|
SILOptions SILOpts;
|
||||||
|
|||||||
@@ -243,6 +243,10 @@ SwiftVersion("swift-version", llvm::cl::desc("Swift version"));
|
|||||||
static llvm::cl::opt<std::string>
|
static llvm::cl::opt<std::string>
|
||||||
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));
|
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));
|
||||||
|
|
||||||
|
static llvm::cl::opt<std::string>
|
||||||
|
PCHOutputDir("pch-output-dir", llvm::cl::desc("place autogenerated PCH files in this directory"));
|
||||||
|
|
||||||
|
|
||||||
static llvm::cl::opt<std::string>
|
static llvm::cl::opt<std::string>
|
||||||
CompletionCachePath("completion-cache-path",
|
CompletionCachePath("completion-cache-path",
|
||||||
llvm::cl::desc("Code completion cache path"),
|
llvm::cl::desc("Code completion cache path"),
|
||||||
@@ -599,6 +603,7 @@ static int doCodeCompletion(const CompilerInvocation &InitInvok,
|
|||||||
<< " at offset " << CodeCompletionOffset << "\n";
|
<< " at offset " << CodeCompletionOffset << "\n";
|
||||||
|
|
||||||
CompilerInvocation Invocation(InitInvok);
|
CompilerInvocation Invocation(InitInvok);
|
||||||
|
|
||||||
Invocation.setCodeCompletionPoint(CleanFile.get(), CodeCompletionOffset);
|
Invocation.setCodeCompletionPoint(CleanFile.get(), CodeCompletionOffset);
|
||||||
|
|
||||||
|
|
||||||
@@ -2973,6 +2978,8 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
InitInvok.getClangImporterOptions().ModuleCachePath =
|
InitInvok.getClangImporterOptions().ModuleCachePath =
|
||||||
options::ModuleCachePath;
|
options::ModuleCachePath;
|
||||||
|
InitInvok.getClangImporterOptions().PrecompiledHeaderOutputDir =
|
||||||
|
options::PCHOutputDir;
|
||||||
InitInvok.setImportSearchPaths(options::ImportPaths);
|
InitInvok.setImportSearchPaths(options::ImportPaths);
|
||||||
std::vector<SearchPathOptions::FrameworkSearchPath> FramePaths;
|
std::vector<SearchPathOptions::FrameworkSearchPath> FramePaths;
|
||||||
for (const auto &path : options::FrameworkPaths) {
|
for (const auto &path : options::FrameworkPaths) {
|
||||||
@@ -2986,6 +2993,8 @@ int main(int argc, char *argv[]) {
|
|||||||
options::EnableSourceImport;
|
options::EnableSourceImport;
|
||||||
InitInvok.getFrontendOptions().ImplicitObjCHeaderPath =
|
InitInvok.getFrontendOptions().ImplicitObjCHeaderPath =
|
||||||
options::ImportObjCHeader;
|
options::ImportObjCHeader;
|
||||||
|
InitInvok.getClangImporterOptions().BridgingHeader =
|
||||||
|
options::ImportObjCHeader;
|
||||||
InitInvok.getLangOptions().EnableAccessControl =
|
InitInvok.getLangOptions().EnableAccessControl =
|
||||||
!options::DisableAccessControl;
|
!options::DisableAccessControl;
|
||||||
InitInvok.getLangOptions().CodeCompleteInitsInPostfixExpr |=
|
InitInvok.getLangOptions().CodeCompleteInitsInPostfixExpr |=
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "SourceKit/SwiftLang/Factory.h"
|
#include "SourceKit/SwiftLang/Factory.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
using namespace SourceKit;
|
using namespace SourceKit;
|
||||||
@@ -102,6 +103,10 @@ public:
|
|||||||
LangSupport &getLang() { return Ctx.getSwiftLangSupport(); }
|
LangSupport &getLang() { return Ctx.getSwiftLangSupport(); }
|
||||||
|
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
|
llvm::InitializeAllTargets();
|
||||||
|
llvm::InitializeAllTargetMCs();
|
||||||
|
llvm::InitializeAllAsmPrinters();
|
||||||
|
llvm::InitializeAllAsmParsers();
|
||||||
NumTasks = 0;
|
NumTasks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user