r195534 - Split registry matcher resolution into a lookup phase and a construction phase.
Peter Collingbourne
peter at pcc.me.uk
Fri Nov 22 17:13:17 PST 2013
Author: pcc
Date: Fri Nov 22 19:13:16 2013
New Revision: 195534
URL: http://llvm.org/viewvc/llvm-project?rev=195534&view=rev
Log:
Split registry matcher resolution into a lookup phase and a construction phase.
The looked-up matchers will be used during code completion.
Differential Revision: http://llvm-reviews.chandlerc.com/D2207
Modified:
cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
cfe/trunk/include/clang/ASTMatchers/Dynamic/Registry.h
cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h?rev=195534&r1=195533&r2=195534&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h Fri Nov 22 19:13:16 2013
@@ -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 @@ public:
///
/// 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,25 @@ public:
/// \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 Optional<MatcherCtor>() if an error
+ /// occurred. In that case, \c Error will contain a description of the
+ /// error.
+ virtual llvm::Optional<MatcherCtor>
+ lookupMatcherCtor(StringRef MatcherName, const SourceRange &NameRange,
+ Diagnostics *Error) = 0;
};
/// \brief Parse a matcher expression, creating matchers from the registry.
Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/Registry.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Registry.h?rev=195534&r1=195533&r2=195534&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Registry.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Registry.h Fri Nov 22 19:13:16 2013
@@ -21,20 +21,33 @@
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
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 value which may be used to refer to the matcher
+ /// constructor, or Optional<MatcherCtor>() if not found. In that case
+ /// \c Error will contain the description of the error.
+ static llvm::Optional<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.
+ /// \param Ctor The matcher constructor to instantiate.
///
/// \param NameRange The location of the name in the matcher source.
/// Useful for error reporting.
@@ -44,10 +57,10 @@ public:
/// 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 +71,7 @@ public:
/// 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,
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp?rev=195534&r1=195533&r2=195534&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp Fri Nov 22 19:13:16 2013
@@ -18,6 +18,7 @@
#include "clang/ASTMatchers/Dynamic/Parser.h"
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "clang/Basic/CharInfo.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Twine.h"
namespace clang {
@@ -242,6 +243,9 @@ bool Parser::parseMatcherExpressionImpl(
return false;
}
+ llvm::Optional<MatcherCtor> Ctor =
+ S->lookupMatcherCtor(NameToken.Text, NameToken.Range, Error);
+
std::vector<ParserValue> Args;
TokenInfo EndToken;
while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
@@ -306,13 +310,16 @@ bool Parser::parseMatcherExpressionImpl(
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 +365,21 @@ Parser::Parser(CodeTokenizer *Tokenizer,
class RegistrySema : public Parser::Sema {
public:
virtual ~RegistrySema() {}
- VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+ llvm::Optional<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);
}
}
};
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=195534&r1=195533&r2=195534&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Fri Nov 22 19:13:16 2013
@@ -306,27 +306,34 @@ static llvm::ManagedStatic<RegistryMaps>
} // anonymous namespace
// static
-VariantMatcher Registry::constructMatcher(StringRef MatcherName,
- const SourceRange &NameRange,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error) {
+llvm::Optional<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 llvm::Optional<MatcherCtor>();
}
- 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();
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=195534&r1=195533&r2=195534&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Fri Nov 22 19:13:16 2013
@@ -14,6 +14,7 @@
#include "clang/ASTMatchers/Dynamic/Parser.h"
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "gtest/gtest.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
namespace clang {
@@ -39,15 +40,24 @@ public:
Errors.push_back(Error.toStringFull());
}
- VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+ llvm::Optional<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 +70,9 @@ public:
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 +205,19 @@ TEST(ParserTest, Errors) {
"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"));
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=195534&r1=195533&r2=195534&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Fri Nov 22 19:13:16 2013
@@ -36,12 +36,24 @@ public:
return Out;
}
+ llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName,
+ Diagnostics *Error = 0) {
+ Diagnostics DummyError;
+ if (!Error) Error = &DummyError;
+ llvm::Optional<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);
+ llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
+ VariantMatcher Out;
+ if (Ctor)
+ Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(), Error);
EXPECT_EQ("", DummyError.toStringFull());
return Out;
}
@@ -51,8 +63,10 @@ public:
Diagnostics *Error = NULL) {
Diagnostics DummyError;
if (!Error) Error = &DummyError;
- const VariantMatcher Out = Registry::constructMatcher(
- MatcherName, SourceRange(), Args(Arg1), Error);
+ llvm::Optional<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 +77,11 @@ public:
Diagnostics *Error = NULL) {
Diagnostics DummyError;
if (!Error) Error = &DummyError;
- const VariantMatcher Out = Registry::constructMatcher(
- MatcherName, SourceRange(), Args(Arg1, Arg2), Error);
+ llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
+ VariantMatcher Out;
+ if (Ctor)
+ Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1, Arg2),
+ Error);
EXPECT_EQ("", DummyError.toStringFull());
return Out;
}
More information about the cfe-commits
mailing list