//=== 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"

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 << "llvm::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 sanity 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);
}
