Exemple #1
0
static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
                         llvm::Constant *DeclPtr) {
  assert(D.hasGlobalStorage() && "VarDecl must have global storage!");
  assert(!D.getType()->isReferenceType() && 
         "Should not call EmitDeclInit on a reference!");
  
  CodeGenModule &CGM = CGF.CGM;
  ASTContext &Context = CGF.getContext();
    
  const Expr *Init = D.getInit();
  QualType T = D.getType();
  bool isVolatile = Context.getCanonicalType(T).isVolatileQualified();

  if (!CGF.hasAggregateLLVMType(T)) {
    llvm::Value *V = CGF.EmitScalarExpr(Init);
    CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
  } else if (T->isAnyComplexType()) {
    CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
  } else {
    CGF.EmitAggExpr(Init, DeclPtr, isVolatile);
    
    // Avoid generating destructor(s) for initialized objects. 
    if (!isa<CXXConstructExpr>(Init))
      return;
    
    const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
    if (Array)
      T = Context.getBaseElementType(Array);
    
    const RecordType *RT = T->getAs<RecordType>();
    if (!RT)
      return;
    
    CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
    if (RD->hasTrivialDestructor())
      return;
    
    CXXDestructorDecl *Dtor = RD->getDestructor(Context);
    
    llvm::Constant *DtorFn;
    if (Array) {
      DtorFn = 
        CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, 
                                                             Array, 
                                                             DeclPtr);
      const llvm::Type *Int8PtrTy =
        llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
      DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
     } else
      DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);

    CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
  }
}
Exemple #2
0
static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
                            llvm::Constant *DeclPtr) {
  CodeGenModule &CGM = CGF.CGM;
  ASTContext &Context = CGF.getContext();
  
  QualType T = D.getType();
  
  // Drill down past array types.
  const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
  if (Array)
    T = Context.getBaseElementType(Array);
  
  /// If that's not a record, we're done.
  /// FIXME:  __attribute__((cleanup)) ?
  const RecordType *RT = T->getAs<RecordType>();
  if (!RT)
    return;
  
  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
  if (RD->hasTrivialDestructor())
    return;
  
  CXXDestructorDecl *Dtor = RD->getDestructor();
  
  llvm::Constant *DtorFn;
  if (Array) {
    DtorFn = 
      CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array, 
                                                           DeclPtr);
    const llvm::Type *Int8PtrTy =
      llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
    DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
  } else
    DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
  
  CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
}