tblgen 0.9.1

Safe Rust bindings for TableGen.
// Original work Copyright 2016 Alexander Stocko <as@coder.gg>.
// Modified work Copyright 2023 Daan Vanoverloop
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#ifndef _CTABLEGEN_TABLEGEN_HPP_
#define _CTABLEGEN_TABLEGEN_HPP_

#include <memory>
#include <utility>

#include <llvm/Support/CommandLine.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/ToolOutputFile.h>
#include <llvm/TableGen/Error.h>
#include <llvm/TableGen/Parser.h>
#include <llvm/TableGen/Record.h>

#include "TableGen.h"
#include "Types.h"
#include "llvm/Support/CBindingWrapping.h"

namespace ctablegen {

typedef std::map<std::string, std::unique_ptr<llvm::Record>, std::less<>>
    RecordMap;
typedef std::vector<const llvm::Record *> RecordVector;
typedef std::pair<std::string, llvm::TypedInit *> DagPair;

class TableGenParser {
public:
  TableGenParser() {}
  bool addSource(const char *source);
  void addSourceFile(const llvm::StringRef source);
  void addIncludeDirectory(const llvm::StringRef include);
  llvm::RecordKeeper *parse();

  llvm::SourceMgr sourceMgr;

private:
  std::vector<std::string> includeDirs;
  std::vector<std::string> files;
};

// Utility
TableGenRecTyKind tableGenFromRecType(const llvm::RecTy *rt);

/// A simple raw ostream subclass that forwards write_impl calls to the
/// user-supplied callback together with opaque user-supplied data.
class CallbackOstream : public llvm::raw_ostream {
public:
  CallbackOstream(std::function<void(TableGenStringRef, void *)> callback,
                  void *opaqueData)
      : raw_ostream(/*unbuffered=*/true), callback(std::move(callback)),
        opaqueData(opaqueData), pos(0u) {}

  void write_impl(const char *ptr, size_t size) override {
    TableGenStringRef string = TableGenStringRef{.data = ptr, .len = size};
    callback(string, opaqueData);
    pos += size;
  }

  uint64_t current_pos() const override { return pos; }

private:
  std::function<void(TableGenStringRef, void *)> callback;
  void *opaqueData;
  uint64_t pos;
};

struct RecordMapIterator {
  RecordMap::const_iterator it;
  RecordMap::const_iterator end;
};

} // namespace ctablegen

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ctablegen::TableGenParser,
                                   TableGenParserRef);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::RecordKeeper, TableGenRecordKeeperRef);

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ctablegen::RecordMap, TableGenRecordMapRef);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ctablegen::RecordVector,
                                   TableGenRecordVectorRef);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::ArrayRef<llvm::Record>,
                                   TableGenRecordArrayRef);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::ArrayRef<llvm::RecordVal>,
                                   TableGenRecordValArrayRef);

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::Record, TableGenRecordRef);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::RecordVal, TableGenRecordValRef);

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::TypedInit, TableGenTypedInitRef);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ctablegen::DagPair, TableGenDagPairRef);

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ctablegen::RecordMapIterator,
                                   TableGenRecordKeeperIteratorRef);

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::vector<llvm::SMLoc>,
                                   TableGenSourceLocationRef);

#endif