Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
213799 views
1
//==-- CIRGenFunctionInfo.h - Representation of fn argument/return types ---==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Defines CIRGenFunctionInfo and associated types used in representing the
10
// CIR source types and ABI-coerced types for function arguments and
11
// return values.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
16
#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
17
18
#include "clang/AST/CanonicalType.h"
19
#include "clang/CIR/MissingFeatures.h"
20
#include "llvm/ADT/FoldingSet.h"
21
#include "llvm/Support/TrailingObjects.h"
22
23
namespace clang::CIRGen {
24
25
/// A class for recording the number of arguments that a function signature
26
/// requires.
27
class RequiredArgs {
28
/// The number of required arguments, or ~0 if the signature does not permit
29
/// optional arguments.
30
unsigned numRequired;
31
32
public:
33
enum All_t { All };
34
35
RequiredArgs(All_t _) : numRequired(~0U) {}
36
explicit RequiredArgs(unsigned n) : numRequired(n) { assert(n != ~0U); }
37
38
unsigned getOpaqueData() const { return numRequired; }
39
40
bool allowsOptionalArgs() const { return numRequired != ~0U; }
41
42
/// Compute the arguments required by the given formal prototype, given that
43
/// there may be some additional, non-formal arguments in play.
44
///
45
/// If FD is not null, this will consider pass_object_size params in FD.
46
static RequiredArgs
47
getFromProtoWithExtraSlots(const clang::FunctionProtoType *prototype,
48
unsigned additional) {
49
if (!prototype->isVariadic())
50
return All;
51
52
if (prototype->hasExtParameterInfos())
53
llvm_unreachable("NYI");
54
55
return RequiredArgs(prototype->getNumParams() + additional);
56
}
57
58
static RequiredArgs
59
getFromProtoWithExtraSlots(clang::CanQual<clang::FunctionProtoType> prototype,
60
unsigned additional) {
61
return getFromProtoWithExtraSlots(prototype.getTypePtr(), additional);
62
}
63
64
unsigned getNumRequiredArgs() const {
65
assert(allowsOptionalArgs());
66
return numRequired;
67
}
68
};
69
70
// The TrailingObjects for this class contain the function return type in the
71
// first CanQualType slot, followed by the argument types.
72
class CIRGenFunctionInfo final
73
: public llvm::FoldingSetNode,
74
private llvm::TrailingObjects<CIRGenFunctionInfo, CanQualType> {
75
RequiredArgs required;
76
77
unsigned numArgs;
78
79
CanQualType *getArgTypes() { return getTrailingObjects(); }
80
const CanQualType *getArgTypes() const { return getTrailingObjects(); }
81
82
CIRGenFunctionInfo() : required(RequiredArgs::All) {}
83
84
public:
85
static CIRGenFunctionInfo *create(CanQualType resultType,
86
llvm::ArrayRef<CanQualType> argTypes,
87
RequiredArgs required);
88
89
void operator delete(void *p) { ::operator delete(p); }
90
91
// Friending class TrailingObjects is apparantly not good enough for MSVC, so
92
// these have to be public.
93
friend class TrailingObjects;
94
95
using const_arg_iterator = const CanQualType *;
96
using arg_iterator = CanQualType *;
97
98
// This function has to be CamelCase because llvm::FoldingSet requires so.
99
// NOLINTNEXTLINE(readability-identifier-naming)
100
static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required,
101
CanQualType resultType,
102
llvm::ArrayRef<CanQualType> argTypes) {
103
id.AddBoolean(required.getOpaqueData());
104
resultType.Profile(id);
105
for (const CanQualType &arg : argTypes)
106
arg.Profile(id);
107
}
108
109
// NOLINTNEXTLINE(readability-identifier-naming)
110
void Profile(llvm::FoldingSetNodeID &id) {
111
// If the Profile functions get out of sync, we can end up with incorrect
112
// function signatures, so we call the static Profile function here rather
113
// than duplicating the logic.
114
Profile(id, required, getReturnType(), arguments());
115
}
116
117
llvm::ArrayRef<CanQualType> arguments() const {
118
return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);
119
}
120
121
llvm::ArrayRef<CanQualType> requiredArguments() const {
122
return llvm::ArrayRef<CanQualType>(argTypesBegin(), getNumRequiredArgs());
123
}
124
125
CanQualType getReturnType() const { return getArgTypes()[0]; }
126
127
const_arg_iterator argTypesBegin() const { return getArgTypes() + 1; }
128
const_arg_iterator argTypesEnd() const { return getArgTypes() + 1 + numArgs; }
129
arg_iterator argTypesBegin() { return getArgTypes() + 1; }
130
arg_iterator argTypesEnd() { return getArgTypes() + 1 + numArgs; }
131
132
unsigned argTypeSize() const { return numArgs; }
133
134
llvm::MutableArrayRef<CanQualType> argTypes() {
135
return llvm::MutableArrayRef<CanQualType>(argTypesBegin(), numArgs);
136
}
137
llvm::ArrayRef<CanQualType> argTypes() const {
138
return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);
139
}
140
141
bool isVariadic() const { return required.allowsOptionalArgs(); }
142
RequiredArgs getRequiredArgs() const { return required; }
143
unsigned getNumRequiredArgs() const {
144
return isVariadic() ? getRequiredArgs().getNumRequiredArgs()
145
: argTypeSize();
146
}
147
};
148
149
} // namespace clang::CIRGen
150
151
#endif
152
153