Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:34

0001 //===--- DependenceFlags.h ------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 #ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H
0009 #define LLVM_CLANG_AST_DEPENDENCEFLAGS_H
0010 
0011 #include "clang/Basic/BitmaskEnum.h"
0012 #include "llvm/ADT/BitmaskEnum.h"
0013 #include <cstdint>
0014 
0015 namespace clang {
0016 struct ExprDependenceScope {
0017   enum ExprDependence : uint8_t {
0018     UnexpandedPack = 1,
0019     // This expr depends in any way on
0020     //   - a template parameter, it implies that the resolution of this expr may
0021     //     cause instantiation to fail
0022     //   - or an error (often in a non-template context)
0023     //
0024     // Note that C++ standard doesn't define the instantiation-dependent term,
0025     // we follow the formal definition coming from the Itanium C++ ABI, and
0026     // extend it to errors.
0027     Instantiation = 2,
0028     // The type of this expr depends on a template parameter, or an error.
0029     Type = 4,
0030     // The value of this expr depends on a template parameter, or an error.
0031     Value = 8,
0032 
0033     // clang extension: this expr contains or references an error, and is
0034     // considered dependent on how that error is resolved.
0035     Error = 16,
0036 
0037     None = 0,
0038     All = 31,
0039 
0040     TypeValue = Type | Value,
0041     TypeInstantiation = Type | Instantiation,
0042     ValueInstantiation = Value | Instantiation,
0043     TypeValueInstantiation = Type | Value | Instantiation,
0044     ErrorDependent = Error | ValueInstantiation,
0045 
0046     LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
0047   };
0048 };
0049 using ExprDependence = ExprDependenceScope::ExprDependence;
0050 
0051 struct TypeDependenceScope {
0052   enum TypeDependence : uint8_t {
0053     /// Whether this type contains an unexpanded parameter pack
0054     /// (for C++11 variadic templates)
0055     UnexpandedPack = 1,
0056     /// Whether this type somehow involves
0057     ///   - a template parameter, even if the resolution of the type does not
0058     ///     depend on a template parameter.
0059     ///   - or an error.
0060     Instantiation = 2,
0061     /// Whether this type
0062     ///   - is a dependent type (C++ [temp.dep.type])
0063     ///   - or it somehow involves an error, e.g. decltype(recovery-expr)
0064     Dependent = 4,
0065     /// Whether this type is a variably-modified type (C99 6.7.5).
0066     VariablyModified = 8,
0067 
0068     /// Whether this type references an error, e.g. decltype(err-expression)
0069     /// yields an error type.
0070     Error = 16,
0071 
0072     None = 0,
0073     All = 31,
0074 
0075     DependentInstantiation = Dependent | Instantiation,
0076 
0077     LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
0078   };
0079 };
0080 using TypeDependence = TypeDependenceScope::TypeDependence;
0081 
0082 #define LLVM_COMMON_DEPENDENCE(NAME)                                           \
0083   struct NAME##Scope {                                                         \
0084     enum NAME : uint8_t {                                                      \
0085       UnexpandedPack = 1,                                                      \
0086       Instantiation = 2,                                                       \
0087       Dependent = 4,                                                           \
0088       Error = 8,                                                               \
0089                                                                                \
0090       None = 0,                                                                \
0091       DependentInstantiation = Dependent | Instantiation,                      \
0092       All = 15,                                                                \
0093                                                                                \
0094       LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)                        \
0095     };                                                                         \
0096   };                                                                           \
0097   using NAME = NAME##Scope::NAME;
0098 
0099 LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence)
0100 LLVM_COMMON_DEPENDENCE(TemplateNameDependence)
0101 LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence)
0102 #undef LLVM_COMMON_DEPENDENCE
0103 
0104 // A combined space of all dependence concepts for all node types.
0105 // Used when aggregating dependence of nodes of different types.
0106 class Dependence {
0107 public:
0108   enum Bits : uint8_t {
0109     None = 0,
0110 
0111     // Contains a template parameter pack that wasn't expanded.
0112     UnexpandedPack = 1,
0113     // Depends on a template parameter or an error in some way.
0114     // Validity depends on how the template is instantiated or the error is
0115     // resolved.
0116     Instantiation = 2,
0117     // Expression type depends on template context, or an error.
0118     // Value and Instantiation should also be set.
0119     Type = 4,
0120     // Expression value depends on template context, or an error.
0121     // Instantiation should also be set.
0122     Value = 8,
0123     // Depends on template context, or an error.
0124     // The type/value distinction is only meaningful for expressions.
0125     Dependent = Type | Value,
0126     // Includes an error, and depends on how it is resolved.
0127     Error = 16,
0128     // Type depends on a runtime value (variable-length array).
0129     VariablyModified = 32,
0130 
0131     // Dependence that is propagated syntactically, regardless of semantics.
0132     Syntactic = UnexpandedPack | Instantiation | Error,
0133     // Dependence that is propagated semantically, even in cases where the
0134     // type doesn't syntactically appear. This currently excludes only
0135     // UnexpandedPack. Even though Instantiation dependence is also notionally
0136     // syntactic, we also want to propagate it semantically because anything
0137     // that semantically depends on an instantiation-dependent entity should
0138     // always be instantiated when that instantiation-dependent entity is.
0139     Semantic =
0140         Instantiation | Type | Value | Dependent | Error | VariablyModified,
0141 
0142     LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
0143   };
0144 
0145   Dependence() : V(None) {}
0146 
0147   Dependence(TypeDependence D)
0148       : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
0149           translate(D, TypeDependence::Instantiation, Instantiation) |
0150           translate(D, TypeDependence::Dependent, Dependent) |
0151           translate(D, TypeDependence::Error, Error) |
0152           translate(D, TypeDependence::VariablyModified, VariablyModified)) {}
0153 
0154   Dependence(ExprDependence D)
0155       : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
0156              translate(D, ExprDependence::Instantiation, Instantiation) |
0157              translate(D, ExprDependence::Type, Type) |
0158              translate(D, ExprDependence::Value, Value) |
0159              translate(D, ExprDependence::Error, Error)) {}
0160 
0161   Dependence(NestedNameSpecifierDependence D) :
0162     V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) |
0163             translate(D, NNSDependence::Instantiation, Instantiation) |
0164             translate(D, NNSDependence::Dependent, Dependent) |
0165             translate(D, NNSDependence::Error, Error)) {}
0166 
0167   Dependence(TemplateArgumentDependence D)
0168       : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) |
0169           translate(D, TADependence::Instantiation, Instantiation) |
0170           translate(D, TADependence::Dependent, Dependent) |
0171           translate(D, TADependence::Error, Error)) {}
0172 
0173   Dependence(TemplateNameDependence D)
0174       : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) |
0175              translate(D, TNDependence::Instantiation, Instantiation) |
0176              translate(D, TNDependence::Dependent, Dependent) |
0177              translate(D, TNDependence::Error, Error)) {}
0178 
0179   /// Extract only the syntactic portions of this type's dependence.
0180   Dependence syntactic() {
0181     Dependence Result = *this;
0182     Result.V &= Syntactic;
0183     return Result;
0184   }
0185 
0186   /// Extract the semantic portions of this type's dependence that apply even
0187   /// to uses where the type does not appear syntactically.
0188   Dependence semantic() {
0189     Dependence Result = *this;
0190     Result.V &= Semantic;
0191     return Result;
0192   }
0193 
0194   TypeDependence type() const {
0195     return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
0196            translate(V, Instantiation, TypeDependence::Instantiation) |
0197            translate(V, Dependent, TypeDependence::Dependent) |
0198            translate(V, Error, TypeDependence::Error) |
0199            translate(V, VariablyModified, TypeDependence::VariablyModified);
0200   }
0201 
0202   ExprDependence expr() const {
0203     return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) |
0204            translate(V, Instantiation, ExprDependence::Instantiation) |
0205            translate(V, Type, ExprDependence::Type) |
0206            translate(V, Value, ExprDependence::Value) |
0207            translate(V, Error, ExprDependence::Error);
0208   }
0209 
0210   NestedNameSpecifierDependence nestedNameSpecifier() const {
0211     return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) |
0212            translate(V, Instantiation, NNSDependence::Instantiation) |
0213            translate(V, Dependent, NNSDependence::Dependent) |
0214            translate(V, Error, NNSDependence::Error);
0215   }
0216 
0217   TemplateArgumentDependence templateArgument() const {
0218     return translate(V, UnexpandedPack, TADependence::UnexpandedPack) |
0219            translate(V, Instantiation, TADependence::Instantiation) |
0220            translate(V, Dependent, TADependence::Dependent) |
0221            translate(V, Error, TADependence::Error);
0222   }
0223 
0224   TemplateNameDependence templateName() const {
0225     return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) |
0226            translate(V, Instantiation, TNDependence::Instantiation) |
0227            translate(V, Dependent, TNDependence::Dependent) |
0228            translate(V, Error, TNDependence::Error);
0229   }
0230 
0231 private:
0232   Bits V;
0233 
0234   template <typename T, typename U>
0235   static U translate(T Bits, T FromBit, U ToBit) {
0236     return (Bits & FromBit) ? ToBit : static_cast<U>(0);
0237   }
0238 
0239   // Abbreviations to make conversions more readable.
0240   using NNSDependence = NestedNameSpecifierDependence;
0241   using TADependence = TemplateArgumentDependence;
0242   using TNDependence = TemplateNameDependence;
0243 };
0244 
0245 /// Computes dependencies of a reference with the name having template arguments
0246 /// with \p TA dependencies.
0247 inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
0248   return Dependence(TA).expr();
0249 }
0250 inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) {
0251   return Dependence(D).semantic().expr();
0252 }
0253 inline ExprDependence toExprDependenceAsWritten(TypeDependence D) {
0254   return Dependence(D).expr();
0255 }
0256 // Note: it's often necessary to strip `Dependent` from qualifiers.
0257 // If V<T>:: refers to the current instantiation, NNS is considered dependent
0258 // but the containing V<T>::foo likely isn't.
0259 inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) {
0260   return Dependence(D).expr();
0261 }
0262 inline ExprDependence turnTypeToValueDependence(ExprDependence D) {
0263   // Type-dependent expressions are always be value-dependent, so we simply drop
0264   // type dependency.
0265   return D & ~ExprDependence::Type;
0266 }
0267 inline ExprDependence turnValueToTypeDependence(ExprDependence D) {
0268   // Type-dependent expressions are always be value-dependent.
0269   if (D & ExprDependence::Value)
0270     D |= ExprDependence::Type;
0271   return D;
0272 }
0273 
0274 // Returned type-dependence will never have VariablyModified set.
0275 inline TypeDependence toTypeDependence(ExprDependence D) {
0276   return Dependence(D).type();
0277 }
0278 inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) {
0279   return Dependence(D).type();
0280 }
0281 inline TypeDependence toTypeDependence(TemplateNameDependence D) {
0282   return Dependence(D).type();
0283 }
0284 inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
0285   return Dependence(D).type();
0286 }
0287 
0288 inline TypeDependence toSyntacticDependence(TypeDependence D) {
0289   return Dependence(D).syntactic().type();
0290 }
0291 inline TypeDependence toSemanticDependence(TypeDependence D) {
0292   return Dependence(D).semantic().type();
0293 }
0294 
0295 inline NestedNameSpecifierDependence
0296 toNestedNameSpecifierDependendence(TypeDependence D) {
0297   return Dependence(D).nestedNameSpecifier();
0298 }
0299 
0300 inline TemplateArgumentDependence
0301 toTemplateArgumentDependence(TypeDependence D) {
0302   return Dependence(D).templateArgument();
0303 }
0304 inline TemplateArgumentDependence
0305 toTemplateArgumentDependence(TemplateNameDependence D) {
0306   return Dependence(D).templateArgument();
0307 }
0308 inline TemplateArgumentDependence
0309 toTemplateArgumentDependence(ExprDependence D) {
0310   return Dependence(D).templateArgument();
0311 }
0312 
0313 inline TemplateNameDependence
0314 toTemplateNameDependence(NestedNameSpecifierDependence D) {
0315   return Dependence(D).templateName();
0316 }
0317 
0318 inline TemplateNameDependence
0319 toTemplateNameDependence(TemplateArgumentDependence D) {
0320   return Dependence(D).templateName();
0321 }
0322 
0323 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
0324 
0325 } // namespace clang
0326 #endif