17#ifndef FRONTENDS_P4_PARSEANNOTATIONS_H_
18#define FRONTENDS_P4_PARSEANNOTATIONS_H_
20#include "frontends/p4/typeChecking/typeChecker.h"
21#include "frontends/parsers/parserDriver.h"
30#define PARSE_SKIP(aname) {aname, &P4::ParseAnnotations::parseSkip}
33#define PARSE_EMPTY(aname) {aname, &P4::ParseAnnotations::parseEmpty}
36#define PARSE(aname, tname) \
37 {aname, [](IR::Annotation *annotation) { \
38 const IR::tname *parsed = \
39 P4::P4ParserDriver::parse##tname(annotation->srcInfo, annotation->getUnparsed()); \
40 if (parsed != nullptr) { \
41 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
43 return parsed != nullptr; \
47#define PARSE_CONSTANT_OR_STRING_LITERAL(aname) \
48 {aname, [](IR::Annotation *annotation) { \
49 const IR::Expression *parsed = P4::P4ParserDriver::parseConstantOrStringLiteral( \
50 annotation->srcInfo, annotation->getUnparsed()); \
51 if (parsed != nullptr) { \
52 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
54 return parsed != nullptr; \
57#define PARSE_CONSTANT(aname) \
58 {aname, [](IR::Annotation *annotation) { \
59 const IR::Expression *parsed = \
60 P4::P4ParserDriver::parseConstant(annotation->srcInfo, annotation->getUnparsed()); \
61 if (parsed != nullptr) { \
62 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
64 return parsed != nullptr; \
67#define PARSE_STRING_LITERAL(aname) \
68 {aname, [](IR::Annotation *annotation) { \
69 const IR::Expression *parsed = P4::P4ParserDriver::parseStringLiteral( \
70 annotation->srcInfo, annotation->getUnparsed()); \
71 if (parsed != nullptr) { \
72 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
74 return parsed != nullptr; \
78#define PARSE_PAIR(aname, tname) \
79 {aname, [](IR::Annotation *annotation) { \
80 const IR::Vector<IR::Expression> *parsed = P4::P4ParserDriver::parse##tname##Pair( \
81 annotation->srcInfo, annotation->getUnparsed()); \
82 if (parsed != nullptr) { \
83 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(*parsed); \
85 return parsed != nullptr; \
89#define PARSE_TRIPLE(aname, tname) \
90 {aname, [](IR::Annotation *annotation) { \
91 const IR::Vector<IR::Expression> *parsed = P4::P4ParserDriver::parse##tname##Triple( \
92 annotation->srcInfo, annotation->getUnparsed()); \
93 if (parsed != nullptr) { \
94 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(*parsed); \
96 return parsed != nullptr; \
100#define PARSE_EXPRESSION_LIST(aname) {aname, &P4::ParseAnnotations::parseExpressionList}
103#define PARSE_KV_LIST(aname) {aname, &P4::ParseAnnotations::parseKvList}
106#define PARSE_CONSTANT_LIST(aname) {aname, &P4::ParseAnnotations::parseConstantList}
110#define PARSE_CONSTANT_OR_STRING_LITERAL_LIST(aname) \
111 {aname, &P4::ParseAnnotations::parseConstantOrStringLiteralList}
114#define PARSE_STRING_LITERAL_LIST(aname) {aname, &P4::ParseAnnotations::parseStringLiteralList}
117#define PARSE_P4RUNTIME_TRANSLATION(aname) \
118 {aname, &P4::ParseAnnotations::parseP4rtTranslationAnnotation}
122 using Modifier::postorder;
126 typedef std::function<bool(IR::Annotation *)>
Handler;
132 explicit ParseAnnotations(
bool warn =
false) : warnUnknown(warn), handlers(standardHandlers()) {
133 setName(
"ParseAnnotations");
139 : warnUnknown(warn) {
140 std::string buf = targetName;
141 buf +=
"__ParseAnnotations";
142 setName(buf.c_str());
144 if (includeStandard) {
145 this->handlers = standardHandlers();
146 this->handlers.insert(handlers.begin(), handlers.end());
148 this->handlers = handlers;
152 void postorder(IR::Annotation *annotation)
final;
156 static bool parseSkip(IR::Annotation *annotation);
157 static bool parseEmpty(IR::Annotation *annotation);
158 static bool parseExpressionList(IR::Annotation *annotation);
159 static bool parseKvList(IR::Annotation *annotation);
160 static bool parseConstantList(IR::Annotation *annotation);
161 static bool parseConstantOrStringLiteralList(IR::Annotation *annotation);
162 static bool parseStringLiteralList(IR::Annotation *annotation);
164 static bool parseP4rtTranslationAnnotation(IR::Annotation *annotation);
166 void addHandler(
cstring name,
Handler h) { handlers.insert({name, h}); }
170 const bool warnUnknown;
174 std::set<cstring> warned;
180class ParseAnnotationBodies final :
public PassManager {
183 passes.push_back(pa);
185 setName(
"ParseAnnotationBodies");
Definition typeChecker.h:32
Definition parseAnnotations.h:120
ParseAnnotations(bool warn=false)
Produces a pass that rewrites the spec-defined annotations.
Definition parseAnnotations.h:132
std::function< bool(IR::Annotation *)> Handler
Definition parseAnnotations.h:126
std::unordered_map< cstring, Handler > HandlerMap
Keyed on annotation names.
Definition parseAnnotations.h:129
ParseAnnotations(const char *targetName, bool includeStandard, HandlerMap handlers, bool warn=false)
Produces a pass that rewrites a custom set of annotations.
Definition parseAnnotations.h:137
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24