1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "CGCXXABI.h" |
15 | #include "CGCleanup.h" |
16 | |
17 | using namespace clang; |
18 | using namespace CodeGen; |
19 | |
20 | CGCXXABI::~CGCXXABI() { } |
21 | |
22 | void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) { |
23 | DiagnosticsEngine &Diags = CGF.CGM.getDiags(); |
24 | unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, |
25 | "cannot yet compile %0 in this ABI"); |
26 | Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()), |
27 | DiagID) |
28 | << S; |
29 | } |
30 | |
31 | bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const { |
32 | |
33 | |
34 | return RD->canPassInRegisters(); |
35 | } |
36 | |
37 | llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) { |
38 | return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T)); |
39 | } |
40 | |
41 | llvm::Type * |
42 | CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { |
43 | return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); |
44 | } |
45 | |
46 | CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( |
47 | CodeGenFunction &CGF, const Expr *E, Address This, |
48 | llvm::Value *&ThisPtrForCall, |
49 | llvm::Value *MemPtr, const MemberPointerType *MPT) { |
50 | ErrorUnsupportedABI(CGF, "calls through member pointers"); |
51 | |
52 | ThisPtrForCall = This.getPointer(); |
53 | const FunctionProtoType *FPT = |
54 | MPT->getPointeeType()->getAs<FunctionProtoType>(); |
55 | const CXXRecordDecl *RD = |
56 | cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); |
57 | llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType( |
58 | CGM.getTypes().arrangeCXXMethodType(RD, FPT, )); |
59 | llvm::Constant *FnPtr = llvm::Constant::getNullValue(FTy->getPointerTo()); |
60 | return CGCallee::forDirect(FnPtr, FPT); |
61 | } |
62 | |
63 | llvm::Value * |
64 | CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, |
65 | Address Base, llvm::Value *MemPtr, |
66 | const MemberPointerType *MPT) { |
67 | ErrorUnsupportedABI(CGF, "loads of member pointers"); |
68 | llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType()) |
69 | ->getPointerTo(Base.getAddressSpace()); |
70 | return llvm::Constant::getNullValue(Ty); |
71 | } |
72 | |
73 | llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, |
74 | const CastExpr *E, |
75 | llvm::Value *Src) { |
76 | ErrorUnsupportedABI(CGF, "member function pointer conversions"); |
77 | return GetBogusMemberPointer(E->getType()); |
78 | } |
79 | |
80 | llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E, |
81 | llvm::Constant *Src) { |
82 | return GetBogusMemberPointer(E->getType()); |
83 | } |
84 | |
85 | llvm::Value * |
86 | CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, |
87 | llvm::Value *L, |
88 | llvm::Value *R, |
89 | const MemberPointerType *MPT, |
90 | bool Inequality) { |
91 | ErrorUnsupportedABI(CGF, "member function pointer comparison"); |
92 | return CGF.Builder.getFalse(); |
93 | } |
94 | |
95 | llvm::Value * |
96 | CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, |
97 | llvm::Value *MemPtr, |
98 | const MemberPointerType *MPT) { |
99 | ErrorUnsupportedABI(CGF, "member function pointer null testing"); |
100 | return CGF.Builder.getFalse(); |
101 | } |
102 | |
103 | llvm::Constant * |
104 | CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { |
105 | return GetBogusMemberPointer(QualType(MPT, 0)); |
106 | } |
107 | |
108 | llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { |
109 | return GetBogusMemberPointer(CGM.getContext().getMemberPointerType( |
110 | MD->getType(), MD->getParent()->getTypeForDecl())); |
111 | } |
112 | |
113 | llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, |
114 | CharUnits offset) { |
115 | return GetBogusMemberPointer(QualType(MPT, 0)); |
116 | } |
117 | |
118 | llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) { |
119 | return GetBogusMemberPointer(MPT); |
120 | } |
121 | |
122 | bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) { |
123 | |
124 | return true; |
125 | } |
126 | |
127 | void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) { |
128 | const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); |
129 | |
130 | |
131 | |
132 | auto *ThisDecl = ImplicitParamDecl::Create( |
133 | CGM.getContext(), nullptr, MD->getLocation(), |
134 | &CGM.getContext().Idents.get("this"), MD->getThisType(), |
135 | ImplicitParamDecl::CXXThis); |
136 | params.push_back(ThisDecl); |
137 | CGF.CXXABIThisDecl = ThisDecl; |
138 | |
139 | |
140 | |
141 | auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent()); |
142 | if (MD->getParent()->getNumVBases() == 0 || |
143 | MD->getParent()->hasAttr<FinalAttr>() || |
144 | !isThisCompleteObject(CGF.CurGD)) { |
145 | CGF.CXXABIThisAlignment = Layout.getAlignment(); |
146 | } else { |
147 | CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment(); |
148 | } |
149 | } |
150 | |
151 | llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) { |
152 | return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)), |
153 | "this"); |
154 | } |
155 | |
156 | void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) { |
157 | |
158 | (0) . __assert_fail ("getThisDecl(CGF) && \"no 'this' variable for function\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCXXABI.cpp", 158, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getThisDecl(CGF) && "no 'this' variable for function"); |
159 | CGF.CXXABIThisValue = ThisPtr; |
160 | } |
161 | |
162 | void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, |
163 | RValue RV, QualType ResultType) { |
164 | CGF.EmitReturnOfRValue(RV, ResultType); |
165 | } |
166 | |
167 | CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) { |
168 | if (!requiresArrayCookie(expr)) |
169 | return CharUnits::Zero(); |
170 | return getArrayCookieSizeImpl(expr->getAllocatedType()); |
171 | } |
172 | |
173 | CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) { |
174 | |
175 | return CharUnits::Zero(); |
176 | } |
177 | |
178 | Address CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, |
179 | Address NewPtr, |
180 | llvm::Value *NumElements, |
181 | const CXXNewExpr *expr, |
182 | QualType ElementType) { |
183 | |
184 | ErrorUnsupportedABI(CGF, "array cookie initialization"); |
185 | return Address::invalid(); |
186 | } |
187 | |
188 | bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, |
189 | QualType elementType) { |
190 | |
191 | |
192 | if (expr->doesUsualArrayDeleteWantSize()) |
193 | return true; |
194 | |
195 | return elementType.isDestructedType(); |
196 | } |
197 | |
198 | bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { |
199 | |
200 | |
201 | if (expr->doesUsualArrayDeleteWantSize()) |
202 | return true; |
203 | |
204 | return expr->getAllocatedType().isDestructedType(); |
205 | } |
206 | |
207 | void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, |
208 | const CXXDeleteExpr *expr, QualType eltTy, |
209 | llvm::Value *&numElements, |
210 | llvm::Value *&allocPtr, CharUnits &cookieSize) { |
211 | |
212 | ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty); |
213 | |
214 | |
215 | if (!requiresArrayCookie(expr, eltTy)) { |
216 | allocPtr = ptr.getPointer(); |
217 | numElements = nullptr; |
218 | cookieSize = CharUnits::Zero(); |
219 | return; |
220 | } |
221 | |
222 | cookieSize = getArrayCookieSizeImpl(eltTy); |
223 | Address allocAddr = |
224 | CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); |
225 | allocPtr = allocAddr.getPointer(); |
226 | numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); |
227 | } |
228 | |
229 | llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, |
230 | Address ptr, |
231 | CharUnits cookieSize) { |
232 | ErrorUnsupportedABI(CGF, "reading a new[] cookie"); |
233 | return llvm::ConstantInt::get(CGF.SizeTy, 0); |
234 | } |
235 | |
236 | |
237 | |
238 | |
239 | llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) { |
240 | getCastKind() == CK_DerivedToBaseMemberPointer || E->getCastKind() == CK_BaseToDerivedMemberPointer", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCXXABI.cpp", 241, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || |
241 | getCastKind() == CK_DerivedToBaseMemberPointer || E->getCastKind() == CK_BaseToDerivedMemberPointer", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCXXABI.cpp", 241, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> E->getCastKind() == CK_BaseToDerivedMemberPointer); |
242 | |
243 | QualType derivedType; |
244 | if (E->getCastKind() == CK_DerivedToBaseMemberPointer) |
245 | derivedType = E->getSubExpr()->getType(); |
246 | else |
247 | derivedType = E->getType(); |
248 | |
249 | const CXXRecordDecl *derivedClass = |
250 | derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl(); |
251 | |
252 | return CGM.GetNonVirtualBaseClassOffset(derivedClass, |
253 | E->path_begin(), |
254 | E->path_end()); |
255 | } |
256 | |
257 | CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) { |
258 | |
259 | |
260 | const ValueDecl *MPD = MP.getMemberPointerDecl(); |
261 | CharUnits ThisAdjustment = CharUnits::Zero(); |
262 | ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath(); |
263 | bool DerivedMember = MP.isMemberPointerToDerivedMember(); |
264 | const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext()); |
265 | for (unsigned I = 0, N = Path.size(); I != N; ++I) { |
266 | const CXXRecordDecl *Base = RD; |
267 | const CXXRecordDecl *Derived = Path[I]; |
268 | if (DerivedMember) |
269 | std::swap(Base, Derived); |
270 | ThisAdjustment += |
271 | getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base); |
272 | RD = Path[I]; |
273 | } |
274 | if (DerivedMember) |
275 | ThisAdjustment = -ThisAdjustment; |
276 | return ThisAdjustment; |
277 | } |
278 | |
279 | llvm::BasicBlock * |
280 | CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, |
281 | const CXXRecordDecl *RD) { |
282 | if (CGM.getTarget().getCXXABI().hasConstructorVariants()) |
283 | llvm_unreachable("shouldn't be called in this ABI"); |
284 | |
285 | ErrorUnsupportedABI(CGF, "complete object detection in ctor"); |
286 | return nullptr; |
287 | } |
288 | |
289 | void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV, |
290 | const CXXDestructorDecl *Dtor, |
291 | CXXDtorType DT) const { |
292 | |
293 | CGM.setDLLImportDLLExport(GV, Dtor); |
294 | } |
295 | |
296 | llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage( |
297 | GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const { |
298 | |
299 | return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage, |
300 | ); |
301 | } |
302 | |
303 | bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) { |
304 | return false; |
305 | } |
306 | |
307 | llvm::CallInst * |
308 | CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF, |
309 | llvm::Value *Exn) { |
310 | |
311 | return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn()); |
312 | } |
313 | |
314 | CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() { |
315 | return CatchTypeInfo{nullptr, 0}; |
316 | } |
317 | |
318 | std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) { |
319 | return std::vector<CharUnits>(); |
320 | } |
321 | |