19063302a82423cb83f002257a416741850739a70Reid Kleckner//===--- MicrosoftVBTables.cpp - Virtual Base Table Emission --------------===//
29063302a82423cb83f002257a416741850739a70Reid Kleckner//
39063302a82423cb83f002257a416741850739a70Reid Kleckner//                     The LLVM Compiler Infrastructure
49063302a82423cb83f002257a416741850739a70Reid Kleckner//
59063302a82423cb83f002257a416741850739a70Reid Kleckner// This file is distributed under the University of Illinois Open Source
69063302a82423cb83f002257a416741850739a70Reid Kleckner// License. See LICENSE.TXT for details.
79063302a82423cb83f002257a416741850739a70Reid Kleckner//
89063302a82423cb83f002257a416741850739a70Reid Kleckner//===----------------------------------------------------------------------===//
99063302a82423cb83f002257a416741850739a70Reid Kleckner//
109063302a82423cb83f002257a416741850739a70Reid Kleckner// This class generates data about MSVC virtual base tables.
119063302a82423cb83f002257a416741850739a70Reid Kleckner//
129063302a82423cb83f002257a416741850739a70Reid Kleckner//===----------------------------------------------------------------------===//
139063302a82423cb83f002257a416741850739a70Reid Kleckner
149063302a82423cb83f002257a416741850739a70Reid Kleckner#include "MicrosoftVBTables.h"
159063302a82423cb83f002257a416741850739a70Reid Kleckner#include "CodeGenModule.h"
169063302a82423cb83f002257a416741850739a70Reid Kleckner#include "CGCXXABI.h"
179063302a82423cb83f002257a416741850739a70Reid Kleckner
189063302a82423cb83f002257a416741850739a70Reid Klecknernamespace clang {
199063302a82423cb83f002257a416741850739a70Reid Klecknernamespace CodeGen {
209063302a82423cb83f002257a416741850739a70Reid Kleckner
219063302a82423cb83f002257a416741850739a70Reid Kleckner/// Holds intermediate data about a path to a vbptr inside a base subobject.
229063302a82423cb83f002257a416741850739a70Reid Klecknerstruct VBTablePath {
239063302a82423cb83f002257a416741850739a70Reid Kleckner  VBTablePath(const VBTableInfo &VBInfo)
249063302a82423cb83f002257a416741850739a70Reid Kleckner    : VBInfo(VBInfo), NextBase(VBInfo.VBPtrSubobject.getBase()) { }
259063302a82423cb83f002257a416741850739a70Reid Kleckner
269063302a82423cb83f002257a416741850739a70Reid Kleckner  /// All the data needed to build a vbtable, minus the GlobalVariable whose
279063302a82423cb83f002257a416741850739a70Reid Kleckner  /// name we haven't computed yet.
289063302a82423cb83f002257a416741850739a70Reid Kleckner  VBTableInfo VBInfo;
299063302a82423cb83f002257a416741850739a70Reid Kleckner
309063302a82423cb83f002257a416741850739a70Reid Kleckner  /// Next base to use for disambiguation.  Can be null if we've already
319063302a82423cb83f002257a416741850739a70Reid Kleckner  /// disambiguated this path once.
329063302a82423cb83f002257a416741850739a70Reid Kleckner  const CXXRecordDecl *NextBase;
339063302a82423cb83f002257a416741850739a70Reid Kleckner
349063302a82423cb83f002257a416741850739a70Reid Kleckner  /// Path is not really a full path like a CXXBasePath.  It holds the subset of
359063302a82423cb83f002257a416741850739a70Reid Kleckner  /// records that need to be mangled into the vbtable symbol name in order to get
369063302a82423cb83f002257a416741850739a70Reid Kleckner  /// a unique name.
379063302a82423cb83f002257a416741850739a70Reid Kleckner  llvm::SmallVector<const CXXRecordDecl *, 1> Path;
389063302a82423cb83f002257a416741850739a70Reid Kleckner};
399063302a82423cb83f002257a416741850739a70Reid Kleckner
409063302a82423cb83f002257a416741850739a70Reid KlecknerVBTableBuilder::VBTableBuilder(CodeGenModule &CGM,
419063302a82423cb83f002257a416741850739a70Reid Kleckner                               const CXXRecordDecl *MostDerived)
429063302a82423cb83f002257a416741850739a70Reid Kleckner    : CGM(CGM), MostDerived(MostDerived),
439063302a82423cb83f002257a416741850739a70Reid Kleckner      DerivedLayout(CGM.getContext().getASTRecordLayout(MostDerived)) {}
449063302a82423cb83f002257a416741850739a70Reid Kleckner
459063302a82423cb83f002257a416741850739a70Reid Klecknervoid VBTableBuilder::enumerateVBTables(VBTableVector &VBTables) {
469063302a82423cb83f002257a416741850739a70Reid Kleckner  VBTablePathVector Paths;
479063302a82423cb83f002257a416741850739a70Reid Kleckner  findUnambiguousPaths(MostDerived, BaseSubobject(MostDerived,
489063302a82423cb83f002257a416741850739a70Reid Kleckner                                                  CharUnits::Zero()), Paths);
499063302a82423cb83f002257a416741850739a70Reid Kleckner  for (VBTablePathVector::iterator I = Paths.begin(), E = Paths.end();
509063302a82423cb83f002257a416741850739a70Reid Kleckner       I != E; ++I) {
519063302a82423cb83f002257a416741850739a70Reid Kleckner    VBTablePath *P = *I;
529063302a82423cb83f002257a416741850739a70Reid Kleckner    P->VBInfo.GV = getAddrOfVBTable(P->VBInfo.ReusingBase, P->Path);
539063302a82423cb83f002257a416741850739a70Reid Kleckner    VBTables.push_back(P->VBInfo);
549063302a82423cb83f002257a416741850739a70Reid Kleckner  }
559063302a82423cb83f002257a416741850739a70Reid Kleckner}
569063302a82423cb83f002257a416741850739a70Reid Kleckner
579063302a82423cb83f002257a416741850739a70Reid Klecknerbool VBTableBuilder::hasVBPtr(const CXXRecordDecl *RD) {
589063302a82423cb83f002257a416741850739a70Reid Kleckner  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
599063302a82423cb83f002257a416741850739a70Reid Kleckner  return Layout.getVBPtrOffset().getQuantity() != -1;
609063302a82423cb83f002257a416741850739a70Reid Kleckner}
619063302a82423cb83f002257a416741850739a70Reid Kleckner
629063302a82423cb83f002257a416741850739a70Reid Klecknervoid VBTableBuilder::findUnambiguousPaths(const CXXRecordDecl *ReusingBase,
639063302a82423cb83f002257a416741850739a70Reid Kleckner                                          BaseSubobject CurSubobject,
649063302a82423cb83f002257a416741850739a70Reid Kleckner                                          VBTablePathVector &Paths) {
659063302a82423cb83f002257a416741850739a70Reid Kleckner  size_t PathsStart = Paths.size();
669063302a82423cb83f002257a416741850739a70Reid Kleckner  bool ReuseVBPtrFromBase = true;
679063302a82423cb83f002257a416741850739a70Reid Kleckner  const CXXRecordDecl *CurBase = CurSubobject.getBase();
689063302a82423cb83f002257a416741850739a70Reid Kleckner
699063302a82423cb83f002257a416741850739a70Reid Kleckner  // If this base has a vbptr, then we've found a path.  These are not full
709063302a82423cb83f002257a416741850739a70Reid Kleckner  // paths, so we don't use CXXBasePath.
719063302a82423cb83f002257a416741850739a70Reid Kleckner  if (hasVBPtr(CurBase)) {
729063302a82423cb83f002257a416741850739a70Reid Kleckner    ReuseVBPtrFromBase = false;
739063302a82423cb83f002257a416741850739a70Reid Kleckner    VBTablePath *Info = new VBTablePath(
749063302a82423cb83f002257a416741850739a70Reid Kleckner      VBTableInfo(ReusingBase, CurSubobject, /*GV=*/0));
759063302a82423cb83f002257a416741850739a70Reid Kleckner    Paths.push_back(Info);
769063302a82423cb83f002257a416741850739a70Reid Kleckner  }
779063302a82423cb83f002257a416741850739a70Reid Kleckner
789063302a82423cb83f002257a416741850739a70Reid Kleckner  // Recurse onto any bases which themselves have virtual bases.
799063302a82423cb83f002257a416741850739a70Reid Kleckner  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(CurBase);
809063302a82423cb83f002257a416741850739a70Reid Kleckner  for (CXXRecordDecl::base_class_const_iterator I = CurBase->bases_begin(),
819063302a82423cb83f002257a416741850739a70Reid Kleckner       E = CurBase->bases_end(); I != E; ++I) {
829063302a82423cb83f002257a416741850739a70Reid Kleckner    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
839063302a82423cb83f002257a416741850739a70Reid Kleckner    if (!Base->getNumVBases())
849063302a82423cb83f002257a416741850739a70Reid Kleckner      continue;  // Bases without virtual bases have no vbptrs.
859063302a82423cb83f002257a416741850739a70Reid Kleckner    CharUnits NextOffset;
869063302a82423cb83f002257a416741850739a70Reid Kleckner    const CXXRecordDecl *NextReusingBase = Base;
879063302a82423cb83f002257a416741850739a70Reid Kleckner    if (I->isVirtual()) {
889063302a82423cb83f002257a416741850739a70Reid Kleckner      if (!VBasesSeen.insert(Base))
899063302a82423cb83f002257a416741850739a70Reid Kleckner        continue;  // Don't visit virtual bases twice.
909063302a82423cb83f002257a416741850739a70Reid Kleckner      NextOffset = DerivedLayout.getVBaseClassOffset(Base);
919063302a82423cb83f002257a416741850739a70Reid Kleckner    } else {
929063302a82423cb83f002257a416741850739a70Reid Kleckner      NextOffset = (CurSubobject.getBaseOffset() +
939063302a82423cb83f002257a416741850739a70Reid Kleckner                    Layout.getBaseClassOffset(Base));
949063302a82423cb83f002257a416741850739a70Reid Kleckner
959063302a82423cb83f002257a416741850739a70Reid Kleckner      // If CurBase didn't have a vbptr, then ReusingBase will reuse the vbptr
969063302a82423cb83f002257a416741850739a70Reid Kleckner      // from the first non-virtual base with vbases for its vbptr.
979063302a82423cb83f002257a416741850739a70Reid Kleckner      if (ReuseVBPtrFromBase) {
989063302a82423cb83f002257a416741850739a70Reid Kleckner        NextReusingBase = ReusingBase;
999063302a82423cb83f002257a416741850739a70Reid Kleckner        ReuseVBPtrFromBase = false;
1009063302a82423cb83f002257a416741850739a70Reid Kleckner      }
1019063302a82423cb83f002257a416741850739a70Reid Kleckner    }
1029063302a82423cb83f002257a416741850739a70Reid Kleckner
1039063302a82423cb83f002257a416741850739a70Reid Kleckner    size_t NumPaths = Paths.size();
1049063302a82423cb83f002257a416741850739a70Reid Kleckner    findUnambiguousPaths(NextReusingBase, BaseSubobject(Base, NextOffset),
1059063302a82423cb83f002257a416741850739a70Reid Kleckner                         Paths);
1069063302a82423cb83f002257a416741850739a70Reid Kleckner
1079063302a82423cb83f002257a416741850739a70Reid Kleckner    // Tag paths through this base with the base itself.  We might use it to
1089063302a82423cb83f002257a416741850739a70Reid Kleckner    // disambiguate.
1099063302a82423cb83f002257a416741850739a70Reid Kleckner    for (size_t I = NumPaths, E = Paths.size(); I != E; ++I)
1109063302a82423cb83f002257a416741850739a70Reid Kleckner      Paths[I]->NextBase = Base;
1119063302a82423cb83f002257a416741850739a70Reid Kleckner  }
1129063302a82423cb83f002257a416741850739a70Reid Kleckner
1139063302a82423cb83f002257a416741850739a70Reid Kleckner  bool AmbiguousPaths = rebucketPaths(Paths, PathsStart);
1149063302a82423cb83f002257a416741850739a70Reid Kleckner  if (AmbiguousPaths)
1159063302a82423cb83f002257a416741850739a70Reid Kleckner    rebucketPaths(Paths, PathsStart, /*SecondPass=*/true);
1169063302a82423cb83f002257a416741850739a70Reid Kleckner
1179063302a82423cb83f002257a416741850739a70Reid Kleckner#ifndef NDEBUG
1189063302a82423cb83f002257a416741850739a70Reid Kleckner  // Check that the paths are in fact unique.
1199063302a82423cb83f002257a416741850739a70Reid Kleckner  for (size_t I = PathsStart + 1, E = Paths.size(); I != E; ++I) {
1209063302a82423cb83f002257a416741850739a70Reid Kleckner    assert(Paths[I]->Path != Paths[I - 1]->Path && "vbtable paths are not unique");
1219063302a82423cb83f002257a416741850739a70Reid Kleckner  }
1229063302a82423cb83f002257a416741850739a70Reid Kleckner#endif
1239063302a82423cb83f002257a416741850739a70Reid Kleckner}
1249063302a82423cb83f002257a416741850739a70Reid Kleckner
1259063302a82423cb83f002257a416741850739a70Reid Klecknerstatic bool pathCompare(VBTablePath *LHS, VBTablePath *RHS) {
1269063302a82423cb83f002257a416741850739a70Reid Kleckner  return LHS->Path < RHS->Path;
1279063302a82423cb83f002257a416741850739a70Reid Kleckner}
1289063302a82423cb83f002257a416741850739a70Reid Kleckner
1299063302a82423cb83f002257a416741850739a70Reid Klecknervoid VBTableBuilder::extendPath(VBTablePath *P, bool SecondPass) {
1309063302a82423cb83f002257a416741850739a70Reid Kleckner  assert(P->NextBase || SecondPass);
1319063302a82423cb83f002257a416741850739a70Reid Kleckner  if (P->NextBase) {
1329063302a82423cb83f002257a416741850739a70Reid Kleckner    P->Path.push_back(P->NextBase);
1339063302a82423cb83f002257a416741850739a70Reid Kleckner    P->NextBase = 0;  // Prevent the path from being extended twice.
1349063302a82423cb83f002257a416741850739a70Reid Kleckner  }
1359063302a82423cb83f002257a416741850739a70Reid Kleckner}
1369063302a82423cb83f002257a416741850739a70Reid Kleckner
1379063302a82423cb83f002257a416741850739a70Reid Klecknerbool VBTableBuilder::rebucketPaths(VBTablePathVector &Paths, size_t PathsStart,
1389063302a82423cb83f002257a416741850739a70Reid Kleckner                                   bool SecondPass) {
1399063302a82423cb83f002257a416741850739a70Reid Kleckner  // What we're essentially doing here is bucketing together ambiguous paths.
1409063302a82423cb83f002257a416741850739a70Reid Kleckner  // Any bucket with more than one path in it gets extended by NextBase, which
1419063302a82423cb83f002257a416741850739a70Reid Kleckner  // is usually the direct base of the inherited the vbptr.  This code uses a
1429063302a82423cb83f002257a416741850739a70Reid Kleckner  // sorted vector to implement a multiset to form the buckets.  Note that the
1439063302a82423cb83f002257a416741850739a70Reid Kleckner  // ordering is based on pointers, but it doesn't change our output order.  The
1449063302a82423cb83f002257a416741850739a70Reid Kleckner  // current algorithm is designed to match MSVC 2012's names.
1459063302a82423cb83f002257a416741850739a70Reid Kleckner  // TODO: Implement MSVC 2010 or earlier names to avoid extra vbtable cruft.
1469063302a82423cb83f002257a416741850739a70Reid Kleckner  VBTablePathVector PathsSorted(&Paths[PathsStart], &Paths.back() + 1);
1479063302a82423cb83f002257a416741850739a70Reid Kleckner  std::sort(PathsSorted.begin(), PathsSorted.end(), pathCompare);
1489063302a82423cb83f002257a416741850739a70Reid Kleckner  bool AmbiguousPaths = false;
1499063302a82423cb83f002257a416741850739a70Reid Kleckner  for (size_t I = 0, E = PathsSorted.size(); I != E;) {
1509063302a82423cb83f002257a416741850739a70Reid Kleckner    // Scan forward to find the end of the bucket.
1519063302a82423cb83f002257a416741850739a70Reid Kleckner    size_t BucketStart = I;
1529063302a82423cb83f002257a416741850739a70Reid Kleckner    do {
1539063302a82423cb83f002257a416741850739a70Reid Kleckner      ++I;
1549063302a82423cb83f002257a416741850739a70Reid Kleckner    } while (I != E && PathsSorted[BucketStart]->Path == PathsSorted[I]->Path);
1559063302a82423cb83f002257a416741850739a70Reid Kleckner
1569063302a82423cb83f002257a416741850739a70Reid Kleckner    // If this bucket has multiple paths, extend them all.
1579063302a82423cb83f002257a416741850739a70Reid Kleckner    if (I - BucketStart > 1) {
1589063302a82423cb83f002257a416741850739a70Reid Kleckner      AmbiguousPaths = true;
1599063302a82423cb83f002257a416741850739a70Reid Kleckner      for (size_t II = BucketStart; II != I; ++II)
1609063302a82423cb83f002257a416741850739a70Reid Kleckner        extendPath(PathsSorted[II], SecondPass);
1619063302a82423cb83f002257a416741850739a70Reid Kleckner    }
1629063302a82423cb83f002257a416741850739a70Reid Kleckner  }
1639063302a82423cb83f002257a416741850739a70Reid Kleckner  return AmbiguousPaths;
1649063302a82423cb83f002257a416741850739a70Reid Kleckner}
1659063302a82423cb83f002257a416741850739a70Reid Kleckner
1669063302a82423cb83f002257a416741850739a70Reid Klecknerllvm::GlobalVariable *
1679063302a82423cb83f002257a416741850739a70Reid KlecknerVBTableBuilder::getAddrOfVBTable(const CXXRecordDecl *ReusingBase,
1689063302a82423cb83f002257a416741850739a70Reid Kleckner                                 ArrayRef<const CXXRecordDecl *> BasePath) {
1699063302a82423cb83f002257a416741850739a70Reid Kleckner  // Caching at this layer is redundant with the caching in EnumerateVBTables().
1709063302a82423cb83f002257a416741850739a70Reid Kleckner
1719063302a82423cb83f002257a416741850739a70Reid Kleckner  SmallString<256> OutName;
1729063302a82423cb83f002257a416741850739a70Reid Kleckner  llvm::raw_svector_ostream Out(OutName);
1739063302a82423cb83f002257a416741850739a70Reid Kleckner  MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
1749063302a82423cb83f002257a416741850739a70Reid Kleckner  Mangler.mangleCXXVBTable(MostDerived, BasePath, Out);
1759063302a82423cb83f002257a416741850739a70Reid Kleckner  Out.flush();
1769063302a82423cb83f002257a416741850739a70Reid Kleckner  StringRef Name = OutName.str();
1779063302a82423cb83f002257a416741850739a70Reid Kleckner
1789063302a82423cb83f002257a416741850739a70Reid Kleckner  llvm::ArrayType *VBTableType =
1799063302a82423cb83f002257a416741850739a70Reid Kleckner    llvm::ArrayType::get(CGM.IntTy, 1 + ReusingBase->getNumVBases());
1809063302a82423cb83f002257a416741850739a70Reid Kleckner
1819063302a82423cb83f002257a416741850739a70Reid Kleckner  assert(!CGM.getModule().getNamedGlobal(Name) &&
1829063302a82423cb83f002257a416741850739a70Reid Kleckner         "vbtable with this name already exists: mangling bug?");
1839063302a82423cb83f002257a416741850739a70Reid Kleckner  llvm::GlobalVariable *VBTable =
1849063302a82423cb83f002257a416741850739a70Reid Kleckner    CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType,
1859063302a82423cb83f002257a416741850739a70Reid Kleckner                                          llvm::GlobalValue::ExternalLinkage);
1869063302a82423cb83f002257a416741850739a70Reid Kleckner  VBTable->setUnnamedAddr(true);
1879063302a82423cb83f002257a416741850739a70Reid Kleckner  return VBTable;
1889063302a82423cb83f002257a416741850739a70Reid Kleckner}
1899063302a82423cb83f002257a416741850739a70Reid Kleckner
1909063302a82423cb83f002257a416741850739a70Reid Klecknervoid VBTableInfo::EmitVBTableDefinition(
1919063302a82423cb83f002257a416741850739a70Reid Kleckner    CodeGenModule &CGM, const CXXRecordDecl *RD,
1929063302a82423cb83f002257a416741850739a70Reid Kleckner    llvm::GlobalVariable::LinkageTypes Linkage) const {
1939063302a82423cb83f002257a416741850739a70Reid Kleckner  assert(RD->getNumVBases() && ReusingBase->getNumVBases() &&
1949063302a82423cb83f002257a416741850739a70Reid Kleckner         "should only emit vbtables for classes with vbtables");
1959063302a82423cb83f002257a416741850739a70Reid Kleckner
1969063302a82423cb83f002257a416741850739a70Reid Kleckner  const ASTRecordLayout &BaseLayout =
1979063302a82423cb83f002257a416741850739a70Reid Kleckner    CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase());
1989063302a82423cb83f002257a416741850739a70Reid Kleckner  const ASTRecordLayout &DerivedLayout =
1999063302a82423cb83f002257a416741850739a70Reid Kleckner    CGM.getContext().getASTRecordLayout(RD);
2009063302a82423cb83f002257a416741850739a70Reid Kleckner
2019063302a82423cb83f002257a416741850739a70Reid Kleckner  SmallVector<llvm::Constant *, 4> Offsets;
2029063302a82423cb83f002257a416741850739a70Reid Kleckner
2039063302a82423cb83f002257a416741850739a70Reid Kleckner  // The offset from ReusingBase's vbptr to itself always leads.
2049063302a82423cb83f002257a416741850739a70Reid Kleckner  CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2059063302a82423cb83f002257a416741850739a70Reid Kleckner  Offsets.push_back(
2069063302a82423cb83f002257a416741850739a70Reid Kleckner      llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity()));
2079063302a82423cb83f002257a416741850739a70Reid Kleckner
2089063302a82423cb83f002257a416741850739a70Reid Kleckner  // These are laid out in the same order as in Itanium, which is the same as
2099063302a82423cb83f002257a416741850739a70Reid Kleckner  // the order of the vbase iterator.
2109063302a82423cb83f002257a416741850739a70Reid Kleckner  for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(),
2119063302a82423cb83f002257a416741850739a70Reid Kleckner       E = ReusingBase->vbases_end(); I != E; ++I) {
2129063302a82423cb83f002257a416741850739a70Reid Kleckner    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
2139063302a82423cb83f002257a416741850739a70Reid Kleckner    CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
2149063302a82423cb83f002257a416741850739a70Reid Kleckner    assert(!Offset.isNegative());
2159063302a82423cb83f002257a416741850739a70Reid Kleckner    // Make it relative to the subobject vbptr.
2169063302a82423cb83f002257a416741850739a70Reid Kleckner    Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset;
2179063302a82423cb83f002257a416741850739a70Reid Kleckner    Offsets.push_back(llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity()));
2189063302a82423cb83f002257a416741850739a70Reid Kleckner  }
2199063302a82423cb83f002257a416741850739a70Reid Kleckner
2209063302a82423cb83f002257a416741850739a70Reid Kleckner  assert(Offsets.size() ==
2219063302a82423cb83f002257a416741850739a70Reid Kleckner         cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2229063302a82423cb83f002257a416741850739a70Reid Kleckner                               ->getElementType())->getNumElements());
2239063302a82423cb83f002257a416741850739a70Reid Kleckner  llvm::ArrayType *VBTableType =
2249063302a82423cb83f002257a416741850739a70Reid Kleckner    llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2259063302a82423cb83f002257a416741850739a70Reid Kleckner  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2269063302a82423cb83f002257a416741850739a70Reid Kleckner  GV->setInitializer(Init);
2279063302a82423cb83f002257a416741850739a70Reid Kleckner
2289063302a82423cb83f002257a416741850739a70Reid Kleckner  // Set the correct linkage.
2299063302a82423cb83f002257a416741850739a70Reid Kleckner  GV->setLinkage(Linkage);
2309063302a82423cb83f002257a416741850739a70Reid Kleckner
2319063302a82423cb83f002257a416741850739a70Reid Kleckner  // Set the right visibility.
2329063302a82423cb83f002257a416741850739a70Reid Kleckner  CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable);
2339063302a82423cb83f002257a416741850739a70Reid Kleckner}
2349063302a82423cb83f002257a416741850739a70Reid Kleckner
2359063302a82423cb83f002257a416741850739a70Reid Kleckner} // namespace CodeGen
2369063302a82423cb83f002257a416741850739a70Reid Kleckner} // namespace clang
237