Index: include/clang/AST/VTableBuilder.h =================================================================== --- include/clang/AST/VTableBuilder.h +++ include/clang/AST/VTableBuilder.h @@ -123,29 +123,39 @@ const CXXRecordDecl *getRTTIDecl() const { assert(getKind() == CK_RTTI && "Invalid component kind!"); - return reinterpret_cast(getPointer()); } const CXXMethodDecl *getFunctionDecl() const { - assert(getKind() == CK_FunctionPointer); - + assert(isFunctionPointerKind() && "Invalid component kind!"); + if (isDestructorKind()) + return getDestructorDecl(); return reinterpret_cast(getPointer()); } const CXXDestructorDecl *getDestructorDecl() const { - assert((getKind() == CK_CompleteDtorPointer || - getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); - + assert(isDestructorKind() && "Invalid component kind!"); return reinterpret_cast(getPointer()); } const CXXMethodDecl *getUnusedFunctionDecl() const { - assert(getKind() == CK_UnusedFunctionPointer); - + assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!"); return reinterpret_cast(getPointer()); } + bool isDestructorKind() const { + return getKind() == CK_CompleteDtorPointer || + getKind() == CK_DeletingDtorPointer; + } + + bool isUsedFunctionPointerKind() const { + return getKind() == CK_FunctionPointer || isDestructorKind(); + } + + bool isFunctionPointerKind() const { + return isUsedFunctionPointerKind() || getKind() == CK_UnusedFunctionPointer; + } + private: VTableComponent(Kind ComponentKind, CharUnits Offset) { assert((ComponentKind == CK_VCallOffset || @@ -158,12 +168,8 @@ } VTableComponent(Kind ComponentKind, uintptr_t Ptr) { - assert((ComponentKind == CK_RTTI || - ComponentKind == CK_FunctionPointer || - ComponentKind == CK_CompleteDtorPointer || - ComponentKind == CK_DeletingDtorPointer || - ComponentKind == CK_UnusedFunctionPointer) && - "Invalid component kind!"); + assert((ComponentKind == CK_RTTI || isFunctionPointerKind()) && + "Invalid component kind!"); assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); @@ -178,11 +184,7 @@ } uintptr_t getPointer() const { - assert((getKind() == CK_RTTI || - getKind() == CK_FunctionPointer || - getKind() == CK_CompleteDtorPointer || - getKind() == CK_DeletingDtorPointer || - getKind() == CK_UnusedFunctionPointer) && + assert((getKind() == CK_RTTI || isFunctionPointerKind()) && "Invalid component kind!"); return static_cast(Value & ~7ULL); Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -320,17 +320,15 @@ void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override; private: - /// Checks if function has any virtual inline function. - bool hasAnyVirtualInlineFunction(const CXXRecordDecl *RD) const { + bool hasAnyUsedVirtualInlineFunction(const CXXRecordDecl *RD) const { const auto &VtableLayout = CGM.getItaniumVTableContext().getVTableLayout(RD); for (const auto &VtableComponent : VtableLayout.vtable_components()) { - if (VtableComponent.getKind() != - VTableComponent::Kind::CK_FunctionPointer) + if (!VtableComponent.isUsedFunctionPointerKind()) continue; - const auto &Method = VtableComponent.getFunctionDecl(); + const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); if (Method->getCanonicalDecl()->isInlined()) return true; } @@ -1536,7 +1534,7 @@ // then we are safe to emit available_externally copy of vtable. // FIXME we can still emit a copy of the vtable if we // can emit definition of the inline functions. - return !hasAnyVirtualInlineFunction(RD); + return !hasAnyUsedVirtualInlineFunction(RD); } static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, llvm::Value *Ptr,