//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with code generation of C++ declarations
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
using namespace clang;
using namespace CodeGen;

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);
  }
}

void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
                                               llvm::Constant *DeclPtr) {

  const Expr *Init = D.getInit();
  QualType T = D.getType();

  if (!T->isReferenceType()) {
    EmitDeclInit(*this, D, DeclPtr);
    return;
  }
  if (Init->isLvalue(getContext()) == Expr::LV_Valid) {
    RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true);
    EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T);
    return;
  }
  ErrorUnsupported(Init, 
                   "global variable that binds reference to a non-lvalue");
}

void
CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
                                               llvm::Constant *DeclPtr) {
  const llvm::Type *Int8PtrTy = 
    llvm::Type::getInt8Ty(VMContext)->getPointerTo();

  std::vector<const llvm::Type *> Params;
  Params.push_back(Int8PtrTy);

  // Get the destructor function type
  const llvm::Type *DtorFnTy =
    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
  DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy);

  Params.clear();
  Params.push_back(DtorFnTy);
  Params.push_back(Int8PtrTy);
  Params.push_back(Int8PtrTy);

  // Get the __cxa_atexit function type
  // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
  const llvm::FunctionType *AtExitFnTy =
    llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false);

  llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy,
                                                       "__cxa_atexit");

  llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy,
                                                     "__dso_handle");
  llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy),
                           llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy),
                           llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) };
  Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args));
}

void
CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
  const llvm::FunctionType *FTy
    = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
                              false);

  // Create a variable initialization function.
  llvm::Function *Fn =
    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
                           "__cxx_global_var_init", &TheModule);

  CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);

  CXXGlobalInits.push_back(Fn);
}

void
CodeGenModule::EmitCXXGlobalInitFunc() {
  if (CXXGlobalInits.empty())
    return;

  const llvm::FunctionType *FTy
    = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
                              false);

  // Create our global initialization function.
  // FIXME: Should this be tweakable by targets?
  llvm::Function *Fn =
    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
                           "__cxx_global_initialization", &TheModule);

  CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
                                                   &CXXGlobalInits[0],
                                                   CXXGlobalInits.size());
  AddGlobalCtor(Fn);
}

void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
                                                       const VarDecl *D) {
  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
                SourceLocation());

  llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
  EmitCXXGlobalVarDeclInit(*D, DeclPtr);

  FinishFunction();
}

void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
                                                llvm::Constant **Decls,
                                                unsigned NumDecls) {
  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
                SourceLocation());

  for (unsigned i = 0; i != NumDecls; ++i)
    Builder.CreateCall(Decls[i]);

  FinishFunction();
}

static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) {
  // int __cxa_guard_acquire(__int64_t *guard_object);
  
  const llvm::Type *Int64PtrTy = 
    llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
  
  std::vector<const llvm::Type*> Args(1, Int64PtrTy);
  
  const llvm::FunctionType *FTy =
    llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy),
                            Args, /*isVarArg=*/false);
  
  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
}

static llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) {
  // void __cxa_guard_release(__int64_t *guard_object);
  
  const llvm::Type *Int64PtrTy = 
    llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
  
  std::vector<const llvm::Type*> Args(1, Int64PtrTy);
  
  const llvm::FunctionType *FTy =
  llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
                          Args, /*isVarArg=*/false);
  
  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
}

static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) {
  // void __cxa_guard_abort(__int64_t *guard_object);
  
  const llvm::Type *Int64PtrTy = 
    llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
  
  std::vector<const llvm::Type*> Args(1, Int64PtrTy);
  
  const llvm::FunctionType *FTy =
  llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
                          Args, /*isVarArg=*/false);
  
  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
}

void
CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
                                               llvm::GlobalVariable *GV) {
  bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics;
  
  llvm::SmallString<256> GuardVName;
  CGM.getMangleContext().mangleGuardVariable(&D, GuardVName);

  // Create the guard variable.
  const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(VMContext);
  llvm::GlobalValue *GuardVariable =
    new llvm::GlobalVariable(CGM.getModule(), Int64Ty,
                             false, GV->getLinkage(),
                             llvm::Constant::getNullValue(Int64Ty),
                             GuardVName.str());

  // Load the first byte of the guard variable.
  const llvm::Type *PtrTy
    = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
  llvm::Value *V = 
    Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp");

  llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check");
  llvm::BasicBlock *EndBlock = createBasicBlock("init.end");

  // Check if the first byte of the guard variable is zero.
  Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"), 
                       InitCheckBlock, EndBlock);

  EmitBlock(InitCheckBlock);

  if (ThreadsafeStatics) {
    // Call __cxa_guard_acquire.
    V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable);
               
    llvm::BasicBlock *InitBlock = createBasicBlock("init");
  
    Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
                         InitBlock, EndBlock);
  
    EmitBlock(InitBlock);

    if (Exceptions) {
      EHCleanupBlock Cleanup(*this);
    
      // Call __cxa_guard_abort.
      Builder.CreateCall(getGuardAbortFn(*this), GuardVariable);
    }
  }

  if (D.getType()->isReferenceType()) {
    QualType T = D.getType();
    // We don't want to pass true for IsInitializer here, because a static
    // reference to a temporary does not extend its lifetime.
    RValue RV = EmitReferenceBindingToExpr(D.getInit(),
                                           /*IsInitializer=*/false);
    EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T);

  } else
    EmitDeclInit(*this, D, GV);

  if (ThreadsafeStatics) {
    // Call __cxa_guard_release.
    Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable);
  } else {
    llvm::Value *One = 
      llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1);
    Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
  }

  EmitBlock(EndBlock);
}
