17#ifndef P4_PARSEANNOTATIONS_H_
18#define P4_PARSEANNOTATIONS_H_
20#include "frontends/p4/typeChecking/typeChecker.h"
21#include "frontends/parsers/parserDriver.h"
30#define PARSE_SKIP(aname) \
31 { aname, &P4::ParseAnnotations::parseSkip }
34#define PARSE_EMPTY(aname) \
35 { aname, &P4::ParseAnnotations::parseEmpty }
38#define PARSE(aname, tname) \
40 aname, [](IR::Annotation *annotation) { \
41 const IR::tname *parsed = \
42 P4::P4ParserDriver::parse##tname(annotation->srcInfo, annotation->getUnparsed()); \
43 if (parsed != nullptr) { \
44 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
46 return parsed != nullptr; \
51#define PARSE_CONSTANT_OR_STRING_LITERAL(aname) \
53 aname, [](IR::Annotation *annotation) { \
54 const IR::Expression *parsed = P4::P4ParserDriver::parseConstantOrStringLiteral( \
55 annotation->srcInfo, annotation->getUnparsed()); \
56 if (parsed != nullptr) { \
57 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
59 return parsed != nullptr; \
63#define PARSE_CONSTANT(aname) \
65 aname, [](IR::Annotation *annotation) { \
66 const IR::Expression *parsed = \
67 P4::P4ParserDriver::parseConstant(annotation->srcInfo, annotation->getUnparsed()); \
68 if (parsed != nullptr) { \
69 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
71 return parsed != nullptr; \
75#define PARSE_STRING_LITERAL(aname) \
77 aname, [](IR::Annotation *annotation) { \
78 const IR::Expression *parsed = P4::P4ParserDriver::parseStringLiteral( \
79 annotation->srcInfo, annotation->getUnparsed()); \
80 if (parsed != nullptr) { \
81 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(parsed); \
83 return parsed != nullptr; \
88#define PARSE_PAIR(aname, tname) \
90 aname, [](IR::Annotation *annotation) { \
91 const IR::Vector<IR::Expression> *parsed = P4::P4ParserDriver::parse##tname##Pair( \
92 annotation->srcInfo, annotation->getUnparsed()); \
93 if (parsed != nullptr) { \
94 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(*parsed); \
96 return parsed != nullptr; \
101#define PARSE_TRIPLE(aname, tname) \
103 aname, [](IR::Annotation *annotation) { \
104 const IR::Vector<IR::Expression> *parsed = P4::P4ParserDriver::parse##tname##Triple( \
105 annotation->srcInfo, annotation->getUnparsed()); \
106 if (parsed != nullptr) { \
107 annotation->body.emplace<IR::Annotation::ExpressionAnnotation>(*parsed); \
109 return parsed != nullptr; \
114#define PARSE_EXPRESSION_LIST(aname) \
115 { aname, &P4::ParseAnnotations::parseExpressionList }
118#define PARSE_KV_LIST(aname) \
119 { aname, &P4::ParseAnnotations::parseKvList }
122#define PARSE_CONSTANT_LIST(aname) \
123 { aname, &P4::ParseAnnotations::parseConstantList }
127#define PARSE_CONSTANT_OR_STRING_LITERAL_LIST(aname) \
128 { aname, &P4::ParseAnnotations::parseConstantOrStringLiteralList }
131#define PARSE_STRING_LITERAL_LIST(aname) \
132 { aname, &P4::ParseAnnotations::parseStringLiteralList }
135#define PARSE_P4RUNTIME_TRANSLATION(aname) \
136 { aname, &P4::ParseAnnotations::parseP4rtTranslationAnnotation }
140 using Modifier::postorder;
144 typedef std::function<bool(IR::Annotation *)>
Handler;
150 explicit ParseAnnotations(
bool warn =
false) : warnUnknown(warn), handlers(standardHandlers()) {
151 setName(
"ParseAnnotations");
157 : warnUnknown(warn) {
158 std::string buf = targetName;
159 buf +=
"__ParseAnnotations";
160 setName(buf.c_str());
162 if (includeStandard) {
163 this->handlers = standardHandlers();
164 this->handlers.insert(handlers.begin(), handlers.end());
166 this->handlers = handlers;
170 void postorder(IR::Annotation *annotation)
final;
174 static bool parseSkip(IR::Annotation *annotation);
175 static bool parseEmpty(IR::Annotation *annotation);
176 static bool parseExpressionList(IR::Annotation *annotation);
177 static bool parseKvList(IR::Annotation *annotation);
178 static bool parseConstantList(IR::Annotation *annotation);
179 static bool parseConstantOrStringLiteralList(IR::Annotation *annotation);
180 static bool parseStringLiteralList(IR::Annotation *annotation);
182 static bool parseP4rtTranslationAnnotation(IR::Annotation *annotation);
184 void addHandler(
cstring name,
Handler h) { handlers.insert({name, h}); }
188 const bool warnUnknown;
192 std::set<cstring> warned;
201 passes.push_back(pa);
203 setName(
"ParseAnnotationBodies");
Definition typeChecker.h:32
Clears a type map after calling a ParseAnnotations instance.
Definition parseAnnotations.h:198
Definition parseAnnotations.h:138
ParseAnnotations(bool warn=false)
Produces a pass that rewrites the spec-defined annotations.
Definition parseAnnotations.h:150
std::function< bool(IR::Annotation *)> Handler
Definition parseAnnotations.h:144
std::unordered_map< cstring, Handler > HandlerMap
Keyed on annotation names.
Definition parseAnnotations.h:147
ParseAnnotations(const char *targetName, bool includeStandard, HandlerMap handlers, bool warn=false)
Produces a pass that rewrites a custom set of annotations.
Definition parseAnnotations.h:155
Definition ir/pass_manager.h:40
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24