Merge pull request #15013 from davidungar/PR-18-11-fileMap

[Batch mode] Write supplementary output file map. rdar://problem/38157859
This commit is contained in:
David Ungar
2018-03-16 17:38:53 -07:00
committed by GitHub
38 changed files with 696 additions and 358 deletions

View File

@@ -54,15 +54,8 @@ private:
bool checkUnusedSupplementaryOutputPaths() const;
/// \returns the output filenames on the command line or in the output
/// filelist, or an empty vector if there were neither -o's nor an output
/// filelist.
ArrayRef<std::string> getOutputFilenamesFromCommandLineOrFilelist();
bool checkForUnusedOutputPaths() const;
std::vector<std::string> readOutputFileList(StringRef filelistPath) const;
public:
ArgsToFrontendOptionsConverter(DiagnosticEngine &Diags,
const llvm::opt::ArgList &Args,

View File

@@ -130,10 +130,7 @@ private:
/// \Return a set of supplementary output paths for each input that might
/// produce supplementary outputs, or None to signal an error.
/// \note
/// At present, only one input can produce supplementary outputs, but
/// in the future, batch-mode will support multiple primary inputs and thus,
/// multiple sets of supplementary outputs. This function is written with that
/// future in mind.
/// Batch-mode supports multiple primary inputs.
/// \par
/// The paths are derived from arguments
/// such as -emit-module-path. These are not the final computed paths,
@@ -145,6 +142,11 @@ private:
Optional<std::vector<SupplementaryOutputPaths>>
getSupplementaryOutputPathsFromArguments() const;
/// Read a supplementary output file map file.
/// \returns `None` if it could not open the file map.
Optional<std::vector<SupplementaryOutputPaths>>
readSupplementaryOutputFileMap() const;
/// Given an ID corresponding to supplementary output argument
/// (e.g. -emit-module-path), collect all such paths, and ensure
/// there are the right number of them.

View File

@@ -0,0 +1,88 @@
//===--- OutputFileMap.h - Driver output file map ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_DRIVER_OUTPUTFILEMAP_H
#define SWIFT_DRIVER_OUTPUTFILEMAP_H
#include "swift/Basic/LLVM.h"
#include "swift/Frontend/Types.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include <memory>
#include <string>
namespace swift {
typedef llvm::DenseMap<types::ID, std::string> TypeToPathMap;
class OutputFileMap {
private:
llvm::StringMap<TypeToPathMap> InputToOutputsMap;
public:
OutputFileMap() {}
~OutputFileMap() = default;
/// Loads an OutputFileMap from the given \p Path into the receiver, if
/// possible.
static llvm::Expected<OutputFileMap> loadFromPath(StringRef Path,
StringRef workingDirectory);
static llvm::Expected<OutputFileMap>
loadFromBuffer(StringRef Data, StringRef workingDirectory);
/// Loads an OutputFileMap from the given \p Buffer, taking ownership
/// of the buffer in the process.
///
/// When non-empty, \p workingDirectory is used to resolve relative paths in
/// the output file map.
static llvm::Expected<OutputFileMap>
loadFromBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer,
StringRef workingDirectory);
/// Get the map of outputs for the given \p Input, if present in the
/// OutputFileMap. (If not present, returns nullptr.)
const TypeToPathMap *getOutputMapForInput(StringRef Input) const;
/// Get a map of outputs for the given \p Input, creating it in
/// the OutputFileMap if not already present.
TypeToPathMap &getOrCreateOutputMapForInput(StringRef Input);
/// Get the map of outputs for a single compile product.
const TypeToPathMap *getOutputMapForSingleOutput() const;
/// Get or create the map of outputs for a single compile product.
TypeToPathMap &getOrCreateOutputMapForSingleOutput();
/// Dump the OutputFileMap to the given \p os.
void dump(llvm::raw_ostream &os, bool Sort = false) const;
/// Write the OutputFilemap for the \p inputs so it can be parsed.
void write(llvm::raw_ostream &os, ArrayRef<StringRef> inputs) const;
private:
/// \brief Parses the given \p Buffer and returns either an OutputFileMap or
/// error, taking ownership of \p Buffer in the process.
static llvm::Expected<OutputFileMap>
parse(std::unique_ptr<llvm::MemoryBuffer> Buffer, StringRef workingDirectory);
};
} // end namespace swift
#endif

View File

@@ -0,0 +1,71 @@
//===--- Types.def - Driver Type info ---------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the driver type information. Users of this file
// must define the TYPE macro to make use of this information.
//
//===----------------------------------------------------------------------===//
#ifndef TYPE
#error "Define TYPE prior to including this file!"
#endif
// TYPE(NAME, ID, SUFFIX, FLAGS)
// The first value is the type name as a string; this should be something which
// could be displayed to the user, or something which the user could provide.
// The second value is the type id, which will result in a
// swift::driver::types::TY_XX enum constant.
// The third value is the suffix to use when creating temporary files
// of this type. It is also used when inferring a type from an extension.
// If multiple types specify the same extension, the first one is chosen when
// performing type inference.
// The fifth value is a string containing option flags. For now, this is unused,
// and should always be the empty string.
// Input types
TYPE("swift", Swift, "swift", "")
TYPE("sil", SIL, "sil", "")
TYPE("sib", SIB, "sib", "")
// Output types
TYPE("image", Image, "out", "")
TYPE("object", Object, "o", "")
TYPE("dSYM", dSYM, "dSYM", "")
TYPE("dependencies", Dependencies, "d", "")
TYPE("autolink", AutolinkFile, "autolink", "")
TYPE("swiftmodule", SwiftModuleFile, "swiftmodule", "")
TYPE("swiftdoc", SwiftModuleDocFile, "swiftdoc", "")
TYPE("assembly", Assembly, "s", "")
TYPE("raw-sil", RawSIL, "sil", "")
TYPE("raw-sib", RawSIB, "sib", "")
TYPE("llvm-ir", LLVM_IR, "ir", "")
TYPE("llvm-bc", LLVM_BC, "bc", "")
TYPE("diagnostics", SerializedDiagnostics, "dia", "")
TYPE("objc-header", ObjCHeader, "h", "")
TYPE("swift-dependencies", SwiftDeps, "swiftdeps", "")
TYPE("remap", Remapping, "remap", "")
TYPE("imported-modules", ImportedModules, "importedmodules", "")
TYPE("tbd", TBD, "tbd", "")
TYPE("module-trace", ModuleTrace, "trace.json", "")
TYPE("index-data", IndexData, "", "")
TYPE("opt-record", OptRecord, "opt.yaml", "")
// Misc types
TYPE("pcm", ClangModuleFile, "pcm", "")
TYPE("pch", PCH, "pch", "")
TYPE("none", Nothing, "", "")
#undef TYPE

View File

@@ -0,0 +1,93 @@
//===--- Types.h - Input & Temporary Driver Types ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_DRIVER_TYPES_H
#define SWIFT_DRIVER_TYPES_H
#include "swift/Basic/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include <functional>
namespace swift {
namespace types {
enum ID : uint8_t {
#define TYPE(NAME, ID, TEMP_SUFFIX, FLAGS) TY_##ID,
#include "swift/Frontend/Types.def"
#undef TYPE
TY_INVALID
};
/// Return the name of the type for \p Id.
StringRef getTypeName(ID Id);
/// Return the suffix to use when creating a temp file of this type,
/// or null if unspecified.
StringRef getTypeTempSuffix(ID Id);
/// Lookup the type to use for the file extension \p Ext.
/// If the extension is empty or is otherwise not recognized, return
/// the invalid type \c TY_INVALID.
ID lookupTypeForExtension(StringRef Ext);
/// Lookup the type to use for the name \p Name.
ID lookupTypeForName(StringRef Name);
/// Returns true if the type represents textual data.
bool isTextual(ID Id);
/// Returns true if the type is produced in the compiler after the LLVM
/// passes.
///
/// For those types the compiler produces multiple output files in multi-
/// threaded compilation.
bool isAfterLLVM(ID Id);
/// Returns true if the type is a file that contributes to the Swift module
/// being compiled.
///
/// These need to be passed to the Swift frontend
bool isPartOfSwiftCompilation(ID Id);
template <typename Fn>
void forAllTypes(const Fn &fn);
} // end namespace types
} // end namespace swift
namespace llvm {
template<>
struct DenseMapInfo<swift::types::ID> {
using ID = swift::types::ID;
static inline ID getEmptyKey() {
return ID::TY_INVALID;
}
static inline ID getTombstoneKey() {
return static_cast<ID>(ID::TY_INVALID + 1);
}
static unsigned getHashValue(ID Val) {
return (unsigned)Val * 37U;
}
static bool isEqual(ID LHS, ID RHS) {
return LHS == RHS;
}
};
}
template <typename Fn>
void swift::types::forAllTypes(const Fn &fn) {
static_assert(std::is_constructible<std::function<void(types::ID)>,Fn>::value,
"must have the signature 'void(types::ID)'");
for (uint8_t i = 0; i < static_cast<uint8_t>(TY_INVALID); ++i)
fn(static_cast<ID>(i));
}
#endif