CGVTables.cpp revision bbfd5babab059af14eed20b63b2aabedaa6a6ac7
1633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham//===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===// 2633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// 3633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// The LLVM Compiler Infrastructure 4633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// 5633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// This file is distributed under the University of Illinois Open Source 6633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// License. See LICENSE.TXT for details. 7633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// 8633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham//===----------------------------------------------------------------------===// 9633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// 10633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// This contains code dealing with C++ code generation of virtual tables. 11633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham// 12633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham//===----------------------------------------------------------------------===// 13633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 14633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "CodeGenModule.h" 15633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "CodeGenFunction.h" 16633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "CGCXXABI.h" 17633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "clang/AST/CXXInheritance.h" 18633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "clang/AST/RecordLayout.h" 19633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "clang/Frontend/CodeGenOptions.h" 20633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "llvm/ADT/DenseSet.h" 21633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "llvm/ADT/SetVector.h" 22633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "llvm/Support/Compiler.h" 23633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include "llvm/Support/Format.h" 24633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <algorithm> 25633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <cstdio> 26633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 27633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamusing namespace clang; 28633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamusing namespace CodeGen; 29633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 30633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamnamespace { 31633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 32633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/// BaseOffset - Represents an offset from a derived class to a direct or 33633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/// indirect base class. 34633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstruct BaseOffset { 35633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// DerivedClass - The derived class. 36633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *DerivedClass; 37633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 38633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// VirtualBase - If the path from the derived class to the base class 39633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// involves a virtual base class, this holds its declaration. 40633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *VirtualBase; 41633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 42633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// NonVirtualOffset - The offset from the derived class to the base class. 43633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// (Or the offset from the virtual base class to the base class, if the 44633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// path from the derived class to the base class involves a virtual base 45633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// class. 46633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t NonVirtualOffset; 47633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 48633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset() : DerivedClass(0), VirtualBase(0), NonVirtualOffset(0) { } 49633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset(const CXXRecordDecl *DerivedClass, 50633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *VirtualBase, int64_t NonVirtualOffset) 51633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 52633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham NonVirtualOffset(NonVirtualOffset) { } 53633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 54633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham bool isEmpty() const { return !NonVirtualOffset && !VirtualBase; } 55633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}; 56633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 57633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/// FinalOverriders - Contains the final overrider member functions for all 58633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/// member functions in the base subobjects of a class. 59633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamclass FinalOverriders { 60633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhampublic: 61633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// OverriderInfo - Information about a final overrider. 62633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham struct OverriderInfo { 63633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// Method - The method decl of the overrider. 64633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *Method; 65633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 66633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// Offset - the base offset of the overrider in the layout class. 67633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t Offset; 68633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 69633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OverriderInfo() : Method(0), Offset(0) { } 70633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham }; 71633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 72633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamprivate: 73633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// MostDerivedClass - The most derived class for which the final overriders 74633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// are stored. 75633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *MostDerivedClass; 76633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 77633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// MostDerivedClassOffset - If we're building final overriders for a 78633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// construction vtable, this holds the offset from the layout class to the 79633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// most derived class. 80633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const uint64_t MostDerivedClassOffset; 81633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 82633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// LayoutClass - The class we're using for layout information. Will be 83633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// different than the most derived class if the final overriders are for a 84633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// construction vtable. 85633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *LayoutClass; 86633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 87633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ASTContext &Context; 88633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 89633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// MostDerivedClassLayout - the AST record layout of the most derived class. 90633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const ASTRecordLayout &MostDerivedClassLayout; 91633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 92633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// MethodBaseOffsetPairTy - Uniquely identifies a member function 93633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// in a base subobject. 94633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham typedef std::pair<const CXXMethodDecl *, uint64_t> MethodBaseOffsetPairTy; 95633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 96633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham typedef llvm::DenseMap<MethodBaseOffsetPairTy, 97633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OverriderInfo> OverridersMapTy; 98633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 99633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// OverridersMap - The final overriders for all virtual member functions of 100633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// all the base subobjects of the most derived class. 101633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OverridersMapTy OverridersMap; 102633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 103633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// SubobjectsToOffsetsMapTy - A mapping from a base subobject (represented 104633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// as a record decl and a subobject number) and its offsets in the most 105633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// derived class as well as the layout class. 106633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>, 107633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t> SubobjectOffsetMapTy; 108633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 109633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham typedef llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCountMapTy; 110633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 111633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// ComputeBaseOffsets - Compute the offsets for all base subobjects of the 112633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// given base. 113633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham void ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, 114633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t OffsetInLayoutClass, 115633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsetMapTy &SubobjectOffsets, 116633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, 117633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectCountMapTy &SubobjectCounts); 118633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 119633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 120633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 121633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// dump - dump the final overriders for a base subobject, and all its direct 122633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// and indirect base subobjects. 123633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham void dump(llvm::raw_ostream &Out, BaseSubobject Base, 124633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham VisitedVirtualBasesSetTy& VisitedVirtualBases); 125633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 126633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhampublic: 127633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham FinalOverriders(const CXXRecordDecl *MostDerivedClass, 128633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t MostDerivedClassOffset, 129633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *LayoutClass); 130633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 131633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// getOverrider - Get the final overrider for the given method declaration in 132633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// the subobject with the given base offset. 133633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OverriderInfo getOverrider(const CXXMethodDecl *MD, 134633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t BaseOffset) const { 135633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && 136633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Did not find overrider!"); 137633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 138633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return OverridersMap.lookup(std::make_pair(MD, BaseOffset)); 139633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 140633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 141633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// dump - dump the final overriders. 142633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham void dump() { 143633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham VisitedVirtualBasesSetTy VisitedVirtualBases; 144633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0), VisitedVirtualBases); 145633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 146633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 147633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}; 148633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 149633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define DUMP_OVERRIDERS 0 150633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 151633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu GandhamFinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, 152633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t MostDerivedClassOffset, 153633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *LayoutClass) 154633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : MostDerivedClass(MostDerivedClass), 155633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), 156633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Context(MostDerivedClass->getASTContext()), 157633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { 158633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 159633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Compute base offsets. 160633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsetMapTy SubobjectOffsets; 161633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsetMapTy SubobjectLayoutClassOffsets; 162633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectCountMapTy SubobjectCounts; 163633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComputeBaseOffsets(BaseSubobject(MostDerivedClass, 0), /*IsVirtual=*/false, 164633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham MostDerivedClassOffset, SubobjectOffsets, 165633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectLayoutClassOffsets, SubobjectCounts); 166633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 167633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Get the the final overriders. 168633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CXXFinalOverriderMap FinalOverriders; 169633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham MostDerivedClass->getFinalOverriders(FinalOverriders); 170633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 171633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(), 172633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham E = FinalOverriders.end(); I != E; ++I) { 173633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *MD = I->first; 174633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const OverridingMethods& Methods = I->second; 175633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 176633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (OverridingMethods::const_iterator I = Methods.begin(), 177633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham E = Methods.end(); I != E; ++I) { 178633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned SubobjectNumber = I->first; 179633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(SubobjectOffsets.count(std::make_pair(MD->getParent(), 180633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectNumber)) && 181633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Did not find subobject offset!"); 182633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 183633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(), 184633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectNumber)]; 185633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 186633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(I->second.size() == 1 && "Final overrider is not unique!"); 187633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const UniqueVirtualMethod &Method = I->second.front(); 188633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 189633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *OverriderRD = Method.Method->getParent(); 190633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(SubobjectLayoutClassOffsets.count( 191633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham std::make_pair(OverriderRD, Method.Subobject)) 192633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham && "Did not find subobject offset!"); 193633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t OverriderOffset = 194633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectLayoutClassOffsets[std::make_pair(OverriderRD, 195633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Method.Subobject)]; 196633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 197633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OverriderInfo& Overrider = OverridersMap[std::make_pair(MD, BaseOffset)]; 198633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(!Overrider.Method && "Overrider should not exist yet!"); 199633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 200633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Overrider.Offset = OverriderOffset; 201633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Overrider.Method = Method.Method; 202633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 203633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 204633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 205633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if DUMP_OVERRIDERS 206633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // And dump them (for now). 207633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham dump(); 208633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 209633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 210633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 211633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic BaseOffset ComputeBaseOffset(ASTContext &Context, 212633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *DerivedRD, 213633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXBasePath &Path) { 214633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t NonVirtualOffset = 0; 215633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 216633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned NonVirtualStart = 0; 217633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *VirtualBase = 0; 218633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 219633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // First, look for the virtual base class. 220633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (unsigned I = 0, E = Path.size(); I != E; ++I) { 221633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXBasePathElement &Element = Path[I]; 222633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 223633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (Element.Base->isVirtual()) { 224633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // FIXME: Can we break when we find the first virtual base? 225633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // (If we can't, can't we just iterate over the path in reverse order?) 226633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham NonVirtualStart = I + 1; 227633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham QualType VBaseType = Element.Base->getType(); 228633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham VirtualBase = 229633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 230633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 231633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 232633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 233633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Now compute the non-virtual offset. 234633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) { 235633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXBasePathElement &Element = Path[I]; 236633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 237633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Check the base class offset. 238633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); 239633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 240633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>(); 241633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl()); 242633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 243633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham NonVirtualOffset += Layout.getBaseClassOffsetInBits(Base); 244633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 245633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 246633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // FIXME: This should probably use CharUnits or something. Maybe we should 247633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // even change the base offsets in ASTRecordLayout to be specified in 248633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // CharUnits. 249633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset / 8); 250633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 251633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 252633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 253633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic BaseOffset ComputeBaseOffset(ASTContext &Context, 254633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *BaseRD, 255633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *DerivedRD) { 256633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CXXBasePaths Paths(/*FindAmbiguities=*/false, 257633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /*RecordPaths=*/true, /*DetectVirtual=*/false); 258633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 259633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!const_cast<CXXRecordDecl *>(DerivedRD)-> 260633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { 261633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(false && "Class must be derived from the passed in base class!"); 262633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return BaseOffset(); 263633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 264633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 265633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return ComputeBaseOffset(Context, DerivedRD, Paths.front()); 266633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 267633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 268633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic BaseOffset 269633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu GandhamComputeReturnAdjustmentBaseOffset(ASTContext &Context, 270633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *DerivedMD, 271633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *BaseMD) { 272633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>(); 273633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>(); 274633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 275633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Canonicalize the return types. 276633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanQualType CanDerivedReturnType = 277633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Context.getCanonicalType(DerivedFT->getResultType()); 278633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanQualType CanBaseReturnType = 279633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Context.getCanonicalType(BaseFT->getResultType()); 280633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 281633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(CanDerivedReturnType->getTypeClass() == 282633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanBaseReturnType->getTypeClass() && 283633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Types must have same type class!"); 284633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 285633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (CanDerivedReturnType == CanBaseReturnType) { 286633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // No adjustment needed. 287633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return BaseOffset(); 288633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 289633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 290633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (isa<ReferenceType>(CanDerivedReturnType)) { 291633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanDerivedReturnType = 292633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType(); 293633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanBaseReturnType = 294633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanBaseReturnType->getAs<ReferenceType>()->getPointeeType(); 295633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (isa<PointerType>(CanDerivedReturnType)) { 296633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanDerivedReturnType = 297633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanDerivedReturnType->getAs<PointerType>()->getPointeeType(); 298633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanBaseReturnType = 299633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanBaseReturnType->getAs<PointerType>()->getPointeeType(); 300633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 301633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(false && "Unexpected return type!"); 302633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 303633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 304633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // We need to compare unqualified types here; consider 305633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // const T *Base::foo(); 306633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // T *Derived::foo(); 307633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (CanDerivedReturnType.getUnqualifiedType() == 308633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanBaseReturnType.getUnqualifiedType()) { 309633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // No adjustment needed. 310633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return BaseOffset(); 311633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 312633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 313633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *DerivedRD = 314633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()); 315633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 316633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *BaseRD = 317633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); 318633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 319633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return ComputeBaseOffset(Context, BaseRD, DerivedRD); 320633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 321633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 322633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamvoid 323633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu GandhamFinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, 324633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t OffsetInLayoutClass, 325633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsetMapTy &SubobjectOffsets, 326633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, 327633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectCountMapTy &SubobjectCounts) { 328633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *RD = Base.getBase(); 329633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 330633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned SubobjectNumber = 0; 331633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!IsVirtual) 332633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectNumber = ++SubobjectCounts[RD]; 333633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 334633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Set up the subobject to offset mapping. 335633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(!SubobjectOffsets.count(std::make_pair(RD, SubobjectNumber)) 336633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham && "Subobject offset already exists!"); 337633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber)) 338633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham && "Subobject offset already exists!"); 339633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 340633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectOffsets[std::make_pair(RD, SubobjectNumber)] = 341633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Base.getBaseOffset(); 342633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectLayoutClassOffsets[std::make_pair(RD, SubobjectNumber)] = 343633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OffsetInLayoutClass; 344633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 345633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Traverse our bases. 346633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 347633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham E = RD->bases_end(); I != E; ++I) { 348633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *BaseDecl = 349633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 350633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 351633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t BaseOffset; 352633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t BaseOffsetInLayoutClass; 353633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (I->isVirtual()) { 354633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Check if we've visited this virtual base before. 355633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0))) 356633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham continue; 357633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 358633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const ASTRecordLayout &LayoutClassLayout = 359633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Context.getASTRecordLayout(LayoutClass); 360633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 361633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset = MostDerivedClassLayout.getVBaseClassOffsetInBits(BaseDecl); 362633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffsetInLayoutClass = 363633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham LayoutClassLayout.getVBaseClassOffsetInBits(BaseDecl); 364633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 365633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 366633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t Offset = Layout.getBaseClassOffsetInBits(BaseDecl); 367633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 368633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset = Base.getBaseOffset() + Offset; 369633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffsetInLayoutClass = OffsetInLayoutClass + Offset; 370633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 371633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 372633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), I->isVirtual(), 373633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffsetInLayoutClass, SubobjectOffsets, 374633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham SubobjectLayoutClassOffsets, SubobjectCounts); 375633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 376633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 377633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 378633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamvoid FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base, 379633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham VisitedVirtualBasesSetTy &VisitedVirtualBases) { 380633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *RD = Base.getBase(); 381633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 382633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 383633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 384633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham E = RD->bases_end(); I != E; ++I) { 385633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *BaseDecl = 386633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 387633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 388633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Ignore bases that don't have any virtual member functions. 389633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!BaseDecl->isPolymorphic()) 390633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham continue; 391633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 392633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uint64_t BaseOffset; 393633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (I->isVirtual()) { 394633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!VisitedVirtualBases.insert(BaseDecl)) { 395633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // We've visited this base before. 396633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham continue; 397633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 398633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 399633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset = MostDerivedClassLayout.getVBaseClassOffsetInBits(BaseDecl); 400633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 401633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset = Layout.getBaseClassOffsetInBits(BaseDecl) + 402633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Base.getBaseOffset(); 403633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 404633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 405633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases); 406633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 407633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 408633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", "; 409633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << Base.getBaseOffset() / 8 << ")\n"; 410633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 411633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Now dump the overriders for this base subobject. 412633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (CXXRecordDecl::method_iterator I = RD->method_begin(), 413633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham E = RD->method_end(); I != E; ++I) { 414633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *MD = *I; 415633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 416633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!MD->isVirtual()) 417633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham continue; 418633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 419633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset()); 420633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 421633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << " " << MD->getQualifiedNameAsString() << " - ("; 422633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << Overrider.Method->getQualifiedNameAsString(); 423633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << ", " << ", " << Overrider.Offset / 8 << ')'; 424633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 425633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BaseOffset Offset; 426633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!Overrider.Method->isPure()) 427633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Offset = ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); 428633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 429633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!Offset.isEmpty()) { 430633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << " [ret-adj: "; 431633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (Offset.VirtualBase) 432633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, "; 433633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 434633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << Offset.NonVirtualOffset << " nv]"; 435633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 436633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 437633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Out << "\n"; 438633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 439633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 440633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 441633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/// VTableComponent - Represents a single component in a vtable. 442633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamclass VTableComponent { 443633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhampublic: 444633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham enum Kind { 445633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_VCallOffset, 446633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_VBaseOffset, 447633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_OffsetToTop, 448633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_RTTI, 449633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_FunctionPointer, 450633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 451633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// CK_CompleteDtorPointer - A pointer to the complete destructor. 452633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_CompleteDtorPointer, 453633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 454633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// CK_DeletingDtorPointer - A pointer to the deleting destructor. 455633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_DeletingDtorPointer, 456633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 457633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer 458633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// will end up never being called. Such vtable function pointers are 459633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// represented as a CK_UnusedFunctionPointer. 460633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CK_UnusedFunctionPointer 461633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham }; 462633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 463633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeVCallOffset(int64_t Offset) { 464633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_VCallOffset, Offset); 465633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 466633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 467633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeVBaseOffset(int64_t Offset) { 468633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_VBaseOffset, Offset); 469633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 470633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 471633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeOffsetToTop(int64_t Offset) { 472633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_OffsetToTop, Offset); 473633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 474633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 475633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeRTTI(const CXXRecordDecl *RD) { 476633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD)); 477633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 478633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 479633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeFunction(const CXXMethodDecl *MD) { 480633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(!isa<CXXDestructorDecl>(MD) && 481633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Don't use MakeFunction with destructors!"); 482633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 483633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_FunctionPointer, 484633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham reinterpret_cast<uintptr_t>(MD)); 485633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 486633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 487633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) { 488633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_CompleteDtorPointer, 489633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham reinterpret_cast<uintptr_t>(DD)); 490633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 491633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 492633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) { 493633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_DeletingDtorPointer, 494633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham reinterpret_cast<uintptr_t>(DD)); 495633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 496633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 497633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) { 498633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(!isa<CXXDestructorDecl>(MD) && 499633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Don't use MakeUnusedFunction with destructors!"); 500633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(CK_UnusedFunctionPointer, 501633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham reinterpret_cast<uintptr_t>(MD)); 502633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 503633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 504633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static VTableComponent getFromOpaqueInteger(uint64_t I) { 505633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return VTableComponent(I); 506633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 507633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 508633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// getKind - Get the kind of this vtable component. 509633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Kind getKind() const { 510633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return (Kind)(Value & 0x7); 511633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 512633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 513633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t getVCallOffset() const { 514633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(getKind() == CK_VCallOffset && "Invalid component kind!"); 515633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 516633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return getOffset(); 517633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 518633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 519633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t getVBaseOffset() const { 520633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(getKind() == CK_VBaseOffset && "Invalid component kind!"); 521633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 522633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return getOffset(); 523633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 524633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 525633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t getOffsetToTop() const { 526633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(getKind() == CK_OffsetToTop && "Invalid component kind!"); 527633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 528633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return getOffset(); 529633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 530633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 531633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXRecordDecl *getRTTIDecl() const { 532633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(getKind() == CK_RTTI && "Invalid component kind!"); 533633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 534633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return reinterpret_cast<CXXRecordDecl *>(getPointer()); 535633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 536633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 537633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *getFunctionDecl() const { 538633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(getKind() == CK_FunctionPointer); 539633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 540633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return reinterpret_cast<CXXMethodDecl *>(getPointer()); 541633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 542633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 543633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXDestructorDecl *getDestructorDecl() const { 544633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert((getKind() == CK_CompleteDtorPointer || 545633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); 546633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 547633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return reinterpret_cast<CXXDestructorDecl *>(getPointer()); 548633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 549633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 550633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *getUnusedFunctionDecl() const { 551633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(getKind() == CK_UnusedFunctionPointer); 552633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 553633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return reinterpret_cast<CXXMethodDecl *>(getPointer()); 554633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 555633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 556633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamprivate: 557633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham VTableComponent(Kind ComponentKind, int64_t Offset) { 558633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert((ComponentKind == CK_VCallOffset || 559633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComponentKind == CK_VBaseOffset || 560633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComponentKind == CK_OffsetToTop) && "Invalid component kind!"); 561633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(Offset <= ((1LL << 56) - 1) && "Offset is too big!"); 562633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 563633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Value = ((Offset << 3) | ComponentKind); 564633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 565633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 566633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham VTableComponent(Kind ComponentKind, uintptr_t Ptr) { 567633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert((ComponentKind == CK_RTTI || 568633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComponentKind == CK_FunctionPointer || 569633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComponentKind == CK_CompleteDtorPointer || 570633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComponentKind == CK_DeletingDtorPointer || 571633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ComponentKind == CK_UnusedFunctionPointer) && 572633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Invalid component kind!"); 573633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 574633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); 575633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 576633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham Value = Ptr | ComponentKind; 577633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 578633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 579633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t getOffset() const { 580633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset || 581633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham getKind() == CK_OffsetToTop) && "Invalid component kind!"); 582633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 583633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return Value >> 3; 584633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 585633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 586633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham uintptr_t getPointer() const { 587633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert((getKind() == CK_RTTI || 588633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham getKind() == CK_FunctionPointer || 589633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham getKind() == CK_CompleteDtorPointer || 590633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham getKind() == CK_DeletingDtorPointer || 591633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham getKind() == CK_UnusedFunctionPointer) && 592633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "Invalid component kind!"); 593633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 594633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return static_cast<uintptr_t>(Value & ~7ULL); 595633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 596633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 597633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham explicit VTableComponent(uint64_t Value) 598633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : Value(Value) { } 599633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 600633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// The kind is stored in the lower 3 bits of the value. For offsets, we 601633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// make use of the facts that classes can't be larger than 2^55 bytes, 602633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// so we store the offset in the lower part of the 61 bytes that remain. 603633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// (The reason that we're not simply using a PointerIntPair here is that we 604633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// need the offsets to be 64-bit, even when on a 32-bit machine). 605633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t Value; 606633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}; 607633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 608633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/// VCallOffsetMap - Keeps track of vcall offsets when building a vtable. 609633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstruct VCallOffsetMap { 610633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 611633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham typedef std::pair<const CXXMethodDecl *, int64_t> MethodAndOffsetPairTy; 612633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 613633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// Offsets - Keeps track of methods and their offsets. 614633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // FIXME: This should be a real map and not a vector. 615633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham llvm::SmallVector<MethodAndOffsetPairTy, 16> Offsets; 616633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 617633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// MethodsCanShareVCallOffset - Returns whether two virtual member functions 618633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// can share the same vcall offset. 619633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 620633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *RHS); 621633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 622633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhampublic: 623633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the 624633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// add was successful, or false if there was already a member function with 625633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// the same signature in the map. 626633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham bool AddVCallOffset(const CXXMethodDecl *MD, int64_t OffsetOffset); 627633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 628633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the 629633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham /// vtable address point) for the given virtual member function. 630633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int64_t getVCallOffsetOffset(const CXXMethodDecl *MD); 631633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 632633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // empty - Return whether the offset map is empty or not. 633633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham bool empty() const { return Offsets.empty(); } 634633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}; 635633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 636633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic bool HasSameVirtualSignature(const CXXMethodDecl *LHS, 637633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *RHS) { 638633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham ASTContext &C = LHS->getASTContext(); // TODO: thread this down 639633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham CanQual<FunctionProtoType> 640633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham LT = C.getCanonicalType(LHS->getType()).getAs<FunctionProtoType>(), 641633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham RT = C.getCanonicalType(RHS->getType()).getAs<FunctionProtoType>(); 642633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 643633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Fast-path matches in the canonical types. 644633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (LT == RT) return true; 645633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 646633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // Force the signatures to match. We can't rely on the overrides 647633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // list here because there isn't necessarily an inheritance 648633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // relationship between the two methods. 649633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (LT.getQualifiers() != RT.getQualifiers() || 650633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham LT->getNumArgs() != RT->getNumArgs()) 651633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return false; 652633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) 653633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (LT->getArgType(I) != RT->getArgType(I)) 654633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return false; 655633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return true; 656633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 657633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 658633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhambool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 659633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const CXXMethodDecl *RHS) { 660633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(LHS->isVirtual() && "LHS must be virtual!"); 661633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham assert(RHS->isVirtual() && "LHS must be virtual!"); 662633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 663633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham // A destructor can share a vcall offset with another destructor. 664 if (isa<CXXDestructorDecl>(LHS)) 665 return isa<CXXDestructorDecl>(RHS); 666 667 // FIXME: We need to check more things here. 668 669 // The methods must have the same name. 670 DeclarationName LHSName = LHS->getDeclName(); 671 DeclarationName RHSName = RHS->getDeclName(); 672 if (LHSName != RHSName) 673 return false; 674 675 // And the same signatures. 676 return HasSameVirtualSignature(LHS, RHS); 677} 678 679bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, 680 int64_t OffsetOffset) { 681 // Check if we can reuse an offset. 682 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 683 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 684 return false; 685 } 686 687 // Add the offset. 688 Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset)); 689 return true; 690} 691 692int64_t VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { 693 // Look for an offset. 694 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 695 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 696 return Offsets[I].second; 697 } 698 699 assert(false && "Should always find a vcall offset offset!"); 700 return 0; 701} 702 703/// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. 704class VCallAndVBaseOffsetBuilder { 705public: 706 typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 707 VBaseOffsetOffsetsMapTy; 708 709private: 710 /// MostDerivedClass - The most derived class for which we're building vcall 711 /// and vbase offsets. 712 const CXXRecordDecl *MostDerivedClass; 713 714 /// LayoutClass - The class we're using for layout information. Will be 715 /// different than the most derived class if we're building a construction 716 /// vtable. 717 const CXXRecordDecl *LayoutClass; 718 719 /// Context - The ASTContext which we will use for layout information. 720 ASTContext &Context; 721 722 /// Components - vcall and vbase offset components 723 typedef llvm::SmallVector<VTableComponent, 64> VTableComponentVectorTy; 724 VTableComponentVectorTy Components; 725 726 /// VisitedVirtualBases - Visited virtual bases. 727 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 728 729 /// VCallOffsets - Keeps track of vcall offsets. 730 VCallOffsetMap VCallOffsets; 731 732 733 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets, 734 /// relative to the address point. 735 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 736 737 /// FinalOverriders - The final overriders of the most derived class. 738 /// (Can be null when we're not building a vtable of the most derived class). 739 const FinalOverriders *Overriders; 740 741 /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the 742 /// given base subobject. 743 void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, 744 uint64_t RealBaseOffset); 745 746 /// AddVCallOffsets - Add vcall offsets for the given base subobject. 747 void AddVCallOffsets(BaseSubobject Base, uint64_t VBaseOffset); 748 749 /// AddVBaseOffsets - Add vbase offsets for the given class. 750 void AddVBaseOffsets(const CXXRecordDecl *Base, uint64_t OffsetInLayoutClass); 751 752 /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in 753 /// bytes, relative to the vtable address point. 754 int64_t getCurrentOffsetOffset() const; 755 756public: 757 VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, 758 const CXXRecordDecl *LayoutClass, 759 const FinalOverriders *Overriders, 760 BaseSubobject Base, bool BaseIsVirtual, 761 uint64_t OffsetInLayoutClass) 762 : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 763 Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { 764 765 // Add vcall and vbase offsets. 766 AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); 767 } 768 769 /// Methods for iterating over the components. 770 typedef VTableComponentVectorTy::const_reverse_iterator const_iterator; 771 const_iterator components_begin() const { return Components.rbegin(); } 772 const_iterator components_end() const { return Components.rend(); } 773 774 const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; } 775 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 776 return VBaseOffsetOffsets; 777 } 778}; 779 780void 781VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, 782 bool BaseIsVirtual, 783 uint64_t RealBaseOffset) { 784 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); 785 786 // Itanium C++ ABI 2.5.2: 787 // ..in classes sharing a virtual table with a primary base class, the vcall 788 // and vbase offsets added by the derived class all come before the vcall 789 // and vbase offsets required by the base class, so that the latter may be 790 // laid out as required by the base class without regard to additions from 791 // the derived class(es). 792 793 // (Since we're emitting the vcall and vbase offsets in reverse order, we'll 794 // emit them for the primary base first). 795 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 796 bool PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); 797 798 uint64_t PrimaryBaseOffset; 799 800 // Get the base offset of the primary base. 801 if (PrimaryBaseIsVirtual) { 802 assert(Layout.getVBaseClassOffsetInBits(PrimaryBase) == 0 && 803 "Primary vbase should have a zero offset!"); 804 805 const ASTRecordLayout &MostDerivedClassLayout = 806 Context.getASTRecordLayout(MostDerivedClass); 807 808 PrimaryBaseOffset = 809 MostDerivedClassLayout.getVBaseClassOffsetInBits(PrimaryBase); 810 } else { 811 assert(Layout.getBaseClassOffsetInBits(PrimaryBase) == 0 && 812 "Primary base should have a zero offset!"); 813 814 PrimaryBaseOffset = Base.getBaseOffset(); 815 } 816 817 AddVCallAndVBaseOffsets(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 818 PrimaryBaseIsVirtual, RealBaseOffset); 819 } 820 821 AddVBaseOffsets(Base.getBase(), RealBaseOffset); 822 823 // We only want to add vcall offsets for virtual bases. 824 if (BaseIsVirtual) 825 AddVCallOffsets(Base, RealBaseOffset); 826} 827 828int64_t VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const { 829 // OffsetIndex is the index of this vcall or vbase offset, relative to the 830 // vtable address point. (We subtract 3 to account for the information just 831 // above the address point, the RTTI info, the offset to top, and the 832 // vcall offset itself). 833 int64_t OffsetIndex = -(int64_t)(3 + Components.size()); 834 835 // FIXME: We shouldn't use / 8 here. 836 int64_t OffsetOffset = OffsetIndex * 837 (int64_t)Context.Target.getPointerWidth(0) / 8; 838 839 return OffsetOffset; 840} 841 842void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 843 uint64_t VBaseOffset) { 844 const CXXRecordDecl *RD = Base.getBase(); 845 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 846 847 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 848 849 // Handle the primary base first. 850 // We only want to add vcall offsets if the base is non-virtual; a virtual 851 // primary base will have its vcall and vbase offsets emitted already. 852 if (PrimaryBase && !Layout.isPrimaryBaseVirtual()) { 853 // Get the base offset of the primary base. 854 assert(Layout.getBaseClassOffsetInBits(PrimaryBase) == 0 && 855 "Primary base should have a zero offset!"); 856 857 AddVCallOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()), 858 VBaseOffset); 859 } 860 861 // Add the vcall offsets. 862 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 863 E = RD->method_end(); I != E; ++I) { 864 const CXXMethodDecl *MD = *I; 865 866 if (!MD->isVirtual()) 867 continue; 868 869 int64_t OffsetOffset = getCurrentOffsetOffset(); 870 871 // Don't add a vcall offset if we already have one for this member function 872 // signature. 873 if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset)) 874 continue; 875 876 int64_t Offset = 0; 877 878 if (Overriders) { 879 // Get the final overrider. 880 FinalOverriders::OverriderInfo Overrider = 881 Overriders->getOverrider(MD, Base.getBaseOffset()); 882 883 /// The vcall offset is the offset from the virtual base to the object 884 /// where the function was overridden. 885 // FIXME: We should not use / 8 here. 886 Offset = (int64_t)(Overrider.Offset - VBaseOffset) / 8; 887 } 888 889 Components.push_back(VTableComponent::MakeVCallOffset(Offset)); 890 } 891 892 // And iterate over all non-virtual bases (ignoring the primary base). 893 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 894 E = RD->bases_end(); I != E; ++I) { 895 896 if (I->isVirtual()) 897 continue; 898 899 const CXXRecordDecl *BaseDecl = 900 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 901 if (BaseDecl == PrimaryBase) 902 continue; 903 904 // Get the base offset of this base. 905 uint64_t BaseOffset = Base.getBaseOffset() + 906 Layout.getBaseClassOffsetInBits(BaseDecl); 907 908 AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), VBaseOffset); 909 } 910} 911 912void VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, 913 uint64_t OffsetInLayoutClass) { 914 const ASTRecordLayout &LayoutClassLayout = 915 Context.getASTRecordLayout(LayoutClass); 916 917 // Add vbase offsets. 918 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 919 E = RD->bases_end(); I != E; ++I) { 920 const CXXRecordDecl *BaseDecl = 921 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 922 923 // Check if this is a virtual base that we haven't visited before. 924 if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) { 925 // FIXME: We shouldn't use / 8 here. 926 int64_t Offset = 927 (int64_t)(LayoutClassLayout.getVBaseClassOffsetInBits(BaseDecl) - 928 OffsetInLayoutClass) / 8; 929 930 // Add the vbase offset offset. 931 assert(!VBaseOffsetOffsets.count(BaseDecl) && 932 "vbase offset offset already exists!"); 933 934 int64_t VBaseOffsetOffset = getCurrentOffsetOffset(); 935 VBaseOffsetOffsets.insert(std::make_pair(BaseDecl, VBaseOffsetOffset)); 936 937 Components.push_back(VTableComponent::MakeVBaseOffset(Offset)); 938 } 939 940 // Check the base class looking for more vbase offsets. 941 AddVBaseOffsets(BaseDecl, OffsetInLayoutClass); 942 } 943} 944 945/// VTableBuilder - Class for building vtable layout information. 946class VTableBuilder { 947public: 948 /// PrimaryBasesSetVectorTy - A set vector of direct and indirect 949 /// primary bases. 950 typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> 951 PrimaryBasesSetVectorTy; 952 953 typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 954 VBaseOffsetOffsetsMapTy; 955 956 typedef llvm::DenseMap<BaseSubobject, uint64_t> 957 AddressPointsMapTy; 958 959private: 960 /// VTables - Global vtable information. 961 CodeGenVTables &VTables; 962 963 /// MostDerivedClass - The most derived class for which we're building this 964 /// vtable. 965 const CXXRecordDecl *MostDerivedClass; 966 967 /// MostDerivedClassOffset - If we're building a construction vtable, this 968 /// holds the offset from the layout class to the most derived class. 969 const uint64_t MostDerivedClassOffset; 970 971 /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual 972 /// base. (This only makes sense when building a construction vtable). 973 bool MostDerivedClassIsVirtual; 974 975 /// LayoutClass - The class we're using for layout information. Will be 976 /// different than the most derived class if we're building a construction 977 /// vtable. 978 const CXXRecordDecl *LayoutClass; 979 980 /// Context - The ASTContext which we will use for layout information. 981 ASTContext &Context; 982 983 /// FinalOverriders - The final overriders of the most derived class. 984 const FinalOverriders Overriders; 985 986 /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual 987 /// bases in this vtable. 988 llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases; 989 990 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for 991 /// the most derived class. 992 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 993 994 /// Components - The components of the vtable being built. 995 llvm::SmallVector<VTableComponent, 64> Components; 996 997 /// AddressPoints - Address points for the vtable being built. 998 AddressPointsMapTy AddressPoints; 999 1000 /// MethodInfo - Contains information about a method in a vtable. 1001 /// (Used for computing 'this' pointer adjustment thunks. 1002 struct MethodInfo { 1003 /// BaseOffset - The base offset of this method. 1004 const uint64_t BaseOffset; 1005 1006 /// BaseOffsetInLayoutClass - The base offset in the layout class of this 1007 /// method. 1008 const uint64_t BaseOffsetInLayoutClass; 1009 1010 /// VTableIndex - The index in the vtable that this method has. 1011 /// (For destructors, this is the index of the complete destructor). 1012 const uint64_t VTableIndex; 1013 1014 MethodInfo(uint64_t BaseOffset, uint64_t BaseOffsetInLayoutClass, 1015 uint64_t VTableIndex) 1016 : BaseOffset(BaseOffset), 1017 BaseOffsetInLayoutClass(BaseOffsetInLayoutClass), 1018 VTableIndex(VTableIndex) { } 1019 1020 MethodInfo() : BaseOffset(0), BaseOffsetInLayoutClass(0), VTableIndex(0) { } 1021 }; 1022 1023 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 1024 1025 /// MethodInfoMap - The information for all methods in the vtable we're 1026 /// currently building. 1027 MethodInfoMapTy MethodInfoMap; 1028 1029 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy; 1030 1031 /// VTableThunks - The thunks by vtable index in the vtable currently being 1032 /// built. 1033 VTableThunksMapTy VTableThunks; 1034 1035 typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 1036 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 1037 1038 /// Thunks - A map that contains all the thunks needed for all methods in the 1039 /// most derived class for which the vtable is currently being built. 1040 ThunksMapTy Thunks; 1041 1042 /// AddThunk - Add a thunk for the given method. 1043 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk); 1044 1045 /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the 1046 /// part of the vtable we're currently building. 1047 void ComputeThisAdjustments(); 1048 1049 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 1050 1051 /// PrimaryVirtualBases - All known virtual bases who are a primary base of 1052 /// some other base. 1053 VisitedVirtualBasesSetTy PrimaryVirtualBases; 1054 1055 /// ComputeReturnAdjustment - Compute the return adjustment given a return 1056 /// adjustment base offset. 1057 ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset); 1058 1059 /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting 1060 /// the 'this' pointer from the base subobject to the derived subobject. 1061 BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 1062 BaseSubobject Derived) const; 1063 1064 /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the 1065 /// given virtual member function, its offset in the layout class and its 1066 /// final overrider. 1067 ThisAdjustment 1068 ComputeThisAdjustment(const CXXMethodDecl *MD, 1069 uint64_t BaseOffsetInLayoutClass, 1070 FinalOverriders::OverriderInfo Overrider); 1071 1072 /// AddMethod - Add a single virtual member function to the vtable 1073 /// components vector. 1074 void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment); 1075 1076 /// IsOverriderUsed - Returns whether the overrider will ever be used in this 1077 /// part of the vtable. 1078 /// 1079 /// Itanium C++ ABI 2.5.2: 1080 /// 1081 /// struct A { virtual void f(); }; 1082 /// struct B : virtual public A { int i; }; 1083 /// struct C : virtual public A { int j; }; 1084 /// struct D : public B, public C {}; 1085 /// 1086 /// When B and C are declared, A is a primary base in each case, so although 1087 /// vcall offsets are allocated in the A-in-B and A-in-C vtables, no this 1088 /// adjustment is required and no thunk is generated. However, inside D 1089 /// objects, A is no longer a primary base of C, so if we allowed calls to 1090 /// C::f() to use the copy of A's vtable in the C subobject, we would need 1091 /// to adjust this from C* to B::A*, which would require a third-party 1092 /// thunk. Since we require that a call to C::f() first convert to A*, 1093 /// C-in-D's copy of A's vtable is never referenced, so this is not 1094 /// necessary. 1095 bool IsOverriderUsed(const CXXMethodDecl *Overrider, 1096 uint64_t BaseOffsetInLayoutClass, 1097 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1098 uint64_t FirstBaseOffsetInLayoutClass) const; 1099 1100 1101 /// AddMethods - Add the methods of this base subobject and all its 1102 /// primary bases to the vtable components vector. 1103 void AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, 1104 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1105 uint64_t FirstBaseOffsetInLayoutClass, 1106 PrimaryBasesSetVectorTy &PrimaryBases); 1107 1108 // LayoutVTable - Layout the vtable for the given base class, including its 1109 // secondary vtables and any vtables for virtual bases. 1110 void LayoutVTable(); 1111 1112 /// LayoutPrimaryAndSecondaryVTables - Layout the primary vtable for the 1113 /// given base subobject, as well as all its secondary vtables. 1114 /// 1115 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 1116 /// or a direct or indirect base of a virtual base. 1117 /// 1118 /// \param BaseIsVirtualInLayoutClass - Whether the base subobject is virtual 1119 /// in the layout class. 1120 void LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, 1121 bool BaseIsMorallyVirtual, 1122 bool BaseIsVirtualInLayoutClass, 1123 uint64_t OffsetInLayoutClass); 1124 1125 /// LayoutSecondaryVTables - Layout the secondary vtables for the given base 1126 /// subobject. 1127 /// 1128 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 1129 /// or a direct or indirect base of a virtual base. 1130 void LayoutSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual, 1131 uint64_t OffsetInLayoutClass); 1132 1133 /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this 1134 /// class hierarchy. 1135 void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 1136 uint64_t OffsetInLayoutClass, 1137 VisitedVirtualBasesSetTy &VBases); 1138 1139 /// LayoutVTablesForVirtualBases - Layout vtables for all virtual bases of the 1140 /// given base (excluding any primary bases). 1141 void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 1142 VisitedVirtualBasesSetTy &VBases); 1143 1144 /// isBuildingConstructionVTable - Return whether this vtable builder is 1145 /// building a construction vtable. 1146 bool isBuildingConstructorVTable() const { 1147 return MostDerivedClass != LayoutClass; 1148 } 1149 1150public: 1151 VTableBuilder(CodeGenVTables &VTables, const CXXRecordDecl *MostDerivedClass, 1152 uint64_t MostDerivedClassOffset, bool MostDerivedClassIsVirtual, 1153 const CXXRecordDecl *LayoutClass) 1154 : VTables(VTables), MostDerivedClass(MostDerivedClass), 1155 MostDerivedClassOffset(MostDerivedClassOffset), 1156 MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 1157 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 1158 Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) { 1159 1160 LayoutVTable(); 1161 } 1162 1163 ThunksMapTy::const_iterator thunks_begin() const { 1164 return Thunks.begin(); 1165 } 1166 1167 ThunksMapTy::const_iterator thunks_end() const { 1168 return Thunks.end(); 1169 } 1170 1171 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 1172 return VBaseOffsetOffsets; 1173 } 1174 1175 /// getNumVTableComponents - Return the number of components in the vtable 1176 /// currently built. 1177 uint64_t getNumVTableComponents() const { 1178 return Components.size(); 1179 } 1180 1181 const uint64_t *vtable_components_data_begin() const { 1182 return reinterpret_cast<const uint64_t *>(Components.begin()); 1183 } 1184 1185 const uint64_t *vtable_components_data_end() const { 1186 return reinterpret_cast<const uint64_t *>(Components.end()); 1187 } 1188 1189 AddressPointsMapTy::const_iterator address_points_begin() const { 1190 return AddressPoints.begin(); 1191 } 1192 1193 AddressPointsMapTy::const_iterator address_points_end() const { 1194 return AddressPoints.end(); 1195 } 1196 1197 VTableThunksMapTy::const_iterator vtable_thunks_begin() const { 1198 return VTableThunks.begin(); 1199 } 1200 1201 VTableThunksMapTy::const_iterator vtable_thunks_end() const { 1202 return VTableThunks.end(); 1203 } 1204 1205 /// dumpLayout - Dump the vtable layout. 1206 void dumpLayout(llvm::raw_ostream&); 1207}; 1208 1209void VTableBuilder::AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) { 1210 assert(!isBuildingConstructorVTable() && 1211 "Can't add thunks for construction vtable"); 1212 1213 llvm::SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD]; 1214 1215 // Check if we have this thunk already. 1216 if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 1217 ThunksVector.end()) 1218 return; 1219 1220 ThunksVector.push_back(Thunk); 1221} 1222 1223typedef llvm::SmallPtrSet<const CXXMethodDecl *, 8> OverriddenMethodsSetTy; 1224 1225/// ComputeAllOverriddenMethods - Given a method decl, will return a set of all 1226/// the overridden methods that the function decl overrides. 1227static void 1228ComputeAllOverriddenMethods(const CXXMethodDecl *MD, 1229 OverriddenMethodsSetTy& OverriddenMethods) { 1230 assert(MD->isVirtual() && "Method is not virtual!"); 1231 1232 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1233 E = MD->end_overridden_methods(); I != E; ++I) { 1234 const CXXMethodDecl *OverriddenMD = *I; 1235 1236 OverriddenMethods.insert(OverriddenMD); 1237 1238 ComputeAllOverriddenMethods(OverriddenMD, OverriddenMethods); 1239 } 1240} 1241 1242void VTableBuilder::ComputeThisAdjustments() { 1243 // Now go through the method info map and see if any of the methods need 1244 // 'this' pointer adjustments. 1245 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 1246 E = MethodInfoMap.end(); I != E; ++I) { 1247 const CXXMethodDecl *MD = I->first; 1248 const MethodInfo &MethodInfo = I->second; 1249 1250 // Ignore adjustments for unused function pointers. 1251 uint64_t VTableIndex = MethodInfo.VTableIndex; 1252 if (Components[VTableIndex].getKind() == 1253 VTableComponent::CK_UnusedFunctionPointer) 1254 continue; 1255 1256 // Get the final overrider for this method. 1257 FinalOverriders::OverriderInfo Overrider = 1258 Overriders.getOverrider(MD, MethodInfo.BaseOffset); 1259 1260 // Check if we need an adjustment at all. 1261 if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) { 1262 // When a return thunk is needed by a derived class that overrides a 1263 // virtual base, gcc uses a virtual 'this' adjustment as well. 1264 // While the thunk itself might be needed by vtables in subclasses or 1265 // in construction vtables, there doesn't seem to be a reason for using 1266 // the thunk in this vtable. Still, we do so to match gcc. 1267 if (VTableThunks.lookup(VTableIndex).Return.isEmpty()) 1268 continue; 1269 } 1270 1271 ThisAdjustment ThisAdjustment = 1272 ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider); 1273 1274 if (ThisAdjustment.isEmpty()) 1275 continue; 1276 1277 // Add it. 1278 VTableThunks[VTableIndex].This = ThisAdjustment; 1279 1280 if (isa<CXXDestructorDecl>(MD)) { 1281 // Add an adjustment for the deleting destructor as well. 1282 VTableThunks[VTableIndex + 1].This = ThisAdjustment; 1283 } 1284 } 1285 1286 /// Clear the method info map. 1287 MethodInfoMap.clear(); 1288 1289 if (isBuildingConstructorVTable()) { 1290 // We don't need to store thunk information for construction vtables. 1291 return; 1292 } 1293 1294 for (VTableThunksMapTy::const_iterator I = VTableThunks.begin(), 1295 E = VTableThunks.end(); I != E; ++I) { 1296 const VTableComponent &Component = Components[I->first]; 1297 const ThunkInfo &Thunk = I->second; 1298 const CXXMethodDecl *MD; 1299 1300 switch (Component.getKind()) { 1301 default: 1302 llvm_unreachable("Unexpected vtable component kind!"); 1303 case VTableComponent::CK_FunctionPointer: 1304 MD = Component.getFunctionDecl(); 1305 break; 1306 case VTableComponent::CK_CompleteDtorPointer: 1307 MD = Component.getDestructorDecl(); 1308 break; 1309 case VTableComponent::CK_DeletingDtorPointer: 1310 // We've already added the thunk when we saw the complete dtor pointer. 1311 continue; 1312 } 1313 1314 if (MD->getParent() == MostDerivedClass) 1315 AddThunk(MD, Thunk); 1316 } 1317} 1318 1319ReturnAdjustment VTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { 1320 ReturnAdjustment Adjustment; 1321 1322 if (!Offset.isEmpty()) { 1323 if (Offset.VirtualBase) { 1324 // Get the virtual base offset offset. 1325 if (Offset.DerivedClass == MostDerivedClass) { 1326 // We can get the offset offset directly from our map. 1327 Adjustment.VBaseOffsetOffset = 1328 VBaseOffsetOffsets.lookup(Offset.VirtualBase); 1329 } else { 1330 Adjustment.VBaseOffsetOffset = 1331 VTables.getVirtualBaseOffsetOffset(Offset.DerivedClass, 1332 Offset.VirtualBase); 1333 } 1334 } 1335 1336 Adjustment.NonVirtual = Offset.NonVirtualOffset; 1337 } 1338 1339 return Adjustment; 1340} 1341 1342BaseOffset 1343VTableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 1344 BaseSubobject Derived) const { 1345 const CXXRecordDecl *BaseRD = Base.getBase(); 1346 const CXXRecordDecl *DerivedRD = Derived.getBase(); 1347 1348 CXXBasePaths Paths(/*FindAmbiguities=*/true, 1349 /*RecordPaths=*/true, /*DetectVirtual=*/true); 1350 1351 if (!const_cast<CXXRecordDecl *>(DerivedRD)-> 1352 isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { 1353 assert(false && "Class must be derived from the passed in base class!"); 1354 return BaseOffset(); 1355 } 1356 1357 // We have to go through all the paths, and see which one leads us to the 1358 // right base subobject. 1359 for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end(); 1360 I != E; ++I) { 1361 BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I); 1362 1363 // FIXME: Should not use * 8 here. 1364 uint64_t OffsetToBaseSubobject = Offset.NonVirtualOffset * 8; 1365 1366 if (Offset.VirtualBase) { 1367 // If we have a virtual base class, the non-virtual offset is relative 1368 // to the virtual base class offset. 1369 const ASTRecordLayout &LayoutClassLayout = 1370 Context.getASTRecordLayout(LayoutClass); 1371 1372 /// Get the virtual base offset, relative to the most derived class 1373 /// layout. 1374 OffsetToBaseSubobject += 1375 LayoutClassLayout.getVBaseClassOffsetInBits(Offset.VirtualBase); 1376 } else { 1377 // Otherwise, the non-virtual offset is relative to the derived class 1378 // offset. 1379 OffsetToBaseSubobject += Derived.getBaseOffset(); 1380 } 1381 1382 // Check if this path gives us the right base subobject. 1383 if (OffsetToBaseSubobject == Base.getBaseOffset()) { 1384 // Since we're going from the base class _to_ the derived class, we'll 1385 // invert the non-virtual offset here. 1386 Offset.NonVirtualOffset = -Offset.NonVirtualOffset; 1387 return Offset; 1388 } 1389 } 1390 1391 return BaseOffset(); 1392} 1393 1394ThisAdjustment 1395VTableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, 1396 uint64_t BaseOffsetInLayoutClass, 1397 FinalOverriders::OverriderInfo Overrider) { 1398 // Ignore adjustments for pure virtual member functions. 1399 if (Overrider.Method->isPure()) 1400 return ThisAdjustment(); 1401 1402 BaseSubobject OverriddenBaseSubobject(MD->getParent(), 1403 BaseOffsetInLayoutClass); 1404 1405 BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), 1406 Overrider.Offset); 1407 1408 // Compute the adjustment offset. 1409 BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject, 1410 OverriderBaseSubobject); 1411 if (Offset.isEmpty()) 1412 return ThisAdjustment(); 1413 1414 ThisAdjustment Adjustment; 1415 1416 if (Offset.VirtualBase) { 1417 // Get the vcall offset map for this virtual base. 1418 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; 1419 1420 if (VCallOffsets.empty()) { 1421 // We don't have vcall offsets for this virtual base, go ahead and 1422 // build them. 1423 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass, 1424 /*FinalOverriders=*/0, 1425 BaseSubobject(Offset.VirtualBase, 0), 1426 /*BaseIsVirtual=*/true, 1427 /*OffsetInLayoutClass=*/0); 1428 1429 VCallOffsets = Builder.getVCallOffsets(); 1430 } 1431 1432 Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD); 1433 } 1434 1435 // Set the non-virtual part of the adjustment. 1436 Adjustment.NonVirtual = Offset.NonVirtualOffset; 1437 1438 return Adjustment; 1439} 1440 1441void 1442VTableBuilder::AddMethod(const CXXMethodDecl *MD, 1443 ReturnAdjustment ReturnAdjustment) { 1444 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1445 assert(ReturnAdjustment.isEmpty() && 1446 "Destructor can't have return adjustment!"); 1447 1448 // Add both the complete destructor and the deleting destructor. 1449 Components.push_back(VTableComponent::MakeCompleteDtor(DD)); 1450 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 1451 } else { 1452 // Add the return adjustment if necessary. 1453 if (!ReturnAdjustment.isEmpty()) 1454 VTableThunks[Components.size()].Return = ReturnAdjustment; 1455 1456 // Add the function. 1457 Components.push_back(VTableComponent::MakeFunction(MD)); 1458 } 1459} 1460 1461/// OverridesIndirectMethodInBase - Return whether the given member function 1462/// overrides any methods in the set of given bases. 1463/// Unlike OverridesMethodInBase, this checks "overriders of overriders". 1464/// For example, if we have: 1465/// 1466/// struct A { virtual void f(); } 1467/// struct B : A { virtual void f(); } 1468/// struct C : B { virtual void f(); } 1469/// 1470/// OverridesIndirectMethodInBase will return true if given C::f as the method 1471/// and { A } as the set of bases. 1472static bool 1473OverridesIndirectMethodInBases(const CXXMethodDecl *MD, 1474 VTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1475 if (Bases.count(MD->getParent())) 1476 return true; 1477 1478 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1479 E = MD->end_overridden_methods(); I != E; ++I) { 1480 const CXXMethodDecl *OverriddenMD = *I; 1481 1482 // Check "indirect overriders". 1483 if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) 1484 return true; 1485 } 1486 1487 return false; 1488} 1489 1490bool 1491VTableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider, 1492 uint64_t BaseOffsetInLayoutClass, 1493 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1494 uint64_t FirstBaseOffsetInLayoutClass) const { 1495 // If the base and the first base in the primary base chain have the same 1496 // offsets, then this overrider will be used. 1497 if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass) 1498 return true; 1499 1500 // We know now that Base (or a direct or indirect base of it) is a primary 1501 // base in part of the class hierarchy, but not a primary base in the most 1502 // derived class. 1503 1504 // If the overrider is the first base in the primary base chain, we know 1505 // that the overrider will be used. 1506 if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) 1507 return true; 1508 1509 VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 1510 1511 const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain; 1512 PrimaryBases.insert(RD); 1513 1514 // Now traverse the base chain, starting with the first base, until we find 1515 // the base that is no longer a primary base. 1516 while (true) { 1517 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1518 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1519 1520 if (!PrimaryBase) 1521 break; 1522 1523 if (Layout.isPrimaryBaseVirtual()) { 1524 assert(Layout.getVBaseClassOffsetInBits(PrimaryBase) == 0 && 1525 "Primary base should always be at offset 0!"); 1526 1527 const ASTRecordLayout &LayoutClassLayout = 1528 Context.getASTRecordLayout(LayoutClass); 1529 1530 // Now check if this is the primary base that is not a primary base in the 1531 // most derived class. 1532 if (LayoutClassLayout.getVBaseClassOffsetInBits(PrimaryBase) != 1533 FirstBaseOffsetInLayoutClass) { 1534 // We found it, stop walking the chain. 1535 break; 1536 } 1537 } else { 1538 assert(Layout.getBaseClassOffsetInBits(PrimaryBase) == 0 && 1539 "Primary base should always be at offset 0!"); 1540 } 1541 1542 if (!PrimaryBases.insert(PrimaryBase)) 1543 assert(false && "Found a duplicate primary base!"); 1544 1545 RD = PrimaryBase; 1546 } 1547 1548 // If the final overrider is an override of one of the primary bases, 1549 // then we know that it will be used. 1550 return OverridesIndirectMethodInBases(Overrider, PrimaryBases); 1551} 1552 1553/// FindNearestOverriddenMethod - Given a method, returns the overridden method 1554/// from the nearest base. Returns null if no method was found. 1555static const CXXMethodDecl * 1556FindNearestOverriddenMethod(const CXXMethodDecl *MD, 1557 VTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1558 OverriddenMethodsSetTy OverriddenMethods; 1559 ComputeAllOverriddenMethods(MD, OverriddenMethods); 1560 1561 for (int I = Bases.size(), E = 0; I != E; --I) { 1562 const CXXRecordDecl *PrimaryBase = Bases[I - 1]; 1563 1564 // Now check the overriden methods. 1565 for (OverriddenMethodsSetTy::const_iterator I = OverriddenMethods.begin(), 1566 E = OverriddenMethods.end(); I != E; ++I) { 1567 const CXXMethodDecl *OverriddenMD = *I; 1568 1569 // We found our overridden method. 1570 if (OverriddenMD->getParent() == PrimaryBase) 1571 return OverriddenMD; 1572 } 1573 } 1574 1575 return 0; 1576} 1577 1578void 1579VTableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, 1580 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1581 uint64_t FirstBaseOffsetInLayoutClass, 1582 PrimaryBasesSetVectorTy &PrimaryBases) { 1583 const CXXRecordDecl *RD = Base.getBase(); 1584 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1585 1586 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1587 uint64_t PrimaryBaseOffset; 1588 uint64_t PrimaryBaseOffsetInLayoutClass; 1589 if (Layout.isPrimaryBaseVirtual()) { 1590 assert(Layout.getVBaseClassOffsetInBits(PrimaryBase) == 0 && 1591 "Primary vbase should have a zero offset!"); 1592 1593 const ASTRecordLayout &MostDerivedClassLayout = 1594 Context.getASTRecordLayout(MostDerivedClass); 1595 1596 PrimaryBaseOffset = 1597 MostDerivedClassLayout.getVBaseClassOffsetInBits(PrimaryBase); 1598 1599 const ASTRecordLayout &LayoutClassLayout = 1600 Context.getASTRecordLayout(LayoutClass); 1601 1602 PrimaryBaseOffsetInLayoutClass = 1603 LayoutClassLayout.getVBaseClassOffsetInBits(PrimaryBase); 1604 } else { 1605 assert(Layout.getBaseClassOffsetInBits(PrimaryBase) == 0 && 1606 "Primary base should have a zero offset!"); 1607 1608 PrimaryBaseOffset = Base.getBaseOffset(); 1609 PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass; 1610 } 1611 1612 AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 1613 PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, 1614 FirstBaseOffsetInLayoutClass, PrimaryBases); 1615 1616 if (!PrimaryBases.insert(PrimaryBase)) 1617 assert(false && "Found a duplicate primary base!"); 1618 } 1619 1620 // Now go through all virtual member functions and add them. 1621 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1622 E = RD->method_end(); I != E; ++I) { 1623 const CXXMethodDecl *MD = *I; 1624 1625 if (!MD->isVirtual()) 1626 continue; 1627 1628 // Get the final overrider. 1629 FinalOverriders::OverriderInfo Overrider = 1630 Overriders.getOverrider(MD, Base.getBaseOffset()); 1631 1632 // Check if this virtual member function overrides a method in a primary 1633 // base. If this is the case, and the return type doesn't require adjustment 1634 // then we can just use the member function from the primary base. 1635 if (const CXXMethodDecl *OverriddenMD = 1636 FindNearestOverriddenMethod(MD, PrimaryBases)) { 1637 if (ComputeReturnAdjustmentBaseOffset(Context, MD, 1638 OverriddenMD).isEmpty()) { 1639 // Replace the method info of the overridden method with our own 1640 // method. 1641 assert(MethodInfoMap.count(OverriddenMD) && 1642 "Did not find the overridden method!"); 1643 MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD]; 1644 1645 MethodInfo MethodInfo(Base.getBaseOffset(), 1646 BaseOffsetInLayoutClass, 1647 OverriddenMethodInfo.VTableIndex); 1648 1649 assert(!MethodInfoMap.count(MD) && 1650 "Should not have method info for this method yet!"); 1651 1652 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1653 MethodInfoMap.erase(OverriddenMD); 1654 1655 // If the overridden method exists in a virtual base class or a direct 1656 // or indirect base class of a virtual base class, we need to emit a 1657 // thunk if we ever have a class hierarchy where the base class is not 1658 // a primary base in the complete object. 1659 if (!isBuildingConstructorVTable() && OverriddenMD != MD) { 1660 // Compute the this adjustment. 1661 ThisAdjustment ThisAdjustment = 1662 ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass, 1663 Overrider); 1664 1665 if (ThisAdjustment.VCallOffsetOffset && 1666 Overrider.Method->getParent() == MostDerivedClass) { 1667 1668 // There's no return adjustment from OverriddenMD and MD, 1669 // but that doesn't mean there isn't one between MD and 1670 // the final overrider. 1671 BaseOffset ReturnAdjustmentOffset = 1672 ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); 1673 ReturnAdjustment ReturnAdjustment = 1674 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1675 1676 // This is a virtual thunk for the most derived class, add it. 1677 AddThunk(Overrider.Method, 1678 ThunkInfo(ThisAdjustment, ReturnAdjustment)); 1679 } 1680 } 1681 1682 continue; 1683 } 1684 } 1685 1686 // Insert the method info for this method. 1687 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 1688 Components.size()); 1689 1690 assert(!MethodInfoMap.count(MD) && 1691 "Should not have method info for this method yet!"); 1692 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1693 1694 // Check if this overrider is going to be used. 1695 const CXXMethodDecl *OverriderMD = Overrider.Method; 1696 if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, 1697 FirstBaseInPrimaryBaseChain, 1698 FirstBaseOffsetInLayoutClass)) { 1699 Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD)); 1700 continue; 1701 } 1702 1703 // Check if this overrider needs a return adjustment. 1704 // We don't want to do this for pure virtual member functions. 1705 BaseOffset ReturnAdjustmentOffset; 1706 if (!OverriderMD->isPure()) { 1707 ReturnAdjustmentOffset = 1708 ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD); 1709 } 1710 1711 ReturnAdjustment ReturnAdjustment = 1712 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1713 1714 AddMethod(Overrider.Method, ReturnAdjustment); 1715 } 1716} 1717 1718void VTableBuilder::LayoutVTable() { 1719 LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass, 0), 1720 /*BaseIsMorallyVirtual=*/false, 1721 MostDerivedClassIsVirtual, 1722 MostDerivedClassOffset); 1723 1724 VisitedVirtualBasesSetTy VBases; 1725 1726 // Determine the primary virtual bases. 1727 DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, 1728 VBases); 1729 VBases.clear(); 1730 1731 LayoutVTablesForVirtualBases(MostDerivedClass, VBases); 1732} 1733 1734void 1735VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, 1736 bool BaseIsMorallyVirtual, 1737 bool BaseIsVirtualInLayoutClass, 1738 uint64_t OffsetInLayoutClass) { 1739 assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!"); 1740 1741 // Add vcall and vbase offsets for this vtable. 1742 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, 1743 Base, BaseIsVirtualInLayoutClass, 1744 OffsetInLayoutClass); 1745 Components.append(Builder.components_begin(), Builder.components_end()); 1746 1747 // Check if we need to add these vcall offsets. 1748 if (BaseIsVirtualInLayoutClass && !Builder.getVCallOffsets().empty()) { 1749 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; 1750 1751 if (VCallOffsets.empty()) 1752 VCallOffsets = Builder.getVCallOffsets(); 1753 } 1754 1755 // If we're laying out the most derived class we want to keep track of the 1756 // virtual base class offset offsets. 1757 if (Base.getBase() == MostDerivedClass) 1758 VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); 1759 1760 // Add the offset to top. 1761 // FIXME: We should not use / 8 here. 1762 int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass - 1763 MostDerivedClassOffset) / 8; 1764 Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop)); 1765 1766 // Next, add the RTTI. 1767 Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); 1768 1769 uint64_t AddressPoint = Components.size(); 1770 1771 // Now go through all virtual member functions and add them. 1772 PrimaryBasesSetVectorTy PrimaryBases; 1773 AddMethods(Base, OffsetInLayoutClass, Base.getBase(), OffsetInLayoutClass, 1774 PrimaryBases); 1775 1776 // Compute 'this' pointer adjustments. 1777 ComputeThisAdjustments(); 1778 1779 // Add all address points. 1780 const CXXRecordDecl *RD = Base.getBase(); 1781 while (true) { 1782 AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass), 1783 AddressPoint)); 1784 1785 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1786 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1787 1788 if (!PrimaryBase) 1789 break; 1790 1791 if (Layout.isPrimaryBaseVirtual()) { 1792 // Check if this virtual primary base is a primary base in the layout 1793 // class. If it's not, we don't want to add it. 1794 const ASTRecordLayout &LayoutClassLayout = 1795 Context.getASTRecordLayout(LayoutClass); 1796 1797 if (LayoutClassLayout.getVBaseClassOffsetInBits(PrimaryBase) != 1798 OffsetInLayoutClass) { 1799 // We don't want to add this class (or any of its primary bases). 1800 break; 1801 } 1802 } 1803 1804 RD = PrimaryBase; 1805 } 1806 1807 // Layout secondary vtables. 1808 LayoutSecondaryVTables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass); 1809} 1810 1811void VTableBuilder::LayoutSecondaryVTables(BaseSubobject Base, 1812 bool BaseIsMorallyVirtual, 1813 uint64_t OffsetInLayoutClass) { 1814 // Itanium C++ ABI 2.5.2: 1815 // Following the primary virtual table of a derived class are secondary 1816 // virtual tables for each of its proper base classes, except any primary 1817 // base(s) with which it shares its primary virtual table. 1818 1819 const CXXRecordDecl *RD = Base.getBase(); 1820 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1821 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1822 1823 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1824 E = RD->bases_end(); I != E; ++I) { 1825 // Ignore virtual bases, we'll emit them later. 1826 if (I->isVirtual()) 1827 continue; 1828 1829 const CXXRecordDecl *BaseDecl = 1830 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1831 1832 // Ignore bases that don't have a vtable. 1833 if (!BaseDecl->isDynamicClass()) 1834 continue; 1835 1836 if (isBuildingConstructorVTable()) { 1837 // Itanium C++ ABI 2.6.4: 1838 // Some of the base class subobjects may not need construction virtual 1839 // tables, which will therefore not be present in the construction 1840 // virtual table group, even though the subobject virtual tables are 1841 // present in the main virtual table group for the complete object. 1842 if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases()) 1843 continue; 1844 } 1845 1846 // Get the base offset of this base. 1847 uint64_t RelativeBaseOffset = Layout.getBaseClassOffsetInBits(BaseDecl); 1848 uint64_t BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; 1849 1850 uint64_t BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset; 1851 1852 // Don't emit a secondary vtable for a primary base. We might however want 1853 // to emit secondary vtables for other bases of this base. 1854 if (BaseDecl == PrimaryBase) { 1855 LayoutSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset), 1856 BaseIsMorallyVirtual, BaseOffsetInLayoutClass); 1857 continue; 1858 } 1859 1860 // Layout the primary vtable (and any secondary vtables) for this base. 1861 LayoutPrimaryAndSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset), 1862 BaseIsMorallyVirtual, 1863 /*BaseIsVirtualInLayoutClass=*/false, 1864 BaseOffsetInLayoutClass); 1865 } 1866} 1867 1868void 1869VTableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 1870 uint64_t OffsetInLayoutClass, 1871 VisitedVirtualBasesSetTy &VBases) { 1872 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1873 1874 // Check if this base has a primary base. 1875 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1876 1877 // Check if it's virtual. 1878 if (Layout.isPrimaryBaseVirtual()) { 1879 bool IsPrimaryVirtualBase = true; 1880 1881 if (isBuildingConstructorVTable()) { 1882 // Check if the base is actually a primary base in the class we use for 1883 // layout. 1884 const ASTRecordLayout &LayoutClassLayout = 1885 Context.getASTRecordLayout(LayoutClass); 1886 1887 uint64_t PrimaryBaseOffsetInLayoutClass = 1888 LayoutClassLayout.getVBaseClassOffsetInBits(PrimaryBase); 1889 1890 // We know that the base is not a primary base in the layout class if 1891 // the base offsets are different. 1892 if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) 1893 IsPrimaryVirtualBase = false; 1894 } 1895 1896 if (IsPrimaryVirtualBase) 1897 PrimaryVirtualBases.insert(PrimaryBase); 1898 } 1899 } 1900 1901 // Traverse bases, looking for more primary virtual bases. 1902 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1903 E = RD->bases_end(); I != E; ++I) { 1904 const CXXRecordDecl *BaseDecl = 1905 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1906 1907 uint64_t BaseOffsetInLayoutClass; 1908 1909 if (I->isVirtual()) { 1910 if (!VBases.insert(BaseDecl)) 1911 continue; 1912 1913 const ASTRecordLayout &LayoutClassLayout = 1914 Context.getASTRecordLayout(LayoutClass); 1915 1916 BaseOffsetInLayoutClass = 1917 LayoutClassLayout.getVBaseClassOffsetInBits(BaseDecl); 1918 } else { 1919 BaseOffsetInLayoutClass = 1920 OffsetInLayoutClass + Layout.getBaseClassOffsetInBits(BaseDecl); 1921 } 1922 1923 DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); 1924 } 1925} 1926 1927void 1928VTableBuilder::LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 1929 VisitedVirtualBasesSetTy &VBases) { 1930 // Itanium C++ ABI 2.5.2: 1931 // Then come the virtual base virtual tables, also in inheritance graph 1932 // order, and again excluding primary bases (which share virtual tables with 1933 // the classes for which they are primary). 1934 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1935 E = RD->bases_end(); I != E; ++I) { 1936 const CXXRecordDecl *BaseDecl = 1937 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1938 1939 // Check if this base needs a vtable. (If it's virtual, not a primary base 1940 // of some other class, and we haven't visited it before). 1941 if (I->isVirtual() && BaseDecl->isDynamicClass() && 1942 !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) { 1943 const ASTRecordLayout &MostDerivedClassLayout = 1944 Context.getASTRecordLayout(MostDerivedClass); 1945 uint64_t BaseOffset = 1946 MostDerivedClassLayout.getVBaseClassOffsetInBits(BaseDecl); 1947 1948 const ASTRecordLayout &LayoutClassLayout = 1949 Context.getASTRecordLayout(LayoutClass); 1950 uint64_t BaseOffsetInLayoutClass = 1951 LayoutClassLayout.getVBaseClassOffsetInBits(BaseDecl); 1952 1953 LayoutPrimaryAndSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset), 1954 /*BaseIsMorallyVirtual=*/true, 1955 /*BaseIsVirtualInLayoutClass=*/true, 1956 BaseOffsetInLayoutClass); 1957 } 1958 1959 // We only need to check the base for virtual base vtables if it actually 1960 // has virtual bases. 1961 if (BaseDecl->getNumVBases()) 1962 LayoutVTablesForVirtualBases(BaseDecl, VBases); 1963 } 1964} 1965 1966/// dumpLayout - Dump the vtable layout. 1967void VTableBuilder::dumpLayout(llvm::raw_ostream& Out) { 1968 1969 if (isBuildingConstructorVTable()) { 1970 Out << "Construction vtable for ('"; 1971 Out << MostDerivedClass->getQualifiedNameAsString() << "', "; 1972 // FIXME: Don't use / 8 . 1973 Out << MostDerivedClassOffset / 8 << ") in '"; 1974 Out << LayoutClass->getQualifiedNameAsString(); 1975 } else { 1976 Out << "Vtable for '"; 1977 Out << MostDerivedClass->getQualifiedNameAsString(); 1978 } 1979 Out << "' (" << Components.size() << " entries).\n"; 1980 1981 // Iterate through the address points and insert them into a new map where 1982 // they are keyed by the index and not the base object. 1983 // Since an address point can be shared by multiple subobjects, we use an 1984 // STL multimap. 1985 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex; 1986 for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(), 1987 E = AddressPoints.end(); I != E; ++I) { 1988 const BaseSubobject& Base = I->first; 1989 uint64_t Index = I->second; 1990 1991 AddressPointsByIndex.insert(std::make_pair(Index, Base)); 1992 } 1993 1994 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 1995 uint64_t Index = I; 1996 1997 Out << llvm::format("%4d | ", I); 1998 1999 const VTableComponent &Component = Components[I]; 2000 2001 // Dump the component. 2002 switch (Component.getKind()) { 2003 2004 case VTableComponent::CK_VCallOffset: 2005 Out << "vcall_offset (" << Component.getVCallOffset() << ")"; 2006 break; 2007 2008 case VTableComponent::CK_VBaseOffset: 2009 Out << "vbase_offset (" << Component.getVBaseOffset() << ")"; 2010 break; 2011 2012 case VTableComponent::CK_OffsetToTop: 2013 Out << "offset_to_top (" << Component.getOffsetToTop() << ")"; 2014 break; 2015 2016 case VTableComponent::CK_RTTI: 2017 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; 2018 break; 2019 2020 case VTableComponent::CK_FunctionPointer: { 2021 const CXXMethodDecl *MD = Component.getFunctionDecl(); 2022 2023 std::string Str = 2024 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2025 MD); 2026 Out << Str; 2027 if (MD->isPure()) 2028 Out << " [pure]"; 2029 2030 ThunkInfo Thunk = VTableThunks.lookup(I); 2031 if (!Thunk.isEmpty()) { 2032 // If this function pointer has a return adjustment, dump it. 2033 if (!Thunk.Return.isEmpty()) { 2034 Out << "\n [return adjustment: "; 2035 Out << Thunk.Return.NonVirtual << " non-virtual"; 2036 2037 if (Thunk.Return.VBaseOffsetOffset) { 2038 Out << ", " << Thunk.Return.VBaseOffsetOffset; 2039 Out << " vbase offset offset"; 2040 } 2041 2042 Out << ']'; 2043 } 2044 2045 // If this function pointer has a 'this' pointer adjustment, dump it. 2046 if (!Thunk.This.isEmpty()) { 2047 Out << "\n [this adjustment: "; 2048 Out << Thunk.This.NonVirtual << " non-virtual"; 2049 2050 if (Thunk.This.VCallOffsetOffset) { 2051 Out << ", " << Thunk.This.VCallOffsetOffset; 2052 Out << " vcall offset offset"; 2053 } 2054 2055 Out << ']'; 2056 } 2057 } 2058 2059 break; 2060 } 2061 2062 case VTableComponent::CK_CompleteDtorPointer: 2063 case VTableComponent::CK_DeletingDtorPointer: { 2064 bool IsComplete = 2065 Component.getKind() == VTableComponent::CK_CompleteDtorPointer; 2066 2067 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 2068 2069 Out << DD->getQualifiedNameAsString(); 2070 if (IsComplete) 2071 Out << "() [complete]"; 2072 else 2073 Out << "() [deleting]"; 2074 2075 if (DD->isPure()) 2076 Out << " [pure]"; 2077 2078 ThunkInfo Thunk = VTableThunks.lookup(I); 2079 if (!Thunk.isEmpty()) { 2080 // If this destructor has a 'this' pointer adjustment, dump it. 2081 if (!Thunk.This.isEmpty()) { 2082 Out << "\n [this adjustment: "; 2083 Out << Thunk.This.NonVirtual << " non-virtual"; 2084 2085 if (Thunk.This.VCallOffsetOffset) { 2086 Out << ", " << Thunk.This.VCallOffsetOffset; 2087 Out << " vcall offset offset"; 2088 } 2089 2090 Out << ']'; 2091 } 2092 } 2093 2094 break; 2095 } 2096 2097 case VTableComponent::CK_UnusedFunctionPointer: { 2098 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); 2099 2100 std::string Str = 2101 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2102 MD); 2103 Out << "[unused] " << Str; 2104 if (MD->isPure()) 2105 Out << " [pure]"; 2106 } 2107 2108 } 2109 2110 Out << '\n'; 2111 2112 // Dump the next address point. 2113 uint64_t NextIndex = Index + 1; 2114 if (AddressPointsByIndex.count(NextIndex)) { 2115 if (AddressPointsByIndex.count(NextIndex) == 1) { 2116 const BaseSubobject &Base = 2117 AddressPointsByIndex.find(NextIndex)->second; 2118 2119 // FIXME: Instead of dividing by 8, we should be using CharUnits. 2120 Out << " -- (" << Base.getBase()->getQualifiedNameAsString(); 2121 Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n"; 2122 } else { 2123 uint64_t BaseOffset = 2124 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); 2125 2126 // We store the class names in a set to get a stable order. 2127 std::set<std::string> ClassNames; 2128 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I = 2129 AddressPointsByIndex.lower_bound(NextIndex), E = 2130 AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) { 2131 assert(I->second.getBaseOffset() == BaseOffset && 2132 "Invalid base offset!"); 2133 const CXXRecordDecl *RD = I->second.getBase(); 2134 ClassNames.insert(RD->getQualifiedNameAsString()); 2135 } 2136 2137 for (std::set<std::string>::const_iterator I = ClassNames.begin(), 2138 E = ClassNames.end(); I != E; ++I) { 2139 // FIXME: Instead of dividing by 8, we should be using CharUnits. 2140 Out << " -- (" << *I; 2141 Out << ", " << BaseOffset / 8 << ") vtable address --\n"; 2142 } 2143 } 2144 } 2145 } 2146 2147 Out << '\n'; 2148 2149 if (isBuildingConstructorVTable()) 2150 return; 2151 2152 if (MostDerivedClass->getNumVBases()) { 2153 // We store the virtual base class names and their offsets in a map to get 2154 // a stable order. 2155 2156 std::map<std::string, int64_t> ClassNamesAndOffsets; 2157 for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(), 2158 E = VBaseOffsetOffsets.end(); I != E; ++I) { 2159 std::string ClassName = I->first->getQualifiedNameAsString(); 2160 int64_t OffsetOffset = I->second; 2161 ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset)); 2162 } 2163 2164 Out << "Virtual base offset offsets for '"; 2165 Out << MostDerivedClass->getQualifiedNameAsString() << "' ("; 2166 Out << ClassNamesAndOffsets.size(); 2167 Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n"; 2168 2169 for (std::map<std::string, int64_t>::const_iterator I = 2170 ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 2171 I != E; ++I) 2172 Out << " " << I->first << " | " << I->second << '\n'; 2173 2174 Out << "\n"; 2175 } 2176 2177 if (!Thunks.empty()) { 2178 // We store the method names in a map to get a stable order. 2179 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 2180 2181 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 2182 I != E; ++I) { 2183 const CXXMethodDecl *MD = I->first; 2184 std::string MethodName = 2185 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2186 MD); 2187 2188 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 2189 } 2190 2191 for (std::map<std::string, const CXXMethodDecl *>::const_iterator I = 2192 MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end(); 2193 I != E; ++I) { 2194 const std::string &MethodName = I->first; 2195 const CXXMethodDecl *MD = I->second; 2196 2197 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 2198 std::sort(ThunksVector.begin(), ThunksVector.end()); 2199 2200 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 2201 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 2202 2203 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 2204 const ThunkInfo &Thunk = ThunksVector[I]; 2205 2206 Out << llvm::format("%4d | ", I); 2207 2208 // If this function pointer has a return pointer adjustment, dump it. 2209 if (!Thunk.Return.isEmpty()) { 2210 Out << "return adjustment: " << Thunk.This.NonVirtual; 2211 Out << " non-virtual"; 2212 if (Thunk.Return.VBaseOffsetOffset) { 2213 Out << ", " << Thunk.Return.VBaseOffsetOffset; 2214 Out << " vbase offset offset"; 2215 } 2216 2217 if (!Thunk.This.isEmpty()) 2218 Out << "\n "; 2219 } 2220 2221 // If this function pointer has a 'this' pointer adjustment, dump it. 2222 if (!Thunk.This.isEmpty()) { 2223 Out << "this adjustment: "; 2224 Out << Thunk.This.NonVirtual << " non-virtual"; 2225 2226 if (Thunk.This.VCallOffsetOffset) { 2227 Out << ", " << Thunk.This.VCallOffsetOffset; 2228 Out << " vcall offset offset"; 2229 } 2230 } 2231 2232 Out << '\n'; 2233 } 2234 2235 Out << '\n'; 2236 2237 } 2238 } 2239} 2240 2241} 2242 2243static void 2244CollectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, 2245 VTableBuilder::PrimaryBasesSetVectorTy &PrimaryBases) { 2246 while (RD) { 2247 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 2248 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 2249 if (PrimaryBase) 2250 PrimaryBases.insert(PrimaryBase); 2251 2252 RD = PrimaryBase; 2253 } 2254} 2255 2256void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) { 2257 2258 // Itanium C++ ABI 2.5.2: 2259 // The order of the virtual function pointers in a virtual table is the 2260 // order of declaration of the corresponding member functions in the class. 2261 // 2262 // There is an entry for any virtual function declared in a class, 2263 // whether it is a new function or overrides a base class function, 2264 // unless it overrides a function from the primary base, and conversion 2265 // between their return types does not require an adjustment. 2266 2267 int64_t CurrentIndex = 0; 2268 2269 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 2270 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 2271 2272 if (PrimaryBase) { 2273 assert(PrimaryBase->isDefinition() && 2274 "Should have the definition decl of the primary base!"); 2275 2276 // Since the record decl shares its vtable pointer with the primary base 2277 // we need to start counting at the end of the primary base's vtable. 2278 CurrentIndex = getNumVirtualFunctionPointers(PrimaryBase); 2279 } 2280 2281 // Collect all the primary bases, so we can check whether methods override 2282 // a method from the base. 2283 VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 2284 CollectPrimaryBases(RD, CGM.getContext(), PrimaryBases); 2285 2286 const CXXDestructorDecl *ImplicitVirtualDtor = 0; 2287 2288 for (CXXRecordDecl::method_iterator i = RD->method_begin(), 2289 e = RD->method_end(); i != e; ++i) { 2290 const CXXMethodDecl *MD = *i; 2291 2292 // We only want virtual methods. 2293 if (!MD->isVirtual()) 2294 continue; 2295 2296 // Check if this method overrides a method in the primary base. 2297 if (const CXXMethodDecl *OverriddenMD = 2298 FindNearestOverriddenMethod(MD, PrimaryBases)) { 2299 // Check if converting from the return type of the method to the 2300 // return type of the overridden method requires conversion. 2301 if (ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD, 2302 OverriddenMD).isEmpty()) { 2303 // This index is shared between the index in the vtable of the primary 2304 // base class. 2305 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2306 const CXXDestructorDecl *OverriddenDD = 2307 cast<CXXDestructorDecl>(OverriddenMD); 2308 2309 // Add both the complete and deleting entries. 2310 MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = 2311 getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete)); 2312 MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = 2313 getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting)); 2314 } else { 2315 MethodVTableIndices[MD] = getMethodVTableIndex(OverriddenMD); 2316 } 2317 2318 // We don't need to add an entry for this method. 2319 continue; 2320 } 2321 } 2322 2323 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2324 if (MD->isImplicit()) { 2325 assert(!ImplicitVirtualDtor && 2326 "Did already see an implicit virtual dtor!"); 2327 ImplicitVirtualDtor = DD; 2328 continue; 2329 } 2330 2331 // Add the complete dtor. 2332 MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++; 2333 2334 // Add the deleting dtor. 2335 MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++; 2336 } else { 2337 // Add the entry. 2338 MethodVTableIndices[MD] = CurrentIndex++; 2339 } 2340 } 2341 2342 if (ImplicitVirtualDtor) { 2343 // Itanium C++ ABI 2.5.2: 2344 // If a class has an implicitly-defined virtual destructor, 2345 // its entries come after the declared virtual function pointers. 2346 2347 // Add the complete dtor. 2348 MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = 2349 CurrentIndex++; 2350 2351 // Add the deleting dtor. 2352 MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Deleting)] = 2353 CurrentIndex++; 2354 } 2355 2356 NumVirtualFunctionPointers[RD] = CurrentIndex; 2357} 2358 2359bool CodeGenVTables::ShouldEmitVTableInThisTU(const CXXRecordDecl *RD) { 2360 assert(RD->isDynamicClass() && "Non dynamic classes have no VTable."); 2361 2362 TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); 2363 if (TSK == TSK_ExplicitInstantiationDeclaration) 2364 return false; 2365 2366 const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD); 2367 if (!KeyFunction) 2368 return true; 2369 2370 // Itanium C++ ABI, 5.2.6 Instantiated Templates: 2371 // An instantiation of a class template requires: 2372 // - In the object where instantiated, the virtual table... 2373 if (TSK == TSK_ImplicitInstantiation || 2374 TSK == TSK_ExplicitInstantiationDefinition) 2375 return true; 2376 2377 // If we're building with optimization, we always emit VTables since that 2378 // allows for virtual function calls to be devirtualized. 2379 // (We don't want to do this in -fapple-kext mode however). 2380 if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOptions().AppleKext) 2381 return true; 2382 2383 return KeyFunction->hasBody(); 2384} 2385 2386uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) { 2387 llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = 2388 NumVirtualFunctionPointers.find(RD); 2389 if (I != NumVirtualFunctionPointers.end()) 2390 return I->second; 2391 2392 ComputeMethodVTableIndices(RD); 2393 2394 I = NumVirtualFunctionPointers.find(RD); 2395 assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!"); 2396 return I->second; 2397} 2398 2399uint64_t CodeGenVTables::getMethodVTableIndex(GlobalDecl GD) { 2400 MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD); 2401 if (I != MethodVTableIndices.end()) 2402 return I->second; 2403 2404 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2405 2406 ComputeMethodVTableIndices(RD); 2407 2408 I = MethodVTableIndices.find(GD); 2409 assert(I != MethodVTableIndices.end() && "Did not find index!"); 2410 return I->second; 2411} 2412 2413int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 2414 const CXXRecordDecl *VBase) { 2415 ClassPairTy ClassPair(RD, VBase); 2416 2417 VirtualBaseClassOffsetOffsetsMapTy::iterator I = 2418 VirtualBaseClassOffsetOffsets.find(ClassPair); 2419 if (I != VirtualBaseClassOffsetOffsets.end()) 2420 return I->second; 2421 2422 VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0, 2423 BaseSubobject(RD, 0), 2424 /*BaseIsVirtual=*/false, 2425 /*OffsetInLayoutClass=*/0); 2426 2427 for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2428 Builder.getVBaseOffsetOffsets().begin(), 2429 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2430 // Insert all types. 2431 ClassPairTy ClassPair(RD, I->first); 2432 2433 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2434 } 2435 2436 I = VirtualBaseClassOffsetOffsets.find(ClassPair); 2437 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); 2438 2439 return I->second; 2440} 2441 2442uint64_t 2443CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { 2444 assert(AddressPoints.count(std::make_pair(RD, Base)) && 2445 "Did not find address point!"); 2446 2447 uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base)); 2448 assert(AddressPoint && "Address point must not be zero!"); 2449 2450 return AddressPoint; 2451} 2452 2453llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 2454 const ThunkInfo &Thunk, 2455 bool ForVTable) { 2456 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2457 2458 // Compute the mangled name. 2459 llvm::SmallString<256> Name; 2460 if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD)) 2461 getCXXABI().getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), 2462 Thunk.This, Name); 2463 else 2464 getCXXABI().getMangleContext().mangleThunk(MD, Thunk, Name); 2465 2466 const llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD); 2467 return GetOrCreateLLVMFunction(Name, Ty, GD, ForVTable); 2468} 2469 2470static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, 2471 llvm::Value *Ptr, 2472 int64_t NonVirtualAdjustment, 2473 int64_t VirtualAdjustment) { 2474 if (!NonVirtualAdjustment && !VirtualAdjustment) 2475 return Ptr; 2476 2477 const llvm::Type *Int8PtrTy = 2478 llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 2479 2480 llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); 2481 2482 if (NonVirtualAdjustment) { 2483 // Do the non-virtual adjustment. 2484 V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); 2485 } 2486 2487 if (VirtualAdjustment) { 2488 const llvm::Type *PtrDiffTy = 2489 CGF.ConvertType(CGF.getContext().getPointerDiffType()); 2490 2491 // Do the virtual adjustment. 2492 llvm::Value *VTablePtrPtr = 2493 CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); 2494 2495 llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); 2496 2497 llvm::Value *OffsetPtr = 2498 CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 2499 2500 OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); 2501 2502 // Load the adjustment offset from the vtable. 2503 llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr); 2504 2505 // Adjust our pointer. 2506 V = CGF.Builder.CreateInBoundsGEP(V, Offset); 2507 } 2508 2509 // Cast back to the original type. 2510 return CGF.Builder.CreateBitCast(V, Ptr->getType()); 2511} 2512 2513static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, 2514 const ThunkInfo &Thunk, llvm::Function *Fn) { 2515 CGM.setGlobalVisibility(Fn, MD); 2516 2517 if (!CGM.getCodeGenOpts().HiddenWeakVTables) 2518 return; 2519 2520 // If the thunk has weak/linkonce linkage, but the function must be 2521 // emitted in every translation unit that references it, then we can 2522 // emit its thunks with hidden visibility, since its thunks must be 2523 // emitted when the function is. 2524 2525 // This follows CodeGenModule::setTypeVisibility; see the comments 2526 // there for explanation. 2527 2528 if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage && 2529 Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) || 2530 Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility) 2531 return; 2532 2533 if (MD->hasAttr<VisibilityAttr>()) 2534 return; 2535 2536 switch (MD->getTemplateSpecializationKind()) { 2537 case TSK_ExplicitInstantiationDefinition: 2538 case TSK_ExplicitInstantiationDeclaration: 2539 return; 2540 2541 case TSK_Undeclared: 2542 break; 2543 2544 case TSK_ExplicitSpecialization: 2545 case TSK_ImplicitInstantiation: 2546 if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables) 2547 return; 2548 break; 2549 } 2550 2551 // If there's an explicit definition, and that definition is 2552 // out-of-line, then we can't assume that all users will have a 2553 // definition to emit. 2554 const FunctionDecl *Def = 0; 2555 if (MD->hasBody(Def) && Def->isOutOfLine()) 2556 return; 2557 2558 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); 2559} 2560 2561void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, 2562 const ThunkInfo &Thunk) { 2563 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2564 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 2565 QualType ResultType = FPT->getResultType(); 2566 QualType ThisType = MD->getThisType(getContext()); 2567 2568 FunctionArgList FunctionArgs; 2569 2570 // FIXME: It would be nice if more of this code could be shared with 2571 // CodeGenFunction::GenerateCode. 2572 2573 // Create the implicit 'this' parameter declaration. 2574 CurGD = GD; 2575 CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResultType, FunctionArgs); 2576 2577 // Add the rest of the parameters. 2578 for (FunctionDecl::param_const_iterator I = MD->param_begin(), 2579 E = MD->param_end(); I != E; ++I) { 2580 ParmVarDecl *Param = *I; 2581 2582 FunctionArgs.push_back(std::make_pair(Param, Param->getType())); 2583 } 2584 2585 StartFunction(GlobalDecl(), ResultType, Fn, FunctionArgs, SourceLocation()); 2586 2587 CGM.getCXXABI().EmitInstanceFunctionProlog(*this); 2588 2589 // Adjust the 'this' pointer if necessary. 2590 llvm::Value *AdjustedThisPtr = 2591 PerformTypeAdjustment(*this, LoadCXXThis(), 2592 Thunk.This.NonVirtual, 2593 Thunk.This.VCallOffsetOffset); 2594 2595 CallArgList CallArgs; 2596 2597 // Add our adjusted 'this' pointer. 2598 CallArgs.push_back(std::make_pair(RValue::get(AdjustedThisPtr), ThisType)); 2599 2600 // Add the rest of the parameters. 2601 for (FunctionDecl::param_const_iterator I = MD->param_begin(), 2602 E = MD->param_end(); I != E; ++I) { 2603 ParmVarDecl *Param = *I; 2604 QualType ArgType = Param->getType(); 2605 RValue Arg = EmitDelegateCallArg(Param); 2606 2607 CallArgs.push_back(std::make_pair(Arg, ArgType)); 2608 } 2609 2610 // Get our callee. 2611 const llvm::Type *Ty = 2612 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(GD), 2613 FPT->isVariadic()); 2614 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); 2615 2616 const CGFunctionInfo &FnInfo = 2617 CGM.getTypes().getFunctionInfo(ResultType, CallArgs, 2618 FPT->getExtInfo()); 2619 2620 // Determine whether we have a return value slot to use. 2621 ReturnValueSlot Slot; 2622 if (!ResultType->isVoidType() && 2623 FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 2624 hasAggregateLLVMType(CurFnInfo->getReturnType())) 2625 Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified()); 2626 2627 // Now emit our call. 2628 RValue RV = EmitCall(FnInfo, Callee, Slot, CallArgs, MD); 2629 2630 if (!Thunk.Return.isEmpty()) { 2631 // Emit the return adjustment. 2632 bool NullCheckValue = !ResultType->isReferenceType(); 2633 2634 llvm::BasicBlock *AdjustNull = 0; 2635 llvm::BasicBlock *AdjustNotNull = 0; 2636 llvm::BasicBlock *AdjustEnd = 0; 2637 2638 llvm::Value *ReturnValue = RV.getScalarVal(); 2639 2640 if (NullCheckValue) { 2641 AdjustNull = createBasicBlock("adjust.null"); 2642 AdjustNotNull = createBasicBlock("adjust.notnull"); 2643 AdjustEnd = createBasicBlock("adjust.end"); 2644 2645 llvm::Value *IsNull = Builder.CreateIsNull(ReturnValue); 2646 Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull); 2647 EmitBlock(AdjustNotNull); 2648 } 2649 2650 ReturnValue = PerformTypeAdjustment(*this, ReturnValue, 2651 Thunk.Return.NonVirtual, 2652 Thunk.Return.VBaseOffsetOffset); 2653 2654 if (NullCheckValue) { 2655 Builder.CreateBr(AdjustEnd); 2656 EmitBlock(AdjustNull); 2657 Builder.CreateBr(AdjustEnd); 2658 EmitBlock(AdjustEnd); 2659 2660 llvm::PHINode *PHI = Builder.CreatePHI(ReturnValue->getType()); 2661 PHI->reserveOperandSpace(2); 2662 PHI->addIncoming(ReturnValue, AdjustNotNull); 2663 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), 2664 AdjustNull); 2665 ReturnValue = PHI; 2666 } 2667 2668 RV = RValue::get(ReturnValue); 2669 } 2670 2671 if (!ResultType->isVoidType() && Slot.isNull()) 2672 CGM.getCXXABI().EmitReturnFromThunk(CGF, RV, ResultType); 2673 2674 FinishFunction(); 2675 2676 // Set the right linkage. 2677 CGM.setFunctionLinkage(MD, Fn); 2678 2679 // Set the right visibility. 2680 setThunkVisibility(CGM, MD, Thunk, Fn); 2681} 2682 2683void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk) 2684{ 2685 llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk, /*ForVTable=*/false); 2686 2687 // Strip off a bitcast if we got one back. 2688 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) { 2689 assert(CE->getOpcode() == llvm::Instruction::BitCast); 2690 Entry = CE->getOperand(0); 2691 } 2692 2693 // There's already a declaration with the same name, check if it has the same 2694 // type or if we need to replace it. 2695 if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != 2696 CGM.getTypes().GetFunctionTypeForVTable(GD)) { 2697 llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(Entry); 2698 2699 // If the types mismatch then we have to rewrite the definition. 2700 assert(OldThunkFn->isDeclaration() && 2701 "Shouldn't replace non-declaration"); 2702 2703 // Remove the name from the old thunk function and get a new thunk. 2704 OldThunkFn->setName(llvm::StringRef()); 2705 Entry = CGM.GetAddrOfThunk(GD, Thunk, /*ForVTable=*/false); 2706 2707 // If needed, replace the old thunk with a bitcast. 2708 if (!OldThunkFn->use_empty()) { 2709 llvm::Constant *NewPtrForOldDecl = 2710 llvm::ConstantExpr::getBitCast(Entry, OldThunkFn->getType()); 2711 OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl); 2712 } 2713 2714 // Remove the old thunk. 2715 OldThunkFn->eraseFromParent(); 2716 } 2717 2718 // Actually generate the thunk body. 2719 llvm::Function *ThunkFn = cast<llvm::Function>(Entry); 2720 CodeGenFunction(CGM).GenerateThunk(ThunkFn, GD, Thunk); 2721} 2722 2723void CodeGenVTables::EmitThunks(GlobalDecl GD) 2724{ 2725 const CXXMethodDecl *MD = 2726 cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl(); 2727 2728 // We don't need to generate thunks for the base destructor. 2729 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) 2730 return; 2731 2732 const CXXRecordDecl *RD = MD->getParent(); 2733 2734 // Compute VTable related info for this class. 2735 ComputeVTableRelatedInformation(RD, false); 2736 2737 ThunksMapTy::const_iterator I = Thunks.find(MD); 2738 if (I == Thunks.end()) { 2739 // We did not find a thunk for this method. 2740 return; 2741 } 2742 2743 const ThunkInfoVectorTy &ThunkInfoVector = I->second; 2744 for (unsigned I = 0, E = ThunkInfoVector.size(); I != E; ++I) 2745 EmitThunk(GD, ThunkInfoVector[I]); 2746} 2747 2748void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD, 2749 bool RequireVTable) { 2750 VTableLayoutData &Entry = VTableLayoutMap[RD]; 2751 2752 // We may need to generate a definition for this vtable. 2753 if (RequireVTable && !Entry.getInt()) { 2754 if (ShouldEmitVTableInThisTU(RD)) 2755 CGM.DeferredVTables.push_back(RD); 2756 2757 Entry.setInt(true); 2758 } 2759 2760 // Check if we've computed this information before. 2761 if (Entry.getPointer()) 2762 return; 2763 2764 VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD); 2765 2766 // Add the VTable layout. 2767 uint64_t NumVTableComponents = Builder.getNumVTableComponents(); 2768 // -fapple-kext adds an extra entry at end of vtbl. 2769 bool IsAppleKext = CGM.getContext().getLangOptions().AppleKext; 2770 if (IsAppleKext) 2771 NumVTableComponents += 1; 2772 2773 uint64_t *LayoutData = new uint64_t[NumVTableComponents + 1]; 2774 if (IsAppleKext) 2775 LayoutData[NumVTableComponents] = 0; 2776 Entry.setPointer(LayoutData); 2777 2778 // Store the number of components. 2779 LayoutData[0] = NumVTableComponents; 2780 2781 // Store the components. 2782 std::copy(Builder.vtable_components_data_begin(), 2783 Builder.vtable_components_data_end(), 2784 &LayoutData[1]); 2785 2786 // Add the known thunks. 2787 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 2788 2789 // Add the thunks needed in this vtable. 2790 assert(!VTableThunksMap.count(RD) && 2791 "Thunks already exists for this vtable!"); 2792 2793 VTableThunksTy &VTableThunks = VTableThunksMap[RD]; 2794 VTableThunks.append(Builder.vtable_thunks_begin(), 2795 Builder.vtable_thunks_end()); 2796 2797 // Sort them. 2798 std::sort(VTableThunks.begin(), VTableThunks.end()); 2799 2800 // Add the address points. 2801 for (VTableBuilder::AddressPointsMapTy::const_iterator I = 2802 Builder.address_points_begin(), E = Builder.address_points_end(); 2803 I != E; ++I) { 2804 2805 uint64_t &AddressPoint = AddressPoints[std::make_pair(RD, I->first)]; 2806 2807 // Check if we already have the address points for this base. 2808 assert(!AddressPoint && "Address point already exists for this base!"); 2809 2810 AddressPoint = I->second; 2811 } 2812 2813 // If we don't have the vbase information for this class, insert it. 2814 // getVirtualBaseOffsetOffset will compute it separately without computing 2815 // the rest of the vtable related information. 2816 if (!RD->getNumVBases()) 2817 return; 2818 2819 const RecordType *VBaseRT = 2820 RD->vbases_begin()->getType()->getAs<RecordType>(); 2821 const CXXRecordDecl *VBase = cast<CXXRecordDecl>(VBaseRT->getDecl()); 2822 2823 if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) 2824 return; 2825 2826 for (VTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2827 Builder.getVBaseOffsetOffsets().begin(), 2828 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2829 // Insert all types. 2830 ClassPairTy ClassPair(RD, I->first); 2831 2832 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2833 } 2834} 2835 2836llvm::Constant * 2837CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, 2838 const uint64_t *Components, 2839 unsigned NumComponents, 2840 const VTableThunksTy &VTableThunks) { 2841 llvm::SmallVector<llvm::Constant *, 64> Inits; 2842 2843 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 2844 2845 const llvm::Type *PtrDiffTy = 2846 CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); 2847 2848 QualType ClassType = CGM.getContext().getTagDeclType(RD); 2849 llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType); 2850 2851 unsigned NextVTableThunkIndex = 0; 2852 2853 llvm::Constant* PureVirtualFn = 0; 2854 2855 for (unsigned I = 0; I != NumComponents; ++I) { 2856 VTableComponent Component = 2857 VTableComponent::getFromOpaqueInteger(Components[I]); 2858 2859 llvm::Constant *Init = 0; 2860 2861 switch (Component.getKind()) { 2862 case VTableComponent::CK_VCallOffset: 2863 Init = llvm::ConstantInt::get(PtrDiffTy, Component.getVCallOffset()); 2864 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 2865 break; 2866 case VTableComponent::CK_VBaseOffset: 2867 Init = llvm::ConstantInt::get(PtrDiffTy, Component.getVBaseOffset()); 2868 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 2869 break; 2870 case VTableComponent::CK_OffsetToTop: 2871 Init = llvm::ConstantInt::get(PtrDiffTy, Component.getOffsetToTop()); 2872 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 2873 break; 2874 case VTableComponent::CK_RTTI: 2875 Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy); 2876 break; 2877 case VTableComponent::CK_FunctionPointer: 2878 case VTableComponent::CK_CompleteDtorPointer: 2879 case VTableComponent::CK_DeletingDtorPointer: { 2880 GlobalDecl GD; 2881 2882 // Get the right global decl. 2883 switch (Component.getKind()) { 2884 default: 2885 llvm_unreachable("Unexpected vtable component kind"); 2886 case VTableComponent::CK_FunctionPointer: 2887 GD = Component.getFunctionDecl(); 2888 break; 2889 case VTableComponent::CK_CompleteDtorPointer: 2890 GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete); 2891 break; 2892 case VTableComponent::CK_DeletingDtorPointer: 2893 GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting); 2894 break; 2895 } 2896 2897 if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { 2898 // We have a pure virtual member function. 2899 if (!PureVirtualFn) { 2900 const llvm::FunctionType *Ty = 2901 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), 2902 /*isVarArg=*/false); 2903 PureVirtualFn = 2904 CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual"); 2905 PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn, 2906 Int8PtrTy); 2907 } 2908 2909 Init = PureVirtualFn; 2910 } else { 2911 // Check if we should use a thunk. 2912 if (NextVTableThunkIndex < VTableThunks.size() && 2913 VTableThunks[NextVTableThunkIndex].first == I) { 2914 const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second; 2915 2916 Init = CGM.GetAddrOfThunk(GD, Thunk, /*ForVTable=*/true); 2917 2918 NextVTableThunkIndex++; 2919 } else { 2920 const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD); 2921 2922 Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); 2923 } 2924 2925 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); 2926 } 2927 break; 2928 } 2929 2930 case VTableComponent::CK_UnusedFunctionPointer: 2931 Init = llvm::ConstantExpr::getNullValue(Int8PtrTy); 2932 break; 2933 }; 2934 2935 Inits.push_back(Init); 2936 } 2937 2938 llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents); 2939 return llvm::ConstantArray::get(ArrayType, Inits.data(), Inits.size()); 2940} 2941 2942llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { 2943 llvm::SmallString<256> OutName; 2944 CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, OutName); 2945 llvm::StringRef Name = OutName.str(); 2946 2947 ComputeVTableRelatedInformation(RD, true); 2948 2949 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 2950 llvm::ArrayType *ArrayType = 2951 llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD)); 2952 2953 llvm::GlobalVariable *GV = 2954 CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, 2955 llvm::GlobalValue::ExternalLinkage); 2956 GV->setUnnamedAddr(true); 2957 return GV; 2958} 2959 2960void 2961CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, 2962 llvm::GlobalVariable::LinkageTypes Linkage, 2963 const CXXRecordDecl *RD) { 2964 // Dump the vtable layout if necessary. 2965 if (CGM.getLangOptions().DumpVTableLayouts) { 2966 VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD); 2967 2968 Builder.dumpLayout(llvm::errs()); 2969 } 2970 2971 assert(VTableThunksMap.count(RD) && 2972 "No thunk status for this record decl!"); 2973 2974 const VTableThunksTy& Thunks = VTableThunksMap[RD]; 2975 2976 // Create and set the initializer. 2977 llvm::Constant *Init = 2978 CreateVTableInitializer(RD, getVTableComponentsData(RD), 2979 getNumVTableComponents(RD), Thunks); 2980 VTable->setInitializer(Init); 2981 2982 // Set the correct linkage. 2983 VTable->setLinkage(Linkage); 2984 2985 // Set the right visibility. 2986 CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); 2987} 2988 2989llvm::GlobalVariable * 2990CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, 2991 const BaseSubobject &Base, 2992 bool BaseIsVirtual, 2993 VTableAddressPointsMapTy& AddressPoints) { 2994 VTableBuilder Builder(*this, Base.getBase(), Base.getBaseOffset(), 2995 /*MostDerivedClassIsVirtual=*/BaseIsVirtual, RD); 2996 2997 // Dump the vtable layout if necessary. 2998 if (CGM.getLangOptions().DumpVTableLayouts) 2999 Builder.dumpLayout(llvm::errs()); 3000 3001 // Add the address points. 3002 AddressPoints.insert(Builder.address_points_begin(), 3003 Builder.address_points_end()); 3004 3005 // Get the mangled construction vtable name. 3006 llvm::SmallString<256> OutName; 3007 CGM.getCXXABI().getMangleContext(). 3008 mangleCXXCtorVTable(RD, Base.getBaseOffset() / 8, Base.getBase(), OutName); 3009 llvm::StringRef Name = OutName.str(); 3010 3011 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 3012 llvm::ArrayType *ArrayType = 3013 llvm::ArrayType::get(Int8PtrTy, Builder.getNumVTableComponents()); 3014 3015 // Create the variable that will hold the construction vtable. 3016 llvm::GlobalVariable *VTable = 3017 CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, 3018 llvm::GlobalValue::InternalLinkage); 3019 3020 // Add the thunks. 3021 VTableThunksTy VTableThunks; 3022 VTableThunks.append(Builder.vtable_thunks_begin(), 3023 Builder.vtable_thunks_end()); 3024 3025 // Sort them. 3026 std::sort(VTableThunks.begin(), VTableThunks.end()); 3027 3028 // Create and set the initializer. 3029 llvm::Constant *Init = 3030 CreateVTableInitializer(Base.getBase(), 3031 Builder.vtable_components_data_begin(), 3032 Builder.getNumVTableComponents(), VTableThunks); 3033 VTable->setInitializer(Init); 3034 3035 return VTable; 3036} 3037 3038void 3039CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, 3040 const CXXRecordDecl *RD) { 3041 llvm::GlobalVariable *&VTable = VTables[RD]; 3042 if (VTable) { 3043 assert(VTable->getInitializer() && "VTable doesn't have a definition!"); 3044 return; 3045 } 3046 3047 VTable = GetAddrOfVTable(RD); 3048 EmitVTableDefinition(VTable, Linkage, RD); 3049 3050 if (RD->getNumVBases()) { 3051 llvm::GlobalVariable *VTT = GetAddrOfVTT(RD); 3052 EmitVTTDefinition(VTT, Linkage, RD); 3053 } 3054 3055 // If this is the magic class __cxxabiv1::__fundamental_type_info, 3056 // we will emit the typeinfo for the fundamental types. This is the 3057 // same behaviour as GCC. 3058 const DeclContext *DC = RD->getDeclContext(); 3059 if (RD->getIdentifier() && 3060 RD->getIdentifier()->isStr("__fundamental_type_info") && 3061 isa<NamespaceDecl>(DC) && 3062 cast<NamespaceDecl>(DC)->getIdentifier() && 3063 cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && 3064 DC->getParent()->isTranslationUnit()) 3065 CGM.EmitFundamentalRTTIDescriptors(); 3066} 3067