From: Anders Carlsson Date: Tue, 30 Mar 2010 03:43:47 +0000 (+0000) Subject: Remove the old vtable layout code. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bfb7a1d6eba6714bd71db921092332da65b774c0;p=clang Remove the old vtable layout code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99869 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 7fb5ad4852..93a182f5cc 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -297,38 +297,6 @@ void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name, getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer()); } -llvm::Constant * -CodeGenModule::GetAddrOfThunk(GlobalDecl GD, - const ThunkAdjustment &ThisAdjustment) { - const CXXMethodDecl *MD = cast(GD.getDecl()); - - // Compute mangled name - llvm::SmallString<256> OutName; - if (const CXXDestructorDecl* DD = dyn_cast(MD)) - getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), ThisAdjustment, - OutName); - else - getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); - - // Get function for mangled name - const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); - return GetOrCreateLLVMFunction(OutName, Ty, GlobalDecl()); -} - -llvm::Constant * -CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD, - const CovariantThunkAdjustment &Adjustment) { - const CXXMethodDecl *MD = cast(GD.getDecl()); - - // Compute mangled name - llvm::SmallString<256> Name; - getMangleContext().mangleCovariantThunk(MD, Adjustment, Name); - - // Get function for mangled name - const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); - return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); -} - static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VtableIndex, llvm::Value *This, const llvm::Type *Ty) { Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo(); diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 6702051bc3..e702c5e783 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -69,42 +69,6 @@ CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *Class, return llvm::ConstantInt::get(PtrDiffTy, Offset); } -// FIXME: This probably belongs in CGVtable, but it relies on -// the static function ComputeNonVirtualBaseClassOffset, so we should make that -// a CodeGenModule member function as well. -ThunkAdjustment -CodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl) { - CXXBasePaths Paths(/*FindAmbiguities=*/false, - /*RecordPaths=*/true, /*DetectVirtual=*/false); - if (!const_cast(ClassDecl)-> - isDerivedFrom(const_cast(BaseClassDecl), Paths)) { - assert(false && "Class must be derived from the passed in base class!"); - return ThunkAdjustment(); - } - - unsigned Start = 0; - uint64_t VirtualOffset = 0; - - const CXXBasePath &Path = Paths.front(); - const CXXRecordDecl *VBase = 0; - for (unsigned i = 0, e = Path.size(); i != e; ++i) { - const CXXBasePathElement& Element = Path[i]; - if (Element.Base->isVirtual()) { - Start = i+1; - QualType VBaseType = Element.Base->getType(); - VBase = cast(VBaseType->getAs()->getDecl()); - } - } - if (VBase) - VirtualOffset = - getVTables().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); - - uint64_t Offset = - ComputeNonVirtualBaseClassOffset(getContext(), Paths.front(), Start); - return ThunkAdjustment(Offset, VirtualOffset); -} - /// Gets the address of a virtual base class within a complete object. /// This should only be used for (1) non-virtual bases or (2) virtual bases /// when the type is known to be complete (e.g. in complete destructors). diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index cdc8133c12..91d9f763bf 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -37,8 +37,6 @@ class VTTBuilder { /// MostDerivedClassLayout - the AST record layout of the most derived class. const ASTRecordLayout &MostDerivedClassLayout; - CodeGenVTables::AddrMap_t &AddressPoints; - typedef llvm::SmallPtrSet VisitedVirtualBasesSetTy; typedef llvm::DenseMap AddressPointsMapTy; @@ -137,7 +135,6 @@ VTTBuilder::VTTBuilder(CodeGenModule &CGM, bool GenerateDefinition) : CGM(CGM), MostDerivedClass(MostDerivedClass), MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)), - AddressPoints(*CGM.getVTables().OldAddressPoints[MostDerivedClass]), GenerateDefinition(GenerateDefinition) { // Lay out this VTT. diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 30c9efc91b..841281cdc4 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -2373,1081 +2373,6 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) { } -namespace { -class OldVtableBuilder { -public: - /// Index_t - Vtable index type. - typedef uint64_t Index_t; - typedef std::vector > > - SavedAdjustmentsVectorTy; - typedef llvm::DenseMap AddressPointsMapTy; - -private: - - // VtableComponents - The components of the vtable being built. - typedef llvm::SmallVector VtableComponentsVectorTy; - VtableComponentsVectorTy VtableComponents; - - const bool BuildVtable; - - llvm::Type *Ptr8Ty; - - /// MostDerivedClass - The most derived class that this vtable is being - /// built for. - const CXXRecordDecl *MostDerivedClass; - - /// LayoutClass - The most derived class used for virtual base layout - /// information. - const CXXRecordDecl *LayoutClass; - /// LayoutOffset - The offset for Class in LayoutClass. - uint64_t LayoutOffset; - /// BLayout - Layout for the most derived class that this vtable is being - /// built for. - const ASTRecordLayout &BLayout; - llvm::SmallSet IndirectPrimary; - llvm::SmallSet SeenVBase; - llvm::Constant *rtti; - llvm::LLVMContext &VMContext; - CodeGenModule &CGM; // Per-module state. - - llvm::DenseMap VCall; - llvm::DenseMap VCallOffset; - llvm::DenseMap VCallOffsetForVCall; - // This is the offset to the nearest virtual base - llvm::DenseMap NonVirtualOffset; - llvm::DenseMap VBIndex; - - /// PureVirtualFunction - Points to __cxa_pure_virtual. - llvm::Constant *PureVirtualFn; - - /// VtableMethods - A data structure for keeping track of methods in a vtable. - /// Can add methods, override methods and iterate in vtable order. - class VtableMethods { - // MethodToIndexMap - Maps from a global decl to the index it has in the - // Methods vector. - llvm::DenseMap MethodToIndexMap; - - /// Methods - The methods, in vtable order. - typedef llvm::SmallVector MethodsVectorTy; - MethodsVectorTy Methods; - MethodsVectorTy OrigMethods; - - public: - /// AddMethod - Add a method to the vtable methods. - void AddMethod(GlobalDecl GD) { - assert(!MethodToIndexMap.count(GD) && - "Method has already been added!"); - - MethodToIndexMap[GD] = Methods.size(); - Methods.push_back(GD); - OrigMethods.push_back(GD); - } - - /// OverrideMethod - Replace a method with another. - void OverrideMethod(GlobalDecl OverriddenGD, GlobalDecl GD) { - llvm::DenseMap::iterator i - = MethodToIndexMap.find(OverriddenGD); - assert(i != MethodToIndexMap.end() && "Did not find entry!"); - - // Get the index of the old decl. - uint64_t Index = i->second; - - // Replace the old decl with the new decl. - Methods[Index] = GD; - - // And add the new. - MethodToIndexMap[GD] = Index; - } - - /// getIndex - Gives the index of a passed in GlobalDecl. Returns false if - /// the index couldn't be found. - bool getIndex(GlobalDecl GD, uint64_t &Index) const { - llvm::DenseMap::const_iterator i - = MethodToIndexMap.find(GD); - - if (i == MethodToIndexMap.end()) - return false; - - Index = i->second; - return true; - } - - GlobalDecl getOrigMethod(uint64_t Index) const { - return OrigMethods[Index]; - } - - MethodsVectorTy::size_type size() const { - return Methods.size(); - } - - void clear() { - MethodToIndexMap.clear(); - Methods.clear(); - OrigMethods.clear(); - } - - GlobalDecl operator[](uint64_t Index) const { - return Methods[Index]; - } - }; - - /// Methods - The vtable methods we're currently building. - VtableMethods Methods; - - /// ThisAdjustments - For a given index in the vtable, contains the 'this' - /// pointer adjustment needed for a method. - typedef llvm::DenseMap ThisAdjustmentsMapTy; - ThisAdjustmentsMapTy ThisAdjustments; - - SavedAdjustmentsVectorTy SavedAdjustments; - - /// BaseReturnTypes - Contains the base return types of methods who have been - /// overridden with methods whose return types require adjustment. Used for - /// generating covariant thunk information. - typedef llvm::DenseMap BaseReturnTypesMapTy; - BaseReturnTypesMapTy BaseReturnTypes; - - std::vector VCalls; - - typedef std::pair CtorVtable_t; - // subAddressPoints - Used to hold the AddressPoints (offsets) into the built - // vtable for use in computing the initializers for the VTT. - llvm::DenseMap &subAddressPoints; - - /// AddressPoints - Address points for this vtable. - AddressPointsMapTy& AddressPoints; - - typedef CXXRecordDecl::method_iterator method_iter; - const uint32_t LLVMPointerWidth; - Index_t extra; - typedef std::vector > Path_t; - static llvm::DenseMap& - AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l, - const CXXRecordDecl *c) { - CodeGenVTables::AddrMap_t *&oref = cgm.getVTables().OldAddressPoints[l]; - if (oref == 0) - oref = new CodeGenVTables::AddrMap_t; - - llvm::DenseMap *&ref = (*oref)[c]; - if (ref == 0) - ref = new llvm::DenseMap; - return *ref; - } - - bool DclIsSame(const FunctionDecl *New, const FunctionDecl *Old) { - FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); - FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); - - // C++ [temp.fct]p2: - // A function template can be overloaded with other function templates - // and with normal (non-template) functions. - if ((OldTemplate == 0) != (NewTemplate == 0)) - return false; - - // Is the function New an overload of the function Old? - QualType OldQType = CGM.getContext().getCanonicalType(Old->getType()); - QualType NewQType = CGM.getContext().getCanonicalType(New->getType()); - - // Compare the signatures (C++ 1.3.10) of the two functions to - // determine whether they are overloads. If we find any mismatch - // in the signature, they are overloads. - - // If either of these functions is a K&R-style function (no - // prototype), then we consider them to have matching signatures. - if (isa(OldQType.getTypePtr()) || - isa(NewQType.getTypePtr())) - return true; - - FunctionProtoType* OldType = cast(OldQType); - FunctionProtoType* NewType = cast(NewQType); - - // The signature of a function includes the types of its - // parameters (C++ 1.3.10), which includes the presence or absence - // of the ellipsis; see C++ DR 357). - if (OldQType != NewQType && - (OldType->getNumArgs() != NewType->getNumArgs() || - OldType->isVariadic() != NewType->isVariadic() || - !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(), - NewType->arg_type_begin()))) - return false; - -#if 0 - // C++ [temp.over.link]p4: - // The signature of a function template consists of its function - // signature, its return type and its template parameter list. The names - // of the template parameters are significant only for establishing the - // relationship between the template parameters and the rest of the - // signature. - // - // We check the return type and template parameter lists for function - // templates first; the remaining checks follow. - if (NewTemplate && - (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), - OldTemplate->getTemplateParameters(), - TPL_TemplateMatch) || - OldType->getResultType() != NewType->getResultType())) - return false; -#endif - - // If the function is a class member, its signature includes the - // cv-qualifiers (if any) on the function itself. - // - // As part of this, also check whether one of the member functions - // is static, in which case they are not overloads (C++ - // 13.1p2). While not part of the definition of the signature, - // this check is important to determine whether these functions - // can be overloaded. - const CXXMethodDecl* OldMethod = dyn_cast(Old); - const CXXMethodDecl* NewMethod = dyn_cast(New); - if (OldMethod && NewMethod && - !OldMethod->isStatic() && !NewMethod->isStatic() && - OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers()) - return false; - - // The signatures match; this is not an overload. - return true; - } - - typedef llvm::DenseMap - ForwardUnique_t; - ForwardUnique_t ForwardUnique; - llvm::DenseMap UniqueOverrider; - - void BuildUniqueOverrider(const CXXMethodDecl *U, const CXXMethodDecl *MD) { - const CXXMethodDecl *PrevU = UniqueOverrider[MD]; - assert(U && "no unique overrider"); - if (PrevU == U) - return; - if (PrevU != U && PrevU != 0) { - // If already set, note the two sets as the same - if (0) - printf("%s::%s same as %s::%s\n", - PrevU->getParent()->getNameAsString().c_str(), - PrevU->getNameAsString().c_str(), - U->getParent()->getNameAsString().c_str(), - U->getNameAsString().c_str()); - ForwardUnique[PrevU] = U; - return; - } - - // Not set, set it now - if (0) - printf("marking %s::%s %p override as %s::%s\n", - MD->getParent()->getNameAsString().c_str(), - MD->getNameAsString().c_str(), - (void*)MD, - U->getParent()->getNameAsString().c_str(), - U->getNameAsString().c_str()); - UniqueOverrider[MD] = U; - - for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(), - me = MD->end_overridden_methods(); mi != me; ++mi) { - BuildUniqueOverrider(U, *mi); - } - } - - void BuildUniqueOverriders(const CXXRecordDecl *RD) { - if (0) printf("walking %s\n", RD->getNameAsCString()); - for (CXXRecordDecl::method_iterator i = RD->method_begin(), - e = RD->method_end(); i != e; ++i) { - const CXXMethodDecl *MD = *i; - if (!MD->isVirtual()) - continue; - - if (UniqueOverrider[MD] == 0) { - // Only set this, if it hasn't been set yet. - BuildUniqueOverrider(MD, MD); - if (0) - printf("top set is %s::%s %p\n", - MD->getParent()->getNameAsString().c_str(), - MD->getNameAsString().c_str(), - (void*)MD); - ForwardUnique[MD] = MD; - } - } - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - BuildUniqueOverriders(Base); - } - } - - static int DclCmp(const void *p1, const void *p2) { - const CXXMethodDecl *MD1 = *(const CXXMethodDecl *const *)p1; - const CXXMethodDecl *MD2 = *(const CXXMethodDecl *const *)p2; - - return (DeclarationName::compare(MD1->getDeclName(), MD2->getDeclName())); - } - - void MergeForwarding() { - typedef llvm::SmallVector A_t; - A_t A; - for (ForwardUnique_t::iterator I = ForwardUnique.begin(), - E = ForwardUnique.end(); I != E; ++I) { - if (I->first == I->second) - // Only add the roots of all trees - A.push_back(I->first); - } - llvm::array_pod_sort(A.begin(), A.end(), DclCmp); - for (A_t::iterator I = A.begin(), - E = A.end(); I != E; ++I) { - A_t::iterator J = I; - while (++J != E && DclCmp(I, J) == 0) - if (DclIsSame(*I, *J)) { - if (0) printf("connecting %s\n", (*I)->getNameAsString().c_str()); - ForwardUnique[*J] = *I; - } - } - } - - const CXXMethodDecl *getUnique(const CXXMethodDecl *MD) { - const CXXMethodDecl *U = UniqueOverrider[MD]; - assert(U && "unique overrider not found"); - while (ForwardUnique.count(U)) { - const CXXMethodDecl *NU = ForwardUnique[U]; - if (NU == U) break; - U = NU; - } - return U; - } - - GlobalDecl getUnique(GlobalDecl GD) { - const CXXMethodDecl *Unique = getUnique(cast(GD.getDecl())); - - if (const CXXConstructorDecl *CD = dyn_cast(Unique)) - return GlobalDecl(CD, GD.getCtorType()); - - if (const CXXDestructorDecl *DD = dyn_cast(Unique)) - return GlobalDecl(DD, GD.getDtorType()); - - return Unique; - } - - /// getPureVirtualFn - Return the __cxa_pure_virtual function. - llvm::Constant* getPureVirtualFn() { - if (!PureVirtualFn) { - const llvm::FunctionType *Ty = - llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), - /*isVarArg=*/false); - PureVirtualFn = wrap(CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual")); - } - - return PureVirtualFn; - } - -public: - OldVtableBuilder(const CXXRecordDecl *MostDerivedClass, - const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm, - bool build, AddressPointsMapTy& AddressPoints) - : BuildVtable(build), MostDerivedClass(MostDerivedClass), LayoutClass(l), - LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)), - rtti(0), VMContext(cgm.getModule().getContext()),CGM(cgm), - PureVirtualFn(0), - subAddressPoints(AllocAddressPoint(cgm, l, MostDerivedClass)), - AddressPoints(AddressPoints), - LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) - { - Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); - if (BuildVtable) { - QualType ClassType = CGM.getContext().getTagDeclType(MostDerivedClass); - rtti = CGM.GetAddrOfRTTIDescriptor(ClassType); - } - BuildUniqueOverriders(MostDerivedClass); - MergeForwarding(); - } - - // getVtableComponents - Returns a reference to the vtable components. - const VtableComponentsVectorTy &getVtableComponents() const { - return VtableComponents; - } - - llvm::DenseMap &getVBIndex() - { return VBIndex; } - - SavedAdjustmentsVectorTy &getSavedAdjustments() - { return SavedAdjustments; } - - llvm::Constant *wrap(Index_t i) { - llvm::Constant *m; - m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i); - return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty); - } - - llvm::Constant *wrap(llvm::Constant *m) { - return llvm::ConstantExpr::getBitCast(m, Ptr8Ty); - } - -//#define D1(x) -#define D1(X) do { if (getenv("CLANG_VTABLE_DEBUG")) { X; } } while (0) - - void GenerateVBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset, - bool updateVBIndex, Index_t current_vbindex) { - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - Index_t next_vbindex = current_vbindex; - if (i->isVirtual() && !SeenVBase.count(Base)) { - SeenVBase.insert(Base); - if (updateVBIndex) { - next_vbindex = (ssize_t)(-(VCalls.size()*LLVMPointerWidth/8) - - 3*LLVMPointerWidth/8); - VBIndex[Base] = next_vbindex; - } - int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8; - VCalls.push_back((0?700:0) + BaseOffset); - D1(printf(" vbase for %s at %d delta %d most derived %s\n", - Base->getNameAsCString(), - (int)-VCalls.size()-3, (int)BaseOffset, - MostDerivedClass->getNameAsCString())); - } - // We also record offsets for non-virtual bases to closest enclosing - // virtual base. We do this so that we don't have to search - // for the nearst virtual base class when generating thunks. - if (updateVBIndex && VBIndex.count(Base) == 0) - VBIndex[Base] = next_vbindex; - GenerateVBaseOffsets(Base, Offset, updateVBIndex, next_vbindex); - } - } - - void StartNewTable() { - SeenVBase.clear(); - } - - Index_t getNVOffset_1(const CXXRecordDecl *D, const CXXRecordDecl *B, - Index_t Offset = 0) { - - if (B == D) - return Offset; - - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(D); - for (CXXRecordDecl::base_class_const_iterator i = D->bases_begin(), - e = D->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - int64_t BaseOffset = 0; - if (!i->isVirtual()) - BaseOffset = Offset + Layout.getBaseClassOffset(Base); - int64_t o = getNVOffset_1(Base, B, BaseOffset); - if (o >= 0) - return o; - } - - return -1; - } - - /// getNVOffset - Returns the non-virtual offset for the given (B) base of the - /// derived class D. - Index_t getNVOffset(QualType qB, QualType qD) { - qD = qD->getPointeeType(); - qB = qB->getPointeeType(); - CXXRecordDecl *D = cast(qD->getAs()->getDecl()); - CXXRecordDecl *B = cast(qB->getAs()->getDecl()); - int64_t o = getNVOffset_1(D, B); - if (o >= 0) - return o; - - assert(false && "FIXME: non-virtual base not found"); - return 0; - } - - /// getVbaseOffset - Returns the index into the vtable for the virtual base - /// offset for the given (B) virtual base of the derived class D. - Index_t getVbaseOffset(QualType qB, QualType qD) { - qD = qD->getPointeeType(); - qB = qB->getPointeeType(); - CXXRecordDecl *D = cast(qD->getAs()->getDecl()); - CXXRecordDecl *B = cast(qB->getAs()->getDecl()); - if (D != MostDerivedClass) - return CGM.getVTables().getVirtualBaseOffsetOffset(D, B); - llvm::DenseMap::iterator i; - i = VBIndex.find(B); - if (i != VBIndex.end()) - return i->second; - - assert(false && "FIXME: Base not found"); - return 0; - } - - bool OverrideMethod(GlobalDecl GD, bool MorallyVirtual, - Index_t OverrideOffset, Index_t Offset, - int64_t CurrentVBaseOffset); - - /// AppendMethods - Append the current methods to the vtable. - void AppendMethodsToVtable(); - - llvm::Constant *WrapAddrOf(GlobalDecl GD) { - const CXXMethodDecl *MD = cast(GD.getDecl()); - - const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD); - - return wrap(CGM.GetAddrOfFunction(GD, Ty)); - } - - void OverrideMethods(Path_t *Path, bool MorallyVirtual, int64_t Offset, - int64_t CurrentVBaseOffset) { - for (Path_t::reverse_iterator i = Path->rbegin(), - e = Path->rend(); i != e; ++i) { - const CXXRecordDecl *RD = i->first; - int64_t OverrideOffset = i->second; - for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; - ++mi) { - const CXXMethodDecl *MD = *mi; - - if (!MD->isVirtual()) - continue; - - if (const CXXDestructorDecl *DD = dyn_cast(MD)) { - // Override both the complete and the deleting destructor. - GlobalDecl CompDtor(DD, Dtor_Complete); - OverrideMethod(CompDtor, MorallyVirtual, OverrideOffset, Offset, - CurrentVBaseOffset); - - GlobalDecl DeletingDtor(DD, Dtor_Deleting); - OverrideMethod(DeletingDtor, MorallyVirtual, OverrideOffset, Offset, - CurrentVBaseOffset); - } else { - OverrideMethod(MD, MorallyVirtual, OverrideOffset, Offset, - CurrentVBaseOffset); - } - } - } - } - - void AddMethod(const GlobalDecl GD, bool MorallyVirtual, Index_t Offset, - int64_t CurrentVBaseOffset) { - // If we can find a previously allocated slot for this, reuse it. - if (OverrideMethod(GD, MorallyVirtual, Offset, Offset, - CurrentVBaseOffset)) - return; - - D1(printf(" vfn for %s at %d\n", - dyn_cast(GD.getDecl())->getNameAsString().c_str(), - (int)Methods.size())); - - // We didn't find an entry in the vtable that we could use, add a new - // entry. - Methods.AddMethod(GD); - - VCallOffset[GD] = Offset/8 - CurrentVBaseOffset/8; - - if (MorallyVirtual) { - GlobalDecl UGD = getUnique(GD); - const CXXMethodDecl *UMD = cast(UGD.getDecl()); - - assert(UMD && "final overrider not found"); - - Index_t &idx = VCall[UMD]; - // Allocate the first one, after that, we reuse the previous one. - if (idx == 0) { - VCallOffsetForVCall[UGD] = Offset/8; - NonVirtualOffset[UMD] = Offset/8 - CurrentVBaseOffset/8; - idx = VCalls.size()+1; - VCalls.push_back(Offset/8 - CurrentVBaseOffset/8); - D1(printf(" vcall for %s at %d with delta %d\n", - dyn_cast(GD.getDecl())->getNameAsString().c_str(), - (int)-VCalls.size()-3, (int)VCalls[idx-1])); - } - } - } - - void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual, - Index_t Offset, int64_t CurrentVBaseOffset) { - for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; - ++mi) { - const CXXMethodDecl *MD = *mi; - if (!MD->isVirtual()) - continue; - - if (const CXXDestructorDecl *DD = dyn_cast(MD)) { - // For destructors, add both the complete and the deleting destructor - // to the vtable. - AddMethod(GlobalDecl(DD, Dtor_Complete), MorallyVirtual, Offset, - CurrentVBaseOffset); - AddMethod(GlobalDecl(DD, Dtor_Deleting), MorallyVirtual, Offset, - CurrentVBaseOffset); - } else - AddMethod(MD, MorallyVirtual, Offset, CurrentVBaseOffset); - } - } - - void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout, - const CXXRecordDecl *PrimaryBase, - bool PrimaryBaseWasVirtual, bool MorallyVirtual, - int64_t Offset, int64_t CurrentVBaseOffset, - Path_t *Path) { - Path->push_back(std::make_pair(RD, Offset)); - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - if (i->isVirtual()) - continue; - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - uint64_t o = Offset + Layout.getBaseClassOffset(Base); - StartNewTable(); - GenerateVtableForBase(Base, o, MorallyVirtual, false, - true, Base == PrimaryBase && !PrimaryBaseWasVirtual, - CurrentVBaseOffset, Path); - } - Path->pop_back(); - } - -// #define D(X) do { X; } while (0) -#define D(X) - - void insertVCalls(int InsertionPoint) { - D1(printf("============= combining vbase/vcall\n")); - D(VCalls.insert(VCalls.begin(), 673)); - D(VCalls.push_back(672)); - - VtableComponents.insert(VtableComponents.begin() + InsertionPoint, - VCalls.size(), 0); - if (BuildVtable) { - // The vcalls come first... - for (std::vector::reverse_iterator i = VCalls.rbegin(), - e = VCalls.rend(); - i != e; ++i) - VtableComponents[InsertionPoint++] = wrap((0?600:0) + *i); - } - VCalls.clear(); - VCall.clear(); - VCallOffsetForVCall.clear(); - VCallOffset.clear(); - NonVirtualOffset.clear(); - } - - void AddAddressPoints(const CXXRecordDecl *RD, uint64_t Offset, - Index_t AddressPoint) { - D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString(), - LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint)); - subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint; - AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint; - - // Now also add the address point for all our primary bases. - while (1) { - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - RD = Layout.getPrimaryBase(); - const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); - // FIXME: Double check this. - if (RD == 0) - break; - if (PrimaryBaseWasVirtual && - BLayout.getVBaseClassOffset(RD) != Offset) - break; - D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString(), - LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint)); - subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint; - AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint; - } - } - - - void FinishGenerateVtable(const CXXRecordDecl *RD, - const ASTRecordLayout &Layout, - const CXXRecordDecl *PrimaryBase, - bool ForNPNVBases, bool WasPrimaryBase, - bool PrimaryBaseWasVirtual, - bool MorallyVirtual, int64_t Offset, - bool ForVirtualBase, int64_t CurrentVBaseOffset, - Path_t *Path) { - bool alloc = false; - if (Path == 0) { - alloc = true; - Path = new Path_t; - } - - StartNewTable(); - extra = 0; - Index_t AddressPoint = 0; - int VCallInsertionPoint = 0; - if (!ForNPNVBases || !WasPrimaryBase) { - bool DeferVCalls = MorallyVirtual || ForVirtualBase; - VCallInsertionPoint = VtableComponents.size(); - if (!DeferVCalls) { - insertVCalls(VCallInsertionPoint); - } else - // FIXME: just for extra, or for all uses of VCalls.size post this? - extra = -VCalls.size(); - - // Add the offset to top. - VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0); - - // Add the RTTI information. - VtableComponents.push_back(rtti); - - AddressPoint = VtableComponents.size(); - - AppendMethodsToVtable(); - } - - // and then the non-virtual bases. - NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual, - MorallyVirtual, Offset, CurrentVBaseOffset, Path); - - if (ForVirtualBase) { - // FIXME: We're adding to VCalls in callers, we need to do the overrides - // in the inner part, so that we know the complete set of vcalls during - // the build and don't have to insert into methods. Saving out the - // AddressPoint here, would need to be fixed, if we didn't do that. Also - // retroactively adding vcalls for overrides later wind up in the wrong - // place, the vcall slot has to be alloted during the walk of the base - // when the function is first introduces. - AddressPoint += VCalls.size(); - insertVCalls(VCallInsertionPoint); - } - - if (!ForNPNVBases || !WasPrimaryBase) - AddAddressPoints(RD, Offset, AddressPoint); - - if (alloc) { - delete Path; - } - } - - void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset, - bool updateVBIndex, Index_t current_vbindex, - int64_t CurrentVBaseOffset) { - if (!RD->isDynamicClass()) - return; - - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); - - // vtables are composed from the chain of primaries. - if (PrimaryBase && !PrimaryBaseWasVirtual) { - D1(printf(" doing primaries for %s most derived %s\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); - Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset, - updateVBIndex, current_vbindex, CurrentVBaseOffset); - } - - D1(printf(" doing vcall entries for %s most derived %s\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); - - // And add the virtuals for the class to the primary vtable. - AddMethods(RD, MorallyVirtual, Offset, CurrentVBaseOffset); - } - - void VBPrimaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset, - bool updateVBIndex, Index_t current_vbindex, - bool RDisVirtualBase, int64_t CurrentVBaseOffset, - bool bottom) { - if (!RD->isDynamicClass()) - return; - - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); - - // vtables are composed from the chain of primaries. - if (PrimaryBase) { - int BaseCurrentVBaseOffset = CurrentVBaseOffset; - if (PrimaryBaseWasVirtual) { - IndirectPrimary.insert(PrimaryBase); - BaseCurrentVBaseOffset = BLayout.getVBaseClassOffset(PrimaryBase); - } - - D1(printf(" doing primaries for %s most derived %s\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); - - VBPrimaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset, - updateVBIndex, current_vbindex, PrimaryBaseWasVirtual, - BaseCurrentVBaseOffset, false); - } - - D1(printf(" doing vbase entries for %s most derived %s\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); - GenerateVBaseOffsets(RD, Offset, updateVBIndex, current_vbindex); - - if (RDisVirtualBase || bottom) { - Primaries(RD, MorallyVirtual, Offset, updateVBIndex, current_vbindex, - CurrentVBaseOffset); - } - } - - void GenerateVtableForBase(const CXXRecordDecl *RD, int64_t Offset = 0, - bool MorallyVirtual = false, - bool ForVirtualBase = false, - bool ForNPNVBases = false, - bool WasPrimaryBase = true, - int CurrentVBaseOffset = 0, - Path_t *Path = 0) { - if (!RD->isDynamicClass()) - return; - - // Construction vtable don't need parts that have no virtual bases and - // aren't morally virtual. - if ((LayoutClass != MostDerivedClass) && - RD->getNumVBases() == 0 && !MorallyVirtual) - return; - - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); - - extra = 0; - D1(printf("building entries for base %s most derived %s\n", - RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); - - if (ForVirtualBase) - extra = VCalls.size(); - - if (!ForNPNVBases || !WasPrimaryBase) { - VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0, - ForVirtualBase, CurrentVBaseOffset, true); - - if (Path) - OverrideMethods(Path, MorallyVirtual, Offset, CurrentVBaseOffset); - } - - FinishGenerateVtable(RD, Layout, PrimaryBase, ForNPNVBases, WasPrimaryBase, - PrimaryBaseWasVirtual, MorallyVirtual, Offset, - ForVirtualBase, CurrentVBaseOffset, Path); - } - - void GenerateVtableForVBases(const CXXRecordDecl *RD, - int64_t Offset = 0, - Path_t *Path = 0) { - bool alloc = false; - if (Path == 0) { - alloc = true; - Path = new Path_t; - } - // FIXME: We also need to override using all paths to a virtual base, - // right now, we just process the first path - Path->push_back(std::make_pair(RD, Offset)); - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - if (i->isVirtual() && !IndirectPrimary.count(Base)) { - // Mark it so we don't output it twice. - IndirectPrimary.insert(Base); - StartNewTable(); - VCall.clear(); - int64_t BaseOffset = BLayout.getVBaseClassOffset(Base); - int64_t CurrentVBaseOffset = BaseOffset; - D1(printf("vtable %s virtual base %s\n", - MostDerivedClass->getNameAsCString(), Base->getNameAsCString())); - GenerateVtableForBase(Base, BaseOffset, true, true, false, - true, CurrentVBaseOffset, Path); - } - int64_t BaseOffset; - if (i->isVirtual()) - BaseOffset = BLayout.getVBaseClassOffset(Base); - else { - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - BaseOffset = Offset + Layout.getBaseClassOffset(Base); - } - - if (Base->getNumVBases()) { - GenerateVtableForVBases(Base, BaseOffset, Path); - } - } - Path->pop_back(); - if (alloc) - delete Path; - } -}; -} // end anonymous namespace - -bool OldVtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual, - Index_t OverrideOffset, Index_t Offset, - int64_t CurrentVBaseOffset) { - const CXXMethodDecl *MD = cast(GD.getDecl()); - - const bool isPure = MD->isPure(); - - // FIXME: Should OverrideOffset's be Offset? - - for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(), - e = MD->end_overridden_methods(); mi != e; ++mi) { - GlobalDecl OGD; - GlobalDecl OGD2; - - const CXXMethodDecl *OMD = *mi; - if (const CXXDestructorDecl *DD = dyn_cast(OMD)) - OGD = GlobalDecl(DD, GD.getDtorType()); - else - OGD = OMD; - - // Check whether this is the method being overridden in this section of - // the vtable. - uint64_t Index; - if (!Methods.getIndex(OGD, Index)) - continue; - - OGD2 = OGD; - - // Get the original method, which we should be computing thunks, etc, - // against. - OGD = Methods.getOrigMethod(Index); - OMD = cast(OGD.getDecl()); - - QualType ReturnType = - MD->getType()->getAs()->getResultType(); - QualType OverriddenReturnType = - OMD->getType()->getAs()->getResultType(); - - // Check if we need a return type adjustment. - if (!ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD, - OMD).isEmpty()) { - CanQualType &BaseReturnType = BaseReturnTypes[Index]; - - // Insert the base return type. - if (BaseReturnType.isNull()) - BaseReturnType = - CGM.getContext().getCanonicalType(OverriddenReturnType); - } - - Methods.OverrideMethod(OGD, GD); - - GlobalDecl UGD = getUnique(GD); - const CXXMethodDecl *UMD = cast(UGD.getDecl()); - assert(UGD.getDecl() && "unique overrider not found"); - assert(UGD == getUnique(OGD) && "unique overrider not unique"); - - ThisAdjustments.erase(Index); - if (MorallyVirtual || VCall.count(UMD)) { - - Index_t &idx = VCall[UMD]; - if (idx == 0) { - VCallOffset[GD] = VCallOffset[OGD]; - // NonVirtualOffset[UMD] = CurrentVBaseOffset/8 - OverrideOffset/8; - NonVirtualOffset[UMD] = VCallOffset[OGD]; - VCallOffsetForVCall[UMD] = OverrideOffset/8; - idx = VCalls.size()+1; - VCalls.push_back(OverrideOffset/8 - CurrentVBaseOffset/8); - D1(printf(" vcall for %s at %d with delta %d most derived %s\n", - MD->getNameAsString().c_str(), (int)-idx-3, - (int)VCalls[idx-1], MostDerivedClass->getNameAsCString())); - } else { - VCallOffset[GD] = NonVirtualOffset[UMD]; - VCalls[idx-1] = -VCallOffsetForVCall[UGD] + OverrideOffset/8; - D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n", - MD->getNameAsString().c_str(), (int)-idx-3, - (int)VCalls[idx-1], MostDerivedClass->getNameAsCString())); - } - int64_t NonVirtualAdjustment = -VCallOffset[OGD]; - QualType DerivedType = MD->getThisType(CGM.getContext()); - QualType BaseType = cast(OGD.getDecl())->getThisType(CGM.getContext()); - int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8); - if (NonVirtualAdjustment2 != NonVirtualAdjustment) { - NonVirtualAdjustment = NonVirtualAdjustment2; - } - int64_t VirtualAdjustment = - -((idx + extra + 2) * LLVMPointerWidth / 8); - - // Optimize out virtual adjustments of 0. - if (VCalls[idx-1] == 0) - VirtualAdjustment = 0; - - ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, - VirtualAdjustment); - - if (!isPure && !ThisAdjustment.isEmpty()) { - ThisAdjustments[Index] = ThisAdjustment; - SavedAdjustments.push_back( - std::make_pair(GD, std::make_pair(OGD, ThisAdjustment))); - } - return true; - } - - VCallOffset[GD] = VCallOffset[OGD2] - OverrideOffset/8; - - int64_t NonVirtualAdjustment = -VCallOffset[GD]; - QualType DerivedType = MD->getThisType(CGM.getContext()); - QualType BaseType = cast(OGD.getDecl())->getThisType(CGM.getContext()); - int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8); - if (NonVirtualAdjustment2 != NonVirtualAdjustment) { - NonVirtualAdjustment = NonVirtualAdjustment2; - } - - if (NonVirtualAdjustment) { - ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, 0); - - if (!isPure) { - ThisAdjustments[Index] = ThisAdjustment; - SavedAdjustments.push_back( - std::make_pair(GD, std::make_pair(OGD, ThisAdjustment))); - } - } - return true; - } - - return false; -} - -void OldVtableBuilder::AppendMethodsToVtable() { - if (!BuildVtable) { - VtableComponents.insert(VtableComponents.end(), Methods.size(), - (llvm::Constant *)0); - ThisAdjustments.clear(); - BaseReturnTypes.clear(); - Methods.clear(); - return; - } - - // Reserve room in the vtable for our new methods. - VtableComponents.reserve(VtableComponents.size() + Methods.size()); - - for (unsigned i = 0, e = Methods.size(); i != e; ++i) { - GlobalDecl GD = Methods[i]; - const CXXMethodDecl *MD = cast(GD.getDecl()); - - // Get the 'this' pointer adjustment. - ThunkAdjustment ThisAdjustment = ThisAdjustments.lookup(i); - - // Construct the return type adjustment. - ThunkAdjustment ReturnAdjustment; - - QualType BaseReturnType = BaseReturnTypes.lookup(i); - if (!BaseReturnType.isNull() && !MD->isPure()) { - QualType DerivedType = - MD->getType()->getAs()->getResultType(); - - int64_t NonVirtualAdjustment = - getNVOffset(BaseReturnType, DerivedType) / 8; - - int64_t VirtualAdjustment = - getVbaseOffset(BaseReturnType, DerivedType); - - ReturnAdjustment = ThunkAdjustment(NonVirtualAdjustment, - VirtualAdjustment); - } - - llvm::Constant *Method = 0; - if (!ReturnAdjustment.isEmpty()) { - // Build a covariant thunk. - CovariantThunkAdjustment Adjustment(ThisAdjustment, ReturnAdjustment); - Method = wrap(CGM.GetAddrOfCovariantThunk(GD, Adjustment)); - } else if (!ThisAdjustment.isEmpty()) { - // Build a "regular" thunk. - Method = wrap(CGM.GetAddrOfThunk(GD, ThisAdjustment)); - } else if (MD->isPure()) { - // We have a pure virtual method. - Method = getPureVirtualFn(); - } else { - // We have a good old regular method. - Method = WrapAddrOf(GD); - } - - // Add the method to the vtable. - VtableComponents.push_back(Method); - } - - - ThisAdjustments.clear(); - BaseReturnTypes.clear(); - - Methods.clear(); -} - void CodeGenVTables::ComputeMethodVtableIndices(const CXXRecordDecl *RD) { // Itanium C++ ABI 2.5.2: @@ -3625,89 +2550,6 @@ CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { return AddressPoint; } -const CodeGenVTables::AddrSubMap_t & -CodeGenVTables::getAddressPoints(const CXXRecordDecl *RD) { - if (!OldAddressPoints[RD]) { - OldVtableBuilder::AddressPointsMapTy AddressPoints; - OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints); - - b.GenerateVtableForBase(RD, 0); - b.GenerateVtableForVBases(RD, 0); - } - - return *(*OldAddressPoints[RD])[RD]; -} - -llvm::GlobalVariable * -CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, - bool GenerateDefinition, - const CXXRecordDecl *LayoutClass, - const CXXRecordDecl *RD, uint64_t Offset, - bool IsVirtual, - llvm::DenseMap &AddressPoints) { - if (GenerateDefinition) { - if (LayoutClass == RD) { - assert(!IsVirtual && - "Can only have a virtual base in construction vtables!"); - assert(!Offset && - "Can only have a base offset in construction vtables!"); - } - - VtableBuilder Builder(*this, RD, Offset, - /*MostDerivedClassIsVirtual=*/IsVirtual, - LayoutClass); - - if (CGM.getLangOptions().DumpVtableLayouts) - Builder.dumpLayout(llvm::errs()); - } - - llvm::SmallString<256> OutName; - if (LayoutClass != RD) - CGM.getMangleContext().mangleCXXCtorVtable(LayoutClass, Offset / 8, - RD, OutName); - else - CGM.getMangleContext().mangleCXXVtable(RD, OutName); - llvm::StringRef Name = OutName.str(); - - llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); - if (GV == 0 || GV->isDeclaration()) { - OldVtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition, - AddressPoints); - - D1(printf("vtable %s\n", RD->getNameAsCString())); - // First comes the vtables for all the non-virtual bases... - b.GenerateVtableForBase(RD, Offset); - - // then the vtables for all the virtual bases. - b.GenerateVtableForVBases(RD, Offset); - - llvm::Constant *Init = 0; - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); - llvm::ArrayType *ArrayType = - llvm::ArrayType::get(Int8PtrTy, b.getVtableComponents().size()); - - if (GenerateDefinition) - Init = llvm::ConstantArray::get(ArrayType, &b.getVtableComponents()[0], - b.getVtableComponents().size()); - - llvm::GlobalVariable *OGV = GV; - - GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, - /*isConstant=*/true, Linkage, Init, Name); - CGM.setGlobalVisibility(GV, RD); - - if (OGV) { - GV->takeName(OGV); - llvm::Constant *NewPtr = - llvm::ConstantExpr::getBitCast(GV, OGV->getType()); - OGV->replaceAllUsesWith(NewPtr); - OGV->eraseFromParent(); - } - } - - return GV; -} - llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk) { const CXXMethodDecl *MD = cast(GD.getDecl()); diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index 714b7c88b5..ca874f8599 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -113,42 +113,6 @@ struct ThunkInfo { bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); } }; -/// ThunkAdjustment - Virtual and non-virtual adjustment for thunks. -class ThunkAdjustment { -public: - ThunkAdjustment(int64_t NonVirtual, int64_t Virtual) - : NonVirtual(NonVirtual), - Virtual(Virtual) { } - - ThunkAdjustment() - : NonVirtual(0), Virtual(0) { } - - // isEmpty - Return whether this thunk adjustment is empty. - bool isEmpty() const { - return NonVirtual == 0 && Virtual == 0; - } - - /// NonVirtual - The non-virtual adjustment. - int64_t NonVirtual; - - /// Virtual - The virtual adjustment. - int64_t Virtual; -}; - -/// CovariantThunkAdjustment - Adjustment of the 'this' pointer and the -/// return pointer for covariant thunks. -class CovariantThunkAdjustment { -public: - CovariantThunkAdjustment(const ThunkAdjustment &ThisAdjustment, - const ThunkAdjustment &ReturnAdjustment) - : ThisAdjustment(ThisAdjustment), ReturnAdjustment(ReturnAdjustment) { } - - CovariantThunkAdjustment() { } - - ThunkAdjustment ThisAdjustment; - ThunkAdjustment ReturnAdjustment; -}; - // BaseSubobject - Uniquely identifies a direct or indirect base class. // Stores both the base class decl and the offset from the most derived class to // the base class. @@ -215,23 +179,8 @@ namespace clang { namespace CodeGen { class CodeGenVTables { -public: - typedef std::vector > - AdjustmentVectorTy; - - typedef std::pair CtorVtable_t; - typedef llvm::DenseMap AddrSubMap_t; - typedef llvm::DenseMap AddrMap_t; - - const CodeGenVTables::AddrSubMap_t& getAddressPoints(const CXXRecordDecl *RD); - - // FIXME: Remove this. - llvm::DenseMap OldAddressPoints; - -private: CodeGenModule &CGM; - /// MethodVtableIndices - Contains the index (relative to the vtable address /// point) where the function pointer for a virtual function is stored. typedef llvm::DenseMap MethodVtableIndicesTy; @@ -318,12 +267,6 @@ private: uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); void ComputeMethodVtableIndices(const CXXRecordDecl *RD); - - llvm::GlobalVariable * - GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, - bool GenerateDefinition, const CXXRecordDecl *LayoutClass, - const CXXRecordDecl *RD, uint64_t Offset, bool IsVirtual, - llvm::DenseMap &AddressPoints); llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index e4b0054650..941dca82ab 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -228,11 +228,6 @@ public: /// GetAddrOfThunk - Get the address of the thunk for the given global decl. llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk); - llvm::Constant *GetAddrOfThunk(GlobalDecl GD, - const ThunkAdjustment &ThisAdjustment); - llvm::Constant *GetAddrOfCovariantThunk(GlobalDecl GD, - const CovariantThunkAdjustment &ThisAdjustment); - /// GetWeakRefReference - Get a reference to the target of VD. llvm::Constant *GetWeakRefReference(const ValueDecl *VD); @@ -242,11 +237,6 @@ public: GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl); - /// ComputeThunkAdjustment - Returns the two parts required to compute the - /// offset for an object. - ThunkAdjustment ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl); - /// GetStringForStringLiteral - Return the appropriate bytes for a string /// literal, properly padded to match the literal type. If only the address of /// a constant is needed consider using GetAddrOfConstantStringLiteral. diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 37052a5462..9fdb12e15e 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -102,7 +102,6 @@ public: llvm::raw_svector_ostream &getStream() { return Out; } void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z"); - void mangleCallOffset(const ThunkAdjustment &Adjustment); void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(int64_t Number); void mangleFunctionEncoding(const FunctionDecl *FD); @@ -440,10 +439,6 @@ void CXXNameMangler::mangleNumber(int64_t Number) { Out << Number; } -void CXXNameMangler::mangleCallOffset(const ThunkAdjustment &Adjustment) { - mangleCallOffset(Adjustment.NonVirtual, Adjustment.Virtual); -} - void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) { // ::= h _ // ::= v _ @@ -1872,22 +1867,6 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, Mangler.mangle(D); } -/// \brief Mangles the a thunk with the offset n for the declaration D and -/// emits that name to the given output stream. -void MangleContext::mangleThunk(const FunctionDecl *FD, - const ThunkAdjustment &ThisAdjustment, - llvm::SmallVectorImpl &Res) { - assert(!isa(FD) && - "Use mangleCXXDtor for destructor decls!"); - - // ::= T - // # base is the nominal target function of thunk - CXXNameMangler Mangler(*this, Res); - Mangler.getStream() << "_ZT"; - Mangler.mangleCallOffset(ThisAdjustment); - Mangler.mangleFunctionEncoding(FD); -} - void MangleContext::mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, llvm::SmallVectorImpl &Res) { @@ -1934,38 +1913,6 @@ MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, Mangler.mangleFunctionEncoding(DD); } -void MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *D, - CXXDtorType Type, - const ThunkAdjustment &ThisAdjustment, - llvm::SmallVectorImpl &Res) { - // ::= T - // # base is the nominal target function of thunk - CXXNameMangler Mangler(*this, Res, D, Type); - Mangler.getStream() << "_ZT"; - Mangler.mangleCallOffset(ThisAdjustment); - Mangler.mangleFunctionEncoding(D); -} - -/// \brief Mangles the a covariant thunk for the declaration D and emits that -/// name to the given output stream. -void -MangleContext::mangleCovariantThunk(const FunctionDecl *FD, - const CovariantThunkAdjustment& Adjustment, - llvm::SmallVectorImpl &Res) { - assert(!isa(FD) && - "No such thing as a covariant thunk for a destructor!"); - - // ::= Tc - // # base is the nominal target function of thunk - // # first call-offset is 'this' adjustment - // # second call-offset is result adjustment - CXXNameMangler Mangler(*this, Res); - Mangler.getStream() << "_ZTc"; - Mangler.mangleCallOffset(Adjustment.ThisAdjustment); - Mangler.mangleCallOffset(Adjustment.ReturnAdjustment); - Mangler.mangleFunctionEncoding(FD); -} - /// mangleGuardVariable - Returns the mangled name for a guard variable /// for the passed in VarDecl. void MangleContext::mangleGuardVariable(const VarDecl *D, diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h index 34b2ab46bb..91a5e97b69 100644 --- a/lib/CodeGen/Mangle.h +++ b/lib/CodeGen/Mangle.h @@ -36,8 +36,6 @@ namespace clang { namespace CodeGen { struct ThisAdjustment; struct ThunkInfo; - class CovariantThunkAdjustment; - class ThunkAdjustment; /// MangleBuffer - a convenient class for storing a name which is /// either the result of a mangling or is a constant string with @@ -94,21 +92,12 @@ public: bool shouldMangleDeclName(const NamedDecl *D); void mangleName(const NamedDecl *D, llvm::SmallVectorImpl &); - void mangleThunk(const FunctionDecl *FD, - const ThunkAdjustment &ThisAdjustment, - llvm::SmallVectorImpl &); void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, llvm::SmallVectorImpl &); - void mangleCXXDtorThunk(const CXXDestructorDecl *D, CXXDtorType Type, - const ThunkAdjustment &ThisAdjustment, - llvm::SmallVectorImpl &); void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, llvm::SmallVectorImpl &); - void mangleCovariantThunk(const FunctionDecl *FD, - const CovariantThunkAdjustment& Adjustment, - llvm::SmallVectorImpl &); void mangleGuardVariable(const VarDecl *D, llvm::SmallVectorImpl &); void mangleCXXVtable(const CXXRecordDecl *RD, llvm::SmallVectorImpl &); void mangleCXXVTT(const CXXRecordDecl *RD, llvm::SmallVectorImpl &);