[cfe-commits] r90396 - /cfe/trunk/lib/CodeGen/CGVtable.cpp
Anders Carlsson
andersca at mac.com
Wed Dec 2 18:32:59 PST 2009
Author: andersca
Date: Wed Dec 2 20:32:59 2009
New Revision: 90396
URL: http://llvm.org/viewvc/llvm-project?rev=90396&view=rev
Log:
Delay computing the return adjustments for covariant thunks until when they are added to the vtable.
Modified:
cfe/trunk/lib/CodeGen/CGVtable.cpp
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=90396&r1=90395&r2=90396&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Wed Dec 2 20:32:59 2009
@@ -281,9 +281,20 @@
Thunks.erase(i);
}
-
- CovariantThunkAdjustment Adjustment(ThisAdjustment,
- Thunk.ReturnAdjustment);
+
+ // Construct the return adjustment.
+ QualType DerivedType =
+ MD->getType()->getAs<FunctionType>()->getResultType();
+
+ int64_t NonVirtualAdjustment =
+ getNVOffset(Thunk.ReturnType, DerivedType) / 8;
+
+ int64_t VirtualAdjustment =
+ getVbaseOffset(Thunk.ReturnType, DerivedType);
+
+ ThunkAdjustment ReturnAdjustment(NonVirtualAdjustment, VirtualAdjustment);
+
+ CovariantThunkAdjustment Adjustment(ThisAdjustment, ReturnAdjustment);
submethods[Index] = CGM.BuildCovariantThunk(MD, Extern, Adjustment);
}
CovariantThunks.clear();
@@ -670,6 +681,83 @@
};
} // end anonymous namespace
+/// TypeConversionRequiresAdjustment - Returns whether conversion from a
+/// derived type to a base type requires adjustment.
+static bool
+TypeConversionRequiresAdjustment(ASTContext &Ctx,
+ const CXXRecordDecl *DerivedDecl,
+ const CXXRecordDecl *BaseDecl) {
+ CXXBasePaths Paths(/*FindAmbiguities=*/false,
+ /*RecordPaths=*/true, /*DetectVirtual=*/true);
+ if (!const_cast<CXXRecordDecl *>(DerivedDecl)->
+ isDerivedFrom(const_cast<CXXRecordDecl *>(BaseDecl), Paths)) {
+ assert(false && "Class must be derived from the passed in base class!");
+ return false;
+ }
+
+ // If we found a virtual base we always want to require adjustment.
+ if (Paths.getDetectedVirtual())
+ return true;
+
+ const CXXBasePath &Path = Paths.front();
+
+ for (size_t Start = 0, End = Path.size(); Start != End; ++Start) {
+ const CXXBasePathElement &Element = Path[Start];
+
+ // Check the base class offset.
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Element.Class);
+
+ const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>();
+ const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl());
+
+ if (Layout.getBaseClassOffset(Base) != 0) {
+ // This requires an adjustment.
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool
+TypeConversionRequiresAdjustment(ASTContext &Ctx,
+ QualType DerivedType, QualType BaseType) {
+ // Canonicalize the types.
+ QualType CanDerivedType = Ctx.getCanonicalType(DerivedType);
+ QualType CanBaseType = Ctx.getCanonicalType(BaseType);
+
+ assert(CanDerivedType->getTypeClass() == CanBaseType->getTypeClass() &&
+ "Types must have same type class!");
+
+ if (CanDerivedType == CanBaseType) {
+ // No adjustment needed.
+ return false;
+ }
+
+ if (const ReferenceType *RT = dyn_cast<ReferenceType>(CanDerivedType)) {
+ CanDerivedType = RT->getPointeeType();
+ CanBaseType = cast<ReferenceType>(CanBaseType)->getPointeeType();
+ } else if (const PointerType *PT = dyn_cast<PointerType>(CanDerivedType)) {
+ CanDerivedType = PT->getPointeeType();
+ CanBaseType = cast<PointerType>(CanBaseType)->getPointeeType();
+ } else {
+ assert(false && "Unexpected return type!");
+ }
+
+ if (CanDerivedType == CanBaseType) {
+ // No adjustment needed.
+ return false;
+ }
+
+ const CXXRecordDecl *DerivedDecl =
+ cast<CXXRecordDecl>(cast<RecordType>(CanDerivedType)->getDecl());
+
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(cast<RecordType>(CanBaseType)->getDecl());
+
+ return TypeConversionRequiresAdjustment(Ctx, DerivedDecl, BaseDecl);
+}
+
bool VtableBuilder::OverrideMethod(GlobalDecl GD, llvm::Constant *m,
bool MorallyVirtual, Index_t OverrideOffset,
Index_t Offset, int64_t CurrentVBaseOffset) {
@@ -704,24 +792,29 @@
// FIXME: begin_overridden_methods might be too lax, covariance */
if (submethods[i] != om)
continue;
- QualType nc_oret = OMD->getType()->getAs<FunctionType>()->getResultType();
- CanQualType oret = CGM.getContext().getCanonicalType(nc_oret);
- QualType nc_ret = MD->getType()->getAs<FunctionType>()->getResultType();
- CanQualType ret = CGM.getContext().getCanonicalType(nc_ret);
- if (oret != ret) {
- // FIXME: calculate offsets for covariance
- CovariantThunksMapTy::iterator it = CovariantThunks.find(i);
- if (it != CovariantThunks.end()) {
- oret = it->second.ReturnType;
- CovariantThunks.erase(it);
- }
- // FIXME: Double check oret
- Index_t nv = getNVOffset(oret, ret)/8;
- CovariantThunks[i] =
- CovariantThunk(GD, ThunkAdjustment(nv, getVbaseOffset(oret, ret)),
- oret);
-
+
+ QualType ReturnType =
+ MD->getType()->getAs<FunctionType>()->getResultType();
+ QualType OverriddenReturnType =
+ OMD->getType()->getAs<FunctionType>()->getResultType();
+
+ // Check if we need a return type adjustment.
+ if (TypeConversionRequiresAdjustment(CGM.getContext(), ReturnType,
+ OverriddenReturnType)) {
+ CovariantThunk &Adjustment = CovariantThunks[i];
+
+ // Get the canonical return type.
+ CanQualType CanReturnType =
+ CGM.getContext().getCanonicalType(ReturnType);
+
+ // Insert the base return type.
+ if (Adjustment.ReturnType.isNull())
+ Adjustment.ReturnType =
+ CGM.getContext().getCanonicalType(OverriddenReturnType);
+
+ Adjustment.GD = GD;
}
+
Index[GD] = i;
submethods[i] = m;
if (isPure)
@@ -779,84 +872,6 @@
return false;
}
-
-/// TypeConversionRequiresAdjustment - Returns whether conversion from a
-/// derived type to a base type requires adjustment.
-static bool
-TypeConversionRequiresAdjustment(ASTContext &Ctx,
- const CXXRecordDecl *DerivedDecl,
- const CXXRecordDecl *BaseDecl) {
- CXXBasePaths Paths(/*FindAmbiguities=*/false,
- /*RecordPaths=*/true, /*DetectVirtual=*/true);
- if (!const_cast<CXXRecordDecl *>(DerivedDecl)->
- isDerivedFrom(const_cast<CXXRecordDecl *>(BaseDecl), Paths)) {
- assert(false && "Class must be derived from the passed in base class!");
- return false;
- }
-
- // If we found a virtual base we always want to require adjustment.
- if (Paths.getDetectedVirtual())
- return true;
-
- const CXXBasePath &Path = Paths.front();
-
- for (size_t Start = 0, End = Path.size(); Start != End; ++Start) {
- const CXXBasePathElement &Element = Path[Start];
-
- // Check the base class offset.
- const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Element.Class);
-
- const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>();
- const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl());
-
- if (Layout.getBaseClassOffset(Base) != 0) {
- // This requires an adjustment.
- return true;
- }
- }
-
- return false;
-}
-
-static bool
-TypeConversionRequiresAdjustment(ASTContext &Ctx,
- QualType DerivedType, QualType BaseType) {
- // Canonicalize the types.
- QualType CanDerivedType = Ctx.getCanonicalType(DerivedType);
- QualType CanBaseType = Ctx.getCanonicalType(BaseType);
-
- assert(CanDerivedType->getTypeClass() == CanBaseType->getTypeClass() &&
- "Types must have same type class!");
-
- if (CanDerivedType == CanBaseType) {
- // No adjustment needed.
- return false;
- }
-
- if (const ReferenceType *RT = dyn_cast<ReferenceType>(CanDerivedType)) {
- CanDerivedType = RT->getPointeeType();
- CanBaseType = cast<ReferenceType>(CanBaseType)->getPointeeType();
- } else if (const PointerType *PT = dyn_cast<PointerType>(CanDerivedType)) {
- CanDerivedType = PT->getPointeeType();
- CanBaseType = cast<PointerType>(CanBaseType)->getPointeeType();
- } else {
- assert(false && "Unexpected return type!");
- }
-
- if (CanDerivedType == CanBaseType) {
- // No adjustment needed.
- return false;
- }
-
- const CXXRecordDecl *DerivedDecl =
- cast<CXXRecordDecl>(cast<RecordType>(CanDerivedType)->getDecl());
-
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(cast<RecordType>(CanBaseType)->getDecl());
-
- return TypeConversionRequiresAdjustment(Ctx, DerivedDecl, BaseDecl);
-}
-
void CGVtableInfo::ComputeMethodVtableIndices(const CXXRecordDecl *RD) {
// Itanium C++ ABI 2.5.2:
More information about the cfe-commits
mailing list