diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/ASTMatchers/Dynamic')
4 files changed, 220 insertions, 40 deletions
diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp index 989ee0fa75cd..f6fdbe868e2d 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp @@ -89,8 +89,9 @@ llvm::Optional<std::string> clang::ast_matchers::dynamic::internal::ArgTypeTraits< clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) { static constexpr llvm::StringRef Allowed[] = { -#define OMP_CLAUSE_CLASS(Enum, Str, Class) #Enum, -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define GEN_CLANG_CLAUSE_CLASS +#define CLAUSE_CLASS(Enum, Str, Class) #Enum, +#include "llvm/Frontend/OpenMP/OMP.inc" }; if (Value.isString()) return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed), @@ -120,7 +121,8 @@ static constexpr std::pair<llvm::StringRef, llvm::Regex::RegexFlags> {"BasicRegex", llvm::Regex::RegexFlags::BasicRegex}, }; -llvm::Optional<llvm::Regex::RegexFlags> getRegexFlag(llvm::StringRef Flag) { +static llvm::Optional<llvm::Regex::RegexFlags> +getRegexFlag(llvm::StringRef Flag) { for (const auto &StringFlag : RegexMap) { if (Flag == StringFlag.first) return StringFlag.second; @@ -128,7 +130,8 @@ llvm::Optional<llvm::Regex::RegexFlags> getRegexFlag(llvm::StringRef Flag) { return llvm::None; } -llvm::Optional<llvm::StringRef> getCloseRegexMatch(llvm::StringRef Flag) { +static llvm::Optional<llvm::StringRef> +getCloseRegexMatch(llvm::StringRef Flag) { for (const auto &StringFlag : RegexMap) { if (Flag.edit_distance(StringFlag.first) < 3) return StringFlag.first; diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 33f6d1e4155c..690b52162e2b 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -58,7 +58,10 @@ template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { }; template <> struct ArgTypeTraits<std::string> { - static bool is(const VariantValue &Value) { return Value.isString(); } + static bool hasCorrectType(const VariantValue &Value) { + return Value.isString(); + } + static bool hasCorrectValue(const VariantValue &Value) { return true; } static const std::string &get(const VariantValue &Value) { return Value.getString(); @@ -78,8 +81,11 @@ struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { }; template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> { - static bool is(const VariantValue &Value) { - return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>(); + static bool hasCorrectType(const VariantValue& Value) { + return Value.isMatcher(); + } + static bool hasCorrectValue(const VariantValue &Value) { + return Value.getMatcher().hasTypedMatcher<T>(); } static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { @@ -96,7 +102,10 @@ template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> { }; template <> struct ArgTypeTraits<bool> { - static bool is(const VariantValue &Value) { return Value.isBoolean(); } + static bool hasCorrectType(const VariantValue &Value) { + return Value.isBoolean(); + } + static bool hasCorrectValue(const VariantValue &Value) { return true; } static bool get(const VariantValue &Value) { return Value.getBoolean(); @@ -112,7 +121,10 @@ template <> struct ArgTypeTraits<bool> { }; template <> struct ArgTypeTraits<double> { - static bool is(const VariantValue &Value) { return Value.isDouble(); } + static bool hasCorrectType(const VariantValue &Value) { + return Value.isDouble(); + } + static bool hasCorrectValue(const VariantValue &Value) { return true; } static double get(const VariantValue &Value) { return Value.getDouble(); @@ -128,7 +140,10 @@ template <> struct ArgTypeTraits<double> { }; template <> struct ArgTypeTraits<unsigned> { - static bool is(const VariantValue &Value) { return Value.isUnsigned(); } + static bool hasCorrectType(const VariantValue &Value) { + return Value.isUnsigned(); + } + static bool hasCorrectValue(const VariantValue &Value) { return true; } static unsigned get(const VariantValue &Value) { return Value.getUnsigned(); @@ -146,15 +161,20 @@ template <> struct ArgTypeTraits<unsigned> { template <> struct ArgTypeTraits<attr::Kind> { private: static Optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) { + if (!AttrKind.consume_front("attr::")) + return llvm::None; return llvm::StringSwitch<Optional<attr::Kind>>(AttrKind) -#define ATTR(X) .Case("attr::" #X, attr:: X) +#define ATTR(X) .Case(#X, attr::X) #include "clang/Basic/AttrList.inc" .Default(llvm::None); } public: - static bool is(const VariantValue &Value) { - return Value.isString() && getAttrKind(Value.getString()); + static bool hasCorrectType(const VariantValue &Value) { + return Value.isString(); + } + static bool hasCorrectValue(const VariantValue& Value) { + return getAttrKind(Value.getString()).hasValue(); } static attr::Kind get(const VariantValue &Value) { @@ -171,15 +191,20 @@ public: template <> struct ArgTypeTraits<CastKind> { private: static Optional<CastKind> getCastKind(llvm::StringRef AttrKind) { + if (!AttrKind.consume_front("CK_")) + return llvm::None; return llvm::StringSwitch<Optional<CastKind>>(AttrKind) -#define CAST_OPERATION(Name) .Case("CK_" #Name, CK_##Name) +#define CAST_OPERATION(Name) .Case(#Name, CK_##Name) #include "clang/AST/OperationKinds.def" .Default(llvm::None); } public: - static bool is(const VariantValue &Value) { - return Value.isString() && getCastKind(Value.getString()); + static bool hasCorrectType(const VariantValue &Value) { + return Value.isString(); + } + static bool hasCorrectValue(const VariantValue& Value) { + return getCastKind(Value.getString()).hasValue(); } static CastKind get(const VariantValue &Value) { @@ -198,8 +223,11 @@ private: static Optional<llvm::Regex::RegexFlags> getFlags(llvm::StringRef Flags); public: - static bool is(const VariantValue &Value) { - return Value.isString() && getFlags(Value.getString()); + static bool hasCorrectType(const VariantValue &Value) { + return Value.isString(); + } + static bool hasCorrectValue(const VariantValue& Value) { + return getFlags(Value.getString()).hasValue(); } static llvm::Regex::RegexFlags get(const VariantValue &Value) { @@ -215,14 +243,18 @@ template <> struct ArgTypeTraits<OpenMPClauseKind> { private: static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) { return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind) -#define OMP_CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define GEN_CLANG_CLAUSE_CLASS +#define CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) +#include "llvm/Frontend/OpenMP/OMP.inc" .Default(llvm::None); } public: - static bool is(const VariantValue &Value) { - return Value.isString() && getClauseKind(Value.getString()); + static bool hasCorrectType(const VariantValue &Value) { + return Value.isString(); + } + static bool hasCorrectValue(const VariantValue& Value) { + return getClauseKind(Value.getString()).hasValue(); } static OpenMPClauseKind get(const VariantValue &Value) { @@ -238,18 +270,22 @@ template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> { private: static Optional<UnaryExprOrTypeTrait> getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) { + if (!ClauseKind.consume_front("UETT_")) + return llvm::None; return llvm::StringSwitch<Optional<UnaryExprOrTypeTrait>>(ClauseKind) -#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \ - .Case("UETT_" #Name, UETT_##Name) +#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) .Case(#Name, UETT_##Name) #define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \ - .Case("UETT_" #Name, UETT_##Name) + .Case(#Name, UETT_##Name) #include "clang/Basic/TokenKinds.def" .Default(llvm::None); } public: - static bool is(const VariantValue &Value) { - return Value.isString() && getUnaryOrTypeTraitKind(Value.getString()); + static bool hasCorrectType(const VariantValue &Value) { + return Value.isString(); + } + static bool hasCorrectValue(const VariantValue& Value) { + return getUnaryOrTypeTraitKind(Value.getString()).hasValue(); } static UnaryExprOrTypeTrait get(const VariantValue &Value) { @@ -453,12 +489,31 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, const ParserValue &Arg = Args[i]; const VariantValue &Value = Arg.Value; - if (!ArgTraits::is(Value)) { + if (!ArgTraits::hasCorrectType(Value)) { Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); HasError = true; break; } + if (!ArgTraits::hasCorrectValue(Value)) { + if (llvm::Optional<std::string> BestGuess = + ArgTraits::getBestGuess(Value)) { + Error->addError(Arg.Range, Error->ET_RegistryUnknownEnumWithReplace) + << i + 1 << Value.getString() << *BestGuess; + } else if (Value.isString()) { + Error->addError(Arg.Range, Error->ET_RegistryValueNotFound) + << Value.getString(); + } else { + // This isn't ideal, but it's better than reporting an empty string as + // the error in this case. + Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) + << (i + 1) << ArgTraits::getKind().asString() + << Value.getTypeAsString(); + } + HasError = true; + break; + } + InnerArgs[i] = new ArgT(ArgTraits::get(Value)); } @@ -568,16 +623,21 @@ private: } #define CHECK_ARG_TYPE(index, type) \ - if (!ArgTypeTraits<type>::is(Args[index].Value)) { \ + if (!ArgTypeTraits<type>::hasCorrectType(Args[index].Value)) { \ + Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ + << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ + << Args[index].Value.getTypeAsString(); \ + return VariantMatcher(); \ + } \ + if (!ArgTypeTraits<type>::hasCorrectValue(Args[index].Value)) { \ if (llvm::Optional<std::string> BestGuess = \ ArgTypeTraits<type>::getBestGuess(Args[index].Value)) { \ Error->addError(Args[index].Range, \ Error->ET_RegistryUnknownEnumWithReplace) \ << index + 1 << Args[index].Value.getString() << *BestGuess; \ - } else { \ - Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ - << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ - << Args[index].Value.getTypeAsString(); \ + } else if (Args[index].Value.isString()) { \ + Error->addError(Args[index].Range, Error->ET_RegistryValueNotFound) \ + << Args[index].Value.getString(); \ } \ return VariantMatcher(); \ } @@ -761,7 +821,7 @@ public: << "1 or 2" << Args.size(); return VariantMatcher(); } - if (!ArgTypeTraits<StringRef>::is(Args[0].Value)) { + if (!ArgTypeTraits<StringRef>::hasCorrectType(Args[0].Value)) { Error->addError(Args[0].Range, Error->ET_RegistryWrongArgType) << 1 << ArgTypeTraits<StringRef>::getKind().asString() << Args[0].Value.getTypeAsString(); @@ -771,16 +831,23 @@ public: return outvalueToVariantMatcher( NoFlags(ArgTypeTraits<StringRef>::get(Args[0].Value))); } - if (!ArgTypeTraits<llvm::Regex::RegexFlags>::is(Args[1].Value)) { + if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectType( + Args[1].Value)) { + Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType) + << 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString() + << Args[1].Value.getTypeAsString(); + return VariantMatcher(); + } + if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectValue( + Args[1].Value)) { if (llvm::Optional<std::string> BestGuess = ArgTypeTraits<llvm::Regex::RegexFlags>::getBestGuess( Args[1].Value)) { Error->addError(Args[1].Range, Error->ET_RegistryUnknownEnumWithReplace) << 2 << Args[1].Value.getString() << *BestGuess; } else { - Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType) - << 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString() - << Args[1].Value.getTypeAsString(); + Error->addError(Args[1].Range, Error->ET_RegistryValueNotFound) + << Args[1].Value.getString(); } return VariantMatcher(); } @@ -858,6 +925,70 @@ private: const StringRef MatcherName; }; +class MapAnyOfMatcherDescriptor : public MatcherDescriptor { + ASTNodeKind CladeNodeKind; + std::vector<ASTNodeKind> NodeKinds; + +public: + MapAnyOfMatcherDescriptor(ASTNodeKind CladeNodeKind, + std::vector<ASTNodeKind> NodeKinds) + : CladeNodeKind(CladeNodeKind), NodeKinds(NodeKinds) {} + + VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args, + Diagnostics *Error) const override { + + std::vector<DynTypedMatcher> NodeArgs; + + for (auto NK : NodeKinds) { + std::vector<DynTypedMatcher> InnerArgs; + + for (const auto &Arg : Args) { + if (!Arg.Value.isMatcher()) + return {}; + const VariantMatcher &VM = Arg.Value.getMatcher(); + if (VM.hasTypedMatcher(NK)) { + auto DM = VM.getTypedMatcher(NK); + InnerArgs.push_back(DM); + } + } + + if (InnerArgs.empty()) { + NodeArgs.push_back( + DynTypedMatcher::trueMatcher(NK).dynCastTo(CladeNodeKind)); + } else { + NodeArgs.push_back( + DynTypedMatcher::constructVariadic( + ast_matchers::internal::DynTypedMatcher::VO_AllOf, NK, + InnerArgs) + .dynCastTo(CladeNodeKind)); + } + } + + auto Result = DynTypedMatcher::constructVariadic( + ast_matchers::internal::DynTypedMatcher::VO_AnyOf, CladeNodeKind, + NodeArgs); + Result.setAllowBind(true); + return VariantMatcher::SingleMatcher(Result); + } + + bool isVariadic() const override { return true; } + unsigned getNumArgs() const override { return 0; } + + void getArgKinds(ASTNodeKind ThisKind, unsigned, + std::vector<ArgKind> &Kinds) const override { + Kinds.push_back(ThisKind); + } + + bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, + ASTNodeKind *LeastDerivedKind) const override { + if (Specificity) + *Specificity = 1; + if (LeastDerivedKind) + *LeastDerivedKind = CladeNodeKind; + return true; + } +}; + /// Helper functions to select the appropriate marshaller functions. /// They detect the number of arguments, arguments types and return type. @@ -962,6 +1093,15 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( MinCount, MaxCount, Func.Op, MatcherName); } +template <typename CladeType, typename... MatcherT> +std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( + ast_matchers::internal::MapAnyOfMatcherImpl<CladeType, MatcherT...>, + StringRef MatcherName) { + return std::make_unique<MapAnyOfMatcherDescriptor>( + ASTNodeKind::getFromNodeKind<CladeType>(), + std::vector<ASTNodeKind>{ASTNodeKind::getFromNodeKind<MatcherT>()...}); +} + } // namespace internal } // namespace dynamic } // namespace ast_matchers diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp index ec2215804c09..00a7c74a0b90 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -31,8 +31,6 @@ #include <utility> #include <vector> -using namespace clang::ast_type_traits; - namespace clang { namespace ast_matchers { namespace dynamic { @@ -145,6 +143,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(autoreleasePoolStmt) REGISTER_MATCHER(binaryConditionalOperator); REGISTER_MATCHER(binaryOperator); + REGISTER_MATCHER(binaryOperation); REGISTER_MATCHER(blockDecl); REGISTER_MATCHER(blockExpr); REGISTER_MATCHER(blockPointerType); @@ -193,6 +192,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(cxxOperatorCallExpr); REGISTER_MATCHER(cxxRecordDecl); REGISTER_MATCHER(cxxReinterpretCastExpr); + REGISTER_MATCHER(cxxRewrittenBinaryOperator); REGISTER_MATCHER(cxxStaticCastExpr); REGISTER_MATCHER(cxxStdInitializerListExpr); REGISTER_MATCHER(cxxTemporaryObjectExpr); @@ -202,6 +202,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(cxxUnresolvedConstructExpr); REGISTER_MATCHER(decayedType); REGISTER_MATCHER(decl); + REGISTER_MATCHER(decompositionDecl); REGISTER_MATCHER(declCountIs); REGISTER_MATCHER(declRefExpr); REGISTER_MATCHER(declStmt); @@ -227,6 +228,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(floatLiteral); REGISTER_MATCHER(forEach); REGISTER_MATCHER(forEachArgumentWithParam); + REGISTER_MATCHER(forEachArgumentWithParamType); REGISTER_MATCHER(forEachConstructorInitializer); REGISTER_MATCHER(forEachDescendant); REGISTER_MATCHER(forEachOverridden); @@ -239,6 +241,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(functionProtoType); REGISTER_MATCHER(functionTemplateDecl); REGISTER_MATCHER(functionType); + REGISTER_MATCHER(genericSelectionExpr); REGISTER_MATCHER(gnuNullExpr); REGISTER_MATCHER(gotoStmt); REGISTER_MATCHER(has); @@ -300,6 +303,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasLocalStorage); REGISTER_MATCHER(hasLoopInit); REGISTER_MATCHER(hasLoopVariable); + REGISTER_MATCHER(hasMemberName); REGISTER_MATCHER(hasMethod); REGISTER_MATCHER(hasName); REGISTER_MATCHER(hasNullSelector); @@ -431,6 +435,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isVirtual); REGISTER_MATCHER(isVirtualAsWritten); REGISTER_MATCHER(isVolatileQualified); + REGISTER_MATCHER(isWeak); REGISTER_MATCHER(isWritten); REGISTER_MATCHER(lValueReferenceType); REGISTER_MATCHER(labelDecl); @@ -440,6 +445,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(materializeTemporaryExpr); REGISTER_MATCHER(member); REGISTER_MATCHER(memberExpr); + REGISTER_MATCHER(memberHasSameNameAsBoundNode); REGISTER_MATCHER(memberPointerType); REGISTER_MATCHER(namedDecl); REGISTER_MATCHER(namesType); @@ -514,6 +520,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(templateArgumentCountIs); REGISTER_MATCHER(templateName); REGISTER_MATCHER(templateSpecializationType); + REGISTER_MATCHER(templateTemplateParmDecl); REGISTER_MATCHER(templateTypeParmDecl); REGISTER_MATCHER(templateTypeParmType); REGISTER_MATCHER(throughUsingDecl); diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp index 866e2d0e3491..d1ecb1e00b91 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp @@ -59,6 +59,11 @@ VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher, return Matcher.canConvertTo(NodeKind); } +DynTypedMatcher VariantMatcher::MatcherOps::convertMatcher( + const DynTypedMatcher &Matcher) const { + return Matcher.dynCastTo(NodeKind); +} + llvm::Optional<DynTypedMatcher> VariantMatcher::MatcherOps::constructVariadicOperator( DynTypedMatcher::VariadicOperator Op, @@ -263,6 +268,10 @@ VariantValue::VariantValue(StringRef String) : Type(VT_Nothing) { setString(String); } +VariantValue::VariantValue(ASTNodeKind NodeKind) : Type(VT_Nothing) { + setNodeKind(NodeKind); +} + VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) { setMatcher(Matcher); } @@ -285,6 +294,9 @@ VariantValue &VariantValue::operator=(const VariantValue &Other) { case VT_String: setString(Other.getString()); break; + case VT_NodeKind: + setNodeKind(Other.getNodeKind()); + break; case VT_Matcher: setMatcher(Other.getMatcher()); break; @@ -303,6 +315,9 @@ void VariantValue::reset() { case VT_Matcher: delete Value.Matcher; break; + case VT_NodeKind: + delete Value.NodeKind; + break; // Cases that do nothing. case VT_Boolean: case VT_Double: @@ -373,6 +388,19 @@ void VariantValue::setString(StringRef NewValue) { Value.String = new std::string(NewValue); } +bool VariantValue::isNodeKind() const { return Type == VT_NodeKind; } + +const ASTNodeKind &VariantValue::getNodeKind() const { + assert(isNodeKind()); + return *Value.NodeKind; +} + +void VariantValue::setNodeKind(ASTNodeKind NewValue) { + reset(); + Type = VT_NodeKind; + Value.NodeKind = new ASTNodeKind(NewValue); +} + bool VariantValue::isMatcher() const { return Type == VT_Matcher; } @@ -444,6 +472,8 @@ std::string VariantValue::getTypeAsString() const { case VT_Boolean: return "Boolean"; case VT_Double: return "Double"; case VT_Unsigned: return "Unsigned"; + case VT_NodeKind: + return getNodeKind().asStringRef().str(); case VT_Nothing: return "Nothing"; } llvm_unreachable("Invalid Type"); |