DependenceFlags.h 13 KB

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