r183231 - Parser/Registry argument enhancements.

Samuel Benzaquen sbenza at google.com
Tue Jun 4 08:46:23 PDT 2013


Author: sbenza
Date: Tue Jun  4 10:46:22 2013
New Revision: 183231

URL: http://llvm.org/viewvc/llvm-project?rev=183231&view=rev
Log:
Parser/Registry argument enhancements.

Summary:
 Parser/Registry argument enhancements.
  - 2 argument support.
  - unsigned values support.

Reviewers: klimek

CC: cfe-commits, revane

Differential Revision: http://llvm-reviews.chandlerc.com/D915

Modified:
    cfe/trunk/include/clang/ASTMatchers/Dynamic/Diagnostics.h
    cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
    cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h
    cfe/trunk/lib/ASTMatchers/Dynamic/Diagnostics.cpp
    cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
    cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
    cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
    cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
    cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
    cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
    cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp

Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/Diagnostics.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Diagnostics.h?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Diagnostics.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Diagnostics.h Tue Jun  4 10:46:22 2013
@@ -69,7 +69,8 @@ class Diagnostics {
     ET_ParserNotAMatcher = 107,
     ET_ParserInvalidToken = 108,
     ET_ParserMalformedBindExpr = 109,
-    ET_ParserTrailingCode = 110
+    ET_ParserTrailingCode = 110,
+    ET_ParserUnsignedError = 111
   };
 
   /// \brief Helper stream class.

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=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h Tue Jun  4 10:46:22 2013
@@ -18,8 +18,10 @@
 ///
 /// \code
 /// Grammar for the expressions supported:
-/// <Expression>        := <StringLiteral> | <MatcherExpression>
+/// <Expression>        := <Literal> | <MatcherExpression>
+/// <Literal>           := <StringLiteral> | <Unsigned>
 /// <StringLiteral>     := "quoted string"
+/// <Unsigned>          := [0-9]+
 /// <MatcherExpression> := <MatcherName>(<ArgumentList>) |
 ///                        <MatcherName>(<ArgumentList>).bind(<StringLiteral>)
 /// <MatcherName>       := [a-zA-Z]+

Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h Tue Jun  4 10:46:22 2013
@@ -37,6 +37,7 @@ using ast_matchers::internal::DynTypedMa
 /// copy/assignment.
 ///
 /// Supported types:
+///  - \c unsigned
 ///  - \c std::string
 ///  - \c DynTypedMatcher, and any \c Matcher<T>
 class VariantValue {
@@ -48,9 +49,15 @@ public:
   VariantValue &operator=(const VariantValue &Other);
 
   /// \brief Specific constructors for each supported type.
+  VariantValue(unsigned Unsigned);
   VariantValue(const std::string &String);
   VariantValue(const DynTypedMatcher &Matcher);
 
+  /// \brief Unsigned value functions.
+  bool isUnsigned() const;
+  unsigned getUnsigned() const;
+  void setUnsigned(unsigned Unsigned);
+
   /// \brief String value functions.
   bool isString() const;
   const std::string &getString() const;
@@ -104,12 +111,14 @@ private:
   /// \brief All supported value types.
   enum ValueType {
     VT_Nothing,
+    VT_Unsigned,
     VT_String,
     VT_Matcher
   };
 
   /// \brief All supported value types.
   union AllValues {
+    unsigned Unsigned;
     std::string *String;
     DynTypedMatcher *Matcher;
   };

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Diagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Diagnostics.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Diagnostics.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Diagnostics.cpp Tue Jun  4 10:46:22 2013
@@ -62,6 +62,8 @@ StringRef ErrorTypeToString(Diagnostics:
     return "Malformed bind() expression.";
   case Diagnostics::ET_ParserTrailingCode:
     return "Expected end of code.";
+  case Diagnostics::ET_ParserUnsignedError:
+    return "Error parsing unsigned token: <$0>";
 
   case Diagnostics::ET_None:
     return "<N/A>";

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Tue Jun  4 10:46:22 2013
@@ -55,7 +55,13 @@ template <class T> struct ArgTypeTraits<
   static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
     return Value.getTypedMatcher<T>();
   }
+};
 
+template <> struct ArgTypeTraits<unsigned> {
+  static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
+  static unsigned get(const VariantValue &Value) {
+    return Value.getUnsigned();
+  }
 };
 
 /// \brief Generic MatcherCreate interface.
@@ -116,15 +122,6 @@ createMarshallerCallback(MarshallerType
     return NULL;                                                               \
   }
 
-/// \brief Metafunction to normalize argument types.
-///
-/// We need to remove the const& out of the function parameters to be able to
-/// find values on VariantValue.
-template <typename T>
-struct remove_const_ref :
-    public llvm::remove_const<typename llvm::remove_reference<T>::type> {
-};
-
 /// \brief 0-arg marshaller function.
 template <typename ReturnType>
 DynTypedMatcher *matcherMarshall0(ReturnType (*Func)(), StringRef MatcherName,
@@ -136,18 +133,31 @@ DynTypedMatcher *matcherMarshall0(Return
 }
 
 /// \brief 1-arg marshaller function.
-template <typename ReturnType, typename InArgType1>
-DynTypedMatcher *matcherMarshall1(ReturnType (*Func)(InArgType1),
+template <typename ReturnType, typename ArgType1>
+DynTypedMatcher *matcherMarshall1(ReturnType (*Func)(ArgType1),
                                   StringRef MatcherName,
                                   const SourceRange &NameRange,
                                   ArrayRef<ParserValue> Args,
                                   Diagnostics *Error) {
-  typedef typename remove_const_ref<InArgType1>::type ArgType1;
   CHECK_ARG_COUNT(1);
   CHECK_ARG_TYPE(0, ArgType1);
   return Func(ArgTypeTraits<ArgType1>::get(Args[0].Value)).clone();
 }
 
+/// \brief 2-arg marshaller function.
+template <typename ReturnType, typename ArgType1, typename ArgType2>
+DynTypedMatcher *matcherMarshall2(ReturnType (*Func)(ArgType1, ArgType2),
+                                  StringRef MatcherName,
+                                  const SourceRange &NameRange,
+                                  ArrayRef<ParserValue> Args,
+                                  Diagnostics *Error) {
+  CHECK_ARG_COUNT(2);
+  CHECK_ARG_TYPE(0, ArgType1);
+  CHECK_ARG_TYPE(1, ArgType2);
+  return Func(ArgTypeTraits<ArgType1>::get(Args[0].Value),
+              ArgTypeTraits<ArgType2>::get(Args[1].Value)).clone();
+}
+
 /// \brief Variadic marshaller function.
 template <typename BaseType, typename DerivedType>
 class VariadicMatcherCreateCallback : public MatcherCreateCallback {
@@ -197,6 +207,15 @@ MatcherCreateCallback *makeMatcherAutoMa
                                   MatcherName);
 }
 
+/// \brief 2-arg overload
+template <typename ReturnType, typename ArgType1, typename ArgType2>
+MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
+                                                                  ArgType2),
+                                               StringRef MatcherName) {
+  return createMarshallerCallback(
+      matcherMarshall2<ReturnType, ArgType1, ArgType2>, Func, MatcherName);
+}
+
 /// \brief Variadic overload.
 template <typename MatcherType>
 MatcherCreateCallback *makeMatcherAutoMarshall(

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp Tue Jun  4 10:46:22 2013
@@ -112,6 +112,12 @@ private:
       consumeStringLiteral(&Result);
       break;
 
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      // Parse an unsigned literal.
+      consumeUnsignedLiteral(&Result);
+      break;
+
     default:
       if (isAlphanumeric(Code[0])) {
         // Parse an identifier
@@ -133,6 +139,35 @@ private:
     return Result;
   }
 
+  /// \brief Consume an unsigned literal.
+  void consumeUnsignedLiteral(TokenInfo *Result) {
+    unsigned Length = 1;
+    if (Code.size() > 1) {
+      // Consume the 'x' or 'b' radix modifier, if present.
+      switch (toLowercase(Code[1])) {
+      case 'x': case 'b': Length = 2;
+      }
+    }
+    while (Length < Code.size() && isHexDigit(Code[Length]))
+      ++Length;
+
+    Result->Text = Code.substr(0, Length);
+    Code = Code.drop_front(Length);
+
+    unsigned Value;
+    if (!Result->Text.getAsInteger(0, Value)) {
+      Result->Kind = TokenInfo::TK_Literal;
+      Result->Value = Value;
+    } else {
+      SourceRange Range;
+      Range.Start = Result->Range.Start;
+      Range.End = currentLocation();
+      Error->pushErrorFrame(Range, Error->ET_ParserUnsignedError)
+          << Result->Text;
+      Result->Kind = TokenInfo::TK_Error;
+    }
+  }
+
   /// \brief Consume a string literal.
   ///
   /// \c Code must be positioned at the start of the literal (the opening

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Tue Jun  4 10:46:22 2013
@@ -44,6 +44,7 @@ private:
 
 void RegistryMaps::registerMatcher(StringRef MatcherName,
                                    MatcherCreateCallback *Callback) {
+  assert(Constructors.find(MatcherName) == Constructors.end());
   Constructors[MatcherName] = Callback;
 }
 
@@ -53,70 +54,236 @@ void RegistryMaps::registerMatcher(Strin
 
 /// \brief Generate a registry map with all the known matchers.
 RegistryMaps::RegistryMaps() {
-  // TODO: This list is not complete. It only has non-overloaded matchers,
-  // which are the simplest to add to the system. Overloaded matchers require
-  // more supporting code that was omitted from the first revision for
-  // simplicitly of code review.
+  // TODO: Here is the list of the missing matchers, grouped by reason.
+  //
+  // Need DynTypedNode fixes:
+  // hasAnyTemplateArgument
+  // hasTemplateArgument
+  //
+  // Need Variant/Parser fixes:
+  // ofKind
+  //
+  // CXXCtorInitializer support:
+  // hasAnyConstructorInitializer
+  // forField
+  // withInitializer
+  // isWritten
+  // isImplicit
+  //
+  // Type traversal:
+  // hasElementType
+  // hasValueType
+  // hasDeducedType
+  // innerType
+  // pointee
+  //
+  // Function overloaded by args:
+  // hasType
+  // callee
+  // hasPrefix
+  // isDerivedFrom
+  // isSameOrDerivedFrom
+  // pointsTo
+  // references
+  // thisPointerType
+  //
+  // Polymorphic matchers:
+  // anything
+  // hasAnyArgument
+  // isTemplateInstantiation
+  // isExplicitTemplateSpecialization
+  // isDefinition
+  // hasOperatorName
+  // hasOverloadedOperatorName
+  // hasCondition
+  // hasBody
+  // argumentCountIs
+  // hasArgument
+  //
+  // Polymorphic + argument overload:
+  // unless
+  // eachOf
+  // anyOf
+  // allOf
+  // findAll
+  //
+  // Adaptative matcher (similar to polymorphic matcher):
+  // has
+  // forEach
+  // forEachDescendant
+  // hasDescendant
+  // hasParent
+  // hasAncestor
+  //
+  // Other:
+  // loc
+  // equals
+  // equalsNode
+  // hasDeclaration
 
+  REGISTER_MATCHER(accessSpecDecl);
+  REGISTER_MATCHER(alignOfExpr);
+  REGISTER_MATCHER(arraySubscriptExpr);
+  REGISTER_MATCHER(arrayType);
+  REGISTER_MATCHER(asString);
+  REGISTER_MATCHER(asmStmt);
+  REGISTER_MATCHER(atomicType);
+  REGISTER_MATCHER(autoType);
   REGISTER_MATCHER(binaryOperator);
   REGISTER_MATCHER(bindTemporaryExpr);
+  REGISTER_MATCHER(blockPointerType);
   REGISTER_MATCHER(boolLiteral);
+  REGISTER_MATCHER(breakStmt);
+  REGISTER_MATCHER(builtinType);
+  REGISTER_MATCHER(cStyleCastExpr);
   REGISTER_MATCHER(callExpr);
+  REGISTER_MATCHER(castExpr);
+  REGISTER_MATCHER(catchStmt);
   REGISTER_MATCHER(characterLiteral);
+  REGISTER_MATCHER(classTemplateDecl);
+  REGISTER_MATCHER(classTemplateSpecializationDecl);
+  REGISTER_MATCHER(complexType);
+  REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constCastExpr);
+  REGISTER_MATCHER(constantArrayType);
   REGISTER_MATCHER(constructExpr);
   REGISTER_MATCHER(constructorDecl);
+  REGISTER_MATCHER(containsDeclaration);
+  REGISTER_MATCHER(continueStmt);
+  REGISTER_MATCHER(decl);
+  REGISTER_MATCHER(declCountIs);
   REGISTER_MATCHER(declRefExpr);
   REGISTER_MATCHER(declStmt);
   REGISTER_MATCHER(defaultArgExpr);
+  REGISTER_MATCHER(deleteExpr);
+  REGISTER_MATCHER(dependentSizedArrayType);
+  REGISTER_MATCHER(destructorDecl);
   REGISTER_MATCHER(doStmt);
   REGISTER_MATCHER(dynamicCastExpr);
+  REGISTER_MATCHER(elaboratedType);
+  REGISTER_MATCHER(enumConstantDecl);
+  REGISTER_MATCHER(enumDecl);
   REGISTER_MATCHER(explicitCastExpr);
   REGISTER_MATCHER(expr);
   REGISTER_MATCHER(fieldDecl);
+  REGISTER_MATCHER(forRangeStmt);
   REGISTER_MATCHER(forStmt);
   REGISTER_MATCHER(functionDecl);
+  REGISTER_MATCHER(functionTemplateDecl);
+  REGISTER_MATCHER(functionType);
+  REGISTER_MATCHER(functionalCastExpr);
+  REGISTER_MATCHER(gotoStmt);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnySubstatement);
+  REGISTER_MATCHER(hasAnyUsingShadowDecl);
+  REGISTER_MATCHER(hasArgumentOfType);
+  REGISTER_MATCHER(hasBase);
+  REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDestinationType);
   REGISTER_MATCHER(hasEitherOperand);
   REGISTER_MATCHER(hasFalseExpression);
   REGISTER_MATCHER(hasImplicitDestinationType);
+  REGISTER_MATCHER(hasIncrement);
+  REGISTER_MATCHER(hasIndex);
   REGISTER_MATCHER(hasInitializer);
   REGISTER_MATCHER(hasLHS);
+  REGISTER_MATCHER(hasLocalQualifiers);
+  REGISTER_MATCHER(hasLoopInit);
+  REGISTER_MATCHER(hasMethod);
   REGISTER_MATCHER(hasName);
   REGISTER_MATCHER(hasObjectExpression);
+  REGISTER_MATCHER(hasParameter);
+  REGISTER_MATCHER(hasQualifier);
   REGISTER_MATCHER(hasRHS);
+  REGISTER_MATCHER(hasSingleDecl);
+  REGISTER_MATCHER(hasSize);
+  REGISTER_MATCHER(hasSizeExpr);
   REGISTER_MATCHER(hasSourceExpression);
+  REGISTER_MATCHER(hasTargetDecl);
   REGISTER_MATCHER(hasTrueExpression);
   REGISTER_MATCHER(hasUnaryOperand);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringImpCasts);
+  REGISTER_MATCHER(ignoringParenCasts);
+  REGISTER_MATCHER(ignoringParenImpCasts);
   REGISTER_MATCHER(implicitCastExpr);
+  REGISTER_MATCHER(incompleteArrayType);
+  REGISTER_MATCHER(initListExpr);
   REGISTER_MATCHER(integerLiteral);
   REGISTER_MATCHER(isArrow);
   REGISTER_MATCHER(isConstQualified);
+  REGISTER_MATCHER(isExternC);
   REGISTER_MATCHER(isImplicit);
+  REGISTER_MATCHER(isInteger);
+  REGISTER_MATCHER(isOverride);
+  REGISTER_MATCHER(isPrivate);
+  REGISTER_MATCHER(isProtected);
+  REGISTER_MATCHER(isPublic);
+  REGISTER_MATCHER(isVirtual);
+  REGISTER_MATCHER(lValueReferenceType);
+  REGISTER_MATCHER(labelStmt);
+  REGISTER_MATCHER(lambdaExpr);
+  REGISTER_MATCHER(matchesName);
+  REGISTER_MATCHER(materializeTemporaryExpr);
   REGISTER_MATCHER(member);
+  REGISTER_MATCHER(memberCallExpr);
   REGISTER_MATCHER(memberExpr);
+  REGISTER_MATCHER(memberPointerType);
   REGISTER_MATCHER(methodDecl);
   REGISTER_MATCHER(namedDecl);
+  REGISTER_MATCHER(namesType);
+  REGISTER_MATCHER(namespaceDecl);
+  REGISTER_MATCHER(nestedNameSpecifier);
+  REGISTER_MATCHER(nestedNameSpecifierLoc);
   REGISTER_MATCHER(newExpr);
+  REGISTER_MATCHER(nullPtrLiteralExpr);
+  REGISTER_MATCHER(nullStmt);
   REGISTER_MATCHER(ofClass);
   REGISTER_MATCHER(on);
   REGISTER_MATCHER(onImplicitObjectArgument);
   REGISTER_MATCHER(operatorCallExpr);
+  REGISTER_MATCHER(parameterCountIs);
+  REGISTER_MATCHER(parenType);
+  REGISTER_MATCHER(pointerType);
+  REGISTER_MATCHER(qualType);
+  REGISTER_MATCHER(rValueReferenceType);
   REGISTER_MATCHER(recordDecl);
+  REGISTER_MATCHER(recordType);
+  REGISTER_MATCHER(referenceType);
+  REGISTER_MATCHER(refersToDeclaration);
+  REGISTER_MATCHER(refersToType);
   REGISTER_MATCHER(reinterpretCastExpr);
+  REGISTER_MATCHER(returnStmt);
+  REGISTER_MATCHER(returns);
+  REGISTER_MATCHER(sizeOfExpr);
+  REGISTER_MATCHER(specifiesNamespace);
+  REGISTER_MATCHER(specifiesType);
+  REGISTER_MATCHER(specifiesTypeLoc);
+  REGISTER_MATCHER(statementCountIs);
   REGISTER_MATCHER(staticCastExpr);
   REGISTER_MATCHER(stmt);
   REGISTER_MATCHER(stringLiteral);
   REGISTER_MATCHER(switchCase);
+  REGISTER_MATCHER(switchStmt);
+  REGISTER_MATCHER(templateSpecializationType);
+  REGISTER_MATCHER(thisExpr);
+  REGISTER_MATCHER(throughUsingDecl);
+  REGISTER_MATCHER(throwExpr);
   REGISTER_MATCHER(to);
+  REGISTER_MATCHER(tryStmt);
+  REGISTER_MATCHER(type);
+  REGISTER_MATCHER(typeLoc);
+  REGISTER_MATCHER(typedefType);
+  REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
   REGISTER_MATCHER(unaryOperator);
+  REGISTER_MATCHER(userDefinedLiteral);
+  REGISTER_MATCHER(usingDecl);
   REGISTER_MATCHER(varDecl);
+  REGISTER_MATCHER(variableArrayType);
   REGISTER_MATCHER(whileStmt);
 }
 

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp Tue Jun  4 10:46:22 2013
@@ -22,20 +22,27 @@ VariantValue::VariantValue(const Variant
   *this = Other;
 }
 
-VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
-  setMatcher(Matcher);
+VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
+  setUnsigned(Unsigned);
 }
 
 VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
   setString(String);
 }
 
+VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
+  setMatcher(Matcher);
+}
+
 VariantValue::~VariantValue() { reset(); }
 
 VariantValue &VariantValue::operator=(const VariantValue &Other) {
   if (this == &Other) return *this;
   reset();
   switch (Other.Type) {
+  case VT_Unsigned:
+    setUnsigned(Other.getUnsigned());
+    break;
   case VT_String:
     setString(Other.getString());
     break;
@@ -58,12 +65,28 @@ void VariantValue::reset() {
     delete Value.Matcher;
     break;
   // Cases that do nothing.
+  case VT_Unsigned:
   case VT_Nothing:
     break;
   }
   Type = VT_Nothing;
 }
 
+bool VariantValue::isUnsigned() const {
+  return Type == VT_Unsigned;
+}
+
+unsigned VariantValue::getUnsigned() const {
+  assert(isUnsigned());
+  return Value.Unsigned;
+}
+
+void VariantValue::setUnsigned(unsigned NewValue) {
+  reset();
+  Type = VT_Unsigned;
+  Value.Unsigned = NewValue;
+}
+
 bool VariantValue::isString() const {
   return Type == VT_String;
 }

Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Tue Jun  4 10:46:22 2013
@@ -96,6 +96,21 @@ public:
   llvm::StringMap<uint64_t> ExpectedMatchers;
 };
 
+TEST(ParserTest, ParseUnsigned) {
+  MockSema Sema;
+  Sema.parse("0");
+  Sema.parse("123");
+  Sema.parse("0x1f");
+  Sema.parse("12345678901");
+  Sema.parse("1a1");
+  EXPECT_EQ(5U, Sema.Values.size());
+  EXPECT_EQ(0U, Sema.Values[0].getUnsigned());
+  EXPECT_EQ(123U, Sema.Values[1].getUnsigned());
+  EXPECT_EQ(31U, Sema.Values[2].getUnsigned());
+  EXPECT_EQ("1:1: Error parsing unsigned token: <12345678901>", Sema.Errors[3]);
+  EXPECT_EQ("1:1: Error parsing unsigned token: <1a1>", Sema.Errors[4]);
+}
+
 TEST(ParserTest, ParseString) {
   MockSema Sema;
   Sema.parse("\"Foo\"");
@@ -122,7 +137,7 @@ TEST(ParserTest, ParseMatcher) {
   const uint64_t ExpectedFoo = Sema.expectMatcher("Foo");
   const uint64_t ExpectedBar = Sema.expectMatcher("Bar");
   const uint64_t ExpectedBaz = Sema.expectMatcher("Baz");
-  Sema.parse(" Foo ( Bar (), Baz( \n \"B A,Z\") ) .bind( \"Yo!\") ");
+  Sema.parse(" Foo ( Bar ( 17), Baz( \n \"B A,Z\") ) .bind( \"Yo!\") ");
   for (size_t i = 0, e = Sema.Errors.size(); i != e; ++i) {
     EXPECT_EQ("", Sema.Errors[i]);
   }
@@ -135,12 +150,13 @@ TEST(ParserTest, ParseMatcher) {
   EXPECT_EQ(3ULL, Sema.Matchers.size());
   const MockSema::MatcherInfo Bar = Sema.Matchers[0];
   EXPECT_EQ("Bar", Bar.MatcherName);
-  EXPECT_TRUE(matchesRange(Bar.NameRange, 1, 1, 8, 14));
-  EXPECT_EQ(0ULL, Bar.Args.size());
+  EXPECT_TRUE(matchesRange(Bar.NameRange, 1, 1, 8, 17));
+  EXPECT_EQ(1ULL, Bar.Args.size());
+  EXPECT_EQ(17U, Bar.Args[0].Value.getUnsigned());
 
   const MockSema::MatcherInfo Baz = Sema.Matchers[1];
   EXPECT_EQ("Baz", Baz.MatcherName);
-  EXPECT_TRUE(matchesRange(Baz.NameRange, 1, 2, 16, 10));
+  EXPECT_TRUE(matchesRange(Baz.NameRange, 1, 2, 19, 10));
   EXPECT_EQ(1ULL, Baz.Args.size());
   EXPECT_EQ("B A,Z", Baz.Args[0].Value.getString());
 
@@ -161,6 +177,11 @@ TEST(ParserTest, FullParserTest) {
   EXPECT_TRUE(matchesDynamic("int x = 1 + false;", *Matcher));
   EXPECT_FALSE(matchesDynamic("int x = true + 1;", *Matcher));
 
+  Matcher.reset(
+      Parser::parseMatcherExpression("hasParameter(1, hasName(\"x\"))", NULL));
+  EXPECT_TRUE(matchesDynamic("void f(int a, int x);", *Matcher));
+  EXPECT_FALSE(matchesDynamic("void f(int x, int a);", *Matcher));
+
   Diagnostics Error;
   EXPECT_TRUE(Parser::parseMatcherExpression(
       "hasInitializer(\n    binaryOperator(hasLHS(\"A\")))", &Error) == NULL);

Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Tue Jun  4 10:46:22 2013
@@ -63,6 +63,10 @@ TEST(RegistryTest, ConstructWithSimpleAr
       constructMatcher("hasName", std::string("X"), NULL));
   EXPECT_TRUE(matchesDynamic("class X {};", *Value));
   EXPECT_FALSE(matchesDynamic("int x;", *Value));
+
+  Value.reset(constructMatcher("parameterCountIs", 2, NULL));
+  EXPECT_TRUE(matchesDynamic("void foo(int,int);", *Value));
+  EXPECT_FALSE(matchesDynamic("void foo(int);", *Value));
 }
 
 TEST(RegistryTest, ConstructWithMatcherArgs) {
@@ -82,6 +86,11 @@ TEST(RegistryTest, ConstructWithMatcherA
   code = "int y(); int i = y();";
   EXPECT_TRUE(matchesDynamic(code, *HasInitializerSimple));
   EXPECT_TRUE(matchesDynamic(code, *HasInitializerComplex));
+
+  OwningPtr<DynTypedMatcher> HasParameter(
+      constructMatcher("hasParameter", 1, hasName("x"), NULL));
+  EXPECT_TRUE(matchesDynamic("void f(int a, int x);", *HasParameter));
+  EXPECT_FALSE(matchesDynamic("void f(int x, int a);", *HasParameter));
 }
 
 TEST(RegistryTest, Errors) {

Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp?rev=183231&r1=183230&r2=183231&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp Tue Jun  4 10:46:22 2013
@@ -19,6 +19,19 @@ namespace {
 using ast_matchers::internal::DynTypedMatcher;
 using ast_matchers::internal::Matcher;
 
+TEST(VariantValueTest, Unsigned) {
+  const unsigned kUnsigned = 17;
+  VariantValue Value = kUnsigned;
+
+  EXPECT_TRUE(Value.isUnsigned());
+  EXPECT_EQ(kUnsigned, Value.getUnsigned());
+
+  EXPECT_FALSE(Value.isString());
+  EXPECT_FALSE(Value.isMatcher());
+  EXPECT_FALSE(Value.isTypedMatcher<clang::Decl>());
+  EXPECT_FALSE(Value.isTypedMatcher<clang::UnaryOperator>());
+}
+
 TEST(VariantValueTest, String) {
   const ::std::string kString = "string";
   VariantValue Value = kString;
@@ -26,6 +39,7 @@ TEST(VariantValueTest, String) {
   EXPECT_TRUE(Value.isString());
   EXPECT_EQ(kString, Value.getString());
 
+  EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isMatcher());
   EXPECT_FALSE(Value.isTypedMatcher<clang::Decl>());
   EXPECT_FALSE(Value.isTypedMatcher<clang::UnaryOperator>());
@@ -34,6 +48,7 @@ TEST(VariantValueTest, String) {
 TEST(VariantValueTest, DynTypedMatcher) {
   VariantValue Value = stmt();
 
+  EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
 
   EXPECT_TRUE(Value.isMatcher());
@@ -59,15 +74,24 @@ TEST(VariantValueTest, Assignment) {
   VariantValue Value = std::string("A");
   EXPECT_TRUE(Value.isString());
   EXPECT_EQ("A", Value.getString());
+  EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isMatcher());
 
   Value = recordDecl();
+  EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
   EXPECT_TRUE(Value.isMatcher());
   EXPECT_TRUE(Value.isTypedMatcher<clang::Decl>());
   EXPECT_TRUE(Value.isTypedMatcher<clang::UnaryOperator>());
 
+  Value = 17;
+  EXPECT_TRUE(Value.isUnsigned());
+  EXPECT_EQ(17U, Value.getUnsigned());
+  EXPECT_FALSE(Value.isMatcher());
+  EXPECT_FALSE(Value.isString());
+
   Value = VariantValue();
+  EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
   EXPECT_FALSE(Value.isMatcher());
 }





More information about the cfe-commits mailing list