Skip to content

Commit cf893ba

Browse files
authored
[clang][bytecode][NFC] Add a FunctionKind enum (#125391)
Some function types are special to us, so add an enum and determinte the function kind once when creating the function, instead of looking at the Decl every time we need the information.
1 parent 1af627b commit cf893ba

File tree

3 files changed

+48
-44
lines changed

3 files changed

+48
-44
lines changed

clang/lib/AST/ByteCode/ByteCodeEmitter.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,9 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
135135
// Create a handle over the emitted code.
136136
Function *Func = P.getFunction(FuncDecl);
137137
if (!Func) {
138-
unsigned BuiltinID = FuncDecl->getBuiltinID();
139-
Func =
140-
P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
141-
std::move(ParamDescriptors), std::move(ParamOffsets),
142-
HasThisPointer, HasRVO, BuiltinID);
138+
Func = P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
139+
std::move(ParamDescriptors),
140+
std::move(ParamOffsets), HasThisPointer, HasRVO);
143141
}
144142

145143
assert(Func);
@@ -212,8 +210,7 @@ Function *ByteCodeEmitter::compileObjCBlock(const BlockExpr *BE) {
212210
Function *Func =
213211
P.createFunction(BE, ParamOffset, std::move(ParamTypes),
214212
std::move(ParamDescriptors), std::move(ParamOffsets),
215-
/*HasThisPointer=*/false, /*HasRVO=*/false,
216-
/*IsUnevaluatedBuiltin=*/false);
213+
/*HasThisPointer=*/false, /*HasRVO=*/false);
217214

218215
assert(Func);
219216
Func->setDefined(true);

clang/lib/AST/ByteCode/Function.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,28 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
1919
llvm::SmallVectorImpl<PrimType> &&ParamTypes,
2020
llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
2121
llvm::SmallVectorImpl<unsigned> &&ParamOffsets,
22-
bool HasThisPointer, bool HasRVO, unsigned BuiltinID)
23-
: P(P), Source(Source), ArgSize(ArgSize), ParamTypes(std::move(ParamTypes)),
24-
Params(std::move(Params)), ParamOffsets(std::move(ParamOffsets)),
25-
HasThisPointer(HasThisPointer), HasRVO(HasRVO), BuiltinID(BuiltinID) {
26-
if (const auto *F = Source.dyn_cast<const FunctionDecl *>())
22+
bool HasThisPointer, bool HasRVO)
23+
: P(P), Kind(FunctionKind::Normal), Source(Source), ArgSize(ArgSize),
24+
ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
25+
ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
26+
HasRVO(HasRVO) {
27+
if (const auto *F = dyn_cast<const FunctionDecl *>(Source)) {
2728
Variadic = F->isVariadic();
29+
BuiltinID = F->getBuiltinID();
30+
if (const auto *CD = dyn_cast<CXXConstructorDecl>(F)) {
31+
Virtual = CD->isVirtual();
32+
Kind = FunctionKind::Ctor;
33+
} else if (const auto *CD = dyn_cast<CXXDestructorDecl>(F)) {
34+
Virtual = CD->isVirtual();
35+
Kind = FunctionKind::Dtor;
36+
} else if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
37+
Virtual = MD->isVirtual();
38+
if (MD->isLambdaStaticInvoker())
39+
Kind = FunctionKind::LambdaStaticInvoker;
40+
else if (clang::isLambdaCallOperator(F))
41+
Kind = FunctionKind::LambdaCallOperator;
42+
}
43+
}
2844
}
2945

3046
Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
@@ -45,13 +61,6 @@ SourceInfo Function::getSource(CodePtr PC) const {
4561
return It->second;
4662
}
4763

48-
bool Function::isVirtual() const {
49-
if (const auto *M = dyn_cast_if_present<CXXMethodDecl>(
50-
Source.dyn_cast<const FunctionDecl *>()))
51-
return M->isVirtual();
52-
return false;
53-
}
54-
5564
/// Unevaluated builtins don't get their arguments put on the stack
5665
/// automatically. They instead operate on the AST of their Call
5766
/// Expression.

clang/lib/AST/ByteCode/Function.h

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ using FunctionDeclTy =
8080
///
8181
class Function final {
8282
public:
83+
enum class FunctionKind {
84+
Normal,
85+
Ctor,
86+
Dtor,
87+
LambdaStaticInvoker,
88+
LambdaCallOperator,
89+
};
8390
using ParamDescriptor = std::pair<PrimType, Descriptor *>;
8491

8592
/// Returns the size of the function's local stack.
@@ -141,43 +148,31 @@ class Function final {
141148
bool isConstexpr() const { return IsValid || isLambdaStaticInvoker(); }
142149

143150
/// Checks if the function is virtual.
144-
bool isVirtual() const;
151+
bool isVirtual() const { return Virtual; };
145152

146153
/// Checks if the function is a constructor.
147-
bool isConstructor() const {
148-
return isa_and_nonnull<CXXConstructorDecl>(
149-
dyn_cast<const FunctionDecl *>(Source));
150-
}
154+
bool isConstructor() const { return Kind == FunctionKind::Ctor; }
151155
/// Checks if the function is a destructor.
152-
bool isDestructor() const {
153-
return isa_and_nonnull<CXXDestructorDecl>(
154-
dyn_cast<const FunctionDecl *>(Source));
155-
}
156-
157-
/// Returns the parent record decl, if any.
158-
const CXXRecordDecl *getParentDecl() const {
159-
if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
160-
dyn_cast<const FunctionDecl *>(Source)))
161-
return MD->getParent();
162-
return nullptr;
163-
}
156+
bool isDestructor() const { return Kind == FunctionKind::Dtor; }
164157

165158
/// Returns whether this function is a lambda static invoker,
166159
/// which we generate custom byte code for.
167160
bool isLambdaStaticInvoker() const {
168-
if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
169-
dyn_cast<const FunctionDecl *>(Source)))
170-
return MD->isLambdaStaticInvoker();
171-
return false;
161+
return Kind == FunctionKind::LambdaStaticInvoker;
172162
}
173163

174164
/// Returns whether this function is the call operator
175165
/// of a lambda record decl.
176166
bool isLambdaCallOperator() const {
167+
return Kind == FunctionKind::LambdaCallOperator;
168+
}
169+
170+
/// Returns the parent record decl, if any.
171+
const CXXRecordDecl *getParentDecl() const {
177172
if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
178173
dyn_cast<const FunctionDecl *>(Source)))
179-
return clang::isLambdaCallOperator(MD);
180-
return false;
174+
return MD->getParent();
175+
return nullptr;
181176
}
182177

183178
/// Checks if the function is fully done compiling.
@@ -213,7 +208,7 @@ class Function final {
213208

214209
bool isThisPointerExplicit() const {
215210
if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
216-
Source.dyn_cast<const FunctionDecl *>()))
211+
dyn_cast<const FunctionDecl *>(Source)))
217212
return MD->isExplicitObjectMemberFunction();
218213
return false;
219214
}
@@ -232,7 +227,7 @@ class Function final {
232227
llvm::SmallVectorImpl<PrimType> &&ParamTypes,
233228
llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
234229
llvm::SmallVectorImpl<unsigned> &&ParamOffsets, bool HasThisPointer,
235-
bool HasRVO, unsigned BuiltinID);
230+
bool HasRVO);
236231

237232
/// Sets the code of a function.
238233
void setCode(unsigned NewFrameSize, std::vector<std::byte> &&NewCode,
@@ -255,6 +250,8 @@ class Function final {
255250

256251
/// Program reference.
257252
Program &P;
253+
/// Function Kind.
254+
FunctionKind Kind;
258255
/// Declaration this function was compiled from.
259256
FunctionDeclTy Source;
260257
/// Local area size: storage + metadata.
@@ -289,6 +286,7 @@ class Function final {
289286
bool HasBody = false;
290287
bool Defined = false;
291288
bool Variadic = false;
289+
bool Virtual = false;
292290
unsigned BuiltinID = 0;
293291

294292
public:

0 commit comments

Comments
 (0)