Bug Summary

File:tools/clang/include/clang/CodeGen/CGFunctionInfo.h
Warning:line 430, 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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -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~svn374814/build-llvm/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-10~svn374814/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include -I /build/llvm-toolchain-snapshot-10~svn374814/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-10~svn374814/build-llvm/include -I /build/llvm-toolchain-snapshot-10~svn374814/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~svn374814/build-llvm/tools/clang/lib/CodeGen -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~svn374814=. -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-2019-10-15-035155-28452-1 -x c++ /build/llvm-toolchain-snapshot-10~svn374814/tools/clang/lib/CodeGen/CGVTables.cpp

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

/build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include/clang/Basic/TargetCXXABI.h

1//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// Defines the TargetCXXABI class, which abstracts details of the
11/// C++ ABI that we're targeting.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
16#define LLVM_CLANG_BASIC_TARGETCXXABI_H
17
18#include "llvm/Support/ErrorHandling.h"
19
20namespace clang {
21
22/// The basic abstraction for the target C++ ABI.
23class TargetCXXABI {
24public:
25 /// The basic C++ ABI kind.
26 enum Kind {
27 /// The generic Itanium ABI is the standard ABI of most open-source
28 /// and Unix-like platforms. It is the primary ABI targeted by
29 /// many compilers, including Clang and GCC.
30 ///
31 /// It is documented here:
32 /// http://www.codesourcery.com/public/cxx-abi/
33 GenericItanium,
34
35 /// The generic ARM ABI is a modified version of the Itanium ABI
36 /// proposed by ARM for use on ARM-based platforms.
37 ///
38 /// These changes include:
39 /// - the representation of member function pointers is adjusted
40 /// to not conflict with the 'thumb' bit of ARM function pointers;
41 /// - constructors and destructors return 'this';
42 /// - guard variables are smaller;
43 /// - inline functions are never key functions;
44 /// - array cookies have a slightly different layout;
45 /// - additional convenience functions are specified;
46 /// - and more!
47 ///
48 /// It is documented here:
49 /// http://infocenter.arm.com
50 /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
51 GenericARM,
52
53 /// The iOS ABI is a partial implementation of the ARM ABI.
54 /// Several of the features of the ARM ABI were not fully implemented
55 /// in the compilers that iOS was launched with.
56 ///
57 /// Essentially, the iOS ABI includes the ARM changes to:
58 /// - member function pointers,
59 /// - guard variables,
60 /// - array cookies, and
61 /// - constructor/destructor signatures.
62 iOS,
63
64 /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
65 /// closely, but we don't guarantee to follow it perfectly.
66 ///
67 /// It is documented here:
68 /// http://infocenter.arm.com
69 /// /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
70 iOS64,
71
72 /// WatchOS is a modernisation of the iOS ABI, which roughly means it's
73 /// the iOS64 ABI ported to 32-bits. The primary difference from iOS64 is
74 /// that RTTI objects must still be unique at the moment.
75 WatchOS,
76
77 /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
78 /// but it has fewer divergences than the 32-bit ARM ABI.
79 ///
80 /// The relevant changes from the generic ABI in this case are:
81 /// - representation of member function pointers adjusted as in ARM.
82 /// - guard variables are smaller.
83 GenericAArch64,
84
85 /// The generic Mips ABI is a modified version of the Itanium ABI.
86 ///
87 /// At the moment, only change from the generic ABI in this case is:
88 /// - representation of member function pointers adjusted as in ARM.
89 GenericMIPS,
90
91 /// The WebAssembly ABI is a modified version of the Itanium ABI.
92 ///
93 /// The changes from the Itanium ABI are:
94 /// - representation of member function pointers is adjusted, as in ARM;
95 /// - member functions are not specially aligned;
96 /// - constructors and destructors return 'this', as in ARM;
97 /// - guard variables are 32-bit on wasm32, as in ARM;
98 /// - unused bits of guard variables are reserved, as in ARM;
99 /// - inline functions are never key functions, as in ARM;
100 /// - C++11 POD rules are used for tail padding, as in iOS64.
101 ///
102 /// TODO: At present the WebAssembly ABI is not considered stable, so none
103 /// of these details is necessarily final yet.
104 WebAssembly,
105
106 /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
107 /// compatible compilers).
108 ///
109 /// FIXME: should this be split into Win32 and Win64 variants?
110 ///
111 /// Only scattered and incomplete official documentation exists.
112 Microsoft
113 };
114
115private:
116 // Right now, this class is passed around as a cheap value type.
117 // If you add more members, especially non-POD members, please
118 // audit the users to pass it by reference instead.
119 Kind TheKind;
120
121public:
122 /// A bogus initialization of the platform ABI.
123 TargetCXXABI() : TheKind(GenericItanium) {}
124
125 TargetCXXABI(Kind kind) : TheKind(kind) {}
126
127 void set(Kind kind) {
128 TheKind = kind;
129 }
130
131 Kind getKind() const { return TheKind; }
132
133 /// Does this ABI generally fall into the Itanium family of ABIs?
134 bool isItaniumFamily() const {
135 switch (getKind()) {
136 case GenericAArch64:
137 case GenericItanium:
138 case GenericARM:
139 case iOS:
140 case iOS64:
141 case WatchOS:
142 case GenericMIPS:
143 case WebAssembly:
144 return true;
145
146 case Microsoft:
147 return false;
148 }
149 llvm_unreachable("bad ABI kind")::llvm::llvm_unreachable_internal("bad ABI kind", "/build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include/clang/Basic/TargetCXXABI.h"
, 149)
;
150 }
151
152 /// Is this ABI an MSVC-compatible ABI?
153 bool isMicrosoft() const {
154 switch (getKind()) {
14
Control jumps to 'case Microsoft:' at line 165
155 case GenericAArch64:
156 case GenericItanium:
157 case GenericARM:
158 case iOS:
159 case iOS64:
160 case WatchOS:
161 case GenericMIPS:
162 case WebAssembly:
163 return false;
164
165 case Microsoft:
166 return true;
15
Returning the value 1, which participates in a condition later
167 }
168 llvm_unreachable("bad ABI kind")::llvm::llvm_unreachable_internal("bad ABI kind", "/build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include/clang/Basic/TargetCXXABI.h"
, 168)
;
169 }
170
171 /// Are member functions differently aligned?
172 ///
173 /// Many Itanium-style C++ ABIs require member functions to be aligned, so
174 /// that a pointer to such a function is guaranteed to have a zero in the
175 /// least significant bit, so that pointers to member functions can use that
176 /// bit to distinguish between virtual and non-virtual functions. However,
177 /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
178 /// functions via other means, and consequently don't require that member
179 /// functions be aligned.
180 bool areMemberFunctionsAligned() const {
181 switch (getKind()) {
182 case WebAssembly:
183 // WebAssembly doesn't require any special alignment for member functions.
184 return false;
185 case GenericARM:
186 case GenericAArch64:
187 case GenericMIPS:
188 // TODO: ARM-style pointers to member functions put the discriminator in
189 // the this adjustment, so they don't require functions to have any
190 // special alignment and could therefore also return false.
191 case GenericItanium:
192 case iOS:
193 case iOS64:
194 case WatchOS:
195 case Microsoft:
196 return true;
197 }
198 llvm_unreachable("bad ABI kind")::llvm::llvm_unreachable_internal("bad ABI kind", "/build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include/clang/Basic/TargetCXXABI.h"
, 198)
;
199 }
200
201 /// Are arguments to a call destroyed left to right in the callee?
202 /// This is a fundamental language change, since it implies that objects
203 /// passed by value do *not* live to the end of the full expression.
204 /// Temporaries passed to a function taking a const reference live to the end
205 /// of the full expression as usual. Both the caller and the callee must
206 /// have access to the destructor, while only the caller needs the
207 /// destructor if this is false.
208 bool areArgsDestroyedLeftToRightInCallee() const {
209 return isMicrosoft();
210 }
211
212 /// Does this ABI have different entrypoints for complete-object
213 /// and base-subobject constructors?
214 bool hasConstructorVariants() const {
215 return isItaniumFamily();
216 }
217
218 /// Does this ABI allow virtual bases to be primary base classes?
219 bool hasPrimaryVBases() const {
220 return isItaniumFamily();
221 }
222
223 /// Does this ABI use key functions? If so, class data such as the
224 /// vtable is emitted with strong linkage by the TU containing the key
225 /// function.
226 bool hasKeyFunctions() const {
227 return isItaniumFamily();
228 }
229
230 /// Can an out-of-line inline function serve as a key function?
231 ///
232 /// This flag is only useful in ABIs where type data (for example,
233 /// vtables and type_info objects) are emitted only after processing
234 /// the definition of a special "key" virtual function. (This is safe
235 /// because the ODR requires that every virtual function be defined
236 /// somewhere in a program.) This usually permits such data to be
237 /// emitted in only a single object file, as opposed to redundantly
238 /// in every object file that requires it.
239 ///
240 /// One simple and common definition of "key function" is the first
241 /// virtual function in the class definition which is not defined there.
242 /// This rule works very well when that function has a non-inline
243 /// definition in some non-header file. Unfortunately, when that
244 /// function is defined inline, this rule requires the type data
245 /// to be emitted weakly, as if there were no key function.
246 ///
247 /// The ARM ABI observes that the ODR provides an additional guarantee:
248 /// a virtual function is always ODR-used, so if it is defined inline,
249 /// that definition must appear in every translation unit that defines
250 /// the class. Therefore, there is no reason to allow such functions
251 /// to serve as key functions.
252 ///
253 /// Because this changes the rules for emitting type data,
254 /// it can cause type data to be emitted with both weak and strong
255 /// linkage, which is not allowed on all platforms. Therefore,
256 /// exploiting this observation requires an ABI break and cannot be
257 /// done on a generic Itanium platform.
258 bool canKeyFunctionBeInline() const {
259 switch (getKind()) {
260 case GenericARM:
261 case iOS64:
262 case WebAssembly:
263 case WatchOS:
264 return false;
265
266 case GenericAArch64:
267 case GenericItanium:
268 case iOS: // old iOS compilers did not follow this rule
269 case Microsoft:
270 case GenericMIPS:
271 return true;
272 }
273 llvm_unreachable("bad ABI kind")::llvm::llvm_unreachable_internal("bad ABI kind", "/build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include/clang/Basic/TargetCXXABI.h"
, 273)
;
274 }
275
276 /// When is record layout allowed to allocate objects in the tail
277 /// padding of a base class?
278 ///
279 /// This decision cannot be changed without breaking platform ABI
280 /// compatibility, and yet it is tied to language guarantees which
281 /// the committee has so far seen fit to strengthen no less than
282 /// three separate times:
283 /// - originally, there were no restrictions at all;
284 /// - C++98 declared that objects could not be allocated in the
285 /// tail padding of a POD type;
286 /// - C++03 extended the definition of POD to include classes
287 /// containing member pointers; and
288 /// - C++11 greatly broadened the definition of POD to include
289 /// all trivial standard-layout classes.
290 /// Each of these changes technically took several existing
291 /// platforms and made them permanently non-conformant.
292 enum TailPaddingUseRules {
293 /// The tail-padding of a base class is always theoretically
294 /// available, even if it's POD. This is not strictly conforming
295 /// in any language mode.
296 AlwaysUseTailPadding,
297
298 /// Only allocate objects in the tail padding of a base class if
299 /// the base class is not POD according to the rules of C++ TR1.
300 /// This is non-strictly conforming in C++11 mode.
301 UseTailPaddingUnlessPOD03,
302
303 /// Only allocate objects in the tail padding of a base class if
304 /// the base class is not POD according to the rules of C++11.
305 UseTailPaddingUnlessPOD11
306 };
307 TailPaddingUseRules getTailPaddingUseRules() const {
308 switch (getKind()) {
309 // To preserve binary compatibility, the generic Itanium ABI has
310 // permanently locked the definition of POD to the rules of C++ TR1,
311 // and that trickles down to derived ABIs.
312 case GenericItanium:
313 case GenericAArch64:
314 case GenericARM:
315 case iOS:
316 case GenericMIPS:
317 return UseTailPaddingUnlessPOD03;
318
319 // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor
320 // the Itanium exception about classes with over-large bitfields.
321 case iOS64:
322 case WebAssembly:
323 case WatchOS:
324 return UseTailPaddingUnlessPOD11;
325
326 // MSVC always allocates fields in the tail-padding of a base class
327 // subobject, even if they're POD.
328 case Microsoft:
329 return AlwaysUseTailPadding;
330 }
331 llvm_unreachable("bad ABI kind")::llvm::llvm_unreachable_internal("bad ABI kind", "/build/llvm-toolchain-snapshot-10~svn374814/tools/clang/include/clang/Basic/TargetCXXABI.h"
, 331)
;
332 }
333
334 friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
335 return left.getKind() == right.getKind();
336 }
337
338 friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
339 return !(left == right);
340 }
341};
342
343} // end namespace clang
344
345#endif

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