8#ifndef FRONTENDS_P4_PARSEANNOTATIONS_H_
9#define FRONTENDS_P4_PARSEANNOTATIONS_H_
11#include "frontends/p4/typeChecking/typeChecker.h"
12#include "frontends/parsers/parserDriver.h"
21#define PARSE_SKIP(aname) {aname, &P4::ParseAnnotations::parseSkip}
24#define PARSE_EMPTY(aname) {aname, &P4::ParseAnnotations::parseEmpty}
27#define PARSE(aname, tname) \
28 {aname, [](IR::Annotation *annotation) { \
29 const IR::tname *parsed = \
30 P4::P4ParserDriver::parse##tname(annotation->srcInfo, annotation->getUnparsed()); \
31 if (parsed != nullptr) { \
32 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
34 return parsed != nullptr; \
38#define PARSE_CONSTANT_OR_STRING_LITERAL(aname) \
39 {aname, [](IR::Annotation *annotation) { \
40 const IR::Expression *parsed = P4::P4ParserDriver::parseConstantOrStringLiteral( \
41 annotation->srcInfo, annotation->getUnparsed()); \
42 if (parsed != nullptr) { \
43 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
45 return parsed != nullptr; \
48#define PARSE_CONSTANT(aname) \
49 {aname, [](IR::Annotation *annotation) { \
50 const IR::Expression *parsed = \
51 P4::P4ParserDriver::parseConstant(annotation->srcInfo, annotation->getUnparsed()); \
52 if (parsed != nullptr) { \
53 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
55 return parsed != nullptr; \
58#define PARSE_STRING_LITERAL(aname) \
59 {aname, [](IR::Annotation *annotation) { \
60 const IR::Expression *parsed = P4::P4ParserDriver::parseStringLiteral( \
61 annotation->srcInfo, annotation->getUnparsed()); \
62 if (parsed != nullptr) { \
63 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
65 return parsed != nullptr; \
69#define PARSE_PAIR(aname, tname) \
70 {aname, [](IR::Annotation *annotation) { \
71 const IR::Vector<IR::Expression> *parsed = P4::P4ParserDriver::parse##tname##Pair( \
72 annotation->srcInfo, annotation->getUnparsed()); \
73 if (parsed != nullptr) { \
74 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(*parsed); \
76 return parsed != nullptr; \
80#define PARSE_TRIPLE(aname, tname) \
81 {aname, [](IR::Annotation *annotation) { \
82 const IR::Vector<IR::Expression> *parsed = P4::P4ParserDriver::parse##tname##Triple( \
83 annotation->srcInfo, annotation->getUnparsed()); \
84 if (parsed != nullptr) { \
85 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(*parsed); \
87 return parsed != nullptr; \
91#define PARSE_EXPRESSION_LIST(aname) {aname, &P4::ParseAnnotations::parseExpressionList}
94#define PARSE_KV_LIST(aname) {aname, &P4::ParseAnnotations::parseKvList}
97#define PARSE_CONSTANT_LIST(aname) {aname, &P4::ParseAnnotations::parseConstantList}
101#define PARSE_CONSTANT_OR_STRING_LITERAL_LIST(aname) \
102 {aname, &P4::ParseAnnotations::parseConstantOrStringLiteralList}
105#define PARSE_STRING_LITERAL_LIST(aname) {aname, &P4::ParseAnnotations::parseStringLiteralList}
108#define PARSE_P4RUNTIME_TRANSLATION(aname) \
109 {aname, &P4::ParseAnnotations::parseP4rtTranslationAnnotation}
113 using Modifier::postorder;
117 typedef std::function<bool(IR::Annotation *)>
Handler;
123 explicit ParseAnnotations(
bool warn =
false) : warnUnknown(warn), handlers(standardHandlers()) {
124 setName(
"ParseAnnotations");
130 : warnUnknown(warn) {
131 std::string buf = targetName;
132 buf +=
"__ParseAnnotations";
133 setName(buf.c_str());
135 if (includeStandard) {
136 this->handlers = standardHandlers();
137 this->handlers.insert(handlers.begin(), handlers.end());
139 this->handlers = handlers;
143 void postorder(IR::Annotation *annotation)
final;
147 static bool parseSkip(IR::Annotation *annotation);
148 static bool parseEmpty(IR::Annotation *annotation);
149 static bool parseExpressionList(IR::Annotation *annotation);
150 static bool parseKvList(IR::Annotation *annotation);
151 static bool parseConstantList(IR::Annotation *annotation);
152 static bool parseConstantOrStringLiteralList(IR::Annotation *annotation);
153 static bool parseStringLiteralList(IR::Annotation *annotation);
155 static bool parseP4rtTranslationAnnotation(IR::Annotation *annotation);
157 void addHandler(
cstring name,
Handler h) { handlers.insert({name, h}); }
161 const bool warnUnknown;
165 std::set<cstring> warned;
171class ParseAnnotationBodies final :
public PassManager {
174 passes.push_back(pa);
176 setName(
"ParseAnnotationBodies");
Definition typeChecker.h:32
Definition parseAnnotations.h:111
ParseAnnotations(bool warn=false)
Produces a pass that rewrites the spec-defined annotations.
Definition parseAnnotations.h:123
std::function< bool(IR::Annotation *)> Handler
Definition parseAnnotations.h:117
std::unordered_map< cstring, Handler > HandlerMap
Keyed on annotation names.
Definition parseAnnotations.h:120
ParseAnnotations(const char *targetName, bool includeStandard, HandlerMap handlers, bool warn=false)
Produces a pass that rewrites a custom set of annotations.
Definition parseAnnotations.h:128
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13