File: SpecializedEmitter.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (117 lines) | stat: -rw-r--r-- 3,748 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//===--- SpecializedEmitter.h - Special emitters for builtin ----*- 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
//
//===----------------------------------------------------------------------===//
//
// Interface to the code for specially emitting builtin functions.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_LOWERING_SPECIALIZEDEMITTER_H
#define SWIFT_LOWERING_SPECIALIZEDEMITTER_H

#include "swift/Basic/LLVM.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/Types.h"

namespace swift {
class Expr;
struct SILDeclRef;
class SILLocation;
class SILModule;
  
namespace Lowering {
class ManagedValue;
class SGFContext;
class SILGenFunction;
class SILGenModule;
class PreparedArguments;

/// Some kind of specialized emitter for a builtin function.
class SpecializedEmitter {
public:
  /// A special function for emitting a call before the arguments
  /// have already been emitted.
  using EarlyEmitter = ManagedValue (SILGenFunction &,
                                     SILLocation,
                                     SubstitutionMap,
                                     PreparedArguments &&args,
                                     SGFContext);

  /// A special function for emitting a call after the arguments
  /// have already been emitted.
  using LateEmitter = ManagedValue (SILGenFunction &,
                                    SILLocation,
                                    SubstitutionMap,
                                    ArrayRef<ManagedValue>,
                                    SGFContext);

  enum class Kind {
    /// This is a builtin function that will be specially handled
    /// downstream, but doesn't require special treatment at the
    /// SILGen level.
    NamedBuiltin,

    /// This is a builtin function that needs to be specially
    /// handled in SILGen and which needs to be given the original
    /// r-value expression.
    EarlyEmitter,

    /// This is a builtin function that needs to be specially
    /// handled in SILGen, but which can be passed normally-emitted
    /// arguments.
    LateEmitter,
  };

private:
  Kind TheKind;
  union {
    EarlyEmitter *TheEarlyEmitter;
    LateEmitter *TheLateEmitter;
    Identifier TheBuiltinName;
  };

public:
  /*implicit*/ SpecializedEmitter(Identifier builtinName)
    : TheKind(Kind::NamedBuiltin), TheBuiltinName(builtinName) {}

  /*implicit*/ SpecializedEmitter(EarlyEmitter *emitter)
    : TheKind(Kind::EarlyEmitter), TheEarlyEmitter(emitter) {}

  /*implicit*/ SpecializedEmitter(LateEmitter *emitter)
    : TheKind(Kind::LateEmitter), TheLateEmitter(emitter) {}

  /// Try to find an appropriate emitter for the given declaration.
  static std::optional<SpecializedEmitter> forDecl(SILGenModule &SGM,
                                                   SILDeclRef decl);

  bool isEarlyEmitter() const { return TheKind == Kind::EarlyEmitter; }
  EarlyEmitter *getEarlyEmitter() const {
    assert(isEarlyEmitter());
    return TheEarlyEmitter;
  }

  bool isLateEmitter() const { return TheKind == Kind::LateEmitter; }
  LateEmitter *getLateEmitter() const {
    assert(isLateEmitter());
    return TheLateEmitter;
  }

  bool isNamedBuiltin() const { return TheKind == Kind::NamedBuiltin; }
  Identifier getBuiltinName() const {
    assert(isNamedBuiltin());
    return TheBuiltinName;
  }
};

} // end namespace Lowering
} // end namespace swift

#endif