summaryrefslogtreecommitdiffstats
path: root/lib/ASTMatchers/Dynamic
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ASTMatchers/Dynamic')
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h105
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp105
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp171
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp164
4 files changed, 344 insertions, 201 deletions
diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h
index 6e144cd..b78bc03 100644
--- a/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -17,8 +17,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
-#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
+#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
+#define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
@@ -30,48 +30,8 @@
namespace clang {
namespace ast_matchers {
namespace dynamic {
-
namespace internal {
-struct ArgKind {
- enum Kind {
- AK_Matcher,
- AK_Unsigned,
- AK_String
- };
- ArgKind(Kind K)
- : K(K) {}
- ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
- : K(AK_Matcher), MatcherKind(MatcherKind) {}
-
- std::string asString() const {
- switch (getArgKind()) {
- case AK_Matcher:
- return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str();
- case AK_Unsigned:
- return "unsigned";
- case AK_String:
- return "string";
- }
- llvm_unreachable("unhandled ArgKind");
- }
-
- Kind getArgKind() const { return K; }
- ast_type_traits::ASTNodeKind getMatcherKind() const {
- assert(K == AK_Matcher);
- return MatcherKind;
- }
-
- bool operator<(const ArgKind &Other) const {
- if (K == AK_Matcher && Other.K == AK_Matcher)
- return MatcherKind < Other.MatcherKind;
- return K < Other.K;
- }
-
-private:
- Kind K;
- ast_type_traits::ASTNodeKind MatcherKind;
-};
/// \brief Helper template class to just from argument type to the right is/get
/// functions in VariantValue.
@@ -116,6 +76,27 @@ template <> struct ArgTypeTraits<unsigned> {
}
};
+template <> struct ArgTypeTraits<attr::Kind> {
+private:
+ static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
+ return llvm::StringSwitch<attr::Kind>(AttrKind)
+#define ATTR(X) .Case("attr::" #X, attr:: X)
+#include "clang/Basic/AttrList.inc"
+ .Default(attr::Kind(-1));
+ }
+public:
+ static bool is(const VariantValue &Value) {
+ return Value.isString() &&
+ getAttrKind(Value.getString()) != attr::Kind(-1);
+ }
+ static attr::Kind get(const VariantValue &Value) {
+ return getAttrKind(Value.getString());
+ }
+ static ArgKind getKind() {
+ return ArgKind(ArgKind::AK_String);
+ }
+};
+
/// \brief Matcher descriptor interface.
///
/// Provides a \c create() method that constructs the matcher from the provided
@@ -161,16 +142,10 @@ inline bool isRetKindConvertibleTo(
ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) {
- for (ArrayRef<ast_type_traits::ASTNodeKind>::const_iterator
- i = RetKinds.begin(),
- e = RetKinds.end();
- i != e; ++i) {
- unsigned Distance;
- if (i->isBaseOf(Kind, &Distance)) {
- if (Specificity)
- *Specificity = 100 - Distance;
+ for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
+ if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
if (LeastDerivedKind)
- *LeastDerivedKind = *i;
+ *LeastDerivedKind = NodeKind;
return true;
}
}
@@ -322,8 +297,8 @@ variadicMatcherDescriptor(StringRef MatcherName, const SourceRange &NameRange,
VariantMatcher Out;
if (!HasError) {
- Out = outvalueToVariantMatcher(
- Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
+ Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
+ Args.size())));
}
for (size_t i = 0, e = Args.size(); i != e; ++i) {
@@ -498,7 +473,7 @@ private:
template <typename FromTypeList>
inline void collect(FromTypeList);
- const StringRef Name;
+ StringRef Name;
std::vector<MatcherDescriptor *> &Out;
};
@@ -581,15 +556,15 @@ private:
/// \brief Variadic operator marshaller function.
class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
public:
- typedef ast_matchers::internal::VariadicOperatorFunction VarFunc;
+ typedef DynTypedMatcher::VariadicOperator VarOp;
VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
- VarFunc Func, StringRef MatcherName)
- : MinCount(MinCount), MaxCount(MaxCount), Func(Func),
+ VarOp Op, StringRef MatcherName)
+ : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
MatcherName(MatcherName) {}
virtual VariantMatcher create(const SourceRange &NameRange,
ArrayRef<ParserValue> Args,
- Diagnostics *Error) const {
+ Diagnostics *Error) const override {
if (Args.size() < MinCount || MaxCount < Args.size()) {
const std::string MaxStr =
(MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
@@ -609,17 +584,17 @@ public:
}
InnerArgs.push_back(Value.getMatcher());
}
- return VariantMatcher::VariadicOperatorMatcher(Func, std::move(InnerArgs));
+ return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
}
- bool isVariadic() const { return true; }
- unsigned getNumArgs() const { return 0; }
+ bool isVariadic() const override { return true; }
+ unsigned getNumArgs() const override { return 0; }
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
- std::vector<ArgKind> &Kinds) const {
+ std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ThisKind);
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
- ast_type_traits::ASTNodeKind *LeastDerivedKind) const {
+ ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
if (Specificity)
*Specificity = 1;
if (LeastDerivedKind)
@@ -631,7 +606,7 @@ public:
private:
const unsigned MinCount;
const unsigned MaxCount;
- const VarFunc Func;
+ const VarOp Op;
const StringRef MatcherName;
};
@@ -724,7 +699,7 @@ MatcherDescriptor *
makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
MinCount, MaxCount> Func,
StringRef MatcherName) {
- return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Func,
+ return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op,
MatcherName);
}
diff --git a/lib/ASTMatchers/Dynamic/Parser.cpp b/lib/ASTMatchers/Dynamic/Parser.cpp
index 25629d9..9930c53 100644
--- a/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -17,6 +17,7 @@
#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ManagedStatic.h"
#include <string>
#include <vector>
@@ -258,8 +259,14 @@ private:
Parser::Sema::~Sema() {}
-VariantValue Parser::Sema::getNamedValue(StringRef Name) {
- return VariantValue();
+std::vector<ArgKind> Parser::Sema::getAcceptedCompletionTypes(
+ llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
+ return std::vector<ArgKind>();
+}
+
+std::vector<MatcherCompletion>
+Parser::Sema::getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) {
+ return std::vector<MatcherCompletion>();
}
struct Parser::ScopedContextEntry {
@@ -288,7 +295,9 @@ bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) {
if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
// Parse as a named value.
- if (const VariantValue NamedValue = S->getNamedValue(NameToken.Text)) {
+ if (const VariantValue NamedValue =
+ NamedValues ? NamedValues->lookup(NameToken.Text)
+ : VariantValue()) {
*Value = NamedValue;
return true;
}
@@ -379,7 +388,7 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
Tokenizer->consumeNextToken(); // consume the period.
const TokenInfo BindToken = Tokenizer->consumeNextToken();
if (BindToken.Kind == TokenInfo::TK_CodeCompletion) {
- addCompletion(BindToken, "bind(\"", "bind");
+ addCompletion(BindToken, MatcherCompletion("bind(\"", "bind", 1));
return false;
}
@@ -427,13 +436,28 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
// If the prefix of this completion matches the completion token, add it to
// Completions minus the prefix.
-void Parser::addCompletion(const TokenInfo &CompToken, StringRef TypedText,
- StringRef Decl) {
- if (TypedText.size() >= CompToken.Text.size() &&
- TypedText.substr(0, CompToken.Text.size()) == CompToken.Text) {
- Completions.push_back(
- MatcherCompletion(TypedText.substr(CompToken.Text.size()), Decl));
+void Parser::addCompletion(const TokenInfo &CompToken,
+ const MatcherCompletion& Completion) {
+ if (StringRef(Completion.TypedText).startswith(CompToken.Text) &&
+ Completion.Specificity > 0) {
+ Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()),
+ Completion.MatcherDecl, Completion.Specificity);
+ }
+}
+
+std::vector<MatcherCompletion> Parser::getNamedValueCompletions(
+ ArrayRef<ArgKind> AcceptedTypes) {
+ if (!NamedValues) return std::vector<MatcherCompletion>();
+ std::vector<MatcherCompletion> Result;
+ for (const auto &Entry : *NamedValues) {
+ unsigned Specificity;
+ if (Entry.getValue().isConvertibleTo(AcceptedTypes, &Specificity)) {
+ std::string Decl =
+ (Entry.getValue().getTypeAsString() + " " + Entry.getKey()).str();
+ Result.emplace_back(Entry.getKey(), Decl, Specificity);
+ }
}
+ return Result;
}
void Parser::addExpressionCompletions() {
@@ -449,12 +473,13 @@ void Parser::addExpressionCompletions() {
return;
}
- std::vector<MatcherCompletion> RegCompletions =
- Registry::getCompletions(ContextStack);
- for (std::vector<MatcherCompletion>::iterator I = RegCompletions.begin(),
- E = RegCompletions.end();
- I != E; ++I) {
- addCompletion(CompToken, I->TypedText, I->MatcherDecl);
+ auto AcceptedTypes = S->getAcceptedCompletionTypes(ContextStack);
+ for (const auto &Completion : S->getMatcherCompletions(AcceptedTypes)) {
+ addCompletion(CompToken, Completion);
+ }
+
+ for (const auto &Completion : getNamedValueCompletions(AcceptedTypes)) {
+ addCompletion(CompToken, Completion);
}
}
@@ -494,9 +519,12 @@ bool Parser::parseExpressionImpl(VariantValue *Value) {
llvm_unreachable("Unknown token kind.");
}
+static llvm::ManagedStatic<Parser::RegistrySema> DefaultRegistrySema;
+
Parser::Parser(CodeTokenizer *Tokenizer, Sema *S,
- Diagnostics *Error)
- : Tokenizer(Tokenizer), S(S), Error(Error) {}
+ const NamedValueMap *NamedValues, Diagnostics *Error)
+ : Tokenizer(Tokenizer), S(S ? S : &*DefaultRegistrySema),
+ NamedValues(NamedValues), Error(Error) {}
Parser::RegistrySema::~RegistrySema() {}
@@ -516,16 +544,22 @@ VariantMatcher Parser::RegistrySema::actOnMatcherExpression(
}
}
-bool Parser::parseExpression(StringRef Code, VariantValue *Value,
- Diagnostics *Error) {
- RegistrySema S;
- return parseExpression(Code, &S, Value, Error);
+std::vector<ArgKind> Parser::RegistrySema::getAcceptedCompletionTypes(
+ ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
+ return Registry::getAcceptedCompletionTypes(Context);
+}
+
+std::vector<MatcherCompletion> Parser::RegistrySema::getMatcherCompletions(
+ ArrayRef<ArgKind> AcceptedTypes) {
+ return Registry::getMatcherCompletions(AcceptedTypes);
}
bool Parser::parseExpression(StringRef Code, Sema *S,
+ const NamedValueMap *NamedValues,
VariantValue *Value, Diagnostics *Error) {
CodeTokenizer Tokenizer(Code, Error);
- if (!Parser(&Tokenizer, S, Error).parseExpressionImpl(Value)) return false;
+ if (!Parser(&Tokenizer, S, NamedValues, Error).parseExpressionImpl(Value))
+ return false;
if (Tokenizer.peekNextToken().Kind != TokenInfo::TK_Eof) {
Error->addError(Tokenizer.peekNextToken().Range,
Error->ET_ParserTrailingCode);
@@ -535,28 +569,31 @@ bool Parser::parseExpression(StringRef Code, Sema *S,
}
std::vector<MatcherCompletion>
-Parser::completeExpression(StringRef Code, unsigned CompletionOffset) {
+Parser::completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S,
+ const NamedValueMap *NamedValues) {
Diagnostics Error;
CodeTokenizer Tokenizer(Code, &Error, CompletionOffset);
- RegistrySema S;
- Parser P(&Tokenizer, &S, &Error);
+ Parser P(&Tokenizer, S, NamedValues, &Error);
VariantValue Dummy;
P.parseExpressionImpl(&Dummy);
- return P.Completions;
-}
+ // Sort by specificity, then by name.
+ std::sort(P.Completions.begin(), P.Completions.end(),
+ [](const MatcherCompletion &A, const MatcherCompletion &B) {
+ if (A.Specificity != B.Specificity)
+ return A.Specificity > B.Specificity;
+ return A.TypedText < B.TypedText;
+ });
-llvm::Optional<DynTypedMatcher>
-Parser::parseMatcherExpression(StringRef Code, Diagnostics *Error) {
- RegistrySema S;
- return parseMatcherExpression(Code, &S, Error);
+ return P.Completions;
}
llvm::Optional<DynTypedMatcher>
-Parser::parseMatcherExpression(StringRef Code, Parser::Sema *S,
+Parser::parseMatcherExpression(StringRef Code, Sema *S,
+ const NamedValueMap *NamedValues,
Diagnostics *Error) {
VariantValue Value;
- if (!parseExpression(Code, S, &Value, Error))
+ if (!parseExpression(Code, S, NamedValues, &Value, Error))
return llvm::Optional<DynTypedMatcher>();
if (!Value.isMatcher()) {
Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 4bc50a0..d550a89 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -101,8 +101,8 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(argumentCountIs);
REGISTER_MATCHER(arraySubscriptExpr);
REGISTER_MATCHER(arrayType);
- REGISTER_MATCHER(asString);
REGISTER_MATCHER(asmStmt);
+ REGISTER_MATCHER(asString);
REGISTER_MATCHER(atomicType);
REGISTER_MATCHER(autoType);
REGISTER_MATCHER(binaryOperator);
@@ -111,7 +111,6 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(boolLiteral);
REGISTER_MATCHER(breakStmt);
REGISTER_MATCHER(builtinType);
- REGISTER_MATCHER(cStyleCastExpr);
REGISTER_MATCHER(callExpr);
REGISTER_MATCHER(caseStmt);
REGISTER_MATCHER(castExpr);
@@ -123,18 +122,20 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(compoundLiteralExpr);
REGISTER_MATCHER(compoundStmt);
REGISTER_MATCHER(conditionalOperator);
- REGISTER_MATCHER(constCastExpr);
REGISTER_MATCHER(constantArrayType);
+ REGISTER_MATCHER(constCastExpr);
REGISTER_MATCHER(constructExpr);
REGISTER_MATCHER(constructorDecl);
REGISTER_MATCHER(containsDeclaration);
REGISTER_MATCHER(continueStmt);
+ REGISTER_MATCHER(cStyleCastExpr);
REGISTER_MATCHER(ctorInitializer);
+ REGISTER_MATCHER(CUDAKernelCallExpr);
REGISTER_MATCHER(decl);
+ REGISTER_MATCHER(declaratorDecl);
REGISTER_MATCHER(declCountIs);
REGISTER_MATCHER(declRefExpr);
REGISTER_MATCHER(declStmt);
- REGISTER_MATCHER(declaratorDecl);
REGISTER_MATCHER(defaultArgExpr);
REGISTER_MATCHER(defaultStmt);
REGISTER_MATCHER(deleteExpr);
@@ -147,6 +148,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(enumConstantDecl);
REGISTER_MATCHER(enumDecl);
REGISTER_MATCHER(equalsBoundNode);
+ REGISTER_MATCHER(equalsIntegralValue);
REGISTER_MATCHER(explicitCastExpr);
REGISTER_MATCHER(expr);
REGISTER_MATCHER(exprWithCleanups);
@@ -160,10 +162,10 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(forRangeStmt);
REGISTER_MATCHER(forStmt);
REGISTER_MATCHER(friendDecl);
+ REGISTER_MATCHER(functionalCastExpr);
REGISTER_MATCHER(functionDecl);
REGISTER_MATCHER(functionTemplateDecl);
REGISTER_MATCHER(functionType);
- REGISTER_MATCHER(functionalCastExpr);
REGISTER_MATCHER(gotoStmt);
REGISTER_MATCHER(has);
REGISTER_MATCHER(hasAncestor);
@@ -175,19 +177,21 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasAnyUsingShadowDecl);
REGISTER_MATCHER(hasArgument);
REGISTER_MATCHER(hasArgumentOfType);
+ REGISTER_MATCHER(hasAttr);
REGISTER_MATCHER(hasBase);
REGISTER_MATCHER(hasBody);
REGISTER_MATCHER(hasCanonicalType);
REGISTER_MATCHER(hasCaseConstant);
REGISTER_MATCHER(hasCondition);
REGISTER_MATCHER(hasConditionVariableStatement);
- REGISTER_MATCHER(hasDeclContext);
REGISTER_MATCHER(hasDeclaration);
+ REGISTER_MATCHER(hasDeclContext);
REGISTER_MATCHER(hasDeducedType);
REGISTER_MATCHER(hasDescendant);
REGISTER_MATCHER(hasDestinationType);
REGISTER_MATCHER(hasEitherOperand);
REGISTER_MATCHER(hasElementType);
+ REGISTER_MATCHER(hasElse);
REGISTER_MATCHER(hasFalseExpression);
REGISTER_MATCHER(hasGlobalStorage);
REGISTER_MATCHER(hasImplicitDestinationType);
@@ -198,6 +202,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasLocalQualifiers);
REGISTER_MATCHER(hasLocalStorage);
REGISTER_MATCHER(hasLoopInit);
+ REGISTER_MATCHER(hasLoopVariable);
REGISTER_MATCHER(hasMethod);
REGISTER_MATCHER(hasName);
REGISTER_MATCHER(hasObjectExpression);
@@ -206,6 +211,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasParameter);
REGISTER_MATCHER(hasParent);
REGISTER_MATCHER(hasQualifier);
+ REGISTER_MATCHER(hasRangeInit);
REGISTER_MATCHER(hasRHS);
REGISTER_MATCHER(hasSingleDecl);
REGISTER_MATCHER(hasSize);
@@ -213,6 +219,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasSourceExpression);
REGISTER_MATCHER(hasTargetDecl);
REGISTER_MATCHER(hasTemplateArgument);
+ REGISTER_MATCHER(hasThen);
REGISTER_MATCHER(hasTrueExpression);
REGISTER_MATCHER(hasTypeLoc);
REGISTER_MATCHER(hasUnaryOperand);
@@ -230,22 +237,30 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isConst);
REGISTER_MATCHER(isConstQualified);
REGISTER_MATCHER(isDefinition);
+ REGISTER_MATCHER(isDeleted);
REGISTER_MATCHER(isExplicitTemplateSpecialization);
REGISTER_MATCHER(isExpr);
REGISTER_MATCHER(isExternC);
REGISTER_MATCHER(isImplicit);
+ REGISTER_MATCHER(isExpansionInFileMatching);
+ REGISTER_MATCHER(isExpansionInMainFile);
+ REGISTER_MATCHER(isInstantiated);
+ REGISTER_MATCHER(isExpansionInSystemHeader);
REGISTER_MATCHER(isInteger);
+ REGISTER_MATCHER(isIntegral);
+ REGISTER_MATCHER(isInTemplateInstantiation);
REGISTER_MATCHER(isListInitialization);
REGISTER_MATCHER(isOverride);
REGISTER_MATCHER(isPrivate);
REGISTER_MATCHER(isProtected);
REGISTER_MATCHER(isPublic);
+ REGISTER_MATCHER(isPure);
REGISTER_MATCHER(isTemplateInstantiation);
REGISTER_MATCHER(isVirtual);
REGISTER_MATCHER(isWritten);
- REGISTER_MATCHER(lValueReferenceType);
REGISTER_MATCHER(labelStmt);
REGISTER_MATCHER(lambdaExpr);
+ REGISTER_MATCHER(lValueReferenceType);
REGISTER_MATCHER(matchesName);
REGISTER_MATCHER(materializeTemporaryExpr);
REGISTER_MATCHER(member);
@@ -254,8 +269,8 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(memberPointerType);
REGISTER_MATCHER(methodDecl);
REGISTER_MATCHER(namedDecl);
- REGISTER_MATCHER(namesType);
REGISTER_MATCHER(namespaceDecl);
+ REGISTER_MATCHER(namesType);
REGISTER_MATCHER(nestedNameSpecifier);
REGISTER_MATCHER(nestedNameSpecifierLoc);
REGISTER_MATCHER(newExpr);
@@ -271,15 +286,16 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(pointee);
REGISTER_MATCHER(pointerType);
REGISTER_MATCHER(qualType);
- REGISTER_MATCHER(rValueReferenceType);
REGISTER_MATCHER(recordDecl);
REGISTER_MATCHER(recordType);
REGISTER_MATCHER(referenceType);
REGISTER_MATCHER(refersToDeclaration);
+ REGISTER_MATCHER(refersToIntegralType);
REGISTER_MATCHER(refersToType);
REGISTER_MATCHER(reinterpretCastExpr);
- REGISTER_MATCHER(returnStmt);
REGISTER_MATCHER(returns);
+ REGISTER_MATCHER(returnStmt);
+ REGISTER_MATCHER(rValueReferenceType);
REGISTER_MATCHER(sizeOfExpr);
REGISTER_MATCHER(specifiesNamespace);
REGISTER_MATCHER(specifiesType);
@@ -288,8 +304,11 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(staticCastExpr);
REGISTER_MATCHER(stmt);
REGISTER_MATCHER(stringLiteral);
+ REGISTER_MATCHER(substNonTypeTemplateParmExpr);
REGISTER_MATCHER(switchCase);
REGISTER_MATCHER(switchStmt);
+ REGISTER_MATCHER(templateArgument);
+ REGISTER_MATCHER(templateArgumentCountIs);
REGISTER_MATCHER(templateSpecializationType);
REGISTER_MATCHER(temporaryObjectExpr);
REGISTER_MATCHER(thisExpr);
@@ -298,8 +317,9 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(to);
REGISTER_MATCHER(tryStmt);
REGISTER_MATCHER(type);
- REGISTER_MATCHER(typeLoc);
+ REGISTER_MATCHER(typedefDecl);
REGISTER_MATCHER(typedefType);
+ REGISTER_MATCHER(typeLoc);
REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
REGISTER_MATCHER(unaryOperator);
REGISTER_MATCHER(unaryTransformType);
@@ -308,8 +328,11 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(unresolvedUsingValueDecl);
REGISTER_MATCHER(userDefinedLiteral);
REGISTER_MATCHER(usingDecl);
+ REGISTER_MATCHER(usingDirectiveDecl);
+ REGISTER_MATCHER(valueDecl);
REGISTER_MATCHER(varDecl);
REGISTER_MATCHER(variableArrayType);
+ REGISTER_MATCHER(voidType);
REGISTER_MATCHER(whileStmt);
REGISTER_MATCHER(withInitializer);
}
@@ -353,77 +376,63 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
return OS;
}
-struct ReverseSpecificityThenName {
- bool operator()(const std::pair<unsigned, std::string> &A,
- const std::pair<unsigned, std::string> &B) const {
- return A.first > B.first || (A.first == B.first && A.second < B.second);
- }
-};
-
-}
+} // namespace
-std::vector<MatcherCompletion> Registry::getCompletions(
- ArrayRef<std::pair<MatcherCtor, unsigned> > Context) {
+std::vector<ArgKind> Registry::getAcceptedCompletionTypes(
+ ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
ASTNodeKind InitialTypes[] = {
- ASTNodeKind::getFromNodeKind<Decl>(),
- ASTNodeKind::getFromNodeKind<QualType>(),
- ASTNodeKind::getFromNodeKind<Type>(),
- ASTNodeKind::getFromNodeKind<Stmt>(),
- ASTNodeKind::getFromNodeKind<NestedNameSpecifier>(),
- ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>(),
- ASTNodeKind::getFromNodeKind<TypeLoc>()
- };
- ArrayRef<ASTNodeKind> InitialTypesRef(InitialTypes);
+ ASTNodeKind::getFromNodeKind<Decl>(),
+ ASTNodeKind::getFromNodeKind<QualType>(),
+ ASTNodeKind::getFromNodeKind<Type>(),
+ ASTNodeKind::getFromNodeKind<Stmt>(),
+ ASTNodeKind::getFromNodeKind<NestedNameSpecifier>(),
+ ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>(),
+ ASTNodeKind::getFromNodeKind<TypeLoc>()};
// Starting with the above seed of acceptable top-level matcher types, compute
// the acceptable type set for the argument indicated by each context element.
- std::set<ASTNodeKind> TypeSet(InitialTypesRef.begin(), InitialTypesRef.end());
- for (ArrayRef<std::pair<MatcherCtor, unsigned> >::iterator
- CtxI = Context.begin(),
- CtxE = Context.end();
- CtxI != CtxE; ++CtxI) {
- std::vector<internal::ArgKind> NextTypeSet;
- for (std::set<ASTNodeKind>::iterator I = TypeSet.begin(), E = TypeSet.end();
- I != E; ++I) {
- if (CtxI->first->isConvertibleTo(*I) &&
- (CtxI->first->isVariadic() ||
- CtxI->second < CtxI->first->getNumArgs()))
- CtxI->first->getArgKinds(*I, CtxI->second, NextTypeSet);
+ std::set<ArgKind> TypeSet(std::begin(InitialTypes), std::end(InitialTypes));
+ for (const auto &CtxEntry : Context) {
+ MatcherCtor Ctor = CtxEntry.first;
+ unsigned ArgNumber = CtxEntry.second;
+ std::vector<ArgKind> NextTypeSet;
+ for (const ArgKind &Kind : TypeSet) {
+ if (Kind.getArgKind() == Kind.AK_Matcher &&
+ Ctor->isConvertibleTo(Kind.getMatcherKind()) &&
+ (Ctor->isVariadic() || ArgNumber < Ctor->getNumArgs()))
+ Ctor->getArgKinds(Kind.getMatcherKind(), ArgNumber, NextTypeSet);
}
TypeSet.clear();
- for (std::vector<internal::ArgKind>::iterator I = NextTypeSet.begin(),
- E = NextTypeSet.end();
- I != E; ++I) {
- if (I->getArgKind() == internal::ArgKind::AK_Matcher)
- TypeSet.insert(I->getMatcherKind());
- }
+ TypeSet.insert(NextTypeSet.begin(), NextTypeSet.end());
}
+ return std::vector<ArgKind>(TypeSet.begin(), TypeSet.end());
+}
- typedef std::map<std::pair<unsigned, std::string>, MatcherCompletion,
- ReverseSpecificityThenName> CompletionsTy;
- CompletionsTy Completions;
+std::vector<MatcherCompletion>
+Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
+ std::vector<MatcherCompletion> Completions;
- // TypeSet now contains the list of acceptable types for the argument we are
- // completing. Search the registry for acceptable matchers.
+ // Search the registry for acceptable matchers.
for (ConstructorMap::const_iterator I = RegistryData->constructors().begin(),
E = RegistryData->constructors().end();
I != E; ++I) {
std::set<ASTNodeKind> RetKinds;
unsigned NumArgs = I->second->isVariadic() ? 1 : I->second->getNumArgs();
bool IsPolymorphic = I->second->isPolymorphic();
- std::vector<std::vector<internal::ArgKind> > ArgsKinds(NumArgs);
+ std::vector<std::vector<ArgKind>> ArgsKinds(NumArgs);
unsigned MaxSpecificity = 0;
- for (std::set<ASTNodeKind>::iterator TI = TypeSet.begin(),
- TE = TypeSet.end();
- TI != TE; ++TI) {
+ for (const ArgKind& Kind : AcceptedTypes) {
+ if (Kind.getArgKind() != Kind.AK_Matcher)
+ continue;
unsigned Specificity;
ASTNodeKind LeastDerivedKind;
- if (I->second->isConvertibleTo(*TI, &Specificity, &LeastDerivedKind)) {
+ if (I->second->isConvertibleTo(Kind.getMatcherKind(), &Specificity,
+ &LeastDerivedKind)) {
if (MaxSpecificity < Specificity)
MaxSpecificity = Specificity;
RetKinds.insert(LeastDerivedKind);
for (unsigned Arg = 0; Arg != NumArgs; ++Arg)
- I->second->getArgKinds(*TI, Arg, ArgsKinds[Arg]);
+ I->second->getArgKinds(Kind.getMatcherKind(), Arg, ArgsKinds[Arg]);
if (IsPolymorphic)
break;
}
@@ -437,24 +446,25 @@ std::vector<MatcherCompletion> Registry::getCompletions(
OS << "Matcher<T> " << I->first() << "(Matcher<T>";
} else {
OS << "Matcher<" << RetKinds << "> " << I->first() << "(";
- for (std::vector<std::vector<internal::ArgKind> >::iterator
- KI = ArgsKinds.begin(),
- KE = ArgsKinds.end();
- KI != KE; ++KI) {
- if (KI != ArgsKinds.begin())
+ for (const std::vector<ArgKind> &Arg : ArgsKinds) {
+ if (&Arg != &ArgsKinds[0])
OS << ", ";
- // This currently assumes that a matcher may not overload a
- // non-matcher, and all non-matcher overloads have identical
- // arguments.
- if ((*KI)[0].getArgKind() == internal::ArgKind::AK_Matcher) {
- std::set<ASTNodeKind> MatcherKinds;
- std::transform(
- KI->begin(), KI->end(),
- std::inserter(MatcherKinds, MatcherKinds.end()),
- std::mem_fun_ref(&internal::ArgKind::getMatcherKind));
+
+ bool FirstArgKind = true;
+ std::set<ASTNodeKind> MatcherKinds;
+ // Two steps. First all non-matchers, then matchers only.
+ for (const ArgKind &AK : Arg) {
+ if (AK.getArgKind() == ArgKind::AK_Matcher) {
+ MatcherKinds.insert(AK.getMatcherKind());
+ } else {
+ if (!FirstArgKind) OS << "|";
+ FirstArgKind = false;
+ OS << AK.asString();
+ }
+ }
+ if (!MatcherKinds.empty()) {
+ if (!FirstArgKind) OS << "|";
OS << "Matcher<" << MatcherKinds << ">";
- } else {
- OS << (*KI)[0].asString();
}
}
}
@@ -466,19 +476,14 @@ std::vector<MatcherCompletion> Registry::getCompletions(
TypedText += "(";
if (ArgsKinds.empty())
TypedText += ")";
- else if (ArgsKinds[0][0].getArgKind() == internal::ArgKind::AK_String)
+ else if (ArgsKinds[0][0].getArgKind() == ArgKind::AK_String)
TypedText += "\"";
- Completions[std::make_pair(MaxSpecificity, I->first())] =
- MatcherCompletion(TypedText, OS.str());
+ Completions.emplace_back(TypedText, OS.str(), MaxSpecificity);
}
}
- std::vector<MatcherCompletion> RetVal;
- for (CompletionsTy::iterator I = Completions.begin(), E = Completions.end();
- I != E; ++I)
- RetVal.push_back(I->second);
- return RetVal;
+ return Completions;
}
// static
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 18c9894..a88b707 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -20,26 +20,88 @@ namespace clang {
namespace ast_matchers {
namespace dynamic {
-VariantMatcher::MatcherOps::~MatcherOps() {}
+std::string ArgKind::asString() const {
+ switch (getArgKind()) {
+ case AK_Matcher:
+ return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str();
+ case AK_Unsigned:
+ return "unsigned";
+ case AK_String:
+ return "string";
+ }
+ llvm_unreachable("unhandled ArgKind");
+}
+
+bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const {
+ if (K != To.K)
+ return false;
+ if (K != AK_Matcher) {
+ if (Specificity)
+ *Specificity = 1;
+ return true;
+ }
+ unsigned Distance;
+ if (!MatcherKind.isBaseOf(To.MatcherKind, &Distance))
+ return false;
+
+ if (Specificity)
+ *Specificity = 100 - Distance;
+ return true;
+}
+
+bool
+VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const {
+ IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
+ return Matcher.canConvertTo(NodeKind);
+}
+
+llvm::Optional<DynTypedMatcher>
+VariantMatcher::MatcherOps::constructVariadicOperator(
+ DynTypedMatcher::VariadicOperator Op,
+ ArrayRef<VariantMatcher> InnerMatchers) const {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (const auto &InnerMatcher : InnerMatchers) {
+ // Abort if any of the inner matchers can't be converted to
+ // Matcher<T>.
+ if (!InnerMatcher.Value)
+ return llvm::None;
+ llvm::Optional<DynTypedMatcher> Inner =
+ InnerMatcher.Value->getTypedMatcher(*this);
+ if (!Inner)
+ return llvm::None;
+ DynMatchers.push_back(*Inner);
+ }
+ return DynTypedMatcher::constructVariadic(Op, DynMatchers);
+}
+
VariantMatcher::Payload::~Payload() {}
class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
public:
SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
return Matcher;
}
- virtual std::string getTypeAsString() const {
+ std::string getTypeAsString() const override {
return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
.str();
}
- virtual void makeTypedMatcher(MatcherOps &Ops) const {
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
bool Ignore;
if (Ops.canConstructFrom(Matcher, Ignore))
- Ops.constructFrom(Matcher);
+ return Matcher;
+ return llvm::None;
+ }
+
+ bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
+ unsigned *Specificity) const override {
+ return ArgKind(Matcher.getSupportedKind())
+ .isConvertibleTo(Kind, Specificity);
}
private:
@@ -51,15 +113,15 @@ public:
PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn)
: Matchers(std::move(MatchersIn)) {}
- virtual ~PolymorphicPayload() {}
+ ~PolymorphicPayload() override {}
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
if (Matchers.size() != 1)
return llvm::Optional<DynTypedMatcher>();
return Matchers[0];
}
- virtual std::string getTypeAsString() const {
+ std::string getTypeAsString() const override {
std::string Inner;
for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
if (i != 0)
@@ -69,7 +131,8 @@ public:
return (Twine("Matcher<") + Inner + ">").str();
}
- virtual void makeTypedMatcher(MatcherOps &Ops) const {
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
bool FoundIsExact = false;
const DynTypedMatcher *Found = nullptr;
int NumFound = 0;
@@ -89,7 +152,23 @@ public:
}
// We only succeed if we found exactly one, or if we found an exact match.
if (Found && (FoundIsExact || NumFound == 1))
- Ops.constructFrom(*Found);
+ return *Found;
+ return llvm::None;
+ }
+
+ bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
+ unsigned *Specificity) const override {
+ unsigned MaxSpecificity = 0;
+ for (const DynTypedMatcher &Matcher : Matchers) {
+ unsigned ThisSpecificity;
+ if (ArgKind(Matcher.getSupportedKind())
+ .isConvertibleTo(Kind, &ThisSpecificity)) {
+ MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
+ }
+ }
+ if (Specificity)
+ *Specificity = MaxSpecificity;
+ return MaxSpecificity > 0;
}
const std::vector<DynTypedMatcher> Matchers;
@@ -97,15 +176,15 @@ public:
class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
public:
- VariadicOpPayload(ast_matchers::internal::VariadicOperatorFunction Func,
+ VariadicOpPayload(DynTypedMatcher::VariadicOperator Op,
std::vector<VariantMatcher> Args)
- : Func(Func), Args(std::move(Args)) {}
+ : Op(Op), Args(std::move(Args)) {}
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
return llvm::Optional<DynTypedMatcher>();
}
- virtual std::string getTypeAsString() const {
+ std::string getTypeAsString() const override {
std::string Inner;
for (size_t i = 0, e = Args.size(); i != e; ++i) {
if (i != 0)
@@ -115,12 +194,22 @@ public:
return Inner;
}
- virtual void makeTypedMatcher(MatcherOps &Ops) const {
- Ops.constructVariadicOperator(Func, Args);
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
+ return Ops.constructVariadicOperator(Op, Args);
+ }
+
+ bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
+ unsigned *Specificity) const override {
+ for (const VariantMatcher &Matcher : Args) {
+ if (!Matcher.isConvertibleTo(Kind, Specificity))
+ return false;
+ }
+ return true;
}
private:
- const ast_matchers::internal::VariadicOperatorFunction Func;
+ const DynTypedMatcher::VariadicOperator Op;
const std::vector<VariantMatcher> Args;
};
@@ -136,9 +225,9 @@ VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) {
}
VariantMatcher VariantMatcher::VariadicOperatorMatcher(
- ast_matchers::internal::VariadicOperatorFunction Func,
+ DynTypedMatcher::VariadicOperator Op,
std::vector<VariantMatcher> Args) {
- return VariantMatcher(new VariadicOpPayload(Func, std::move(Args)));
+ return VariantMatcher(new VariadicOpPayload(Op, std::move(Args)));
}
llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
@@ -251,6 +340,43 @@ void VariantValue::setMatcher(const VariantMatcher &NewValue) {
Value.Matcher = new VariantMatcher(NewValue);
}
+bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const {
+ switch (Kind.getArgKind()) {
+ case ArgKind::AK_Unsigned:
+ if (!isUnsigned())
+ return false;
+ *Specificity = 1;
+ return true;
+
+ case ArgKind::AK_String:
+ if (!isString())
+ return false;
+ *Specificity = 1;
+ return true;
+
+ case ArgKind::AK_Matcher:
+ if (!isMatcher())
+ return false;
+ return getMatcher().isConvertibleTo(Kind.getMatcherKind(), Specificity);
+ }
+ llvm_unreachable("Invalid Type");
+}
+
+bool VariantValue::isConvertibleTo(ArrayRef<ArgKind> Kinds,
+ unsigned *Specificity) const {
+ unsigned MaxSpecificity = 0;
+ for (const ArgKind& Kind : Kinds) {
+ unsigned ThisSpecificity;
+ if (!isConvertibleTo(Kind, &ThisSpecificity))
+ continue;
+ MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
+ }
+ if (Specificity && MaxSpecificity > 0) {
+ *Specificity = MaxSpecificity;
+ }
+ return MaxSpecificity > 0;
+}
+
std::string VariantValue::getTypeAsString() const {
switch (Type) {
case VT_String: return "String";
OpenPOWER on IntegriCloud