Attributes.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. //===- Attributes.cpp - Generate attributes -------------------------------===//
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Support/MemoryBuffer.h"
  9. #include "llvm/TableGen/Record.h"
  10. #include <algorithm>
  11. #include <string>
  12. #include <vector>
  13. using namespace llvm;
  14. #define DEBUG_TYPE "attr-enum"
  15. namespace {
  16. class Attributes {
  17. public:
  18. Attributes(RecordKeeper &R) : Records(R) {}
  19. void emit(raw_ostream &OS);
  20. private:
  21. void emitTargetIndependentNames(raw_ostream &OS);
  22. void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
  23. RecordKeeper &Records;
  24. };
  25. } // End anonymous namespace.
  26. void Attributes::emitTargetIndependentNames(raw_ostream &OS) {
  27. OS << "#ifdef GET_ATTR_NAMES\n";
  28. OS << "#undef GET_ATTR_NAMES\n";
  29. OS << "#ifndef ATTRIBUTE_ALL\n";
  30. OS << "#define ATTRIBUTE_ALL(FIRST, SECOND)\n";
  31. OS << "#endif\n\n";
  32. auto Emit = [&](ArrayRef<StringRef> KindNames, StringRef MacroName) {
  33. OS << "#ifndef " << MacroName << "\n";
  34. OS << "#define " << MacroName
  35. << "(FIRST, SECOND) ATTRIBUTE_ALL(FIRST, SECOND)\n";
  36. OS << "#endif\n\n";
  37. for (StringRef KindName : KindNames) {
  38. for (auto A : Records.getAllDerivedDefinitions(KindName)) {
  39. OS << MacroName << "(" << A->getName() << ","
  40. << A->getValueAsString("AttrString") << ")\n";
  41. }
  42. }
  43. OS << "#undef " << MacroName << "\n\n";
  44. };
  45. // Emit attribute enums in the same order llvm::Attribute::operator< expects.
  46. Emit({"EnumAttr", "TypeAttr", "IntAttr"}, "ATTRIBUTE_ENUM");
  47. Emit({"StrBoolAttr"}, "ATTRIBUTE_STRBOOL");
  48. OS << "#undef ATTRIBUTE_ALL\n";
  49. OS << "#endif\n";
  50. }
  51. void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
  52. OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
  53. OS << "#undef GET_ATTR_COMPAT_FUNC\n";
  54. OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
  55. << " const Function &Callee) {\n";
  56. OS << " bool Ret = true;\n\n";
  57. std::vector<Record *> CompatRules =
  58. Records.getAllDerivedDefinitions("CompatRule");
  59. for (auto *Rule : CompatRules) {
  60. StringRef FuncName = Rule->getValueAsString("CompatFunc");
  61. OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
  62. }
  63. OS << "\n";
  64. OS << " return Ret;\n";
  65. OS << "}\n\n";
  66. std::vector<Record *> MergeRules =
  67. Records.getAllDerivedDefinitions("MergeRule");
  68. OS << "static inline void mergeFnAttrs(Function &Caller,\n"
  69. << " const Function &Callee) {\n";
  70. for (auto *Rule : MergeRules) {
  71. StringRef FuncName = Rule->getValueAsString("MergeFunc");
  72. OS << " " << FuncName << "(Caller, Callee);\n";
  73. }
  74. OS << "}\n\n";
  75. OS << "#endif\n";
  76. }
  77. void Attributes::emit(raw_ostream &OS) {
  78. emitTargetIndependentNames(OS);
  79. emitFnAttrCompatCheck(OS, false);
  80. }
  81. namespace llvm {
  82. void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
  83. Attributes(RK).emit(OS);
  84. }
  85. } // End llvm namespace.