Bug Summary

File:clang/include/clang/CodeGen/CGFunctionInfo.h
Warning:line 429, column 10
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name CGVTables.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/build-llvm/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include -I /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/build-llvm/tools/clang/lib/CodeGen -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-01-11-115256-23437-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp

/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp

1//===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
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// This contains code dealing with C++ code generation of virtual tables.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGCXXABI.h"
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
16#include "clang/AST/Attr.h"
17#include "clang/AST/CXXInheritance.h"
18#include "clang/AST/RecordLayout.h"
19#include "clang/Basic/CodeGenOptions.h"
20#include "clang/CodeGen/CGFunctionInfo.h"
21#include "clang/CodeGen/ConstantInitBuilder.h"
22#include "llvm/IR/IntrinsicInst.h"
23#include "llvm/Support/Format.h"
24#include "llvm/Transforms/Utils/Cloning.h"
25#include <algorithm>
26#include <cstdio>
27
28using namespace clang;
29using namespace CodeGen;
30
31CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
32 : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
33
34llvm::Constant *CodeGenModule::GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
35 GlobalDecl GD) {
36 return GetOrCreateLLVMFunction(Name, FnTy, GD, /*ForVTable=*/true,
37 /*DontDefer=*/true, /*IsThunk=*/true);
38}
39
40static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
41 llvm::Function *ThunkFn, bool ForVTable,
42 GlobalDecl GD) {
43 CGM.setFunctionLinkage(GD, ThunkFn);
44 CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
45 !Thunk.Return.isEmpty());
46
47 // Set the right visibility.
48 CGM.setGVProperties(ThunkFn, GD);
49
50 if (!CGM.getCXXABI().exportThunk()) {
51 ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
52 ThunkFn->setDSOLocal(true);
53 }
54
55 if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
56 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
57}
58
59#ifndef NDEBUG
60static bool similar(const ABIArgInfo &infoL, CanQualType typeL,
61 const ABIArgInfo &infoR, CanQualType typeR) {
62 return (infoL.getKind() == infoR.getKind() &&
63 (typeL == typeR ||
64 (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
65 (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
66}
67#endif
68
69static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
70 QualType ResultType, RValue RV,
71 const ThunkInfo &Thunk) {
72 // Emit the return adjustment.
73 bool NullCheckValue = !ResultType->isReferenceType();
74
75 llvm::BasicBlock *AdjustNull = nullptr;
76 llvm::BasicBlock *AdjustNotNull = nullptr;
77 llvm::BasicBlock *AdjustEnd = nullptr;
78
79 llvm::Value *ReturnValue = RV.getScalarVal();
80
81 if (NullCheckValue) {
82 AdjustNull = CGF.createBasicBlock("adjust.null");
83 AdjustNotNull = CGF.createBasicBlock("adjust.notnull");
84 AdjustEnd = CGF.createBasicBlock("adjust.end");
85
86 llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue);
87 CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
88 CGF.EmitBlock(AdjustNotNull);
89 }
90
91 auto ClassDecl = ResultType->getPointeeType()->getAsCXXRecordDecl();
92 auto ClassAlign = CGF.CGM.getClassPointerAlignment(ClassDecl);
93 ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment(CGF,
94 Address(ReturnValue, ClassAlign),
95 Thunk.Return);
96
97 if (NullCheckValue) {
98 CGF.Builder.CreateBr(AdjustEnd);
99 CGF.EmitBlock(AdjustNull);
100 CGF.Builder.CreateBr(AdjustEnd);
101 CGF.EmitBlock(AdjustEnd);
102
103 llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2);
104 PHI->addIncoming(ReturnValue, AdjustNotNull);
105 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
106 AdjustNull);
107 ReturnValue = PHI;
108 }
109
110 return RValue::get(ReturnValue);
111}
112
113/// This function clones a function's DISubprogram node and enters it into
114/// a value map with the intent that the map can be utilized by the cloner
115/// to short-circuit Metadata node mapping.
116/// Furthermore, the function resolves any DILocalVariable nodes referenced
117/// by dbg.value intrinsics so they can be properly mapped during cloning.
118static void resolveTopLevelMetadata(llvm::Function *Fn,
119 llvm::ValueToValueMapTy &VMap) {
120 // Clone the DISubprogram node and put it into the Value map.
121 auto *DIS = Fn->getSubprogram();
122 if (!DIS)
123 return;
124 auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
125 VMap.MD()[DIS].reset(NewDIS);
126
127 // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
128 // they are referencing.
129 for (auto &BB : Fn->getBasicBlockList()) {
130 for (auto &I : BB) {
131 if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
132 auto *DILocal = DII->getVariable();
133 if (!DILocal->isResolved())
134 DILocal->resolve();
135 }
136 }
137 }
138}
139
140// This function does roughly the same thing as GenerateThunk, but in a
141// very different way, so that va_start and va_end work correctly.
142// FIXME: This function assumes "this" is the first non-sret LLVM argument of
143// a function, and that there is an alloca built in the entry block
144// for all accesses to "this".
145// FIXME: This function assumes there is only one "ret" statement per function.
146// FIXME: Cloning isn't correct in the presence of indirect goto!
147// FIXME: This implementation of thunks bloats codesize by duplicating the
148// function definition. There are alternatives:
149// 1. Add some sort of stub support to LLVM for cases where we can
150// do a this adjustment, then a sibcall.
151// 2. We could transform the definition to take a va_list instead of an
152// actual variable argument list, then have the thunks (including a
153// no-op thunk for the regular definition) call va_start/va_end.
154// There's a bit of per-call overhead for this solution, but it's
155// better for codesize if the definition is long.
156llvm::Function *
157CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,
158 const CGFunctionInfo &FnInfo,
159 GlobalDecl GD, const ThunkInfo &Thunk) {
160 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
161 const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
162 QualType ResultType = FPT->getReturnType();
163
164 // Get the original function
165 assert(FnInfo.isVariadic())((FnInfo.isVariadic()) ? static_cast<void> (0) : __assert_fail
("FnInfo.isVariadic()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 165, __PRETTY_FUNCTION__))
;
166 llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo);
167 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
168 llvm::Function *BaseFn = cast<llvm::Function>(Callee);
169
170 // Cloning can't work if we don't have a definition. The Microsoft ABI may
171 // require thunks when a definition is not available. Emit an error in these
172 // cases.
173 if (!MD->isDefined()) {
174 CGM.ErrorUnsupported(MD, "return-adjusting thunk with variadic arguments");
175 return Fn;
176 }
177 assert(!BaseFn->isDeclaration() && "cannot clone undefined variadic method")((!BaseFn->isDeclaration() && "cannot clone undefined variadic method"
) ? static_cast<void> (0) : __assert_fail ("!BaseFn->isDeclaration() && \"cannot clone undefined variadic method\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 177, __PRETTY_FUNCTION__))
;
178
179 // Clone to thunk.
180 llvm::ValueToValueMapTy VMap;
181
182 // We are cloning a function while some Metadata nodes are still unresolved.
183 // Ensure that the value mapper does not encounter any of them.
184 resolveTopLevelMetadata(BaseFn, VMap);
185 llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
186 Fn->replaceAllUsesWith(NewFn);
187 NewFn->takeName(Fn);
188 Fn->eraseFromParent();
189 Fn = NewFn;
190
191 // "Initialize" CGF (minimally).
192 CurFn = Fn;
193
194 // Get the "this" value
195 llvm::Function::arg_iterator AI = Fn->arg_begin();
196 if (CGM.ReturnTypeUsesSRet(FnInfo))
197 ++AI;
198
199 // Find the first store of "this", which will be to the alloca associated
200 // with "this".
201 Address ThisPtr(&*AI, CGM.getClassPointerAlignment(MD->getParent()));
202 llvm::BasicBlock *EntryBB = &Fn->front();
203 llvm::BasicBlock::iterator ThisStore =
204 std::find_if(EntryBB->begin(), EntryBB->end(), [&](llvm::Instruction &I) {
205 return isa<llvm::StoreInst>(I) &&
206 I.getOperand(0) == ThisPtr.getPointer();
207 });
208 assert(ThisStore != EntryBB->end() &&((ThisStore != EntryBB->end() && "Store of this should be in entry block?"
) ? static_cast<void> (0) : __assert_fail ("ThisStore != EntryBB->end() && \"Store of this should be in entry block?\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 209, __PRETTY_FUNCTION__))
209 "Store of this should be in entry block?")((ThisStore != EntryBB->end() && "Store of this should be in entry block?"
) ? static_cast<void> (0) : __assert_fail ("ThisStore != EntryBB->end() && \"Store of this should be in entry block?\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 209, __PRETTY_FUNCTION__))
;
210 // Adjust "this", if necessary.
211 Builder.SetInsertPoint(&*ThisStore);
212 llvm::Value *AdjustedThisPtr =
213 CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This);
214 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,
215 ThisStore->getOperand(0)->getType());
216 ThisStore->setOperand(0, AdjustedThisPtr);
217
218 if (!Thunk.Return.isEmpty()) {
219 // Fix up the returned value, if necessary.
220 for (llvm::BasicBlock &BB : *Fn) {
221 llvm::Instruction *T = BB.getTerminator();
222 if (isa<llvm::ReturnInst>(T)) {
223 RValue RV = RValue::get(T->getOperand(0));
224 T->eraseFromParent();
225 Builder.SetInsertPoint(&BB);
226 RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk);
227 Builder.CreateRet(RV.getScalarVal());
228 break;
229 }
230 }
231 }
232
233 return Fn;
234}
235
236void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
237 const CGFunctionInfo &FnInfo,
238 bool IsUnprototyped) {
239 assert(!CurGD.getDecl() && "CurGD was already set!")((!CurGD.getDecl() && "CurGD was already set!") ? static_cast
<void> (0) : __assert_fail ("!CurGD.getDecl() && \"CurGD was already set!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 239, __PRETTY_FUNCTION__))
;
240 CurGD = GD;
241 CurFuncIsThunk = true;
242
243 // Build FunctionArgs.
244 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
245 QualType ThisType = MD->getThisType();
246 QualType ResultType;
247 if (IsUnprototyped)
248 ResultType = CGM.getContext().VoidTy;
249 else if (CGM.getCXXABI().HasThisReturn(GD))
250 ResultType = ThisType;
251 else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
252 ResultType = CGM.getContext().VoidPtrTy;
253 else
254 ResultType = MD->getType()->castAs<FunctionProtoType>()->getReturnType();
255 FunctionArgList FunctionArgs;
256
257 // Create the implicit 'this' parameter declaration.
258 CGM.getCXXABI().buildThisParam(*this, FunctionArgs);
259
260 // Add the rest of the parameters, if we have a prototype to work with.
261 if (!IsUnprototyped) {
262 FunctionArgs.append(MD->param_begin(), MD->param_end());
263
264 if (isa<CXXDestructorDecl>(MD))
265 CGM.getCXXABI().addImplicitStructorParams(*this, ResultType,
266 FunctionArgs);
267 }
268
269 // Start defining the function.
270 auto NL = ApplyDebugLocation::CreateEmpty(*this);
271 StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
272 MD->getLocation());
273 // Create a scope with an artificial location for the body of this function.
274 auto AL = ApplyDebugLocation::CreateArtificial(*this);
275
276 // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.
277 CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
278 CXXThisValue = CXXABIThisValue;
279 CurCodeDecl = MD;
280 CurFuncDecl = MD;
281}
282
283void CodeGenFunction::FinishThunk() {
284 // Clear these to restore the invariants expected by
285 // StartFunction/FinishFunction.
286 CurCodeDecl = nullptr;
287 CurFuncDecl = nullptr;
288
289 FinishFunction();
290}
291
292void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
293 const ThunkInfo *Thunk,
294 bool IsUnprototyped) {
295 assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&((isa<CXXMethodDecl>(CurGD.getDecl()) && "Please use a new CGF for this thunk"
) ? static_cast<void> (0) : __assert_fail ("isa<CXXMethodDecl>(CurGD.getDecl()) && \"Please use a new CGF for this thunk\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 296, __PRETTY_FUNCTION__))
32
Assuming the object is a 'CXXMethodDecl'
33
'?' condition is true
296 "Please use a new CGF for this thunk")((isa<CXXMethodDecl>(CurGD.getDecl()) && "Please use a new CGF for this thunk"
) ? static_cast<void> (0) : __assert_fail ("isa<CXXMethodDecl>(CurGD.getDecl()) && \"Please use a new CGF for this thunk\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 296, __PRETTY_FUNCTION__))
;
297 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
34
The object is a 'CXXMethodDecl'
298
299 // Adjust the 'this' pointer if necessary
300 llvm::Value *AdjustedThisPtr =
301 Thunk
34.1
'Thunk' is non-null
34.1
'Thunk' is non-null
? CGM.getCXXABI().performThisAdjustment(
35
'?' condition is true
302 *this, LoadCXXThisAddress(), Thunk->This)
303 : LoadCXXThis();
304
305 // If perfect forwarding is required a variadic method, a method using
306 // inalloca, or an unprototyped thunk, use musttail. Emit an error if this
307 // thunk requires a return adjustment, since that is impossible with musttail.
308 if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic() || IsUnprototyped
43.1
'IsUnprototyped' is false
43.1
'IsUnprototyped' is false
) {
36
Assuming the condition is false
37
Calling 'CGFunctionInfo::isVariadic'
43
Returning from 'CGFunctionInfo::isVariadic'
44
Taking false branch
309 if (Thunk && !Thunk->Return.isEmpty()) {
310 if (IsUnprototyped)
311 CGM.ErrorUnsupported(
312 MD, "return-adjusting thunk with incomplete parameter type");
313 else if (CurFnInfo->isVariadic())
314 llvm_unreachable("shouldn't try to emit musttail return-adjusting "::llvm::llvm_unreachable_internal("shouldn't try to emit musttail return-adjusting "
"thunks for variadic functions", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 315)
315 "thunks for variadic functions")::llvm::llvm_unreachable_internal("shouldn't try to emit musttail return-adjusting "
"thunks for variadic functions", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 315)
;
316 else
317 CGM.ErrorUnsupported(
318 MD, "non-trivial argument copy for return-adjusting thunk");
319 }
320 EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee);
321 return;
322 }
323
324 // Start building CallArgs.
325 CallArgList CallArgs;
326 QualType ThisType = MD->getThisType();
327 CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);
328
329 if (isa<CXXDestructorDecl>(MD))
45
Assuming 'MD' is not a 'CXXDestructorDecl'
46
Taking false branch
330 CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs);
331
332#ifndef NDEBUG
333 unsigned PrefixArgs = CallArgs.size() - 1;
334#endif
335 // Add the rest of the arguments.
336 for (const ParmVarDecl *PD : MD->parameters())
47
Assuming '__begin1' is equal to '__end1'
337 EmitDelegateCallArg(CallArgs, PD, SourceLocation());
338
339 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
48
Assuming the object is not a 'FunctionProtoType'
49
'FPT' initialized to a null pointer value
340
341#ifndef NDEBUG
342 const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
343 CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1), PrefixArgs);
50
Passing null pointer value via 1st parameter 'prototype'
51
Calling 'RequiredArgs::forPrototypePlus'
344 assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&((CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention
()) ? static_cast<void> (0) : __assert_fail ("CallFnInfo.getRegParm() == CurFnInfo->getRegParm() && CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() && CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention()"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 346, __PRETTY_FUNCTION__))
345 CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&((CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention
()) ? static_cast<void> (0) : __assert_fail ("CallFnInfo.getRegParm() == CurFnInfo->getRegParm() && CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() && CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention()"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 346, __PRETTY_FUNCTION__))
346 CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention())((CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention
()) ? static_cast<void> (0) : __assert_fail ("CallFnInfo.getRegParm() == CurFnInfo->getRegParm() && CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() && CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention()"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 346, __PRETTY_FUNCTION__))
;
347 assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types((isa<CXXDestructorDecl>(MD) || similar(CallFnInfo.getReturnInfo
(), CallFnInfo.getReturnType(), CurFnInfo->getReturnInfo()
, CurFnInfo->getReturnType())) ? static_cast<void> (
0) : __assert_fail ("isa<CXXDestructorDecl>(MD) || similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(), CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType())"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 349, __PRETTY_FUNCTION__))
348 similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),((isa<CXXDestructorDecl>(MD) || similar(CallFnInfo.getReturnInfo
(), CallFnInfo.getReturnType(), CurFnInfo->getReturnInfo()
, CurFnInfo->getReturnType())) ? static_cast<void> (
0) : __assert_fail ("isa<CXXDestructorDecl>(MD) || similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(), CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType())"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 349, __PRETTY_FUNCTION__))
349 CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType()))((isa<CXXDestructorDecl>(MD) || similar(CallFnInfo.getReturnInfo
(), CallFnInfo.getReturnType(), CurFnInfo->getReturnInfo()
, CurFnInfo->getReturnType())) ? static_cast<void> (
0) : __assert_fail ("isa<CXXDestructorDecl>(MD) || similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(), CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType())"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 349, __PRETTY_FUNCTION__))
;
350 assert(CallFnInfo.arg_size() == CurFnInfo->arg_size())((CallFnInfo.arg_size() == CurFnInfo->arg_size()) ? static_cast
<void> (0) : __assert_fail ("CallFnInfo.arg_size() == CurFnInfo->arg_size()"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 350, __PRETTY_FUNCTION__))
;
351 for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)
352 assert(similar(CallFnInfo.arg_begin()[i].info,((similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin
()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->
arg_begin()[i].type)) ? static_cast<void> (0) : __assert_fail
("similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->arg_begin()[i].type)"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 355, __PRETTY_FUNCTION__))
353 CallFnInfo.arg_begin()[i].type,((similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin
()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->
arg_begin()[i].type)) ? static_cast<void> (0) : __assert_fail
("similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->arg_begin()[i].type)"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 355, __PRETTY_FUNCTION__))
354 CurFnInfo->arg_begin()[i].info,((similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin
()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->
arg_begin()[i].type)) ? static_cast<void> (0) : __assert_fail
("similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->arg_begin()[i].type)"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 355, __PRETTY_FUNCTION__))
355 CurFnInfo->arg_begin()[i].type))((similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin
()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->
arg_begin()[i].type)) ? static_cast<void> (0) : __assert_fail
("similar(CallFnInfo.arg_begin()[i].info, CallFnInfo.arg_begin()[i].type, CurFnInfo->arg_begin()[i].info, CurFnInfo->arg_begin()[i].type)"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 355, __PRETTY_FUNCTION__))
;
356#endif
357
358 // Determine whether we have a return value slot to use.
359 QualType ResultType = CGM.getCXXABI().HasThisReturn(CurGD)
360 ? ThisType
361 : CGM.getCXXABI().hasMostDerivedReturn(CurGD)
362 ? CGM.getContext().VoidPtrTy
363 : FPT->getReturnType();
364 ReturnValueSlot Slot;
365 if (!ResultType->isVoidType() &&
366 CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect)
367 Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
368
369 // Now emit our call.
370 llvm::CallBase *CallOrInvoke;
371 RValue RV = EmitCall(*CurFnInfo, CGCallee::forDirect(Callee, CurGD), Slot,
372 CallArgs, &CallOrInvoke);
373
374 // Consider return adjustment if we have ThunkInfo.
375 if (Thunk && !Thunk->Return.isEmpty())
376 RV = PerformReturnAdjustment(*this, ResultType, RV, *Thunk);
377 else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
378 Call->setTailCallKind(llvm::CallInst::TCK_Tail);
379
380 // Emit return.
381 if (!ResultType->isVoidType() && Slot.isNull())
382 CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);
383
384 // Disable the final ARC autorelease.
385 AutoreleaseResult = false;
386
387 FinishThunk();
388}
389
390void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
391 llvm::Value *AdjustedThisPtr,
392 llvm::FunctionCallee Callee) {
393 // Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
394 // to translate AST arguments into LLVM IR arguments. For thunks, we know
395 // that the caller prototype more or less matches the callee prototype with
396 // the exception of 'this'.
397 SmallVector<llvm::Value *, 8> Args;
398 for (llvm::Argument &A : CurFn->args())
399 Args.push_back(&A);
400
401 // Set the adjusted 'this' pointer.
402 const ABIArgInfo &ThisAI = CurFnInfo->arg_begin()->info;
403 if (ThisAI.isDirect()) {
404 const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo();
405 int ThisArgNo = RetAI.isIndirect() && !RetAI.isSRetAfterThis() ? 1 : 0;
406 llvm::Type *ThisType = Args[ThisArgNo]->getType();
407 if (ThisType != AdjustedThisPtr->getType())
408 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
409 Args[ThisArgNo] = AdjustedThisPtr;
410 } else {
411 assert(ThisAI.isInAlloca() && "this is passed directly or inalloca")((ThisAI.isInAlloca() && "this is passed directly or inalloca"
) ? static_cast<void> (0) : __assert_fail ("ThisAI.isInAlloca() && \"this is passed directly or inalloca\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 411, __PRETTY_FUNCTION__))
;
412 Address ThisAddr = GetAddrOfLocalVar(CXXABIThisDecl);
413 llvm::Type *ThisType = ThisAddr.getElementType();
414 if (ThisType != AdjustedThisPtr->getType())
415 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
416 Builder.CreateStore(AdjustedThisPtr, ThisAddr);
417 }
418
419 // Emit the musttail call manually. Even if the prologue pushed cleanups, we
420 // don't actually want to run them.
421 llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
422 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
423
424 // Apply the standard set of call attributes.
425 unsigned CallingConv;
426 llvm::AttributeList Attrs;
427 CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,
428 Attrs, CallingConv, /*AttrOnCallSite=*/true);
429 Call->setAttributes(Attrs);
430 Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
431
432 if (Call->getType()->isVoidTy())
433 Builder.CreateRetVoid();
434 else
435 Builder.CreateRet(Call);
436
437 // Finish the function to maintain CodeGenFunction invariants.
438 // FIXME: Don't emit unreachable code.
439 EmitBlock(createBasicBlock());
440 FinishFunction();
441}
442
443void CodeGenFunction::generateThunk(llvm::Function *Fn,
444 const CGFunctionInfo &FnInfo, GlobalDecl GD,
445 const ThunkInfo &Thunk,
446 bool IsUnprototyped) {
447 StartThunk(Fn, GD, FnInfo, IsUnprototyped);
448 // Create a scope with an artificial location for the body of this function.
449 auto AL = ApplyDebugLocation::CreateArtificial(*this);
450
451 // Get our callee. Use a placeholder type if this method is unprototyped so
452 // that CodeGenModule doesn't try to set attributes.
453 llvm::Type *Ty;
454 if (IsUnprototyped
28.1
'IsUnprototyped' is false
28.1
'IsUnprototyped' is false
)
29
Taking false branch
455 Ty = llvm::StructType::get(getLLVMContext());
456 else
457 Ty = CGM.getTypes().GetFunctionType(FnInfo);
458
459 llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
460
461 // Fix up the function type for an unprototyped musttail call.
462 if (IsUnprototyped
29.1
'IsUnprototyped' is false
29.1
'IsUnprototyped' is false
)
30
Taking false branch
463 Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType());
464
465 // Make the call and return the result.
466 EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee),
31
Calling 'CodeGenFunction::EmitCallAndReturnForThunk'
467 &Thunk, IsUnprototyped);
468}
469
470static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
471 bool IsUnprototyped, bool ForVTable) {
472 // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to
473 // provide thunks for us.
474 if (CGM.getTarget().getCXXABI().isMicrosoft())
13
Assuming the condition is true
14
Taking true branch
475 return true;
15
Returning the value 1, which participates in a condition later
476
477 // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide
478 // definitions of the main method. Therefore, emitting thunks with the vtable
479 // is purely an optimization. Emit the thunk if optimizations are enabled and
480 // all of the parameter types are complete.
481 if (ForVTable)
482 return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped;
483
484 // Always emit thunks along with the method definition.
485 return true;
486}
487
488llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
489 const ThunkInfo &TI,
490 bool ForVTable) {
491 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
7
The object is a 'CXXMethodDecl'
492
493 // First, get a declaration. Compute the mangled name. Don't worry about
494 // getting the function prototype right, since we may only need this
495 // declaration to fill in a vtable slot.
496 SmallString<256> Name;
497 MangleContext &MCtx = CGM.getCXXABI().getMangleContext();
498 llvm::raw_svector_ostream Out(Name);
499 if (const CXXDestructorDecl *DD
8.1
'DD' is null
8.1
'DD' is null
= dyn_cast<CXXDestructorDecl>(MD))
8
Assuming 'MD' is not a 'CXXDestructorDecl'
9
Taking false branch
500 MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI.This, Out);
501 else
502 MCtx.mangleThunk(MD, TI, Out);
503 llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
504 llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD);
505
506 // If we don't need to emit a definition, return this declaration as is.
507 bool IsUnprototyped = !CGM.getTypes().isFuncTypeConvertible(
11
Assuming the condition is false
508 MD->getType()->castAs<FunctionType>());
10
The object is a 'FunctionType'
509 if (!shouldEmitVTableThunk(CGM, MD, IsUnprototyped, ForVTable))
12
Calling 'shouldEmitVTableThunk'
16
Returning from 'shouldEmitVTableThunk'
17
Taking false branch
510 return Thunk;
511
512 // Arrange a function prototype appropriate for a function definition. In some
513 // cases in the MS ABI, we may need to build an unprototyped musttail thunk.
514 const CGFunctionInfo &FnInfo =
515 IsUnprototyped
17.1
'IsUnprototyped' is false
17.1
'IsUnprototyped' is false
? CGM.getTypes().arrangeUnprototypedMustTailThunk(MD)
18
'?' condition is false
516 : CGM.getTypes().arrangeGlobalDeclaration(GD);
517 llvm::FunctionType *ThunkFnTy = CGM.getTypes().GetFunctionType(FnInfo);
518
519 // If the type of the underlying GlobalValue is wrong, we'll have to replace
520 // it. It should be a declaration.
521 llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
19
The object is a 'Function'
522 if (ThunkFn->getFunctionType() != ThunkFnTy) {
20
Assuming the condition is false
21
Taking false branch
523 llvm::GlobalValue *OldThunkFn = ThunkFn;
524
525 assert(OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration")((OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration"
) ? static_cast<void> (0) : __assert_fail ("OldThunkFn->isDeclaration() && \"Shouldn't replace non-declaration\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 525, __PRETTY_FUNCTION__))
;
526
527 // Remove the name from the old thunk function and get a new thunk.
528 OldThunkFn->setName(StringRef());
529 ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
530 Name.str(), &CGM.getModule());
531 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
532
533 // If needed, replace the old thunk with a bitcast.
534 if (!OldThunkFn->use_empty()) {
535 llvm::Constant *NewPtrForOldDecl =
536 llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType());
537 OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
538 }
539
540 // Remove the old thunk.
541 OldThunkFn->eraseFromParent();
542 }
543
544 bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
545 bool UseAvailableExternallyLinkage = ForVTable
21.1
'ForVTable' is false
21.1
'ForVTable' is false
&& ABIHasKeyFunctions;
546
547 if (!ThunkFn->isDeclaration()) {
22
Assuming the condition is false
23
Taking false branch
548 if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
549 // There is already a thunk emitted for this function, do nothing.
550 return ThunkFn;
551 }
552
553 setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
554 return ThunkFn;
555 }
556
557 // If this will be unprototyped, add the "thunk" attribute so that LLVM knows
558 // that the return type is meaningless. These thunks can be used to call
559 // functions with differing return types, and the caller is required to cast
560 // the prototype appropriately to extract the correct value.
561 if (IsUnprototyped
23.1
'IsUnprototyped' is false
23.1
'IsUnprototyped' is false
)
24
Taking false branch
562 ThunkFn->addFnAttr("thunk");
563
564 CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
565
566 // Thunks for variadic methods are special because in general variadic
567 // arguments cannot be perferctly forwarded. In the general case, clang
568 // implements such thunks by cloning the original function body. However, for
569 // thunks with no return adjustment on targets that support musttail, we can
570 // use musttail to perfectly forward the variadic arguments.
571 bool ShouldCloneVarArgs = false;
572 if (!IsUnprototyped
24.1
'IsUnprototyped' is false
24.1
'IsUnprototyped' is false
&& ThunkFn->isVarArg()) {
25
Assuming the condition is false
26
Taking false branch
573 ShouldCloneVarArgs = true;
574 if (TI.Return.isEmpty()) {
575 switch (CGM.getTriple().getArch()) {
576 case llvm::Triple::x86_64:
577 case llvm::Triple::x86:
578 case llvm::Triple::aarch64:
579 ShouldCloneVarArgs = false;
580 break;
581 default:
582 break;
583 }
584 }
585 }
586
587 if (ShouldCloneVarArgs
26.1
'ShouldCloneVarArgs' is false
26.1
'ShouldCloneVarArgs' is false
) {
27
Taking false branch
588 if (UseAvailableExternallyLinkage)
589 return ThunkFn;
590 ThunkFn =
591 CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, TI);
592 } else {
593 // Normal thunk body generation.
594 CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, TI, IsUnprototyped);
28
Calling 'CodeGenFunction::generateThunk'
595 }
596
597 setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
598 return ThunkFn;
599}
600
601void CodeGenVTables::EmitThunks(GlobalDecl GD) {
602 const CXXMethodDecl *MD =
603 cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
1
The object is a 'CXXMethodDecl'
604
605 // We don't need to generate thunks for the base destructor.
606 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
2
Assuming 'MD' is not a 'CXXDestructorDecl'
607 return;
608
609 const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector =
610 VTContext->getThunkInfo(GD);
611
612 if (!ThunkInfoVector)
3
Assuming 'ThunkInfoVector' is non-null
4
Taking false branch
613 return;
614
615 for (const ThunkInfo& Thunk : *ThunkInfoVector)
5
Assuming '__begin1' is not equal to '__end1'
616 maybeEmitThunk(GD, Thunk, /*ForVTable=*/false);
6
Calling 'CodeGenVTables::maybeEmitThunk'
617}
618
619void CodeGenVTables::addVTableComponent(
620 ConstantArrayBuilder &builder, const VTableLayout &layout,
621 unsigned idx, llvm::Constant *rtti, unsigned &nextVTableThunkIndex) {
622 auto &component = layout.vtable_components()[idx];
623
624 auto addOffsetConstant = [&](CharUnits offset) {
625 builder.add(llvm::ConstantExpr::getIntToPtr(
626 llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()),
627 CGM.Int8PtrTy));
628 };
629
630 switch (component.getKind()) {
631 case VTableComponent::CK_VCallOffset:
632 return addOffsetConstant(component.getVCallOffset());
633
634 case VTableComponent::CK_VBaseOffset:
635 return addOffsetConstant(component.getVBaseOffset());
636
637 case VTableComponent::CK_OffsetToTop:
638 return addOffsetConstant(component.getOffsetToTop());
639
640 case VTableComponent::CK_RTTI:
641 return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.Int8PtrTy));
642
643 case VTableComponent::CK_FunctionPointer:
644 case VTableComponent::CK_CompleteDtorPointer:
645 case VTableComponent::CK_DeletingDtorPointer: {
646 GlobalDecl GD;
647
648 // Get the right global decl.
649 switch (component.getKind()) {
650 default:
651 llvm_unreachable("Unexpected vtable component kind")::llvm::llvm_unreachable_internal("Unexpected vtable component kind"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 651)
;
652 case VTableComponent::CK_FunctionPointer:
653 GD = component.getFunctionDecl();
654 break;
655 case VTableComponent::CK_CompleteDtorPointer:
656 GD = GlobalDecl(component.getDestructorDecl(), Dtor_Complete);
657 break;
658 case VTableComponent::CK_DeletingDtorPointer:
659 GD = GlobalDecl(component.getDestructorDecl(), Dtor_Deleting);
660 break;
661 }
662
663 if (CGM.getLangOpts().CUDA) {
664 // Emit NULL for methods we can't codegen on this
665 // side. Otherwise we'd end up with vtable with unresolved
666 // references.
667 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
668 // OK on device side: functions w/ __device__ attribute
669 // OK on host side: anything except __device__-only functions.
670 bool CanEmitMethod =
671 CGM.getLangOpts().CUDAIsDevice
672 ? MD->hasAttr<CUDADeviceAttr>()
673 : (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
674 if (!CanEmitMethod)
675 return builder.addNullPointer(CGM.Int8PtrTy);
676 // Method is acceptable, continue processing as usual.
677 }
678
679 auto getSpecialVirtualFn = [&](StringRef name) {
680 llvm::FunctionType *fnTy =
681 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
682 llvm::Constant *fn = cast<llvm::Constant>(
683 CGM.CreateRuntimeFunction(fnTy, name).getCallee());
684 if (auto f = dyn_cast<llvm::Function>(fn))
685 f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
686 return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy);
687 };
688
689 llvm::Constant *fnPtr;
690
691 // Pure virtual member functions.
692 if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
693 if (!PureVirtualFn)
694 PureVirtualFn =
695 getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
696 fnPtr = PureVirtualFn;
697
698 // Deleted virtual member functions.
699 } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
700 if (!DeletedVirtualFn)
701 DeletedVirtualFn =
702 getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());
703 fnPtr = DeletedVirtualFn;
704
705 // Thunks.
706 } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
707 layout.vtable_thunks()[nextVTableThunkIndex].first == idx) {
708 auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
709
710 nextVTableThunkIndex++;
711 fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true);
712
713 // Otherwise we can use the method definition directly.
714 } else {
715 llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
716 fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
717 }
718
719 fnPtr = llvm::ConstantExpr::getBitCast(fnPtr, CGM.Int8PtrTy);
720 builder.add(fnPtr);
721 return;
722 }
723
724 case VTableComponent::CK_UnusedFunctionPointer:
725 return builder.addNullPointer(CGM.Int8PtrTy);
726 }
727
728 llvm_unreachable("Unexpected vtable component kind")::llvm::llvm_unreachable_internal("Unexpected vtable component kind"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 728)
;
729}
730
731llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) {
732 SmallVector<llvm::Type *, 4> tys;
733 for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) {
734 tys.push_back(llvm::ArrayType::get(CGM.Int8PtrTy, layout.getVTableSize(i)));
735 }
736
737 return llvm::StructType::get(CGM.getLLVMContext(), tys);
738}
739
740void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
741 const VTableLayout &layout,
742 llvm::Constant *rtti) {
743 unsigned nextVTableThunkIndex = 0;
744 for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) {
745 auto vtableElem = builder.beginArray(CGM.Int8PtrTy);
746 size_t thisIndex = layout.getVTableOffset(i);
747 size_t nextIndex = thisIndex + layout.getVTableSize(i);
748 for (unsigned i = thisIndex; i != nextIndex; ++i) {
749 addVTableComponent(vtableElem, layout, i, rtti, nextVTableThunkIndex);
750 }
751 vtableElem.finishAndAddTo(builder);
752 }
753}
754
755llvm::GlobalVariable *
756CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
757 const BaseSubobject &Base,
758 bool BaseIsVirtual,
759 llvm::GlobalVariable::LinkageTypes Linkage,
760 VTableAddressPointsMapTy& AddressPoints) {
761 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
762 DI->completeClassData(Base.getBase());
763
764 std::unique_ptr<VTableLayout> VTLayout(
765 getItaniumVTableContext().createConstructionVTableLayout(
766 Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
767
768 // Add the address points.
769 AddressPoints = VTLayout->getAddressPoints();
770
771 // Get the mangled construction vtable name.
772 SmallString<256> OutName;
773 llvm::raw_svector_ostream Out(OutName);
774 cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
775 .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(),
776 Base.getBase(), Out);
777 StringRef Name = OutName.str();
778
779 llvm::Type *VTType = getVTableType(*VTLayout);
780
781 // Construction vtable symbols are not part of the Itanium ABI, so we cannot
782 // guarantee that they actually will be available externally. Instead, when
783 // emitting an available_externally VTT, we provide references to an internal
784 // linkage construction vtable. The ABI only requires complete-object vtables
785 // to be the same for all instances of a type, not construction vtables.
786 if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
787 Linkage = llvm::GlobalVariable::InternalLinkage;
788
789 unsigned Align = CGM.getDataLayout().getABITypeAlignment(VTType);
790
791 // Create the variable that will hold the construction vtable.
792 llvm::GlobalVariable *VTable =
793 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);
794
795 // V-tables are always unnamed_addr.
796 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
797
798 llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
799 CGM.getContext().getTagDeclType(Base.getBase()));
800
801 // Create and set the initializer.
802 ConstantInitBuilder builder(CGM);
803 auto components = builder.beginStruct();
804 createVTableInitializer(components, *VTLayout, RTTI);
805 components.finishAndSetAsInitializer(VTable);
806
807 // Set properties only after the initializer has been set to ensure that the
808 // GV is treated as definition and not declaration.
809 assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration")((!VTable->isDeclaration() && "Shouldn't set properties on declaration"
) ? static_cast<void> (0) : __assert_fail ("!VTable->isDeclaration() && \"Shouldn't set properties on declaration\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 809, __PRETTY_FUNCTION__))
;
810 CGM.setGVProperties(VTable, RD);
811
812 CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get());
813
814 return VTable;
815}
816
817static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
818 const CXXRecordDecl *RD) {
819 return CGM.getCodeGenOpts().OptimizationLevel > 0 &&
820 CGM.getCXXABI().canSpeculativelyEmitVTable(RD);
821}
822
823/// Compute the required linkage of the vtable for the given class.
824///
825/// Note that we only call this at the end of the translation unit.
826llvm::GlobalVariable::LinkageTypes
827CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
828 if (!RD->isExternallyVisible())
829 return llvm::GlobalVariable::InternalLinkage;
830
831 // We're at the end of the translation unit, so the current key
832 // function is fully correct.
833 const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD);
834 if (keyFunction && !RD->hasAttr<DLLImportAttr>()) {
835 // If this class has a key function, use that to determine the
836 // linkage of the vtable.
837 const FunctionDecl *def = nullptr;
838 if (keyFunction->hasBody(def))
839 keyFunction = cast<CXXMethodDecl>(def);
840
841 switch (keyFunction->getTemplateSpecializationKind()) {
842 case TSK_Undeclared:
843 case TSK_ExplicitSpecialization:
844 assert((def || CodeGenOpts.OptimizationLevel > 0 ||(((def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts
.getDebugInfo() != codegenoptions::NoDebugInfo) && "Shouldn't query vtable linkage without key function, "
"optimizations, or debug info") ? static_cast<void> (0
) : __assert_fail ("(def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) && \"Shouldn't query vtable linkage without key function, \" \"optimizations, or debug info\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 847, __PRETTY_FUNCTION__))
845 CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) &&(((def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts
.getDebugInfo() != codegenoptions::NoDebugInfo) && "Shouldn't query vtable linkage without key function, "
"optimizations, or debug info") ? static_cast<void> (0
) : __assert_fail ("(def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) && \"Shouldn't query vtable linkage without key function, \" \"optimizations, or debug info\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 847, __PRETTY_FUNCTION__))
846 "Shouldn't query vtable linkage without key function, "(((def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts
.getDebugInfo() != codegenoptions::NoDebugInfo) && "Shouldn't query vtable linkage without key function, "
"optimizations, or debug info") ? static_cast<void> (0
) : __assert_fail ("(def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) && \"Shouldn't query vtable linkage without key function, \" \"optimizations, or debug info\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 847, __PRETTY_FUNCTION__))
847 "optimizations, or debug info")(((def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts
.getDebugInfo() != codegenoptions::NoDebugInfo) && "Shouldn't query vtable linkage without key function, "
"optimizations, or debug info") ? static_cast<void> (0
) : __assert_fail ("(def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) && \"Shouldn't query vtable linkage without key function, \" \"optimizations, or debug info\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 847, __PRETTY_FUNCTION__))
;
848 if (!def && CodeGenOpts.OptimizationLevel > 0)
849 return llvm::GlobalVariable::AvailableExternallyLinkage;
850
851 if (keyFunction->isInlined())
852 return !Context.getLangOpts().AppleKext ?
853 llvm::GlobalVariable::LinkOnceODRLinkage :
854 llvm::Function::InternalLinkage;
855
856 return llvm::GlobalVariable::ExternalLinkage;
857
858 case TSK_ImplicitInstantiation:
859 return !Context.getLangOpts().AppleKext ?
860 llvm::GlobalVariable::LinkOnceODRLinkage :
861 llvm::Function::InternalLinkage;
862
863 case TSK_ExplicitInstantiationDefinition:
864 return !Context.getLangOpts().AppleKext ?
865 llvm::GlobalVariable::WeakODRLinkage :
866 llvm::Function::InternalLinkage;
867
868 case TSK_ExplicitInstantiationDeclaration:
869 llvm_unreachable("Should not have been asked to emit this")::llvm::llvm_unreachable_internal("Should not have been asked to emit this"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 869)
;
870 }
871 }
872
873 // -fapple-kext mode does not support weak linkage, so we must use
874 // internal linkage.
875 if (Context.getLangOpts().AppleKext)
876 return llvm::Function::InternalLinkage;
877
878 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
879 llvm::GlobalValue::LinkOnceODRLinkage;
880 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
881 llvm::GlobalValue::WeakODRLinkage;
882 if (RD->hasAttr<DLLExportAttr>()) {
883 // Cannot discard exported vtables.
884 DiscardableODRLinkage = NonDiscardableODRLinkage;
885 } else if (RD->hasAttr<DLLImportAttr>()) {
886 // Imported vtables are available externally.
887 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
888 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
889 }
890
891 switch (RD->getTemplateSpecializationKind()) {
892 case TSK_Undeclared:
893 case TSK_ExplicitSpecialization:
894 case TSK_ImplicitInstantiation:
895 return DiscardableODRLinkage;
896
897 case TSK_ExplicitInstantiationDeclaration:
898 // Explicit instantiations in MSVC do not provide vtables, so we must emit
899 // our own.
900 if (getTarget().getCXXABI().isMicrosoft())
901 return DiscardableODRLinkage;
902 return shouldEmitAvailableExternallyVTable(*this, RD)
903 ? llvm::GlobalVariable::AvailableExternallyLinkage
904 : llvm::GlobalVariable::ExternalLinkage;
905
906 case TSK_ExplicitInstantiationDefinition:
907 return NonDiscardableODRLinkage;
908 }
909
910 llvm_unreachable("Invalid TemplateSpecializationKind!")::llvm::llvm_unreachable_internal("Invalid TemplateSpecializationKind!"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 910)
;
911}
912
913/// This is a callback from Sema to tell us that a particular vtable is
914/// required to be emitted in this translation unit.
915///
916/// This is only called for vtables that _must_ be emitted (mainly due to key
917/// functions). For weak vtables, CodeGen tracks when they are needed and
918/// emits them as-needed.
919void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) {
920 VTables.GenerateClassData(theClass);
921}
922
923void
924CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
925 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
926 DI->completeClassData(RD);
927
928 if (RD->getNumVBases())
929 CGM.getCXXABI().emitVirtualInheritanceTables(RD);
930
931 CGM.getCXXABI().emitVTableDefinitions(*this, RD);
932}
933
934/// At this point in the translation unit, does it appear that can we
935/// rely on the vtable being defined elsewhere in the program?
936///
937/// The response is really only definitive when called at the end of
938/// the translation unit.
939///
940/// The only semantic restriction here is that the object file should
941/// not contain a vtable definition when that vtable is defined
942/// strongly elsewhere. Otherwise, we'd just like to avoid emitting
943/// vtables when unnecessary.
944bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
945 assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.")((RD->isDynamicClass() && "Non-dynamic classes have no VTable."
) ? static_cast<void> (0) : __assert_fail ("RD->isDynamicClass() && \"Non-dynamic classes have no VTable.\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 945, __PRETTY_FUNCTION__))
;
946
947 // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't
948 // emit them even if there is an explicit template instantiation.
949 if (CGM.getTarget().getCXXABI().isMicrosoft())
950 return false;
951
952 // If we have an explicit instantiation declaration (and not a
953 // definition), the vtable is defined elsewhere.
954 TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
955 if (TSK == TSK_ExplicitInstantiationDeclaration)
956 return true;
957
958 // Otherwise, if the class is an instantiated template, the
959 // vtable must be defined here.
960 if (TSK == TSK_ImplicitInstantiation ||
961 TSK == TSK_ExplicitInstantiationDefinition)
962 return false;
963
964 // Otherwise, if the class doesn't have a key function (possibly
965 // anymore), the vtable must be defined here.
966 const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD);
967 if (!keyFunction)
968 return false;
969
970 // Otherwise, if we don't have a definition of the key function, the
971 // vtable must be defined somewhere else.
972 return !keyFunction->hasBody();
973}
974
975/// Given that we're currently at the end of the translation unit, and
976/// we've emitted a reference to the vtable for this class, should
977/// we define that vtable?
978static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
979 const CXXRecordDecl *RD) {
980 // If vtable is internal then it has to be done.
981 if (!CGM.getVTables().isVTableExternal(RD))
982 return true;
983
984 // If it's external then maybe we will need it as available_externally.
985 return shouldEmitAvailableExternallyVTable(CGM, RD);
986}
987
988/// Given that at some point we emitted a reference to one or more
989/// vtables, and that we are now at the end of the translation unit,
990/// decide whether we should emit them.
991void CodeGenModule::EmitDeferredVTables() {
992#ifndef NDEBUG
993 // Remember the size of DeferredVTables, because we're going to assume
994 // that this entire operation doesn't modify it.
995 size_t savedSize = DeferredVTables.size();
996#endif
997
998 for (const CXXRecordDecl *RD : DeferredVTables)
999 if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
1000 VTables.GenerateClassData(RD);
1001 else if (shouldOpportunisticallyEmitVTables())
1002 OpportunisticVTables.push_back(RD);
1003
1004 assert(savedSize == DeferredVTables.size() &&((savedSize == DeferredVTables.size() && "deferred extra vtables during vtable emission?"
) ? static_cast<void> (0) : __assert_fail ("savedSize == DeferredVTables.size() && \"deferred extra vtables during vtable emission?\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 1005, __PRETTY_FUNCTION__))
1005 "deferred extra vtables during vtable emission?")((savedSize == DeferredVTables.size() && "deferred extra vtables during vtable emission?"
) ? static_cast<void> (0) : __assert_fail ("savedSize == DeferredVTables.size() && \"deferred extra vtables during vtable emission?\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/lib/CodeGen/CGVTables.cpp"
, 1005, __PRETTY_FUNCTION__))
;
1006 DeferredVTables.clear();
1007}
1008
1009bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
1010 LinkageInfo LV = RD->getLinkageAndVisibility();
1011 if (!isExternallyVisible(LV.getLinkage()))
1012 return true;
1013
1014 if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
1015 return false;
1016
1017 if (getTriple().isOSBinFormatCOFF()) {
1018 if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
1019 return false;
1020 } else {
1021 if (LV.getVisibility() != HiddenVisibility)
1022 return false;
1023 }
1024
1025 if (getCodeGenOpts().LTOVisibilityPublicStd) {
1026 const DeclContext *DC = RD;
1027 while (1) {
1028 auto *D = cast<Decl>(DC);
1029 DC = DC->getParent();
1030 if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
1031 if (auto *ND = dyn_cast<NamespaceDecl>(D))
1032 if (const IdentifierInfo *II = ND->getIdentifier())
1033 if (II->isStr("std") || II->isStr("stdext"))
1034 return false;
1035 break;
1036 }
1037 }
1038 }
1039
1040 return true;
1041}
1042
1043llvm::GlobalObject::VCallVisibility
1044CodeGenModule::GetVCallVisibilityLevel(const CXXRecordDecl *RD) {
1045 LinkageInfo LV = RD->getLinkageAndVisibility();
1046 llvm::GlobalObject::VCallVisibility TypeVis;
1047 if (!isExternallyVisible(LV.getLinkage()))
1048 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
1049 else if (HasHiddenLTOVisibility(RD))
1050 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
1051 else
1052 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
1053
1054 for (auto B : RD->bases())
1055 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1056 TypeVis = std::min(TypeVis,
1057 GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl()));
1058
1059 for (auto B : RD->vbases())
1060 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1061 TypeVis = std::min(TypeVis,
1062 GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl()));
1063
1064 return TypeVis;
1065}
1066
1067void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
1068 llvm::GlobalVariable *VTable,
1069 const VTableLayout &VTLayout) {
1070 if (!getCodeGenOpts().LTOUnit)
1071 return;
1072
1073 CharUnits PointerWidth =
1074 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
1075
1076 typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
1077 std::vector<AddressPoint> AddressPoints;
1078 for (auto &&AP : VTLayout.getAddressPoints())
1079 AddressPoints.push_back(std::make_pair(
1080 AP.first.getBase(), VTLayout.getVTableOffset(AP.second.VTableIndex) +
1081 AP.second.AddressPointIndex));
1082
1083 // Sort the address points for determinism.
1084 llvm::sort(AddressPoints, [this](const AddressPoint &AP1,
1085 const AddressPoint &AP2) {
1086 if (&AP1 == &AP2)
1087 return false;
1088
1089 std::string S1;
1090 llvm::raw_string_ostream O1(S1);
1091 getCXXABI().getMangleContext().mangleTypeName(
1092 QualType(AP1.first->getTypeForDecl(), 0), O1);
1093 O1.flush();
1094
1095 std::string S2;
1096 llvm::raw_string_ostream O2(S2);
1097 getCXXABI().getMangleContext().mangleTypeName(
1098 QualType(AP2.first->getTypeForDecl(), 0), O2);
1099 O2.flush();
1100
1101 if (S1 < S2)
1102 return true;
1103 if (S1 != S2)
1104 return false;
1105
1106 return AP1.second < AP2.second;
1107 });
1108
1109 ArrayRef<VTableComponent> Comps = VTLayout.vtable_components();
1110 for (auto AP : AddressPoints) {
1111 // Create type metadata for the address point.
1112 AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first);
1113
1114 // The class associated with each address point could also potentially be
1115 // used for indirect calls via a member function pointer, so we need to
1116 // annotate the address of each function pointer with the appropriate member
1117 // function pointer type.
1118 for (unsigned I = 0; I != Comps.size(); ++I) {
1119 if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer)
1120 continue;
1121 llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
1122 Context.getMemberPointerType(
1123 Comps[I].getFunctionDecl()->getType(),
1124 Context.getRecordType(AP.first).getTypePtr()));
1125 VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
1126 }
1127 }
1128
1129 if (getCodeGenOpts().VirtualFunctionElimination) {
1130 llvm::GlobalObject::VCallVisibility TypeVis = GetVCallVisibilityLevel(RD);
1131 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1132 VTable->addVCallVisibilityMetadata(TypeVis);
1133 }
1134}

/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h

1//==-- CGFunctionInfo.h - Representation of function 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 CGFunctionInfo and associated types used in representing the
10// LLVM source types and ABI-coerced types for function arguments and
11// return values.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
16#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
17
18#include "clang/AST/CanonicalType.h"
19#include "clang/AST/CharUnits.h"
20#include "clang/AST/Decl.h"
21#include "clang/AST/Type.h"
22#include "llvm/IR/DerivedTypes.h"
23#include "llvm/ADT/FoldingSet.h"
24#include "llvm/Support/TrailingObjects.h"
25#include <cassert>
26
27namespace clang {
28namespace CodeGen {
29
30/// ABIArgInfo - Helper class to encapsulate information about how a
31/// specific C type should be passed to or returned from a function.
32class ABIArgInfo {
33public:
34 enum Kind : uint8_t {
35 /// Direct - Pass the argument directly using the normal converted LLVM
36 /// type, or by coercing to another specified type stored in
37 /// 'CoerceToType'). If an offset is specified (in UIntData), then the
38 /// argument passed is offset by some number of bytes in the memory
39 /// representation. A dummy argument is emitted before the real argument
40 /// if the specified type stored in "PaddingType" is not zero.
41 Direct,
42
43 /// Extend - Valid only for integer argument types. Same as 'direct'
44 /// but also emit a zero/sign extension attribute.
45 Extend,
46
47 /// Indirect - Pass the argument indirectly via a hidden pointer
48 /// with the specified alignment (0 indicates default alignment).
49 Indirect,
50
51 /// Ignore - Ignore the argument (treat as void). Useful for void and
52 /// empty structs.
53 Ignore,
54
55 /// Expand - Only valid for aggregate argument types. The structure should
56 /// be expanded into consecutive arguments for its constituent fields.
57 /// Currently expand is only allowed on structures whose fields
58 /// are all scalar types or are themselves expandable types.
59 Expand,
60
61 /// CoerceAndExpand - Only valid for aggregate argument types. The
62 /// structure should be expanded into consecutive arguments corresponding
63 /// to the non-array elements of the type stored in CoerceToType.
64 /// Array elements in the type are assumed to be padding and skipped.
65 CoerceAndExpand,
66
67 /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
68 /// This is similar to indirect with byval, except it only applies to
69 /// arguments stored in memory and forbids any implicit copies. When
70 /// applied to a return type, it means the value is returned indirectly via
71 /// an implicit sret parameter stored in the argument struct.
72 InAlloca,
73 KindFirst = Direct,
74 KindLast = InAlloca
75 };
76
77private:
78 llvm::Type *TypeData; // canHaveCoerceToType()
79 union {
80 llvm::Type *PaddingType; // canHavePaddingType()
81 llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
82 };
83 union {
84 unsigned DirectOffset; // isDirect() || isExtend()
85 unsigned IndirectAlign; // isIndirect()
86 unsigned AllocaFieldIndex; // isInAlloca()
87 };
88 Kind TheKind;
89 bool PaddingInReg : 1;
90 bool InAllocaSRet : 1; // isInAlloca()
91 bool IndirectByVal : 1; // isIndirect()
92 bool IndirectRealign : 1; // isIndirect()
93 bool SRetAfterThis : 1; // isIndirect()
94 bool InReg : 1; // isDirect() || isExtend() || isIndirect()
95 bool CanBeFlattened: 1; // isDirect()
96 bool SignExt : 1; // isExtend()
97
98 bool canHavePaddingType() const {
99 return isDirect() || isExtend() || isIndirect() || isExpand();
100 }
101 void setPaddingType(llvm::Type *T) {
102 assert(canHavePaddingType())((canHavePaddingType()) ? static_cast<void> (0) : __assert_fail
("canHavePaddingType()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 102, __PRETTY_FUNCTION__))
;
103 PaddingType = T;
104 }
105
106 void setUnpaddedCoerceToType(llvm::Type *T) {
107 assert(isCoerceAndExpand())((isCoerceAndExpand()) ? static_cast<void> (0) : __assert_fail
("isCoerceAndExpand()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 107, __PRETTY_FUNCTION__))
;
108 UnpaddedCoerceAndExpandType = T;
109 }
110
111public:
112 ABIArgInfo(Kind K = Direct)
113 : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
114 TheKind(K), PaddingInReg(false), InAllocaSRet(false),
115 IndirectByVal(false), IndirectRealign(false), SRetAfterThis(false),
116 InReg(false), CanBeFlattened(false), SignExt(false) {}
117
118 static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
119 llvm::Type *Padding = nullptr,
120 bool CanBeFlattened = true) {
121 auto AI = ABIArgInfo(Direct);
122 AI.setCoerceToType(T);
123 AI.setPaddingType(Padding);
124 AI.setDirectOffset(Offset);
125 AI.setCanBeFlattened(CanBeFlattened);
126 return AI;
127 }
128 static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
129 auto AI = getDirect(T);
130 AI.setInReg(true);
131 return AI;
132 }
133
134 static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
135 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType")((Ty->isIntegralOrEnumerationType() && "Unexpected QualType"
) ? static_cast<void> (0) : __assert_fail ("Ty->isIntegralOrEnumerationType() && \"Unexpected QualType\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 135, __PRETTY_FUNCTION__))
;
136 auto AI = ABIArgInfo(Extend);
137 AI.setCoerceToType(T);
138 AI.setPaddingType(nullptr);
139 AI.setDirectOffset(0);
140 AI.setSignExt(true);
141 return AI;
142 }
143
144 static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
145 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType")((Ty->isIntegralOrEnumerationType() && "Unexpected QualType"
) ? static_cast<void> (0) : __assert_fail ("Ty->isIntegralOrEnumerationType() && \"Unexpected QualType\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 145, __PRETTY_FUNCTION__))
;
146 auto AI = ABIArgInfo(Extend);
147 AI.setCoerceToType(T);
148 AI.setPaddingType(nullptr);
149 AI.setDirectOffset(0);
150 AI.setSignExt(false);
151 return AI;
152 }
153
154 // ABIArgInfo will record the argument as being extended based on the sign
155 // of its type.
156 static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
157 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType")((Ty->isIntegralOrEnumerationType() && "Unexpected QualType"
) ? static_cast<void> (0) : __assert_fail ("Ty->isIntegralOrEnumerationType() && \"Unexpected QualType\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 157, __PRETTY_FUNCTION__))
;
158 if (Ty->hasSignedIntegerRepresentation())
159 return getSignExtend(Ty, T);
160 return getZeroExtend(Ty, T);
161 }
162
163 static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
164 auto AI = getExtend(Ty, T);
165 AI.setInReg(true);
166 return AI;
167 }
168 static ABIArgInfo getIgnore() {
169 return ABIArgInfo(Ignore);
170 }
171 static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
172 bool Realign = false,
173 llvm::Type *Padding = nullptr) {
174 auto AI = ABIArgInfo(Indirect);
175 AI.setIndirectAlign(Alignment);
176 AI.setIndirectByVal(ByVal);
177 AI.setIndirectRealign(Realign);
178 AI.setSRetAfterThis(false);
179 AI.setPaddingType(Padding);
180 return AI;
181 }
182 static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
183 bool Realign = false) {
184 auto AI = getIndirect(Alignment, ByVal, Realign);
185 AI.setInReg(true);
186 return AI;
187 }
188 static ABIArgInfo getInAlloca(unsigned FieldIndex) {
189 auto AI = ABIArgInfo(InAlloca);
190 AI.setInAllocaFieldIndex(FieldIndex);
191 return AI;
192 }
193 static ABIArgInfo getExpand() {
194 auto AI = ABIArgInfo(Expand);
195 AI.setPaddingType(nullptr);
196 return AI;
197 }
198 static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
199 llvm::Type *Padding) {
200 auto AI = getExpand();
201 AI.setPaddingInReg(PaddingInReg);
202 AI.setPaddingType(Padding);
203 return AI;
204 }
205
206 /// \param unpaddedCoerceToType The coerce-to type with padding elements
207 /// removed, canonicalized to a single element if it would otherwise
208 /// have exactly one element.
209 static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
210 llvm::Type *unpaddedCoerceToType) {
211#ifndef NDEBUG
212 // Sanity checks on unpaddedCoerceToType.
213
214 // Assert that we only have a struct type if there are multiple elements.
215 auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
216 assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1)((!unpaddedStruct || unpaddedStruct->getNumElements() != 1
) ? static_cast<void> (0) : __assert_fail ("!unpaddedStruct || unpaddedStruct->getNumElements() != 1"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 216, __PRETTY_FUNCTION__))
;
217
218 // Assert that all the non-padding elements have a corresponding element
219 // in the unpadded type.
220 unsigned unpaddedIndex = 0;
221 for (auto eltType : coerceToType->elements()) {
222 if (isPaddingForCoerceAndExpand(eltType)) continue;
223 if (unpaddedStruct) {
224 assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType)((unpaddedStruct->getElementType(unpaddedIndex) == eltType
) ? static_cast<void> (0) : __assert_fail ("unpaddedStruct->getElementType(unpaddedIndex) == eltType"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 224, __PRETTY_FUNCTION__))
;
225 } else {
226 assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType)((unpaddedIndex == 0 && unpaddedCoerceToType == eltType
) ? static_cast<void> (0) : __assert_fail ("unpaddedIndex == 0 && unpaddedCoerceToType == eltType"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 226, __PRETTY_FUNCTION__))
;
227 }
228 unpaddedIndex++;
229 }
230
231 // Assert that there aren't extra elements in the unpadded type.
232 if (unpaddedStruct) {
233 assert(unpaddedStruct->getNumElements() == unpaddedIndex)((unpaddedStruct->getNumElements() == unpaddedIndex) ? static_cast
<void> (0) : __assert_fail ("unpaddedStruct->getNumElements() == unpaddedIndex"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 233, __PRETTY_FUNCTION__))
;
234 } else {
235 assert(unpaddedIndex == 1)((unpaddedIndex == 1) ? static_cast<void> (0) : __assert_fail
("unpaddedIndex == 1", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 235, __PRETTY_FUNCTION__))
;
236 }
237#endif
238
239 auto AI = ABIArgInfo(CoerceAndExpand);
240 AI.setCoerceToType(coerceToType);
241 AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
242 return AI;
243 }
244
245 static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
246 if (eltType->isArrayTy()) {
247 assert(eltType->getArrayElementType()->isIntegerTy(8))((eltType->getArrayElementType()->isIntegerTy(8)) ? static_cast
<void> (0) : __assert_fail ("eltType->getArrayElementType()->isIntegerTy(8)"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 247, __PRETTY_FUNCTION__))
;
248 return true;
249 } else {
250 return false;
251 }
252 }
253
254 Kind getKind() const { return TheKind; }
255 bool isDirect() const { return TheKind == Direct; }
256 bool isInAlloca() const { return TheKind == InAlloca; }
257 bool isExtend() const { return TheKind == Extend; }
258 bool isIgnore() const { return TheKind == Ignore; }
259 bool isIndirect() const { return TheKind == Indirect; }
260 bool isExpand() const { return TheKind == Expand; }
261 bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
262
263 bool canHaveCoerceToType() const {
264 return isDirect() || isExtend() || isCoerceAndExpand();
265 }
266
267 // Direct/Extend accessors
268 unsigned getDirectOffset() const {
269 assert((isDirect() || isExtend()) && "Not a direct or extend kind")(((isDirect() || isExtend()) && "Not a direct or extend kind"
) ? static_cast<void> (0) : __assert_fail ("(isDirect() || isExtend()) && \"Not a direct or extend kind\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 269, __PRETTY_FUNCTION__))
;
270 return DirectOffset;
271 }
272 void setDirectOffset(unsigned Offset) {
273 assert((isDirect() || isExtend()) && "Not a direct or extend kind")(((isDirect() || isExtend()) && "Not a direct or extend kind"
) ? static_cast<void> (0) : __assert_fail ("(isDirect() || isExtend()) && \"Not a direct or extend kind\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 273, __PRETTY_FUNCTION__))
;
274 DirectOffset = Offset;
275 }
276
277 bool isSignExt() const {
278 assert(isExtend() && "Invalid kind!")((isExtend() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isExtend() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 278, __PRETTY_FUNCTION__))
;
279 return SignExt;
280 }
281 void setSignExt(bool SExt) {
282 assert(isExtend() && "Invalid kind!")((isExtend() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isExtend() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 282, __PRETTY_FUNCTION__))
;
283 SignExt = SExt;
284 }
285
286 llvm::Type *getPaddingType() const {
287 return (canHavePaddingType() ? PaddingType : nullptr);
288 }
289
290 bool getPaddingInReg() const {
291 return PaddingInReg;
292 }
293 void setPaddingInReg(bool PIR) {
294 PaddingInReg = PIR;
295 }
296
297 llvm::Type *getCoerceToType() const {
298 assert(canHaveCoerceToType() && "Invalid kind!")((canHaveCoerceToType() && "Invalid kind!") ? static_cast
<void> (0) : __assert_fail ("canHaveCoerceToType() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 298, __PRETTY_FUNCTION__))
;
299 return TypeData;
300 }
301
302 void setCoerceToType(llvm::Type *T) {
303 assert(canHaveCoerceToType() && "Invalid kind!")((canHaveCoerceToType() && "Invalid kind!") ? static_cast
<void> (0) : __assert_fail ("canHaveCoerceToType() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 303, __PRETTY_FUNCTION__))
;
304 TypeData = T;
305 }
306
307 llvm::StructType *getCoerceAndExpandType() const {
308 assert(isCoerceAndExpand())((isCoerceAndExpand()) ? static_cast<void> (0) : __assert_fail
("isCoerceAndExpand()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 308, __PRETTY_FUNCTION__))
;
309 return cast<llvm::StructType>(TypeData);
310 }
311
312 llvm::Type *getUnpaddedCoerceAndExpandType() const {
313 assert(isCoerceAndExpand())((isCoerceAndExpand()) ? static_cast<void> (0) : __assert_fail
("isCoerceAndExpand()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 313, __PRETTY_FUNCTION__))
;
314 return UnpaddedCoerceAndExpandType;
315 }
316
317 ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const {
318 assert(isCoerceAndExpand())((isCoerceAndExpand()) ? static_cast<void> (0) : __assert_fail
("isCoerceAndExpand()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 318, __PRETTY_FUNCTION__))
;
319 if (auto structTy =
320 dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
321 return structTy->elements();
322 } else {
323 return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1);
324 }
325 }
326
327 bool getInReg() const {
328 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!")(((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"
) ? static_cast<void> (0) : __assert_fail ("(isDirect() || isExtend() || isIndirect()) && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 328, __PRETTY_FUNCTION__))
;
329 return InReg;
330 }
331
332 void setInReg(bool IR) {
333 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!")(((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"
) ? static_cast<void> (0) : __assert_fail ("(isDirect() || isExtend() || isIndirect()) && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 333, __PRETTY_FUNCTION__))
;
334 InReg = IR;
335 }
336
337 // Indirect accessors
338 CharUnits getIndirectAlign() const {
339 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 339, __PRETTY_FUNCTION__))
;
340 return CharUnits::fromQuantity(IndirectAlign);
341 }
342 void setIndirectAlign(CharUnits IA) {
343 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 343, __PRETTY_FUNCTION__))
;
344 IndirectAlign = IA.getQuantity();
345 }
346
347 bool getIndirectByVal() const {
348 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 348, __PRETTY_FUNCTION__))
;
349 return IndirectByVal;
350 }
351 void setIndirectByVal(bool IBV) {
352 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 352, __PRETTY_FUNCTION__))
;
353 IndirectByVal = IBV;
354 }
355
356 bool getIndirectRealign() const {
357 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 357, __PRETTY_FUNCTION__))
;
358 return IndirectRealign;
359 }
360 void setIndirectRealign(bool IR) {
361 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 361, __PRETTY_FUNCTION__))
;
362 IndirectRealign = IR;
363 }
364
365 bool isSRetAfterThis() const {
366 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 366, __PRETTY_FUNCTION__))
;
367 return SRetAfterThis;
368 }
369 void setSRetAfterThis(bool AfterThis) {
370 assert(isIndirect() && "Invalid kind!")((isIndirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isIndirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 370, __PRETTY_FUNCTION__))
;
371 SRetAfterThis = AfterThis;
372 }
373
374 unsigned getInAllocaFieldIndex() const {
375 assert(isInAlloca() && "Invalid kind!")((isInAlloca() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isInAlloca() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 375, __PRETTY_FUNCTION__))
;
376 return AllocaFieldIndex;
377 }
378 void setInAllocaFieldIndex(unsigned FieldIndex) {
379 assert(isInAlloca() && "Invalid kind!")((isInAlloca() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isInAlloca() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 379, __PRETTY_FUNCTION__))
;
380 AllocaFieldIndex = FieldIndex;
381 }
382
383 /// Return true if this field of an inalloca struct should be returned
384 /// to implement a struct return calling convention.
385 bool getInAllocaSRet() const {
386 assert(isInAlloca() && "Invalid kind!")((isInAlloca() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isInAlloca() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 386, __PRETTY_FUNCTION__))
;
387 return InAllocaSRet;
388 }
389
390 void setInAllocaSRet(bool SRet) {
391 assert(isInAlloca() && "Invalid kind!")((isInAlloca() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isInAlloca() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 391, __PRETTY_FUNCTION__))
;
392 InAllocaSRet = SRet;
393 }
394
395 bool getCanBeFlattened() const {
396 assert(isDirect() && "Invalid kind!")((isDirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isDirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 396, __PRETTY_FUNCTION__))
;
397 return CanBeFlattened;
398 }
399
400 void setCanBeFlattened(bool Flatten) {
401 assert(isDirect() && "Invalid kind!")((isDirect() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isDirect() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 401, __PRETTY_FUNCTION__))
;
402 CanBeFlattened = Flatten;
403 }
404
405 void dump() const;
406};
407
408/// A class for recording the number of arguments that a function
409/// signature requires.
410class RequiredArgs {
411 /// The number of required arguments, or ~0 if the signature does
412 /// not permit optional arguments.
413 unsigned NumRequired;
414public:
415 enum All_t { All };
416
417 RequiredArgs(All_t _) : NumRequired(~0U) {}
418 explicit RequiredArgs(unsigned n) : NumRequired(n) {
419 assert(n != ~0U)((n != ~0U) ? static_cast<void> (0) : __assert_fail ("n != ~0U"
, "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 419, __PRETTY_FUNCTION__))
;
420 }
421
422 /// Compute the arguments required by the given formal prototype,
423 /// given that there may be some additional, non-formal arguments
424 /// in play.
425 ///
426 /// If FD is not null, this will consider pass_object_size params in FD.
427 static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
428 unsigned additional) {
429 if (!prototype->isVariadic()) return All;
52
Called C++ object pointer is null
430
431 if (prototype->hasExtParameterInfos())
432 additional += llvm::count_if(
433 prototype->getExtParameterInfos(),
434 [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
435 return ExtInfo.hasPassObjectSize();
436 });
437
438 return RequiredArgs(prototype->getNumParams() + additional);
439 }
440
441 static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
442 unsigned additional) {
443 return forPrototypePlus(prototype.getTypePtr(), additional);
444 }
445
446 static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
447 return forPrototypePlus(prototype, 0);
448 }
449
450 static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
451 return forPrototypePlus(prototype.getTypePtr(), 0);
452 }
453
454 bool allowsOptionalArgs() const { return NumRequired != ~0U; }
39
Assuming the condition is false
40
Returning zero, which participates in a condition later
455 unsigned getNumRequiredArgs() const {
456 assert(allowsOptionalArgs())((allowsOptionalArgs()) ? static_cast<void> (0) : __assert_fail
("allowsOptionalArgs()", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 456, __PRETTY_FUNCTION__))
;
457 return NumRequired;
458 }
459
460 unsigned getOpaqueData() const { return NumRequired; }
461 static RequiredArgs getFromOpaqueData(unsigned value) {
462 if (value == ~0U) return All;
463 return RequiredArgs(value);
464 }
465};
466
467// Implementation detail of CGFunctionInfo, factored out so it can be named
468// in the TrailingObjects base class of CGFunctionInfo.
469struct CGFunctionInfoArgInfo {
470 CanQualType type;
471 ABIArgInfo info;
472};
473
474/// CGFunctionInfo - Class to encapsulate the information about a
475/// function definition.
476class CGFunctionInfo final
477 : public llvm::FoldingSetNode,
478 private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
479 FunctionProtoType::ExtParameterInfo> {
480 typedef CGFunctionInfoArgInfo ArgInfo;
481 typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo;
482
483 /// The LLVM::CallingConv to use for this function (as specified by the
484 /// user).
485 unsigned CallingConvention : 8;
486
487 /// The LLVM::CallingConv to actually use for this function, which may
488 /// depend on the ABI.
489 unsigned EffectiveCallingConvention : 8;
490
491 /// The clang::CallingConv that this was originally created with.
492 unsigned ASTCallingConvention : 6;
493
494 /// Whether this is an instance method.
495 unsigned InstanceMethod : 1;
496
497 /// Whether this is a chain call.
498 unsigned ChainCall : 1;
499
500 /// Whether this function is noreturn.
501 unsigned NoReturn : 1;
502
503 /// Whether this function is returns-retained.
504 unsigned ReturnsRetained : 1;
505
506 /// Whether this function saved caller registers.
507 unsigned NoCallerSavedRegs : 1;
508
509 /// How many arguments to pass inreg.
510 unsigned HasRegParm : 1;
511 unsigned RegParm : 3;
512
513 /// Whether this function has nocf_check attribute.
514 unsigned NoCfCheck : 1;
515
516 RequiredArgs Required;
517
518 /// The struct representing all arguments passed in memory. Only used when
519 /// passing non-trivial types with inalloca. Not part of the profile.
520 llvm::StructType *ArgStruct;
521 unsigned ArgStructAlign : 31;
522 unsigned HasExtParameterInfos : 1;
523
524 unsigned NumArgs;
525
526 ArgInfo *getArgsBuffer() {
527 return getTrailingObjects<ArgInfo>();
528 }
529 const ArgInfo *getArgsBuffer() const {
530 return getTrailingObjects<ArgInfo>();
531 }
532
533 ExtParameterInfo *getExtParameterInfosBuffer() {
534 return getTrailingObjects<ExtParameterInfo>();
535 }
536 const ExtParameterInfo *getExtParameterInfosBuffer() const{
537 return getTrailingObjects<ExtParameterInfo>();
538 }
539
540 CGFunctionInfo() : Required(RequiredArgs::All) {}
541
542public:
543 static CGFunctionInfo *create(unsigned llvmCC,
544 bool instanceMethod,
545 bool chainCall,
546 const FunctionType::ExtInfo &extInfo,
547 ArrayRef<ExtParameterInfo> paramInfos,
548 CanQualType resultType,
549 ArrayRef<CanQualType> argTypes,
550 RequiredArgs required);
551 void operator delete(void *p) { ::operator delete(p); }
552
553 // Friending class TrailingObjects is apparently not good enough for MSVC,
554 // so these have to be public.
555 friend class TrailingObjects;
556 size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
557 return NumArgs + 1;
558 }
559 size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
560 return (HasExtParameterInfos ? NumArgs : 0);
561 }
562
563 typedef const ArgInfo *const_arg_iterator;
564 typedef ArgInfo *arg_iterator;
565
566 typedef llvm::iterator_range<arg_iterator> arg_range;
567 typedef llvm::iterator_range<const_arg_iterator> const_arg_range;
568
569 arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
570 const_arg_range arguments() const {
571 return const_arg_range(arg_begin(), arg_end());
572 }
573
574 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
575 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
576 arg_iterator arg_begin() { return getArgsBuffer() + 1; }
577 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
578
579 unsigned arg_size() const { return NumArgs; }
580
581 bool isVariadic() const { return Required.allowsOptionalArgs(); }
38
Calling 'RequiredArgs::allowsOptionalArgs'
41
Returning from 'RequiredArgs::allowsOptionalArgs'
42
Returning zero, which participates in a condition later
582 RequiredArgs getRequiredArgs() const { return Required; }
583 unsigned getNumRequiredArgs() const {
584 return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
585 }
586
587 bool isInstanceMethod() const { return InstanceMethod; }
588
589 bool isChainCall() const { return ChainCall; }
590
591 bool isNoReturn() const { return NoReturn; }
592
593 /// In ARC, whether this function retains its return value. This
594 /// is not always reliable for call sites.
595 bool isReturnsRetained() const { return ReturnsRetained; }
596
597 /// Whether this function no longer saves caller registers.
598 bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
599
600 /// Whether this function has nocf_check attribute.
601 bool isNoCfCheck() const { return NoCfCheck; }
602
603 /// getASTCallingConvention() - Return the AST-specified calling
604 /// convention.
605 CallingConv getASTCallingConvention() const {
606 return CallingConv(ASTCallingConvention);
607 }
608
609 /// getCallingConvention - Return the user specified calling
610 /// convention, which has been translated into an LLVM CC.
611 unsigned getCallingConvention() const { return CallingConvention; }
612
613 /// getEffectiveCallingConvention - Return the actual calling convention to
614 /// use, which may depend on the ABI.
615 unsigned getEffectiveCallingConvention() const {
616 return EffectiveCallingConvention;
617 }
618 void setEffectiveCallingConvention(unsigned Value) {
619 EffectiveCallingConvention = Value;
620 }
621
622 bool getHasRegParm() const { return HasRegParm; }
623 unsigned getRegParm() const { return RegParm; }
624
625 FunctionType::ExtInfo getExtInfo() const {
626 return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
627 getASTCallingConvention(), isReturnsRetained(),
628 isNoCallerSavedRegs(), isNoCfCheck());
629 }
630
631 CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
632
633 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
634 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
635
636 ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
637 if (!HasExtParameterInfos) return {};
638 return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
639 }
640 ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
641 assert(argIndex <= NumArgs)((argIndex <= NumArgs) ? static_cast<void> (0) : __assert_fail
("argIndex <= NumArgs", "/build/llvm-toolchain-snapshot-10~++20200110111110+a1cc19b5814/clang/include/clang/CodeGen/CGFunctionInfo.h"
, 641, __PRETTY_FUNCTION__))
;
642 if (!HasExtParameterInfos) return ExtParameterInfo();
643 return getExtParameterInfos()[argIndex];
644 }
645
646 /// Return true if this function uses inalloca arguments.
647 bool usesInAlloca() const { return ArgStruct; }
648
649 /// Get the struct type used to represent all the arguments in memory.
650 llvm::StructType *getArgStruct() const { return ArgStruct; }
651 CharUnits getArgStructAlignment() const {
652 return CharUnits::fromQuantity(ArgStructAlign);
653 }
654 void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
655 ArgStruct = Ty;
656 ArgStructAlign = Align.getQuantity();
657 }
658
659 void Profile(llvm::FoldingSetNodeID &ID) {
660 ID.AddInteger(getASTCallingConvention());
661 ID.AddBoolean(InstanceMethod);
662 ID.AddBoolean(ChainCall);
663 ID.AddBoolean(NoReturn);
664 ID.AddBoolean(ReturnsRetained);
665 ID.AddBoolean(NoCallerSavedRegs);
666 ID.AddBoolean(HasRegParm);
667 ID.AddInteger(RegParm);
668 ID.AddBoolean(NoCfCheck);
669 ID.AddInteger(Required.getOpaqueData());
670 ID.AddBoolean(HasExtParameterInfos);
671 if (HasExtParameterInfos) {
672 for (auto paramInfo : getExtParameterInfos())
673 ID.AddInteger(paramInfo.getOpaqueValue());
674 }
675 getReturnType().Profile(ID);
676 for (const auto &I : arguments())
677 I.type.Profile(ID);
678 }
679 static void Profile(llvm::FoldingSetNodeID &ID,
680 bool InstanceMethod,
681 bool ChainCall,
682 const FunctionType::ExtInfo &info,
683 ArrayRef<ExtParameterInfo> paramInfos,
684 RequiredArgs required,
685 CanQualType resultType,
686 ArrayRef<CanQualType> argTypes) {
687 ID.AddInteger(info.getCC());
688 ID.AddBoolean(InstanceMethod);
689 ID.AddBoolean(ChainCall);
690 ID.AddBoolean(info.getNoReturn());
691 ID.AddBoolean(info.getProducesResult());
692 ID.AddBoolean(info.getNoCallerSavedRegs());
693 ID.AddBoolean(info.getHasRegParm());
694 ID.AddInteger(info.getRegParm());
695 ID.AddBoolean(info.getNoCfCheck());
696 ID.AddInteger(required.getOpaqueData());
697 ID.AddBoolean(!paramInfos.empty());
698 if (!paramInfos.empty()) {
699 for (auto paramInfo : paramInfos)
700 ID.AddInteger(paramInfo.getOpaqueValue());
701 }
702 resultType.Profile(ID);
703 for (ArrayRef<CanQualType>::iterator
704 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
705 i->Profile(ID);
706 }
707 }
708};
709
710} // end namespace CodeGen
711} // end namespace clang
712
713#endif