15ffd83dbSDimitry Andric //===--- DependenceFlags.h ------------------------------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric #ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H
95ffd83dbSDimitry Andric #define LLVM_CLANG_AST_DEPENDENCEFLAGS_H
105ffd83dbSDimitry Andric
115ffd83dbSDimitry Andric #include "clang/Basic/BitmaskEnum.h"
125ffd83dbSDimitry Andric #include "llvm/ADT/BitmaskEnum.h"
135ffd83dbSDimitry Andric #include <cstdint>
145ffd83dbSDimitry Andric
155ffd83dbSDimitry Andric namespace clang {
165ffd83dbSDimitry Andric struct ExprDependenceScope {
175ffd83dbSDimitry Andric enum ExprDependence : uint8_t {
185ffd83dbSDimitry Andric UnexpandedPack = 1,
195ffd83dbSDimitry Andric // This expr depends in any way on
205ffd83dbSDimitry Andric // - a template parameter, it implies that the resolution of this expr may
215ffd83dbSDimitry Andric // cause instantiation to fail
225ffd83dbSDimitry Andric // - or an error (often in a non-template context)
235ffd83dbSDimitry Andric //
245ffd83dbSDimitry Andric // Note that C++ standard doesn't define the instantiation-dependent term,
255ffd83dbSDimitry Andric // we follow the formal definition coming from the Itanium C++ ABI, and
265ffd83dbSDimitry Andric // extend it to errors.
275ffd83dbSDimitry Andric Instantiation = 2,
285ffd83dbSDimitry Andric // The type of this expr depends on a template parameter, or an error.
295ffd83dbSDimitry Andric Type = 4,
305ffd83dbSDimitry Andric // The value of this expr depends on a template parameter, or an error.
315ffd83dbSDimitry Andric Value = 8,
325ffd83dbSDimitry Andric
335ffd83dbSDimitry Andric // clang extension: this expr contains or references an error, and is
345ffd83dbSDimitry Andric // considered dependent on how that error is resolved.
355ffd83dbSDimitry Andric Error = 16,
365ffd83dbSDimitry Andric
375ffd83dbSDimitry Andric None = 0,
385ffd83dbSDimitry Andric All = 31,
395ffd83dbSDimitry Andric
405ffd83dbSDimitry Andric TypeValue = Type | Value,
415ffd83dbSDimitry Andric TypeInstantiation = Type | Instantiation,
425ffd83dbSDimitry Andric ValueInstantiation = Value | Instantiation,
435ffd83dbSDimitry Andric TypeValueInstantiation = Type | Value | Instantiation,
44e8d8bef9SDimitry Andric ErrorDependent = Error | ValueInstantiation,
455ffd83dbSDimitry Andric
465ffd83dbSDimitry Andric LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
475ffd83dbSDimitry Andric };
485ffd83dbSDimitry Andric };
495ffd83dbSDimitry Andric using ExprDependence = ExprDependenceScope::ExprDependence;
505ffd83dbSDimitry Andric
515ffd83dbSDimitry Andric struct TypeDependenceScope {
525ffd83dbSDimitry Andric enum TypeDependence : uint8_t {
535ffd83dbSDimitry Andric /// Whether this type contains an unexpanded parameter pack
545ffd83dbSDimitry Andric /// (for C++11 variadic templates)
555ffd83dbSDimitry Andric UnexpandedPack = 1,
565ffd83dbSDimitry Andric /// Whether this type somehow involves
575ffd83dbSDimitry Andric /// - a template parameter, even if the resolution of the type does not
585ffd83dbSDimitry Andric /// depend on a template parameter.
595ffd83dbSDimitry Andric /// - or an error.
605ffd83dbSDimitry Andric Instantiation = 2,
615ffd83dbSDimitry Andric /// Whether this type
625ffd83dbSDimitry Andric /// - is a dependent type (C++ [temp.dep.type])
635ffd83dbSDimitry Andric /// - or it somehow involves an error, e.g. decltype(recovery-expr)
645ffd83dbSDimitry Andric Dependent = 4,
655ffd83dbSDimitry Andric /// Whether this type is a variably-modified type (C99 6.7.5).
665ffd83dbSDimitry Andric VariablyModified = 8,
675ffd83dbSDimitry Andric
685ffd83dbSDimitry Andric /// Whether this type references an error, e.g. decltype(err-expression)
695ffd83dbSDimitry Andric /// yields an error type.
705ffd83dbSDimitry Andric Error = 16,
715ffd83dbSDimitry Andric
725ffd83dbSDimitry Andric None = 0,
735ffd83dbSDimitry Andric All = 31,
745ffd83dbSDimitry Andric
755ffd83dbSDimitry Andric DependentInstantiation = Dependent | Instantiation,
765ffd83dbSDimitry Andric
775ffd83dbSDimitry Andric LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
785ffd83dbSDimitry Andric };
795ffd83dbSDimitry Andric };
805ffd83dbSDimitry Andric using TypeDependence = TypeDependenceScope::TypeDependence;
815ffd83dbSDimitry Andric
825ffd83dbSDimitry Andric #define LLVM_COMMON_DEPENDENCE(NAME) \
835ffd83dbSDimitry Andric struct NAME##Scope { \
845ffd83dbSDimitry Andric enum NAME : uint8_t { \
855ffd83dbSDimitry Andric UnexpandedPack = 1, \
865ffd83dbSDimitry Andric Instantiation = 2, \
875ffd83dbSDimitry Andric Dependent = 4, \
885ffd83dbSDimitry Andric Error = 8, \
895ffd83dbSDimitry Andric \
905ffd83dbSDimitry Andric None = 0, \
915ffd83dbSDimitry Andric DependentInstantiation = Dependent | Instantiation, \
925ffd83dbSDimitry Andric All = 15, \
935ffd83dbSDimitry Andric \
945ffd83dbSDimitry Andric LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \
955ffd83dbSDimitry Andric }; \
965ffd83dbSDimitry Andric }; \
975ffd83dbSDimitry Andric using NAME = NAME##Scope::NAME;
985ffd83dbSDimitry Andric
995ffd83dbSDimitry Andric LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence)
LLVM_COMMON_DEPENDENCE(TemplateNameDependence)1005ffd83dbSDimitry Andric LLVM_COMMON_DEPENDENCE(TemplateNameDependence)
1015ffd83dbSDimitry Andric LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence)
1025ffd83dbSDimitry Andric #undef LLVM_COMMON_DEPENDENCE
1035ffd83dbSDimitry Andric
1045ffd83dbSDimitry Andric // A combined space of all dependence concepts for all node types.
1055ffd83dbSDimitry Andric // Used when aggregating dependence of nodes of different types.
1065ffd83dbSDimitry Andric class Dependence {
1075ffd83dbSDimitry Andric public:
1085ffd83dbSDimitry Andric enum Bits : uint8_t {
1095ffd83dbSDimitry Andric None = 0,
1105ffd83dbSDimitry Andric
1115ffd83dbSDimitry Andric // Contains a template parameter pack that wasn't expanded.
1125ffd83dbSDimitry Andric UnexpandedPack = 1,
1135ffd83dbSDimitry Andric // Depends on a template parameter or an error in some way.
1145ffd83dbSDimitry Andric // Validity depends on how the template is instantiated or the error is
1155ffd83dbSDimitry Andric // resolved.
1165ffd83dbSDimitry Andric Instantiation = 2,
1175ffd83dbSDimitry Andric // Expression type depends on template context, or an error.
1185ffd83dbSDimitry Andric // Value and Instantiation should also be set.
1195ffd83dbSDimitry Andric Type = 4,
1205ffd83dbSDimitry Andric // Expression value depends on template context, or an error.
1215ffd83dbSDimitry Andric // Instantiation should also be set.
1225ffd83dbSDimitry Andric Value = 8,
1235ffd83dbSDimitry Andric // Depends on template context, or an error.
1245ffd83dbSDimitry Andric // The type/value distinction is only meaningful for expressions.
1255ffd83dbSDimitry Andric Dependent = Type | Value,
1265ffd83dbSDimitry Andric // Includes an error, and depends on how it is resolved.
1275ffd83dbSDimitry Andric Error = 16,
1285ffd83dbSDimitry Andric // Type depends on a runtime value (variable-length array).
1295ffd83dbSDimitry Andric VariablyModified = 32,
1305ffd83dbSDimitry Andric
131fe6060f1SDimitry Andric // Dependence that is propagated syntactically, regardless of semantics.
132fe6060f1SDimitry Andric Syntactic = UnexpandedPack | Instantiation | Error,
1333b7f365eSDimitry Andric // Dependence that is propagated semantically, even in cases where the
1343b7f365eSDimitry Andric // type doesn't syntactically appear. This currently excludes only
1353b7f365eSDimitry Andric // UnexpandedPack. Even though Instantiation dependence is also notionally
1363b7f365eSDimitry Andric // syntactic, we also want to propagate it semantically because anything
1373b7f365eSDimitry Andric // that semantically depends on an instantiation-dependent entity should
1383b7f365eSDimitry Andric // always be instantiated when that instantiation-dependent entity is.
1393b7f365eSDimitry Andric Semantic =
1403b7f365eSDimitry Andric Instantiation | Type | Value | Dependent | Error | VariablyModified,
141fe6060f1SDimitry Andric
1425ffd83dbSDimitry Andric LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
1435ffd83dbSDimitry Andric };
1445ffd83dbSDimitry Andric
1455ffd83dbSDimitry Andric Dependence() : V(None) {}
1465ffd83dbSDimitry Andric
1475ffd83dbSDimitry Andric Dependence(TypeDependence D)
1485ffd83dbSDimitry Andric : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
1495ffd83dbSDimitry Andric translate(D, TypeDependence::Instantiation, Instantiation) |
1505ffd83dbSDimitry Andric translate(D, TypeDependence::Dependent, Dependent) |
1515ffd83dbSDimitry Andric translate(D, TypeDependence::Error, Error) |
1525ffd83dbSDimitry Andric translate(D, TypeDependence::VariablyModified, VariablyModified)) {}
1535ffd83dbSDimitry Andric
1545ffd83dbSDimitry Andric Dependence(ExprDependence D)
1555ffd83dbSDimitry Andric : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
1565ffd83dbSDimitry Andric translate(D, ExprDependence::Instantiation, Instantiation) |
1575ffd83dbSDimitry Andric translate(D, ExprDependence::Type, Type) |
1585ffd83dbSDimitry Andric translate(D, ExprDependence::Value, Value) |
1595ffd83dbSDimitry Andric translate(D, ExprDependence::Error, Error)) {}
1605ffd83dbSDimitry Andric
1615ffd83dbSDimitry Andric Dependence(NestedNameSpecifierDependence D) :
1625ffd83dbSDimitry Andric V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) |
1635ffd83dbSDimitry Andric translate(D, NNSDependence::Instantiation, Instantiation) |
1645ffd83dbSDimitry Andric translate(D, NNSDependence::Dependent, Dependent) |
1655ffd83dbSDimitry Andric translate(D, NNSDependence::Error, Error)) {}
1665ffd83dbSDimitry Andric
1675ffd83dbSDimitry Andric Dependence(TemplateArgumentDependence D)
1685ffd83dbSDimitry Andric : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) |
1695ffd83dbSDimitry Andric translate(D, TADependence::Instantiation, Instantiation) |
1705ffd83dbSDimitry Andric translate(D, TADependence::Dependent, Dependent) |
1715ffd83dbSDimitry Andric translate(D, TADependence::Error, Error)) {}
1725ffd83dbSDimitry Andric
1735ffd83dbSDimitry Andric Dependence(TemplateNameDependence D)
1745ffd83dbSDimitry Andric : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) |
1755ffd83dbSDimitry Andric translate(D, TNDependence::Instantiation, Instantiation) |
1765ffd83dbSDimitry Andric translate(D, TNDependence::Dependent, Dependent) |
1775ffd83dbSDimitry Andric translate(D, TNDependence::Error, Error)) {}
1785ffd83dbSDimitry Andric
179fe6060f1SDimitry Andric /// Extract only the syntactic portions of this type's dependence.
180fe6060f1SDimitry Andric Dependence syntactic() {
181fe6060f1SDimitry Andric Dependence Result = *this;
182fe6060f1SDimitry Andric Result.V &= Syntactic;
183fe6060f1SDimitry Andric return Result;
184fe6060f1SDimitry Andric }
185fe6060f1SDimitry Andric
1863b7f365eSDimitry Andric /// Extract the semantic portions of this type's dependence that apply even
1873b7f365eSDimitry Andric /// to uses where the type does not appear syntactically.
1883b7f365eSDimitry Andric Dependence semantic() {
1893b7f365eSDimitry Andric Dependence Result = *this;
1903b7f365eSDimitry Andric Result.V &= Semantic;
1913b7f365eSDimitry Andric return Result;
1923b7f365eSDimitry Andric }
1933b7f365eSDimitry Andric
1945ffd83dbSDimitry Andric TypeDependence type() const {
1955ffd83dbSDimitry Andric return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
1965ffd83dbSDimitry Andric translate(V, Instantiation, TypeDependence::Instantiation) |
1975ffd83dbSDimitry Andric translate(V, Dependent, TypeDependence::Dependent) |
1985ffd83dbSDimitry Andric translate(V, Error, TypeDependence::Error) |
1995ffd83dbSDimitry Andric translate(V, VariablyModified, TypeDependence::VariablyModified);
2005ffd83dbSDimitry Andric }
2015ffd83dbSDimitry Andric
2025ffd83dbSDimitry Andric ExprDependence expr() const {
2035ffd83dbSDimitry Andric return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) |
2045ffd83dbSDimitry Andric translate(V, Instantiation, ExprDependence::Instantiation) |
2055ffd83dbSDimitry Andric translate(V, Type, ExprDependence::Type) |
2065ffd83dbSDimitry Andric translate(V, Value, ExprDependence::Value) |
2075ffd83dbSDimitry Andric translate(V, Error, ExprDependence::Error);
2085ffd83dbSDimitry Andric }
2095ffd83dbSDimitry Andric
2105ffd83dbSDimitry Andric NestedNameSpecifierDependence nestedNameSpecifier() const {
2115ffd83dbSDimitry Andric return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) |
2125ffd83dbSDimitry Andric translate(V, Instantiation, NNSDependence::Instantiation) |
2135ffd83dbSDimitry Andric translate(V, Dependent, NNSDependence::Dependent) |
2145ffd83dbSDimitry Andric translate(V, Error, NNSDependence::Error);
2155ffd83dbSDimitry Andric }
2165ffd83dbSDimitry Andric
2175ffd83dbSDimitry Andric TemplateArgumentDependence templateArgument() const {
2185ffd83dbSDimitry Andric return translate(V, UnexpandedPack, TADependence::UnexpandedPack) |
2195ffd83dbSDimitry Andric translate(V, Instantiation, TADependence::Instantiation) |
2205ffd83dbSDimitry Andric translate(V, Dependent, TADependence::Dependent) |
2215ffd83dbSDimitry Andric translate(V, Error, TADependence::Error);
2225ffd83dbSDimitry Andric }
2235ffd83dbSDimitry Andric
2245ffd83dbSDimitry Andric TemplateNameDependence templateName() const {
2255ffd83dbSDimitry Andric return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) |
2265ffd83dbSDimitry Andric translate(V, Instantiation, TNDependence::Instantiation) |
2275ffd83dbSDimitry Andric translate(V, Dependent, TNDependence::Dependent) |
2285ffd83dbSDimitry Andric translate(V, Error, TNDependence::Error);
2295ffd83dbSDimitry Andric }
2305ffd83dbSDimitry Andric
2315ffd83dbSDimitry Andric private:
2325ffd83dbSDimitry Andric Bits V;
2335ffd83dbSDimitry Andric
2345ffd83dbSDimitry Andric template <typename T, typename U>
2355ffd83dbSDimitry Andric static U translate(T Bits, T FromBit, U ToBit) {
2365ffd83dbSDimitry Andric return (Bits & FromBit) ? ToBit : static_cast<U>(0);
2375ffd83dbSDimitry Andric }
2385ffd83dbSDimitry Andric
2395ffd83dbSDimitry Andric // Abbreviations to make conversions more readable.
2405ffd83dbSDimitry Andric using NNSDependence = NestedNameSpecifierDependence;
2415ffd83dbSDimitry Andric using TADependence = TemplateArgumentDependence;
2425ffd83dbSDimitry Andric using TNDependence = TemplateNameDependence;
2435ffd83dbSDimitry Andric };
2445ffd83dbSDimitry Andric
2455ffd83dbSDimitry Andric /// Computes dependencies of a reference with the name having template arguments
2465ffd83dbSDimitry Andric /// with \p TA dependencies.
toExprDependence(TemplateArgumentDependence TA)2475ffd83dbSDimitry Andric inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
2485ffd83dbSDimitry Andric return Dependence(TA).expr();
2495ffd83dbSDimitry Andric }
toExprDependenceForImpliedType(TypeDependence D)2503b7f365eSDimitry Andric inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) {
2513b7f365eSDimitry Andric return Dependence(D).semantic().expr();
2523b7f365eSDimitry Andric }
toExprDependenceAsWritten(TypeDependence D)2533b7f365eSDimitry Andric inline ExprDependence toExprDependenceAsWritten(TypeDependence D) {
2545ffd83dbSDimitry Andric return Dependence(D).expr();
2555ffd83dbSDimitry Andric }
2565ffd83dbSDimitry Andric // Note: it's often necessary to strip `Dependent` from qualifiers.
2575ffd83dbSDimitry Andric // If V<T>:: refers to the current instantiation, NNS is considered dependent
2585ffd83dbSDimitry Andric // but the containing V<T>::foo likely isn't.
toExprDependence(NestedNameSpecifierDependence D)2595ffd83dbSDimitry Andric inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) {
2605ffd83dbSDimitry Andric return Dependence(D).expr();
2615ffd83dbSDimitry Andric }
turnTypeToValueDependence(ExprDependence D)2625ffd83dbSDimitry Andric inline ExprDependence turnTypeToValueDependence(ExprDependence D) {
2635ffd83dbSDimitry Andric // Type-dependent expressions are always be value-dependent, so we simply drop
2645ffd83dbSDimitry Andric // type dependency.
2655ffd83dbSDimitry Andric return D & ~ExprDependence::Type;
2665ffd83dbSDimitry Andric }
turnValueToTypeDependence(ExprDependence D)2675ffd83dbSDimitry Andric inline ExprDependence turnValueToTypeDependence(ExprDependence D) {
2685ffd83dbSDimitry Andric // Type-dependent expressions are always be value-dependent.
2695ffd83dbSDimitry Andric if (D & ExprDependence::Value)
2705ffd83dbSDimitry Andric D |= ExprDependence::Type;
2715ffd83dbSDimitry Andric return D;
2725ffd83dbSDimitry Andric }
2735ffd83dbSDimitry Andric
2745ffd83dbSDimitry Andric // Returned type-dependence will never have VariablyModified set.
toTypeDependence(ExprDependence D)2755ffd83dbSDimitry Andric inline TypeDependence toTypeDependence(ExprDependence D) {
2765ffd83dbSDimitry Andric return Dependence(D).type();
2775ffd83dbSDimitry Andric }
toTypeDependence(NestedNameSpecifierDependence D)2785ffd83dbSDimitry Andric inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) {
2795ffd83dbSDimitry Andric return Dependence(D).type();
2805ffd83dbSDimitry Andric }
toTypeDependence(TemplateNameDependence D)2815ffd83dbSDimitry Andric inline TypeDependence toTypeDependence(TemplateNameDependence D) {
2825ffd83dbSDimitry Andric return Dependence(D).type();
2835ffd83dbSDimitry Andric }
toTypeDependence(TemplateArgumentDependence D)2845ffd83dbSDimitry Andric inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
2855ffd83dbSDimitry Andric return Dependence(D).type();
2865ffd83dbSDimitry Andric }
2875ffd83dbSDimitry Andric
toSyntacticDependence(TypeDependence D)288fe6060f1SDimitry Andric inline TypeDependence toSyntacticDependence(TypeDependence D) {
289fe6060f1SDimitry Andric return Dependence(D).syntactic().type();
290fe6060f1SDimitry Andric }
toSemanticDependence(TypeDependence D)2913b7f365eSDimitry Andric inline TypeDependence toSemanticDependence(TypeDependence D) {
2923b7f365eSDimitry Andric return Dependence(D).semantic().type();
2933b7f365eSDimitry Andric }
294fe6060f1SDimitry Andric
2955ffd83dbSDimitry Andric inline NestedNameSpecifierDependence
toNestedNameSpecifierDependendence(TypeDependence D)2965ffd83dbSDimitry Andric toNestedNameSpecifierDependendence(TypeDependence D) {
2975ffd83dbSDimitry Andric return Dependence(D).nestedNameSpecifier();
2985ffd83dbSDimitry Andric }
2995ffd83dbSDimitry Andric
3005ffd83dbSDimitry Andric inline TemplateArgumentDependence
toTemplateArgumentDependence(TypeDependence D)3015ffd83dbSDimitry Andric toTemplateArgumentDependence(TypeDependence D) {
3025ffd83dbSDimitry Andric return Dependence(D).templateArgument();
3035ffd83dbSDimitry Andric }
3045ffd83dbSDimitry Andric inline TemplateArgumentDependence
toTemplateArgumentDependence(TemplateNameDependence D)3055ffd83dbSDimitry Andric toTemplateArgumentDependence(TemplateNameDependence D) {
3065ffd83dbSDimitry Andric return Dependence(D).templateArgument();
3075ffd83dbSDimitry Andric }
3085ffd83dbSDimitry Andric inline TemplateArgumentDependence
toTemplateArgumentDependence(ExprDependence D)3095ffd83dbSDimitry Andric toTemplateArgumentDependence(ExprDependence D) {
3105ffd83dbSDimitry Andric return Dependence(D).templateArgument();
3115ffd83dbSDimitry Andric }
3125ffd83dbSDimitry Andric
3135ffd83dbSDimitry Andric inline TemplateNameDependence
toTemplateNameDependence(NestedNameSpecifierDependence D)3145ffd83dbSDimitry Andric toTemplateNameDependence(NestedNameSpecifierDependence D) {
3155ffd83dbSDimitry Andric return Dependence(D).templateName();
3165ffd83dbSDimitry Andric }
3175ffd83dbSDimitry Andric
3185ffd83dbSDimitry Andric LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
3195ffd83dbSDimitry Andric
3205ffd83dbSDimitry Andric } // namespace clang
3215ffd83dbSDimitry Andric #endif
322