//=== 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/Record.h"
#include "llvm/TableGen/Error.h"
#include <optional>

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

llvm::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(Record *node, StringRef suffix) {
  StringRef nodeName = node->getName();
  if (!nodeName.endswith(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(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);
  }

  // Find all the nodes in the hierarchy.
  auto nodes = records.getAllDerivedDefinitions(nodeClassName);

  // Derive the child map.
  ChildMap hierarchy;
  ASTNode root;
  for (ASTNode node : nodes) {
    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(RecordKeeper &records,
                                              StringRef nodeClassName,
                                      ASTNodeHierarchyVisitor<ASTNode> visit) {
  visitHierarchy(records, nodeClassName, visit);
}
