//=== ClangTypeNodesEmitter.cpp - Generate type node tables -----*- 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
//
//===----------------------------------------------------------------------===//
//
// This tblgen backend emits the node table (the .def file) for Clang
// type nodes.
//
// This file defines the AST type info database. Each type node is
// enumerated by providing its name (e.g., "Builtin" or "Enum") and
// base class (e.g., "Type" or "TagType"). Depending on where in the
// abstract syntax tree the type will show up, the enumeration uses
// one of five different macros:
//
//    TYPE(Class, Base) - A type that can show up anywhere in the AST,
//    and might be dependent, canonical, or non-canonical. All clients
//    will need to understand these types.
//
//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
//    the type hierarchy but has no concrete instances.
//
//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up
//    anywhere in the AST but will never be a part of a canonical
//    type. Clients that only need to deal with canonical types
//    (ignoring, e.g., typedefs and other type aliases used for
//    pretty-printing) can ignore these types.
//
//    DEPENDENT_TYPE(Class, Base) - A type that will only show up
//    within a C++ template that has not been instantiated, e.g., a
//    type that is always dependent. Clients that do not need to deal
//    with uninstantiated C++ templates can ignore these types.
//
//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
//    is non-canonical unless it is dependent.  Defaults to TYPE because
//    it is neither reliably dependent nor reliably non-canonical.
//
// There is a sixth macro, independent of the others.  Most clients
// will not need to use it.
//
//    LEAF_TYPE(Class) - A type that never has inner types.  Clients
//    which can operate on such types more efficiently may wish to do so.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <set>
#include <string>
#include <vector>
#include "TableGenBackends.h"

using namespace llvm;

// These are spellings in the generated output.
#define TypeMacroName "TYPE"
#define AbstractTypeMacroName "ABSTRACT_TYPE"
#define DependentTypeMacroName "DEPENDENT_TYPE"
#define NonCanonicalTypeMacroName "NON_CANONICAL_TYPE"
#define NonCanonicalUnlessDependentTypeMacroName "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"
#define TypeMacroArgs "(Class, Base)"
#define LastTypeMacroName "LAST_TYPE"
#define LeafTypeMacroName "LEAF_TYPE"

// These are spellings in the tblgen file.
// (Type is also used for the spelling of the AST class.)
#define TypeClassName "Type"
#define DerivedTypeClassName "DerivedType"
#define AlwaysDependentClassName "AlwaysDependent"
#define NeverCanonicalClassName "NeverCanonical"
#define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
#define LeafTypeClassName "LeafType"
#define AbstractFieldName "Abstract"
#define BaseFieldName "Base"

static StringRef getIdForType(Record *type) {
	// The record name is expected to be the full C++ class name,
	// including "Type".  Check for that and strip it off.
	auto fullName = type->getName();
	if (!fullName.endswith("Type"))
		PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");
	return fullName.drop_back(4);
}

namespace {
class TypeNodeEmitter {
	RecordKeeper &Records;
	raw_ostream &Out;
	const std::vector<Record*> Types;
	std::vector<StringRef> MacrosToUndef;

public:
	TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
		: Records(records), Out(out),
			Types(Records.getAllDerivedDefinitions("Type")) {
	}

	void emit();

private:
	void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,
													StringRef args);

	void emitNodeInvocations();
	void emitLastNodeInvocation();
	void emitLeafNodeInvocations();

	void addMacroToUndef(StringRef macroName);
	void emitUndefs();
};
}

void TypeNodeEmitter::emit() {
	if (Types.empty())
		PrintFatalError("no Type records in input!");

	emitSourceFileHeader("An x-macro database of Clang type nodes", Out);

	// Preamble
	addMacroToUndef(TypeMacroName);
	addMacroToUndef(AbstractTypeMacroName);
	emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
	emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
	emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
	emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName, 
										 TypeMacroArgs);

	// Invocations.
	emitNodeInvocations();
	emitLastNodeInvocation();
	emitLeafNodeInvocations();

	// Postmatter
	emitUndefs();
}

void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
																				 StringRef fallbackMacroName,
																				 StringRef args) {
  Out << "#ifndef " << macroName << "\n";
  Out << "#  define " << macroName << args
  	  << " " << fallbackMacroName << args << "\n";
  Out << "#endif\n";

  addMacroToUndef(macroName);
}

void TypeNodeEmitter::emitNodeInvocations() {
	for (auto type : Types) {
		// The name with the Type suffix.
		StringRef id = getIdForType(type);

		// Figure out which macro to use.
		StringRef macroName;
		auto setMacroName = [&](StringRef newName) {
			if (!macroName.empty())
				PrintFatalError(type->getLoc(),
												Twine("conflict when computing macro name for "
															"Type node: trying to use both \"")
													+ macroName + "\" and \"" + newName + "\"");
			macroName = newName;
		};
		if (type->isSubClassOf(AlwaysDependentClassName))
			setMacroName(DependentTypeMacroName);
		if (type->isSubClassOf(NeverCanonicalClassName))
			setMacroName(NonCanonicalTypeMacroName);
		if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))
			setMacroName(NonCanonicalUnlessDependentTypeMacroName);
		if (type->getValueAsBit(AbstractFieldName))
			setMacroName(AbstractTypeMacroName);
		if (macroName.empty())
			macroName = TypeMacroName;

		// Compute the base class.
		StringRef baseName = TypeClassName;
		if (type->isSubClassOf(DerivedTypeClassName))
			baseName = type->getValueAsDef(BaseFieldName)->getName();

		// Generate the invocation line.
		Out << macroName << "(" << id << ", " << baseName << ")\n";
	}
}

void TypeNodeEmitter::emitLastNodeInvocation() {
	// We check that this is non-empty earlier.
	Out << "#ifdef " LastTypeMacroName "\n"
	       LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"
				 "#undef " LastTypeMacroName "\n"
				 "#endif\n";
}

void TypeNodeEmitter::emitLeafNodeInvocations() {
	Out << "#ifdef " LeafTypeMacroName "\n";

	for (auto type : Types) {
		if (!type->isSubClassOf(LeafTypeClassName)) continue;
		Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";
	}

	Out << "#undef " LeafTypeMacroName "\n"
				 "#endif\n";
}

void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {
	MacrosToUndef.push_back(macroName);
}

void TypeNodeEmitter::emitUndefs() {
	for (auto &macroName : MacrosToUndef) {
		Out << "#undef " << macroName << "\n";
	}
}

void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) {
	TypeNodeEmitter(records, out).emit();
}
