Coverage Report

Created: 2018-12-11 17:59

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/CodeGen/SwiftCallingConv.h
Line
Count
Source
1
//==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// Defines constants and types related to Swift ABI lowering.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
15
#define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
16
17
#include "clang/AST/CanonicalType.h"
18
#include "clang/AST/CharUnits.h"
19
#include "clang/AST/Type.h"
20
#include "llvm/Support/TrailingObjects.h"
21
#include <cassert>
22
23
namespace llvm {
24
  class IntegerType;
25
  class Type;
26
  class StructType;
27
  class VectorType;
28
}
29
30
namespace clang {
31
class Decl;
32
class FieldDecl;
33
class ASTRecordLayout;
34
35
namespace CodeGen {
36
class ABIArgInfo;
37
class CodeGenModule;
38
class CGFunctionInfo;
39
40
namespace swiftcall {
41
42
class SwiftAggLowering {
43
  CodeGenModule &CGM;
44
45
  struct StorageEntry {
46
    CharUnits Begin;
47
    CharUnits End;
48
    llvm::Type *Type;
49
50
24
    CharUnits getWidth() const {
51
24
      return End - Begin;
52
24
    }
53
  };
54
  SmallVector<StorageEntry, 4> Entries;
55
  bool Finished = false;
56
57
public:
58
1.06k
  SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
59
60
16
  void addOpaqueData(CharUnits begin, CharUnits end) {
61
16
    addEntry(nullptr, begin, end);
62
16
  }
63
64
  void addTypedData(QualType type, CharUnits begin);
65
  void addTypedData(const RecordDecl *record, CharUnits begin);
66
  void addTypedData(const RecordDecl *record, CharUnits begin,
67
                    const ASTRecordLayout &layout);
68
  void addTypedData(llvm::Type *type, CharUnits begin);
69
  void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
70
71
  void finish();
72
73
  /// Does this lowering require passing any data?
74
1.06k
  bool empty() const {
75
1.06k
    assert(Finished && "didn't finish lowering before calling empty()");
76
1.06k
    return Entries.empty();
77
1.06k
  }
78
79
  /// According to the target Swift ABI, should a value with this lowering
80
  /// be passed indirectly?
81
  ///
82
  /// Note that this decision is based purely on the data layout of the
83
  /// value and does not consider whether the type is address-only,
84
  /// must be passed indirectly to match a function abstraction pattern, or
85
  /// anything else that is expected to be handled by high-level lowering.
86
  ///
87
  /// \param asReturnValue - if true, answer whether it should be passed
88
  ///   indirectly as a return value; if false, answer whether it should be
89
  ///   passed indirectly as an argument
90
  bool shouldPassIndirectly(bool asReturnValue) const;
91
92
  using EnumerationCallback =
93
    llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
94
95
  /// Enumerate the expanded components of this type.
96
  ///
97
  /// The component types will always be legal vector, floating-point,
98
  /// integer, or pointer types.
99
  void enumerateComponents(EnumerationCallback callback) const;
100
101
  /// Return the types for a coerce-and-expand operation.
102
  ///
103
  /// The first type matches the memory layout of the data that's been
104
  /// added to this structure, including explicit [N x i8] arrays for any
105
  /// internal padding.
106
  ///
107
  /// The second type removes any internal padding members and, if only
108
  /// one element remains, is simply that element type.
109
  std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
110
111
private:
112
  void addBitFieldData(const FieldDecl *field, CharUnits begin,
113
                       uint64_t bitOffset);
114
  void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
115
  void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
116
  void splitVectorEntry(unsigned index);
117
  static bool shouldMergeEntries(const StorageEntry &first,
118
                                 const StorageEntry &second,
119
                                 CharUnits chunkSize);
120
};
121
122
/// Should an aggregate which expands to the given type sequence
123
/// be passed/returned indirectly under swiftcall?
124
bool shouldPassIndirectly(CodeGenModule &CGM,
125
                          ArrayRef<llvm::Type*> types,
126
                          bool asReturnValue);
127
128
/// Return the maximum voluntary integer size for the current target.
129
CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
130
131
/// Return the Swift CC's notion of the natural alignment of a type.
132
CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
133
134
/// Is the given integer type "legal" for Swift's perspective on the
135
/// current platform?
136
bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
137
138
/// Is the given vector type "legal" for Swift's perspective on the
139
/// current platform?
140
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
141
                       llvm::VectorType *vectorTy);
142
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
143
                       llvm::Type *eltTy, unsigned numElts);
144
145
/// Minimally split a legal vector type.
146
std::pair<llvm::Type*, unsigned>
147
splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
148
                     llvm::VectorType *vectorTy);
149
150
/// Turn a vector type in a sequence of legal component vector types.
151
///
152
/// The caller may assume that the sum of the data sizes of the resulting
153
/// types will equal the data size of the vector type.
154
void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
155
                        llvm::VectorType *vectorTy,
156
                        llvm::SmallVectorImpl<llvm::Type*> &types);
157
158
/// Is the given record type required to be passed and returned indirectly
159
/// because of language restrictions?
160
///
161
/// This considers *only* mandatory indirectness due to language restrictions,
162
/// such as C++'s non-trivially-copyable types and Objective-C's __weak
163
/// references.  A record for which this returns true may still be passed
164
/// indirectly for other reasons, such as being too large to fit in a
165
/// reasonable number of registers.
166
bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
167
168
/// Classify the rules for how to return a particular type.
169
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
170
171
/// Classify the rules for how to pass a particular type.
172
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
173
174
/// Compute the ABI information of a swiftcall function.  This is a
175
/// private interface for Clang.
176
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
177
178
/// Is swifterror lowered to a register by the target ABI?
179
bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
180
181
} // end namespace swiftcall
182
} // end namespace CodeGen
183
} // end namespace clang
184
185
#endif