/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Sema/Ownership.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Ownership.h - Parser ownership helpers -------------------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file contains classes for managing ownership of Stmt and Expr nodes. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H |
14 | | #define LLVM_CLANG_SEMA_OWNERSHIP_H |
15 | | |
16 | | #include "clang/AST/Expr.h" |
17 | | #include "clang/Basic/LLVM.h" |
18 | | #include "llvm/ADT/ArrayRef.h" |
19 | | #include "llvm/Support/PointerLikeTypeTraits.h" |
20 | | #include "llvm/Support/type_traits.h" |
21 | | #include <cassert> |
22 | | #include <cstddef> |
23 | | #include <cstdint> |
24 | | |
25 | | //===----------------------------------------------------------------------===// |
26 | | // OpaquePtr |
27 | | //===----------------------------------------------------------------------===// |
28 | | |
29 | | namespace clang { |
30 | | |
31 | | class CXXBaseSpecifier; |
32 | | class CXXCtorInitializer; |
33 | | class Decl; |
34 | | class Expr; |
35 | | class ParsedTemplateArgument; |
36 | | class QualType; |
37 | | class Stmt; |
38 | | class TemplateName; |
39 | | class TemplateParameterList; |
40 | | |
41 | | /// Wrapper for void* pointer. |
42 | | /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like |
43 | | /// a pointer. |
44 | | /// |
45 | | /// This is a very simple POD type that wraps a pointer that the Parser |
46 | | /// doesn't know about but that Sema or another client does. The PtrTy |
47 | | /// template argument is used to make sure that "Decl" pointers are not |
48 | | /// compatible with "Type" pointers for example. |
49 | | template <class PtrTy> |
50 | | class OpaquePtr { |
51 | | void *Ptr = nullptr; |
52 | | |
53 | 89.6M | explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} clang::OpaquePtr<clang::QualType>::OpaquePtr(void*) Line | Count | Source | 53 | 89.6M | explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} |
clang::OpaquePtr<clang::TemplateName>::OpaquePtr(void*) Line | Count | Source | 53 | 6.58k | explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} |
|
54 | | |
55 | | using Traits = llvm::PointerLikeTypeTraits<PtrTy>; |
56 | | |
57 | | public: |
58 | 302M | OpaquePtr(std::nullptr_t = nullptr) {} clang::OpaquePtr<clang::DeclGroupRef>::OpaquePtr(std::nullptr_t) Line | Count | Source | 58 | 40.4M | OpaquePtr(std::nullptr_t = nullptr) {} |
clang::OpaquePtr<clang::TemplateName>::OpaquePtr(std::nullptr_t) Line | Count | Source | 58 | 28.9M | OpaquePtr(std::nullptr_t = nullptr) {} |
clang::OpaquePtr<clang::QualType>::OpaquePtr(std::nullptr_t) Line | Count | Source | 58 | 233M | OpaquePtr(std::nullptr_t = nullptr) {} |
|
59 | | |
60 | 97.9M | static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } clang::OpaquePtr<clang::QualType>::make(clang::QualType) Line | Count | Source | 60 | 72.6M | static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } |
clang::OpaquePtr<clang::TemplateName>::make(clang::TemplateName) Line | Count | Source | 60 | 2.81M | static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } |
clang::OpaquePtr<clang::DeclGroupRef>::make(clang::DeclGroupRef) Line | Count | Source | 60 | 22.4M | static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } |
|
61 | | |
62 | | /// Returns plain pointer to the entity pointed by this wrapper. |
63 | | /// \tparam PointeeT Type of pointed entity. |
64 | | /// |
65 | | /// It is identical to getPtrAs<PointeeT*>. |
66 | | template <typename PointeeT> PointeeT* getPtrTo() const { |
67 | | return get(); |
68 | | } |
69 | | |
70 | | /// Returns pointer converted to the specified type. |
71 | | /// \tparam PtrT Result pointer type. There must be implicit conversion |
72 | | /// from PtrTy to PtrT. |
73 | | /// |
74 | | /// In contrast to getPtrTo, this method allows the return type to be |
75 | | /// a smart pointer. |
76 | | template <typename PtrT> PtrT getPtrAs() const { |
77 | | return get(); |
78 | | } |
79 | | |
80 | 116M | PtrTy get() const { |
81 | 116M | return Traits::getFromVoidPointer(Ptr); |
82 | 116M | } clang::OpaquePtr<clang::DeclGroupRef>::get() const Line | Count | Source | 80 | 17.2M | PtrTy get() const { | 81 | 17.2M | return Traits::getFromVoidPointer(Ptr); | 82 | 17.2M | } |
clang::OpaquePtr<clang::QualType>::get() const Line | Count | Source | 80 | 96.7M | PtrTy get() const { | 81 | 96.7M | return Traits::getFromVoidPointer(Ptr); | 82 | 96.7M | } |
clang::OpaquePtr<clang::TemplateName>::get() const Line | Count | Source | 80 | 2.83M | PtrTy get() const { | 81 | 2.83M | return Traits::getFromVoidPointer(Ptr); | 82 | 2.83M | } |
|
83 | | |
84 | 97.9M | void set(PtrTy P) { |
85 | 97.9M | Ptr = Traits::getAsVoidPointer(P); |
86 | 97.9M | } clang::OpaquePtr<clang::QualType>::set(clang::QualType) Line | Count | Source | 84 | 72.6M | void set(PtrTy P) { | 85 | 72.6M | Ptr = Traits::getAsVoidPointer(P); | 86 | 72.6M | } |
clang::OpaquePtr<clang::TemplateName>::set(clang::TemplateName) Line | Count | Source | 84 | 2.81M | void set(PtrTy P) { | 85 | 2.81M | Ptr = Traits::getAsVoidPointer(P); | 86 | 2.81M | } |
clang::OpaquePtr<clang::DeclGroupRef>::set(clang::DeclGroupRef) Line | Count | Source | 84 | 22.4M | void set(PtrTy P) { | 85 | 22.4M | Ptr = Traits::getAsVoidPointer(P); | 86 | 22.4M | } |
|
87 | | |
88 | 241M | explicit operator bool() const { return Ptr != nullptr; } clang::OpaquePtr<clang::DeclGroupRef>::operator bool() const Line | Count | Source | 88 | 16.0M | explicit operator bool() const { return Ptr != nullptr; } |
clang::OpaquePtr<clang::QualType>::operator bool() const Line | Count | Source | 88 | 222M | explicit operator bool() const { return Ptr != nullptr; } |
clang::OpaquePtr<clang::TemplateName>::operator bool() const Line | Count | Source | 88 | 2.65M | explicit operator bool() const { return Ptr != nullptr; } |
|
89 | | |
90 | 100M | void *getAsOpaquePtr() const { return Ptr; } clang::OpaquePtr<clang::QualType>::getAsOpaquePtr() const Line | Count | Source | 90 | 100M | void *getAsOpaquePtr() const { return Ptr; } |
clang::OpaquePtr<clang::TemplateName>::getAsOpaquePtr() const Line | Count | Source | 90 | 5.26k | void *getAsOpaquePtr() const { return Ptr; } |
clang::OpaquePtr<clang::DeclGroupRef>::getAsOpaquePtr() const Line | Count | Source | 90 | 2 | void *getAsOpaquePtr() const { return Ptr; } |
|
91 | 89.6M | static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } clang::OpaquePtr<clang::QualType>::getFromOpaquePtr(void*) Line | Count | Source | 91 | 89.6M | static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } |
clang::OpaquePtr<clang::TemplateName>::getFromOpaquePtr(void*) Line | Count | Source | 91 | 6.58k | static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } |
|
92 | | }; |
93 | | |
94 | | /// UnionOpaquePtr - A version of OpaquePtr suitable for membership |
95 | | /// in a union. |
96 | | template <class T> struct UnionOpaquePtr { |
97 | | void *Ptr; |
98 | | |
99 | | static UnionOpaquePtr make(OpaquePtr<T> P) { |
100 | | UnionOpaquePtr OP = { P.getAsOpaquePtr() }; |
101 | | return OP; |
102 | | } |
103 | | |
104 | 63.7M | OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } clang::UnionOpaquePtr<clang::QualType>::get() const Line | Count | Source | 104 | 63.7M | OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } |
clang::UnionOpaquePtr<clang::TemplateName>::get() const Line | Count | Source | 104 | 1.70k | OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } |
|
105 | 63.7M | operator OpaquePtr<T>() const { return get(); } |
106 | | |
107 | 74.3M | UnionOpaquePtr &operator=(OpaquePtr<T> P) { |
108 | 74.3M | Ptr = P.getAsOpaquePtr(); |
109 | 74.3M | return *this; |
110 | 74.3M | } clang::UnionOpaquePtr<clang::QualType>::operator=(clang::OpaquePtr<clang::QualType>) Line | Count | Source | 107 | 74.3M | UnionOpaquePtr &operator=(OpaquePtr<T> P) { | 108 | 74.3M | Ptr = P.getAsOpaquePtr(); | 109 | 74.3M | return *this; | 110 | 74.3M | } |
clang::UnionOpaquePtr<clang::TemplateName>::operator=(clang::OpaquePtr<clang::TemplateName>) Line | Count | Source | 107 | 427 | UnionOpaquePtr &operator=(OpaquePtr<T> P) { | 108 | 427 | Ptr = P.getAsOpaquePtr(); | 109 | 427 | return *this; | 110 | 427 | } |
|
111 | | }; |
112 | | |
113 | | } // namespace clang |
114 | | |
115 | | namespace llvm { |
116 | | |
117 | | template <class T> |
118 | | struct PointerLikeTypeTraits<clang::OpaquePtr<T>> { |
119 | | static constexpr int NumLowBitsAvailable = 0; |
120 | | |
121 | | static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) { |
122 | | // FIXME: Doesn't work? return P.getAs< void >(); |
123 | | return P.getAsOpaquePtr(); |
124 | | } |
125 | | |
126 | | static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) { |
127 | | return clang::OpaquePtr<T>::getFromOpaquePtr(P); |
128 | | } |
129 | | }; |
130 | | |
131 | | } // namespace llvm |
132 | | |
133 | | namespace clang { |
134 | | |
135 | | // Basic |
136 | | class StreamingDiagnostic; |
137 | | |
138 | | // Determines whether the low bit of the result pointer for the |
139 | | // given UID is always zero. If so, ActionResult will use that bit |
140 | | // for it's "invalid" flag. |
141 | | template <class Ptr> struct IsResultPtrLowBitFree { |
142 | | static const bool value = false; |
143 | | }; |
144 | | |
145 | | /// ActionResult - This structure is used while parsing/acting on |
146 | | /// expressions, stmts, etc. It encapsulates both the object returned by |
147 | | /// the action, plus a sense of whether or not it is valid. |
148 | | /// When CompressInvalid is true, the "invalid" flag will be |
149 | | /// stored in the low bit of the Val pointer. |
150 | | template<class PtrTy, |
151 | | bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value> |
152 | | class ActionResult { |
153 | | PtrTy Val; |
154 | | bool Invalid; |
155 | | |
156 | | public: |
157 | 22.1M | ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {} clang::ActionResult<clang::OpaquePtr<clang::QualType>, false>::ActionResult(bool) Line | Count | Source | 157 | 20.1M | ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {} |
clang::ActionResult<clang::Decl*, false>::ActionResult(bool) Line | Count | Source | 157 | 1.97M | ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {} |
clang::ActionResult<clang::CXXRecordDecl*, false>::ActionResult(bool) Line | Count | Source | 157 | 31 | ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {} |
|
158 | 52.8M | ActionResult(PtrTy val) : Val(val), Invalid(false) {} clang::ActionResult<clang::OpaquePtr<clang::QualType>, false>::ActionResult(clang::OpaquePtr<clang::QualType>) Line | Count | Source | 158 | 51.5M | ActionResult(PtrTy val) : Val(val), Invalid(false) {} |
clang::ActionResult<clang::Decl*, false>::ActionResult(clang::Decl*) Line | Count | Source | 158 | 563k | ActionResult(PtrTy val) : Val(val), Invalid(false) {} |
clang::ActionResult<clang::CXXRecordDecl*, false>::ActionResult(clang::CXXRecordDecl*) Line | Count | Source | 158 | 754k | ActionResult(PtrTy val) : Val(val), Invalid(false) {} |
|
159 | | ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {} |
160 | | |
161 | | // These two overloads prevent void* -> bool conversions. |
162 | | ActionResult(const void *) = delete; |
163 | | ActionResult(volatile void *) = delete; |
164 | | |
165 | 90.2M | bool isInvalid() const { return Invalid; } clang::ActionResult<clang::OpaquePtr<clang::QualType>, false>::isInvalid() const Line | Count | Source | 165 | 86.2M | bool isInvalid() const { return Invalid; } |
clang::ActionResult<clang::Decl*, false>::isInvalid() const Line | Count | Source | 165 | 3.97M | bool isInvalid() const { return Invalid; } |
clang::ActionResult<clang::CXXRecordDecl*, false>::isInvalid() const Line | Count | Source | 165 | 31 | bool isInvalid() const { return Invalid; } |
|
166 | 16.2M | bool isUsable() const { return !Invalid && Val16.2M ; } clang::ActionResult<clang::Decl*, false>::isUsable() const Line | Count | Source | 166 | 77.0k | bool isUsable() const { return !Invalid && Val; } |
clang::ActionResult<clang::OpaquePtr<clang::QualType>, false>::isUsable() const Line | Count | Source | 166 | 15.3M | bool isUsable() const { return !Invalid && Val15.3M ; } |
clang::ActionResult<clang::CXXRecordDecl*, false>::isUsable() const Line | Count | Source | 166 | 754k | bool isUsable() const { return !Invalid && Val754k ; } |
|
167 | 2.32M | bool isUnset() const { return !Invalid && !Val2.32M ; } |
168 | | |
169 | 99.6M | PtrTy get() const { return Val; } clang::ActionResult<clang::OpaquePtr<clang::QualType>, false>::get() const Line | Count | Source | 169 | 93.4M | PtrTy get() const { return Val; } |
clang::ActionResult<clang::Decl*, false>::get() const Line | Count | Source | 169 | 5.42M | PtrTy get() const { return Val; } |
clang::ActionResult<clang::CXXRecordDecl*, false>::get() const Line | Count | Source | 169 | 754k | PtrTy get() const { return Val; } |
|
170 | | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
171 | | |
172 | | void set(PtrTy V) { Val = V; } |
173 | | |
174 | 1.74M | const ActionResult &operator=(PtrTy RHS) { |
175 | 1.74M | Val = RHS; |
176 | 1.74M | Invalid = false; |
177 | 1.74M | return *this; |
178 | 1.74M | } clang::ActionResult<clang::Decl*, false>::operator=(clang::Decl*) Line | Count | Source | 174 | 1.74M | const ActionResult &operator=(PtrTy RHS) { | 175 | 1.74M | Val = RHS; | 176 | 1.74M | Invalid = false; | 177 | 1.74M | return *this; | 178 | 1.74M | } |
Unexecuted instantiation: clang::ActionResult<clang::OpaquePtr<clang::QualType>, false>::operator=(clang::OpaquePtr<clang::QualType>) |
179 | | }; |
180 | | |
181 | | // This ActionResult partial specialization places the "invalid" |
182 | | // flag into the low bit of the pointer. |
183 | | template<typename PtrTy> |
184 | | class ActionResult<PtrTy, true> { |
185 | | // A pointer whose low bit is 1 if this result is invalid, 0 |
186 | | // otherwise. |
187 | | uintptr_t PtrWithInvalid; |
188 | | |
189 | | using PtrTraits = llvm::PointerLikeTypeTraits<PtrTy>; |
190 | | |
191 | | public: |
192 | | ActionResult(bool Invalid = false) |
193 | 180M | : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {} clang::ActionResult<clang::Expr*, true>::ActionResult(bool) Line | Count | Source | 193 | 162M | : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {} |
clang::ActionResult<clang::CXXCtorInitializer*, true>::ActionResult(bool) Line | Count | Source | 193 | 32.5k | : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {} |
clang::ActionResult<clang::CXXBaseSpecifier*, true>::ActionResult(bool) Line | Count | Source | 193 | 241 | : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {} |
clang::ActionResult<clang::Stmt*, true>::ActionResult(bool) Line | Count | Source | 193 | 17.9M | : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {} |
|
194 | | |
195 | 347M | ActionResult(PtrTy V) { |
196 | 347M | void *VP = PtrTraits::getAsVoidPointer(V); |
197 | 347M | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); |
198 | 347M | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); |
199 | 347M | } clang::ActionResult<clang::Expr*, true>::ActionResult(clang::Expr*) Line | Count | Source | 195 | 334M | ActionResult(PtrTy V) { | 196 | 334M | void *VP = PtrTraits::getAsVoidPointer(V); | 197 | 334M | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); | 198 | 334M | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); | 199 | 334M | } |
clang::ActionResult<clang::CXXBaseSpecifier*, true>::ActionResult(clang::CXXBaseSpecifier*) Line | Count | Source | 195 | 196k | ActionResult(PtrTy V) { | 196 | 196k | void *VP = PtrTraits::getAsVoidPointer(V); | 197 | 196k | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); | 198 | 196k | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); | 199 | 196k | } |
clang::ActionResult<clang::CXXCtorInitializer*, true>::ActionResult(clang::CXXCtorInitializer*) Line | Count | Source | 195 | 235k | ActionResult(PtrTy V) { | 196 | 235k | void *VP = PtrTraits::getAsVoidPointer(V); | 197 | 235k | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); | 198 | 235k | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); | 199 | 235k | } |
clang::ActionResult<clang::Stmt*, true>::ActionResult(clang::Stmt*) Line | Count | Source | 195 | 12.1M | ActionResult(PtrTy V) { | 196 | 12.1M | void *VP = PtrTraits::getAsVoidPointer(V); | 197 | 12.1M | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); | 198 | 12.1M | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); | 199 | 12.1M | } |
|
200 | | |
201 | 1 | ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) {} Unexecuted instantiation: clang::ActionResult<clang::CXXCtorInitializer*, true>::ActionResult(clang::DiagnosticBuilder const&) clang::ActionResult<clang::Expr*, true>::ActionResult(clang::DiagnosticBuilder const&) Line | Count | Source | 201 | 1 | ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) {} |
|
202 | | |
203 | | // These two overloads prevent void* -> bool conversions. |
204 | | ActionResult(const void *) = delete; |
205 | | ActionResult(volatile void *) = delete; |
206 | | |
207 | 444M | bool isInvalid() const { return PtrWithInvalid & 0x01; } clang::ActionResult<clang::Expr*, true>::isInvalid() const Line | Count | Source | 207 | 433M | bool isInvalid() const { return PtrWithInvalid & 0x01; } |
clang::ActionResult<clang::Stmt*, true>::isInvalid() const Line | Count | Source | 207 | 10.3M | bool isInvalid() const { return PtrWithInvalid & 0x01; } |
clang::ActionResult<clang::CXXBaseSpecifier*, true>::isInvalid() const Line | Count | Source | 207 | 196k | bool isInvalid() const { return PtrWithInvalid & 0x01; } |
clang::ActionResult<clang::CXXCtorInitializer*, true>::isInvalid() const Line | Count | Source | 207 | 235k | bool isInvalid() const { return PtrWithInvalid & 0x01; } |
|
208 | 72.8M | bool isUsable() const { return PtrWithInvalid > 0x01; } clang::ActionResult<clang::Expr*, true>::isUsable() const Line | Count | Source | 208 | 65.7M | bool isUsable() const { return PtrWithInvalid > 0x01; } |
clang::ActionResult<clang::Stmt*, true>::isUsable() const Line | Count | Source | 208 | 7.10M | bool isUsable() const { return PtrWithInvalid > 0x01; } |
|
209 | 24.8M | bool isUnset() const { return PtrWithInvalid == 0; } |
210 | | |
211 | 760M | PtrTy get() const { |
212 | 760M | void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); |
213 | 760M | return PtrTraits::getFromVoidPointer(VP); |
214 | 760M | } clang::ActionResult<clang::Expr*, true>::get() const Line | Count | Source | 211 | 741M | PtrTy get() const { | 212 | 741M | void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); | 213 | 741M | return PtrTraits::getFromVoidPointer(VP); | 214 | 741M | } |
clang::ActionResult<clang::Stmt*, true>::get() const Line | Count | Source | 211 | 18.0M | PtrTy get() const { | 212 | 18.0M | void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); | 213 | 18.0M | return PtrTraits::getFromVoidPointer(VP); | 214 | 18.0M | } |
clang::ActionResult<clang::CXXBaseSpecifier*, true>::get() const Line | Count | Source | 211 | 196k | PtrTy get() const { | 212 | 196k | void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); | 213 | 196k | return PtrTraits::getFromVoidPointer(VP); | 214 | 196k | } |
clang::ActionResult<clang::CXXCtorInitializer*, true>::get() const Line | Count | Source | 211 | 235k | PtrTy get() const { | 212 | 235k | void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); | 213 | 235k | return PtrTraits::getFromVoidPointer(VP); | 214 | 235k | } |
|
215 | | |
216 | 14.2M | template <typename T> T *getAs() { return static_cast<T*>(get()); } clang::StringLiteral* clang::ActionResult<clang::Expr*, true>::getAs<clang::StringLiteral>() Line | Count | Source | 216 | 14 | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
clang::Expr* clang::ActionResult<clang::Expr*, true>::getAs<clang::Expr>() Line | Count | Source | 216 | 11.7M | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
clang::Stmt* clang::ActionResult<clang::Expr*, true>::getAs<clang::Stmt>() Line | Count | Source | 216 | 2.06M | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
clang::Expr* clang::ActionResult<clang::Stmt*, true>::getAs<clang::Expr>() Line | Count | Source | 216 | 476 | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
clang::CXXConstructExpr* clang::ActionResult<clang::Expr*, true>::getAs<clang::CXXConstructExpr>() Line | Count | Source | 216 | 75 | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
clang::Stmt* clang::ActionResult<clang::Stmt*, true>::getAs<clang::Stmt>() Line | Count | Source | 216 | 435k | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
clang::DeclRefExpr* clang::ActionResult<clang::Expr*, true>::getAs<clang::DeclRefExpr>() Line | Count | Source | 216 | 218 | template <typename T> T *getAs() { return static_cast<T*>(get()); } |
|
217 | | |
218 | | void set(PtrTy V) { |
219 | | void *VP = PtrTraits::getAsVoidPointer(V); |
220 | | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); |
221 | | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); |
222 | | } |
223 | | |
224 | 24.8M | const ActionResult &operator=(PtrTy RHS) { |
225 | 24.8M | void *VP = PtrTraits::getAsVoidPointer(RHS); |
226 | 24.8M | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); |
227 | 24.8M | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); |
228 | 24.8M | return *this; |
229 | 24.8M | } clang::ActionResult<clang::Expr*, true>::operator=(clang::Expr*) Line | Count | Source | 224 | 24.8M | const ActionResult &operator=(PtrTy RHS) { | 225 | 24.8M | void *VP = PtrTraits::getAsVoidPointer(RHS); | 226 | 24.8M | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); | 227 | 24.8M | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); | 228 | 24.8M | return *this; | 229 | 24.8M | } |
clang::ActionResult<clang::Stmt*, true>::operator=(clang::Stmt*) Line | Count | Source | 224 | 24 | const ActionResult &operator=(PtrTy RHS) { | 225 | 24 | void *VP = PtrTraits::getAsVoidPointer(RHS); | 226 | 24 | PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); | 227 | 24 | assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); | 228 | 24 | return *this; | 229 | 24 | } |
|
230 | | |
231 | | // For types where we can fit a flag in with the pointer, provide |
232 | | // conversions to/from pointer type. |
233 | 663k | static ActionResult getFromOpaquePointer(void *P) { |
234 | 663k | ActionResult Result; |
235 | 663k | Result.PtrWithInvalid = (uintptr_t)P; |
236 | 663k | return Result; |
237 | 663k | } |
238 | 663k | void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; } |
239 | | }; |
240 | | |
241 | | /// An opaque type for threading parsed type information through the |
242 | | /// parser. |
243 | | using ParsedType = OpaquePtr<QualType>; |
244 | | using UnionParsedType = UnionOpaquePtr<QualType>; |
245 | | |
246 | | // We can re-use the low bit of expression, statement, base, and |
247 | | // member-initializer pointers for the "invalid" flag of |
248 | | // ActionResult. |
249 | | template<> struct IsResultPtrLowBitFree<Expr*> { |
250 | | static const bool value = true; |
251 | | }; |
252 | | template<> struct IsResultPtrLowBitFree<Stmt*> { |
253 | | static const bool value = true; |
254 | | }; |
255 | | template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> { |
256 | | static const bool value = true; |
257 | | }; |
258 | | template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> { |
259 | | static const bool value = true; |
260 | | }; |
261 | | |
262 | | using ExprResult = ActionResult<Expr *>; |
263 | | using StmtResult = ActionResult<Stmt *>; |
264 | | using TypeResult = ActionResult<ParsedType>; |
265 | | using BaseResult = ActionResult<CXXBaseSpecifier *>; |
266 | | using MemInitResult = ActionResult<CXXCtorInitializer *>; |
267 | | |
268 | | using DeclResult = ActionResult<Decl *>; |
269 | | using ParsedTemplateTy = OpaquePtr<TemplateName>; |
270 | | using UnionParsedTemplateTy = UnionOpaquePtr<TemplateName>; |
271 | | |
272 | | using MultiExprArg = MutableArrayRef<Expr *>; |
273 | | using MultiStmtArg = MutableArrayRef<Stmt *>; |
274 | | using ASTTemplateArgsPtr = MutableArrayRef<ParsedTemplateArgument>; |
275 | | using MultiTypeArg = MutableArrayRef<ParsedType>; |
276 | | using MultiTemplateParamsArg = MutableArrayRef<TemplateParameterList *>; |
277 | | |
278 | 2.49M | inline ExprResult ExprError() { return ExprResult(true); } |
279 | 634k | inline StmtResult StmtError() { return StmtResult(true); } |
280 | 840 | inline TypeResult TypeError() { return TypeResult(true); } |
281 | | |
282 | 64 | inline ExprResult ExprError(const StreamingDiagnostic &) { |
283 | 64 | return ExprError(); |
284 | 64 | } |
285 | 13 | inline StmtResult StmtError(const StreamingDiagnostic &) { |
286 | 13 | return StmtError(); |
287 | 13 | } |
288 | | |
289 | 16.7M | inline ExprResult ExprEmpty() { return ExprResult(false); } |
290 | 81 | inline StmtResult StmtEmpty() { return StmtResult(false); } |
291 | | |
292 | 0 | inline Expr *AssertSuccess(ExprResult R) { |
293 | 0 | assert(!R.isInvalid() && "operation was asserted to never fail!"); |
294 | 0 | return R.get(); |
295 | 0 | } |
296 | | |
297 | 0 | inline Stmt *AssertSuccess(StmtResult R) { |
298 | 0 | assert(!R.isInvalid() && "operation was asserted to never fail!"); |
299 | 0 | return R.get(); |
300 | 0 | } |
301 | | |
302 | | } // namespace clang |
303 | | |
304 | | #endif // LLVM_CLANG_SEMA_OWNERSHIP_H |