P4C
The P4 Compiler
Loading...
Searching...
No Matches
ir-traversal-internal.h
1/*
2 * SPDX-FileCopyrightText: 2024 Intel Corporation.
3 * Copyright 2024-present Intel Corporation.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
13
14#ifndef IR_IR_TRAVERSAL_INTERNAL_H_
15#define IR_IR_TRAVERSAL_INTERNAL_H_
16
17#include "lib/exceptions.h"
18#include "lib/rtti_utils.h"
19
20#ifndef IR_IR_TRAVERSAL_INTERNAL_ENABLE
21#error "This file must not be used directly"
22#endif
23
24namespace P4::IR::Traversal::Detail {
25
28struct Traverse {
29 template <typename Obj, typename T>
30 static const Obj *modify(const Obj *, Assign<const T *> asgn) {
31 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
32 return asgn.value;
33 }
34
35 template <typename Obj, typename T>
36 static const Obj *modify(Obj *, Assign<const T *> asgn) {
37 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
38 return asgn.value;
39 }
40
41 template <typename Obj, typename T>
42 static Obj *modify(Obj *obj, Assign<T> &&asgn) {
43 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
44 *obj = std::move(asgn.value);
45 return obj;
46 }
47
48 template <typename Obj, typename T>
49 static Obj *modify(Obj *obj, const Assign<T> &asgn) {
50 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
51 *obj = asgn.value;
52 return obj;
53 }
54
55 template <typename Obj, typename Fn>
56 static decltype(auto) modify(Obj *obj, Fn fn) {
57 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
58 return fn(obj);
59 }
60
61 template <typename Obj, typename... Selectors>
62 static Obj *modify(Obj *obj, Index idx, Selectors &&...selectors) {
63 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
64 BUG_CHECK(obj->size() > idx.value, "Index %1% out of bounds of %2%", idx.value, obj);
65 modifyRef((*obj)[idx.value], std::forward<Selectors>(selectors)...);
66 return obj;
67 }
68
69 template <typename Obj, typename To, typename... Selectors>
70 static To *modify(Obj *obj, RTTI::Detail::ToType<To> cast, Selectors &&...selectors) {
71 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
72 auto *casted = cast(obj);
73 BUG_CHECK(casted, "Cast of %1% failed", obj);
74 return modify(casted, std::forward<Selectors>(selectors)...);
75 }
76
77 template <typename Obj, typename T, typename Sub, typename... Selectors>
78 static Obj *modify(Obj *obj, Sub T::*member, Selectors &&...selectors) {
79 static_assert(!std::is_const_v<Obj>, "Cannot modify constant object");
80 modifyRef(obj->*member, std::forward<Selectors>(selectors)...);
81 return obj;
82 }
83
84 template <typename T, typename... Selectors>
85 static void modifyRef(T &ref, Selectors &&...selectors) {
86 if constexpr (std::is_pointer_v<T>) {
87 ref = modify(ref->clone(), std::forward<Selectors>(selectors)...);
88 } else {
89 auto *res = modify(&ref, std::forward<Selectors>(selectors)...);
90 if (&ref != res) {
91 ref = *res;
92 }
93 }
94 }
95};
96
97} // namespace P4::IR::Traversal::Detail
98
99#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:27
Internal, don't use directly. The class exists so that the functions can be mutually recursive.
Definition ir-traversal-internal.h:28
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:41
Definition rtti_utils.h:63