- //===--- DependenceFlags.h ------------------------------------------------===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- #ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H 
- #define LLVM_CLANG_AST_DEPENDENCEFLAGS_H 
-   
- #include "clang/Basic/BitmaskEnum.h" 
- #include "llvm/ADT/BitmaskEnum.h" 
- #include <cstdint> 
-   
- namespace clang { 
- struct ExprDependenceScope { 
-   enum ExprDependence : uint8_t { 
-     UnexpandedPack = 1, 
-     // This expr depends in any way on 
-     //   - a template parameter, it implies that the resolution of this expr may 
-     //     cause instantiation to fail 
-     //   - or an error (often in a non-template context) 
-     // 
-     // Note that C++ standard doesn't define the instantiation-dependent term, 
-     // we follow the formal definition coming from the Itanium C++ ABI, and 
-     // extend it to errors. 
-     Instantiation = 2, 
-     // The type of this expr depends on a template parameter, or an error. 
-     Type = 4, 
-     // The value of this expr depends on a template parameter, or an error. 
-     Value = 8, 
-   
-     // clang extension: this expr contains or references an error, and is 
-     // considered dependent on how that error is resolved. 
-     Error = 16, 
-   
-     None = 0, 
-     All = 31, 
-   
-     TypeValue = Type | Value, 
-     TypeInstantiation = Type | Instantiation, 
-     ValueInstantiation = Value | Instantiation, 
-     TypeValueInstantiation = Type | Value | Instantiation, 
-     ErrorDependent = Error | ValueInstantiation, 
-   
-     LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) 
-   }; 
- }; 
- using ExprDependence = ExprDependenceScope::ExprDependence; 
-   
- struct TypeDependenceScope { 
-   enum TypeDependence : uint8_t { 
-     /// Whether this type contains an unexpanded parameter pack 
-     /// (for C++11 variadic templates) 
-     UnexpandedPack = 1, 
-     /// Whether this type somehow involves 
-     ///   - a template parameter, even if the resolution of the type does not 
-     ///     depend on a template parameter. 
-     ///   - or an error. 
-     Instantiation = 2, 
-     /// Whether this type 
-     ///   - is a dependent type (C++ [temp.dep.type]) 
-     ///   - or it somehow involves an error, e.g. decltype(recovery-expr) 
-     Dependent = 4, 
-     /// Whether this type is a variably-modified type (C99 6.7.5). 
-     VariablyModified = 8, 
-   
-     /// Whether this type references an error, e.g. decltype(err-expression) 
-     /// yields an error type. 
-     Error = 16, 
-   
-     None = 0, 
-     All = 31, 
-   
-     DependentInstantiation = Dependent | Instantiation, 
-   
-     LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) 
-   }; 
- }; 
- using TypeDependence = TypeDependenceScope::TypeDependence; 
-   
- #define LLVM_COMMON_DEPENDENCE(NAME)                                           \ 
-   struct NAME##Scope {                                                         \ 
-     enum NAME : uint8_t {                                                      \ 
-       UnexpandedPack = 1,                                                      \ 
-       Instantiation = 2,                                                       \ 
-       Dependent = 4,                                                           \ 
-       Error = 8,                                                               \ 
-                                                                                \ 
-       None = 0,                                                                \ 
-       DependentInstantiation = Dependent | Instantiation,                      \ 
-       All = 15,                                                                \ 
-                                                                                \ 
-       LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)                        \ 
-     };                                                                         \ 
-   };                                                                           \ 
-   using NAME = NAME##Scope::NAME; 
-   
- LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) 
- LLVM_COMMON_DEPENDENCE(TemplateNameDependence) 
- LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) 
- #undef LLVM_COMMON_DEPENDENCE 
-   
- // A combined space of all dependence concepts for all node types. 
- // Used when aggregating dependence of nodes of different types. 
- class Dependence { 
- public: 
-   enum Bits : uint8_t { 
-     None = 0, 
-   
-     // Contains a template parameter pack that wasn't expanded. 
-     UnexpandedPack = 1, 
-     // Depends on a template parameter or an error in some way. 
-     // Validity depends on how the template is instantiated or the error is 
-     // resolved. 
-     Instantiation = 2, 
-     // Expression type depends on template context, or an error. 
-     // Value and Instantiation should also be set. 
-     Type = 4, 
-     // Expression value depends on template context, or an error. 
-     // Instantiation should also be set. 
-     Value = 8, 
-     // Depends on template context, or an error. 
-     // The type/value distinction is only meaningful for expressions. 
-     Dependent = Type | Value, 
-     // Includes an error, and depends on how it is resolved. 
-     Error = 16, 
-     // Type depends on a runtime value (variable-length array). 
-     VariablyModified = 32, 
-   
-     // Dependence that is propagated syntactically, regardless of semantics. 
-     Syntactic = UnexpandedPack | Instantiation | Error, 
-     // Dependence that is propagated semantically, even in cases where the 
-     // type doesn't syntactically appear. This currently excludes only 
-     // UnexpandedPack. Even though Instantiation dependence is also notionally 
-     // syntactic, we also want to propagate it semantically because anything 
-     // that semantically depends on an instantiation-dependent entity should 
-     // always be instantiated when that instantiation-dependent entity is. 
-     Semantic = 
-         Instantiation | Type | Value | Dependent | Error | VariablyModified, 
-   
-     LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) 
-   }; 
-   
-   Dependence() : V(None) {} 
-   
-   Dependence(TypeDependence D) 
-       : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) | 
-           translate(D, TypeDependence::Instantiation, Instantiation) | 
-           translate(D, TypeDependence::Dependent, Dependent) | 
-           translate(D, TypeDependence::Error, Error) | 
-           translate(D, TypeDependence::VariablyModified, VariablyModified)) {} 
-   
-   Dependence(ExprDependence D) 
-       : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) | 
-              translate(D, ExprDependence::Instantiation, Instantiation) | 
-              translate(D, ExprDependence::Type, Type) | 
-              translate(D, ExprDependence::Value, Value) | 
-              translate(D, ExprDependence::Error, Error)) {} 
-   
-   Dependence(NestedNameSpecifierDependence D) : 
-     V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) | 
-             translate(D, NNSDependence::Instantiation, Instantiation) | 
-             translate(D, NNSDependence::Dependent, Dependent) | 
-             translate(D, NNSDependence::Error, Error)) {} 
-   
-   Dependence(TemplateArgumentDependence D) 
-       : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) | 
-           translate(D, TADependence::Instantiation, Instantiation) | 
-           translate(D, TADependence::Dependent, Dependent) | 
-           translate(D, TADependence::Error, Error)) {} 
-   
-   Dependence(TemplateNameDependence D) 
-       : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) | 
-              translate(D, TNDependence::Instantiation, Instantiation) | 
-              translate(D, TNDependence::Dependent, Dependent) | 
-              translate(D, TNDependence::Error, Error)) {} 
-   
-   /// Extract only the syntactic portions of this type's dependence. 
-   Dependence syntactic() { 
-     Dependence Result = *this; 
-     Result.V &= Syntactic; 
-     return Result; 
-   } 
-   
-   /// Extract the semantic portions of this type's dependence that apply even 
-   /// to uses where the type does not appear syntactically. 
-   Dependence semantic() { 
-     Dependence Result = *this; 
-     Result.V &= Semantic; 
-     return Result; 
-   } 
-   
-   TypeDependence type() const { 
-     return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | 
-            translate(V, Instantiation, TypeDependence::Instantiation) | 
-            translate(V, Dependent, TypeDependence::Dependent) | 
-            translate(V, Error, TypeDependence::Error) | 
-            translate(V, VariablyModified, TypeDependence::VariablyModified); 
-   } 
-   
-   ExprDependence expr() const { 
-     return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) | 
-            translate(V, Instantiation, ExprDependence::Instantiation) | 
-            translate(V, Type, ExprDependence::Type) | 
-            translate(V, Value, ExprDependence::Value) | 
-            translate(V, Error, ExprDependence::Error); 
-   } 
-   
-   NestedNameSpecifierDependence nestedNameSpecifier() const { 
-     return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) | 
-            translate(V, Instantiation, NNSDependence::Instantiation) | 
-            translate(V, Dependent, NNSDependence::Dependent) | 
-            translate(V, Error, NNSDependence::Error); 
-   } 
-   
-   TemplateArgumentDependence templateArgument() const { 
-     return translate(V, UnexpandedPack, TADependence::UnexpandedPack) | 
-            translate(V, Instantiation, TADependence::Instantiation) | 
-            translate(V, Dependent, TADependence::Dependent) | 
-            translate(V, Error, TADependence::Error); 
-   } 
-   
-   TemplateNameDependence templateName() const { 
-     return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) | 
-            translate(V, Instantiation, TNDependence::Instantiation) | 
-            translate(V, Dependent, TNDependence::Dependent) | 
-            translate(V, Error, TNDependence::Error); 
-   } 
-   
- private: 
-   Bits V; 
-   
-   template <typename T, typename U> 
-   static U translate(T Bits, T FromBit, U ToBit) { 
-     return (Bits & FromBit) ? ToBit : static_cast<U>(0); 
-   } 
-   
-   // Abbreviations to make conversions more readable. 
-   using NNSDependence = NestedNameSpecifierDependence; 
-   using TADependence = TemplateArgumentDependence; 
-   using TNDependence = TemplateNameDependence; 
- }; 
-   
- /// Computes dependencies of a reference with the name having template arguments 
- /// with \p TA dependencies. 
- inline ExprDependence toExprDependence(TemplateArgumentDependence TA) { 
-   return Dependence(TA).expr(); 
- } 
- inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) { 
-   return Dependence(D).semantic().expr(); 
- } 
- inline ExprDependence toExprDependenceAsWritten(TypeDependence D) { 
-   return Dependence(D).expr(); 
- } 
- // Note: it's often necessary to strip `Dependent` from qualifiers. 
- // If V<T>:: refers to the current instantiation, NNS is considered dependent 
- // but the containing V<T>::foo likely isn't. 
- inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) { 
-   return Dependence(D).expr(); 
- } 
- inline ExprDependence turnTypeToValueDependence(ExprDependence D) { 
-   // Type-dependent expressions are always be value-dependent, so we simply drop 
-   // type dependency. 
-   return D & ~ExprDependence::Type; 
- } 
- inline ExprDependence turnValueToTypeDependence(ExprDependence D) { 
-   // Type-dependent expressions are always be value-dependent. 
-   if (D & ExprDependence::Value) 
-     D |= ExprDependence::Type; 
-   return D; 
- } 
-   
- // Returned type-dependence will never have VariablyModified set. 
- inline TypeDependence toTypeDependence(ExprDependence D) { 
-   return Dependence(D).type(); 
- } 
- inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) { 
-   return Dependence(D).type(); 
- } 
- inline TypeDependence toTypeDependence(TemplateNameDependence D) { 
-   return Dependence(D).type(); 
- } 
- inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { 
-   return Dependence(D).type(); 
- } 
-   
- inline TypeDependence toSyntacticDependence(TypeDependence D) { 
-   return Dependence(D).syntactic().type(); 
- } 
- inline TypeDependence toSemanticDependence(TypeDependence D) { 
-   return Dependence(D).semantic().type(); 
- } 
-   
- inline NestedNameSpecifierDependence 
- toNestedNameSpecifierDependendence(TypeDependence D) { 
-   return Dependence(D).nestedNameSpecifier(); 
- } 
-   
- inline TemplateArgumentDependence 
- toTemplateArgumentDependence(TypeDependence D) { 
-   return Dependence(D).templateArgument(); 
- } 
- inline TemplateArgumentDependence 
- toTemplateArgumentDependence(TemplateNameDependence D) { 
-   return Dependence(D).templateArgument(); 
- } 
- inline TemplateArgumentDependence 
- toTemplateArgumentDependence(ExprDependence D) { 
-   return Dependence(D).templateArgument(); 
- } 
-   
- inline TemplateNameDependence 
- toTemplateNameDependence(NestedNameSpecifierDependence D) { 
-   return Dependence(D).templateName(); 
- } 
-   
- LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); 
-   
- } // namespace clang 
- #endif 
-