From 22a69bcb1a98ffa277cefefd0a5f9d62bbeb7109 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 25 Feb 2015 02:19:56 +0000 Subject: [PATCH] Reland r230314 "Fix codegen for virtual methods that are (re-) exported from multiple modules." This reverts the revert from commit r230406. The changes in r230445 and r230446 make the test pass on Windows now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@230448 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/VTableBuilder.cpp | 6 ++++- test/Modules/Inputs/merge-vtable-codegen/a.h | 8 +++++++ test/Modules/Inputs/merge-vtable-codegen/b.h | 17 +++++++++++++ test/Modules/Inputs/merge-vtable-codegen/c.h | 6 +++++ .../merge-vtable-codegen.modulemap | 11 +++++++++ test/Modules/merge-vtable-codegen.cpp | 24 +++++++++++++++++++ 6 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 test/Modules/Inputs/merge-vtable-codegen/a.h create mode 100644 test/Modules/Inputs/merge-vtable-codegen/b.h create mode 100644 test/Modules/Inputs/merge-vtable-codegen/c.h create mode 100644 test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap create mode 100644 test/Modules/merge-vtable-codegen.cpp diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 8632ff81fa..4e7715d7f0 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -411,7 +411,8 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, for (const auto *MD : RD->methods()) { if (!MD->isVirtual()) continue; - + MD = MD->getCanonicalDecl(); + OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset()); Out << " "; @@ -695,6 +696,7 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, for (const auto *MD : RD->methods()) { if (!MD->isVirtual()) continue; + MD = MD->getCanonicalDecl(); CharUnits OffsetOffset = getCurrentOffsetOffset(); @@ -1514,6 +1516,7 @@ void ItaniumVTableBuilder::AddMethods( for (const auto *MD : RD->methods()) { if (!MD->isVirtual()) continue; + MD = MD->getCanonicalDecl(); // Get the final overrider. FinalOverriders::OverriderInfo Overrider = @@ -2196,6 +2199,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { // We only want virtual member functions. if (!MD->isVirtual()) continue; + MD = MD->getCanonicalDecl(); std::string MethodName = PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, diff --git a/test/Modules/Inputs/merge-vtable-codegen/a.h b/test/Modules/Inputs/merge-vtable-codegen/a.h new file mode 100644 index 0000000000..c2885379aa --- /dev/null +++ b/test/Modules/Inputs/merge-vtable-codegen/a.h @@ -0,0 +1,8 @@ +#ifndef A_H +#define A_H + +struct A { + virtual void x(); +}; + +#endif diff --git a/test/Modules/Inputs/merge-vtable-codegen/b.h b/test/Modules/Inputs/merge-vtable-codegen/b.h new file mode 100644 index 0000000000..770e46077f --- /dev/null +++ b/test/Modules/Inputs/merge-vtable-codegen/b.h @@ -0,0 +1,17 @@ +#ifndef B_H +#define B_H + +#include "a.h" + +class B : virtual public A { + virtual void x() {} +}; + +void b(A* p) { + p->x(); + // Instantiating a class that virtually inherits 'A' + // triggers calculation of the vtable offsets in 'A'. + B b; +} + +#endif diff --git a/test/Modules/Inputs/merge-vtable-codegen/c.h b/test/Modules/Inputs/merge-vtable-codegen/c.h new file mode 100644 index 0000000000..40cbbb047c --- /dev/null +++ b/test/Modules/Inputs/merge-vtable-codegen/c.h @@ -0,0 +1,6 @@ +#ifndef C_H +#define C_H + +#include "a.h" + +#endif diff --git a/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap b/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap new file mode 100644 index 0000000000..1edaa07101 --- /dev/null +++ b/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap @@ -0,0 +1,11 @@ +module "a" { + textual header "a.h" +} + +module "b" { + header "b.h" +} + +module "c" { + header "c.h" +} diff --git a/test/Modules/merge-vtable-codegen.cpp b/test/Modules/merge-vtable-codegen.cpp new file mode 100644 index 0000000000..7372073891 --- /dev/null +++ b/test/Modules/merge-vtable-codegen.cpp @@ -0,0 +1,24 @@ +// RUN: rm -rf %t + +// First, build two modules that both re-export the same header. +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=b -o %t/b.pcm -fmodule-maps \ +// RUN: -emit-module %S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I %S/Inputs/merge-vtable-codegen +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=c -o %t/c.pcm -fmodule-maps \ +// RUN: -emit-module %S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I %S/Inputs/merge-vtable-codegen + +// Use the two modules in a single compile. +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/b.pcm -fmodule-file=%t/c.pcm \ +// RUN: -fmodule-map-file=%S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -emit-llvm -o %t/test.o %s + +// Note that order is important: +// Module 'c' just reexports A, while module 'b' defines a method that uses a +// virtual method of A. +#include "Inputs/merge-vtable-codegen/c.h" +#include "Inputs/merge-vtable-codegen/b.h" + +void t() { + b(nullptr); +} -- 2.40.0