P4C
The P4 Compiler
Loading...
Searching...
No Matches
parseAnnotations.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef FRONTENDS_P4_PARSEANNOTATIONS_H_
9#define FRONTENDS_P4_PARSEANNOTATIONS_H_
10
11#include "frontends/p4/typeChecking/typeChecker.h"
12#include "frontends/parsers/parserDriver.h"
13#include "ir/ir.h"
14
15/*
16 * Parses known/predefined annotations used by the compiler.
17 */
18namespace P4 {
19
20// A no-op handler. Useful for avoiding warnings about ignored annotations.
21#define PARSE_SKIP(aname) {aname, &P4::ParseAnnotations::parseSkip}
22
23// Parses an empty annotation.
24#define PARSE_EMPTY(aname) {aname, &P4::ParseAnnotations::parseEmpty}
25
26// Parses an annotation with a single-element body.
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); \
33 } \
34 return parsed != nullptr; \
35 }}
36
37// Parses an annotation that is either an integer constant or a string literal.
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); \
44 } \
45 return parsed != nullptr; \
46 }}
47
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); \
54 } \
55 return parsed != nullptr; \
56 }}
57
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); \
64 } \
65 return parsed != nullptr; \
66 }}
67
68// Parses an annotation whose body is a pair.
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); \
75 } \
76 return parsed != nullptr; \
77 }}
78
79// Parses an annotation whose body is a triple.
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); \
86 } \
87 return parsed != nullptr; \
88 }}
89
90// Parses an annotation whose body is a list of expressions.
91#define PARSE_EXPRESSION_LIST(aname) {aname, &P4::ParseAnnotations::parseExpressionList}
92
93// Parses an annotation whose body is a list of key-value pairs.
94#define PARSE_KV_LIST(aname) {aname, &P4::ParseAnnotations::parseKvList}
95
96// Parses an annotation whose body is a list of integer constants.
97#define PARSE_CONSTANT_LIST(aname) {aname, &P4::ParseAnnotations::parseConstantList}
98
99// Parses an annotation whose body is a list, where each element is an integer constant or a string
100// literal.
101#define PARSE_CONSTANT_OR_STRING_LITERAL_LIST(aname) \
102 {aname, &P4::ParseAnnotations::parseConstantOrStringLiteralList}
103
104// Parses an annotation whose body is a list of string literals.
105#define PARSE_STRING_LITERAL_LIST(aname) {aname, &P4::ParseAnnotations::parseStringLiteralList}
106
107// Parses a P4Runtime translation which contains both types or expressions.
108#define PARSE_P4RUNTIME_TRANSLATION(aname) \
109 {aname, &P4::ParseAnnotations::parseP4rtTranslationAnnotation}
110
112 public:
113 using Modifier::postorder;
114
117 typedef std::function<bool(IR::Annotation *)> Handler;
118
120 typedef std::unordered_map<cstring, Handler> HandlerMap;
121
123 explicit ParseAnnotations(bool warn = false) : warnUnknown(warn), handlers(standardHandlers()) {
124 setName("ParseAnnotations");
125 }
126
128 ParseAnnotations(const char *targetName, bool includeStandard, HandlerMap handlers,
129 bool warn = false)
130 : warnUnknown(warn) {
131 std::string buf = targetName;
132 buf += "__ParseAnnotations";
133 setName(buf.c_str());
134
135 if (includeStandard) {
136 this->handlers = standardHandlers();
137 this->handlers.insert(handlers.begin(), handlers.end());
138 } else {
139 this->handlers = handlers;
140 }
141 }
142
143 void postorder(IR::Annotation *annotation) final;
144
145 static HandlerMap standardHandlers();
146
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);
154 // Parses a `@p4runtime_translation` annotation.
155 static bool parseP4rtTranslationAnnotation(IR::Annotation *annotation);
156
157 void addHandler(cstring name, Handler h) { handlers.insert({name, h}); }
158
159 private:
161 const bool warnUnknown;
162
165 std::set<cstring> warned;
166
167 HandlerMap handlers;
168};
169
171class ParseAnnotationBodies final : public PassManager {
172 public:
173 ParseAnnotationBodies(ParseAnnotations *pa, TypeMap *typeMap) {
174 passes.push_back(pa);
175 passes.push_back(new ClearTypeMap(typeMap));
176 setName("ParseAnnotationBodies");
177 }
178};
179
180} // namespace P4
181
182#endif /* FRONTENDS_P4_PARSEANNOTATIONS_H_ */
Definition typeChecker.h:32
Definition visitor.h:385
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
Definition typeMap.h:32
Definition cstring.h:85
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13