• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_PROGRAM_ID_H_
16 #define SRC_PROGRAM_ID_H_
17 
18 #include <stdint.h>
19 #include <iostream>
20 #include <utility>
21 
22 #include "src/debug.h"
23 
24 namespace tint {
25 
26 /// If 1 then checks are enabled that AST nodes are not leaked from one program
27 /// to another.
28 /// TODO(bclayton): We'll want to disable this in production builds. For now we
29 /// always check.
30 #define TINT_CHECK_FOR_CROSS_PROGRAM_LEAKS 1
31 
32 /// A ProgramID is a unique identifier of a Program.
33 /// ProgramID can be used to ensure that objects referenced by the Program are
34 /// owned exclusively by that Program and have accidentally not leaked from
35 /// another Program.
36 class ProgramID {
37  public:
38   /// Constructor
39   ProgramID();
40 
41   /// @returns a new. globally unique ProgramID
42   static ProgramID New();
43 
44   /// Equality operator
45   /// @param rhs the other ProgramID
46   /// @returns true if the ProgramIDs are equal
47   bool operator==(const ProgramID& rhs) const { return val == rhs.val; }
48 
49   /// Inequality operator
50   /// @param rhs the other ProgramID
51   /// @returns true if the ProgramIDs are not equal
52   bool operator!=(const ProgramID& rhs) const { return val != rhs.val; }
53 
54   /// @returns the numerical identifier value
Value()55   uint32_t Value() const { return val; }
56 
57   /// @returns true if this ProgramID is valid
58   operator bool() const { return val != 0; }
59 
60  private:
61   explicit ProgramID(uint32_t);
62 
63   uint32_t val = 0;
64 };
65 
66 /// A simple pass-through function for ProgramID. Intended to be overloaded for
67 /// other types.
68 /// @param id a ProgramID
69 /// @returns id. Simple pass-through function
ProgramIDOf(ProgramID id)70 inline ProgramID ProgramIDOf(ProgramID id) {
71   return id;
72 }
73 
74 /// Writes the ProgramID to the std::ostream.
75 /// @param out the std::ostream to write to
76 /// @param id the program identifier to write
77 /// @returns out so calls can be chained
78 inline std::ostream& operator<<(std::ostream& out, ProgramID id) {
79   out << "Program<" << id.Value() << ">";
80   return out;
81 }
82 
83 namespace detail {
84 
85 /// AssertProgramIDsEqual is called by TINT_ASSERT_PROGRAM_IDS_EQUAL() and
86 /// TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID() to assert that the ProgramIDs
87 /// `a` and `b` are equal.
88 void AssertProgramIDsEqual(ProgramID a,
89                            ProgramID b,
90                            bool if_valid,
91                            diag::System system,
92                            const char* msg,
93                            const char* file,
94                            size_t line);
95 
96 }  // namespace detail
97 
98 /// TINT_ASSERT_PROGRAM_IDS_EQUAL(SYSTEM, A, B) is a macro that asserts that the
99 /// program identifiers for A and B are equal.
100 ///
101 /// TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(SYSTEM, A, B) is a macro that asserts
102 /// that the program identifiers for A and B are equal, if both A and B have
103 /// valid program identifiers.
104 #if TINT_CHECK_FOR_CROSS_PROGRAM_LEAKS
105 #define TINT_ASSERT_PROGRAM_IDS_EQUAL(system, a, b)                          \
106   detail::AssertProgramIDsEqual(                                             \
107       ProgramIDOf(a), ProgramIDOf(b), false, tint::diag::System::system,     \
108       "TINT_ASSERT_PROGRAM_IDS_EQUAL(" #system "," #a ", " #b ")", __FILE__, \
109       __LINE__)
110 #define TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(system, a, b)                 \
111   detail::AssertProgramIDsEqual(                                             \
112       ProgramIDOf(a), ProgramIDOf(b), true, tint::diag::System::system,      \
113       "TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(" #system ", " #a ", " #b ")", \
114       __FILE__, __LINE__)
115 #else
116 #define TINT_ASSERT_PROGRAM_IDS_EQUAL(a, b) \
117   do {                                      \
118   } while (false)
119 #define TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(a, b) \
120   do {                                               \
121   } while (false)
122 #endif
123 
124 }  // namespace tint
125 
126 #endif  // SRC_PROGRAM_ID_H_
127