Files
swift-mirror/lib/DependencyScan/DependencyScanningTool.cpp
Josh Soref 81d3ad76ac Spelling ast (#42463)
* spelling: accessor

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accommodates

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: argument

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: associated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: availability

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: available

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: belongs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: bookkeeping

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: building

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clonable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: closure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: concatenated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conformance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: context

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: correspondence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declared

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: defining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: delayed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: dependency

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deployed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: descendants

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnostic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equitable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: evaluation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: exclusivity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existential

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: explicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: expressed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: for

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: foreign

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: function

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identifier

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: implicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: information

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interchangeable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interface

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introduced

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: invalid

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: kind-in

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: least

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: library

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: location

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: namespace

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessary

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: nonexistent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: not

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: number

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: obtains

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: occurs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: opaque

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: precede

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: preceding

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: property

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: protocol

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: qualified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recursively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: references

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: relaxing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: represented

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: request

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirements

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: returned

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfied

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfy

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scanner

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: siblings

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: something

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: source

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specializations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specially

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: statement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: stripped

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: structure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transform

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transformed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transparent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: typecheck

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unknown

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unlabeled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unqualified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whether

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: with

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scanner

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 12:57:16 -07:00

208 lines
7.4 KiB
C++

//===------------ DependencyScanningTool.cpp - Swift Compiler -------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/DependencyScan/DependencyScanningTool.h"
#include "swift/DependencyScan/SerializedModuleDependencyCacheFormat.h"
#include "swift/DependencyScan/StringUtils.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/TargetInfo.h"
#include "swift/DependencyScan/DependencyScanImpl.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include <sstream>
namespace swift {
namespace dependencies {
llvm::ErrorOr<swiftscan_string_ref_t> getTargetInfo(ArrayRef<const char *> Command) {
// We must reset option occurences because we are handling an unrelated
// command-line to those possibly parsed parsed before using the same tool.
// We must do so because LLVM options parsing is done using a managed
// static `GlobalParser`.
llvm::cl::ResetAllOptionOccurrences();
// Parse arguments.
std::string CommandString;
for (const auto *c : Command) {
CommandString.append(c);
CommandString.append(" ");
}
SmallVector<const char *, 4> Args;
llvm::BumpPtrAllocator Alloc;
llvm::StringSaver Saver(Alloc);
llvm::cl::TokenizeGNUCommandLine(CommandString, Saver, Args);
SourceManager dummySM;
DiagnosticEngine DE(dummySM);
CompilerInvocation Invocation;
if (Invocation.parseArgs(Args, DE)) {
return std::make_error_code(std::errc::invalid_argument);
}
// Store the result to a string.
std::string ResultStr;
llvm::raw_string_ostream StrOS(ResultStr);
swift::targetinfo::printTargetInfo(Invocation, StrOS);
return c_string_utils::create_clone(ResultStr.c_str());
}
DependencyScanningTool::DependencyScanningTool()
: SharedCache(std::make_unique<GlobalModuleDependenciesCache>()),
VersionedPCMInstanceCacheCache(
std::make_unique<CompilerArgInstanceCacheMap>()),
PDC(), Alloc(), Saver(Alloc) {}
llvm::ErrorOr<swiftscan_dependency_graph_t>
DependencyScanningTool::getDependencies(
ArrayRef<const char *> Command,
const llvm::StringSet<> &PlaceholderModules) {
// The primary instance used to scan the query Swift source-code
auto InstanceOrErr = initScannerForAction(Command);
if (std::error_code EC = InstanceOrErr.getError())
return EC;
auto Instance = std::move(*InstanceOrErr);
// Local scan cache instance, wrapping the shared global cache.
ModuleDependenciesCache cache(*SharedCache);
// Execute the scanning action, retreiving the in-memory result
auto DependenciesOrErr = performModuleScan(*Instance.get(), cache);
if (DependenciesOrErr.getError())
return std::make_error_code(std::errc::not_supported);
auto Dependencies = std::move(*DependenciesOrErr);
return Dependencies;
}
llvm::ErrorOr<swiftscan_import_set_t>
DependencyScanningTool::getImports(ArrayRef<const char *> Command) {
// The primary instance used to scan the query Swift source-code
auto InstanceOrErr = initScannerForAction(Command);
if (std::error_code EC = InstanceOrErr.getError())
return EC;
auto Instance = std::move(*InstanceOrErr);
// Execute the scanning action, retreiving the in-memory result
auto DependenciesOrErr = performModulePrescan(*Instance.get());
if (DependenciesOrErr.getError())
return std::make_error_code(std::errc::not_supported);
auto Dependencies = std::move(*DependenciesOrErr);
return Dependencies;
}
std::vector<llvm::ErrorOr<swiftscan_dependency_graph_t>>
DependencyScanningTool::getDependencies(
ArrayRef<const char *> Command,
const std::vector<BatchScanInput> &BatchInput,
const llvm::StringSet<> &PlaceholderModules) {
// The primary instance used to scan Swift modules
auto InstanceOrErr = initScannerForAction(Command);
if (std::error_code EC = InstanceOrErr.getError())
return std::vector<llvm::ErrorOr<swiftscan_dependency_graph_t>>(
BatchInput.size(), std::make_error_code(std::errc::invalid_argument));
auto Instance = std::move(*InstanceOrErr);
// Local scan cache instance, wrapping the shared global cache.
ModuleDependenciesCache cache(*SharedCache);
auto BatchScanResults = performBatchModuleScan(
*Instance.get(), cache, VersionedPCMInstanceCacheCache.get(),
Saver, BatchInput);
return BatchScanResults;
}
void DependencyScanningTool::serializeCache(llvm::StringRef path) {
SourceManager SM;
DiagnosticEngine Diags(SM);
Diags.addConsumer(PDC);
module_dependency_cache_serialization::writeInterModuleDependenciesCache(
Diags, path, *SharedCache);
}
bool DependencyScanningTool::loadCache(llvm::StringRef path) {
SourceManager SM;
DiagnosticEngine Diags(SM);
Diags.addConsumer(PDC);
SharedCache = std::make_unique<GlobalModuleDependenciesCache>();
bool readFailed =
module_dependency_cache_serialization::readInterModuleDependenciesCache(
path, *SharedCache);
if (readFailed) {
Diags.diagnose(SourceLoc(), diag::warn_scanner_deserialize_failed, path);
}
return readFailed;
}
void DependencyScanningTool::resetCache() {
SharedCache.reset(new GlobalModuleDependenciesCache());
}
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
DependencyScanningTool::initScannerForAction(
ArrayRef<const char *> Command) {
auto instanceOrErr = initCompilerInstanceForScan(Command);
if (instanceOrErr.getError())
return instanceOrErr;
SharedCache->configureForTriple((*instanceOrErr)->getInvocation()
.getLangOptions().Target.str());
return instanceOrErr;
}
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
DependencyScanningTool::initCompilerInstanceForScan(
ArrayRef<const char *> Command) {
// State unique to an individual scan
auto Instance = std::make_unique<CompilerInstance>();
Instance->addDiagnosticConsumer(&PDC);
// Basic error checking on the arguments
if (Command.empty()) {
Instance->getDiags().diagnose(SourceLoc(), diag::error_no_frontend_args);
return std::make_error_code(std::errc::invalid_argument);
}
CompilerInvocation Invocation;
SmallString<128> WorkingDirectory;
llvm::sys::fs::current_path(WorkingDirectory);
// We must reset option occurences because we are handling an unrelated
// command-line to those possibly parsed parsed before using the same tool.
// We must do so because LLVM options parsing is done using a managed
// static `GlobalParser`.
llvm::cl::ResetAllOptionOccurrences();
// Parse arguments.
std::string CommandString;
for (const auto *c : Command) {
CommandString.append(c);
CommandString.append(" ");
}
SmallVector<const char *, 4> Args;
llvm::cl::TokenizeGNUCommandLine(CommandString, Saver, Args);
if (Invocation.parseArgs(Args, Instance->getDiags())) {
return std::make_error_code(std::errc::invalid_argument);
}
// Setup the instance
std::string InstanceSetupError;
if (Instance->setup(Invocation, InstanceSetupError)) {
return std::make_error_code(std::errc::not_supported);
}
(void)Instance->getMainModule();
return Instance;
}
} // namespace dependencies
} // namespace swift