summaryrefslogtreecommitdiffstats
path: root/lib/AST/VTableBuilder.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
committerdim <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
commitc72c57c9e9b69944e3e009cd5e209634839581d3 (patch)
tree4fc2f184c499d106f29a386c452b49e5197bf63d /lib/AST/VTableBuilder.cpp
parent5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff)
downloadFreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip
FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'lib/AST/VTableBuilder.cpp')
-rw-r--r--lib/AST/VTableBuilder.cpp126
1 files changed, 90 insertions, 36 deletions
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 33dad40..f80232f 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdio>
@@ -256,11 +257,9 @@ static BaseOffset ComputeBaseOffset(ASTContext &Context,
const CXXRecordDecl *DerivedRD) {
CXXBasePaths Paths(/*FindAmbiguities=*/false,
/*RecordPaths=*/true, /*DetectVirtual=*/false);
-
- if (!const_cast<CXXRecordDecl *>(DerivedRD)->
- isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) {
+
+ if (!DerivedRD->isDerivedFrom(BaseRD, Paths))
llvm_unreachable("Class must be derived from the passed in base class!");
- }
return ComputeBaseOffset(Context, DerivedRD, Paths.front());
}
@@ -1001,6 +1000,10 @@ public:
dumpLayout(llvm::errs());
}
+ bool isMicrosoftABI() const {
+ return VTables.isMicrosoftABI();
+ }
+
uint64_t getNumThunks() const {
return Thunks.size();
}
@@ -1157,6 +1160,8 @@ void VTableBuilder::ComputeThisAdjustments() {
break;
case VTableComponent::CK_DeletingDtorPointer:
// We've already added the thunk when we saw the complete dtor pointer.
+ // FIXME: check how this works in the Microsoft ABI
+ // while working on the multiple inheritance patch.
continue;
}
@@ -1197,10 +1202,8 @@ VTableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base,
CXXBasePaths Paths(/*FindAmbiguities=*/true,
/*RecordPaths=*/true, /*DetectVirtual=*/true);
- if (!const_cast<CXXRecordDecl *>(DerivedRD)->
- isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) {
+ if (!DerivedRD->isDerivedFrom(BaseRD, Paths))
llvm_unreachable("Class must be derived from the passed in base class!");
- }
// We have to go through all the paths, and see which one leads us to the
// right base subobject.
@@ -1295,9 +1298,15 @@ VTableBuilder::AddMethod(const CXXMethodDecl *MD,
assert(ReturnAdjustment.isEmpty() &&
"Destructor can't have return adjustment!");
- // Add both the complete destructor and the deleting destructor.
- Components.push_back(VTableComponent::MakeCompleteDtor(DD));
- Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+ // FIXME: Should probably add a layer of abstraction for vtable generation.
+ if (!isMicrosoftABI()) {
+ // Add both the complete destructor and the deleting destructor.
+ Components.push_back(VTableComponent::MakeCompleteDtor(DD));
+ Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+ } else {
+ // Add the scalar deleting destructor.
+ Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+ }
} else {
// Add the return adjustment if necessary.
if (!ReturnAdjustment.isEmpty())
@@ -1612,14 +1621,19 @@ VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
if (Base.getBase() == MostDerivedClass)
VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets();
- // Add the offset to top.
- CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
- Components.push_back(
- VTableComponent::MakeOffsetToTop(OffsetToTop));
-
- // Next, add the RTTI.
- Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
-
+ // FIXME: Should probably add a layer of abstraction for vtable generation.
+ if (!isMicrosoftABI()) {
+ // Add the offset to top.
+ CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
+ Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop));
+
+ // Next, add the RTTI.
+ Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+ } else {
+ // FIXME: unclear what to do with RTTI in MS ABI as emitting it anywhere
+ // breaks the vftable layout. Just skip RTTI for now, can't mangle anyway.
+ }
+
uint64_t AddressPoint = Components.size();
// Now go through all virtual member functions and add them.
@@ -1936,6 +1950,8 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) {
Out << DD->getQualifiedNameAsString();
if (IsComplete)
Out << "() [complete]";
+ else if (isMicrosoftABI())
+ Out << "() [scalar deleting]";
else
Out << "() [deleting]";
@@ -2120,10 +2136,16 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) {
MD);
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
- IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Complete))] =
- MethodName + " [complete]";
- IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))] =
- MethodName + " [deleting]";
+ // FIXME: Should add a layer of abstraction for vtable generation.
+ if (!isMicrosoftABI()) {
+ IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Complete))]
+ = MethodName + " [complete]";
+ IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))]
+ = MethodName + " [deleting]";
+ } else {
+ IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))]
+ = MethodName + " [scalar deleting]";
+ }
} else {
IndicesMap[VTables.getMethodVTableIndex(MD)] = MethodName;
}
@@ -2154,12 +2176,14 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents,
const VTableComponent *VTableComponents,
uint64_t NumVTableThunks,
const VTableThunkTy *VTableThunks,
- const AddressPointsMapTy &AddressPoints)
+ const AddressPointsMapTy &AddressPoints,
+ bool IsMicrosoftABI)
: NumVTableComponents(NumVTableComponents),
VTableComponents(new VTableComponent[NumVTableComponents]),
NumVTableThunks(NumVTableThunks),
VTableThunks(new VTableThunkTy[NumVTableThunks]),
- AddressPoints(AddressPoints) {
+ AddressPoints(AddressPoints),
+ IsMicrosoftABI(IsMicrosoftABI) {
std::copy(VTableComponents, VTableComponents+NumVTableComponents,
this->VTableComponents.get());
std::copy(VTableThunks, VTableThunks+NumVTableThunks,
@@ -2168,6 +2192,11 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents,
VTableLayout::~VTableLayout() { }
+VTableContext::VTableContext(ASTContext &Context)
+ : Context(Context),
+ IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+}
+
VTableContext::~VTableContext() {
llvm::DeleteContainerSeconds(VTableLayouts);
}
@@ -2239,12 +2268,18 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
const CXXDestructorDecl *OverriddenDD =
cast<CXXDestructorDecl>(OverriddenMD);
-
- // Add both the complete and deleting entries.
- MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] =
- getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
- MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
- getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+
+ if (!isMicrosoftABI()) {
+ // Add both the complete and deleting entries.
+ MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] =
+ getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
+ MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
+ getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+ } else {
+ // Add the scalar deleting destructor.
+ MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
+ getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+ }
} else {
MethodVTableIndices[MD] = getMethodVTableIndex(OverriddenMD);
}
@@ -2262,11 +2297,16 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
continue;
}
- // Add the complete dtor.
- MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
-
- // Add the deleting dtor.
- MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+ if (!isMicrosoftABI()) {
+ // Add the complete dtor.
+ MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
+
+ // Add the deleting dtor.
+ MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+ } else {
+ // Add the scalar deleting dtor.
+ MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+ }
} else {
// Add the entry.
MethodVTableIndices[MD] = CurrentIndex++;
@@ -2278,6 +2318,11 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
// If a class has an implicitly-defined virtual destructor,
// its entries come after the declared virtual function pointers.
+ if (isMicrosoftABI()) {
+ ErrorUnsupported("implicit virtual destructor in the Microsoft ABI",
+ ImplicitVirtualDtor->getLocation());
+ }
+
// Add the complete dtor.
MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] =
CurrentIndex++;
@@ -2357,7 +2402,8 @@ static VTableLayout *CreateVTableLayout(const VTableBuilder &Builder) {
Builder.vtable_component_begin(),
VTableThunks.size(),
VTableThunks.data(),
- Builder.getAddressPoints());
+ Builder.getAddressPoints(),
+ Builder.isMicrosoftABI());
}
void VTableContext::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
@@ -2397,6 +2443,14 @@ void VTableContext::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
}
}
+void VTableContext::ErrorUnsupported(StringRef Feature,
+ SourceLocation Location) {
+ clang::DiagnosticsEngine &Diags = Context.getDiagnostics();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "v-table layout for %0 is not supported yet");
+ Diags.Report(Context.getFullLoc(Location), DiagID) << Feature;
+}
+
VTableLayout *VTableContext::createConstructionVTableLayout(
const CXXRecordDecl *MostDerivedClass,
CharUnits MostDerivedClassOffset,
OpenPOWER on IntegriCloud