//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===//
//
//                     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 C++ code generation of temporaries
//
//===----------------------------------------------------------------------===//

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

void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
                                       llvm::Value *Ptr) {
  llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");

  llvm::Value *CondPtr = 0;

  // Check if temporaries need to be conditional. If so, we'll create a
  // condition boolean, initialize it to 0 and
  if (!ConditionalTempDestructionStack.empty()) {
    CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");

    // Initialize it to false. This initialization takes place right after
    // the alloca insert point.
    llvm::StoreInst *SI =
      new llvm::StoreInst(llvm::ConstantInt::getFalse(VMContext), CondPtr);
    llvm::BasicBlock *Block = AllocaInsertPt->getParent();
    Block->getInstList().insertAfter((llvm::Instruction *)AllocaInsertPt, SI);

    // Now set it to true.
    Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
  }

  LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock,
                                                 CondPtr));

  PushCleanupBlock(DtorBlock);
}

void CodeGenFunction::PopCXXTemporary() {
  const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();

  CleanupBlockInfo CleanupInfo = PopCleanupBlock();
  assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
         "Cleanup block mismatch!");
  assert(!CleanupInfo.SwitchBlock &&
         "Should not have a switch block for temporary cleanup!");
  assert(!CleanupInfo.EndBlock &&
         "Should not have an end block for temporary cleanup!");

  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
  if (CurBB && !CurBB->getTerminator() &&
      Info.DtorBlock->getNumUses() == 0) {
    CurBB->getInstList().splice(CurBB->end(), Info.DtorBlock->getInstList());
    delete Info.DtorBlock;
  } else
    EmitBlock(Info.DtorBlock);

  llvm::BasicBlock *CondEnd = 0;

  // If this is a conditional temporary, we need to check the condition
  // boolean and only call the destructor if it's true.
  if (Info.CondPtr) {
    llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
    CondEnd = createBasicBlock("cond.dtor.end");

    llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
    Builder.CreateCondBr(Cond, CondBlock, CondEnd);
    EmitBlock(CondBlock);
  }

  EmitCXXDestructorCall(Info.Temporary->getDestructor(),
                        Dtor_Complete, Info.ThisPtr);

  if (CondEnd) {
    // Reset the condition. to false.
    Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
    EmitBlock(CondEnd);
  }

  LiveTemporaries.pop_back();
}

RValue
CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
                                            llvm::Value *AggLoc,
                                            bool IsAggLocVolatile,
                                            bool IsInitializer) {
  // If we shouldn't destroy the temporaries, just emit the
  // child expression.
  if (!E->shouldDestroyTemporaries())
    return EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
                       /*IgnoreResult=*/false, IsInitializer);

  // Keep track of the current cleanup stack depth.
  size_t CleanupStackDepth = CleanupEntries.size();
  (void) CleanupStackDepth;

  unsigned OldNumLiveTemporaries = LiveTemporaries.size();

  RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
                          /*IgnoreResult=*/false, IsInitializer);

  // Pop temporaries.
  while (LiveTemporaries.size() > OldNumLiveTemporaries)
    PopCXXTemporary();

  assert(CleanupEntries.size() == CleanupStackDepth &&
         "Cleanup size mismatch!");

  return RV;
}

LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
                                              const CXXExprWithTemporaries *E) {
  // If we shouldn't destroy the temporaries, just emit the
  // child expression.
  if (!E->shouldDestroyTemporaries())
    return EmitLValue(E->getSubExpr());
  
  // Keep track of the current cleanup stack depth.
  size_t CleanupStackDepth = CleanupEntries.size();
  (void) CleanupStackDepth;

  unsigned OldNumLiveTemporaries = LiveTemporaries.size();

  LValue LV = EmitLValue(E->getSubExpr());

  // Pop temporaries.
  while (LiveTemporaries.size() > OldNumLiveTemporaries)
    PopCXXTemporary();

  assert(CleanupEntries.size() == CleanupStackDepth &&
         "Cleanup size mismatch!");

  return LV;
}

void
CodeGenFunction::PushConditionalTempDestruction() {
  // Store the current number of live temporaries.
  ConditionalTempDestructionStack.push_back(LiveTemporaries.size());
}

void CodeGenFunction::PopConditionalTempDestruction() {
 size_t NumLiveTemporaries = ConditionalTempDestructionStack.back();
 ConditionalTempDestructionStack.pop_back();

  // Pop temporaries.
  while (LiveTemporaries.size() > NumLiveTemporaries) {
    assert(LiveTemporaries.back().CondPtr &&
           "Conditional temporary must have a cond ptr!");

    PopCXXTemporary();
  }
}

