//===- EHPersonalities.cpp - Compute EH-related information ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

/// See if the given exception handling personality function is one that we
/// understand.  If so, return a description of it; otherwise return Unknown.
EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
  const Function *F =
      Pers ? dyn_cast<Function>(Pers->stripPointerCasts()) : nullptr;
  if (!F)
    return EHPersonality::Unknown;
  return StringSwitch<EHPersonality>(F->getName())
    .Case("__gnat_eh_personality",     EHPersonality::GNU_Ada)
    .Case("__gxx_personality_v0",      EHPersonality::GNU_CXX)
    .Case("__gxx_personality_seh0",    EHPersonality::GNU_CXX)
    .Case("__gxx_personality_sj0",     EHPersonality::GNU_CXX_SjLj)
    .Case("__gcc_personality_v0",      EHPersonality::GNU_C)
    .Case("__gcc_personality_seh0",    EHPersonality::GNU_C)
    .Case("__gcc_personality_sj0",     EHPersonality::GNU_C_SjLj)
    .Case("__objc_personality_v0",     EHPersonality::GNU_ObjC)
    .Case("_except_handler3",          EHPersonality::MSVC_X86SEH)
    .Case("_except_handler4",          EHPersonality::MSVC_X86SEH)
    .Case("__C_specific_handler",      EHPersonality::MSVC_Win64SEH)
    .Case("__CxxFrameHandler3",        EHPersonality::MSVC_CXX)
    .Case("ProcessCLRException",       EHPersonality::CoreCLR)
    .Case("rust_eh_personality",       EHPersonality::Rust)
    .Case("__gxx_wasm_personality_v0", EHPersonality::Wasm_CXX)
    .Default(EHPersonality::Unknown);
}

StringRef llvm::getEHPersonalityName(EHPersonality Pers) {
  switch (Pers) {
  case EHPersonality::GNU_Ada:       return "__gnat_eh_personality";
  case EHPersonality::GNU_CXX:       return "__gxx_personality_v0";
  case EHPersonality::GNU_CXX_SjLj:  return "__gxx_personality_sj0";
  case EHPersonality::GNU_C:         return "__gcc_personality_v0";
  case EHPersonality::GNU_C_SjLj:    return "__gcc_personality_sj0";
  case EHPersonality::GNU_ObjC:      return "__objc_personality_v0";
  case EHPersonality::MSVC_X86SEH:   return "_except_handler3";
  case EHPersonality::MSVC_Win64SEH: return "__C_specific_handler";
  case EHPersonality::MSVC_CXX:      return "__CxxFrameHandler3";
  case EHPersonality::CoreCLR:       return "ProcessCLRException";
  case EHPersonality::Rust:          return "rust_eh_personality";
  case EHPersonality::Wasm_CXX:      return "__gxx_wasm_personality_v0";
  case EHPersonality::Unknown:       llvm_unreachable("Unknown EHPersonality!");
  }

  llvm_unreachable("Invalid EHPersonality!");
}

EHPersonality llvm::getDefaultEHPersonality(const Triple &T) {
  return EHPersonality::GNU_C;
}

bool llvm::canSimplifyInvokeNoUnwind(const Function *F) {
  EHPersonality Personality = classifyEHPersonality(F->getPersonalityFn());
  // We can't simplify any invokes to nounwind functions if the personality
  // function wants to catch asynch exceptions.  The nounwind attribute only
  // implies that the function does not throw synchronous exceptions.
  return !isAsynchronousEHPersonality(Personality);
}

DenseMap<BasicBlock *, ColorVector> llvm::colorEHFunclets(Function &F) {
  SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist;
  BasicBlock *EntryBlock = &F.getEntryBlock();
  DenseMap<BasicBlock *, ColorVector> BlockColors;

  // Build up the color map, which maps each block to its set of 'colors'.
  // For any block B the "colors" of B are the set of funclets F (possibly
  // including a root "funclet" representing the main function) such that
  // F will need to directly contain B or a copy of B (where the term "directly
  // contain" is used to distinguish from being "transitively contained" in
  // a nested funclet).
  //
  // Note: Despite not being a funclet in the truest sense, a catchswitch is
  // considered to belong to its own funclet for the purposes of coloring.

  DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for "
                                                  << F.getName() << "\n");

  Worklist.push_back({EntryBlock, EntryBlock});

  while (!Worklist.empty()) {
    BasicBlock *Visiting;
    BasicBlock *Color;
    std::tie(Visiting, Color) = Worklist.pop_back_val();
    DEBUG_WITH_TYPE("winehprepare-coloring",
                    dbgs() << "Visiting " << Visiting->getName() << ", "
                           << Color->getName() << "\n");
    Instruction *VisitingHead = Visiting->getFirstNonPHI();
    if (VisitingHead->isEHPad()) {
      // Mark this funclet head as a member of itself.
      Color = Visiting;
    }
    // Note that this is a member of the given color.
    ColorVector &Colors = BlockColors[Visiting];
    if (!is_contained(Colors, Color))
      Colors.push_back(Color);
    else
      continue;

    DEBUG_WITH_TYPE("winehprepare-coloring",
                    dbgs() << "  Assigned color \'" << Color->getName()
                           << "\' to block \'" << Visiting->getName()
                           << "\'.\n");

    BasicBlock *SuccColor = Color;
    Instruction *Terminator = Visiting->getTerminator();
    if (auto *CatchRet = dyn_cast<CatchReturnInst>(Terminator)) {
      Value *ParentPad = CatchRet->getCatchSwitchParentPad();
      if (isa<ConstantTokenNone>(ParentPad))
        SuccColor = EntryBlock;
      else
        SuccColor = cast<Instruction>(ParentPad)->getParent();
    }

    for (BasicBlock *Succ : successors(Visiting))
      Worklist.push_back({Succ, SuccColor});
  }
  return BlockColors;
}
