diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp index 2f8a17a..545c5ef 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp @@ -35,7 +35,7 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { return true; // Producing an alias to a base class ctor/dtor can degrade debug quality - // as the debugger cannot tell them appart. + // as the debugger cannot tell them apart. if (getCodeGenOpts().OptimizationLevel == 0) return true; @@ -44,6 +44,10 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { if (!D->hasTrivialBody()) return true; + // For exported destructors, we need a full definition. + if (D->hasAttr<DLLExportAttr>()) + return true; + const CXXRecordDecl *Class = D->getParent(); // If we need to manipulate a VTT parameter, give up. @@ -56,22 +60,20 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { // If any field has a non-trivial destructor, we have to emit the // destructor separately. - for (CXXRecordDecl::field_iterator I = Class->field_begin(), - E = Class->field_end(); I != E; ++I) + for (const auto *I : Class->fields()) if (I->getType().isDestructedType()) return true; // Try to find a unique base class with a non-trivial destructor. - const CXXRecordDecl *UniqueBase = 0; - for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), - E = Class->bases_end(); I != E; ++I) { + const CXXRecordDecl *UniqueBase = nullptr; + for (const auto &I : Class->bases()) { // We're in the base destructor, so skip virtual bases. - if (I->isVirtual()) continue; + if (I.isVirtual()) continue; // Skip base classes with trivial destructors. - const CXXRecordDecl *Base - = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); + const auto *Base = + cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); if (Base->hasTrivialDestructor()) continue; // If we've already found a base class with a non-trivial @@ -113,7 +115,7 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, if (!getCodeGenOpts().CXXCtorDtorAliases) return true; - // The alias will use the linkage of the referrent. If we can't + // The alias will use the linkage of the referent. If we can't // support aliases with that linkage, fail. llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl); @@ -136,20 +138,20 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, llvm::PointerType *AliasType = getTypes().GetFunctionType(AliasDecl)->getPointerTo(); - // Find the referrent. Some aliases might require a bitcast, in + // Find the referent. Some aliases might require a bitcast, in // which case the caller is responsible for ensuring the soundness // of these semantics. - llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl)); + auto *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl)); llvm::Constant *Aliasee = Ref; if (Ref->getType() != AliasType) Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType); // Instead of creating as alias to a linkonce_odr, replace all of the uses - // of the aliassee. + // of the aliasee. if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && (TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage || !TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { - // FIXME: An extern template instanciation will create functions with + // FIXME: An extern template instantiation will create functions with // linkage "AvailableExternally". In libc++, some classes also define // members with attribute "AlwaysInline" and expect no reference to // be generated. It is desirable to reenable this optimisation after @@ -174,8 +176,8 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, return true; // Create the alias with no name. - llvm::GlobalAlias *Alias = - new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule()); + auto *Alias = llvm::GlobalAlias::create(AliasType->getElementType(), 0, + Linkage, "", Aliasee, &getModule()); // Switch any previous uses to the alias. if (Entry) { @@ -196,11 +198,13 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor, CXXCtorType ctorType) { - // The complete constructor is equivalent to the base constructor - // for classes with no virtual bases. Try to emit it as an alias. - if (getTarget().getCXXABI().hasConstructorVariants() && - !ctor->getParent()->getNumVBases() && - (ctorType == Ctor_Complete || ctorType == Ctor_Base)) { + if (!getTarget().getCXXABI().hasConstructorVariants()) { + // If there are no constructor variants, always emit the complete destructor. + ctorType = Ctor_Complete; + } else if (!ctor->getParent()->getNumVBases() && + (ctorType == Ctor_Complete || ctorType == Ctor_Base)) { + // The complete constructor is equivalent to the base constructor + // for classes with no virtual bases. Try to emit it as an alias. bool ProducedAlias = !TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true); @@ -211,20 +215,21 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor, const CGFunctionInfo &fnInfo = getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType); - llvm::Function *fn = - cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo)); + auto *fn = cast<llvm::Function>( + GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo, true)); setFunctionLinkage(GlobalDecl(ctor, ctorType), fn); CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo); - SetFunctionDefinitionAttributes(ctor, fn); + setFunctionDefinitionAttributes(ctor, fn); SetLLVMFunctionAttributesForDefinition(ctor, fn); } llvm::GlobalValue * CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, CXXCtorType ctorType, - const CGFunctionInfo *fnInfo) { + const CGFunctionInfo *fnInfo, + bool DontDefer) { GlobalDecl GD(ctor, ctorType); StringRef name = getMangledName(GD); @@ -236,7 +241,8 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo); return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD, - /*ForVTable=*/false)); + /*ForVTable=*/false, + DontDefer)); } void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor, @@ -266,13 +272,13 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor, const CGFunctionInfo &fnInfo = getTypes().arrangeCXXDestructor(dtor, dtorType); - llvm::Function *fn = - cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo)); + auto *fn = cast<llvm::Function>( + GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo, nullptr, true)); setFunctionLinkage(GlobalDecl(dtor, dtorType), fn); CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo); - SetFunctionDefinitionAttributes(dtor, fn); + setFunctionDefinitionAttributes(dtor, fn); SetLLVMFunctionAttributesForDefinition(dtor, fn); } @@ -280,7 +286,8 @@ llvm::GlobalValue * CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor, CXXDtorType dtorType, const CGFunctionInfo *fnInfo, - llvm::FunctionType *fnType) { + llvm::FunctionType *fnType, + bool DontDefer) { GlobalDecl GD(dtor, dtorType); StringRef name = getMangledName(GD); @@ -292,7 +299,8 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor, fnType = getTypes().GetFunctionType(*fnInfo); } return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD, - /*ForVTable=*/false)); + /*ForVTable=*/false, + DontDefer)); } static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF, @@ -331,9 +339,9 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, QualType T = QualType(QTy, 0); const RecordType *RT = T->getAs<RecordType>(); assert(RT && "BuildAppleKextVirtualCall - Qual type must be record"); - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - - if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) + const auto *RD = cast<CXXRecordDecl>(RT->getDecl()); + + if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD); return ::BuildAppleKextVirtualCall(*this, MD, Ty, RD); @@ -346,7 +354,7 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall( const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD) { - const CXXMethodDecl *MD = cast<CXXMethodDecl>(DD); + const auto *MD = cast<CXXMethodDecl>(DD); // FIXME. Dtor_Base dtor is always direct!! // It need be somehow inline expanded into the caller. // -O does that. But need to support -O0 as well. @@ -357,5 +365,5 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall( llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo); return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD); } - return 0; + return nullptr; } |