Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.