1 //===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This contains code dealing with code generation of C++ declarations
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "CodeGenFunction.h"
15 #include "clang/Frontend/CodeGenOptions.h"
16 #include "llvm/Intrinsics.h"
17 
18 using namespace clang;
19 using namespace CodeGen;
20 
21 static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
22                          llvm::Constant *DeclPtr) {
23   assert(D.hasGlobalStorage() && "VarDecl must have global storage!");
24   assert(!D.getType()->isReferenceType() &&
25          "Should not call EmitDeclInit on a reference!");
26 
27   ASTContext &Context = CGF.getContext();
28 
29   const Expr *Init = D.getInit();
30   QualType T = D.getType();
31   bool isVolatile = Context.getCanonicalType(T).isVolatileQualified();
32 
33   if (!CGF.hasAggregateLLVMType(T)) {
34     llvm::Value *V = CGF.EmitScalarExpr(Init);
35     CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
36   } else if (T->isAnyComplexType()) {
37     CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
38   } else {
39     CGF.EmitAggExpr(Init, DeclPtr, isVolatile);
40   }
41 }
42 
43 static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
44                             llvm::Constant *DeclPtr) {
45   CodeGenModule &CGM = CGF.CGM;
46   ASTContext &Context = CGF.getContext();
47 
48   const Expr *Init = D.getInit();
49   QualType T = D.getType();
50   if (!CGF.hasAggregateLLVMType(T) || T->isAnyComplexType())
51     return;
52 
53   // Avoid generating destructor(s) for initialized objects.
54   if (!isa<CXXConstructExpr>(Init))
55     return;
56 
57   const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
58   if (Array)
59     T = Context.getBaseElementType(Array);
60 
61   const RecordType *RT = T->getAs<RecordType>();
62   if (!RT)
63     return;
64 
65   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
66   if (RD->hasTrivialDestructor())
67     return;
68 
69   CXXDestructorDecl *Dtor = RD->getDestructor();
70 
71   llvm::Constant *DtorFn;
72   if (Array) {
73     DtorFn =
74       CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array,
75                                                            DeclPtr);
76     const llvm::Type *Int8PtrTy =
77       llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
78     DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
79   } else
80     DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
81 
82   CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
83 }
84 
85 void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
86                                                llvm::Constant *DeclPtr) {
87 
88   const Expr *Init = D.getInit();
89   QualType T = D.getType();
90 
91   if (!T->isReferenceType()) {
92     EmitDeclInit(*this, D, DeclPtr);
93     EmitDeclDestroy(*this, D, DeclPtr);
94     return;
95   }
96 
97   RValue RV = EmitReferenceBindingToExpr(Init, &D);
98   EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T);
99 }
100 
101 void
102 CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
103                                                llvm::Constant *DeclPtr) {
104   // Generate a global destructor entry if not using __cxa_atexit.
105   if (!CGM.getCodeGenOpts().CXAAtExit) {
106     CGM.AddCXXDtorEntry(DtorFn, DeclPtr);
107     return;
108   }
109 
110   const llvm::Type *Int8PtrTy =
111     llvm::Type::getInt8Ty(VMContext)->getPointerTo();
112 
113   std::vector<const llvm::Type *> Params;
114   Params.push_back(Int8PtrTy);
115 
116   // Get the destructor function type
117   const llvm::Type *DtorFnTy =
118     llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
119   DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy);
120 
121   Params.clear();
122   Params.push_back(DtorFnTy);
123   Params.push_back(Int8PtrTy);
124   Params.push_back(Int8PtrTy);
125 
126   // Get the __cxa_atexit function type
127   // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
128   const llvm::FunctionType *AtExitFnTy =
129     llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false);
130 
131   llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy,
132                                                        "__cxa_atexit");
133 
134   llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy,
135                                                      "__dso_handle");
136   llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy),
137                            llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy),
138                            llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) };
139   Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args));
140 }
141 
142 static llvm::Function *
143 CreateGlobalInitOrDestructFunction(CodeGenModule &CGM,
144                                    const llvm::FunctionType *FTy,
145                                    llvm::StringRef Name) {
146   llvm::Function *Fn =
147     llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
148                            Name, &CGM.getModule());
149 
150   // Set the section if needed.
151   if (const char *Section =
152         CGM.getContext().Target.getStaticInitSectionSpecifier())
153     Fn->setSection(Section);
154 
155   if (!CGM.getLangOptions().Exceptions)
156     Fn->setDoesNotThrow();
157 
158   return Fn;
159 }
160 
161 void
162 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
163   const llvm::FunctionType *FTy
164     = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
165                               false);
166 
167   // Create a variable initialization function.
168   llvm::Function *Fn =
169     CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init");
170 
171   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);
172 
173   if (D->hasAttr<InitPriorityAttr>()) {
174     unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority();
175     OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size());
176     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
177   }
178   else
179     CXXGlobalInits.push_back(Fn);
180 }
181 
182 void
183 CodeGenModule::EmitCXXGlobalInitFunc() {
184   if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
185     return;
186 
187   const llvm::FunctionType *FTy
188     = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
189                               false);
190 
191   // Create our global initialization function.
192   llvm::Function *Fn =
193     CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a");
194 
195   if (!PrioritizedCXXGlobalInits.empty()) {
196     llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits;
197     llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
198                          PrioritizedCXXGlobalInits.end());
199     for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) {
200       llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second;
201       LocalCXXGlobalInits.push_back(Fn);
202     }
203     for (unsigned i = 0; i < CXXGlobalInits.size(); i++)
204       LocalCXXGlobalInits.push_back(CXXGlobalInits[i]);
205     CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
206                                                     &LocalCXXGlobalInits[0],
207                                                     LocalCXXGlobalInits.size());
208   }
209   else
210     CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
211                                                      &CXXGlobalInits[0],
212                                                      CXXGlobalInits.size());
213   AddGlobalCtor(Fn);
214 }
215 
216 void CodeGenModule::EmitCXXGlobalDtorFunc() {
217   if (CXXGlobalDtors.empty())
218     return;
219 
220   const llvm::FunctionType *FTy
221     = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
222                               false);
223 
224   // Create our global destructor function.
225   llvm::Function *Fn =
226     CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a");
227 
228   CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors);
229   AddGlobalDtor(Fn);
230 }
231 
232 void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
233                                                        const VarDecl *D) {
234   StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
235                 SourceLocation());
236 
237   llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
238   EmitCXXGlobalVarDeclInit(*D, DeclPtr);
239 
240   FinishFunction();
241 }
242 
243 void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
244                                                 llvm::Constant **Decls,
245                                                 unsigned NumDecls) {
246   StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
247                 SourceLocation());
248 
249   for (unsigned i = 0; i != NumDecls; ++i)
250     Builder.CreateCall(Decls[i]);
251 
252   FinishFunction();
253 }
254 
255 void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
256                   const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
257                                                 &DtorsAndObjects) {
258   StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
259                 SourceLocation());
260 
261   // Emit the dtors, in reverse order from construction.
262   for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
263     llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
264     llvm::CallInst *CI = Builder.CreateCall(Callee,
265                                             DtorsAndObjects[e - i - 1].second);
266     // Make sure the call and the callee agree on calling convention.
267     if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
268       CI->setCallingConv(F->getCallingConv());
269   }
270 
271   FinishFunction();
272 }
273 
274 static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) {
275   // int __cxa_guard_acquire(__int64_t *guard_object);
276 
277   const llvm::Type *Int64PtrTy =
278     llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
279 
280   std::vector<const llvm::Type*> Args(1, Int64PtrTy);
281 
282   const llvm::FunctionType *FTy =
283     llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy),
284                             Args, /*isVarArg=*/false);
285 
286   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
287 }
288 
289 static llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) {
290   // void __cxa_guard_release(__int64_t *guard_object);
291 
292   const llvm::Type *Int64PtrTy =
293     llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
294 
295   std::vector<const llvm::Type*> Args(1, Int64PtrTy);
296 
297   const llvm::FunctionType *FTy =
298   llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
299                           Args, /*isVarArg=*/false);
300 
301   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
302 }
303 
304 static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) {
305   // void __cxa_guard_abort(__int64_t *guard_object);
306 
307   const llvm::Type *Int64PtrTy =
308     llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
309 
310   std::vector<const llvm::Type*> Args(1, Int64PtrTy);
311 
312   const llvm::FunctionType *FTy =
313   llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
314                           Args, /*isVarArg=*/false);
315 
316   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
317 }
318 
319 void
320 CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
321                                                llvm::GlobalVariable *GV) {
322   // Bail out early if this initializer isn't reachable.
323   if (!Builder.GetInsertBlock()) return;
324 
325   bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics;
326 
327   llvm::SmallString<256> GuardVName;
328   CGM.getMangleContext().mangleGuardVariable(&D, GuardVName);
329 
330   // Create the guard variable.
331   llvm::GlobalValue *GuardVariable =
332     new llvm::GlobalVariable(CGM.getModule(), Int64Ty,
333                              false, GV->getLinkage(),
334                              llvm::Constant::getNullValue(Int64Ty),
335                              GuardVName.str());
336 
337   // Load the first byte of the guard variable.
338   const llvm::Type *PtrTy
339     = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
340   llvm::Value *V =
341     Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp");
342 
343   llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check");
344   llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
345 
346   // Check if the first byte of the guard variable is zero.
347   Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"),
348                        InitCheckBlock, EndBlock);
349 
350   EmitBlock(InitCheckBlock);
351 
352   // Variables used when coping with thread-safe statics and exceptions.
353   if (ThreadsafeStatics) {
354     // Call __cxa_guard_acquire.
355     V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable);
356 
357     llvm::BasicBlock *InitBlock = createBasicBlock("init");
358 
359     Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
360                          InitBlock, EndBlock);
361 
362     // Call __cxa_guard_abort along the exceptional edge.
363     if (Exceptions) {
364       CleanupBlock Cleanup(*this, EHCleanup);
365       Builder.CreateCall(getGuardAbortFn(*this), GuardVariable);
366     }
367 
368     EmitBlock(InitBlock);
369   }
370 
371   if (D.getType()->isReferenceType()) {
372     QualType T = D.getType();
373     RValue RV = EmitReferenceBindingToExpr(D.getInit(), &D);
374     EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T);
375 
376   } else
377     EmitDeclInit(*this, D, GV);
378 
379   if (ThreadsafeStatics) {
380     // Call __cxa_guard_release.  This cannot throw.
381     Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable);
382   } else {
383     llvm::Value *One =
384       llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1);
385     Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
386   }
387 
388   // Register the call to the destructor.
389   if (!D.getType()->isReferenceType())
390     EmitDeclDestroy(*this, D, GV);
391 
392   EmitBlock(EndBlock);
393 }
394 
395 /// GenerateCXXAggrDestructorHelper - Generates a helper function which when
396 /// invoked, calls the default destructor on array elements in reverse order of
397 /// construction.
398 llvm::Function *
399 CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
400                                                  const ArrayType *Array,
401                                                  llvm::Value *This) {
402   FunctionArgList Args;
403   ImplicitParamDecl *Dst =
404     ImplicitParamDecl::Create(getContext(), 0,
405                               SourceLocation(), 0,
406                               getContext().getPointerType(getContext().VoidTy));
407   Args.push_back(std::make_pair(Dst, Dst->getType()));
408 
409   const CGFunctionInfo &FI =
410     CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args,
411                                    FunctionType::ExtInfo());
412   const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
413   llvm::Function *Fn =
414     CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
415 
416   StartFunction(GlobalDecl(), getContext().VoidTy, Fn, Args, SourceLocation());
417 
418   QualType BaseElementTy = getContext().getBaseElementType(Array);
419   const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo();
420   llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
421 
422   EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
423 
424   FinishFunction();
425 
426   return Fn;
427 }
428