Reland (2x) r230314, "Fix codegen for virtual methods that are (re-) exported from multiple modules."

This reverts commits r230477 and r230478.

llvm-svn: 230526
This commit is contained in:
Reid Kleckner 2015-02-25 19:17:48 +00:00
parent 8b6d034cab
commit 1cbd9aa96d
6 changed files with 70 additions and 0 deletions

View File

@ -411,6 +411,7 @@ 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());
@ -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,

View File

@ -0,0 +1,8 @@
#ifndef A_H
#define A_H
struct A {
virtual void x();
};
#endif

View File

@ -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

View File

@ -0,0 +1,6 @@
#ifndef C_H
#define C_H
#include "a.h"
#endif

View File

@ -0,0 +1,11 @@
module "a" {
textual header "a.h"
}
module "b" {
header "b.h"
}
module "c" {
header "c.h"
}

View File

@ -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);
}