@@ -25,20 +25,68 @@ struct CIRGenFunctionInfoArgInfo {
2525 CanQualType type;
2626};
2727
28+ // / A class for recording the number of arguments that a function signature
29+ // / requires.
30+ class RequiredArgs {
31+ // / The number of required arguments, or ~0 if the signature does not permit
32+ // / optional arguments.
33+ unsigned numRequired;
34+
35+ public:
36+ enum All_t { All };
37+
38+ RequiredArgs (All_t _) : numRequired(~0U ) {}
39+ explicit RequiredArgs (unsigned n) : numRequired(n) { assert (n != ~0U ); }
40+
41+ unsigned getOpaqueData () const { return numRequired; }
42+
43+ bool allowsOptionalArgs () const { return numRequired != ~0U ; }
44+
45+ // / Compute the arguments required by the given formal prototype, given that
46+ // / there may be some additional, non-formal arguments in play.
47+ // /
48+ // / If FD is not null, this will consider pass_object_size params in FD.
49+ static RequiredArgs
50+ forPrototypePlus (const clang::FunctionProtoType *prototype) {
51+ if (!prototype->isVariadic ())
52+ return All;
53+
54+ if (prototype->hasExtParameterInfos ())
55+ llvm_unreachable (" NYI" );
56+
57+ return RequiredArgs (prototype->getNumParams ());
58+ }
59+
60+ static RequiredArgs
61+ forPrototypePlus (clang::CanQual<clang::FunctionProtoType> prototype) {
62+ return forPrototypePlus (prototype.getTypePtr ());
63+ }
64+
65+ unsigned getNumRequiredArgs () const {
66+ assert (allowsOptionalArgs ());
67+ return numRequired;
68+ }
69+ };
70+
2871class CIRGenFunctionInfo final
2972 : public llvm::FoldingSetNode,
3073 private llvm::TrailingObjects<CIRGenFunctionInfo,
3174 CIRGenFunctionInfoArgInfo> {
3275 using ArgInfo = CIRGenFunctionInfoArgInfo;
3376
77+ RequiredArgs required;
78+
3479 unsigned numArgs;
3580
3681 ArgInfo *getArgsBuffer () { return getTrailingObjects<ArgInfo>(); }
3782 const ArgInfo *getArgsBuffer () const { return getTrailingObjects<ArgInfo>(); }
3883
84+ CIRGenFunctionInfo () : required(RequiredArgs::All) {}
85+
3986public:
4087 static CIRGenFunctionInfo *create (CanQualType resultType,
41- llvm::ArrayRef<CanQualType> argTypes);
88+ llvm::ArrayRef<CanQualType> argTypes,
89+ RequiredArgs required);
4290
4391 void operator delete (void *p) { ::operator delete (p); }
4492
@@ -51,30 +99,45 @@ class CIRGenFunctionInfo final
5199
52100 // This function has to be CamelCase because llvm::FoldingSet requires so.
53101 // NOLINTNEXTLINE(readability-identifier-naming)
54- static void Profile (llvm::FoldingSetNodeID &id, CanQualType resultType,
55- llvm::ArrayRef<clang::CanQualType> argTypes) {
102+ static void Profile (llvm::FoldingSetNodeID &id, RequiredArgs required,
103+ CanQualType resultType,
104+ llvm::ArrayRef<CanQualType> argTypes) {
105+ id.AddBoolean (required.getOpaqueData ());
56106 resultType.Profile (id);
57- for (auto i : argTypes)
58- i .Profile (id);
107+ for (const CanQualType &arg : argTypes)
108+ arg .Profile (id);
59109 }
60110
61- void Profile (llvm::FoldingSetNodeID &id) { getReturnType (). Profile (id); }
62-
63- llvm::MutableArrayRef<ArgInfo> arguments () {
64- return llvm::MutableArrayRef<ArgInfo>( arg_begin (), numArgs );
111+ // NOLINTNEXTLINE(readability-identifier-naming)
112+ void Profile (llvm::FoldingSetNodeID &id) {
113+ id. AddBoolean (required. getOpaqueData ());
114+ getReturnType (). Profile (id );
65115 }
66- llvm::ArrayRef<ArgInfo> arguments () const {
67- return llvm::ArrayRef<ArgInfo>(arg_begin (), numArgs);
116+
117+ CanQualType getReturnType () const { return getArgsBuffer ()[0 ].type ; }
118+
119+ const_arg_iterator argInfoBegin () const { return getArgsBuffer () + 1 ; }
120+ const_arg_iterator argInfoEnd () const {
121+ return getArgsBuffer () + 1 + numArgs;
68122 }
123+ arg_iterator argInfoBegin () { return getArgsBuffer () + 1 ; }
124+ arg_iterator argInfoEnd () { return getArgsBuffer () + 1 + numArgs; }
69125
70- const_arg_iterator arg_begin () const { return getArgsBuffer () + 1 ; }
71- const_arg_iterator arg_end () const { return getArgsBuffer () + 1 + numArgs; }
72- arg_iterator arg_begin () { return getArgsBuffer () + 1 ; }
73- arg_iterator arg_end () { return getArgsBuffer () + 1 + numArgs; }
126+ unsigned argInfoSize () const { return numArgs; }
74127
75- unsigned arg_size () const { return numArgs; }
128+ llvm::MutableArrayRef<ArgInfo> argInfos () {
129+ return llvm::MutableArrayRef<ArgInfo>(argInfoBegin (), numArgs);
130+ }
131+ llvm::ArrayRef<ArgInfo> argInfos () const {
132+ return llvm::ArrayRef<ArgInfo>(argInfoBegin (), numArgs);
133+ }
76134
77- CanQualType getReturnType () const { return getArgsBuffer ()[0 ].type ; }
135+ bool isVariadic () const { return required.allowsOptionalArgs (); }
136+ RequiredArgs getRequiredArgs () const { return required; }
137+ unsigned getNumRequiredArgs () const {
138+ return isVariadic () ? getRequiredArgs ().getNumRequiredArgs ()
139+ : argInfoSize ();
140+ }
78141};
79142
80143} // namespace clang::CIRGen
0 commit comments