]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/utils/TableGen/Attributes.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / utils / TableGen / Attributes.cpp
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
9 #include "llvm/Support/MemoryBuffer.h"
10 #include "llvm/TableGen/Record.h"
11 #include <algorithm>
12 #include <string>
13 #include <vector>
14 using namespace llvm;
15
16 #define DEBUG_TYPE "attr-enum"
17
18 namespace {
19
20 class Attributes {
21 public:
22   Attributes(RecordKeeper &R) : Records(R) {}
23   void emit(raw_ostream &OS);
24
25 private:
26   void emitTargetIndependentEnums(raw_ostream &OS);
27   void emitConversionFn(raw_ostream &OS);
28   void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
29
30   void printEnumAttrClasses(raw_ostream &OS,
31                             const std::vector<Record *> &Records);
32   void printStrBoolAttrClasses(raw_ostream &OS,
33                                const std::vector<Record *> &Records);
34
35   RecordKeeper &Records;
36 };
37
38 } // End anonymous namespace.
39
40 void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
41   OS << "#ifdef GET_ATTR_ENUM\n";
42   OS << "#undef GET_ATTR_ENUM\n";
43
44   std::vector<Record*> Attrs =
45       Records.getAllDerivedDefinitions("EnumAttr");
46
47   for (auto A : Attrs)
48     OS << A->getName() << ",\n";
49
50   OS << "#endif\n";
51 }
52
53 void Attributes::emitConversionFn(raw_ostream &OS) {
54   OS << "#ifdef GET_ATTR_KIND_FROM_NAME\n";
55   OS << "#undef GET_ATTR_KIND_FROM_NAME\n";
56
57   std::vector<Record*> Attrs =
58       Records.getAllDerivedDefinitions("EnumAttr");
59
60   OS << "static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {\n";
61   OS << "  return StringSwitch<Attribute::AttrKind>(AttrName)\n";
62
63   for (auto A : Attrs) {
64     OS << "    .Case(\"" << A->getValueAsString("AttrString");
65     OS << "\", Attribute::" << A->getName() << ")\n";
66   }
67
68   OS << "    .Default(Attribute::None);\n";
69   OS << "}\n\n";
70
71   OS << "#endif\n";
72 }
73
74 void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
75   OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
76   OS << "#undef GET_ATTR_COMPAT_FUNC\n";
77
78   OS << "struct EnumAttr {\n";
79   OS << "  static bool isSet(const Function &Fn,\n";
80   OS << "                    Attribute::AttrKind Kind) {\n";
81   OS << "    return Fn.hasFnAttribute(Kind);\n";
82   OS << "  }\n\n";
83   OS << "  static void set(Function &Fn,\n";
84   OS << "                  Attribute::AttrKind Kind, bool Val) {\n";
85   OS << "    if (Val)\n";
86   OS << "      Fn.addFnAttr(Kind);\n";
87   OS << "    else\n";
88   OS << "      Fn.removeFnAttr(Kind);\n";
89   OS << "  }\n";
90   OS << "};\n\n";
91
92   OS << "struct StrBoolAttr {\n";
93   OS << "  static bool isSet(const Function &Fn,\n";
94   OS << "                    StringRef Kind) {\n";
95   OS << "    auto A = Fn.getFnAttribute(Kind);\n";
96   OS << "    return A.getValueAsString().equals(\"true\");\n";
97   OS << "  }\n\n";
98   OS << "  static void set(Function &Fn,\n";
99   OS << "                  StringRef Kind, bool Val) {\n";
100   OS << "    Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
101   OS << "  }\n";
102   OS << "};\n\n";
103
104   printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
105   printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
106
107   OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
108      << "                                        const Function &Callee) {\n";
109   OS << "  bool Ret = true;\n\n";
110
111   std::vector<Record *> CompatRules =
112       Records.getAllDerivedDefinitions("CompatRule");
113
114   for (auto *Rule : CompatRules) {
115     StringRef FuncName = Rule->getValueAsString("CompatFunc");
116     OS << "  Ret &= " << FuncName << "(Caller, Callee);\n";
117   }
118
119   OS << "\n";
120   OS << "  return Ret;\n";
121   OS << "}\n\n";
122
123   std::vector<Record *> MergeRules =
124       Records.getAllDerivedDefinitions("MergeRule");
125   OS << "static inline void mergeFnAttrs(Function &Caller,\n"
126      << "                                const Function &Callee) {\n";
127
128   for (auto *Rule : MergeRules) {
129     StringRef FuncName = Rule->getValueAsString("MergeFunc");
130     OS << "  " << FuncName << "(Caller, Callee);\n";
131   }
132
133   OS << "}\n\n";
134
135   OS << "#endif\n";
136 }
137
138 void Attributes::printEnumAttrClasses(raw_ostream &OS,
139                                       const std::vector<Record *> &Records) {
140   OS << "// EnumAttr classes\n";
141   for (const auto *R : Records) {
142     OS << "struct " << R->getName() << "Attr : EnumAttr {\n";
143     OS << "  static enum Attribute::AttrKind getKind() {\n";
144     OS << "    return llvm::Attribute::" << R->getName() << ";\n";
145     OS << "  }\n";
146     OS << "};\n";
147   }
148   OS << "\n";
149 }
150
151 void Attributes::printStrBoolAttrClasses(raw_ostream &OS,
152                                          const std::vector<Record *> &Records) {
153   OS << "// StrBoolAttr classes\n";
154   for (const auto *R : Records) {
155     OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n";
156     OS << "  static StringRef getKind() {\n";
157     OS << "    return \"" << R->getValueAsString("AttrString") << "\";\n";
158     OS << "  }\n";
159     OS << "};\n";
160   }
161   OS << "\n";
162 }
163
164 void Attributes::emit(raw_ostream &OS) {
165   emitTargetIndependentEnums(OS);
166   emitConversionFn(OS);
167   emitFnAttrCompatCheck(OS, false);
168 }
169
170 namespace llvm {
171
172 void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
173   Attributes(RK).emit(OS);
174 }
175
176 } // End llvm namespace.