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;
124 : warnUnknown(warn), errorRequireParse(errStruct), handlers(standardHandlers()) {
125 setName(
"ParseAnnotations");
130 bool warn =
false,
bool errStruct =
false)
131 : warnUnknown(warn), errorRequireParse(errStruct) {
132 std::string buf = targetName;
133 buf +=
"__ParseAnnotations";
134 setName(buf.c_str());
136 if (includeStandard) {
137 this->handlers = standardHandlers();
138 this->handlers.insert(handlers.begin(), handlers.end());
140 this->handlers = handlers;
144 void postorder(IR::Annotation *annotation)
final;
148 static bool parseSkip(IR::Annotation *annotation);
149 static bool parseEmpty(IR::Annotation *annotation);
150 static bool parseExpressionList(IR::Annotation *annotation);
151 static bool parseKvList(IR::Annotation *annotation);
152 static bool parseConstantList(IR::Annotation *annotation);
153 static bool parseConstantOrStringLiteralList(IR::Annotation *annotation);
154 static bool parseStringLiteralList(IR::Annotation *annotation);
156 static bool parseP4rtTranslationAnnotation(IR::Annotation *annotation);
158 void addHandler(
cstring name,
Handler h) { handlers.insert({name, h}); }
162 const bool warnUnknown;
166 const bool errorRequireParse;
170 std::set<cstring> warned;
176class ParseAnnotationBodies final :
public PassManager {
179 passes.push_back(pa);
181 setName(
"ParseAnnotationBodies");
Definition typeChecker.h:23
Definition parseAnnotations.h:111
ParseAnnotations(bool warn=false, bool errStruct=false)
Produces a pass that rewrites the spec-defined annotations.
Definition parseAnnotations.h:123
ParseAnnotations(const char *targetName, bool includeStandard, HandlerMap handlers, bool warn=false, bool errStruct=false)
Produces a pass that rewrites a custom set of annotations.
Definition parseAnnotations.h:129
std::function< bool(IR::Annotation *)> Handler
Definition parseAnnotations.h:117
std::unordered_map< cstring, Handler > HandlerMap
Keyed on annotation names.
Definition parseAnnotations.h:120
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13