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