1 //===--- DependenceFlags.h ------------------------------------------------===// 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 #ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H 9 #define LLVM_CLANG_AST_DEPENDENCEFLAGS_H 10 11 #include "clang/Basic/BitmaskEnum.h" 12 #include "llvm/ADT/BitmaskEnum.h" 13 #include <cstdint> 14 15 namespace clang { 16 struct ExprDependenceScope { 17 enum ExprDependence : uint8_t { 18 UnexpandedPack = 1, 19 // This expr depends in any way on 20 // - a template parameter, it implies that the resolution of this expr may 21 // cause instantiation to fail 22 // - or an error (often in a non-template context) 23 // 24 // Note that C++ standard doesn't define the instantiation-dependent term, 25 // we follow the formal definition coming from the Itanium C++ ABI, and 26 // extend it to errors. 27 Instantiation = 2, 28 // The type of this expr depends on a template parameter, or an error. 29 Type = 4, 30 // The value of this expr depends on a template parameter, or an error. 31 Value = 8, 32 33 // clang extension: this expr contains or references an error, and is 34 // considered dependent on how that error is resolved. 35 Error = 16, 36 37 None = 0, 38 All = 31, 39 40 TypeValue = Type | Value, 41 TypeInstantiation = Type | Instantiation, 42 ValueInstantiation = Value | Instantiation, 43 TypeValueInstantiation = Type | Value | Instantiation, 44 ErrorDependent = Error | ValueInstantiation, 45 46 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) 47 }; 48 }; 49 using ExprDependence = ExprDependenceScope::ExprDependence; 50 51 struct TypeDependenceScope { 52 enum TypeDependence : uint8_t { 53 /// Whether this type contains an unexpanded parameter pack 54 /// (for C++11 variadic templates) 55 UnexpandedPack = 1, 56 /// Whether this type somehow involves 57 /// - a template parameter, even if the resolution of the type does not 58 /// depend on a template parameter. 59 /// - or an error. 60 Instantiation = 2, 61 /// Whether this type 62 /// - is a dependent type (C++ [temp.dep.type]) 63 /// - or it somehow involves an error, e.g. decltype(recovery-expr) 64 Dependent = 4, 65 /// Whether this type is a variably-modified type (C99 6.7.5). 66 VariablyModified = 8, 67 68 /// Whether this type references an error, e.g. decltype(err-expression) 69 /// yields an error type. 70 Error = 16, 71 72 None = 0, 73 All = 31, 74 75 DependentInstantiation = Dependent | Instantiation, 76 77 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) 78 }; 79 }; 80 using TypeDependence = TypeDependenceScope::TypeDependence; 81 82 #define LLVM_COMMON_DEPENDENCE(NAME) \ 83 struct NAME##Scope { \ 84 enum NAME : uint8_t { \ 85 UnexpandedPack = 1, \ 86 Instantiation = 2, \ 87 Dependent = 4, \ 88 Error = 8, \ 89 \ 90 None = 0, \ 91 DependentInstantiation = Dependent | Instantiation, \ 92 All = 15, \ 93 \ 94 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \ 95 }; \ 96 }; \ 97 using NAME = NAME##Scope::NAME; 98 99 LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) 100 LLVM_COMMON_DEPENDENCE(TemplateNameDependence) 101 LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) 102 #undef LLVM_COMMON_DEPENDENCE 103 104 // A combined space of all dependence concepts for all node types. 105 // Used when aggregating dependence of nodes of different types. 106 class Dependence { 107 public: 108 enum Bits : uint8_t { 109 None = 0, 110 111 // Contains a template parameter pack that wasn't expanded. 112 UnexpandedPack = 1, 113 // Depends on a template parameter or an error in some way. 114 // Validity depends on how the template is instantiated or the error is 115 // resolved. 116 Instantiation = 2, 117 // Expression type depends on template context, or an error. 118 // Value and Instantiation should also be set. 119 Type = 4, 120 // Expression value depends on template context, or an error. 121 // Instantiation should also be set. 122 Value = 8, 123 // Depends on template context, or an error. 124 // The type/value distinction is only meaningful for expressions. 125 Dependent = Type | Value, 126 // Includes an error, and depends on how it is resolved. 127 Error = 16, 128 // Type depends on a runtime value (variable-length array). 129 VariablyModified = 32, 130 131 // Dependence that is propagated syntactically, regardless of semantics. 132 Syntactic = UnexpandedPack | Instantiation | Error, 133 // Dependence that is propagated semantically, even in cases where the 134 // type doesn't syntactically appear. This currently excludes only 135 // UnexpandedPack. Even though Instantiation dependence is also notionally 136 // syntactic, we also want to propagate it semantically because anything 137 // that semantically depends on an instantiation-dependent entity should 138 // always be instantiated when that instantiation-dependent entity is. 139 Semantic = 140 Instantiation | Type | Value | Dependent | Error | VariablyModified, 141 142 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) 143 }; 144 145 Dependence() : V(None) {} 146 147 Dependence(TypeDependence D) 148 : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) | 149 translate(D, TypeDependence::Instantiation, Instantiation) | 150 translate(D, TypeDependence::Dependent, Dependent) | 151 translate(D, TypeDependence::Error, Error) | 152 translate(D, TypeDependence::VariablyModified, VariablyModified)) {} 153 154 Dependence(ExprDependence D) 155 : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) | 156 translate(D, ExprDependence::Instantiation, Instantiation) | 157 translate(D, ExprDependence::Type, Type) | 158 translate(D, ExprDependence::Value, Value) | 159 translate(D, ExprDependence::Error, Error)) {} 160 161 Dependence(NestedNameSpecifierDependence D) : 162 V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) | 163 translate(D, NNSDependence::Instantiation, Instantiation) | 164 translate(D, NNSDependence::Dependent, Dependent) | 165 translate(D, NNSDependence::Error, Error)) {} 166 167 Dependence(TemplateArgumentDependence D) 168 : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) | 169 translate(D, TADependence::Instantiation, Instantiation) | 170 translate(D, TADependence::Dependent, Dependent) | 171 translate(D, TADependence::Error, Error)) {} 172 173 Dependence(TemplateNameDependence D) 174 : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) | 175 translate(D, TNDependence::Instantiation, Instantiation) | 176 translate(D, TNDependence::Dependent, Dependent) | 177 translate(D, TNDependence::Error, Error)) {} 178 179 /// Extract only the syntactic portions of this type's dependence. 180 Dependence syntactic() { 181 Dependence Result = *this; 182 Result.V &= Syntactic; 183 return Result; 184 } 185 186 /// Extract the semantic portions of this type's dependence that apply even 187 /// to uses where the type does not appear syntactically. 188 Dependence semantic() { 189 Dependence Result = *this; 190 Result.V &= Semantic; 191 return Result; 192 } 193 194 TypeDependence type() const { 195 return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | 196 translate(V, Instantiation, TypeDependence::Instantiation) | 197 translate(V, Dependent, TypeDependence::Dependent) | 198 translate(V, Error, TypeDependence::Error) | 199 translate(V, VariablyModified, TypeDependence::VariablyModified); 200 } 201 202 ExprDependence expr() const { 203 return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) | 204 translate(V, Instantiation, ExprDependence::Instantiation) | 205 translate(V, Type, ExprDependence::Type) | 206 translate(V, Value, ExprDependence::Value) | 207 translate(V, Error, ExprDependence::Error); 208 } 209 210 NestedNameSpecifierDependence nestedNameSpecifier() const { 211 return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) | 212 translate(V, Instantiation, NNSDependence::Instantiation) | 213 translate(V, Dependent, NNSDependence::Dependent) | 214 translate(V, Error, NNSDependence::Error); 215 } 216 217 TemplateArgumentDependence templateArgument() const { 218 return translate(V, UnexpandedPack, TADependence::UnexpandedPack) | 219 translate(V, Instantiation, TADependence::Instantiation) | 220 translate(V, Dependent, TADependence::Dependent) | 221 translate(V, Error, TADependence::Error); 222 } 223 224 TemplateNameDependence templateName() const { 225 return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) | 226 translate(V, Instantiation, TNDependence::Instantiation) | 227 translate(V, Dependent, TNDependence::Dependent) | 228 translate(V, Error, TNDependence::Error); 229 } 230 231 private: 232 Bits V; 233 234 template <typename T, typename U> 235 static U translate(T Bits, T FromBit, U ToBit) { 236 return (Bits & FromBit) ? ToBit : static_cast<U>(0); 237 } 238 239 // Abbreviations to make conversions more readable. 240 using NNSDependence = NestedNameSpecifierDependence; 241 using TADependence = TemplateArgumentDependence; 242 using TNDependence = TemplateNameDependence; 243 }; 244 245 /// Computes dependencies of a reference with the name having template arguments 246 /// with \p TA dependencies. 247 inline ExprDependence toExprDependence(TemplateArgumentDependence TA) { 248 return Dependence(TA).expr(); 249 } 250 inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) { 251 return Dependence(D).semantic().expr(); 252 } 253 inline ExprDependence toExprDependenceAsWritten(TypeDependence D) { 254 return Dependence(D).expr(); 255 } 256 // Note: it's often necessary to strip `Dependent` from qualifiers. 257 // If V<T>:: refers to the current instantiation, NNS is considered dependent 258 // but the containing V<T>::foo likely isn't. 259 inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) { 260 return Dependence(D).expr(); 261 } 262 inline ExprDependence turnTypeToValueDependence(ExprDependence D) { 263 // Type-dependent expressions are always be value-dependent, so we simply drop 264 // type dependency. 265 return D & ~ExprDependence::Type; 266 } 267 inline ExprDependence turnValueToTypeDependence(ExprDependence D) { 268 // Type-dependent expressions are always be value-dependent. 269 if (D & ExprDependence::Value) 270 D |= ExprDependence::Type; 271 return D; 272 } 273 274 // Returned type-dependence will never have VariablyModified set. 275 inline TypeDependence toTypeDependence(ExprDependence D) { 276 return Dependence(D).type(); 277 } 278 inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) { 279 return Dependence(D).type(); 280 } 281 inline TypeDependence toTypeDependence(TemplateNameDependence D) { 282 return Dependence(D).type(); 283 } 284 inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { 285 return Dependence(D).type(); 286 } 287 288 inline TypeDependence toSyntacticDependence(TypeDependence D) { 289 return Dependence(D).syntactic().type(); 290 } 291 inline TypeDependence toSemanticDependence(TypeDependence D) { 292 return Dependence(D).semantic().type(); 293 } 294 295 inline NestedNameSpecifierDependence 296 toNestedNameSpecifierDependendence(TypeDependence D) { 297 return Dependence(D).nestedNameSpecifier(); 298 } 299 300 inline TemplateArgumentDependence 301 toTemplateArgumentDependence(TypeDependence D) { 302 return Dependence(D).templateArgument(); 303 } 304 inline TemplateArgumentDependence 305 toTemplateArgumentDependence(TemplateNameDependence D) { 306 return Dependence(D).templateArgument(); 307 } 308 inline TemplateArgumentDependence 309 toTemplateArgumentDependence(ExprDependence D) { 310 return Dependence(D).templateArgument(); 311 } 312 313 inline TemplateNameDependence 314 toTemplateNameDependence(NestedNameSpecifierDependence D) { 315 return Dependence(D).templateName(); 316 } 317 318 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); 319 320 } // namespace clang 321 #endif 322