//===--- Types.cpp - Driver input & temporary type 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 "clang/Driver/Types.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include <cassert>
#include <cstring>

using namespace clang::driver;
using namespace clang::driver::types;

struct TypeInfo {
  const char *Name;
  const char *TempSuffix;
  ID PreprocessedType;
  const llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> Phases;
};

static const TypeInfo TypeInfos[] = {
#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, ...) \
  { NAME, TEMP_SUFFIX, TY_##PP_TYPE, { __VA_ARGS__ }, },
#include "clang/Driver/Types.def"
#undef TYPE
};
static const unsigned numTypes = llvm::array_lengthof(TypeInfos);

static const TypeInfo &getInfo(unsigned id) {
  assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
  return TypeInfos[id - 1];
}

const char *types::getTypeName(ID Id) {
  return getInfo(Id).Name;
}

types::ID types::getPreprocessedType(ID Id) {
  ID PPT = getInfo(Id).PreprocessedType;
  assert((llvm::is_contained(getInfo(Id).Phases, phases::Preprocess) !=
          (PPT == TY_INVALID)) &&
         "Unexpected Preprocess Type.");
  return PPT;
}

static bool isPrepeocessedModuleType(ID Id) {
  return Id == TY_CXXModule || Id == TY_PP_CXXModule;
}

types::ID types::getPrecompiledType(ID Id) {
  if (isPrepeocessedModuleType(Id))
    return TY_ModuleFile;
  if (onlyPrecompileType(Id))
    return TY_PCH;
  return TY_INVALID;
}

const char *types::getTypeTempSuffix(ID Id, bool CLMode) {
  if (CLMode) {
    switch (Id) {
    case TY_Object:
    case TY_LTO_BC:
      return "obj";
    case TY_Image:
      return "exe";
    case TY_PP_Asm:
      return "asm";
    default:
      break;
    }
  }
  return getInfo(Id).TempSuffix;
}

bool types::onlyAssembleType(ID Id) {
  return llvm::is_contained(getInfo(Id).Phases, phases::Assemble) &&
         !llvm::is_contained(getInfo(Id).Phases, phases::Compile) &&
         !llvm::is_contained(getInfo(Id).Phases, phases::Backend);
}

bool types::onlyPrecompileType(ID Id) {
  return llvm::is_contained(getInfo(Id).Phases, phases::Precompile) &&
         !isPrepeocessedModuleType(Id);
}

bool types::canTypeBeUserSpecified(ID Id) {
  static const clang::driver::types::ID kStaticLangageTypes[] = {
      TY_CUDA_DEVICE,   TY_HIP_DEVICE,    TY_PP_CHeader,
      TY_PP_ObjCHeader, TY_PP_CXXHeader,  TY_PP_ObjCXXHeader,
      TY_PP_CXXModule,  TY_LTO_IR,        TY_LTO_BC,
      TY_Plist,         TY_RewrittenObjC, TY_RewrittenLegacyObjC,
      TY_Remap,         TY_PCH,           TY_Object,
      TY_Image,         TY_dSYM,          TY_Dependencies,
      TY_CUDA_FATBIN,   TY_HIP_FATBIN};
  return !llvm::is_contained(kStaticLangageTypes, Id);
}

bool types::appendSuffixForType(ID Id) {
  return Id == TY_PCH || Id == TY_dSYM || Id == TY_CUDA_FATBIN ||
         Id == TY_HIP_FATBIN;
}

bool types::canLipoType(ID Id) {
  return (Id == TY_Nothing ||
          Id == TY_Image ||
          Id == TY_Object ||
          Id == TY_LTO_BC);
}

bool types::isAcceptedByClang(ID Id) {
  switch (Id) {
  default:
    return false;

  case TY_Asm:
  case TY_C: case TY_PP_C:
  case TY_CL:
  case TY_CUDA: case TY_PP_CUDA:
  case TY_CUDA_DEVICE:
  case TY_HIP:
  case TY_PP_HIP:
  case TY_HIP_DEVICE:
  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
  case TY_CXX: case TY_PP_CXX:
  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
  case TY_CHeader: case TY_PP_CHeader:
  case TY_CLHeader:
  case TY_ObjCHeader: case TY_PP_ObjCHeader:
  case TY_CXXHeader: case TY_PP_CXXHeader:
  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
  case TY_CXXModule: case TY_PP_CXXModule:
  case TY_AST: case TY_ModuleFile:
  case TY_LLVM_IR: case TY_LLVM_BC:
    return true;
  }
}

bool types::isObjC(ID Id) {
  switch (Id) {
  default:
    return false;

  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
  case TY_ObjCXX: case TY_PP_ObjCXX:
  case TY_ObjCHeader: case TY_PP_ObjCHeader:
  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias:
    return true;
  }
}

bool types::isCXX(ID Id) {
  switch (Id) {
  default:
    return false;

  case TY_CXX: case TY_PP_CXX:
  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
  case TY_CXXHeader: case TY_PP_CXXHeader:
  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
  case TY_CXXModule: case TY_PP_CXXModule:
  case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
  case TY_HIP:
  case TY_PP_HIP:
  case TY_HIP_DEVICE:
    return true;
  }
}

bool types::isLLVMIR(ID Id) {
  switch (Id) {
  default:
    return false;

  case TY_LLVM_IR:
  case TY_LLVM_BC:
  case TY_LTO_IR:
  case TY_LTO_BC:
    return true;
  }
}

bool types::isCuda(ID Id) {
  switch (Id) {
  default:
    return false;

  case TY_CUDA:
  case TY_PP_CUDA:
  case TY_CUDA_DEVICE:
    return true;
  }
}

bool types::isHIP(ID Id) {
  switch (Id) {
  default:
    return false;

  case TY_HIP:
  case TY_PP_HIP:
  case TY_HIP_DEVICE:
    return true;
  }
}

bool types::isSrcFile(ID Id) {
  return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
}

types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
  return llvm::StringSwitch<types::ID>(Ext)
           .Case("c", TY_C)
           .Case("C", TY_CXX)
           .Case("F", TY_Fortran)
           .Case("f", TY_PP_Fortran)
           .Case("h", TY_CHeader)
           .Case("H", TY_CXXHeader)
           .Case("i", TY_PP_C)
           .Case("m", TY_ObjC)
           .Case("M", TY_ObjCXX)
           .Case("o", TY_Object)
           .Case("S", TY_Asm)
           .Case("s", TY_PP_Asm)
           .Case("bc", TY_LLVM_BC)
           .Case("cc", TY_CXX)
           .Case("CC", TY_CXX)
           .Case("cl", TY_CL)
           .Case("cp", TY_CXX)
           .Case("cu", TY_CUDA)
           .Case("hh", TY_CXXHeader)
           .Case("ii", TY_PP_CXX)
           .Case("ll", TY_LLVM_IR)
           .Case("mi", TY_PP_ObjC)
           .Case("mm", TY_ObjCXX)
           .Case("rs", TY_RenderScript)
           .Case("adb", TY_Ada)
           .Case("ads", TY_Ada)
           .Case("asm", TY_PP_Asm)
           .Case("ast", TY_AST)
           .Case("ccm", TY_CXXModule)
           .Case("cpp", TY_CXX)
           .Case("CPP", TY_CXX)
           .Case("c++", TY_CXX)
           .Case("C++", TY_CXX)
           .Case("cui", TY_PP_CUDA)
           .Case("cxx", TY_CXX)
           .Case("CXX", TY_CXX)
           .Case("F90", TY_Fortran)
           .Case("f90", TY_PP_Fortran)
           .Case("F95", TY_Fortran)
           .Case("f95", TY_PP_Fortran)
           .Case("for", TY_PP_Fortran)
           .Case("FOR", TY_PP_Fortran)
           .Case("fpp", TY_Fortran)
           .Case("FPP", TY_Fortran)
           .Case("gch", TY_PCH)
           .Case("hip", TY_HIP)
           .Case("hpp", TY_CXXHeader)
           .Case("iim", TY_PP_CXXModule)
           .Case("lib", TY_Object)
           .Case("mii", TY_PP_ObjCXX)
           .Case("obj", TY_Object)
           .Case("ifs", TY_IFS)
           .Case("pch", TY_PCH)
           .Case("pcm", TY_ModuleFile)
           .Case("c++m", TY_CXXModule)
           .Case("cppm", TY_CXXModule)
           .Case("cxxm", TY_CXXModule)
           .Default(TY_INVALID);
}

types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
  for (unsigned i=0; i<numTypes; ++i) {
    types::ID Id = (types::ID) (i + 1);
    if (canTypeBeUserSpecified(Id) &&
        strcmp(Name, getInfo(Id).Name) == 0)
      return Id;
  }

  return TY_INVALID;
}

// FIXME: Why don't we just put this list in the defs file, eh.
// FIXME: The list is now in Types.def but for now this function will verify
//        the old behavior and a subsequent change will delete most of the body.
void types::getCompilationPhases(ID Id, llvm::SmallVectorImpl<phases::ID> &P) {
  P = getInfo(Id).Phases;
  assert(0 < P.size() && "Not enough phases in list");
  assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list");
}

void types::getCompilationPhases(const clang::driver::Driver &Driver,
                                 llvm::opt::DerivedArgList &DAL, ID Id,
                                 llvm::SmallVectorImpl<phases::ID> &P) {
  llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhaseList;
  types::getCompilationPhases(Id, PhaseList);

  // Filter to compiler mode. When the compiler is run as a preprocessor then
  // compilation is not an option.
  // -S runs the compiler in Assembly listing mode.
  if (Driver.CCCIsCPP() || DAL.getLastArg(options::OPT_E) ||
      DAL.getLastArg(options::OPT__SLASH_EP) ||
      DAL.getLastArg(options::OPT_M, options::OPT_MM) ||
      DAL.getLastArg(options::OPT__SLASH_P))
    llvm::copy_if(PhaseList, std::back_inserter(P),
                  [](phases::ID Phase) { return Phase <= phases::Preprocess; });

  // --precompile only runs up to precompilation.
  // This is a clang extension and is not compatible with GCC.
  else if (DAL.getLastArg(options::OPT__precompile))
    llvm::copy_if(PhaseList, std::back_inserter(P),
                  [](phases::ID Phase) { return Phase <= phases::Precompile; });

  // Treat Interface Stubs like its own compilation mode.
  else if (DAL.getLastArg(options::OPT_emit_iterface_stubs)) {
    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> IfsModePhaseList;
    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &PL = PhaseList;
    phases::ID LastPhase = phases::IfsMerge;
    if (Id != types::TY_IFS) {
      if (DAL.hasArg(options::OPT_c))
        LastPhase = phases::Compile;
      PL = IfsModePhaseList;
      types::getCompilationPhases(types::TY_IFS_CPP, PL);
    }
    llvm::copy_if(PL, std::back_inserter(P), [&](phases::ID Phase) {
      return Phase <= LastPhase;
    });
  }

  // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
  else if (DAL.getLastArg(options::OPT_fsyntax_only) ||
           DAL.getLastArg(options::OPT_print_supported_cpus) ||
           DAL.getLastArg(options::OPT_module_file_info) ||
           DAL.getLastArg(options::OPT_verify_pch) ||
           DAL.getLastArg(options::OPT_rewrite_objc) ||
           DAL.getLastArg(options::OPT_rewrite_legacy_objc) ||
           DAL.getLastArg(options::OPT__migrate) ||
           DAL.getLastArg(options::OPT__analyze) ||
           DAL.getLastArg(options::OPT_emit_ast))
    llvm::copy_if(PhaseList, std::back_inserter(P),
                  [](phases::ID Phase) { return Phase <= phases::Compile; });

  else if (DAL.getLastArg(options::OPT_S) ||
           DAL.getLastArg(options::OPT_emit_llvm))
    llvm::copy_if(PhaseList, std::back_inserter(P),
                  [](phases::ID Phase) { return Phase <= phases::Backend; });

  else if (DAL.getLastArg(options::OPT_c))
    llvm::copy_if(PhaseList, std::back_inserter(P),
                  [](phases::ID Phase) { return Phase <= phases::Assemble; });

  // Generally means, do every phase until Link.
  else
    P = PhaseList;
}

ID types::lookupCXXTypeForCType(ID Id) {
  switch (Id) {
  default:
    return Id;

  case types::TY_C:
    return types::TY_CXX;
  case types::TY_PP_C:
    return types::TY_PP_CXX;
  case types::TY_CHeader:
    return types::TY_CXXHeader;
  case types::TY_PP_CHeader:
    return types::TY_PP_CXXHeader;
  }
}

ID types::lookupHeaderTypeForSourceType(ID Id) {
  switch (Id) {
  default:
    return Id;

  // FIXME: Handle preprocessed input types.
  case types::TY_C:
    return types::TY_CHeader;
  case types::TY_CXX:
  case types::TY_CXXModule:
    return types::TY_CXXHeader;
  case types::TY_ObjC:
    return types::TY_ObjCHeader;
  case types::TY_ObjCXX:
    return types::TY_ObjCXXHeader;
  case types::TY_CL:
    return types::TY_CLHeader;
  }
}
