//===--- MicrosoftVBTables.cpp - Virtual Base Table Emission --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class generates data about MSVC virtual base tables.
//
//===----------------------------------------------------------------------===//

#include "MicrosoftVBTables.h"
#include "CodeGenModule.h"
#include "CGCXXABI.h"

namespace clang {
namespace CodeGen {

/// Holds intermediate data about a path to a vbptr inside a base subobject.
struct VBTablePath {
  VBTablePath(const VBTableInfo &VBInfo)
    : VBInfo(VBInfo), NextBase(VBInfo.VBPtrSubobject.getBase()) { }

  /// All the data needed to build a vbtable, minus the GlobalVariable whose
  /// name we haven't computed yet.
  VBTableInfo VBInfo;

  /// Next base to use for disambiguation.  Can be null if we've already
  /// disambiguated this path once.
  const CXXRecordDecl *NextBase;

  /// Path is not really a full path like a CXXBasePath.  It holds the subset of
  /// records that need to be mangled into the vbtable symbol name in order to get
  /// a unique name.
  llvm::SmallVector<const CXXRecordDecl *, 1> Path;
};

VBTableBuilder::VBTableBuilder(CodeGenModule &CGM,
                               const CXXRecordDecl *MostDerived)
    : CGM(CGM), MostDerived(MostDerived),
      DerivedLayout(CGM.getContext().getASTRecordLayout(MostDerived)) {}

void VBTableBuilder::enumerateVBTables(VBTableVector &VBTables) {
  VBTablePathVector Paths;
  findUnambiguousPaths(MostDerived, BaseSubobject(MostDerived,
                                                  CharUnits::Zero()), Paths);
  for (VBTablePathVector::iterator I = Paths.begin(), E = Paths.end();
       I != E; ++I) {
    VBTablePath *P = *I;
    P->VBInfo.GV = getAddrOfVBTable(P->VBInfo.ReusingBase, P->Path);
    VBTables.push_back(P->VBInfo);
  }
}

bool VBTableBuilder::hasVBPtr(const CXXRecordDecl *RD) {
  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
  return Layout.getVBPtrOffset().getQuantity() != -1;
}

void VBTableBuilder::findUnambiguousPaths(const CXXRecordDecl *ReusingBase,
                                          BaseSubobject CurSubobject,
                                          VBTablePathVector &Paths) {
  size_t PathsStart = Paths.size();
  bool ReuseVBPtrFromBase = true;
  const CXXRecordDecl *CurBase = CurSubobject.getBase();

  // If this base has a vbptr, then we've found a path.  These are not full
  // paths, so we don't use CXXBasePath.
  if (hasVBPtr(CurBase)) {
    ReuseVBPtrFromBase = false;
    VBTablePath *Info = new VBTablePath(
      VBTableInfo(ReusingBase, CurSubobject, /*GV=*/0));
    Paths.push_back(Info);
  }

  // Recurse onto any bases which themselves have virtual bases.
  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(CurBase);
  for (CXXRecordDecl::base_class_const_iterator I = CurBase->bases_begin(),
       E = CurBase->bases_end(); I != E; ++I) {
    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
    if (!Base->getNumVBases())
      continue;  // Bases without virtual bases have no vbptrs.
    CharUnits NextOffset;
    const CXXRecordDecl *NextReusingBase = Base;
    if (I->isVirtual()) {
      if (!VBasesSeen.insert(Base))
        continue;  // Don't visit virtual bases twice.
      NextOffset = DerivedLayout.getVBaseClassOffset(Base);
    } else {
      NextOffset = (CurSubobject.getBaseOffset() +
                    Layout.getBaseClassOffset(Base));

      // If CurBase didn't have a vbptr, then ReusingBase will reuse the vbptr
      // from the first non-virtual base with vbases for its vbptr.
      if (ReuseVBPtrFromBase) {
        NextReusingBase = ReusingBase;
        ReuseVBPtrFromBase = false;
      }
    }

    size_t NumPaths = Paths.size();
    findUnambiguousPaths(NextReusingBase, BaseSubobject(Base, NextOffset),
                         Paths);

    // Tag paths through this base with the base itself.  We might use it to
    // disambiguate.
    for (size_t I = NumPaths, E = Paths.size(); I != E; ++I)
      Paths[I]->NextBase = Base;
  }

  bool AmbiguousPaths = rebucketPaths(Paths, PathsStart);
  if (AmbiguousPaths)
    rebucketPaths(Paths, PathsStart, /*SecondPass=*/true);

#ifndef NDEBUG
  // Check that the paths are in fact unique.
  for (size_t I = PathsStart + 1, E = Paths.size(); I != E; ++I) {
    assert(Paths[I]->Path != Paths[I - 1]->Path && "vbtable paths are not unique");
  }
#endif
}

static bool pathCompare(VBTablePath *LHS, VBTablePath *RHS) {
  return LHS->Path < RHS->Path;
}

void VBTableBuilder::extendPath(VBTablePath *P, bool SecondPass) {
  assert(P->NextBase || SecondPass);
  if (P->NextBase) {
    P->Path.push_back(P->NextBase);
    P->NextBase = 0;  // Prevent the path from being extended twice.
  }
}

bool VBTableBuilder::rebucketPaths(VBTablePathVector &Paths, size_t PathsStart,
                                   bool SecondPass) {
  // What we're essentially doing here is bucketing together ambiguous paths.
  // Any bucket with more than one path in it gets extended by NextBase, which
  // is usually the direct base of the inherited the vbptr.  This code uses a
  // sorted vector to implement a multiset to form the buckets.  Note that the
  // ordering is based on pointers, but it doesn't change our output order.  The
  // current algorithm is designed to match MSVC 2012's names.
  // TODO: Implement MSVC 2010 or earlier names to avoid extra vbtable cruft.
  VBTablePathVector PathsSorted(&Paths[PathsStart], &Paths.back() + 1);
  std::sort(PathsSorted.begin(), PathsSorted.end(), pathCompare);
  bool AmbiguousPaths = false;
  for (size_t I = 0, E = PathsSorted.size(); I != E;) {
    // Scan forward to find the end of the bucket.
    size_t BucketStart = I;
    do {
      ++I;
    } while (I != E && PathsSorted[BucketStart]->Path == PathsSorted[I]->Path);

    // If this bucket has multiple paths, extend them all.
    if (I - BucketStart > 1) {
      AmbiguousPaths = true;
      for (size_t II = BucketStart; II != I; ++II)
        extendPath(PathsSorted[II], SecondPass);
    }
  }
  return AmbiguousPaths;
}

llvm::GlobalVariable *
VBTableBuilder::getAddrOfVBTable(const CXXRecordDecl *ReusingBase,
                                 ArrayRef<const CXXRecordDecl *> BasePath) {
  // Caching at this layer is redundant with the caching in EnumerateVBTables().

  SmallString<256> OutName;
  llvm::raw_svector_ostream Out(OutName);
  MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
  Mangler.mangleCXXVBTable(MostDerived, BasePath, Out);
  Out.flush();
  StringRef Name = OutName.str();

  llvm::ArrayType *VBTableType =
    llvm::ArrayType::get(CGM.IntTy, 1 + ReusingBase->getNumVBases());

  assert(!CGM.getModule().getNamedGlobal(Name) &&
         "vbtable with this name already exists: mangling bug?");
  llvm::GlobalVariable *VBTable =
    CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType,
                                          llvm::GlobalValue::ExternalLinkage);
  VBTable->setUnnamedAddr(true);
  return VBTable;
}

void VBTableInfo::EmitVBTableDefinition(
    CodeGenModule &CGM, const CXXRecordDecl *RD,
    llvm::GlobalVariable::LinkageTypes Linkage) const {
  assert(RD->getNumVBases() && ReusingBase->getNumVBases() &&
         "should only emit vbtables for classes with vbtables");

  const ASTRecordLayout &BaseLayout =
    CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase());
  const ASTRecordLayout &DerivedLayout =
    CGM.getContext().getASTRecordLayout(RD);

  SmallVector<llvm::Constant *, 4> Offsets;

  // The offset from ReusingBase's vbptr to itself always leads.
  CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
  Offsets.push_back(
      llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity()));

  // These are laid out in the same order as in Itanium, which is the same as
  // the order of the vbase iterator.
  for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(),
       E = ReusingBase->vbases_end(); I != E; ++I) {
    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
    CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
    assert(!Offset.isNegative());
    // Make it relative to the subobject vbptr.
    Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset;
    Offsets.push_back(llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity()));
  }

  assert(Offsets.size() ==
         cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
                               ->getElementType())->getNumElements());
  llvm::ArrayType *VBTableType =
    llvm::ArrayType::get(CGM.IntTy, Offsets.size());
  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
  GV->setInitializer(Init);

  // Set the correct linkage.
  GV->setLinkage(Linkage);

  // Set the right visibility.
  CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable);
}

} // namespace CodeGen
} // namespace clang
