diff --git a/clang/include/clang/AST/VTableBuilder.h b/clang/include/clang/AST/VTableBuilder.h --- a/clang/include/clang/AST/VTableBuilder.h +++ b/clang/include/clang/AST/VTableBuilder.h @@ -371,7 +371,17 @@ void computeVTableRelatedInformation(const CXXRecordDecl *RD) override; public: - ItaniumVTableContext(ASTContext &Context); + enum VTableComponentLayout { + /// Components in the vtable are pointers to other structs/functions. + Pointer, + + /// Components in the vtable are relative offsets between the vtable and the + /// other structs/functions. + Relative, + }; + + ItaniumVTableContext(ASTContext &Context, + VTableComponentLayout ComponentLayout = Pointer); ~ItaniumVTableContext() override; const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { @@ -402,6 +412,16 @@ static bool classof(const VTableContextBase *VT) { return !VT->isMicrosoft(); } + + VTableComponentLayout getVTableComponentLayout() const { + return ComponentLayout; + } + + bool isPointerLayout() const { return ComponentLayout == Pointer; } + bool isRelativeLayout() const { return ComponentLayout == Relative; } + +private: + VTableComponentLayout ComponentLayout; }; /// Holds information about the inheritance path to a virtual base or function diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -10390,6 +10390,8 @@ if (Target->getCXXABI().isMicrosoft()) VTContext.reset(new MicrosoftVTableContext(*this)); else + // TODO: Specify that we want to use the Relative VTableComponentLayout + // here once we add the option for selecting it for Fuchsia. VTContext.reset(new ItaniumVTableContext(*this)); } return VTContext.get(); diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -2221,8 +2221,9 @@ VTableLayout::~VTableLayout() { } -ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context) - : VTableContextBase(/*MS=*/false) {} +ItaniumVTableContext::ItaniumVTableContext( + ASTContext &Context, VTableComponentLayout ComponentLayout) + : VTableContextBase(/*MS=*/false), ComponentLayout(ComponentLayout) {} ItaniumVTableContext::~ItaniumVTableContext() {} diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -808,6 +808,9 @@ // Create and set the initializer. ConstantInitBuilder builder(CGM); auto components = builder.beginStruct(); + // TODO: Check for a Relative VTableComponentLayout, and call a different + // initializer from CodeGenVTables for this relative layout once it is + // implemented. createVTableInitializer(components, *VTLayout, RTTI); components.finishAndSetAsInitializer(VTable); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1681,6 +1681,9 @@ // Create and set the initializer. ConstantInitBuilder Builder(CGM); auto Components = Builder.beginStruct(); + // TODO: Check for a Relative VTableComponentLayout, and call a different + // initializer from CodeGenVTables for this relative layout once it is + // implemented. CGVT.createVTableInitializer(Components, VTLayout, RTTI); Components.finishAndSetAsInitializer(VTable);