brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 5652611 Raw
200 lines · cpp
1//===- offload-tblgen/DocGen.cpp - Tablegen backend for Offload header ----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This is a Tablegen backend that produces the contents of the Offload API10// specification. The generated reStructuredText is Sphinx compatible, see11// https://www.sphinx-doc.org/en/master/usage/domains/c.html for further12// details on the C language domain.13//14//===----------------------------------------------------------------------===//15 16#include "llvm/ADT/StringExtras.h"17#include "llvm/Support/FormatVariadic.h"18#include "llvm/TableGen/Record.h"19#include "llvm/TableGen/TableGenBackend.h"20 21#include "GenCommon.hpp"22#include "RecordTypes.hpp"23 24using namespace llvm;25using namespace offload::tblgen;26 27namespace {28std::string makeFunctionSignature(StringRef RetTy, StringRef Name,29                                  ArrayRef<ParamRec> Params) {30  std::string S;31  raw_string_ostream OS{S};32  OS << RetTy << " " << Name << "(";33  for (const ParamRec &Param : Params) {34    OS << Param.getType() << " " << Param.getName();35    if (Param != Params.back()) {36      OS << ", ";37    }38  }39  OS << ")";40  return S;41}42 43std::string makeDoubleBackticks(StringRef R) {44  std::string S;45  for (char C : R) {46    if (C == '`') {47      S.push_back('`');48    }49    S.push_back(C);50  }51  return S;52}53 54void processMacro(const MacroRec &M, raw_ostream &OS) {55  OS << formatv(".. c:macro:: {0}\n\n", M.getNameWithArgs());56  OS << "  " << M.getDesc() << "\n\n";57}58 59void processTypedef(const TypedefRec &T, raw_ostream &OS) {60  OS << formatv(".. c:type:: {0} {1}\n\n", T.getValue(), T.getName());61  OS << "  " << T.getDesc() << "\n\n";62}63 64void processHandle(const HandleRec &H, raw_ostream &OS) {65 66  OS << formatv(".. c:type:: struct {0} *{1}\n\n", getHandleImplName(H),67                H.getName());68  OS << "  " << H.getDesc() << "\n\n";69}70 71void processFptrTypedef(const FptrTypedefRec &F, raw_ostream &OS) {72  OS << ".. c:type:: "73     << makeFunctionSignature(F.getReturn(),74                              StringRef{formatv("(*{0})", F.getName())},75                              F.getParams())76     << "\n\n";77  for (const ParamRec &P : F.getParams()) {78    OS << formatv("  :param {0}: {1}\n", P.getName(), P.getDesc());79  }80  OS << "\n";81}82 83void processEnum(const EnumRec &E, raw_ostream &OS) {84  OS << formatv(".. c:enum:: {0}\n\n", E.getName());85  OS << "  " << E.getDesc() << "\n\n";86  for (const EnumValueRec Etor : E.getValues()) {87    OS << formatv("  .. c:enumerator:: {0}_{1}\n\n", E.getEnumValNamePrefix(),88                  Etor.getName());89    OS << "    ";90    if (E.isTyped()) {91      OS << ":c:expr:`" << Etor.getTaggedType() << "` — ";92    }93    OS << Etor.getDesc() << "\n\n";94  }95}96 97void processStruct(const StructRec &S, raw_ostream &OS) {98  OS << formatv(".. c:struct:: {0}\n\n", S.getName());99  OS << "  " << S.getDesc() << "\n\n";100  for (const StructMemberRec &M : S.getMembers()) {101    OS << formatv("  .. c:member:: {0} {1}\n\n", M.getType(), M.getName());102    OS << "    " << M.getDesc() << "\n\n";103  }104}105 106void processFunction(const FunctionRec &F, raw_ostream &OS) {107  OS << ".. c:function:: "108     << makeFunctionSignature({formatv("{0}_result_t", PrefixLower)},109                              F.getName(), F.getParams())110     << "\n\n";111 112  OS << "  " << F.getDesc() << "\n\n";113  for (StringRef D : F.getDetails()) {114    OS << "  " << D << "\n";115  }116  if (!F.getDetails().empty()) {117    OS << "\n";118  }119 120  for (const ParamRec &P : F.getParams()) {121    OS << formatv("  :param {0}: {1}\n", P.getName(), P.getDesc());122  }123 124  for (const ReturnRec &R : F.getReturns()) {125    OS << formatv("  :retval {0}:\n", R.getValue());126    for (StringRef C : R.getConditions()) {127      OS << "    * ";128      if (C.starts_with("`") && C.ends_with("`")) {129        OS << ":c:expr:" << C;130      } else {131        OS << makeDoubleBackticks(C);132      }133      OS << "\n";134    }135  }136  OS << "\n";137}138} // namespace139 140void EmitOffloadDoc(const RecordKeeper &Records, raw_ostream &OS) {141  OS << "Offload API\n";142  OS << "===========\n\n";143 144  ArrayRef<const Record *> Macros = Records.getAllDerivedDefinitions("Macro");145  if (!Macros.empty()) {146    OS << "Macros\n";147    OS << "------\n\n";148    for (const Record *M : Macros) {149      processMacro(MacroRec{M}, OS);150    }151  }152 153  ArrayRef<const Record *> Handles = Records.getAllDerivedDefinitions("Handle");154  ArrayRef<const Record *> Typedefs =155      Records.getAllDerivedDefinitions("Typedef");156  ArrayRef<const Record *> FptrTypedefs =157      Records.getAllDerivedDefinitions("FptrTypedef");158  if (!Handles.empty() || !Typedefs.empty() || !FptrTypedefs.empty()) {159    OS << "Type Definitions\n";160    OS << "----------------\n\n";161    for (const Record *H : Handles) {162      processHandle(HandleRec{H}, OS);163    }164    for (const Record *T : Typedefs) {165      processTypedef(TypedefRec{T}, OS);166    }167    for (const Record *F : FptrTypedefs) {168      processFptrTypedef(FptrTypedefRec{F}, OS);169    }170  }171 172  ArrayRef<const Record *> Enums = Records.getAllDerivedDefinitions("Enum");173  OS << "Enums\n";174  OS << "-----\n\n";175  if (!Enums.empty()) {176    for (const Record *E : Enums) {177      processEnum(EnumRec{E}, OS);178    }179  }180 181  ArrayRef<const Record *> Structs = Records.getAllDerivedDefinitions("Struct");182  if (!Structs.empty()) {183    OS << "Structs\n";184    OS << "-------\n\n";185    for (const Record *S : Structs) {186      processStruct(StructRec{S}, OS);187    }188  }189 190  ArrayRef<const Record *> Functions =191      Records.getAllDerivedDefinitions("Function");192  if (!Functions.empty()) {193    OS << "Functions\n";194    OS << "---------\n\n";195    for (const Record *F : Functions) {196      processFunction(FunctionRec{F}, OS);197    }198  }199}200