diff options
author | Samuel Benzaquen <sbenza@google.com> | 2013-06-04 15:46:22 +0000 |
---|---|---|
committer | Samuel Benzaquen <sbenza@google.com> | 2013-06-04 15:46:22 +0000 |
commit | c31b3524cb60481f1746c1faa1cb5eb31c04c0df (patch) | |
tree | 755b7a9a7d713ad9b08153249c263a94f4d1866f /clang/lib | |
parent | 16522c01dca90d70c5888d78eae3d4014e42e9d1 (diff) | |
download | bcm5719-llvm-c31b3524cb60481f1746c1faa1cb5eb31c04c0df.tar.gz bcm5719-llvm-c31b3524cb60481f1746c1faa1cb5eb31c04c0df.zip |
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
llvm-svn: 183231
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp | 2 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Marshallers.h | 43 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Parser.cpp | 35 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 175 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/VariantValue.cpp | 27 |
5 files changed, 264 insertions, 18 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp index 4b01b997a17..79c9389cf5f 100644 --- a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp @@ -62,6 +62,8 @@ StringRef ErrorTypeToString(Diagnostics::ErrorType Type) { 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>"; diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index a41ed249983..2cc5f7cdaa4 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -55,7 +55,13 @@ template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > { 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 Marshaller, FuncType Func, 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(ReturnType (*Func)(), StringRef MatcherName, } /// \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 *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), 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( diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp index 1ed40f3050f..eff50f4061c 100644 --- a/clang/lib/ASTMatchers/Dynamic/Parser.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp @@ -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 diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 6e543fc8504..5f6b35df696 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -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(StringRef MatcherName, /// \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); } diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp index e310fbfc58f..6fcbe7fc495 100644 --- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp +++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp @@ -22,20 +22,27 @@ VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) { *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; } |