diff options
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
| -rw-r--r-- | lib/CodeGen/CGCXX.cpp | 32 | 
1 files changed, 15 insertions, 17 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 0f3141ab76d0..5ef4dc45fba1 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -110,16 +110,14 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {      return true;    return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base), -                                  GlobalDecl(BaseD, Dtor_Base), -                                  false); +                                  GlobalDecl(BaseD, Dtor_Base));  }  /// Try to emit a definition as a global alias for another definition.  /// If \p InEveryTU is true, we know that an equivalent alias can be produced  /// in every translation unit.  bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, -                                             GlobalDecl TargetDecl, -                                             bool InEveryTU) { +                                             GlobalDecl TargetDecl) {    if (!getCodeGenOpts().CXXCtorDtorAliases)      return true; @@ -134,11 +132,6 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,    llvm::GlobalValue::LinkageTypes TargetLinkage =        getFunctionLinkage(TargetDecl); -  // available_externally definitions aren't real definitions, so we cannot -  // create an alias to one. -  if (TargetLinkage == llvm::GlobalValue::AvailableExternallyLinkage) -    return true; -    // Check if we have it already.    StringRef MangledName = getMangledName(AliasDecl);    llvm::GlobalValue *Entry = GetGlobalValue(MangledName); @@ -161,7 +154,14 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,    // Instead of creating as alias to a linkonce_odr, replace all of the uses    // of the aliasee. -  if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) { +  if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && +      !(TargetLinkage == llvm::GlobalValue::AvailableExternallyLinkage && +        TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { +    // 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 +    // corresponding LLVM changes.      addReplacement(MangledName, Aliasee);      return false;    } @@ -176,13 +176,11 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,      return true;    } -  if (!InEveryTU) { -    // If we don't have a definition for the destructor yet, don't -    // emit.  We can't emit aliases to declarations; that's just not -    // how aliases work. -    if (Ref->isDeclaration()) -      return true; -  } +  // If we don't have a definition for the destructor yet or the definition is +  // avaialable_externally, don't emit an alias.  We can't emit aliases to +  // declarations; that's just not how aliases work. +  if (Ref->isDeclarationForLinker()) +    return true;    // Don't create an alias to a linker weak symbol. This avoids producing    // different COMDATs in different TUs. Another option would be to  | 
