P4C
The P4 Compiler
Loading...
Searching...
No Matches
ir-traversal-internal.h
1/*
2Copyright 2024-present Intel Corporation.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
23#ifndef IR_IR_TRAVERSAL_INTERNAL_H_
24#define IR_IR_TRAVERSAL_INTERNAL_H_
25
26#include "lib/exceptions.h"
27#include "lib/rtti_utils.h"
28
29#ifndef IR_IR_TRAVERSAL_INTERNAL_ENABLE
30#error "This file must not be used directly"
31#endif
32
33namespace P4::IR::Traversal::Detail {
34
37struct Traverse {
38 template <typename Obj, typename T>
39 static const Obj *modify(const Obj *, Assign<const T *> asgn) {
40 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
41 return asgn.value;
42 }
43
44 template <typename Obj, typename T>
45 static const Obj *modify(Obj *, Assign<const T *> asgn) {
46 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
47 return asgn.value;
48 }
49
50 template <typename Obj, typename T>
51 static Obj *modify(Obj *obj, Assign<T> &&asgn) {
52 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
53 *obj = std::move(asgn.value);
54 return obj;
55 }
56
57 template <typename Obj, typename T>
58 static Obj *modify(Obj *obj, const Assign<T> &asgn) {
59 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
60 *obj = asgn.value;
61 return obj;
62 }
63
64 template <typename Obj, typename Fn>
65 static decltype(auto) modify(Obj *obj, Fn fn) {
66 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
67 return fn(obj);
68 }
69
70 template <typename Obj, typename... Selectors>
71 static Obj *modify(Obj *obj, Index idx, Selectors &&...selectors) {
72 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
73 BUG_CHECK(obj->size() > idx.value, "Index %1% out of bounds of %2%", idx.value, obj);
74 modifyRef((*obj)[idx.value], std::forward<Selectors>(selectors)...);
75 return obj;
76 }
77
78 template <typename Obj, typename To, typename... Selectors>
79 static To *modify(Obj *obj, RTTI::Detail::ToType<To> cast, Selectors &&...selectors) {
80 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
81 auto *casted = cast(obj);
82 BUG_CHECK(casted, "Cast of %1% failed", obj);
83 return modify(casted, std::forward<Selectors>(selectors)...);
84 }
85
86 template <typename Obj, typename T, typename Sub, typename... Selectors>
87 static Obj *modify(Obj *obj, Sub T::*member, Selectors &&...selectors) {
88 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
89 modifyRef(obj->*member, std::forward<Selectors>(selectors)...);
90 return obj;
91 }
92
93 template <typename T, typename... Selectors>
94 static void modifyRef(T &ref, Selectors &&...selectors) {
95 if constexpr (std::is_pointer_v<T>) {
96 ref = modify(ref->clone(), std::forward<Selectors>(selectors)...);
97 } else {
98 auto *res = modify(&ref, std::forward<Selectors>(selectors)...);
99 if (&ref != res) {
100 ref = *res;
101 }
102 }
103 }
104};
105
106} // namespace P4::IR::Traversal::Detail
107
108#endif // IR_IR_TRAVERSAL_INTERNAL_H_
A selector used at the end of selector chain to assign to the current sub-object. e....
Definition ir-traversal.h:36
Internal, don't use directly. The class exists so that the functions can be mutually recursive.
Definition ir-traversal-internal.h:37
Select an index of a integer-indexed sub-object. This is useful e.g. to select first parameter of a m...
Definition ir-traversal.h:50
Definition rtti_utils.h:72