diff options
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 3f3825b76275..4d143e3e1bdf 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -35,20 +35,37 @@ using namespace CodeGen; /// Return the best known alignment for an unknown pointer to a /// particular class. CharUnits CodeGenModule::getClassPointerAlignment(const CXXRecordDecl *RD) { - if (!RD->isCompleteDefinition()) + if (!RD->hasDefinition()) return CharUnits::One(); // Hopefully won't be used anywhere. auto &layout = getContext().getASTRecordLayout(RD); // If the class is final, then we know that the pointer points to an // object of that type and can use the full alignment. - if (RD->hasAttr<FinalAttr>()) { + if (RD->isEffectivelyFinal()) return layout.getAlignment(); // Otherwise, we have to assume it could be a subclass. - } else { - return layout.getNonVirtualAlignment(); - } + return layout.getNonVirtualAlignment(); +} + +/// Return the smallest possible amount of storage that might be allocated +/// starting from the beginning of an object of a particular class. +/// +/// This may be smaller than sizeof(RD) if RD has virtual base classes. +CharUnits CodeGenModule::getMinimumClassObjectSize(const CXXRecordDecl *RD) { + if (!RD->hasDefinition()) + return CharUnits::One(); + + auto &layout = getContext().getASTRecordLayout(RD); + + // If the class is final, then we know that the pointer points to an + // object of that type and can use the full alignment. + if (RD->isEffectivelyFinal()) + return layout.getSize(); + + // Otherwise, we have to assume it could be a subclass. + return std::max(layout.getNonVirtualSize(), CharUnits::One()); } /// Return the best known alignment for a pointer to a virtual base, @@ -138,8 +155,8 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base, memberPtr, memberPtrType); QualType memberType = memberPtrType->getPointeeType(); - CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo, - TBAAInfo); + CharUnits memberAlign = + CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo); memberAlign = CGM.getDynamicOffsetAlignment(base.getAlignment(), memberPtrType->getClass()->getAsCXXRecordDecl(), @@ -236,8 +253,13 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, // Compute the offset from the static and dynamic components. llvm::Value *baseOffset; if (!nonVirtualOffset.isZero()) { - baseOffset = llvm::ConstantInt::get(CGF.PtrDiffTy, - nonVirtualOffset.getQuantity()); + llvm::Type *OffsetType = + (CGF.CGM.getTarget().getCXXABI().isItaniumFamily() && + CGF.CGM.getItaniumVTableContext().isRelativeLayout()) + ? CGF.Int32Ty + : CGF.PtrDiffTy; + baseOffset = + llvm::ConstantInt::get(OffsetType, nonVirtualOffset.getQuantity()); if (virtualOffset) { baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); } @@ -730,7 +752,7 @@ bool CodeGenFunction::IsConstructorDelegationValid( // parameters // - etc. // If we ever add any of the above cases, remember that: - // - function-try-blocks will always blacklist this optimization + // - function-try-blocks will always exclude this optimization // - we need to perform the constructor prologue and cleanup in // EmitConstructorBody. @@ -2128,7 +2150,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType(); Address Src(Args[1].getRValue(*this).getScalarVal(), - getNaturalTypeAlignment(SrcTy)); + CGM.getNaturalTypeAlignment(SrcTy)); LValue SrcLVal = MakeAddrLValue(Src, SrcTy); QualType DestTy = getContext().getTypeDeclType(ClassDecl); LValue DestLVal = MakeAddrLValue(This, DestTy); @@ -2148,7 +2170,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, } // Insert any ABI-specific implicit constructor arguments. - CGCXXABI::AddedStructorArgs ExtraArgs = + CGCXXABI::AddedStructorArgCounts ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase, Delegating, Args); @@ -2157,7 +2179,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall( Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs); CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type)); - EmitCall(Info, Callee, ReturnValueSlot(), Args); + EmitCall(Info, Callee, ReturnValueSlot(), Args, nullptr, Loc); // Generate vtable assumptions if we're constructing a complete object // with a vtable. We don't do this for base subobjects for two reasons: @@ -2641,7 +2663,9 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, if (SanOpts.has(SanitizerKind::CFIVCall)) EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc); else if (CGM.getCodeGenOpts().WholeProgramVTables && - CGM.HasHiddenLTOVisibility(RD)) { + // Don't insert type test assumes if we are forcing public std + // visibility. + !CGM.HasLTOVisibilityPublicStd(RD)) { llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); llvm::Value *TypeId = @@ -2850,7 +2874,9 @@ void CodeGenFunction::EmitForwardingCallToLambda( if (!resultType->isVoidType() && calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && !hasScalarEvaluationKind(calleeFnInfo.getReturnType())) - returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified()); + returnSlot = + ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(), + /*IsUnused=*/false, /*IsExternallyDestructed=*/true); // We don't need to separately arrange the call arguments because // the call can't be variadic anyway --- it's impossible to forward |