Hi klimek, sbenza,

The looked-up matchers will be used during code completion.

http://llvm-reviews.chandlerc.com/D2207

Files:
  include/clang/ASTMatchers/Dynamic/Parser.h
  include/clang/ASTMatchers/Dynamic/Registry.h
  lib/ASTMatchers/Dynamic/Parser.cpp
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/Dynamic/ParserTest.cpp
  unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: include/clang/ASTMatchers/Dynamic/Parser.h
===================================================================
--- include/clang/ASTMatchers/Dynamic/Parser.h
+++ include/clang/ASTMatchers/Dynamic/Parser.h
@@ -34,6 +34,7 @@
 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
 
 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/Registry.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -65,7 +66,7 @@
     ///
     /// All the arguments passed here have already been processed.
     ///
-    /// \param MatcherName The matcher name found by the parser.
+    /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
     ///
     /// \param NameRange The location of the name in the matcher source.
     ///   Useful for error reporting.
@@ -78,11 +79,24 @@
     /// \return The matcher objects constructed by the processor, or a null
     ///   matcher if an error occurred. In that case, \c Error will contain a
     ///   description of the error.
-    virtual VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+    virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                                   const SourceRange &NameRange,
                                                   StringRef BindID,
                                                   ArrayRef<ParserValue> Args,
                                                   Diagnostics *Error) = 0;
+
+    /// \brief Look up a matcher by name.
+    ///
+    /// \param MatcherName The matcher name found by the parser.
+    ///
+    /// \param NameRange The location of the name in the matcher source.
+    ///   Useful for error reporting.
+    ///
+    /// \return The matcher constructor, or null if an error occurred. In that
+    ///   case, \c Error will contain a description of the error.
+    virtual MatcherCtor lookupMatcherCtor(StringRef MatcherName,
+                                          const SourceRange &NameRange,
+                                          Diagnostics *Error) = 0;
   };
 
   /// \brief Parse a matcher expression, creating matchers from the registry.
Index: include/clang/ASTMatchers/Dynamic/Registry.h
===================================================================
--- include/clang/ASTMatchers/Dynamic/Registry.h
+++ include/clang/ASTMatchers/Dynamic/Registry.h
@@ -27,12 +27,24 @@
 namespace ast_matchers {
 namespace dynamic {
 
+namespace internal {
+class MatcherCreateCallback;
+}
+
+typedef const internal::MatcherCreateCallback *MatcherCtor;
+
 class Registry {
 public:
-  /// \brief Construct a matcher from the registry by name.
+  /// \brief Look up a matcher in the registry by name,
   ///
-  /// Consult the registry of known matchers and construct the appropriate
-  /// matcher by name.
+  /// \return An opaque pointer which may be used to refer to the matcher
+  /// constructor, or null if not found.  In that case \c Error will contain the
+  /// description of the error.
+  static MatcherCtor lookupMatcherCtor(StringRef MatcherName,
+                                       const SourceRange &NameRange,
+                                       Diagnostics *Error);
+
+  /// \brief Construct a matcher from the registry.
   ///
   /// \param MatcherName The name of the matcher to instantiate.
   ///
@@ -44,10 +56,10 @@
   ///   will return an error.
   ///
   /// \return The matcher object constructed if no error was found.
-  ///   A null matcher if the matcher is not found, or if the number of
-  ///   arguments or argument types do not match the signature.
-  ///   In that case \c Error will contain the description of the error.
-  static VariantMatcher constructMatcher(StringRef MatcherName,
+  ///   A null matcher if the number of arguments or argument types do not match
+  ///   the signature.  In that case \c Error will contain the description of
+  ///   the error.
+  static VariantMatcher constructMatcher(MatcherCtor Ctor,
                                          const SourceRange &NameRange,
                                          ArrayRef<ParserValue> Args,
                                          Diagnostics *Error);
@@ -58,7 +70,7 @@
   /// matcher to the specified \c BindID.
   /// If the matcher is not bindable, it sets an error in \c Error and returns
   /// a null matcher.
-  static VariantMatcher constructBoundMatcher(StringRef MatcherName,
+  static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
                                               const SourceRange &NameRange,
                                               StringRef BindID,
                                               ArrayRef<ParserValue> Args,
Index: lib/ASTMatchers/Dynamic/Parser.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Parser.cpp
+++ lib/ASTMatchers/Dynamic/Parser.cpp
@@ -242,6 +242,9 @@
     return false;
   }
 
+  MatcherCtor Ctor =
+      S->lookupMatcherCtor(NameToken.Text, NameToken.Range, Error);
+
   std::vector<ParserValue> Args;
   TokenInfo EndToken;
   while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
@@ -306,13 +309,16 @@
     BindID = IDToken.Value.getString();
   }
 
+  if (!Ctor)
+    return false;
+
   // Merge the start and end infos.
   Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
                            NameToken.Text, NameToken.Range);
   SourceRange MatcherRange = NameToken.Range;
   MatcherRange.End = EndToken.Range.End;
   VariantMatcher Result = S->actOnMatcherExpression(
-      NameToken.Text, MatcherRange, BindID, Args, Error);
+      Ctor, MatcherRange, BindID, Args, Error);
   if (Result.isNull()) return false;
 
   *Value = Result;
@@ -358,16 +364,21 @@
 class RegistrySema : public Parser::Sema {
 public:
   virtual ~RegistrySema() {}
-  VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+  MatcherCtor lookupMatcherCtor(StringRef MatcherName,
+                                const SourceRange &NameRange,
+                                Diagnostics *Error) {
+    return Registry::lookupMatcherCtor(MatcherName, NameRange, Error);
+  }
+  VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                         const SourceRange &NameRange,
                                         StringRef BindID,
                                         ArrayRef<ParserValue> Args,
                                         Diagnostics *Error) {
     if (BindID.empty()) {
-      return Registry::constructMatcher(MatcherName, NameRange, Args, Error);
+      return Registry::constructMatcher(Ctor, NameRange, Args, Error);
     } else {
-      return Registry::constructBoundMatcher(MatcherName, NameRange, BindID,
-                                             Args, Error);
+      return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
+                                             Error);
     }
   }
 };
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -306,27 +306,34 @@
 } // anonymous namespace
 
 // static
-VariantMatcher Registry::constructMatcher(StringRef MatcherName,
-                                          const SourceRange &NameRange,
-                                          ArrayRef<ParserValue> Args,
-                                          Diagnostics *Error) {
+MatcherCtor Registry::lookupMatcherCtor(StringRef MatcherName,
+                                        const SourceRange &NameRange,
+                                        Diagnostics *Error) {
   ConstructorMap::const_iterator it =
       RegistryData->constructors().find(MatcherName);
   if (it == RegistryData->constructors().end()) {
     Error->addError(NameRange, Error->ET_RegistryNotFound) << MatcherName;
-    return VariantMatcher();
+    return 0;
   }
 
-  return it->second->run(NameRange, Args, Error);
+  return it->second;
+}
+
+// static
+VariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
+                                          const SourceRange &NameRange,
+                                          ArrayRef<ParserValue> Args,
+                                          Diagnostics *Error) {
+  return Ctor->run(NameRange, Args, Error);
 }
 
 // static
-VariantMatcher Registry::constructBoundMatcher(StringRef MatcherName,
+VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
                                                const SourceRange &NameRange,
                                                StringRef BindID,
                                                ArrayRef<ParserValue> Args,
                                                Diagnostics *Error) {
-  VariantMatcher Out = constructMatcher(MatcherName, NameRange, Args, Error);
+  VariantMatcher Out = constructMatcher(Ctor, NameRange, Args, Error);
   if (Out.isNull()) return Out;
 
   llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
Index: unittests/ASTMatchers/Dynamic/ParserTest.cpp
===================================================================
--- unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -39,15 +39,24 @@
     Errors.push_back(Error.toStringFull());
   }
 
-  VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+  MatcherCtor lookupMatcherCtor(StringRef MatcherName,
+                                const SourceRange &NameRange,
+                                Diagnostics *Error) {
+    const ExpectedMatchersTy::value_type *Matcher =
+        &*ExpectedMatchers.find(MatcherName);
+    return reinterpret_cast<MatcherCtor>(Matcher);
+  }
+
+  VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                         const SourceRange &NameRange,
                                         StringRef BindID,
                                         ArrayRef<ParserValue> Args,
                                         Diagnostics *Error) {
-    MatcherInfo ToStore = { MatcherName, NameRange, Args, BindID };
+    const ExpectedMatchersTy::value_type *Matcher =
+        reinterpret_cast<const ExpectedMatchersTy::value_type *>(Ctor);
+    MatcherInfo ToStore = { Matcher->first, NameRange, Args, BindID };
     Matchers.push_back(ToStore);
-    return VariantMatcher::SingleMatcher(
-        ExpectedMatchers.find(MatcherName)->second);
+    return VariantMatcher::SingleMatcher(Matcher->second);
   }
 
   struct MatcherInfo {
@@ -60,8 +69,9 @@
   std::vector<std::string> Errors;
   std::vector<VariantValue> Values;
   std::vector<MatcherInfo> Matchers;
-  std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
-  ExpectedMatchers;
+  typedef std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
+  ExpectedMatchersTy;
+  ExpectedMatchersTy ExpectedMatchers;
 };
 
 TEST(ParserTest, ParseUnsigned) {
@@ -194,16 +204,19 @@
       "1:5: Error parsing matcher. Found token <123> while looking for '('.",
       ParseWithError("Foo 123"));
   EXPECT_EQ(
+      "1:1: Matcher not found: Foo\n"
       "1:9: Error parsing matcher. Found token <123> while looking for ','.",
       ParseWithError("Foo(\"A\" 123)"));
   EXPECT_EQ(
+      "1:1: Matcher not found: Foo\n"
       "1:4: Error parsing matcher. Found end-of-code while looking for ')'.",
       ParseWithError("Foo("));
   EXPECT_EQ("1:1: End of code found while looking for token.",
             ParseWithError(""));
   EXPECT_EQ("Input value is not a matcher expression.",
             ParseMatcherWithError("\"A\""));
-  EXPECT_EQ("1:1: Error parsing argument 1 for matcher Foo.\n"
+  EXPECT_EQ("1:1: Matcher not found: Foo\n"
+            "1:1: Error parsing argument 1 for matcher Foo.\n"
             "1:5: Invalid token <(> found when looking for a value.",
             ParseWithError("Foo(("));
   EXPECT_EQ("1:7: Expected end of code.", ParseWithError("expr()a"));
Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -36,12 +36,23 @@
     return Out;
   }
 
+  MatcherCtor lookupMatcherCtor(StringRef MatcherName, Diagnostics *Error = 0) {
+    Diagnostics DummyError;
+    if (!Error) Error = &DummyError;
+    MatcherCtor Ctor =
+        Registry::lookupMatcherCtor(MatcherName, SourceRange(), Error);
+    EXPECT_EQ("", DummyError.toStringFull());
+    return Ctor;
+  }
+
   VariantMatcher constructMatcher(StringRef MatcherName,
                                   Diagnostics *Error = NULL) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
-    const VariantMatcher Out =
-        Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error);
+    MatcherCtor Ctor = lookupMatcherCtor(MatcherName, Error);
+    VariantMatcher Out;
+    if (Ctor)
+      Out = Registry::constructMatcher(Ctor, SourceRange(), Args(), Error);
     EXPECT_EQ("", DummyError.toStringFull());
     return Out;
   }
@@ -51,8 +62,10 @@
                                   Diagnostics *Error = NULL) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
-    const VariantMatcher Out = Registry::constructMatcher(
-        MatcherName, SourceRange(), Args(Arg1), Error);
+    MatcherCtor Ctor = lookupMatcherCtor(MatcherName, Error);
+    VariantMatcher Out;
+    if (Ctor)
+      Out = Registry::constructMatcher(Ctor, SourceRange(), Args(Arg1), Error);
     EXPECT_EQ("", DummyError.toStringFull());
     return Out;
   }
@@ -63,8 +76,11 @@
                                   Diagnostics *Error = NULL) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
-    const VariantMatcher Out = Registry::constructMatcher(
-        MatcherName, SourceRange(), Args(Arg1, Arg2), Error);
+    MatcherCtor Ctor = lookupMatcherCtor(MatcherName, Error);
+    VariantMatcher Out;
+    if (Ctor)
+      Out = Registry::constructMatcher(Ctor, SourceRange(), Args(Arg1, Arg2),
+                                       Error);
     EXPECT_EQ("", DummyError.toStringFull());
     return Out;
   }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to