//===- ForceFunctionAttrs.cpp - Force function attrs for debugging --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "forceattrs"

static cl::list<std::string>
    ForceAttributes("force-attribute", cl::Hidden,
                    cl::desc("Add an attribute to a function. This should be a "
                             "pair of 'function-name:attribute-name', for "
                             "example -force-attribute=foo:noinline. This "
                             "option can be specified multiple times."));

static Attribute::AttrKind parseAttrKind(StringRef Kind) {
  return StringSwitch<Attribute::AttrKind>(Kind)
      .Case("alwaysinline", Attribute::AlwaysInline)
      .Case("builtin", Attribute::Builtin)
      .Case("cold", Attribute::Cold)
      .Case("convergent", Attribute::Convergent)
      .Case("inlinehint", Attribute::InlineHint)
      .Case("jumptable", Attribute::JumpTable)
      .Case("minsize", Attribute::MinSize)
      .Case("naked", Attribute::Naked)
      .Case("nobuiltin", Attribute::NoBuiltin)
      .Case("noduplicate", Attribute::NoDuplicate)
      .Case("noimplicitfloat", Attribute::NoImplicitFloat)
      .Case("noinline", Attribute::NoInline)
      .Case("nonlazybind", Attribute::NonLazyBind)
      .Case("noredzone", Attribute::NoRedZone)
      .Case("noreturn", Attribute::NoReturn)
      .Case("nocf_check", Attribute::NoCfCheck)
      .Case("norecurse", Attribute::NoRecurse)
      .Case("nounwind", Attribute::NoUnwind)
      .Case("optforfuzzing", Attribute::OptForFuzzing)
      .Case("optnone", Attribute::OptimizeNone)
      .Case("optsize", Attribute::OptimizeForSize)
      .Case("readnone", Attribute::ReadNone)
      .Case("readonly", Attribute::ReadOnly)
      .Case("argmemonly", Attribute::ArgMemOnly)
      .Case("returns_twice", Attribute::ReturnsTwice)
      .Case("safestack", Attribute::SafeStack)
      .Case("shadowcallstack", Attribute::ShadowCallStack)
      .Case("sanitize_address", Attribute::SanitizeAddress)
      .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
      .Case("sanitize_memory", Attribute::SanitizeMemory)
      .Case("sanitize_thread", Attribute::SanitizeThread)
      .Case("ssp", Attribute::StackProtect)
      .Case("sspreq", Attribute::StackProtectReq)
      .Case("sspstrong", Attribute::StackProtectStrong)
      .Case("strictfp", Attribute::StrictFP)
      .Case("uwtable", Attribute::UWTable)
      .Default(Attribute::None);
}

/// If F has any forced attributes given on the command line, add them.
static void addForcedAttributes(Function &F) {
  for (auto &S : ForceAttributes) {
    auto KV = StringRef(S).split(':');
    if (KV.first != F.getName())
      continue;

    auto Kind = parseAttrKind(KV.second);
    if (Kind == Attribute::None) {
      LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV.second
                        << " unknown or not handled!\n");
      continue;
    }
    if (F.hasFnAttribute(Kind))
      continue;
    F.addFnAttr(Kind);
  }
}

PreservedAnalyses ForceFunctionAttrsPass::run(Module &M,
                                              ModuleAnalysisManager &) {
  if (ForceAttributes.empty())
    return PreservedAnalyses::all();

  for (Function &F : M.functions())
    addForcedAttributes(F);

  // Just conservatively invalidate analyses, this isn't likely to be important.
  return PreservedAnalyses::none();
}

namespace {
struct ForceFunctionAttrsLegacyPass : public ModulePass {
  static char ID; // Pass identification, replacement for typeid
  ForceFunctionAttrsLegacyPass() : ModulePass(ID) {
    initializeForceFunctionAttrsLegacyPassPass(
        *PassRegistry::getPassRegistry());
  }

  bool runOnModule(Module &M) override {
    if (ForceAttributes.empty())
      return false;

    for (Function &F : M.functions())
      addForcedAttributes(F);

    // Conservatively assume we changed something.
    return true;
  }
};
}

char ForceFunctionAttrsLegacyPass::ID = 0;
INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs",
                "Force set function attributes", false, false)

Pass *llvm::createForceFunctionAttrsLegacyPass() {
  return new ForceFunctionAttrsLegacyPass();
}
