blob: 340fa6802c67a4edd86f96fc4f48770bb7782f57 [file] [log] [blame]
//===--- SILGenRequests.h - SILGen Requests ---------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 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
//
//===----------------------------------------------------------------------===//
//
// This file defines SILGen requests.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILGEN_REQUESTS_H
#define SWIFT_SILGEN_REQUESTS_H
#include "swift/AST/ASTTypeIDs.h"
#include "swift/AST/EvaluatorDependencies.h"
#include "swift/AST/SimpleRequest.h"
#include "swift/SIL/SILDeclRef.h"
namespace swift {
class FileUnit;
class LangOptions;
class ModuleDecl;
class SILModule;
class SILOptions;
class SourceFile;
namespace Lowering {
class TypeConverter;
}
/// Report that a request of the given kind is being evaluated, so it
/// can be recorded by the stats reporter.
template<typename Request>
void reportEvaluatedRequest(UnifiedStatsReporter &stats,
const Request &request);
using SILRefsToEmit = llvm::SmallVector<SILDeclRef, 1>;
/// Describes a file or module to be lowered to SIL.
struct ASTLoweringDescriptor {
llvm::PointerUnion<FileUnit *, ModuleDecl *> context;
Lowering::TypeConverter &conv;
const SILOptions &opts;
/// A specific set of SILDeclRefs to emit. If set, only these refs will be
/// emitted. Otherwise the entire \c context will be emitted.
Optional<SILRefsToEmit> refsToEmit;
friend llvm::hash_code hash_value(const ASTLoweringDescriptor &owner) {
return llvm::hash_combine(owner.context, (void *)&owner.conv,
(void *)&owner.opts,
owner.refsToEmit);
}
friend bool operator==(const ASTLoweringDescriptor &lhs,
const ASTLoweringDescriptor &rhs) {
return lhs.context == rhs.context &&
&lhs.conv == &rhs.conv &&
&lhs.opts == &rhs.opts &&
lhs.refsToEmit == rhs.refsToEmit;
}
friend bool operator!=(const ASTLoweringDescriptor &lhs,
const ASTLoweringDescriptor &rhs) {
return !(lhs == rhs);
}
public:
static ASTLoweringDescriptor
forFile(FileUnit &sf, Lowering::TypeConverter &conv, const SILOptions &opts,
Optional<SILRefsToEmit> refsToEmit = None) {
return ASTLoweringDescriptor{&sf, conv, opts, refsToEmit};
}
static ASTLoweringDescriptor
forWholeModule(ModuleDecl *mod, Lowering::TypeConverter &conv,
const SILOptions &opts,
Optional<SILRefsToEmit> refsToEmit = None) {
return ASTLoweringDescriptor{mod, conv, opts, refsToEmit};
}
/// Retrieves the files to generate SIL for. If the descriptor is configured
/// only to emit a specific set of SILDeclRefs, this will be empty.
ArrayRef<FileUnit *> getFilesToEmit() const;
/// If the module or file contains SIL that needs parsing, returns the file
/// to be parsed, or \c nullptr if parsing isn't required.
SourceFile *getSourceFileToParse() const;
};
void simple_display(llvm::raw_ostream &out, const ASTLoweringDescriptor &d);
SourceLoc extractNearestSourceLoc(const ASTLoweringDescriptor &desc);
/// Lowers a file or module to SIL. In most cases this involves transforming
/// a file's AST into SIL, through SILGen. However it can also handle files
/// containing SIL in textual or binary form, which will be parsed or
/// deserialized as needed.
class ASTLoweringRequest
: public SimpleRequest<
ASTLoweringRequest, std::unique_ptr<SILModule>(ASTLoweringDescriptor),
RequestFlags::Uncached | RequestFlags::DependencySource> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
std::unique_ptr<SILModule> evaluate(Evaluator &evaluator,
ASTLoweringDescriptor desc) const;
public:
// Incremental dependencies.
evaluator::DependencySource
readDependencySource(const evaluator::DependencyRecorder &) const;
};
/// Parses a .sil file into a SILModule.
class ParseSILModuleRequest
: public SimpleRequest<ParseSILModuleRequest,
std::unique_ptr<SILModule>(ASTLoweringDescriptor),
RequestFlags::Uncached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
std::unique_ptr<SILModule> evaluate(Evaluator &evaluator,
ASTLoweringDescriptor desc) const;
};
/// The zone number for SILGen.
#define SWIFT_TYPEID_ZONE SILGen
#define SWIFT_TYPEID_HEADER "swift/AST/SILGenTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
#undef SWIFT_TYPEID_ZONE
#undef SWIFT_TYPEID_HEADER
// Set up reporting of evaluated requests.
#define SWIFT_REQUEST(Zone, RequestType, Sig, Caching, LocOptions) \
template<> \
inline void reportEvaluatedRequest(UnifiedStatsReporter &stats, \
const RequestType &request) { \
++stats.getFrontendCounters().RequestType; \
}
#include "swift/AST/SILGenTypeIDZone.def"
#undef SWIFT_REQUEST
} // end namespace swift
#endif // SWIFT_SILGEN_REQUESTS_H