[PATCH] First revision of the dynamic ASTMatcher library

Samuel Benzaquen sbenza at google.com
Fri May 3 11:06:53 PDT 2013


  The way it works is like this:
  In Marshallers.h I use template argument deduction to determine the signature of the function I am wrapping. Using the deduced arguments, the marshaller function calls is<ArgType>() and get<ArgType>() to verify the arguments and call the wrapped function.
  Somewhere there needs to be some dispatch magic that can take the deduced types and verify/get the right stuff from VariantValue. I put this magic in VariantValue itself.
  The other thing I could do is to have simple methods in VariantValue like isString()/getString()/isDynMatcher()/getDynMatcher(), etc. and do the overload magic inside of Marshallers.h.
  I am ok either way.
  Please consider that I will be adding bool and numbers to VariantValue, so making the change now rather than later would be best.


================
Comment at: lib/ASTMatchers/Dynamic/Diagnostics.cpp:34-35
@@ +33,4 @@
+  switch (Type) {
+    case Diagnostics::ET_REGISTRY_NOT_FOUND:
+      return "Matcher not found: $0";
+    case Diagnostics::ET_REGISTRY_WRONG_ARG_COUNT:
----------------
Dmitri Gribenko wrote:
> According to style guide, 'case' is not indented inside a switch().
Fixed.
I am fighting vi here... it is configured for another style.

================
Comment at: lib/ASTMatchers/Dynamic/Diagnostics.cpp:61-62
@@ +60,4 @@
+    case Diagnostics::ET_NONE:
+    default:
+      return "<N/A>";
+  }
----------------
Dmitri Gribenko wrote:
> 'default' is discouraged in a fully-covered switch.  You'll need to add llvm_unreachable() after the switch to silence a warning from gcc.
Thanks for the tip. I only added the default: to get rid of the warning!

================
Comment at: lib/ASTMatchers/Dynamic/Parser.cpp:45
@@ +44,3 @@
+  TokenKind Kind;
+  SourceRange Location;
+};
----------------
Dmitri Gribenko wrote:
> IMHO, 'Range' would be a better name than 'Location'.
Done.

================
Comment at: lib/ASTMatchers/Dynamic/Parser.cpp:67
@@ +66,3 @@
+      Result.Text = "";
+    } else if (isSingleCharToken(Code[0], &Result.Kind)) {
+      Result.Text = Code.substr(0, 1);
----------------
Dmitri Gribenko wrote:
> It would be better to inline the switch() from isSingleCharToken() here and turn the whole if-else chain into a switch().  This is idiomatic for lexers.
Done.

================
Comment at: lib/ASTMatchers/Dynamic/Parser.cpp:88-89
@@ +87,4 @@
+
+    Result.Location.End.Line = Line;
+    Result.Location.End.Column = column() - 1;
+    return Result;
----------------
Manuel Klimek wrote:
> Dmitri Gribenko wrote:
> > This makes 'End' inclusive.  In my opinion, this is not intuitive and not consistent with STL-like half-open ranges.
> > 
> > If you decide to make 'End' non-inclusive, you can also factor out a function to get a 'current' location (this piece of code is repeated twice in getNextToken()).
> IIRC source ranges have an inclusive end in clang (they usually point at the beginning of the last token of a range).
Done.

================
Comment at: lib/ASTMatchers/Dynamic/Parser.cpp:93-94
@@ +92,4 @@
+
+  /// \brief Returns \c true when the whole input has been consumed.
+  bool isDone() const { return Code.empty(); }
+
----------------
Dmitri Gribenko wrote:
> This should not be needed after switching to an EOF token.
Removed.

================
Comment at: lib/ASTMatchers/Dynamic/Parser.cpp:270
@@ +269,3 @@
+    case TokenInfo::TK_COMMA:
+    default:
+      Error->pushErrorFrame(Token.Location, Error->ET_PARSER_INVALID_TOKEN)
----------------
Dmitri Gribenko wrote:
> 'default' is discouraged in a fully-covered switch.
> 
Fixed.

================
Comment at: lib/ASTMatchers/Dynamic/Parser.cpp:242
@@ +241,3 @@
+/// parse function.
+bool parseToken(const TokenInfo &Token, CodeTokenizer *Tokenizer,
+                Parser::TokenProcessor *Processor, VariantValue *Value,
----------------
Dmitri Gribenko wrote:
> Why doesn't lexer do this?  Every token could have an associated value (optional, of course).
It could do the rest of the parsing, except for the matchers. I would have to pass more state to it, though.

================
Comment at: include/clang/ASTMatchers/Dynamic/Parser.h:42-43
@@ +41,4 @@
+
+/// \brief Matcher expression parser.
+class Parser {
+public:
----------------
Dmitri Gribenko wrote:
> Samuel Benzaquen wrote:
> > Dmitri Gribenko wrote:
> > > This class just holds a few static member functions.  Is the class really needed here?
> > It is not really needed. I could take out the class / rename as namespace.
> > The same applies to Registry, I guess.
> Or you could take advantage of 'Parser' being a real class: if it is appropriate, you could move 'TokenProcessor' and 'Diagnostics' to be class members.
Done.


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

BRANCH
  svn

ARCANIST PROJECT
  clang



More information about the cfe-commits mailing list