CGCXX.cpp revision ffb945ffb5d29b80fd93649c3572b6d87abce3fc
1daaf1de7c5f975b77798c551aaefeb36349e5ca7Devang Patel//===--- CGCXX.cpp - Emit LLVM Code for declarations ----------------------===//
2e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
3e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//                     The LLVM Compiler Infrastructure
4e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
5e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This file is distributed under the University of Illinois Open Source
6e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// License. See LICENSE.TXT for details.
7e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
8e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
9e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
10e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This contains code dealing with C++ code generation.
11e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
12e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
13e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump// We might split this into multiple files if it gets too unwieldy
15e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
163a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis#include "CGCXXABI.h"
17e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenFunction.h"
18e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenModule.h"
19e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/ASTContext.h"
20742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian#include "clang/AST/RecordLayout.h"
21e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/Decl.h"
22774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson#include "clang/AST/DeclCXX.h"
2386e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson#include "clang/AST/DeclObjC.h"
2414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/Mangle.h"
256815e941998659a55c20c147861b0f437928c3d8Anders Carlsson#include "clang/AST/StmtCXX.h"
2606057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth#include "clang/Frontend/CodeGenOptions.h"
27e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h"
28e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang;
29e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen;
30e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
31c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Try to emit a base destructor as an alias to its primary
32c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// base-class destructor.
33c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallbool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
34d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  if (!getCodeGenOpts().CXXCtorDtorAliases)
35d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    return true;
36d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
37c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // If the destructor doesn't have a trivial body, we have to emit it
38c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // separately.
39ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson  if (!D->hasTrivialBody())
40c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    return true;
41d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
42c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  const CXXRecordDecl *Class = D->getParent();
43c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
44c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // If we need to manipulate a VTT parameter, give up.
45c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  if (Class->getNumVBases()) {
46c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // Extra Credit:  passing extra parameters is perfectly safe
47c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // in many calling conventions, so only bail out if the ctor's
48c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // calling convention is nonstandard.
49c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    return true;
50c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  }
51c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
520d70d71ccbc4f7f59cadb759f61b7172a149676cJohn McCall  // If any field has a non-trivial destructor, we have to emit the
530d70d71ccbc4f7f59cadb759f61b7172a149676cJohn McCall  // destructor separately.
54c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  for (CXXRecordDecl::field_iterator I = Class->field_begin(),
55c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall         E = Class->field_end(); I != E; ++I)
560d70d71ccbc4f7f59cadb759f61b7172a149676cJohn McCall    if ((*I)->getType().isDestructedType())
570d70d71ccbc4f7f59cadb759f61b7172a149676cJohn McCall      return true;
58c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
59c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // Try to find a unique base class with a non-trivial destructor.
60c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  const CXXRecordDecl *UniqueBase = 0;
61c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
62c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall         E = Class->bases_end(); I != E; ++I) {
63c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
64c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // We're in the base destructor, so skip virtual bases.
65c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    if (I->isVirtual()) continue;
66c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
67c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // Skip base classes with trivial destructors.
68c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    const CXXRecordDecl *Base
69c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
70c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    if (Base->hasTrivialDestructor()) continue;
71c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
72c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // If we've already found a base class with a non-trivial
73c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    // destructor, give up.
74c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    if (UniqueBase) return true;
75c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    UniqueBase = Base;
76d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  }
77d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
78c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // If we didn't find any bases with a non-trivial destructor, then
79c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // the base destructor is actually effectively trivial, which can
80c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // happen if it was needlessly user-defined or if there are virtual
81c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // bases with non-trivial destructors.
82c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  if (!UniqueBase)
83c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    return true;
84c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
859a70846c5ffd5ff5cce60de49cd7b312146bf502John McCall  /// If we don't have a definition for the destructor yet, don't
869a70846c5ffd5ff5cce60de49cd7b312146bf502John McCall  /// emit.  We can't emit aliases to declarations; that's just not
879a70846c5ffd5ff5cce60de49cd7b312146bf502John McCall  /// how aliases work.
881d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor  const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
8906a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis  if (!BaseD->isImplicit() && !BaseD->hasBody())
909a70846c5ffd5ff5cce60de49cd7b312146bf502John McCall    return true;
919a70846c5ffd5ff5cce60de49cd7b312146bf502John McCall
92c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // If the base is at a non-zero offset, give up.
93c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(Class);
94a14f5979572aa25c03d24750ee4724d2031d4edeAnders Carlsson  if (ClassLayout.getBaseClassOffsetInBits(UniqueBase) != 0)
95c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    return true;
96c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
97c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
98c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall                                  GlobalDecl(BaseD, Dtor_Base));
99c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall}
100c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
101c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Try to emit a definition as a global alias for another definition.
102c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallbool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
103c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall                                             GlobalDecl TargetDecl) {
104c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  if (!getCodeGenOpts().CXXCtorDtorAliases)
105c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    return true;
106c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
107d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The alias will use the linkage of the referrent.  If we can't
108d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // support aliases with that linkage, fail.
109d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  llvm::GlobalValue::LinkageTypes Linkage
110d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    = getFunctionLinkage(cast<FunctionDecl>(AliasDecl.getDecl()));
111d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
112d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  switch (Linkage) {
113d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // We can definitely emit aliases to definitions with external linkage.
114d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::ExternalLinkage:
115d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::ExternalWeakLinkage:
116d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    break;
117d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
118d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // Same with local linkage.
119d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::InternalLinkage:
120d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::PrivateLinkage:
121d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::LinkerPrivateLinkage:
122d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    break;
123d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
124d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // We should try to support linkonce linkages.
125d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::LinkOnceAnyLinkage:
126d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  case llvm::GlobalValue::LinkOnceODRLinkage:
127d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    return true;
128d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
129d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // Other linkages will probably never be supported.
130d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  default:
131d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    return true;
132d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  }
133d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
134bc6afd158cc67b5f87dcc2d8efe2a2254af8debeRafael Espindola  llvm::GlobalValue::LinkageTypes TargetLinkage
135bc6afd158cc67b5f87dcc2d8efe2a2254af8debeRafael Espindola    = getFunctionLinkage(cast<FunctionDecl>(TargetDecl.getDecl()));
136bc6afd158cc67b5f87dcc2d8efe2a2254af8debeRafael Espindola
1373c15745b4baaa0c075418cfbe9f1be19c3a59c45Rafael Espindola  if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
138bc6afd158cc67b5f87dcc2d8efe2a2254af8debeRafael Espindola    return true;
139bc6afd158cc67b5f87dcc2d8efe2a2254af8debeRafael Espindola
140c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // Derive the type for the alias.
141c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  const llvm::PointerType *AliasType
142c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    = getTypes().GetFunctionType(AliasDecl)->getPointerTo();
143c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
144c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // Find the referrent.  Some aliases might require a bitcast, in
145c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // which case the caller is responsible for ensuring the soundness
146c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // of these semantics.
147c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
148c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  llvm::Constant *Aliasee = Ref;
149c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  if (Ref->getType() != AliasType)
150c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
151c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
152d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // Create the alias with no name.
153d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  llvm::GlobalAlias *Alias =
154c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
155d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
1561962beee04d3635b12cf6254a53b40ec6c50098dJohn McCall  // Switch any previous uses to the alias.
1579a20d55807cc2f6534a9c51a46cc8143ed16786dAnders Carlsson  llvm::StringRef MangledName = getMangledName(AliasDecl);
158f746aa6a8f538be914173a4aef2d9a2fd9f99d17John McCall  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
159d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  if (Entry) {
1601962beee04d3635b12cf6254a53b40ec6c50098dJohn McCall    assert(Entry->isDeclaration() && "definition already exists for alias");
1611962beee04d3635b12cf6254a53b40ec6c50098dJohn McCall    assert(Entry->getType() == AliasType &&
1621962beee04d3635b12cf6254a53b40ec6c50098dJohn McCall           "declaration exists with different type");
163f746aa6a8f538be914173a4aef2d9a2fd9f99d17John McCall    Alias->takeName(Entry);
164d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    Entry->replaceAllUsesWith(Alias);
165d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    Entry->eraseFromParent();
166f746aa6a8f538be914173a4aef2d9a2fd9f99d17John McCall  } else {
1679a20d55807cc2f6534a9c51a46cc8143ed16786dAnders Carlsson    Alias->setName(MangledName);
168d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  }
169d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
170d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // Finally, set up the alias with its proper name and attributes.
1711fb0caaa7bef765b85972274e3b434af2572c141John McCall  SetCommonAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias);
172d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
173d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  return false;
174d46f98573ba104eda102dd3224b2dca69f1c6336John McCall}
175b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
17695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
177d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The constructor used for constructing this as a complete class;
178d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // constucts the virtual bases, then calls the base constructor.
1798e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson  if (!D->getParent()->isAbstract()) {
1808e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson    // We don't need to emit the complete ctor if the class is abstract.
1818e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson    EmitGlobal(GlobalDecl(D, Ctor_Complete));
1828e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson  }
183d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
184d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The constructor used for constructing this as a base class;
185d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // ignores virtual bases.
1868e51a1f5da6ef4a1a168d14116c6eed3a578a263John McCall  EmitGlobal(GlobalDecl(D, Ctor_Base));
18795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
188363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
1891f6f961293da9c2b1c23da2411c1b439a9502ed0John McCallvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,
1901f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                       CXXCtorType ctorType) {
191d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The complete constructor is equivalent to the base constructor
192d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // for classes with no virtual bases.  Try to emit it as an alias.
1931f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (ctorType == Ctor_Complete &&
1941f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall      !ctor->getParent()->getNumVBases() &&
1951f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall      !TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete),
1961f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                GlobalDecl(ctor, Ctor_Base)))
197d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    return;
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1991f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  const CGFunctionInfo &fnInfo = getTypes().getFunctionInfo(ctor, ctorType);
200d26bc76c98006609002d9930f8840490e88ac5b5John McCall
2011f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  llvm::Function *fn =
2021f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall    cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo));
2031f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  setFunctionLinkage(ctor, fn);
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2051f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo);
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2071f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  SetFunctionDefinitionAttributes(ctor, fn);
2081f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  SetLLVMFunctionAttributesForDefinition(ctor, fn);
20927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
21027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
211d46f98573ba104eda102dd3224b2dca69f1c6336John McCallllvm::GlobalValue *
2121f6f961293da9c2b1c23da2411c1b439a9502ed0John McCallCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
2131f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                       CXXCtorType ctorType,
2141f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                       const CGFunctionInfo *fnInfo) {
2151f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  GlobalDecl GD(ctor, ctorType);
216dc709a8aea1072f11080f3a9519fd253582bf973Anders Carlsson
2171f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  llvm::StringRef name = getMangledName(GD);
2181f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (llvm::GlobalValue *existing = GetGlobalValue(name))
2191f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall    return existing;
2201f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall
2211f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (!fnInfo) fnInfo = &getTypes().getFunctionInfo(ctor, ctorType);
2221f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall
2231f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  const FunctionProtoType *proto = ctor->getType()->castAs<FunctionProtoType>();
2241f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  const llvm::FunctionType *fnType =
2251f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall    getTypes().GetFunctionType(*fnInfo, proto->isVariadic());
2261f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
2271faa89f9c619e4b2411fab4af7e22ee7a2bd9009Anders Carlsson                                                      /*ForVTable=*/false));
228363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
22927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
23027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
231d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The destructor in a virtual table is always a 'deleting'
232d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // destructor, which calls the complete destructor and then uses the
233d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // appropriate operator delete.
234ea9a20834cf9311fdf758cfbd73b8daa8e655f15Eli Friedman  if (D->isVirtual())
235624c7d704dc9f1dbb5dd3e5a0ef7eacfb3b699e2Eli Friedman    EmitGlobal(GlobalDecl(D, Dtor_Deleting));
236d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
237d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The destructor used for destructing this as a most-derived class;
238d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // call the base destructor and then destructs any virtual bases.
2398e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson  if (!D->getParent()->isAbstract() || D->isVirtual()) {
2408e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson    // We don't need to emit the complete ctor if the class is abstract,
2418e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson    // unless the destructor is virtual and needs to be in the vtable.
2428e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson    EmitGlobal(GlobalDecl(D, Dtor_Complete));
2438e0397a39eaf9db83cbd9a3a459893fd12a3a05eAnders Carlsson  }
244d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
245d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The destructor used for destructing this as a base class; ignores
246d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // virtual bases.
2478e51a1f5da6ef4a1a168d14116c6eed3a578a263John McCall  EmitGlobal(GlobalDecl(D, Dtor_Base));
24827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
24927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
2501f6f961293da9c2b1c23da2411c1b439a9502ed0John McCallvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
2511f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                      CXXDtorType dtorType) {
252d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // The complete destructor is equivalent to the base destructor for
253d46f98573ba104eda102dd3224b2dca69f1c6336John McCall  // classes with no virtual bases, so try to emit it as an alias.
2541f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (dtorType == Dtor_Complete &&
2551f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall      !dtor->getParent()->getNumVBases() &&
2561f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall      !TryEmitDefinitionAsAlias(GlobalDecl(dtor, Dtor_Complete),
2571f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                GlobalDecl(dtor, Dtor_Base)))
258d46f98573ba104eda102dd3224b2dca69f1c6336John McCall    return;
259d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
260c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // The base destructor is equivalent to the base destructor of its
261c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // base class if there is exactly one non-virtual base class with a
262c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // non-trivial destructor, there are no fields with a non-trivial
263c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  // destructor, and the body of the destructor is trivial.
2641f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (dtorType == Dtor_Base && !TryEmitBaseDestructorAsAlias(dtor))
265c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    return;
266c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall
2671f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  const CGFunctionInfo &fnInfo = getTypes().getFunctionInfo(dtor, dtorType);
268d26bc76c98006609002d9930f8840490e88ac5b5John McCall
2691f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  llvm::Function *fn =
2701f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall    cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo));
2711f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  setFunctionLinkage(dtor, fn);
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2731f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo);
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2751f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  SetFunctionDefinitionAttributes(dtor, fn);
2761f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  SetLLVMFunctionAttributesForDefinition(dtor, fn);
27727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
27827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
279d46f98573ba104eda102dd3224b2dca69f1c6336John McCallllvm::GlobalValue *
2801f6f961293da9c2b1c23da2411c1b439a9502ed0John McCallCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
2811f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                      CXXDtorType dtorType,
2821f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall                                      const CGFunctionInfo *fnInfo) {
2831f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  GlobalDecl GD(dtor, dtorType);
2841f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall
2851f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  llvm::StringRef name = getMangledName(GD);
2861f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (llvm::GlobalValue *existing = GetGlobalValue(name))
2871f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall    return existing;
288dc709a8aea1072f11080f3a9519fd253582bf973Anders Carlsson
2891f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  if (!fnInfo) fnInfo = &getTypes().getFunctionInfo(dtor, dtorType);
290d46f98573ba104eda102dd3224b2dca69f1c6336John McCall
2911f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  const llvm::FunctionType *fnType =
2921f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall    getTypes().GetFunctionType(*fnInfo, false);
2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2941f6f961293da9c2b1c23da2411c1b439a9502ed0John McCall  return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
2951faa89f9c619e4b2411fab4af7e22ee7a2bd9009Anders Carlsson                                                      /*ForVTable=*/false));
29627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
29727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
298046c294a43024874ff35656c6e785b64e72f1f36Anders Carlssonstatic llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VTableIndex,
299566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson                                     llvm::Value *This, const llvm::Type *Ty) {
300043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman  Ty = Ty->getPointerTo()->getPointerTo();
301566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson
302043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman  llvm::Value *VTable = CGF.GetVTablePtr(This, Ty);
303566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson  llvm::Value *VFuncPtr =
304046c294a43024874ff35656c6e785b64e72f1f36Anders Carlsson    CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
305566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson  return CGF.Builder.CreateLoad(VFuncPtr);
306566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson}
307566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson
3082f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonllvm::Value *
309566abee1e9828a7700b51e4d17ea08234fde3bb4Anders CarlssonCodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
310f0070dbae9535836ad41711081465dec2259786bMike Stump                                  const llvm::Type *Ty) {
311566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson  MD = MD->getCanonicalDecl();
312046c294a43024874ff35656c6e785b64e72f1f36Anders Carlsson  uint64_t VTableIndex = CGM.getVTables().getMethodVTableIndex(MD);
3132b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson
314af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson  return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
315566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson}
316566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson
3172726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian/// BuildVirtualCall - This routine is to support gcc's kext ABI making
3182726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian/// indirect call to virtual functions. It makes the call through indexing
3192726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian/// into the vtable.
3202726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanianllvm::Value *
3212726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz JahanianCodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
3222726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian                                  NestedNameSpecifier *Qual,
3232726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian                                  const llvm::Type *Ty) {
3242726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  llvm::Value *VTable = 0;
3252726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) &&
3262726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian         "BuildAppleKextVirtualCall - bad Qual kind");
3272726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian
3282726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  const Type *QTy = Qual->getAsType();
3292726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  QualType T = QualType(QTy, 0);
3302726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  const RecordType *RT = T->getAs<RecordType>();
3312726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  assert(RT && "BuildAppleKextVirtualCall - Qual type must be record");
3322726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
333ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian
334ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
335ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD);
336ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian
3372726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  VTable = CGM.getVTables().GetAddrOfVTable(RD);
3382726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  Ty = Ty->getPointerTo()->getPointerTo();
3392726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  VTable = Builder.CreateBitCast(VTable, Ty);
3402726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");
3412726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  MD = MD->getCanonicalDecl();
3422726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  uint64_t VTableIndex = CGM.getVTables().getMethodVTableIndex(MD);
343a50e33eb0ff7b73d44aebce88de3732583a7e960Fariborz Jahanian  uint64_t AddressPoint =
3444230d529a8797bbeef2328b60abeae333f7e143fKen Dyck    CGM.getVTables().getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD);
345a50e33eb0ff7b73d44aebce88de3732583a7e960Fariborz Jahanian  VTableIndex += AddressPoint;
3462726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian  llvm::Value *VFuncPtr =
347d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall    Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
348d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall  return Builder.CreateLoad(VFuncPtr);
3492726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian}
3502726267f094a0c1f5ac5b501ec5a9898c58876bfFariborz Jahanian
351ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian/// BuildVirtualCall - This routine makes indirect vtable call for
352ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian/// call to virtual destructors. It returns 0 if it could not do it.
353ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanianllvm::Value *
354ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz JahanianCodeGenFunction::BuildAppleKextVirtualDestructorCall(
355ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian                                            const CXXDestructorDecl *DD,
356ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian                                            CXXDtorType Type,
357ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian                                            const CXXRecordDecl *RD) {
358ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  llvm::Value * Callee = 0;
359ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  const CXXMethodDecl *MD = cast<CXXMethodDecl>(DD);
360ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  // FIXME. Dtor_Base dtor is always direct!!
361ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  // It need be somehow inline expanded into the caller.
362ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  // -O does that. But need to support -O0 as well.
363ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  if (MD->isVirtual() && Type != Dtor_Base) {
364ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    // Compute the function type we're calling.
365ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    const CGFunctionInfo *FInfo =
366ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    &CGM.getTypes().getFunctionInfo(cast<CXXDestructorDecl>(MD),
367ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian                                    Dtor_Complete);
368ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
369ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    const llvm::Type *Ty
370ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian      = CGM.getTypes().GetFunctionType(*FInfo, FPT->isVariadic());
371771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian
372ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    llvm::Value *VTable = CGM.getVTables().GetAddrOfVTable(RD);
373ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    Ty = Ty->getPointerTo()->getPointerTo();
374ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    VTable = Builder.CreateBitCast(VTable, Ty);
375771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian    DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
376ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    uint64_t VTableIndex =
377771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian      CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type));
378ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    uint64_t AddressPoint =
3794230d529a8797bbeef2328b60abeae333f7e143fKen Dyck      CGM.getVTables().getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD);
380ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    VTableIndex += AddressPoint;
381ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian    llvm::Value *VFuncPtr =
382d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall      Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
383d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall    Callee = Builder.CreateLoad(VFuncPtr);
384ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  }
385ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian  return Callee;
386ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian}
387ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian
388566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlssonllvm::Value *
389566abee1e9828a7700b51e4d17ea08234fde3bb4Anders CarlssonCodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,
39083eedd9fa800c273647c7a90465ea9c110f9d93cAnders Carlsson                                  llvm::Value *This, const llvm::Type *Ty) {
391566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson  DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
392af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson  uint64_t VTableIndex =
393046c294a43024874ff35656c6e785b64e72f1f36Anders Carlsson    CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type));
394566abee1e9828a7700b51e4d17ea08234fde3bb4Anders Carlsson
395af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson  return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
396f0070dbae9535836ad41711081465dec2259786bMike Stump}
3973a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
398