blob: 7b001bf14de588a4ee6831d2da740e70b26c9cfa [file] [log] [blame]
Akira Hatanakad9326792015-11-11 20:35:42 +00001//===- Attributes.cpp - Generate attributes -------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Support/SourceMgr.h"
11#include "llvm/Support/MemoryBuffer.h"
12#include "llvm/TableGen/Error.h"
13#include "llvm/TableGen/Record.h"
14#include <algorithm>
15#include <string>
16#include <vector>
17using namespace llvm;
18
19#define DEBUG_TYPE "attr-enum"
20
21namespace {
22
23class Attributes {
24public:
25 Attributes(RecordKeeper &R) : Records(R) {}
26 void emit(raw_ostream &OS);
27
28private:
29 void emitTargetIndependentEnums(raw_ostream &OS);
Akira Hatanaka1cb242e2015-12-22 23:57:37 +000030 void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
31
32 void printEnumAttrClasses(raw_ostream &OS,
33 const std::vector<Record *> &Records);
34 void printStrBoolAttrClasses(raw_ostream &OS,
35 const std::vector<Record *> &Records);
Akira Hatanakad9326792015-11-11 20:35:42 +000036
37 RecordKeeper &Records;
38};
39
40} // End anonymous namespace.
41
42void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
43 OS << "#ifdef GET_ATTR_ENUM\n";
44 OS << "#undef GET_ATTR_ENUM\n";
45
Akira Hatanaka1cb242e2015-12-22 23:57:37 +000046 std::vector<Record*> Attrs =
Akira Hatanakad9326792015-11-11 20:35:42 +000047 Records.getAllDerivedDefinitions("EnumAttr");
48
49 for (auto A : Attrs)
50 OS << A->getName() << ",\n";
51
52 OS << "#endif\n";
53}
54
Akira Hatanaka1cb242e2015-12-22 23:57:37 +000055void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
56 OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
57 OS << "#undef GET_ATTR_COMPAT_FUNC\n";
58
59 OS << "struct EnumAttr {\n";
60 OS << " static bool isSet(const Function &Fn,\n";
61 OS << " Attribute::AttrKind Kind) {\n";
62 OS << " return Fn.hasFnAttribute(Kind);\n";
63 OS << " }\n\n";
64 OS << " static void set(Function &Fn,\n";
65 OS << " Attribute::AttrKind Kind, bool Val) {\n";
66 OS << " if (Val)\n";
67 OS << " Fn.addFnAttr(Kind);\n";
68 OS << " else\n";
69 OS << " Fn.removeFnAttr(Kind);\n";
70 OS << " }\n";
71 OS << "};\n\n";
72
73 OS << "struct StrBoolAttr {\n";
74 OS << " static bool isSet(const Function &Fn,\n";
75 OS << " StringRef Kind) {\n";
76 OS << " auto A = Fn.getFnAttribute(Kind);\n";
77 OS << " return A.getValueAsString().equals(\"true\");\n";
78 OS << " }\n\n";
79 OS << " static void set(Function &Fn,\n";
80 OS << " StringRef Kind, bool Val) {\n";
81 OS << " Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
82 OS << " }\n";
83 OS << "};\n\n";
84
85 printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
86 printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
87
88 OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
89 << " const Function &Callee) {\n";
90 OS << " bool Ret = true;\n\n";
91
92 std::vector<Record *> CompatRules =
93 Records.getAllDerivedDefinitions("CompatRule");
94
95 for (auto *Rule : CompatRules) {
96 std::string FuncName = Rule->getValueAsString("CompatFunc");
97 OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
98 }
99
100 OS << "\n";
101 OS << " return Ret;\n";
102 OS << "}\n\n";
103
104 std::vector<Record *> MergeRules =
105 Records.getAllDerivedDefinitions("MergeRule");
106 OS << "static inline void mergeFnAttrs(Function &Caller,\n"
107 << " const Function &Callee) {\n";
108
109 for (auto *Rule : MergeRules) {
110 std::string FuncName = Rule->getValueAsString("MergeFunc");
111 OS << " " << FuncName << "(Caller, Callee);\n";
112 }
113
114 OS << "}\n\n";
115
116 OS << "#endif\n";
117}
118
119void Attributes::printEnumAttrClasses(raw_ostream &OS,
120 const std::vector<Record *> &Records) {
121 OS << "// EnumAttr classes\n";
122 for (const auto *R : Records) {
123 OS << "struct " << R->getName() << "Attr : EnumAttr {\n";
124 OS << " static enum Attribute::AttrKind getKind() {\n";
125 OS << " return llvm::Attribute::" << R->getName() << ";\n";
126 OS << " }\n";
127 OS << "};\n";
128 }
129 OS << "\n";
130}
131
132void Attributes::printStrBoolAttrClasses(raw_ostream &OS,
133 const std::vector<Record *> &Records) {
134 OS << "// StrBoolAttr classes\n";
135 for (const auto *R : Records) {
136 OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n";
137 OS << " static const char *getKind() {\n";
138 OS << " return \"" << R->getValueAsString("AttrString") << "\";\n";
139 OS << " }\n";
140 OS << "};\n";
141 }
142 OS << "\n";
143}
144
Akira Hatanakad9326792015-11-11 20:35:42 +0000145void Attributes::emit(raw_ostream &OS) {
146 emitTargetIndependentEnums(OS);
Akira Hatanaka1cb242e2015-12-22 23:57:37 +0000147 emitFnAttrCompatCheck(OS, false);
Akira Hatanakad9326792015-11-11 20:35:42 +0000148}
149
150namespace llvm {
151
152void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
153 Attributes(RK).emit(OS);
154}
155
156} // End llvm namespace.