//=== ASTTableGen.h - Common definitions for AST node tablegen --*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_AST_TABLEGEN_H
#define CLANG_AST_TABLEGEN_H

#include "llvm/TableGen/Record.h"
#include "llvm/ADT/STLExtras.h"

// These are spellings in the tblgen files.

#define HasPropertiesClassName "HasProperties"

// ASTNodes and their common fields.  `Base` is actually defined
// in subclasses, but it's still common across the hierarchies.
#define ASTNodeClassName "ASTNode"
#define BaseFieldName "Base"
#define AbstractFieldName "Abstract"

// Comment node hierarchy.
#define CommentNodeClassName "CommentNode"

// Decl node hierarchy.
#define DeclNodeClassName "DeclNode"
#define DeclContextNodeClassName "DeclContext"

// Stmt node hierarchy.
#define StmtNodeClassName "StmtNode"

// Type node hierarchy.
#define TypeNodeClassName "TypeNode"
#define AlwaysDependentClassName "AlwaysDependent"
#define NeverCanonicalClassName "NeverCanonical"
#define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
#define LeafTypeClassName "LeafType"

// Cases of various non-ASTNode structured types like DeclarationName.
#define TypeKindClassName "PropertyTypeKind"
#define KindTypeFieldName "KindType"
#define KindPropertyNameFieldName "KindPropertyName"
#define TypeCaseClassName "PropertyTypeCase"

// Properties of AST nodes.
#define PropertyClassName "Property"
#define ClassFieldName "Class"
#define NameFieldName "Name"
#define TypeFieldName "Type"
#define ReadFieldName "Read"

// Types of properties.
#define PropertyTypeClassName "PropertyType"
#define CXXTypeNameFieldName "CXXName"
#define PassByReferenceFieldName "PassByReference"
#define ConstWhenWritingFieldName "ConstWhenWriting"
#define ConditionalCodeFieldName "Conditional"
#define PackOptionalCodeFieldName "PackOptional"
#define UnpackOptionalCodeFieldName "UnpackOptional"
#define BufferElementTypesFieldName "BufferElementTypes"
#define ArrayTypeClassName "Array"
#define ArrayElementTypeFieldName "Element"
#define OptionalTypeClassName "Optional"
#define OptionalElementTypeFieldName "Element"
#define SubclassPropertyTypeClassName "SubclassPropertyType"
#define SubclassBaseTypeFieldName "Base"
#define SubclassClassNameFieldName "SubclassName"
#define EnumPropertyTypeClassName "EnumPropertyType"

// Write helper rules.
#define ReadHelperRuleClassName "ReadHelper"
#define HelperCodeFieldName "Code"

// Creation rules.
#define CreationRuleClassName "Creator"
#define CreateFieldName "Create"

// Override rules.
#define OverrideRuleClassName "Override"
#define IgnoredPropertiesFieldName "IgnoredProperties"

namespace clang {
namespace tblgen {

class WrappedRecord {
  llvm::Record *Record;

protected:
  WrappedRecord(llvm::Record *record = nullptr) : Record(record) {}

  llvm::Record *get() const {
    assert(Record && "accessing null record");
    return Record;
  }

public:
  llvm::Record *getRecord() const { return Record; }

  explicit operator bool() const { return Record != nullptr; }

  llvm::ArrayRef<llvm::SMLoc> getLoc() const {
    return get()->getLoc();
  }

  /// Does the node inherit from the given TableGen class?
  bool isSubClassOf(llvm::StringRef className) const {
    return get()->isSubClassOf(className);
  }

  template <class NodeClass>
  NodeClass getAs() const {
    return (isSubClassOf(NodeClass::getTableGenNodeClassName())
              ? NodeClass(get()) : NodeClass());
  }

  friend bool operator<(WrappedRecord lhs, WrappedRecord rhs) {
    assert(lhs && rhs && "sorting null nodes");
    return lhs.get()->getName() < rhs.get()->getName();
  }
  friend bool operator>(WrappedRecord lhs, WrappedRecord rhs) {
    return rhs < lhs;
  }
  friend bool operator<=(WrappedRecord lhs, WrappedRecord rhs) {
    return !(rhs < lhs);
  }
  friend bool operator>=(WrappedRecord lhs, WrappedRecord rhs) {
    return !(lhs < rhs);
  }
  friend bool operator==(WrappedRecord lhs, WrappedRecord rhs) {
    // This should handle null nodes.
    return lhs.getRecord() == rhs.getRecord();
  }
  friend bool operator!=(WrappedRecord lhs, WrappedRecord rhs) {
    return !(lhs == rhs);
  }
};

/// Anything in the AST that has properties.
class HasProperties : public WrappedRecord {
public:
  static constexpr llvm::StringRef ClassName = HasPropertiesClassName;

  HasProperties(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  llvm::StringRef getName() const;

  static llvm::StringRef getTableGenNodeClassName() {
    return HasPropertiesClassName;
  }
};

/// An (optional) reference to a TableGen node representing a class
/// in one of Clang's AST hierarchies.
class ASTNode : public HasProperties {
public:
  ASTNode(llvm::Record *record = nullptr) : HasProperties(record) {}

  llvm::StringRef getName() const {
    return get()->getName();
  }

  /// Return the node for the base, if there is one.
  ASTNode getBase() const {
    return get()->getValueAsOptionalDef(BaseFieldName);
  }

  /// Is the corresponding class abstract?
  bool isAbstract() const {
    return get()->getValueAsBit(AbstractFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return ASTNodeClassName;
  }
};

class DeclNode : public ASTNode {
public:
  DeclNode(llvm::Record *record = nullptr) : ASTNode(record) {}

  llvm::StringRef getId() const;
  std::string getClassName() const;
  DeclNode getBase() const { return DeclNode(ASTNode::getBase().getRecord()); }

  static llvm::StringRef getASTHierarchyName() {
    return "Decl";
  }
  static llvm::StringRef getASTIdTypeName() {
    return "Decl::Kind";
  }
  static llvm::StringRef getASTIdAccessorName() {
    return "getKind";
  }
  static llvm::StringRef getTableGenNodeClassName() {
    return DeclNodeClassName;
  }
};

class TypeNode : public ASTNode {
public:
  TypeNode(llvm::Record *record = nullptr) : ASTNode(record) {}

  llvm::StringRef getId() const;
  llvm::StringRef getClassName() const;
  TypeNode getBase() const { return TypeNode(ASTNode::getBase().getRecord()); }

  static llvm::StringRef getASTHierarchyName() {
    return "Type";
  }
  static llvm::StringRef getASTIdTypeName() {
    return "Type::TypeClass";
  }
  static llvm::StringRef getASTIdAccessorName() {
    return "getTypeClass";
  }
  static llvm::StringRef getTableGenNodeClassName() {
    return TypeNodeClassName;
  }
};

class StmtNode : public ASTNode {
public:
  StmtNode(llvm::Record *record = nullptr) : ASTNode(record) {}

  std::string getId() const;
  llvm::StringRef getClassName() const;
  StmtNode getBase() const { return StmtNode(ASTNode::getBase().getRecord()); }

  static llvm::StringRef getASTHierarchyName() {
    return "Stmt";
  }
  static llvm::StringRef getASTIdTypeName() {
    return "Stmt::StmtClass";
  }
  static llvm::StringRef getASTIdAccessorName() {
    return "getStmtClass";
  }
  static llvm::StringRef getTableGenNodeClassName() {
    return StmtNodeClassName;
  }
};

/// The type of a property.
class PropertyType : public WrappedRecord {
public:
  PropertyType(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  /// Is this a generic specialization (i.e. `Array<T>` or `Optional<T>`)?
  bool isGenericSpecialization() const {
    return get()->isAnonymous();
  }

  /// The abstract type name of the property.  Doesn't work for generic
  /// specializations.
  llvm::StringRef getAbstractTypeName() const {
    return get()->getName();
  }

  /// The C++ type name of the property.  Doesn't work for generic
  /// specializations.
  llvm::StringRef getCXXTypeName() const {
    return get()->getValueAsString(CXXTypeNameFieldName);
  }
  void emitCXXValueTypeName(bool forRead, llvm::raw_ostream &out) const;

  /// Whether the C++ type should be passed around by reference.
  bool shouldPassByReference() const {
    return get()->getValueAsBit(PassByReferenceFieldName);
  }

  /// Whether the C++ type should have 'const' prepended when working with
  /// a value of the type being written.
  bool isConstWhenWriting() const {
    return get()->getValueAsBit(ConstWhenWritingFieldName);
  }

  /// If this is `Array<T>`, return `T`; otherwise return null.
  PropertyType getArrayElementType() const {
    if (isSubClassOf(ArrayTypeClassName))
      return get()->getValueAsDef(ArrayElementTypeFieldName);
    return nullptr;
  }

  /// If this is `Optional<T>`, return `T`; otherwise return null.
  PropertyType getOptionalElementType() const {
    if (isSubClassOf(OptionalTypeClassName))
      return get()->getValueAsDef(OptionalElementTypeFieldName);
    return nullptr;
  }

  /// If this is a subclass type, return its superclass type.
  PropertyType getSuperclassType() const {
    if (isSubClassOf(SubclassPropertyTypeClassName))
      return get()->getValueAsDef(SubclassBaseTypeFieldName);
    return nullptr;
  }

  // Given that this is a subclass type, return the C++ name of its
  // subclass type.  This is just the bare class name, suitable for
  // use in `cast<>`.
  llvm::StringRef getSubclassClassName() const {
    return get()->getValueAsString(SubclassClassNameFieldName);
  }

  /// Does this represent an enum type?
  bool isEnum() const {
    return isSubClassOf(EnumPropertyTypeClassName);
  }

  llvm::StringRef getPackOptionalCode() const {
    return get()->getValueAsString(PackOptionalCodeFieldName);
  }

  llvm::StringRef getUnpackOptionalCode() const {
    return get()->getValueAsString(UnpackOptionalCodeFieldName);
  }

  std::vector<llvm::Record*> getBufferElementTypes() const {
    return get()->getValueAsListOfDefs(BufferElementTypesFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return PropertyTypeClassName;
  }
};

/// A rule for returning the kind of a type.
class TypeKindRule : public WrappedRecord {
public:
  TypeKindRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  /// Return the type to which this applies.
  PropertyType getParentType() const {
    return get()->getValueAsDef(TypeFieldName);
  }

  /// Return the type of the kind.
  PropertyType getKindType() const {
    return get()->getValueAsDef(KindTypeFieldName);
  }

  /// Return the name to use for the kind property.
  llvm::StringRef getKindPropertyName() const {
    return get()->getValueAsString(KindPropertyNameFieldName);
  }

  /// Return the code for reading the kind value.
  llvm::StringRef getReadCode() const {
    return get()->getValueAsString(ReadFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return TypeKindClassName;
  }
};

/// An implementation case of a property type.
class TypeCase : public HasProperties {
public:
  TypeCase(llvm::Record *record = nullptr) : HasProperties(record) {}

  /// Return the name of this case.
  llvm::StringRef getCaseName() const {
    return get()->getValueAsString(NameFieldName);
  }

  /// Return the type of which this is a case.
  PropertyType getParentType() const {
    return get()->getValueAsDef(TypeFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return TypeCaseClassName;
  }
};

/// A property of an AST node.
class Property : public WrappedRecord {
public:
  Property(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  /// Return the name of this property.
  llvm::StringRef getName() const {
    return get()->getValueAsString(NameFieldName);
  }

  /// Return the type of this property.
  PropertyType getType() const {
    return get()->getValueAsDef(TypeFieldName);
  }

  /// Return the class of which this is a property.
  HasProperties getClass() const {
    return get()->getValueAsDef(ClassFieldName);
  }

  /// Return the code for reading this property.
  llvm::StringRef getReadCode() const {
    return get()->getValueAsString(ReadFieldName);
  }

  /// Return the code for determining whether to add this property.
  llvm::StringRef getCondition() const {
    return get()->getValueAsString(ConditionalCodeFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return PropertyClassName;
  }
};

/// A rule for running some helper code for reading properties from
/// a value (which is actually done when writing the value out).
class ReadHelperRule : public WrappedRecord {
public:
  ReadHelperRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  /// Return the class for which this is a creation rule.
  /// Should never be abstract.
  HasProperties getClass() const {
    return get()->getValueAsDef(ClassFieldName);
  }

  llvm::StringRef getHelperCode() const {
    return get()->getValueAsString(HelperCodeFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return ReadHelperRuleClassName;
  }
};

/// A rule for how to create an AST node from its properties.
class CreationRule : public WrappedRecord {
public:
  CreationRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  /// Return the class for which this is a creation rule.
  /// Should never be abstract.
  HasProperties getClass() const {
    return get()->getValueAsDef(ClassFieldName);
  }

  llvm::StringRef getCreationCode() const {
    return get()->getValueAsString(CreateFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return CreationRuleClassName;
  }
};

/// A rule which overrides the standard rules for serializing an AST node.
class OverrideRule : public WrappedRecord {
public:
  OverrideRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}

  /// Return the class for which this is an override rule.
  /// Should never be abstract.
  HasProperties getClass() const {
    return get()->getValueAsDef(ClassFieldName);
  }

  /// Return a set of properties that are unnecessary when serializing
  /// this AST node.  Generally this is used for inherited properties
  /// that are derived for this subclass.
  std::vector<llvm::StringRef> getIgnoredProperties() const {
    return get()->getValueAsListOfStrings(IgnoredPropertiesFieldName);
  }

  static llvm::StringRef getTableGenNodeClassName() {
    return OverrideRuleClassName;
  }
};

/// A visitor for an AST node hierarchy.  Note that `base` can be null for
/// the root class.
template <class NodeClass>
using ASTNodeHierarchyVisitor =
  llvm::function_ref<void(NodeClass node, NodeClass base)>;

void visitASTNodeHierarchyImpl(llvm::RecordKeeper &records,
                               llvm::StringRef nodeClassName,
                               ASTNodeHierarchyVisitor<ASTNode> visit);

template <class NodeClass>
void visitASTNodeHierarchy(llvm::RecordKeeper &records,
                           ASTNodeHierarchyVisitor<NodeClass> visit) {
  visitASTNodeHierarchyImpl(records, NodeClass::getTableGenNodeClassName(),
                            [visit](ASTNode node, ASTNode base) {
                              visit(NodeClass(node.getRecord()),
                                    NodeClass(base.getRecord()));
                            });
}

} // end namespace clang::tblgen
} // end namespace clang

#endif
