CGVTables.cpp revision f622b450d722b2954572e6ba04e1cdf18a21a41f
1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//===--- CGVtables.cpp - Emit LLVM Code for C++ vtables -------------------===// 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// The LLVM Compiler Infrastructure 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This file is distributed under the University of Illinois Open Source 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// License. See LICENSE.TXT for details. 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 8c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru//===----------------------------------------------------------------------===// 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This contains code dealing with C++ code generation of virtual tables. 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//===----------------------------------------------------------------------===// 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CodeGenModule.h" 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CodeGenFunction.h" 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "clang/AST/CXXInheritance.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "clang/AST/RecordLayout.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "llvm/ADT/DenseSet.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "llvm/ADT/SetVector.h" 20c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru#include "llvm/Support/Compiler.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "llvm/Support/Format.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <algorithm> 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <cstdio> 24c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 25c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queruusing namespace clang; 26c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queruusing namespace CodeGen; 27c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 28c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Querunamespace { 29c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 30c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru/// BaseOffset - Represents an offset from a derived class to a direct or 31c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru/// indirect base class. 32c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Querustruct BaseOffset { 33c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// DerivedClass - The derived class. 34c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *DerivedClass; 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// VirtualBase - If the path from the derived class to the base class 37c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// involves a virtual base class, this holds its declaration. 38c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *VirtualBase; 39c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 40c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// NonVirtualOffset - The offset from the derived class to the base class. 41c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// (Or the offset from the virtual base class to the base class, if the 42c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// path from the derived class to the base class involves a virtual base 43c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// class. 44c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru int64_t NonVirtualOffset; 45c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 46c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru BaseOffset() : DerivedClass(0), VirtualBase(0), NonVirtualOffset(0) { } 47c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru BaseOffset(const CXXRecordDecl *DerivedClass, 48c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *VirtualBase, int64_t NonVirtualOffset) 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NonVirtualOffset(NonVirtualOffset) { } 51c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 52c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru bool isEmpty() const { return !NonVirtualOffset && !VirtualBase; } 53c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru}; 54c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 55c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru/// FinalOverriders - Contains the final overrider member functions for all 56c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru/// member functions in the base subobjects of a class. 57c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queruclass FinalOverriders { 58c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Querupublic: 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// OverriderInfo - Information about a final overrider. 60c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru struct OverriderInfo { 61c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// Method - The method decl of the overrider. 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXMethodDecl *Method; 63c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 64c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// Offset - the base offset of the overrider in the layout class. 65c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru uint64_t Offset; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru OverriderInfo() : Method(0), Offset(0) { } 68c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru }; 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 70c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queruprivate: 71c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// MostDerivedClass - The most derived class for which the final overriders 72c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// are stored. 73c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *MostDerivedClass; 74c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 75c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// MostDerivedClassOffset - If we're building final overriders for a 76c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// construction vtable, this holds the offset from the layout class to the 77c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// most derived class. 78c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const uint64_t MostDerivedClassOffset; 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 80c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// LayoutClass - The class we're using for layout information. Will be 81c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// different than the most derived class if the final overriders are for a 82c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// construction vtable. 83c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *LayoutClass; 84c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 85c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ASTContext &Context; 86c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 87c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// MostDerivedClassLayout - the AST record layout of the most derived class. 88c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const ASTRecordLayout &MostDerivedClassLayout; 89c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 90c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// BaseSubobjectMethodPairTy - Uniquely identifies a member function 91c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// in a base subobject. 92c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru typedef std::pair<BaseSubobject, const CXXMethodDecl *> 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru BaseSubobjectMethodPairTy; 94c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 95c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru typedef llvm::DenseMap<BaseSubobjectMethodPairTy, 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OverriderInfo> OverridersMapTy; 97c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 98c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// OverridersMap - The final overriders for all virtual member functions of 99c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// all the base subobjects of the most derived class. 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OverridersMapTy OverridersMap; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 102c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// VisitedVirtualBases - A set of all the visited virtual bases, used to 103c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// avoid visiting virtual bases more than once. 104c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 105c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru typedef llvm::DenseMap<BaseSubobjectMethodPairTy, BaseOffset> 107c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru AdjustmentOffsetsMapTy; 108c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// ReturnAdjustments - Holds return adjustments for all the overriders that 110c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// need to perform return value adjustments. 111c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru AdjustmentOffsetsMapTy ReturnAdjustments; 112c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 113c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // FIXME: We might be able to get away with making this a SmallSet. 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru typedef llvm::SmallSetVector<uint64_t, 2> OffsetSetVectorTy; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// SubobjectOffsetsMapTy - This map is used for keeping track of all the 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// base subobject offsets that a single class declaration might refer to. 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// For example, in: 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct A { virtual void f(); }; 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct B1 : A { }; 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct B2 : A { }; 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct C : B1, B2 { virtual void f(); }; 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// when we determine that C::f() overrides A::f(), we need to update the 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// overriders map for both A-in-B1 and A-in-B2 and the subobject offsets map 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// will have the subobject offsets for both A copies. 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru typedef llvm::DenseMap<const CXXRecordDecl *, OffsetSetVectorTy> 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SubobjectOffsetsMapTy; 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// ComputeFinalOverriders - Compute the final overriders for a given base 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// subobject (and all its direct and indirect bases). 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void ComputeFinalOverriders(BaseSubobject Base, 135c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru bool BaseSubobjectIsVisitedVBase, 136d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru uint64_t OffsetInLayoutClass, 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SubobjectOffsetsMapTy &Offsets); 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 139c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// AddOverriders - Add the final overriders for this base subobject to the 140c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /// map of final overriders. 141d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru void AddOverriders(BaseSubobject Base, uint64_t OffsetInLayoutClass, 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SubobjectOffsetsMapTy &Offsets); 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// PropagateOverrider - Propagate the NewMD overrider to all the functions 145d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// that OldMD overrides. For example, if we have: 146d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// 147d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// struct A { virtual void f(); }; 148d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// struct B : A { virtual void f(); }; 149d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// struct C : B { virtual void f(); }; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// and we want to override B::f with C::f, we also need to override A::f with 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// C::f. 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void PropagateOverrider(const CXXMethodDecl *OldMD, 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru BaseSubobject NewBase, 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint64_t OverriderOffsetInLayoutClass, 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXMethodDecl *NewMD, 157d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru SubobjectOffsetsMapTy &Offsets); 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static void MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets, 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SubobjectOffsetsMapTy &Offsets); 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FinalOverriders(const CXXRecordDecl *MostDerivedClass, 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint64_t MostDerivedClassOffset, 165d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *LayoutClass); 166d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 167d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// getOverrider - Get the final overrider for the given method declaration in 168d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// the given base subobject. 169d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru OverriderInfo getOverrider(BaseSubobject Base, 170d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXMethodDecl *MD) const { 171d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru assert(OverridersMap.count(std::make_pair(Base, MD)) && 172d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru "Did not find overrider!"); 173d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 174d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru return OverridersMap.lookup(std::make_pair(Base, MD)); 175d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 176d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 177d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// getReturnAdjustmentOffset - Get the return adjustment offset for the 178d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// method decl in the given base subobject. Returns an empty base offset if 179d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// no adjustment is needed. 180d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru BaseOffset getReturnAdjustmentOffset(BaseSubobject Base, 181d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXMethodDecl *MD) const { 182d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru return ReturnAdjustments.lookup(std::make_pair(Base, MD)); 183d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 184d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 185d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// dump - dump the final overriders. 186d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru void dump() { 187d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru assert(VisitedVirtualBases.empty() && 188d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru "Visited virtual bases aren't empty!"); 189d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0)); 190d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru VisitedVirtualBases.clear(); 191d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 192d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 193d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// dump - dump the final overriders for a base subobject, and all its direct 194d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /// and indirect base subobjects. 195d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru void dump(llvm::raw_ostream &Out, BaseSubobject Base); 196d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru}; 197d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 198d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru#define DUMP_OVERRIDERS 0 199d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 200d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste QueruFinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, 201d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru uint64_t MostDerivedClassOffset, 202d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *LayoutClass) 203d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru : MostDerivedClass(MostDerivedClass), 204d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), 205d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru Context(MostDerivedClass->getASTContext()), 206d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { 207d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 208d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // Compute the final overriders. 209d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru SubobjectOffsetsMapTy Offsets; 210d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru ComputeFinalOverriders(BaseSubobject(MostDerivedClass, 0), 211d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /*BaseSubobjectIsVisitedVBase=*/false, 212d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru MostDerivedClassOffset, Offsets); 213d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru VisitedVirtualBases.clear(); 214d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 215d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru#if DUMP_OVERRIDERS 216d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // And dump them (for now). 217d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru dump(); 218d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 219d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // Also dump the base offsets (for now). 220d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru for (SubobjectOffsetsMapTy::const_iterator I = Offsets.begin(), 221d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru E = Offsets.end(); I != E; ++I) { 222d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const OffsetSetVectorTy& OffsetSetVector = I->second; 223d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 224d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru llvm::errs() << "Base offsets for "; 225d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru llvm::errs() << I->first->getQualifiedNameAsString() << '\n'; 226d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 227d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru for (unsigned I = 0, E = OffsetSetVector.size(); I != E; ++I) 228d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru llvm::errs() << " " << I << " - " << OffsetSetVector[I] / 8 << '\n'; 229d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 230d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru#endif 231d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru} 232d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 233d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queruvoid FinalOverriders::AddOverriders(BaseSubobject Base, 234d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru uint64_t OffsetInLayoutClass, 235d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru SubobjectOffsetsMapTy &Offsets) { 236d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *RD = Base.getBase(); 237d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 238d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru for (CXXRecordDecl::method_iterator I = RD->method_begin(), 239d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru E = RD->method_end(); I != E; ++I) { 240d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXMethodDecl *MD = *I; 241d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 242d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru if (!MD->isVirtual()) 243d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru continue; 244d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 245d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // First, propagate the overrider. 246d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru PropagateOverrider(MD, Base, OffsetInLayoutClass, MD, Offsets); 247d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 248d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // Add the overrider as the final overrider of itself. 249d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru OverriderInfo& Overrider = OverridersMap[std::make_pair(Base, MD)]; 250d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru assert(!Overrider.Method && "Overrider should not exist yet!"); 251d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 252d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru Overrider.Offset = OffsetInLayoutClass; 253d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru Overrider.Method = MD; 254d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 255d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru} 256d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 257d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Querustatic BaseOffset ComputeBaseOffset(ASTContext &Context, 258d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *DerivedRD, 259d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXBasePath &Path) { 260d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru int64_t NonVirtualOffset = 0; 261d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 262d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru unsigned NonVirtualStart = 0; 263d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *VirtualBase = 0; 264d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 265d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // First, look for the virtual base class. 266d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru for (unsigned I = 0, E = Path.size(); I != E; ++I) { 267d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXBasePathElement &Element = Path[I]; 268d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 269d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru if (Element.Base->isVirtual()) { 270d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // FIXME: Can we break when we find the first virtual base? 271d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // (If we can't, can't we just iterate over the path in reverse order?) 272d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru NonVirtualStart = I + 1; 273d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru QualType VBaseType = Element.Base->getType(); 274d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru VirtualBase = 275d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 276d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 277d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 278d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 279d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // Now compute the non-virtual offset. 280d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) { 281d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXBasePathElement &Element = Path[I]; 282d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 283d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // Check the base class offset. 284d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); 285d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 286d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>(); 287d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl()); 288d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 289d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru NonVirtualOffset += Layout.getBaseClassOffset(Base); 290d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 291d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 292d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // FIXME: This should probably use CharUnits or something. Maybe we should 293d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // even change the base offsets in ASTRecordLayout to be specified in 294d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // CharUnits. 295d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset / 8); 296d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 297d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru} 298d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 299d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Querustatic BaseOffset ComputeBaseOffset(ASTContext &Context, 300d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *BaseRD, 301d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *DerivedRD) { 302d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru CXXBasePaths Paths(/*FindAmbiguities=*/false, 303d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru /*RecordPaths=*/true, /*DetectVirtual=*/false); 304d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 305d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru if (!const_cast<CXXRecordDecl *>(DerivedRD)-> 306d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { 307d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru assert(false && "Class must be derived from the passed in base class!"); 308d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru return BaseOffset(); 309d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru } 310d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 311d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru return ComputeBaseOffset(Context, DerivedRD, Paths.front()); 312d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru} 313d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru 314d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Querustatic BaseOffset 315d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste QueruComputeReturnAdjustmentBaseOffset(ASTContext &Context, 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXMethodDecl *DerivedMD, 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXMethodDecl *BaseMD) { 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>(); 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>(); 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Canonicalize the return types. 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanQualType CanDerivedReturnType = 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Context.getCanonicalType(DerivedFT->getResultType()); 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanQualType CanBaseReturnType = 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Context.getCanonicalType(BaseFT->getResultType()); 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru assert(CanDerivedReturnType->getTypeClass() == 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanBaseReturnType->getTypeClass() && 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "Types must have same type class!"); 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (CanDerivedReturnType == CanBaseReturnType) { 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // No adjustment needed. 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return BaseOffset(); 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isa<ReferenceType>(CanDerivedReturnType)) { 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanDerivedReturnType = 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType(); 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanBaseReturnType = 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanBaseReturnType->getAs<ReferenceType>()->getPointeeType(); 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (isa<PointerType>(CanDerivedReturnType)) { 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanDerivedReturnType = 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanDerivedReturnType->getAs<PointerType>()->getPointeeType(); 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanBaseReturnType = 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanBaseReturnType->getAs<PointerType>()->getPointeeType(); 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru assert(false && "Unexpected return type!"); 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // We need to compare unqualified types here; consider 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // const T *Base::foo(); 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // T *Derived::foo(); 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (CanDerivedReturnType.getUnqualifiedType() == 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanBaseReturnType.getUnqualifiedType()) { 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // No adjustment needed. 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return BaseOffset(); 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXRecordDecl *DerivedRD = 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()); 361a733874a9800264e7b41d880049ac4bf9d7f405fJean-Baptiste Queru 362d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru const CXXRecordDecl *BaseRD = 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ComputeBaseOffset(Context, BaseRD, DerivedRD); 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD, 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru BaseSubobject NewBase, 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint64_t OverriderOffsetInLayoutClass, 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXMethodDecl *NewMD, 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SubobjectOffsetsMapTy &Offsets) { 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (CXXMethodDecl::method_iterator I = OldMD->begin_overridden_methods(), 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru E = OldMD->end_overridden_methods(); I != E; ++I) { 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXMethodDecl *OverriddenMD = *I; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent(); 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 378a733874a9800264e7b41d880049ac4bf9d7f405fJean-Baptiste Queru // We want to override OverriddenMD in all subobjects, for example: 379d6d7ff8f454b9a685bba7df6ad106f7e83559922Jean-Baptiste Queru // 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct A { virtual void f(); }; 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct B1 : A { }; 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct B2 : A { }; 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// struct C : B1, B2 { virtual void f(); }; 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// When overriding A::f with C::f we need to do so in both A subobjects. 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const OffsetSetVectorTy &OffsetVector = Offsets[OverriddenRD]; 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Go through all the subobjects. 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (unsigned I = 0, E = OffsetVector.size(); I != E; ++I) { 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint64_t Offset = OffsetVector[I]; 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru BaseSubobject OverriddenSubobject = BaseSubobject(OverriddenRD, Offset); 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru BaseSubobjectMethodPairTy SubobjectAndMethod = 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru std::make_pair(OverriddenSubobject, OverriddenMD); 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OverriderInfo &Overrider = OverridersMap[SubobjectAndMethod]; 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru assert(Overrider.Method && "Did not find existing overrider!"); 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Check if we need return adjustments or base adjustments. 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (We don't want to do this for pure virtual member functions). 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!NewMD->isPure()) { 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Get the return adjustment base offset. 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru BaseOffset ReturnBaseOffset = 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ComputeReturnAdjustmentBaseOffset(Context, NewMD, OverriddenMD); 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ReturnBaseOffset.isEmpty()) { 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Store the return adjustment base offset. 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ReturnAdjustments[SubobjectAndMethod] = ReturnBaseOffset; 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Set the new overrider. 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Overrider.Offset = OverriderOffsetInLayoutClass; 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Overrider.Method = NewMD; 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // And propagate it further. 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru PropagateOverrider(OverriddenMD, NewBase, OverriderOffsetInLayoutClass, 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NewMD, Offsets); 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 421c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 422c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru} 423c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 424c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queruvoid 425c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste QueruFinalOverriders::MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets, 426c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru SubobjectOffsetsMapTy &Offsets) { 427c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // Iterate over the new offsets. 428c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru for (SubobjectOffsetsMapTy::const_iterator I = NewOffsets.begin(), 429c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru E = NewOffsets.end(); I != E; ++I) { 430c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *NewRD = I->first; 431c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const OffsetSetVectorTy& NewOffsetVector = I->second; 432c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 433c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru OffsetSetVectorTy &OffsetVector = Offsets[NewRD]; 434c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 435c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // Merge the new offsets set vector into the old. 436c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru OffsetVector.insert(NewOffsetVector.begin(), NewOffsetVector.end()); 437c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 438c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru} 439c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 440c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queruvoid FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, 441c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru bool BaseSubobjectIsVisitedVBase, 442c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru uint64_t OffsetInLayoutClass, 443c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru SubobjectOffsetsMapTy &Offsets) { 444c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *RD = Base.getBase(); 445c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 446c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 447c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru SubobjectOffsetsMapTy NewOffsets; 448c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 449c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 450c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru E = RD->bases_end(); I != E; ++I) { 451c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const CXXRecordDecl *BaseDecl = 452c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 453c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 454c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // Ignore bases that don't have any virtual member functions. 455c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if (!BaseDecl->isPolymorphic()) 456c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru continue; 457c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 458c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru bool IsVisitedVirtualBase = BaseSubobjectIsVisitedVBase; 459c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru uint64_t BaseOffset; 460c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru uint64_t BaseOffsetInLayoutClass; 461c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if (I->isVirtual()) { 462c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if (!VisitedVirtualBases.insert(BaseDecl)) 463c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru IsVisitedVirtualBase = true; 464c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 465c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 466c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const ASTRecordLayout &LayoutClassLayout = 467c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru Context.getASTRecordLayout(LayoutClass); 468c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru BaseOffsetInLayoutClass = 469c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru LayoutClassLayout.getVBaseClassOffset(BaseDecl); 470c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } else { 471c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); 472c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru BaseOffsetInLayoutClass = Layout.getBaseClassOffset(BaseDecl) + 473c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru OffsetInLayoutClass; 474c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 475c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 476c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // Compute the final overriders for this base. 477c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // We always want to compute the final overriders, even if the base is a 478c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // visited virtual base. Consider: 479c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // 480c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // struct A { 481c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // virtual void f(); 482c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // virtual void g(); 483c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // }; 484c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // 485c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // struct B : virtual A { 486c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // void f(); 487c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // }; 488c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // 489c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // struct C : virtual A { 490c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // void g (); 491c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // }; 492c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // 493c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // struct D : B, C { }; 494c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // 495c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // Here, we still want to compute the overriders for A as a base of C, 496c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru // because otherwise we'll miss that C::g overrides A::f. 497c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset), 498c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru IsVisitedVirtualBase, BaseOffsetInLayoutClass, 499c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru NewOffsets); 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// Now add the overriders for this particular subobject. 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /// (We don't want to do this more than once for a virtual base). 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!BaseSubobjectIsVisitedVBase) 505 AddOverriders(Base, OffsetInLayoutClass, NewOffsets); 506 507 // And merge the newly discovered subobject offsets. 508 MergeSubobjectOffsets(NewOffsets, Offsets); 509 510 /// Finally, add the offset for our own subobject. 511 Offsets[RD].insert(Base.getBaseOffset()); 512} 513 514void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) { 515 const CXXRecordDecl *RD = Base.getBase(); 516 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 517 518 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 519 E = RD->bases_end(); I != E; ++I) { 520 const CXXRecordDecl *BaseDecl = 521 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 522 523 // Ignore bases that don't have any virtual member functions. 524 if (!BaseDecl->isPolymorphic()) 525 continue; 526 527 uint64_t BaseOffset; 528 if (I->isVirtual()) { 529 if (!VisitedVirtualBases.insert(BaseDecl)) { 530 // We've visited this base before. 531 continue; 532 } 533 534 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 535 } else { 536 BaseOffset = Layout.getBaseClassOffset(BaseDecl) + 537 Base.getBaseOffset(); 538 } 539 540 dump(Out, BaseSubobject(BaseDecl, BaseOffset)); 541 } 542 543 Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", "; 544 Out << Base.getBaseOffset() / 8 << ")\n"; 545 546 // Now dump the overriders for this base subobject. 547 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 548 E = RD->method_end(); I != E; ++I) { 549 const CXXMethodDecl *MD = *I; 550 551 if (!MD->isVirtual()) 552 continue; 553 554 OverriderInfo Overrider = getOverrider(Base, MD); 555 556 Out << " " << MD->getQualifiedNameAsString() << " - ("; 557 Out << Overrider.Method->getQualifiedNameAsString(); 558 Out << ", " << ", " << Overrider.Offset / 8 << ')'; 559 560 AdjustmentOffsetsMapTy::const_iterator AI = 561 ReturnAdjustments.find(std::make_pair(Base, MD)); 562 if (AI != ReturnAdjustments.end()) { 563 const BaseOffset &Offset = AI->second; 564 565 Out << " [ret-adj: "; 566 if (Offset.VirtualBase) 567 Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, "; 568 569 Out << Offset.NonVirtualOffset << " nv]"; 570 } 571 572 Out << "\n"; 573 } 574} 575 576/// VTableComponent - Represents a single component in a vtable. 577class VTableComponent { 578public: 579 enum Kind { 580 CK_VCallOffset, 581 CK_VBaseOffset, 582 CK_OffsetToTop, 583 CK_RTTI, 584 CK_FunctionPointer, 585 586 /// CK_CompleteDtorPointer - A pointer to the complete destructor. 587 CK_CompleteDtorPointer, 588 589 /// CK_DeletingDtorPointer - A pointer to the deleting destructor. 590 CK_DeletingDtorPointer, 591 592 /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer 593 /// will end up never being called. Such vtable function pointers are 594 /// represented as a CK_UnusedFunctionPointer. 595 CK_UnusedFunctionPointer 596 }; 597 598 static VTableComponent MakeVCallOffset(int64_t Offset) { 599 return VTableComponent(CK_VCallOffset, Offset); 600 } 601 602 static VTableComponent MakeVBaseOffset(int64_t Offset) { 603 return VTableComponent(CK_VBaseOffset, Offset); 604 } 605 606 static VTableComponent MakeOffsetToTop(int64_t Offset) { 607 return VTableComponent(CK_OffsetToTop, Offset); 608 } 609 610 static VTableComponent MakeRTTI(const CXXRecordDecl *RD) { 611 return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD)); 612 } 613 614 static VTableComponent MakeFunction(const CXXMethodDecl *MD) { 615 assert(!isa<CXXDestructorDecl>(MD) && 616 "Don't use MakeFunction with destructors!"); 617 618 return VTableComponent(CK_FunctionPointer, 619 reinterpret_cast<uintptr_t>(MD)); 620 } 621 622 static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) { 623 return VTableComponent(CK_CompleteDtorPointer, 624 reinterpret_cast<uintptr_t>(DD)); 625 } 626 627 static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) { 628 return VTableComponent(CK_DeletingDtorPointer, 629 reinterpret_cast<uintptr_t>(DD)); 630 } 631 632 static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) { 633 assert(!isa<CXXDestructorDecl>(MD) && 634 "Don't use MakeUnusedFunction with destructors!"); 635 return VTableComponent(CK_UnusedFunctionPointer, 636 reinterpret_cast<uintptr_t>(MD)); 637 } 638 639 static VTableComponent getFromOpaqueInteger(uint64_t I) { 640 return VTableComponent(I); 641 } 642 643 /// getKind - Get the kind of this vtable component. 644 Kind getKind() const { 645 return (Kind)(Value & 0x7); 646 } 647 648 int64_t getVCallOffset() const { 649 assert(getKind() == CK_VCallOffset && "Invalid component kind!"); 650 651 return getOffset(); 652 } 653 654 int64_t getVBaseOffset() const { 655 assert(getKind() == CK_VBaseOffset && "Invalid component kind!"); 656 657 return getOffset(); 658 } 659 660 int64_t getOffsetToTop() const { 661 assert(getKind() == CK_OffsetToTop && "Invalid component kind!"); 662 663 return getOffset(); 664 } 665 666 const CXXRecordDecl *getRTTIDecl() const { 667 assert(getKind() == CK_RTTI && "Invalid component kind!"); 668 669 return reinterpret_cast<CXXRecordDecl *>(getPointer()); 670 } 671 672 const CXXMethodDecl *getFunctionDecl() const { 673 assert(getKind() == CK_FunctionPointer); 674 675 return reinterpret_cast<CXXMethodDecl *>(getPointer()); 676 } 677 678 const CXXDestructorDecl *getDestructorDecl() const { 679 assert((getKind() == CK_CompleteDtorPointer || 680 getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); 681 682 return reinterpret_cast<CXXDestructorDecl *>(getPointer()); 683 } 684 685 const CXXMethodDecl *getUnusedFunctionDecl() const { 686 assert(getKind() == CK_UnusedFunctionPointer); 687 688 return reinterpret_cast<CXXMethodDecl *>(getPointer()); 689 } 690 691private: 692 VTableComponent(Kind ComponentKind, int64_t Offset) { 693 assert((ComponentKind == CK_VCallOffset || 694 ComponentKind == CK_VBaseOffset || 695 ComponentKind == CK_OffsetToTop) && "Invalid component kind!"); 696 assert(Offset <= ((1LL << 56) - 1) && "Offset is too big!"); 697 698 Value = ((Offset << 3) | ComponentKind); 699 } 700 701 VTableComponent(Kind ComponentKind, uintptr_t Ptr) { 702 assert((ComponentKind == CK_RTTI || 703 ComponentKind == CK_FunctionPointer || 704 ComponentKind == CK_CompleteDtorPointer || 705 ComponentKind == CK_DeletingDtorPointer || 706 ComponentKind == CK_UnusedFunctionPointer) && 707 "Invalid component kind!"); 708 709 assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); 710 711 Value = Ptr | ComponentKind; 712 } 713 714 int64_t getOffset() const { 715 assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset || 716 getKind() == CK_OffsetToTop) && "Invalid component kind!"); 717 718 return Value >> 3; 719 } 720 721 uintptr_t getPointer() const { 722 assert((getKind() == CK_RTTI || 723 getKind() == CK_FunctionPointer || 724 getKind() == CK_CompleteDtorPointer || 725 getKind() == CK_DeletingDtorPointer || 726 getKind() == CK_UnusedFunctionPointer) && 727 "Invalid component kind!"); 728 729 return static_cast<uintptr_t>(Value & ~7ULL); 730 } 731 732 explicit VTableComponent(uint64_t Value) 733 : Value(Value) { } 734 735 /// The kind is stored in the lower 3 bits of the value. For offsets, we 736 /// make use of the facts that classes can't be larger than 2^55 bytes, 737 /// so we store the offset in the lower part of the 61 bytes that remain. 738 /// (The reason that we're not simply using a PointerIntPair here is that we 739 /// need the offsets to be 64-bit, even when on a 32-bit machine). 740 int64_t Value; 741}; 742 743/// VCallOffsetMap - Keeps track of vcall offsets when building a vtable. 744struct VCallOffsetMap { 745 746 typedef std::pair<const CXXMethodDecl *, int64_t> MethodAndOffsetPairTy; 747 748 /// Offsets - Keeps track of methods and their offsets. 749 // FIXME: This should be a real map and not a vector. 750 llvm::SmallVector<MethodAndOffsetPairTy, 16> Offsets; 751 752 /// MethodsCanShareVCallOffset - Returns whether two virtual member functions 753 /// can share the same vcall offset. 754 static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 755 const CXXMethodDecl *RHS); 756 757public: 758 /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the 759 /// add was successful, or false if there was already a member function with 760 /// the same signature in the map. 761 bool AddVCallOffset(const CXXMethodDecl *MD, int64_t OffsetOffset); 762 763 /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the 764 /// vtable address point) for the given virtual member function. 765 int64_t getVCallOffsetOffset(const CXXMethodDecl *MD); 766 767 // empty - Return whether the offset map is empty or not. 768 bool empty() const { return Offsets.empty(); } 769}; 770 771static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, 772 const CXXMethodDecl *RHS) { 773 ASTContext &C = LHS->getASTContext(); // TODO: thread this down 774 CanQual<FunctionProtoType> 775 LT = C.getCanonicalType(LHS->getType()).getAs<FunctionProtoType>(), 776 RT = C.getCanonicalType(RHS->getType()).getAs<FunctionProtoType>(); 777 778 // Fast-path matches in the canonical types. 779 if (LT == RT) return true; 780 781 // Force the signatures to match. We can't rely on the overrides 782 // list here because there isn't necessarily an inheritance 783 // relationship between the two methods. 784 if (LT.getQualifiers() != RT.getQualifiers() || 785 LT->getNumArgs() != RT->getNumArgs()) 786 return false; 787 for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) 788 if (LT->getArgType(I) != RT->getArgType(I)) 789 return false; 790 return true; 791} 792 793bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 794 const CXXMethodDecl *RHS) { 795 assert(LHS->isVirtual() && "LHS must be virtual!"); 796 assert(RHS->isVirtual() && "LHS must be virtual!"); 797 798 // A destructor can share a vcall offset with another destructor. 799 if (isa<CXXDestructorDecl>(LHS)) 800 return isa<CXXDestructorDecl>(RHS); 801 802 // FIXME: We need to check more things here. 803 804 // The methods must have the same name. 805 DeclarationName LHSName = LHS->getDeclName(); 806 DeclarationName RHSName = RHS->getDeclName(); 807 if (LHSName != RHSName) 808 return false; 809 810 // And the same signatures. 811 return HasSameVirtualSignature(LHS, RHS); 812} 813 814bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, 815 int64_t OffsetOffset) { 816 // Check if we can reuse an offset. 817 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 818 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 819 return false; 820 } 821 822 // Add the offset. 823 Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset)); 824 return true; 825} 826 827int64_t VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { 828 // Look for an offset. 829 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 830 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 831 return Offsets[I].second; 832 } 833 834 assert(false && "Should always find a vcall offset offset!"); 835 return 0; 836} 837 838/// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. 839class VCallAndVBaseOffsetBuilder { 840public: 841 typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 842 VBaseOffsetOffsetsMapTy; 843 844private: 845 /// MostDerivedClass - The most derived class for which we're building vcall 846 /// and vbase offsets. 847 const CXXRecordDecl *MostDerivedClass; 848 849 /// LayoutClass - The class we're using for layout information. Will be 850 /// different than the most derived class if we're building a construction 851 /// vtable. 852 const CXXRecordDecl *LayoutClass; 853 854 /// Context - The ASTContext which we will use for layout information. 855 ASTContext &Context; 856 857 /// Components - vcall and vbase offset components 858 typedef llvm::SmallVector<VTableComponent, 64> VTableComponentVectorTy; 859 VTableComponentVectorTy Components; 860 861 /// VisitedVirtualBases - Visited virtual bases. 862 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 863 864 /// VCallOffsets - Keeps track of vcall offsets. 865 VCallOffsetMap VCallOffsets; 866 867 868 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets, 869 /// relative to the address point. 870 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 871 872 /// FinalOverriders - The final overriders of the most derived class. 873 /// (Can be null when we're not building a vtable of the most derived class). 874 const FinalOverriders *Overriders; 875 876 /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the 877 /// given base subobject. 878 void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, 879 uint64_t RealBaseOffset); 880 881 /// AddVCallOffsets - Add vcall offsets for the given base subobject. 882 void AddVCallOffsets(BaseSubobject Base, uint64_t VBaseOffset); 883 884 /// AddVBaseOffsets - Add vbase offsets for the given class. 885 void AddVBaseOffsets(const CXXRecordDecl *Base, uint64_t OffsetInLayoutClass); 886 887 /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in 888 /// bytes, relative to the vtable address point. 889 int64_t getCurrentOffsetOffset() const; 890 891public: 892 VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, 893 const CXXRecordDecl *LayoutClass, 894 const FinalOverriders *Overriders, 895 BaseSubobject Base, bool BaseIsVirtual, 896 uint64_t OffsetInLayoutClass) 897 : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 898 Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { 899 900 // Add vcall and vbase offsets. 901 AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); 902 } 903 904 /// Methods for iterating over the components. 905 typedef VTableComponentVectorTy::const_reverse_iterator const_iterator; 906 const_iterator components_begin() const { return Components.rbegin(); } 907 const_iterator components_end() const { return Components.rend(); } 908 909 const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; } 910 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 911 return VBaseOffsetOffsets; 912 } 913}; 914 915void 916VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, 917 bool BaseIsVirtual, 918 uint64_t RealBaseOffset) { 919 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); 920 921 // Itanium C++ ABI 2.5.2: 922 // ..in classes sharing a virtual table with a primary base class, the vcall 923 // and vbase offsets added by the derived class all come before the vcall 924 // and vbase offsets required by the base class, so that the latter may be 925 // laid out as required by the base class without regard to additions from 926 // the derived class(es). 927 928 // (Since we're emitting the vcall and vbase offsets in reverse order, we'll 929 // emit them for the primary base first). 930 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 931 bool PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual(); 932 933 uint64_t PrimaryBaseOffset; 934 935 // Get the base offset of the primary base. 936 if (PrimaryBaseIsVirtual) { 937 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 938 "Primary vbase should have a zero offset!"); 939 940 const ASTRecordLayout &MostDerivedClassLayout = 941 Context.getASTRecordLayout(MostDerivedClass); 942 943 PrimaryBaseOffset = 944 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 945 } else { 946 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 947 "Primary base should have a zero offset!"); 948 949 PrimaryBaseOffset = Base.getBaseOffset(); 950 } 951 952 AddVCallAndVBaseOffsets(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 953 PrimaryBaseIsVirtual, RealBaseOffset); 954 } 955 956 AddVBaseOffsets(Base.getBase(), RealBaseOffset); 957 958 // We only want to add vcall offsets for virtual bases. 959 if (BaseIsVirtual) 960 AddVCallOffsets(Base, RealBaseOffset); 961} 962 963int64_t VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const { 964 // OffsetIndex is the index of this vcall or vbase offset, relative to the 965 // vtable address point. (We subtract 3 to account for the information just 966 // above the address point, the RTTI info, the offset to top, and the 967 // vcall offset itself). 968 int64_t OffsetIndex = -(int64_t)(3 + Components.size()); 969 970 // FIXME: We shouldn't use / 8 here. 971 int64_t OffsetOffset = OffsetIndex * 972 (int64_t)Context.Target.getPointerWidth(0) / 8; 973 974 return OffsetOffset; 975} 976 977void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 978 uint64_t VBaseOffset) { 979 const CXXRecordDecl *RD = Base.getBase(); 980 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 981 982 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 983 984 // Handle the primary base first. 985 if (PrimaryBase) { 986 uint64_t PrimaryBaseOffset; 987 988 // Get the base offset of the primary base. 989 if (Layout.getPrimaryBaseWasVirtual()) { 990 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 991 "Primary vbase should have a zero offset!"); 992 993 const ASTRecordLayout &MostDerivedClassLayout = 994 Context.getASTRecordLayout(MostDerivedClass); 995 996 PrimaryBaseOffset = 997 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 998 } else { 999 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 1000 "Primary base should have a zero offset!"); 1001 1002 PrimaryBaseOffset = Base.getBaseOffset(); 1003 } 1004 1005 AddVCallOffsets(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 1006 VBaseOffset); 1007 } 1008 1009 // Add the vcall offsets. 1010 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1011 E = RD->method_end(); I != E; ++I) { 1012 const CXXMethodDecl *MD = *I; 1013 1014 if (!MD->isVirtual()) 1015 continue; 1016 1017 int64_t OffsetOffset = getCurrentOffsetOffset(); 1018 1019 // Don't add a vcall offset if we already have one for this member function 1020 // signature. 1021 if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset)) 1022 continue; 1023 1024 int64_t Offset = 0; 1025 1026 if (Overriders) { 1027 // Get the final overrider. 1028 FinalOverriders::OverriderInfo Overrider = 1029 Overriders->getOverrider(Base, MD); 1030 1031 /// The vcall offset is the offset from the virtual base to the object 1032 /// where the function was overridden. 1033 // FIXME: We should not use / 8 here. 1034 Offset = (int64_t)(Overrider.Offset - VBaseOffset) / 8; 1035 } 1036 1037 Components.push_back(VTableComponent::MakeVCallOffset(Offset)); 1038 } 1039 1040 // And iterate over all non-virtual bases (ignoring the primary base). 1041 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1042 E = RD->bases_end(); I != E; ++I) { 1043 1044 if (I->isVirtual()) 1045 continue; 1046 1047 const CXXRecordDecl *BaseDecl = 1048 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1049 if (BaseDecl == PrimaryBase) 1050 continue; 1051 1052 // Get the base offset of this base. 1053 uint64_t BaseOffset = Base.getBaseOffset() + 1054 Layout.getBaseClassOffset(BaseDecl); 1055 1056 AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), VBaseOffset); 1057 } 1058} 1059 1060void VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, 1061 uint64_t OffsetInLayoutClass) { 1062 const ASTRecordLayout &LayoutClassLayout = 1063 Context.getASTRecordLayout(LayoutClass); 1064 1065 // Add vbase offsets. 1066 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1067 E = RD->bases_end(); I != E; ++I) { 1068 const CXXRecordDecl *BaseDecl = 1069 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1070 1071 // Check if this is a virtual base that we haven't visited before. 1072 if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) { 1073 // FIXME: We shouldn't use / 8 here. 1074 int64_t Offset = 1075 (int64_t)(LayoutClassLayout.getVBaseClassOffset(BaseDecl) - 1076 OffsetInLayoutClass) / 8; 1077 1078 // Add the vbase offset offset. 1079 assert(!VBaseOffsetOffsets.count(BaseDecl) && 1080 "vbase offset offset already exists!"); 1081 1082 int64_t VBaseOffsetOffset = getCurrentOffsetOffset(); 1083 VBaseOffsetOffsets.insert(std::make_pair(BaseDecl, VBaseOffsetOffset)); 1084 1085 Components.push_back(VTableComponent::MakeVBaseOffset(Offset)); 1086 } 1087 1088 // Check the base class looking for more vbase offsets. 1089 AddVBaseOffsets(BaseDecl, OffsetInLayoutClass); 1090 } 1091} 1092 1093/// VTableBuilder - Class for building vtable layout information. 1094class VTableBuilder { 1095public: 1096 /// PrimaryBasesSetVectorTy - A set vector of direct and indirect 1097 /// primary bases. 1098 typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> 1099 PrimaryBasesSetVectorTy; 1100 1101 typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 1102 VBaseOffsetOffsetsMapTy; 1103 1104 typedef llvm::DenseMap<BaseSubobject, uint64_t> 1105 AddressPointsMapTy; 1106 1107private: 1108 /// VTables - Global vtable information. 1109 CodeGenVTables &VTables; 1110 1111 /// MostDerivedClass - The most derived class for which we're building this 1112 /// vtable. 1113 const CXXRecordDecl *MostDerivedClass; 1114 1115 /// MostDerivedClassOffset - If we're building a construction vtable, this 1116 /// holds the offset from the layout class to the most derived class. 1117 const uint64_t MostDerivedClassOffset; 1118 1119 /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual 1120 /// base. (This only makes sense when building a construction vtable). 1121 bool MostDerivedClassIsVirtual; 1122 1123 /// LayoutClass - The class we're using for layout information. Will be 1124 /// different than the most derived class if we're building a construction 1125 /// vtable. 1126 const CXXRecordDecl *LayoutClass; 1127 1128 /// Context - The ASTContext which we will use for layout information. 1129 ASTContext &Context; 1130 1131 /// FinalOverriders - The final overriders of the most derived class. 1132 const FinalOverriders Overriders; 1133 1134 /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual 1135 /// bases in this vtable. 1136 llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases; 1137 1138 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for 1139 /// the most derived class. 1140 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 1141 1142 /// Components - The components of the vtable being built. 1143 llvm::SmallVector<VTableComponent, 64> Components; 1144 1145 /// AddressPoints - Address points for the vtable being built. 1146 AddressPointsMapTy AddressPoints; 1147 1148 /// MethodInfo - Contains information about a method in a vtable. 1149 /// (Used for computing 'this' pointer adjustment thunks. 1150 struct MethodInfo { 1151 /// BaseOffset - The base offset of this method. 1152 const uint64_t BaseOffset; 1153 1154 /// BaseOffsetInLayoutClass - The base offset in the layout class of this 1155 /// method. 1156 const uint64_t BaseOffsetInLayoutClass; 1157 1158 /// VtableIndex - The index in the vtable that this method has. 1159 /// (For destructors, this is the index of the complete destructor). 1160 const uint64_t VtableIndex; 1161 1162 MethodInfo(uint64_t BaseOffset, uint64_t BaseOffsetInLayoutClass, 1163 uint64_t VtableIndex) 1164 : BaseOffset(BaseOffset), 1165 BaseOffsetInLayoutClass(BaseOffsetInLayoutClass), 1166 VtableIndex(VtableIndex) { } 1167 1168 MethodInfo() : BaseOffset(0), BaseOffsetInLayoutClass(0), VtableIndex(0) { } 1169 }; 1170 1171 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 1172 1173 /// MethodInfoMap - The information for all methods in the vtable we're 1174 /// currently building. 1175 MethodInfoMapTy MethodInfoMap; 1176 1177 typedef llvm::DenseMap<uint64_t, ThunkInfo> VtableThunksMapTy; 1178 1179 /// VTableThunks - The thunks by vtable index in the vtable currently being 1180 /// built. 1181 VtableThunksMapTy VTableThunks; 1182 1183 typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 1184 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 1185 1186 /// Thunks - A map that contains all the thunks needed for all methods in the 1187 /// most derived class for which the vtable is currently being built. 1188 ThunksMapTy Thunks; 1189 1190 /// AddThunk - Add a thunk for the given method. 1191 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk); 1192 1193 /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the 1194 /// part of the vtable we're currently building. 1195 void ComputeThisAdjustments(); 1196 1197 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 1198 1199 /// PrimaryVirtualBases - All known virtual bases who are a primary base of 1200 /// some other base. 1201 VisitedVirtualBasesSetTy PrimaryVirtualBases; 1202 1203 /// ComputeReturnAdjustment - Compute the return adjustment given a return 1204 /// adjustment base offset. 1205 ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset); 1206 1207 /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting 1208 /// the 'this' pointer from the base subobject to the derived subobject. 1209 BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 1210 BaseSubobject Derived) const; 1211 1212 /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the 1213 /// given virtual member function, its offset in the layout class and its 1214 /// final overrider. 1215 ThisAdjustment 1216 ComputeThisAdjustment(const CXXMethodDecl *MD, 1217 uint64_t BaseOffsetInLayoutClass, 1218 FinalOverriders::OverriderInfo Overrider); 1219 1220 /// AddMethod - Add a single virtual member function to the vtable 1221 /// components vector. 1222 void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment); 1223 1224 /// IsOverriderUsed - Returns whether the overrider will ever be used in this 1225 /// part of the vtable. 1226 /// 1227 /// Itanium C++ ABI 2.5.2: 1228 /// 1229 /// struct A { virtual void f(); }; 1230 /// struct B : virtual public A { int i; }; 1231 /// struct C : virtual public A { int j; }; 1232 /// struct D : public B, public C {}; 1233 /// 1234 /// When B and C are declared, A is a primary base in each case, so although 1235 /// vcall offsets are allocated in the A-in-B and A-in-C vtables, no this 1236 /// adjustment is required and no thunk is generated. However, inside D 1237 /// objects, A is no longer a primary base of C, so if we allowed calls to 1238 /// C::f() to use the copy of A's vtable in the C subobject, we would need 1239 /// to adjust this from C* to B::A*, which would require a third-party 1240 /// thunk. Since we require that a call to C::f() first convert to A*, 1241 /// C-in-D's copy of A's vtable is never referenced, so this is not 1242 /// necessary. 1243 bool IsOverriderUsed(const CXXMethodDecl *Overrider, 1244 uint64_t BaseOffsetInLayoutClass, 1245 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1246 uint64_t FirstBaseOffsetInLayoutClass) const; 1247 1248 1249 /// AddMethods - Add the methods of this base subobject and all its 1250 /// primary bases to the vtable components vector. 1251 void AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, 1252 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1253 uint64_t FirstBaseOffsetInLayoutClass, 1254 PrimaryBasesSetVectorTy &PrimaryBases); 1255 1256 // LayoutVtable - Layout the vtable for the given base class, including its 1257 // secondary vtables and any vtables for virtual bases. 1258 void LayoutVtable(); 1259 1260 /// LayoutPrimaryAndSecondaryVtables - Layout the primary vtable for the 1261 /// given base subobject, as well as all its secondary vtables. 1262 void LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, 1263 bool BaseIsVirtual, 1264 uint64_t OffsetInLayoutClass); 1265 1266 /// LayoutSecondaryVtables - Layout the secondary vtables for the given base 1267 /// subobject. 1268 /// 1269 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 1270 /// or a direct or indirect base of a virtual base. 1271 void LayoutSecondaryVtables(BaseSubobject Base, bool BaseIsMorallyVirtual, 1272 uint64_t OffsetInLayoutClass); 1273 1274 /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this 1275 /// class hierarchy. 1276 void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 1277 uint64_t OffsetInLayoutClass, 1278 VisitedVirtualBasesSetTy &VBases); 1279 1280 /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the 1281 /// given base (excluding any primary bases). 1282 void LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, 1283 VisitedVirtualBasesSetTy &VBases); 1284 1285 /// isBuildingConstructionVtable - Return whether this vtable builder is 1286 /// building a construction vtable. 1287 bool isBuildingConstructorVtable() const { 1288 return MostDerivedClass != LayoutClass; 1289 } 1290 1291public: 1292 VTableBuilder(CodeGenVTables &VTables, const CXXRecordDecl *MostDerivedClass, 1293 uint64_t MostDerivedClassOffset, bool MostDerivedClassIsVirtual, 1294 const CXXRecordDecl *LayoutClass) 1295 : VTables(VTables), MostDerivedClass(MostDerivedClass), 1296 MostDerivedClassOffset(MostDerivedClassOffset), 1297 MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 1298 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 1299 Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) { 1300 1301 LayoutVtable(); 1302 } 1303 1304 ThunksMapTy::const_iterator thunks_begin() const { 1305 return Thunks.begin(); 1306 } 1307 1308 ThunksMapTy::const_iterator thunks_end() const { 1309 return Thunks.end(); 1310 } 1311 1312 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 1313 return VBaseOffsetOffsets; 1314 } 1315 1316 /// getNumVTableComponents - Return the number of components in the vtable 1317 /// currently built. 1318 uint64_t getNumVTableComponents() const { 1319 return Components.size(); 1320 } 1321 1322 const uint64_t *vtable_components_data_begin() const { 1323 return reinterpret_cast<const uint64_t *>(Components.begin()); 1324 } 1325 1326 const uint64_t *vtable_components_data_end() const { 1327 return reinterpret_cast<const uint64_t *>(Components.end()); 1328 } 1329 1330 AddressPointsMapTy::const_iterator address_points_begin() const { 1331 return AddressPoints.begin(); 1332 } 1333 1334 AddressPointsMapTy::const_iterator address_points_end() const { 1335 return AddressPoints.end(); 1336 } 1337 1338 VtableThunksMapTy::const_iterator vtable_thunks_begin() const { 1339 return VTableThunks.begin(); 1340 } 1341 1342 VtableThunksMapTy::const_iterator vtable_thunks_end() const { 1343 return VTableThunks.end(); 1344 } 1345 1346 /// dumpLayout - Dump the vtable layout. 1347 void dumpLayout(llvm::raw_ostream&); 1348}; 1349 1350void VTableBuilder::AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) { 1351 assert(!isBuildingConstructorVtable() && 1352 "Can't add thunks for construction vtable"); 1353 1354 llvm::SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD]; 1355 1356 // Check if we have this thunk already. 1357 if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 1358 ThunksVector.end()) 1359 return; 1360 1361 ThunksVector.push_back(Thunk); 1362} 1363 1364typedef llvm::SmallPtrSet<const CXXMethodDecl *, 8> OverriddenMethodsSetTy; 1365 1366/// ComputeAllOverriddenMethods - Given a method decl, will return a set of all 1367/// the overridden methods that the function decl overrides. 1368static void 1369ComputeAllOverriddenMethods(const CXXMethodDecl *MD, 1370 OverriddenMethodsSetTy& OverriddenMethods) { 1371 assert(MD->isVirtual() && "Method is not virtual!"); 1372 1373 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1374 E = MD->end_overridden_methods(); I != E; ++I) { 1375 const CXXMethodDecl *OverriddenMD = *I; 1376 1377 OverriddenMethods.insert(OverriddenMD); 1378 1379 ComputeAllOverriddenMethods(OverriddenMD, OverriddenMethods); 1380 } 1381} 1382 1383void VTableBuilder::ComputeThisAdjustments() { 1384 // Now go through the method info map and see if any of the methods need 1385 // 'this' pointer adjustments. 1386 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 1387 E = MethodInfoMap.end(); I != E; ++I) { 1388 const CXXMethodDecl *MD = I->first; 1389 const MethodInfo &MethodInfo = I->second; 1390 1391 // Ignore adjustments for unused function pointers. 1392 uint64_t VtableIndex = MethodInfo.VtableIndex; 1393 if (Components[VtableIndex].getKind() == 1394 VTableComponent::CK_UnusedFunctionPointer) 1395 continue; 1396 1397 // Get the final overrider for this method. 1398 FinalOverriders::OverriderInfo Overrider = 1399 Overriders.getOverrider(BaseSubobject(MD->getParent(), 1400 MethodInfo.BaseOffset), MD); 1401 1402 // Check if we need an adjustment at all. 1403 if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) { 1404 // When a return thunk is needed by a derived class that overrides a 1405 // virtual base, gcc uses a virtual 'this' adjustment as well. 1406 // While the thunk itself might be needed by vtables in subclasses or 1407 // in construction vtables, there doesn't seem to be a reason for using 1408 // the thunk in this vtable. Still, we do so to match gcc. 1409 if (VTableThunks.lookup(VtableIndex).Return.isEmpty()) 1410 continue; 1411 } 1412 1413 ThisAdjustment ThisAdjustment = 1414 ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider); 1415 1416 if (ThisAdjustment.isEmpty()) 1417 continue; 1418 1419 // Add it. 1420 VTableThunks[VtableIndex].This = ThisAdjustment; 1421 1422 if (isa<CXXDestructorDecl>(MD)) { 1423 // Add an adjustment for the deleting destructor as well. 1424 VTableThunks[VtableIndex + 1].This = ThisAdjustment; 1425 } 1426 } 1427 1428 /// Clear the method info map. 1429 MethodInfoMap.clear(); 1430 1431 if (isBuildingConstructorVtable()) { 1432 // We don't need to store thunk information for construction vtables. 1433 return; 1434 } 1435 1436 for (VtableThunksMapTy::const_iterator I = VTableThunks.begin(), 1437 E = VTableThunks.end(); I != E; ++I) { 1438 const VTableComponent &Component = Components[I->first]; 1439 const ThunkInfo &Thunk = I->second; 1440 const CXXMethodDecl *MD; 1441 1442 switch (Component.getKind()) { 1443 default: 1444 llvm_unreachable("Unexpected vtable component kind!"); 1445 case VTableComponent::CK_FunctionPointer: 1446 MD = Component.getFunctionDecl(); 1447 break; 1448 case VTableComponent::CK_CompleteDtorPointer: 1449 MD = Component.getDestructorDecl(); 1450 break; 1451 case VTableComponent::CK_DeletingDtorPointer: 1452 // We've already added the thunk when we saw the complete dtor pointer. 1453 continue; 1454 } 1455 1456 if (MD->getParent() == MostDerivedClass) 1457 AddThunk(MD, Thunk); 1458 } 1459} 1460 1461ReturnAdjustment VTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { 1462 ReturnAdjustment Adjustment; 1463 1464 if (!Offset.isEmpty()) { 1465 if (Offset.VirtualBase) { 1466 // Get the virtual base offset offset. 1467 if (Offset.DerivedClass == MostDerivedClass) { 1468 // We can get the offset offset directly from our map. 1469 Adjustment.VBaseOffsetOffset = 1470 VBaseOffsetOffsets.lookup(Offset.VirtualBase); 1471 } else { 1472 Adjustment.VBaseOffsetOffset = 1473 VTables.getVirtualBaseOffsetOffset(Offset.DerivedClass, 1474 Offset.VirtualBase); 1475 } 1476 1477 // FIXME: Once the assert in getVirtualBaseOffsetOffset is back again, 1478 // we can get rid of this assert. 1479 assert(Adjustment.VBaseOffsetOffset != 0 && 1480 "Invalid vbase offset offset!"); 1481 } 1482 1483 Adjustment.NonVirtual = Offset.NonVirtualOffset; 1484 } 1485 1486 return Adjustment; 1487} 1488 1489BaseOffset 1490VTableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 1491 BaseSubobject Derived) const { 1492 const CXXRecordDecl *BaseRD = Base.getBase(); 1493 const CXXRecordDecl *DerivedRD = Derived.getBase(); 1494 1495 CXXBasePaths Paths(/*FindAmbiguities=*/true, 1496 /*RecordPaths=*/true, /*DetectVirtual=*/true); 1497 1498 if (!const_cast<CXXRecordDecl *>(DerivedRD)-> 1499 isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { 1500 assert(false && "Class must be derived from the passed in base class!"); 1501 return BaseOffset(); 1502 } 1503 1504 // We have to go through all the paths, and see which one leads us to the 1505 // right base subobject. 1506 for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end(); 1507 I != E; ++I) { 1508 BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I); 1509 1510 // FIXME: Should not use * 8 here. 1511 uint64_t OffsetToBaseSubobject = Offset.NonVirtualOffset * 8; 1512 1513 if (Offset.VirtualBase) { 1514 // If we have a virtual base class, the non-virtual offset is relative 1515 // to the virtual base class offset. 1516 const ASTRecordLayout &LayoutClassLayout = 1517 Context.getASTRecordLayout(LayoutClass); 1518 1519 /// Get the virtual base offset, relative to the most derived class 1520 /// layout. 1521 OffsetToBaseSubobject += 1522 LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase); 1523 } else { 1524 // Otherwise, the non-virtual offset is relative to the derived class 1525 // offset. 1526 OffsetToBaseSubobject += Derived.getBaseOffset(); 1527 } 1528 1529 // Check if this path gives us the right base subobject. 1530 if (OffsetToBaseSubobject == Base.getBaseOffset()) { 1531 // Since we're going from the base class _to_ the derived class, we'll 1532 // invert the non-virtual offset here. 1533 Offset.NonVirtualOffset = -Offset.NonVirtualOffset; 1534 return Offset; 1535 } 1536 } 1537 1538 return BaseOffset(); 1539} 1540 1541ThisAdjustment 1542VTableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, 1543 uint64_t BaseOffsetInLayoutClass, 1544 FinalOverriders::OverriderInfo Overrider) { 1545 // Ignore adjustments for pure virtual member functions. 1546 if (Overrider.Method->isPure()) 1547 return ThisAdjustment(); 1548 1549 BaseSubobject OverriddenBaseSubobject(MD->getParent(), 1550 BaseOffsetInLayoutClass); 1551 1552 BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), 1553 Overrider.Offset); 1554 1555 // Compute the adjustment offset. 1556 BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject, 1557 OverriderBaseSubobject); 1558 if (Offset.isEmpty()) 1559 return ThisAdjustment(); 1560 1561 ThisAdjustment Adjustment; 1562 1563 if (Offset.VirtualBase) { 1564 // Get the vcall offset map for this virtual base. 1565 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; 1566 1567 if (VCallOffsets.empty()) { 1568 // We don't have vcall offsets for this virtual base, go ahead and 1569 // build them. 1570 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass, 1571 /*FinalOverriders=*/0, 1572 BaseSubobject(Offset.VirtualBase, 0), 1573 /*BaseIsVirtual=*/true, 1574 /*OffsetInLayoutClass=*/0); 1575 1576 VCallOffsets = Builder.getVCallOffsets(); 1577 } 1578 1579 Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD); 1580 } 1581 1582 // Set the non-virtual part of the adjustment. 1583 Adjustment.NonVirtual = Offset.NonVirtualOffset; 1584 1585 return Adjustment; 1586} 1587 1588void 1589VTableBuilder::AddMethod(const CXXMethodDecl *MD, 1590 ReturnAdjustment ReturnAdjustment) { 1591 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1592 assert(ReturnAdjustment.isEmpty() && 1593 "Destructor can't have return adjustment!"); 1594 1595 // Add both the complete destructor and the deleting destructor. 1596 Components.push_back(VTableComponent::MakeCompleteDtor(DD)); 1597 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 1598 } else { 1599 // Add the return adjustment if necessary. 1600 if (!ReturnAdjustment.isEmpty()) 1601 VTableThunks[Components.size()].Return = ReturnAdjustment; 1602 1603 // Add the function. 1604 Components.push_back(VTableComponent::MakeFunction(MD)); 1605 } 1606} 1607 1608/// OverridesIndirectMethodInBase - Return whether the given member function 1609/// overrides any methods in the set of given bases. 1610/// Unlike OverridesMethodInBase, this checks "overriders of overriders". 1611/// For example, if we have: 1612/// 1613/// struct A { virtual void f(); } 1614/// struct B : A { virtual void f(); } 1615/// struct C : B { virtual void f(); } 1616/// 1617/// OverridesIndirectMethodInBase will return true if given C::f as the method 1618/// and { A } as the set of bases. 1619static bool 1620OverridesIndirectMethodInBases(const CXXMethodDecl *MD, 1621 VTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1622 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1623 E = MD->end_overridden_methods(); I != E; ++I) { 1624 const CXXMethodDecl *OverriddenMD = *I; 1625 const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent(); 1626 assert(OverriddenMD->isCanonicalDecl() && 1627 "Should have the canonical decl of the overridden RD!"); 1628 1629 if (Bases.count(OverriddenRD)) 1630 return true; 1631 1632 // Check "indirect overriders". 1633 if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) 1634 return true; 1635 } 1636 1637 return false; 1638} 1639 1640bool 1641VTableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider, 1642 uint64_t BaseOffsetInLayoutClass, 1643 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1644 uint64_t FirstBaseOffsetInLayoutClass) const { 1645 // If the base and the first base in the primary base chain have the same 1646 // offsets, then this overrider will be used. 1647 if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass) 1648 return true; 1649 1650 // We know now that Base (or a direct or indirect base of it) is a primary 1651 // base in part of the class hierarchy, but not a primary base in the most 1652 // derived class. 1653 1654 // If the overrider is the first base in the primary base chain, we know 1655 // that the overrider will be used. 1656 if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) 1657 return true; 1658 1659 VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 1660 1661 const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain; 1662 PrimaryBases.insert(RD); 1663 1664 // Now traverse the base chain, starting with the first base, until we find 1665 // the base that is no longer a primary base. 1666 while (true) { 1667 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1668 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1669 1670 if (!PrimaryBase) 1671 break; 1672 1673 if (Layout.getPrimaryBaseWasVirtual()) { 1674 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 1675 "Primary base should always be at offset 0!"); 1676 1677 const ASTRecordLayout &LayoutClassLayout = 1678 Context.getASTRecordLayout(LayoutClass); 1679 1680 // Now check if this is the primary base that is not a primary base in the 1681 // most derived class. 1682 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 1683 FirstBaseOffsetInLayoutClass) { 1684 // We found it, stop walking the chain. 1685 break; 1686 } 1687 } else { 1688 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 1689 "Primary base should always be at offset 0!"); 1690 } 1691 1692 if (!PrimaryBases.insert(PrimaryBase)) 1693 assert(false && "Found a duplicate primary base!"); 1694 1695 RD = PrimaryBase; 1696 } 1697 1698 // If the final overrider is an override of one of the primary bases, 1699 // then we know that it will be used. 1700 return OverridesIndirectMethodInBases(Overrider, PrimaryBases); 1701} 1702 1703/// FindNearestOverriddenMethod - Given a method, returns the overridden method 1704/// from the nearest base. Returns null if no method was found. 1705static const CXXMethodDecl * 1706FindNearestOverriddenMethod(const CXXMethodDecl *MD, 1707 VTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1708 OverriddenMethodsSetTy OverriddenMethods; 1709 ComputeAllOverriddenMethods(MD, OverriddenMethods); 1710 1711 for (int I = Bases.size(), E = 0; I != E; --I) { 1712 const CXXRecordDecl *PrimaryBase = Bases[I - 1]; 1713 1714 // Now check the overriden methods. 1715 for (OverriddenMethodsSetTy::const_iterator I = OverriddenMethods.begin(), 1716 E = OverriddenMethods.end(); I != E; ++I) { 1717 const CXXMethodDecl *OverriddenMD = *I; 1718 1719 // We found our overridden method. 1720 if (OverriddenMD->getParent() == PrimaryBase) 1721 return OverriddenMD; 1722 } 1723 } 1724 1725 return 0; 1726} 1727 1728void 1729VTableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, 1730 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1731 uint64_t FirstBaseOffsetInLayoutClass, 1732 PrimaryBasesSetVectorTy &PrimaryBases) { 1733 const CXXRecordDecl *RD = Base.getBase(); 1734 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1735 1736 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1737 uint64_t PrimaryBaseOffset; 1738 uint64_t PrimaryBaseOffsetInLayoutClass; 1739 if (Layout.getPrimaryBaseWasVirtual()) { 1740 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 1741 "Primary vbase should have a zero offset!"); 1742 1743 const ASTRecordLayout &MostDerivedClassLayout = 1744 Context.getASTRecordLayout(MostDerivedClass); 1745 1746 PrimaryBaseOffset = 1747 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 1748 1749 const ASTRecordLayout &LayoutClassLayout = 1750 Context.getASTRecordLayout(LayoutClass); 1751 1752 PrimaryBaseOffsetInLayoutClass = 1753 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 1754 } else { 1755 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 1756 "Primary base should have a zero offset!"); 1757 1758 PrimaryBaseOffset = Base.getBaseOffset(); 1759 PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass; 1760 } 1761 1762 AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 1763 PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, 1764 FirstBaseOffsetInLayoutClass, PrimaryBases); 1765 1766 if (!PrimaryBases.insert(PrimaryBase)) 1767 assert(false && "Found a duplicate primary base!"); 1768 } 1769 1770 // Now go through all virtual member functions and add them. 1771 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1772 E = RD->method_end(); I != E; ++I) { 1773 const CXXMethodDecl *MD = *I; 1774 1775 if (!MD->isVirtual()) 1776 continue; 1777 1778 // Get the final overrider. 1779 FinalOverriders::OverriderInfo Overrider = 1780 Overriders.getOverrider(Base, MD); 1781 1782 // Check if this virtual member function overrides a method in a primary 1783 // base. If this is the case, and the return type doesn't require adjustment 1784 // then we can just use the member function from the primary base. 1785 if (const CXXMethodDecl *OverriddenMD = 1786 FindNearestOverriddenMethod(MD, PrimaryBases)) { 1787 if (ComputeReturnAdjustmentBaseOffset(Context, MD, 1788 OverriddenMD).isEmpty()) { 1789 // Replace the method info of the overridden method with our own 1790 // method. 1791 assert(MethodInfoMap.count(OverriddenMD) && 1792 "Did not find the overridden method!"); 1793 MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD]; 1794 1795 MethodInfo MethodInfo(Base.getBaseOffset(), 1796 BaseOffsetInLayoutClass, 1797 OverriddenMethodInfo.VtableIndex); 1798 1799 assert(!MethodInfoMap.count(MD) && 1800 "Should not have method info for this method yet!"); 1801 1802 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1803 MethodInfoMap.erase(OverriddenMD); 1804 1805 // If the overridden method exists in a virtual base class or a direct 1806 // or indirect base class of a virtual base class, we need to emit a 1807 // thunk if we ever have a class hierarchy where the base class is not 1808 // a primary base in the complete object. 1809 if (!isBuildingConstructorVtable() && OverriddenMD != MD) { 1810 // Compute the this adjustment. 1811 ThisAdjustment ThisAdjustment = 1812 ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass, 1813 Overrider); 1814 1815 if (ThisAdjustment.VCallOffsetOffset && 1816 Overrider.Method->getParent() == MostDerivedClass) { 1817 // This is a virtual thunk for the most derived class, add it. 1818 AddThunk(Overrider.Method, 1819 ThunkInfo(ThisAdjustment, ReturnAdjustment())); 1820 } 1821 } 1822 1823 continue; 1824 } 1825 } 1826 1827 // Insert the method info for this method. 1828 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 1829 Components.size()); 1830 1831 assert(!MethodInfoMap.count(MD) && 1832 "Should not have method info for this method yet!"); 1833 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1834 1835 // Check if this overrider is going to be used. 1836 const CXXMethodDecl *OverriderMD = Overrider.Method; 1837 if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, 1838 FirstBaseInPrimaryBaseChain, 1839 FirstBaseOffsetInLayoutClass)) { 1840 Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD)); 1841 continue; 1842 } 1843 1844 // Check if this overrider needs a return adjustment. 1845 BaseOffset ReturnAdjustmentOffset = 1846 Overriders.getReturnAdjustmentOffset(Base, MD); 1847 1848 ReturnAdjustment ReturnAdjustment = 1849 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1850 1851 AddMethod(Overrider.Method, ReturnAdjustment); 1852 } 1853} 1854 1855void VTableBuilder::LayoutVtable() { 1856 LayoutPrimaryAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0), 1857 MostDerivedClassIsVirtual, 1858 MostDerivedClassOffset); 1859 1860 VisitedVirtualBasesSetTy VBases; 1861 1862 // Determine the primary virtual bases. 1863 DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, 1864 VBases); 1865 VBases.clear(); 1866 1867 LayoutVtablesForVirtualBases(MostDerivedClass, VBases); 1868} 1869 1870void 1871VTableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, 1872 bool BaseIsVirtual, 1873 uint64_t OffsetInLayoutClass) { 1874 assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!"); 1875 1876 // Add vcall and vbase offsets for this vtable. 1877 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, 1878 Base, BaseIsVirtual, OffsetInLayoutClass); 1879 Components.append(Builder.components_begin(), Builder.components_end()); 1880 1881 // Check if we need to add these vcall offsets. 1882 if (BaseIsVirtual && !Builder.getVCallOffsets().empty()) { 1883 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; 1884 1885 if (VCallOffsets.empty()) 1886 VCallOffsets = Builder.getVCallOffsets(); 1887 } 1888 1889 // If we're laying out the most derived class we want to keep track of the 1890 // virtual base class offset offsets. 1891 if (Base.getBase() == MostDerivedClass) 1892 VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); 1893 1894 // Add the offset to top. 1895 // FIXME: We should not use / 8 here. 1896 int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass - 1897 MostDerivedClassOffset) / 8; 1898 Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop)); 1899 1900 // Next, add the RTTI. 1901 Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); 1902 1903 uint64_t AddressPoint = Components.size(); 1904 1905 // Now go through all virtual member functions and add them. 1906 PrimaryBasesSetVectorTy PrimaryBases; 1907 AddMethods(Base, OffsetInLayoutClass, Base.getBase(), OffsetInLayoutClass, 1908 PrimaryBases); 1909 1910 // Compute 'this' pointer adjustments. 1911 ComputeThisAdjustments(); 1912 1913 // Add all address points. 1914 const CXXRecordDecl *RD = Base.getBase(); 1915 while (true) { 1916 AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass), 1917 AddressPoint)); 1918 1919 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1920 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1921 1922 if (!PrimaryBase) 1923 break; 1924 1925 if (Layout.getPrimaryBaseWasVirtual()) { 1926 // Check if this virtual primary base is a primary base in the layout 1927 // class. If it's not, we don't want to add it. 1928 const ASTRecordLayout &LayoutClassLayout = 1929 Context.getASTRecordLayout(LayoutClass); 1930 1931 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 1932 OffsetInLayoutClass) { 1933 // We don't want to add this class (or any of its primary bases). 1934 break; 1935 } 1936 } 1937 1938 RD = PrimaryBase; 1939 } 1940 1941 bool BaseIsMorallyVirtual = BaseIsVirtual; 1942 if (isBuildingConstructorVtable() && Base.getBase() == MostDerivedClass) 1943 BaseIsMorallyVirtual = false; 1944 1945 // Layout secondary vtables. 1946 LayoutSecondaryVtables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass); 1947} 1948 1949void VTableBuilder::LayoutSecondaryVtables(BaseSubobject Base, 1950 bool BaseIsMorallyVirtual, 1951 uint64_t OffsetInLayoutClass) { 1952 // Itanium C++ ABI 2.5.2: 1953 // Following the primary virtual table of a derived class are secondary 1954 // virtual tables for each of its proper base classes, except any primary 1955 // base(s) with which it shares its primary virtual table. 1956 1957 const CXXRecordDecl *RD = Base.getBase(); 1958 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1959 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1960 1961 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1962 E = RD->bases_end(); I != E; ++I) { 1963 // Ignore virtual bases, we'll emit them later. 1964 if (I->isVirtual()) 1965 continue; 1966 1967 const CXXRecordDecl *BaseDecl = 1968 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1969 1970 // Ignore bases that don't have a vtable. 1971 if (!BaseDecl->isDynamicClass()) 1972 continue; 1973 1974 if (isBuildingConstructorVtable()) { 1975 // Itanium C++ ABI 2.6.4: 1976 // Some of the base class subobjects may not need construction virtual 1977 // tables, which will therefore not be present in the construction 1978 // virtual table group, even though the subobject virtual tables are 1979 // present in the main virtual table group for the complete object. 1980 if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases()) 1981 continue; 1982 } 1983 1984 // Get the base offset of this base. 1985 uint64_t RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl); 1986 uint64_t BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; 1987 1988 uint64_t BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset; 1989 1990 // Don't emit a secondary vtable for a primary base. We might however want 1991 // to emit secondary vtables for other bases of this base. 1992 if (BaseDecl == PrimaryBase) { 1993 LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), 1994 BaseIsMorallyVirtual, BaseOffsetInLayoutClass); 1995 continue; 1996 } 1997 1998 // Layout the primary vtable (and any secondary vtables) for this base. 1999 LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), 2000 /*BaseIsVirtual=*/false, 2001 BaseOffsetInLayoutClass); 2002 } 2003} 2004 2005void 2006VTableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 2007 uint64_t OffsetInLayoutClass, 2008 VisitedVirtualBasesSetTy &VBases) { 2009 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 2010 2011 // Check if this base has a primary base. 2012 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 2013 2014 // Check if it's virtual. 2015 if (Layout.getPrimaryBaseWasVirtual()) { 2016 bool IsPrimaryVirtualBase = true; 2017 2018 if (isBuildingConstructorVtable()) { 2019 // Check if the base is actually a primary base in the class we use for 2020 // layout. 2021 const ASTRecordLayout &LayoutClassLayout = 2022 Context.getASTRecordLayout(LayoutClass); 2023 2024 uint64_t PrimaryBaseOffsetInLayoutClass = 2025 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 2026 2027 // We know that the base is not a primary base in the layout class if 2028 // the base offsets are different. 2029 if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) 2030 IsPrimaryVirtualBase = false; 2031 } 2032 2033 if (IsPrimaryVirtualBase) 2034 PrimaryVirtualBases.insert(PrimaryBase); 2035 } 2036 } 2037 2038 // Traverse bases, looking for more primary virtual bases. 2039 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 2040 E = RD->bases_end(); I != E; ++I) { 2041 const CXXRecordDecl *BaseDecl = 2042 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 2043 2044 uint64_t BaseOffsetInLayoutClass; 2045 2046 if (I->isVirtual()) { 2047 if (!VBases.insert(BaseDecl)) 2048 continue; 2049 2050 const ASTRecordLayout &LayoutClassLayout = 2051 Context.getASTRecordLayout(LayoutClass); 2052 2053 BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); 2054 } else { 2055 BaseOffsetInLayoutClass = 2056 OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); 2057 } 2058 2059 DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); 2060 } 2061} 2062 2063void 2064VTableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, 2065 VisitedVirtualBasesSetTy &VBases) { 2066 // Itanium C++ ABI 2.5.2: 2067 // Then come the virtual base virtual tables, also in inheritance graph 2068 // order, and again excluding primary bases (which share virtual tables with 2069 // the classes for which they are primary). 2070 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 2071 E = RD->bases_end(); I != E; ++I) { 2072 const CXXRecordDecl *BaseDecl = 2073 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 2074 2075 // Check if this base needs a vtable. (If it's virtual, not a primary base 2076 // of some other class, and we haven't visited it before). 2077 if (I->isVirtual() && BaseDecl->isDynamicClass() && 2078 !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) { 2079 const ASTRecordLayout &MostDerivedClassLayout = 2080 Context.getASTRecordLayout(MostDerivedClass); 2081 uint64_t BaseOffset = 2082 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 2083 2084 const ASTRecordLayout &LayoutClassLayout = 2085 Context.getASTRecordLayout(LayoutClass); 2086 uint64_t BaseOffsetInLayoutClass = 2087 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 2088 2089 LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), 2090 /*BaseIsVirtual=*/true, 2091 BaseOffsetInLayoutClass); 2092 } 2093 2094 // We only need to check the base for virtual base vtables if it actually 2095 // has virtual bases. 2096 if (BaseDecl->getNumVBases()) 2097 LayoutVtablesForVirtualBases(BaseDecl, VBases); 2098 } 2099} 2100 2101/// dumpLayout - Dump the vtable layout. 2102void VTableBuilder::dumpLayout(llvm::raw_ostream& Out) { 2103 2104 if (isBuildingConstructorVtable()) { 2105 Out << "Construction vtable for ('"; 2106 Out << MostDerivedClass->getQualifiedNameAsString() << "', "; 2107 // FIXME: Don't use / 8 . 2108 Out << MostDerivedClassOffset / 8 << ") in '"; 2109 Out << LayoutClass->getQualifiedNameAsString(); 2110 } else { 2111 Out << "Vtable for '"; 2112 Out << MostDerivedClass->getQualifiedNameAsString(); 2113 } 2114 Out << "' (" << Components.size() << " entries).\n"; 2115 2116 // Iterate through the address points and insert them into a new map where 2117 // they are keyed by the index and not the base object. 2118 // Since an address point can be shared by multiple subobjects, we use an 2119 // STL multimap. 2120 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex; 2121 for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(), 2122 E = AddressPoints.end(); I != E; ++I) { 2123 const BaseSubobject& Base = I->first; 2124 uint64_t Index = I->second; 2125 2126 AddressPointsByIndex.insert(std::make_pair(Index, Base)); 2127 } 2128 2129 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 2130 uint64_t Index = I; 2131 2132 Out << llvm::format("%4d | ", I); 2133 2134 const VTableComponent &Component = Components[I]; 2135 2136 // Dump the component. 2137 switch (Component.getKind()) { 2138 2139 case VTableComponent::CK_VCallOffset: 2140 Out << "vcall_offset (" << Component.getVCallOffset() << ")"; 2141 break; 2142 2143 case VTableComponent::CK_VBaseOffset: 2144 Out << "vbase_offset (" << Component.getVBaseOffset() << ")"; 2145 break; 2146 2147 case VTableComponent::CK_OffsetToTop: 2148 Out << "offset_to_top (" << Component.getOffsetToTop() << ")"; 2149 break; 2150 2151 case VTableComponent::CK_RTTI: 2152 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; 2153 break; 2154 2155 case VTableComponent::CK_FunctionPointer: { 2156 const CXXMethodDecl *MD = Component.getFunctionDecl(); 2157 2158 std::string Str = 2159 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2160 MD); 2161 Out << Str; 2162 if (MD->isPure()) 2163 Out << " [pure]"; 2164 2165 ThunkInfo Thunk = VTableThunks.lookup(I); 2166 if (!Thunk.isEmpty()) { 2167 // If this function pointer has a return adjustment, dump it. 2168 if (!Thunk.Return.isEmpty()) { 2169 Out << "\n [return adjustment: "; 2170 Out << Thunk.Return.NonVirtual << " non-virtual"; 2171 2172 if (Thunk.Return.VBaseOffsetOffset) { 2173 Out << ", " << Thunk.Return.VBaseOffsetOffset; 2174 Out << " vbase offset offset"; 2175 } 2176 2177 Out << ']'; 2178 } 2179 2180 // If this function pointer has a 'this' pointer adjustment, dump it. 2181 if (!Thunk.This.isEmpty()) { 2182 Out << "\n [this adjustment: "; 2183 Out << Thunk.This.NonVirtual << " non-virtual"; 2184 2185 if (Thunk.This.VCallOffsetOffset) { 2186 Out << ", " << Thunk.This.VCallOffsetOffset; 2187 Out << " vcall offset offset"; 2188 } 2189 2190 Out << ']'; 2191 } 2192 } 2193 2194 break; 2195 } 2196 2197 case VTableComponent::CK_CompleteDtorPointer: 2198 case VTableComponent::CK_DeletingDtorPointer: { 2199 bool IsComplete = 2200 Component.getKind() == VTableComponent::CK_CompleteDtorPointer; 2201 2202 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 2203 2204 Out << DD->getQualifiedNameAsString(); 2205 if (IsComplete) 2206 Out << "() [complete]"; 2207 else 2208 Out << "() [deleting]"; 2209 2210 if (DD->isPure()) 2211 Out << " [pure]"; 2212 2213 ThunkInfo Thunk = VTableThunks.lookup(I); 2214 if (!Thunk.isEmpty()) { 2215 // If this destructor has a 'this' pointer adjustment, dump it. 2216 if (!Thunk.This.isEmpty()) { 2217 Out << "\n [this adjustment: "; 2218 Out << Thunk.This.NonVirtual << " non-virtual"; 2219 2220 if (Thunk.This.VCallOffsetOffset) { 2221 Out << ", " << Thunk.This.VCallOffsetOffset; 2222 Out << " vcall offset offset"; 2223 } 2224 2225 Out << ']'; 2226 } 2227 } 2228 2229 break; 2230 } 2231 2232 case VTableComponent::CK_UnusedFunctionPointer: { 2233 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); 2234 2235 std::string Str = 2236 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2237 MD); 2238 Out << "[unused] " << Str; 2239 if (MD->isPure()) 2240 Out << " [pure]"; 2241 } 2242 2243 } 2244 2245 Out << '\n'; 2246 2247 // Dump the next address point. 2248 uint64_t NextIndex = Index + 1; 2249 if (AddressPointsByIndex.count(NextIndex)) { 2250 if (AddressPointsByIndex.count(NextIndex) == 1) { 2251 const BaseSubobject &Base = 2252 AddressPointsByIndex.find(NextIndex)->second; 2253 2254 // FIXME: Instead of dividing by 8, we should be using CharUnits. 2255 Out << " -- (" << Base.getBase()->getQualifiedNameAsString(); 2256 Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n"; 2257 } else { 2258 uint64_t BaseOffset = 2259 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); 2260 2261 // We store the class names in a set to get a stable order. 2262 std::set<std::string> ClassNames; 2263 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I = 2264 AddressPointsByIndex.lower_bound(NextIndex), E = 2265 AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) { 2266 assert(I->second.getBaseOffset() == BaseOffset && 2267 "Invalid base offset!"); 2268 const CXXRecordDecl *RD = I->second.getBase(); 2269 ClassNames.insert(RD->getQualifiedNameAsString()); 2270 } 2271 2272 for (std::set<std::string>::const_iterator I = ClassNames.begin(), 2273 E = ClassNames.end(); I != E; ++I) { 2274 // FIXME: Instead of dividing by 8, we should be using CharUnits. 2275 Out << " -- (" << *I; 2276 Out << ", " << BaseOffset / 8 << ") vtable address --\n"; 2277 } 2278 } 2279 } 2280 } 2281 2282 Out << '\n'; 2283 2284 if (isBuildingConstructorVtable()) 2285 return; 2286 2287 if (MostDerivedClass->getNumVBases()) { 2288 // We store the virtual base class names and their offsets in a map to get 2289 // a stable order. 2290 2291 std::map<std::string, int64_t> ClassNamesAndOffsets; 2292 for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(), 2293 E = VBaseOffsetOffsets.end(); I != E; ++I) { 2294 std::string ClassName = I->first->getQualifiedNameAsString(); 2295 int64_t OffsetOffset = I->second; 2296 ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset)); 2297 } 2298 2299 Out << "Virtual base offset offsets for '"; 2300 Out << MostDerivedClass->getQualifiedNameAsString() << "' ("; 2301 Out << ClassNamesAndOffsets.size(); 2302 Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n"; 2303 2304 for (std::map<std::string, int64_t>::const_iterator I = 2305 ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 2306 I != E; ++I) 2307 Out << " " << I->first << " | " << I->second << '\n'; 2308 2309 Out << "\n"; 2310 } 2311 2312 if (!Thunks.empty()) { 2313 // We store the method names in a map to get a stable order. 2314 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 2315 2316 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 2317 I != E; ++I) { 2318 const CXXMethodDecl *MD = I->first; 2319 std::string MethodName = 2320 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2321 MD); 2322 2323 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 2324 } 2325 2326 for (std::map<std::string, const CXXMethodDecl *>::const_iterator I = 2327 MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end(); 2328 I != E; ++I) { 2329 const std::string &MethodName = I->first; 2330 const CXXMethodDecl *MD = I->second; 2331 2332 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 2333 std::sort(ThunksVector.begin(), ThunksVector.end()); 2334 2335 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 2336 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 2337 2338 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 2339 const ThunkInfo &Thunk = ThunksVector[I]; 2340 2341 Out << llvm::format("%4d | ", I); 2342 2343 // If this function pointer has a return pointer adjustment, dump it. 2344 if (!Thunk.Return.isEmpty()) { 2345 Out << "return adjustment: " << Thunk.This.NonVirtual; 2346 Out << " non-virtual"; 2347 if (Thunk.Return.VBaseOffsetOffset) { 2348 Out << ", " << Thunk.Return.VBaseOffsetOffset; 2349 Out << " vbase offset offset"; 2350 } 2351 2352 if (!Thunk.This.isEmpty()) 2353 Out << "\n "; 2354 } 2355 2356 // If this function pointer has a 'this' pointer adjustment, dump it. 2357 if (!Thunk.This.isEmpty()) { 2358 Out << "this adjustment: "; 2359 Out << Thunk.This.NonVirtual << " non-virtual"; 2360 2361 if (Thunk.This.VCallOffsetOffset) { 2362 Out << ", " << Thunk.This.VCallOffsetOffset; 2363 Out << " vcall offset offset"; 2364 } 2365 } 2366 2367 Out << '\n'; 2368 } 2369 2370 Out << '\n'; 2371 2372 } 2373 } 2374} 2375 2376} 2377 2378void CodeGenVTables::ComputeMethodVtableIndices(const CXXRecordDecl *RD) { 2379 2380 // Itanium C++ ABI 2.5.2: 2381 // The order of the virtual function pointers in a virtual table is the 2382 // order of declaration of the corresponding member functions in the class. 2383 // 2384 // There is an entry for any virtual function declared in a class, 2385 // whether it is a new function or overrides a base class function, 2386 // unless it overrides a function from the primary base, and conversion 2387 // between their return types does not require an adjustment. 2388 2389 int64_t CurrentIndex = 0; 2390 2391 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 2392 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 2393 2394 if (PrimaryBase) { 2395 assert(PrimaryBase->isDefinition() && 2396 "Should have the definition decl of the primary base!"); 2397 2398 // Since the record decl shares its vtable pointer with the primary base 2399 // we need to start counting at the end of the primary base's vtable. 2400 CurrentIndex = getNumVirtualFunctionPointers(PrimaryBase); 2401 } 2402 2403 // Collect all the primary bases, so we can check whether methods override 2404 // a method from the base. 2405 VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 2406 for (ASTRecordLayout::primary_base_info_iterator 2407 I = Layout.primary_base_begin(), E = Layout.primary_base_end(); 2408 I != E; ++I) 2409 PrimaryBases.insert((*I).getBase()); 2410 2411 const CXXDestructorDecl *ImplicitVirtualDtor = 0; 2412 2413 for (CXXRecordDecl::method_iterator i = RD->method_begin(), 2414 e = RD->method_end(); i != e; ++i) { 2415 const CXXMethodDecl *MD = *i; 2416 2417 // We only want virtual methods. 2418 if (!MD->isVirtual()) 2419 continue; 2420 2421 // Check if this method overrides a method in the primary base. 2422 if (const CXXMethodDecl *OverriddenMD = 2423 FindNearestOverriddenMethod(MD, PrimaryBases)) { 2424 // Check if converting from the return type of the method to the 2425 // return type of the overridden method requires conversion. 2426 if (ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD, 2427 OverriddenMD).isEmpty()) { 2428 // This index is shared between the index in the vtable of the primary 2429 // base class. 2430 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2431 const CXXDestructorDecl *OverriddenDD = 2432 cast<CXXDestructorDecl>(OverriddenMD); 2433 2434 // Add both the complete and deleting entries. 2435 MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = 2436 getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Complete)); 2437 MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = 2438 getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting)); 2439 } else { 2440 MethodVtableIndices[MD] = getMethodVtableIndex(OverriddenMD); 2441 } 2442 2443 // We don't need to add an entry for this method. 2444 continue; 2445 } 2446 } 2447 2448 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2449 if (MD->isImplicit()) { 2450 assert(!ImplicitVirtualDtor && 2451 "Did already see an implicit virtual dtor!"); 2452 ImplicitVirtualDtor = DD; 2453 continue; 2454 } 2455 2456 // Add the complete dtor. 2457 MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++; 2458 2459 // Add the deleting dtor. 2460 MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++; 2461 } else { 2462 // Add the entry. 2463 MethodVtableIndices[MD] = CurrentIndex++; 2464 } 2465 } 2466 2467 if (ImplicitVirtualDtor) { 2468 // Itanium C++ ABI 2.5.2: 2469 // If a class has an implicitly-defined virtual destructor, 2470 // its entries come after the declared virtual function pointers. 2471 2472 // Add the complete dtor. 2473 MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = 2474 CurrentIndex++; 2475 2476 // Add the deleting dtor. 2477 MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Deleting)] = 2478 CurrentIndex++; 2479 } 2480 2481 NumVirtualFunctionPointers[RD] = CurrentIndex; 2482} 2483 2484uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) { 2485 llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = 2486 NumVirtualFunctionPointers.find(RD); 2487 if (I != NumVirtualFunctionPointers.end()) 2488 return I->second; 2489 2490 ComputeMethodVtableIndices(RD); 2491 2492 I = NumVirtualFunctionPointers.find(RD); 2493 assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!"); 2494 return I->second; 2495} 2496 2497uint64_t CodeGenVTables::getMethodVtableIndex(GlobalDecl GD) { 2498 MethodVtableIndicesTy::iterator I = MethodVtableIndices.find(GD); 2499 if (I != MethodVtableIndices.end()) 2500 return I->second; 2501 2502 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2503 2504 ComputeMethodVtableIndices(RD); 2505 2506 I = MethodVtableIndices.find(GD); 2507 assert(I != MethodVtableIndices.end() && "Did not find index!"); 2508 return I->second; 2509} 2510 2511int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 2512 const CXXRecordDecl *VBase) { 2513 ClassPairTy ClassPair(RD, VBase); 2514 2515 VirtualBaseClassOffsetOffsetsMapTy::iterator I = 2516 VirtualBaseClassOffsetOffsets.find(ClassPair); 2517 if (I != VirtualBaseClassOffsetOffsets.end()) 2518 return I->second; 2519 2520 VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0, 2521 BaseSubobject(RD, 0), 2522 /*BaseIsVirtual=*/false, 2523 /*OffsetInLayoutClass=*/0); 2524 2525 for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2526 Builder.getVBaseOffsetOffsets().begin(), 2527 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2528 // Insert all types. 2529 ClassPairTy ClassPair(RD, I->first); 2530 2531 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2532 } 2533 2534 I = VirtualBaseClassOffsetOffsets.find(ClassPair); 2535 2536 // FIXME: The assertion below assertion currently fails with the old vtable 2537 /// layout code if there is a non-virtual thunk adjustment in a vtable. 2538 // Once the new layout is in place, this return should be removed. 2539 if (I == VirtualBaseClassOffsetOffsets.end()) 2540 return 0; 2541 2542 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); 2543 2544 return I->second; 2545} 2546 2547uint64_t 2548CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { 2549 assert(AddressPoints.count(std::make_pair(RD, Base)) && 2550 "Did not find address point!"); 2551 2552 uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base)); 2553 assert(AddressPoint && "Address point must not be zero!"); 2554 2555 return AddressPoint; 2556} 2557 2558llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 2559 const ThunkInfo &Thunk) { 2560 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2561 2562 // Compute the mangled name. 2563 llvm::SmallString<256> Name; 2564 if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD)) 2565 getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), Thunk.This, 2566 Name); 2567 else 2568 getMangleContext().mangleThunk(MD, Thunk, Name); 2569 2570 const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); 2571 return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); 2572} 2573 2574static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, 2575 llvm::Value *Ptr, 2576 int64_t NonVirtualAdjustment, 2577 int64_t VirtualAdjustment) { 2578 if (!NonVirtualAdjustment && !VirtualAdjustment) 2579 return Ptr; 2580 2581 const llvm::Type *Int8PtrTy = 2582 llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 2583 2584 llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); 2585 2586 if (NonVirtualAdjustment) { 2587 // Do the non-virtual adjustment. 2588 V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); 2589 } 2590 2591 if (VirtualAdjustment) { 2592 const llvm::Type *PtrDiffTy = 2593 CGF.ConvertType(CGF.getContext().getPointerDiffType()); 2594 2595 // Do the virtual adjustment. 2596 llvm::Value *VTablePtrPtr = 2597 CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); 2598 2599 llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); 2600 2601 llvm::Value *OffsetPtr = 2602 CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 2603 2604 OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); 2605 2606 // Load the adjustment offset from the vtable. 2607 llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr); 2608 2609 // Adjust our pointer. 2610 V = CGF.Builder.CreateInBoundsGEP(V, Offset); 2611 } 2612 2613 // Cast back to the original type. 2614 return CGF.Builder.CreateBitCast(V, Ptr->getType()); 2615} 2616 2617void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, 2618 const ThunkInfo &Thunk) { 2619 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2620 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 2621 QualType ResultType = FPT->getResultType(); 2622 QualType ThisType = MD->getThisType(getContext()); 2623 2624 FunctionArgList FunctionArgs; 2625 2626 // FIXME: It would be nice if more of this code could be shared with 2627 // CodeGenFunction::GenerateCode. 2628 2629 // Create the implicit 'this' parameter declaration. 2630 CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0, 2631 MD->getLocation(), 2632 &getContext().Idents.get("this"), 2633 ThisType); 2634 2635 // Add the 'this' parameter. 2636 FunctionArgs.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType())); 2637 2638 // Add the rest of the parameters. 2639 for (FunctionDecl::param_const_iterator I = MD->param_begin(), 2640 E = MD->param_end(); I != E; ++I) { 2641 ParmVarDecl *Param = *I; 2642 2643 FunctionArgs.push_back(std::make_pair(Param, Param->getType())); 2644 } 2645 2646 StartFunction(GlobalDecl(), ResultType, Fn, FunctionArgs, SourceLocation()); 2647 2648 // Adjust the 'this' pointer if necessary. 2649 llvm::Value *AdjustedThisPtr = 2650 PerformTypeAdjustment(*this, LoadCXXThis(), 2651 Thunk.This.NonVirtual, 2652 Thunk.This.VCallOffsetOffset); 2653 2654 CallArgList CallArgs; 2655 2656 // Add our adjusted 'this' pointer. 2657 CallArgs.push_back(std::make_pair(RValue::get(AdjustedThisPtr), ThisType)); 2658 2659 // Add the rest of the parameters. 2660 for (FunctionDecl::param_const_iterator I = MD->param_begin(), 2661 E = MD->param_end(); I != E; ++I) { 2662 ParmVarDecl *Param = *I; 2663 QualType ArgType = Param->getType(); 2664 2665 // FIXME: Declaring a DeclRefExpr on the stack is kinda icky. 2666 DeclRefExpr ArgExpr(Param, ArgType.getNonReferenceType(), SourceLocation()); 2667 CallArgs.push_back(std::make_pair(EmitCallArg(&ArgExpr, ArgType), ArgType)); 2668 } 2669 2670 // Get our callee. 2671 const llvm::Type *Ty = 2672 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 2673 FPT->isVariadic()); 2674 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); 2675 2676 const CGFunctionInfo &FnInfo = 2677 CGM.getTypes().getFunctionInfo(ResultType, CallArgs, 2678 FPT->getExtInfo()); 2679 2680 // Now emit our call. 2681 RValue RV = EmitCall(FnInfo, Callee, ReturnValueSlot(), CallArgs, MD); 2682 2683 if (!Thunk.Return.isEmpty()) { 2684 // Emit the return adjustment. 2685 bool NullCheckValue = !ResultType->isReferenceType(); 2686 2687 llvm::BasicBlock *AdjustNull = 0; 2688 llvm::BasicBlock *AdjustNotNull = 0; 2689 llvm::BasicBlock *AdjustEnd = 0; 2690 2691 llvm::Value *ReturnValue = RV.getScalarVal(); 2692 2693 if (NullCheckValue) { 2694 AdjustNull = createBasicBlock("adjust.null"); 2695 AdjustNotNull = createBasicBlock("adjust.notnull"); 2696 AdjustEnd = createBasicBlock("adjust.end"); 2697 2698 llvm::Value *IsNull = Builder.CreateIsNull(ReturnValue); 2699 Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull); 2700 EmitBlock(AdjustNotNull); 2701 } 2702 2703 ReturnValue = PerformTypeAdjustment(*this, ReturnValue, 2704 Thunk.Return.NonVirtual, 2705 Thunk.Return.VBaseOffsetOffset); 2706 2707 if (NullCheckValue) { 2708 Builder.CreateBr(AdjustEnd); 2709 EmitBlock(AdjustNull); 2710 Builder.CreateBr(AdjustEnd); 2711 EmitBlock(AdjustEnd); 2712 2713 llvm::PHINode *PHI = Builder.CreatePHI(ReturnValue->getType()); 2714 PHI->reserveOperandSpace(2); 2715 PHI->addIncoming(ReturnValue, AdjustNotNull); 2716 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), 2717 AdjustNull); 2718 ReturnValue = PHI; 2719 } 2720 2721 RV = RValue::get(ReturnValue); 2722 } 2723 2724 if (!ResultType->isVoidType()) 2725 EmitReturnOfRValue(RV, ResultType); 2726 2727 FinishFunction(); 2728 2729 // Destroy the 'this' declaration. 2730 CXXThisDecl->Destroy(getContext()); 2731 2732 // Set the right linkage. 2733 Fn->setLinkage(CGM.getFunctionLinkage(MD)); 2734 2735 // Set the right visibility. 2736 CGM.setGlobalVisibility(Fn, MD); 2737} 2738 2739void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk) 2740{ 2741 llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk); 2742 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2743 2744 // Strip off a bitcast if we got one back. 2745 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) { 2746 assert(CE->getOpcode() == llvm::Instruction::BitCast); 2747 Entry = CE->getOperand(0); 2748 } 2749 2750 // There's already a declaration with the same name, check if it has the same 2751 // type or if we need to replace it. 2752 if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != 2753 CGM.getTypes().GetFunctionTypeForVtable(MD)) { 2754 llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(Entry); 2755 2756 // If the types mismatch then we have to rewrite the definition. 2757 assert(OldThunkFn->isDeclaration() && 2758 "Shouldn't replace non-declaration"); 2759 2760 // Remove the name from the old thunk function and get a new thunk. 2761 OldThunkFn->setName(llvm::StringRef()); 2762 Entry = CGM.GetAddrOfThunk(GD, Thunk); 2763 2764 // If needed, replace the old thunk with a bitcast. 2765 if (!OldThunkFn->use_empty()) { 2766 llvm::Constant *NewPtrForOldDecl = 2767 llvm::ConstantExpr::getBitCast(Entry, OldThunkFn->getType()); 2768 OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl); 2769 } 2770 2771 // Remove the old thunk. 2772 OldThunkFn->eraseFromParent(); 2773 } 2774 2775 // Actually generate the thunk body. 2776 llvm::Function *ThunkFn = cast<llvm::Function>(Entry); 2777 CodeGenFunction(CGM).GenerateThunk(ThunkFn, GD, Thunk); 2778} 2779 2780void CodeGenVTables::EmitThunks(GlobalDecl GD) 2781{ 2782 const CXXMethodDecl *MD = 2783 cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl(); 2784 2785 // We don't need to generate thunks for the base destructor. 2786 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) 2787 return; 2788 2789 const CXXRecordDecl *RD = MD->getParent(); 2790 2791 // Compute VTable related info for this class. 2792 ComputeVTableRelatedInformation(RD); 2793 2794 ThunksMapTy::const_iterator I = Thunks.find(MD); 2795 if (I == Thunks.end()) { 2796 // We did not find a thunk for this method. 2797 return; 2798 } 2799 2800 const ThunkInfoVectorTy &ThunkInfoVector = I->second; 2801 for (unsigned I = 0, E = ThunkInfoVector.size(); I != E; ++I) 2802 EmitThunk(GD, ThunkInfoVector[I]); 2803} 2804 2805void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { 2806 uint64_t *&LayoutData = VTableLayoutMap[RD]; 2807 2808 // Check if we've computed this information before. 2809 if (LayoutData) 2810 return; 2811 2812 VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD); 2813 2814 // Add the VTable layout. 2815 uint64_t NumVTableComponents = Builder.getNumVTableComponents(); 2816 LayoutData = new uint64_t[NumVTableComponents + 1]; 2817 2818 // Store the number of components. 2819 LayoutData[0] = NumVTableComponents; 2820 2821 // Store the components. 2822 std::copy(Builder.vtable_components_data_begin(), 2823 Builder.vtable_components_data_end(), 2824 &LayoutData[1]); 2825 2826 // Add the known thunks. 2827 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 2828 2829 // Add the thunks needed in this vtable. 2830 assert(!VTableThunksMap.count(RD) && 2831 "Thunks already exists for this vtable!"); 2832 2833 VTableThunksTy &VTableThunks = VTableThunksMap[RD]; 2834 VTableThunks.append(Builder.vtable_thunks_begin(), 2835 Builder.vtable_thunks_end()); 2836 2837 // Sort them. 2838 std::sort(VTableThunks.begin(), VTableThunks.end()); 2839 2840 // Add the address points. 2841 for (VTableBuilder::AddressPointsMapTy::const_iterator I = 2842 Builder.address_points_begin(), E = Builder.address_points_end(); 2843 I != E; ++I) { 2844 2845 uint64_t &AddressPoint = AddressPoints[std::make_pair(RD, I->first)]; 2846 2847 // Check if we already have the address points for this base. 2848 assert(!AddressPoint && "Address point already exists for this base!"); 2849 2850 AddressPoint = I->second; 2851 } 2852 2853 // If we don't have the vbase information for this class, insert it. 2854 // getVirtualBaseOffsetOffset will compute it separately without computing 2855 // the rest of the vtable related information. 2856 if (!RD->getNumVBases()) 2857 return; 2858 2859 const RecordType *VBaseRT = 2860 RD->vbases_begin()->getType()->getAs<RecordType>(); 2861 const CXXRecordDecl *VBase = cast<CXXRecordDecl>(VBaseRT->getDecl()); 2862 2863 if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) 2864 return; 2865 2866 for (VTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2867 Builder.getVBaseOffsetOffsets().begin(), 2868 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2869 // Insert all types. 2870 ClassPairTy ClassPair(RD, I->first); 2871 2872 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2873 } 2874} 2875 2876llvm::Constant * 2877CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, 2878 const uint64_t *Components, 2879 unsigned NumComponents, 2880 const VTableThunksTy &VTableThunks) { 2881 llvm::SmallVector<llvm::Constant *, 64> Inits; 2882 2883 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 2884 2885 const llvm::Type *PtrDiffTy = 2886 CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); 2887 2888 QualType ClassType = CGM.getContext().getTagDeclType(RD); 2889 llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType); 2890 2891 unsigned NextVTableThunkIndex = 0; 2892 2893 llvm::Constant* PureVirtualFn = 0; 2894 2895 for (unsigned I = 0; I != NumComponents; ++I) { 2896 VTableComponent Component = 2897 VTableComponent::getFromOpaqueInteger(Components[I]); 2898 2899 llvm::Constant *Init = 0; 2900 2901 switch (Component.getKind()) { 2902 case VTableComponent::CK_VCallOffset: 2903 Init = llvm::ConstantInt::get(PtrDiffTy, Component.getVCallOffset()); 2904 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 2905 break; 2906 case VTableComponent::CK_VBaseOffset: 2907 Init = llvm::ConstantInt::get(PtrDiffTy, Component.getVBaseOffset()); 2908 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 2909 break; 2910 case VTableComponent::CK_OffsetToTop: 2911 Init = llvm::ConstantInt::get(PtrDiffTy, Component.getOffsetToTop()); 2912 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 2913 break; 2914 case VTableComponent::CK_RTTI: 2915 Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy); 2916 break; 2917 case VTableComponent::CK_FunctionPointer: 2918 case VTableComponent::CK_CompleteDtorPointer: 2919 case VTableComponent::CK_DeletingDtorPointer: { 2920 GlobalDecl GD; 2921 2922 // Get the right global decl. 2923 switch (Component.getKind()) { 2924 default: 2925 llvm_unreachable("Unexpected vtable component kind"); 2926 case VTableComponent::CK_FunctionPointer: 2927 GD = Component.getFunctionDecl(); 2928 break; 2929 case VTableComponent::CK_CompleteDtorPointer: 2930 GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete); 2931 break; 2932 case VTableComponent::CK_DeletingDtorPointer: 2933 GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting); 2934 break; 2935 } 2936 2937 if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { 2938 // We have a pure virtual member function. 2939 if (!PureVirtualFn) { 2940 const llvm::FunctionType *Ty = 2941 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), 2942 /*isVarArg=*/false); 2943 PureVirtualFn = 2944 CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual"); 2945 PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn, 2946 Int8PtrTy); 2947 } 2948 2949 Init = PureVirtualFn; 2950 } else { 2951 // Check if we should use a thunk. 2952 if (NextVTableThunkIndex < VTableThunks.size() && 2953 VTableThunks[NextVTableThunkIndex].first == I) { 2954 const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second; 2955 2956 Init = CGM.GetAddrOfThunk(GD, Thunk); 2957 2958 NextVTableThunkIndex++; 2959 } else { 2960 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2961 const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD); 2962 2963 Init = CGM.GetAddrOfFunction(GD, Ty); 2964 } 2965 2966 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); 2967 } 2968 break; 2969 } 2970 2971 case VTableComponent::CK_UnusedFunctionPointer: 2972 Init = llvm::ConstantExpr::getNullValue(Int8PtrTy); 2973 break; 2974 }; 2975 2976 Inits.push_back(Init); 2977 } 2978 2979 llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents); 2980 return llvm::ConstantArray::get(ArrayType, Inits.data(), Inits.size()); 2981} 2982 2983/// GetGlobalVariable - Will return a global variable of the given type. 2984/// If a variable with a different type already exists then a new variable 2985/// with the right type will be created. 2986/// FIXME: We should move this to CodeGenModule and rename it to something 2987/// better and then use it in CGVTT and CGRTTI. 2988static llvm::GlobalVariable * 2989GetGlobalVariable(llvm::Module &Module, llvm::StringRef Name, 2990 const llvm::Type *Ty, 2991 llvm::GlobalValue::LinkageTypes Linkage) { 2992 2993 llvm::GlobalVariable *GV = Module.getNamedGlobal(Name); 2994 llvm::GlobalVariable *OldGV = 0; 2995 2996 if (GV) { 2997 // Check if the variable has the right type. 2998 if (GV->getType()->getElementType() == Ty) 2999 return GV; 3000 3001 assert(GV->isDeclaration() && "Declaration has wrong type!"); 3002 3003 OldGV = GV; 3004 } 3005 3006 // Create a new variable. 3007 GV = new llvm::GlobalVariable(Module, Ty, /*isConstant=*/true, 3008 Linkage, 0, Name); 3009 3010 if (OldGV) { 3011 // Replace occurrences of the old variable if needed. 3012 GV->takeName(OldGV); 3013 3014 if (!OldGV->use_empty()) { 3015 llvm::Constant *NewPtrForOldDecl = 3016 llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); 3017 OldGV->replaceAllUsesWith(NewPtrForOldDecl); 3018 } 3019 3020 OldGV->eraseFromParent(); 3021 } 3022 3023 return GV; 3024} 3025 3026llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { 3027 llvm::SmallString<256> OutName; 3028 CGM.getMangleContext().mangleCXXVtable(RD, OutName); 3029 llvm::StringRef Name = OutName.str(); 3030 3031 ComputeVTableRelatedInformation(RD); 3032 3033 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 3034 llvm::ArrayType *ArrayType = 3035 llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD)); 3036 3037 return GetGlobalVariable(CGM.getModule(), Name, ArrayType, 3038 llvm::GlobalValue::ExternalLinkage); 3039} 3040 3041void 3042CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, 3043 llvm::GlobalVariable::LinkageTypes Linkage, 3044 const CXXRecordDecl *RD) { 3045 // Dump the vtable layout if necessary. 3046 if (CGM.getLangOptions().DumpVtableLayouts) { 3047 VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD); 3048 3049 Builder.dumpLayout(llvm::errs()); 3050 } 3051 3052 assert(VTableThunksMap.count(RD) && 3053 "No thunk status for this record decl!"); 3054 3055 const VTableThunksTy& Thunks = VTableThunksMap[RD]; 3056 3057 // Create and set the initializer. 3058 llvm::Constant *Init = 3059 CreateVTableInitializer(RD, getVTableComponentsData(RD), 3060 getNumVTableComponents(RD), Thunks); 3061 VTable->setInitializer(Init); 3062 3063 // Set the correct linkage. 3064 VTable->setLinkage(Linkage); 3065} 3066 3067llvm::GlobalVariable * 3068CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, 3069 const BaseSubobject &Base, 3070 bool BaseIsVirtual, 3071 VTableAddressPointsMapTy& AddressPoints) { 3072 VTableBuilder Builder(*this, Base.getBase(), Base.getBaseOffset(), 3073 /*MostDerivedClassIsVirtual=*/BaseIsVirtual, RD); 3074 3075 // Dump the vtable layout if necessary. 3076 if (CGM.getLangOptions().DumpVtableLayouts) 3077 Builder.dumpLayout(llvm::errs()); 3078 3079 // Add the address points. 3080 AddressPoints.insert(Builder.address_points_begin(), 3081 Builder.address_points_end()); 3082 3083 // Get the mangled construction vtable name. 3084 llvm::SmallString<256> OutName; 3085 CGM.getMangleContext().mangleCXXCtorVtable(RD, Base.getBaseOffset() / 8, 3086 Base.getBase(), OutName); 3087 llvm::StringRef Name = OutName.str(); 3088 3089 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 3090 llvm::ArrayType *ArrayType = 3091 llvm::ArrayType::get(Int8PtrTy, Builder.getNumVTableComponents()); 3092 3093 // Create the variable that will hold the construction vtable. 3094 llvm::GlobalVariable *VTable = 3095 GetGlobalVariable(CGM.getModule(), Name, ArrayType, 3096 llvm::GlobalValue::InternalLinkage); 3097 3098 // Add the thunks. 3099 VTableThunksTy VTableThunks; 3100 VTableThunks.append(Builder.vtable_thunks_begin(), 3101 Builder.vtable_thunks_end()); 3102 3103 // Sort them. 3104 std::sort(VTableThunks.begin(), VTableThunks.end()); 3105 3106 // Create and set the initializer. 3107 llvm::Constant *Init = 3108 CreateVTableInitializer(Base.getBase(), 3109 Builder.vtable_components_data_begin(), 3110 Builder.getNumVTableComponents(), VTableThunks); 3111 VTable->setInitializer(Init); 3112 3113 return VTable; 3114} 3115 3116void 3117CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, 3118 const CXXRecordDecl *RD) { 3119 llvm::GlobalVariable *&VTable = Vtables[RD]; 3120 if (VTable) { 3121 assert(VTable->getInitializer() && "Vtable doesn't have a definition!"); 3122 return; 3123 } 3124 3125 VTable = GetAddrOfVTable(RD); 3126 EmitVTableDefinition(VTable, Linkage, RD); 3127 3128 GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); 3129 3130 // If this is the magic class __cxxabiv1::__fundamental_type_info, 3131 // we will emit the typeinfo for the fundamental types. This is the 3132 // same behaviour as GCC. 3133 const DeclContext *DC = RD->getDeclContext(); 3134 if (RD->getIdentifier() && 3135 RD->getIdentifier()->isStr("__fundamental_type_info") && 3136 isa<NamespaceDecl>(DC) && 3137 cast<NamespaceDecl>(DC)->getIdentifier() && 3138 cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && 3139 DC->getParent()->isTranslationUnit()) 3140 CGM.EmitFundamentalRTTIDescriptors(); 3141} 3142 3143void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) { 3144 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 3145 const CXXRecordDecl *RD = MD->getParent(); 3146 3147 // If the class doesn't have a vtable we don't need to emit one. 3148 if (!RD->isDynamicClass()) 3149 return; 3150 3151 // Check if we need to emit thunks for this function. 3152 if (MD->isVirtual()) 3153 EmitThunks(GD); 3154 3155 // Get the key function. 3156 const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD); 3157 3158 TemplateSpecializationKind RDKind = RD->getTemplateSpecializationKind(); 3159 TemplateSpecializationKind MDKind = MD->getTemplateSpecializationKind(); 3160 3161 if (KeyFunction) { 3162 // We don't have the right key function. 3163 if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) 3164 return; 3165 } else { 3166 // If we have no key funcion and this is a explicit instantiation declaration, 3167 // we will produce a vtable at the explicit instantiation. We don't need one 3168 // here. 3169 if (RDKind == clang::TSK_ExplicitInstantiationDeclaration) 3170 return; 3171 3172 // If this is an explicit instantiation of a method, we don't need a vtable. 3173 // Since we have no key function, we will emit the vtable when we see 3174 // a use, and just defining a function is not an use. 3175 if (RDKind == TSK_ImplicitInstantiation && 3176 MDKind == TSK_ExplicitInstantiationDefinition) 3177 return; 3178 } 3179 3180 if (Vtables.count(RD)) 3181 return; 3182 3183 if (RDKind == TSK_ImplicitInstantiation) 3184 CGM.DeferredVtables.push_back(RD); 3185 else 3186 GenerateClassData(CGM.getVtableLinkage(RD), RD); 3187} 3188