CGDeclCXX.cpp revision 5ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5b
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"
15using namespace clang;
16using namespace CodeGen;
17
18void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
19                                               llvm::Constant *DeclPtr) {
20  assert(D.hasGlobalStorage() &&
21         "VarDecl must have global storage!");
22
23  const Expr *Init = D.getInit();
24  QualType T = D.getType();
25  bool isVolatile = getContext().getCanonicalType(T).isVolatileQualified();
26
27  if (T->isReferenceType()) {
28    ErrorUnsupported(Init, "global variable that binds to a reference");
29  } else if (!hasAggregateLLVMType(T)) {
30    llvm::Value *V = EmitScalarExpr(Init);
31    EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
32  } else if (T->isAnyComplexType()) {
33    EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
34  } else {
35    EmitAggExpr(Init, DeclPtr, isVolatile);
36    // Avoid generating destructor(s) for initialized objects.
37    if (!isa<CXXConstructExpr>(Init))
38      return;
39    const ConstantArrayType *Array = getContext().getAsConstantArrayType(T);
40    if (Array)
41      T = getContext().getBaseElementType(Array);
42
43    if (const RecordType *RT = T->getAs<RecordType>()) {
44      CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
45      if (!RD->hasTrivialDestructor()) {
46        llvm::Constant *DtorFn;
47        if (Array) {
48          DtorFn = CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(
49                                                RD->getDestructor(getContext()),
50                                                Array, DeclPtr);
51          DeclPtr =
52            llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
53        }
54        else
55          DtorFn = CGM.GetAddrOfCXXDestructor(RD->getDestructor(getContext()),
56                                              Dtor_Complete);
57        EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
58      }
59    }
60  }
61}
62
63