diff options
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 58 | 
1 files changed, 31 insertions, 27 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 717ed17dd4e..695048e5b32 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -598,61 +598,65 @@ static bool hasUnwindExceptions(const LangOptions &LangOpts) {  void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,                                                             llvm::Function *F) { +  llvm::AttrBuilder B; +    if (CodeGenOpts.UnwindTables) -    F->setHasUWTable(); +    B.addAttribute(llvm::Attribute::UWTable);    if (!hasUnwindExceptions(LangOpts)) -    F->addFnAttr(llvm::Attribute::NoUnwind); +    B.addAttribute(llvm::Attribute::NoUnwind);    if (D->hasAttr<NakedAttr>()) {      // Naked implies noinline: we should not be inlining such functions. -    F->addFnAttr(llvm::Attribute::Naked); -    F->addFnAttr(llvm::Attribute::NoInline); +    B.addAttribute(llvm::Attribute::Naked); +    B.addAttribute(llvm::Attribute::NoInline); +  } else if (D->hasAttr<NoInlineAttr>()) { +    B.addAttribute(llvm::Attribute::NoInline); +  } else if ((D->hasAttr<AlwaysInlineAttr>() || +              D->hasAttr<ForceInlineAttr>()) && +             !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, +                                              llvm::Attribute::NoInline)) { +    // (noinline wins over always_inline, and we can't specify both in IR) +    B.addAttribute(llvm::Attribute::AlwaysInline);    } -  if (D->hasAttr<NoInlineAttr>()) -    F->addFnAttr(llvm::Attribute::NoInline); - -  // (noinline wins over always_inline, and we can't specify both in IR) -  if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) && -      !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, -                                       llvm::Attribute::NoInline)) -    F->addFnAttr(llvm::Attribute::AlwaysInline); -    // FIXME: Communicate hot and cold attributes to LLVM more directly.    if (D->hasAttr<ColdAttr>()) -    F->addFnAttr(llvm::Attribute::OptimizeForSize); +    B.addAttribute(llvm::Attribute::OptimizeForSize);    if (D->hasAttr<MinSizeAttr>()) -    F->addFnAttr(llvm::Attribute::MinSize); - -  if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) -    F->setUnnamedAddr(true); - -  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) -    if (MD->isVirtual()) -      F->setUnnamedAddr(true); +    B.addAttribute(llvm::Attribute::MinSize);    if (LangOpts.getStackProtector() == LangOptions::SSPOn) -    F->addFnAttr(llvm::Attribute::StackProtect); +    B.addAttribute(llvm::Attribute::StackProtect);    else if (LangOpts.getStackProtector() == LangOptions::SSPReq) -    F->addFnAttr(llvm::Attribute::StackProtectReq); +    B.addAttribute(llvm::Attribute::StackProtectReq);    // Add sanitizer attributes if function is not blacklisted.    if (!SanitizerBlacklist.isIn(*F)) {      // When AddressSanitizer is enabled, set SanitizeAddress attribute      // unless __attribute__((no_sanitize_address)) is used.      if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>()) -      F->addFnAttr(llvm::Attribute::SanitizeAddress); +      B.addAttribute(llvm::Attribute::SanitizeAddress);      // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))      if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) { -      F->addFnAttr(llvm::Attribute::SanitizeThread); +      B.addAttribute(llvm::Attribute::SanitizeThread);      }      // Same for MemorySanitizer and __attribute__((no_sanitize_memory))      if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>()) -      F->addFnAttr(llvm::Attribute::SanitizeMemory); +      B.addAttribute(llvm::Attribute::SanitizeMemory);    } +  F->addAttributes(llvm::AttributeSet::FunctionIndex, +                   llvm::AttributeSet::get( +                       F->getContext(), llvm::AttributeSet::FunctionIndex, B)); + +  if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) +    F->setUnnamedAddr(true); +  else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) +    if (MD->isVirtual()) +      F->setUnnamedAddr(true); +    unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();    if (alignment)      F->setAlignment(alignment);  | 

