//=- ClangSACheckersEmitter.cpp - Generate Clang SA checkers tables -*- C++ -*-
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend emits Clang Static Analyzer checkers tables.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckersEmitter.h"
#include "llvm/TableGen/Record.h"
#include "llvm/ADT/DenseSet.h"
#include <map>
#include <string>
using namespace llvm;

//===----------------------------------------------------------------------===//
// Static Analyzer Checkers Tables generation
//===----------------------------------------------------------------------===//

/// \brief True if it is specified hidden or a parent package is specified
/// as hidden, otherwise false.
static bool isHidden(const Record &R) {
  if (R.getValueAsBit("Hidden"))
    return true;
  // Not declared as hidden, check the parent package if it is hidden.
  if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("ParentPackage")))
    return isHidden(*DI->getDef());

  return false;
}

static bool isCheckerNamed(const Record *R) {
  return !R->getValueAsString("CheckerName").empty();
}

static std::string getPackageFullName(const Record *R);

static std::string getParentPackageFullName(const Record *R) {
  std::string name;
  if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage")))
    name = getPackageFullName(DI->getDef());
  return name;
}

static std::string getPackageFullName(const Record *R) {
  std::string name = getParentPackageFullName(R);
  if (!name.empty()) name += ".";
  return name + R->getValueAsString("PackageName");
}

static std::string getCheckerFullName(const Record *R) {
  std::string name = getParentPackageFullName(R);
  if (isCheckerNamed(R)) {
    if (!name.empty()) name += ".";
    name += R->getValueAsString("CheckerName");
  }
  return name;
}

static std::string getStringValue(const Record &R, StringRef field) {
  if (StringInit *
        SI = dynamic_cast<StringInit*>(R.getValueInit(field)))
    return SI->getValue();
  return std::string();
}

namespace {
struct GroupInfo {
  llvm::DenseSet<const Record*> Checkers;
  llvm::DenseSet<const Record *> SubGroups;
  bool Hidden;
  unsigned Index;

  GroupInfo() : Hidden(false) { }
};
}

static void addPackageToCheckerGroup(const Record *package, const Record *group,
                  llvm::DenseMap<const Record *, GroupInfo *> &recordGroupMap) {
  llvm::DenseSet<const Record *> &checkers = recordGroupMap[package]->Checkers;
  for (llvm::DenseSet<const Record *>::iterator
         I = checkers.begin(), E = checkers.end(); I != E; ++I)
    recordGroupMap[group]->Checkers.insert(*I);

  llvm::DenseSet<const Record *> &subGroups = recordGroupMap[package]->SubGroups;
  for (llvm::DenseSet<const Record *>::iterator
         I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
    addPackageToCheckerGroup(*I, group, recordGroupMap);
}

void ClangSACheckersEmitter::run(raw_ostream &OS) {
  std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker");
  llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap;
  for (unsigned i = 0, e = checkers.size(); i != e; ++i)
    checkerRecIndexMap[checkers[i]] = i;

  // Invert the mapping of checkers to package/group into a one to many
  // mapping of packages/groups to checkers.
  std::map<std::string, GroupInfo> groupInfoByName;
  llvm::DenseMap<const Record *, GroupInfo *> recordGroupMap;

  std::vector<Record*> packages = Records.getAllDerivedDefinitions("Package");
  for (unsigned i = 0, e = packages.size(); i != e; ++i) {
    Record *R = packages[i];
    std::string fullName = getPackageFullName(R);
    if (!fullName.empty()) {
      GroupInfo &info = groupInfoByName[fullName];
      info.Hidden = isHidden(*R);
      recordGroupMap[R] = &info;
    }
  }

  std::vector<Record*>
      checkerGroups = Records.getAllDerivedDefinitions("CheckerGroup");
  for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) {
    Record *R = checkerGroups[i];
    std::string name = R->getValueAsString("GroupName");
    if (!name.empty()) {
      GroupInfo &info = groupInfoByName[name];
      recordGroupMap[R] = &info;
    }
  }

  for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
    Record *R = checkers[i];
    Record *package = 0;
    if (DefInit *
          DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage")))
      package = DI->getDef();
    if (!isCheckerNamed(R) && !package)
      throw "Checker '" + R->getName() + "' is neither named, nor in a package!";

    if (isCheckerNamed(R)) {
      // Create a pseudo-group to hold this checker.
      std::string fullName = getCheckerFullName(R);
      GroupInfo &info = groupInfoByName[fullName];
      info.Hidden = R->getValueAsBit("Hidden");
      recordGroupMap[R] = &info;
      info.Checkers.insert(R);
    } else {
      recordGroupMap[package]->Checkers.insert(R);
    }

    Record *currR = isCheckerNamed(R) ? R : package;
    // Insert the checker and its parent packages into the subgroups set of
    // the corresponding parent package.
    while (DefInit *DI
             = dynamic_cast<DefInit*>(currR->getValueInit("ParentPackage"))) {
      Record *parentPackage = DI->getDef();
      recordGroupMap[parentPackage]->SubGroups.insert(currR);
      currR = parentPackage;
    }
    // Insert the checker into the set of its group.
    if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group")))
      recordGroupMap[DI->getDef()]->Checkers.insert(R);
  }

  // If a package is in group, add all its checkers and its sub-packages
  // checkers into the group.
  for (unsigned i = 0, e = packages.size(); i != e; ++i)
    if (DefInit *DI = dynamic_cast<DefInit*>(packages[i]->getValueInit("Group")))
      addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap);

  typedef std::map<std::string, const Record *> SortedRecords;
  typedef llvm::DenseMap<const Record *, unsigned> RecToSortIndex;

  SortedRecords sortedGroups;
  RecToSortIndex groupToSortIndex;
  OS << "\n#ifdef GET_GROUPS\n";
  {
    for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i)
      sortedGroups[checkerGroups[i]->getValueAsString("GroupName")]
                   = checkerGroups[i];

    unsigned sortIndex = 0;
    for (SortedRecords::iterator
           I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) {
      const Record *R = I->second;
  
      OS << "GROUP(" << "\"";
      OS.write_escaped(R->getValueAsString("GroupName")) << "\"";
      OS << ")\n";

      groupToSortIndex[R] = sortIndex++;
    }
  }
  OS << "#endif // GET_GROUPS\n\n";

  OS << "\n#ifdef GET_PACKAGES\n";
  {
    SortedRecords sortedPackages;
    for (unsigned i = 0, e = packages.size(); i != e; ++i)
      sortedPackages[getPackageFullName(packages[i])] = packages[i];
  
    for (SortedRecords::iterator
           I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) {
      const Record &R = *I->second;
  
      OS << "PACKAGE(" << "\"";
      OS.write_escaped(getPackageFullName(&R)) << "\", ";
      // Group index
      if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group")))
        OS << groupToSortIndex[DI->getDef()] << ", ";
      else
        OS << "-1, ";
      // Hidden bit
      if (isHidden(R))
        OS << "true";
      else
        OS << "false";
      OS << ")\n";
    }
  }
  OS << "#endif // GET_PACKAGES\n\n";
  
  OS << "\n#ifdef GET_CHECKERS\n";
  for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
    const Record &R = *checkers[i];

    OS << "CHECKER(" << "\"";
    std::string name;
    if (isCheckerNamed(&R))
      name = getCheckerFullName(&R);
    OS.write_escaped(name) << "\", ";
    OS << R.getName() << ", ";
    OS << getStringValue(R, "DescFile") << ", ";
    OS << "\"";
    OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
    // Group index
    if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group")))
      OS << groupToSortIndex[DI->getDef()] << ", ";
    else
      OS << "-1, ";
    // Hidden bit
    if (isHidden(R))
      OS << "true";
    else
      OS << "false";
    OS << ")\n";
  }
  OS << "#endif // GET_CHECKERS\n\n";

  unsigned index = 0;
  for (std::map<std::string, GroupInfo>::iterator
         I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I)
    I->second.Index = index++;

  // Walk through the packages/groups/checkers emitting an array for each
  // set of checkers and an array for each set of subpackages.

  OS << "\n#ifdef GET_MEMBER_ARRAYS\n";
  unsigned maxLen = 0;
  for (std::map<std::string, GroupInfo>::iterator
         I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) {
    maxLen = std::max(maxLen, (unsigned)I->first.size());

    llvm::DenseSet<const Record *> &checkers = I->second.Checkers;
    if (!checkers.empty()) {
      OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
      // Make the output order deterministic.
      std::map<int, const Record *> sorted;
      for (llvm::DenseSet<const Record *>::iterator
             I = checkers.begin(), E = checkers.end(); I != E; ++I)
        sorted[(*I)->getID()] = *I;

      for (std::map<int, const Record *>::iterator
             I = sorted.begin(), E = sorted.end(); I != E; ++I)
        OS << checkerRecIndexMap[I->second] << ", ";
      OS << "-1 };\n";
    }
    
    llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups;
    if (!subGroups.empty()) {
      OS << "static const short SubPackageArray" << I->second.Index << "[] = { ";
      // Make the output order deterministic.
      std::map<int, const Record *> sorted;
      for (llvm::DenseSet<const Record *>::iterator
             I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
        sorted[(*I)->getID()] = *I;

      for (std::map<int, const Record *>::iterator
             I = sorted.begin(), E = sorted.end(); I != E; ++I) {
        OS << recordGroupMap[I->second]->Index << ", ";
      }
      OS << "-1 };\n";
    }
  }
  OS << "#endif // GET_MEMBER_ARRAYS\n\n";

  OS << "\n#ifdef GET_CHECKNAME_TABLE\n";
  for (std::map<std::string, GroupInfo>::iterator
         I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) {
    // Group option string.
    OS << "  { \"";
    OS.write_escaped(I->first) << "\","
                               << std::string(maxLen-I->first.size()+1, ' ');
    
    if (I->second.Checkers.empty())
      OS << "0, ";
    else
      OS << "CheckerArray" << I->second.Index << ", ";
    
    // Subgroups.
    if (I->second.SubGroups.empty())
      OS << "0, ";
    else
      OS << "SubPackageArray" << I->second.Index << ", ";

    OS << (I->second.Hidden ? "true" : "false");

    OS << " },\n";
  }
  OS << "#endif // GET_CHECKNAME_TABLE\n\n";
}
