//===-- llvm-c++filt.cpp --------------------------------------------------===//
//
// 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/ADT/StringExtras.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
#include <iostream>

using namespace llvm;

enum Style {
  Auto,  ///< auto-detect mangling
  GNU,   ///< GNU
  Lucid, ///< Lucid compiler (lcc)
  ARM,
  HP,    ///< HP compiler (xCC)
  EDG,   ///< EDG compiler
  GNUv3, ///< GNU C++ v3 ABI
  Java,  ///< Java (gcj)
  GNAT   ///< ADA compiler (gnat)
};
static cl::opt<Style>
    Format("format", cl::desc("decoration style"),
           cl::values(clEnumValN(Auto, "auto", "auto-detect style"),
                      clEnumValN(GNU, "gnu", "GNU (itanium) style")),
           cl::init(Auto));
static cl::alias FormatShort("s", cl::desc("alias for --format"),
                             cl::aliasopt(Format));

static cl::opt<bool> StripUnderscore("strip-underscore",
                                     cl::desc("strip the leading underscore"),
                                     cl::init(false));
static cl::alias StripUnderscoreShort("_",
                                      cl::desc("alias for --strip-underscore"),
                                      cl::aliasopt(StripUnderscore));

static cl::opt<bool>
    Types("types",
          cl::desc("attempt to demangle types as well as function names"),
          cl::init(false));
static cl::alias TypesShort("t", cl::desc("alias for --types"),
                            cl::aliasopt(Types));

static cl::list<std::string>
Decorated(cl::Positional, cl::desc("<mangled>"), cl::ZeroOrMore);

static cl::extrahelp
    HelpResponse("\nPass @FILE as argument to read options from FILE.\n");

static std::string demangle(llvm::raw_ostream &OS, const std::string &Mangled) {
  int Status;

  const char *DecoratedStr = Mangled.c_str();
  if (StripUnderscore)
    if (DecoratedStr[0] == '_')
      ++DecoratedStr;
  size_t DecoratedLength = strlen(DecoratedStr);

  char *Undecorated = nullptr;

  if (Types ||
      ((DecoratedLength >= 2 && strncmp(DecoratedStr, "_Z", 2) == 0) ||
       (DecoratedLength >= 4 && strncmp(DecoratedStr, "___Z", 4) == 0)))
    Undecorated = itaniumDemangle(DecoratedStr, nullptr, nullptr, &Status);

  if (!Undecorated &&
      (DecoratedLength > 6 && strncmp(DecoratedStr, "__imp_", 6) == 0)) {
    OS << "import thunk for ";
    Undecorated = itaniumDemangle(DecoratedStr + 6, nullptr, nullptr, &Status);
  }

  std::string Result(Undecorated ? Undecorated : Mangled);
  free(Undecorated);
  return Result;
}

// Split 'Source' on any character that fails to pass 'IsLegalChar'.  The
// returned vector consists of pairs where 'first' is the delimited word, and
// 'second' are the delimiters following that word.
static void SplitStringDelims(
    StringRef Source,
    SmallVectorImpl<std::pair<StringRef, StringRef>> &OutFragments,
    function_ref<bool(char)> IsLegalChar) {
  // The beginning of the input string.
  const auto Head = Source.begin();

  // Obtain any leading delimiters.
  auto Start = std::find_if(Head, Source.end(), IsLegalChar);
  if (Start != Head)
    OutFragments.push_back({"", Source.slice(0, Start - Head)});

  // Capture each word and the delimiters following that word.
  while (Start != Source.end()) {
    Start = std::find_if(Start, Source.end(), IsLegalChar);
    auto End = std::find_if_not(Start, Source.end(), IsLegalChar);
    auto DEnd = std::find_if(End, Source.end(), IsLegalChar);
    OutFragments.push_back({Source.slice(Start - Head, End - Head),
                            Source.slice(End - Head, DEnd - Head)});
    Start = DEnd;
  }
}

// This returns true if 'C' is a character that can show up in an
// Itanium-mangled string.
static bool IsLegalItaniumChar(char C) {
  // Itanium CXX ABI [External Names]p5.1.1:
  // '$' and '.' in mangled names are reserved for private implementations.
  return isalnum(C) || C == '.' || C == '$' || C == '_';
}

// If 'Split' is true, then 'Mangled' is broken into individual words and each
// word is demangled.  Otherwise, the entire string is treated as a single
// mangled item.  The result is output to 'OS'.
static void demangleLine(llvm::raw_ostream &OS, StringRef Mangled, bool Split) {
  std::string Result;
  if (Split) {
    SmallVector<std::pair<StringRef, StringRef>, 16> Words;
    SplitStringDelims(Mangled, Words, IsLegalItaniumChar);
    for (const auto &Word : Words)
      Result += demangle(OS, Word.first) + Word.second.str();
  } else
    Result = demangle(OS, Mangled);
  OS << Result << '\n';
  OS.flush();
}

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);

  cl::ParseCommandLineOptions(argc, argv, "llvm symbol undecoration tool\n");

  if (Decorated.empty())
    for (std::string Mangled; std::getline(std::cin, Mangled);)
      demangleLine(llvm::outs(), Mangled, true);
  else
    for (const auto &Symbol : Decorated)
      demangleLine(llvm::outs(), Symbol, false);

  return EXIT_SUCCESS;
}
