//===-- ASTTableGen.cpp - Helper functions for working with AST records ---===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines some helper functions for working with tblegen reocrds
// for the Clang AST: that is, the contents of files such as DeclNodes.td,
// StmtNodes.td, and TypeNodes.td.
//
//===----------------------------------------------------------------------===//

#include "ASTTableGen.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

using namespace llvm;
using namespace clang;
using namespace clang::tblgen;

StringRef clang::tblgen::HasProperties::getName() const {
  if (auto node = getAs<ASTNode>()) {
    return node.getName();
  } else if (auto typeCase = getAs<TypeCase>()) {
    return typeCase.getCaseName();
  } else {
    PrintFatalError(getLoc(), "unexpected node declaring properties");
  }
}

static StringRef removeExpectedNodeNameSuffix(const Record *node,
                                              StringRef suffix) {
  StringRef nodeName = node->getName();
  if (!nodeName.ends_with(suffix)) {
    PrintFatalError(node->getLoc(),
                    Twine("name of node doesn't end in ") + suffix);
  }
  return nodeName.drop_back(suffix.size());
}

// Decl node names don't end in Decl for historical reasons, and it would
// be somewhat annoying to fix now.  Conveniently, this means the ID matches
// is exactly the node name, and the class name is simply that plus Decl.
std::string clang::tblgen::DeclNode::getClassName() const {
  return (Twine(getName()) + "Decl").str();
}
StringRef clang::tblgen::DeclNode::getId() const {
  return getName();
}

// Type nodes are all named ending in Type, just like the corresponding
// C++ class, and the ID just strips this suffix.
StringRef clang::tblgen::TypeNode::getClassName() const {
  return getName();
}
StringRef clang::tblgen::TypeNode::getId() const {
  return removeExpectedNodeNameSuffix(getRecord(), "Type");
}

// Stmt nodes are named the same as the C++ class, which has no regular
// naming convention (all the non-expression statements end in Stmt,
// and *many* expressions end in Expr, but there are also several
// core expression classes like IntegerLiteral and BinaryOperator with
// no standard suffix).  The ID adds "Class" for historical reasons.
StringRef clang::tblgen::StmtNode::getClassName() const {
  return getName();
}
std::string clang::tblgen::StmtNode::getId() const {
  return (Twine(getName()) + "Class").str();
}

/// Emit a string spelling out the C++ value type.
void PropertyType::emitCXXValueTypeName(bool forRead, raw_ostream &out) const {
  if (!isGenericSpecialization()) {
    if (!forRead && isConstWhenWriting())
      out << "const ";
    out << getCXXTypeName();
  } else if (auto elementType = getArrayElementType()) {
    out << "llvm::ArrayRef<";
    elementType.emitCXXValueTypeName(forRead, out);
    out << ">";
  } else if (auto valueType = getOptionalElementType()) {
    out << "std::optional<";
    valueType.emitCXXValueTypeName(forRead, out);
    out << ">";
  } else {
    //PrintFatalError(getLoc(), "unexpected generic property type");
    abort();
  }
}

// A map from a node to each of its child nodes.
using ChildMap = std::multimap<ASTNode, ASTNode>;

static void visitASTNodeRecursive(ASTNode node, ASTNode base,
                                  const ChildMap &map,
                                  ASTNodeHierarchyVisitor<ASTNode> visit) {
  visit(node, base);

  auto i = map.lower_bound(node), e = map.upper_bound(node);
  for (; i != e; ++i) {
    visitASTNodeRecursive(i->second, node, map, visit);
  }
}

static void visitHierarchy(const RecordKeeper &records, StringRef nodeClassName,
                           ASTNodeHierarchyVisitor<ASTNode> visit) {
  // Check for the node class, just as a basic correctness check.
  if (!records.getClass(nodeClassName)) {
    PrintFatalError(Twine("cannot find definition for node class ")
                      + nodeClassName);
  }

  // Derive the child map for all nodes in the hierarchy.
  ChildMap hierarchy;
  ASTNode root;
  for (ASTNode node : records.getAllDerivedDefinitions(nodeClassName)) {
    if (auto base = node.getBase())
      hierarchy.insert(std::make_pair(base, node));
    else if (root)
      PrintFatalError(node.getLoc(),
                      "multiple root nodes in " + nodeClassName + " hierarchy");
    else
      root = node;
  }
  if (!root)
    PrintFatalError(Twine("no root node in ") + nodeClassName + " hierarchy");

  // Now visit the map recursively, starting at the root node.
  visitASTNodeRecursive(root, ASTNode(), hierarchy, visit);
}

void clang::tblgen::visitASTNodeHierarchyImpl(
    const RecordKeeper &records, StringRef nodeClassName,
    ASTNodeHierarchyVisitor<ASTNode> visit) {
  visitHierarchy(records, nodeClassName, visit);
}
