clang 24.0.0git
CodeGenUtils.cpp
Go to the documentation of this file.
1//==--- CodeGenUtils.cpp - Shared Classic CodeGen/CIR CodeGen Utils--C++ -*-==//
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
11
12namespace clang::CodeGenUtils {
13static bool
15 const CXXRecordDecl *BaseClassDecl,
16 const CXXRecordDecl *MostDerivedClassDecl) {
17 // If the destructor is trivial we don't have to check anything else.
18 if (BaseClassDecl->hasTrivialDestructor())
19 return true;
20
21 if (!BaseClassDecl->getDestructor()->hasTrivialBody())
22 return false;
23
24 // Check fields.
25 for (const auto *Field : BaseClassDecl->fields())
26 if (!fieldHasTrivialDestructorBody(Context, Field))
27 return false;
28
29 // Check non-virtual bases.
30 for (const auto &I : BaseClassDecl->bases()) {
31 if (I.isVirtual())
32 continue;
33
34 const auto *NonVirtualBase = I.getType()->castAsCXXRecordDecl();
36 MostDerivedClassDecl))
37 return false;
38 }
39
40 if (BaseClassDecl == MostDerivedClassDecl) {
41 // Check virtual bases.
42 for (const auto &I : BaseClassDecl->vbases()) {
43 const auto *VirtualBase = I.getType()->castAsCXXRecordDecl();
44 if (!hasTrivialDestructorBody(Context, VirtualBase, MostDerivedClassDecl))
45 return false;
46 }
47 }
48
49 return true;
50}
51
53 const FieldDecl *Field) {
54 QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
55
56 auto *FieldClassDecl = FieldBaseElementType->getAsCXXRecordDecl();
57 if (!FieldClassDecl)
58 return true;
59
60 // The destructor for an implicit anonymous union member is never invoked.
61 if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
62 return true;
63
64 return hasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
65}
66
67/// Check whether we need to initialize any vtable pointers before calling this
68/// destructor.
70 const CXXDestructorDecl *Dtor) {
71 const CXXRecordDecl *ClassDecl = Dtor->getParent();
72 if (!ClassDecl->isDynamicClass())
73 return true;
74
75 // For a final class, the vtable pointer is known to already point to the
76 // class's vtable.
77 if (ClassDecl->isEffectivelyFinal())
78 return true;
79
80 if (!Dtor->hasTrivialBody())
81 return false;
82
83 // Check the fields.
84 for (const auto *Field : ClassDecl->fields())
85 if (!fieldHasTrivialDestructorBody(Ctx, Field))
86 return false;
87
88 return true;
89}
90bool hasUnwindExceptions(const LangOptions &LangOpts) {
91 // If exceptions are completely disabled, obviously this is false.
92 if (!LangOpts.Exceptions)
93 return false;
94
95 // If C++ exceptions are enabled, this is true.
96 if (LangOpts.CXXExceptions)
97 return true;
98
99 // If ObjC exceptions are enabled, this depends on the ABI.
100 if (LangOpts.ObjCExceptions) {
101 return LangOpts.ObjCRuntime.hasUnwindExceptions();
102 }
103
104 return true;
105}
106
108 return TargetInfo.getABI().starts_with("aapcs");
109}
111 const Type *BaseType = BaseInit->getBaseClass();
112 return BaseType->castAsCXXRecordDecl()->isDynamicClass();
113}
114
115} // namespace clang::CodeGenUtils
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
Represents a C++ base or member initializer.
Definition DeclCXX.h:2406
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
Definition DeclCXX.cpp:2946
Represents a C++ destructor within a class.
Definition DeclCXX.h:2906
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition DeclCXX.cpp:2341
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1381
base_class_range bases()
Definition DeclCXX.h:608
base_class_range vbases()
Definition DeclCXX.h:625
bool isDynamicClass() const
Definition DeclCXX.h:574
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp:2129
Represents a member of a struct/union/class.
Definition Decl.h:3295
bool hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen.
Definition Decl.cpp:3199
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
A (possibly-)qualified type.
Definition TypeBase.h:938
field_range fields() const
Definition Decl.h:4663
Exposes information about the current target.
Definition TargetInfo.h:226
virtual StringRef getABI() const
Get the ABI currently in use.
The base class of the type hierarchy.
Definition TypeBase.h:1879
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
Defines the clang::TargetInfo interface.
static bool hasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit)
bool canSkipVTablePointerInitialization(ASTContext &Ctx, const CXXDestructorDecl *Dtor)
Check whether we need to initialize any vtable pointers before calling this destructor.
bool fieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
Check whether destructing Field has no observable behaviors, and thus can be skipped when creating a ...
bool hasUnwindExceptions(const LangOptions &LangOpts)
Determines whether the language options require us to model unwind exceptions.