Make it possible to store NodeKinds in ArgKind
authorStephen Kelly <steveire@gmail.com>
Sat, 6 Feb 2021 23:28:50 +0000 (23:28 +0000)
committerStephen Kelly <steveire@gmail.com>
Sun, 7 Feb 2021 14:00:45 +0000 (14:00 +0000)
clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
clang/lib/ASTMatchers/Dynamic/VariantValue.cpp

index abfb297..5b3f8a7 100644 (file)
@@ -35,6 +35,7 @@ class ArgKind {
  public:
   enum Kind {
     AK_Matcher,
+    AK_Node,
     AK_Boolean,
     AK_Double,
     AK_Unsigned,
@@ -48,11 +49,19 @@ class ArgKind {
     return ArgKind{AK_Matcher, MatcherKind};
   }
 
+  static ArgKind MakeNodeArg(ASTNodeKind MatcherKind) {
+    return ArgKind{AK_Node, MatcherKind};
+  }
+
   Kind getArgKind() const { return K; }
   ASTNodeKind getMatcherKind() const {
     assert(K == AK_Matcher);
     return NodeKind;
   }
+  ASTNodeKind getNodeKind() const {
+    assert(K == AK_Node);
+    return NodeKind;
+  }
 
   /// Determines if this type can be converted to \p To.
   ///
@@ -63,7 +72,8 @@ class ArgKind {
   bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
 
   bool operator<(const ArgKind &Other) const {
-    if (K == AK_Matcher && Other.K == AK_Matcher)
+    if ((K == AK_Matcher && Other.K == AK_Matcher) ||
+        (K == AK_Node && Other.K == AK_Node))
       return NodeKind < Other.NodeKind;
     return K < Other.K;
   }
index d367ad0..813eb15 100644 (file)
@@ -23,6 +23,8 @@ std::string ArgKind::asString() const {
   switch (getArgKind()) {
   case AK_Matcher:
     return (Twine("Matcher<") + NodeKind.asStringRef() + ">").str();
+  case AK_Node:
+    return NodeKind.asStringRef().str();
   case AK_Boolean:
     return "boolean";
   case AK_Double:
@@ -38,7 +40,7 @@ std::string ArgKind::asString() const {
 bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const {
   if (K != To.K)
     return false;
-  if (K != AK_Matcher) {
+  if (K != AK_Matcher && K != AK_Node) {
     if (Specificity)
       *Specificity = 1;
     return true;
@@ -443,6 +445,11 @@ bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const {
     *Specificity = 1;
     return true;
 
+  case ArgKind::AK_Node:
+    if (!isNodeKind())
+      return false;
+    return getMatcher().isConvertibleTo(Kind.getNodeKind(), Specificity);
+
   case ArgKind::AK_Matcher:
     if (!isMatcher())
       return false;