summaryrefslogtreecommitdiff
path: root/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/ASTMatchers/ASTMatchersInternal.cpp')
-rw-r--r--clang/lib/ASTMatchers/ASTMatchersInternal.cpp282
1 files changed, 200 insertions, 82 deletions
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 199a6d839e2eb..4b9baf7a0e751 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -15,9 +15,11 @@
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ParentMapContext.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Lex/Lexer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/None.h"
@@ -27,6 +29,8 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -40,39 +44,56 @@ namespace ast_matchers {
AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,
Matches) {
- std::string SelString = Node.getSelector().getAsString();
- for (const std::string &S : Matches)
- if (S == SelString)
- return true;
- return false;
+ return llvm::is_contained(Matches, Node.getSelector().getAsString());
}
namespace internal {
-bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+bool NotUnaryOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
-bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+bool AllOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
-bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+bool EachOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
-bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+bool AnyOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
-bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
+bool OptionallyVariadicOperator(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
+bool matchesAnyBase(const CXXRecordDecl &Node,
+ const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) {
+ if (!Node.hasDefinition())
+ return false;
+
+ CXXBasePaths Paths;
+ Paths.setOrigin(&Node);
+
+ const auto basePredicate =
+ [Finder, Builder, &BaseSpecMatcher](const CXXBaseSpecifier *BaseSpec,
+ CXXBasePath &IgnoredParam) {
+ BoundNodesTreeBuilder Result(*Builder);
+ if (BaseSpecMatcher.matches(*BaseSpec, Finder, Builder)) {
+ *Builder = std::move(Result);
+ return true;
+ }
+ return false;
+ };
+
+ return Node.lookupInBases(basePredicate, Paths,
+ /*LookupInDependent =*/true);
+}
+
void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
if (Bindings.empty())
Bindings.push_back(BoundNodesMap());
@@ -84,7 +105,7 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
namespace {
using VariadicOperatorFunction = bool (*)(
- const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
+ const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
template <VariadicOperatorFunction Func>
@@ -93,8 +114,7 @@ public:
VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
: InnerMatchers(std::move(InnerMatchers)) {}
- bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+ bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
return Func(DynNode, Finder, Builder, InnerMatchers);
}
@@ -109,16 +129,14 @@ public:
IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
: ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
- bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+ bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
if (Result) Builder->setBinding(ID, DynNode);
return Result;
}
- llvm::Optional<ast_type_traits::TraversalKind>
- TraversalKind() const override {
+ llvm::Optional<clang::TraversalKind> TraversalKind() const override {
return InnerMatcher->TraversalKind();
}
@@ -138,20 +156,45 @@ public:
Retain(); // Reference count will never become zero.
}
- bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
+ bool dynMatches(const DynTypedNode &, ASTMatchFinder *,
BoundNodesTreeBuilder *) const override {
return true;
}
};
+/// A matcher that specifies a particular \c TraversalKind.
+///
+/// The kind provided to the constructor overrides any kind that may be
+/// specified by the `InnerMatcher`.
+class DynTraversalMatcherImpl : public DynMatcherInterface {
+public:
+ explicit DynTraversalMatcherImpl(
+ clang::TraversalKind TK,
+ IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
+ : TK(TK), InnerMatcher(std::move(InnerMatcher)) {}
+
+ bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
+ return this->InnerMatcher->dynMatches(DynNode, Finder, Builder);
+ }
+
+ llvm::Optional<clang::TraversalKind> TraversalKind() const override {
+ return TK;
+ }
+
+private:
+ clang::TraversalKind TK;
+ IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
+};
+
} // namespace
static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
-DynTypedMatcher DynTypedMatcher::constructVariadic(
- DynTypedMatcher::VariadicOperator Op,
- ast_type_traits::ASTNodeKind SupportedKind,
- std::vector<DynTypedMatcher> InnerMatchers) {
+DynTypedMatcher
+DynTypedMatcher::constructVariadic(DynTypedMatcher::VariadicOperator Op,
+ ASTNodeKind SupportedKind,
+ std::vector<DynTypedMatcher> InnerMatchers) {
assert(!InnerMatchers.empty() && "Array must not be empty.");
assert(llvm::all_of(InnerMatchers,
[SupportedKind](const DynTypedMatcher &M) {
@@ -172,8 +215,8 @@ DynTypedMatcher DynTypedMatcher::constructVariadic(
// invalid types earlier and we can elide the kind checks inside the
// matcher.
for (auto &IM : InnerMatchers) {
- RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType(
- RestrictKind, IM.RestrictKind);
+ RestrictKind =
+ ASTNodeKind::getMostDerivedType(RestrictKind, IM.RestrictKind);
}
return DynTypedMatcher(
SupportedKind, RestrictKind,
@@ -204,40 +247,45 @@ DynTypedMatcher DynTypedMatcher::constructVariadic(
llvm_unreachable("Invalid Op value.");
}
-DynTypedMatcher DynTypedMatcher::constructRestrictedWrapper(
- const DynTypedMatcher &InnerMatcher,
- ast_type_traits::ASTNodeKind RestrictKind) {
+DynTypedMatcher
+DynTypedMatcher::constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
+ ASTNodeKind RestrictKind) {
DynTypedMatcher Copy = InnerMatcher;
Copy.RestrictKind = RestrictKind;
return Copy;
}
-DynTypedMatcher DynTypedMatcher::trueMatcher(
- ast_type_traits::ASTNodeKind NodeKind) {
+DynTypedMatcher
+DynTypedMatcher::withTraversalKind(ast_type_traits::TraversalKind TK) {
+ auto Copy = *this;
+ Copy.Implementation =
+ new DynTraversalMatcherImpl(TK, std::move(Copy.Implementation));
+ return Copy;
+}
+
+DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) {
return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
}
-bool DynTypedMatcher::canMatchNodesOfKind(
- ast_type_traits::ASTNodeKind Kind) const {
+bool DynTypedMatcher::canMatchNodesOfKind(ASTNodeKind Kind) const {
return RestrictKind.isBaseOf(Kind);
}
-DynTypedMatcher DynTypedMatcher::dynCastTo(
- const ast_type_traits::ASTNodeKind Kind) const {
+DynTypedMatcher DynTypedMatcher::dynCastTo(const ASTNodeKind Kind) const {
auto Copy = *this;
Copy.SupportedKind = Kind;
- Copy.RestrictKind =
- ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
+ Copy.RestrictKind = ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
return Copy;
}
-bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
+bool DynTypedMatcher::matches(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
TraversalKindScope RAII(Finder->getASTContext(),
Implementation->TraversalKind());
- auto N = Finder->getASTContext().traverseIgnored(DynNode);
+ auto N =
+ Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
if (RestrictKind.isBaseOf(N.getNodeKind()) &&
Implementation->dynMatches(N, Finder, Builder)) {
@@ -250,13 +298,14 @@ bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
return false;
}
-bool DynTypedMatcher::matchesNoKindCheck(
- const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+bool DynTypedMatcher::matchesNoKindCheck(const DynTypedNode &DynNode,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
TraversalKindScope raii(Finder->getASTContext(),
Implementation->TraversalKind());
- auto N = Finder->getASTContext().traverseIgnored(DynNode);
+ auto N =
+ Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
assert(RestrictKind.isBaseOf(N.getNodeKind()));
if (Implementation->dynMatches(N, Finder, Builder)) {
@@ -277,10 +326,10 @@ llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
return std::move(Result);
}
-bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
+bool DynTypedMatcher::canConvertTo(ASTNodeKind To) const {
const auto From = getSupportedKind();
- auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
- auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
+ auto QualKind = ASTNodeKind::getFromNodeKind<QualType>();
+ auto TypeKind = ASTNodeKind::getFromNodeKind<Type>();
/// Mimic the implicit conversions of Matcher<>.
/// - From Matcher<Type> to Matcher<QualType>
if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
@@ -292,8 +341,8 @@ void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
}
-bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+bool NotUnaryOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
if (InnerMatchers.size() != 1)
return false;
@@ -312,22 +361,18 @@ bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
}
-bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+bool AllOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
// allOf leads to one matcher for each alternative in the first
// matcher combined with each alternative in the second matcher.
// Thus, we can reuse the same Builder.
- for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
- if (!InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder))
- return false;
- }
- return true;
+ return llvm::all_of(InnerMatchers, [&](const DynTypedMatcher &InnerMatcher) {
+ return InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder);
+ });
}
-bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+bool EachOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
BoundNodesTreeBuilder Result;
@@ -343,8 +388,7 @@ bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
return Matched;
}
-bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
- ASTMatchFinder *Finder,
+bool AnyOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
@@ -357,31 +401,31 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
return false;
}
-bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
+bool OptionallyVariadicOperator(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
- BoundNodesTreeBuilder Result;
- for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
- BoundNodesTreeBuilder BuilderInner(*Builder);
- if (InnerMatcher.matches(DynNode, Finder, &BuilderInner))
- Result.addMatch(BuilderInner);
- }
- *Builder = std::move(Result);
+ if (InnerMatchers.size() != 1)
+ return false;
+
+ BoundNodesTreeBuilder Result(*Builder);
+ if (InnerMatchers[0].matches(DynNode, Finder, &Result))
+ *Builder = std::move(Result);
return true;
}
inline static
std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {
std::vector<std::string> Names;
+ Names.reserve(NameRefs.size());
for (auto *Name : NameRefs)
Names.emplace_back(*Name);
return Names;
}
Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) {
- std::vector<std::string> Names = vectorFromRefs(NameRefs);
- return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names));
+ return internal::Matcher<NamedDecl>(
+ new internal::HasNameMatcher(vectorFromRefs(NameRefs)));
}
Matcher<ObjCMessageExpr> hasAnySelectorFunc(
@@ -389,10 +433,18 @@ Matcher<ObjCMessageExpr> hasAnySelectorFunc(
return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
}
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
+ return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
+HasOverloadOpNameMatcher
+hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
+ return HasOverloadOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
HasNameMatcher::HasNameMatcher(std::vector<std::string> N)
- : UseUnqualifiedMatch(std::all_of(
- N.begin(), N.end(),
- [](StringRef Name) { return Name.find("::") == Name.npos; })),
+ : UseUnqualifiedMatch(llvm::all_of(
+ N, [](StringRef Name) { return Name.find("::") == Name.npos; })),
Names(std::move(N)) {
#ifndef NDEBUG
for (StringRef Name : Names)
@@ -450,6 +502,7 @@ namespace {
class PatternSet {
public:
PatternSet(ArrayRef<std::string> Names) {
+ Patterns.reserve(Names.size());
for (StringRef Name : Names)
Patterns.push_back({Name, Name.startswith("::")});
}
@@ -474,10 +527,10 @@ public:
/// A match will be a pattern that was fully consumed, that also matches the
/// 'fully qualified' requirement.
bool foundMatch(bool AllowFullyQualified) const {
- for (auto& P: Patterns)
- if (P.P.empty() && (AllowFullyQualified || !P.IsFullyQualified))
- return true;
- return false;
+ return llvm::any_of(Patterns, [&](const Pattern &Pattern) {
+ return Pattern.P.empty() &&
+ (AllowFullyQualified || !Pattern.IsFullyQualified);
+ });
}
private:
@@ -523,7 +576,13 @@ bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
if (Ctx->isFunctionOrMethod())
return Patterns.foundMatch(/*AllowFullyQualified=*/false);
- for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
+ for (; Ctx; Ctx = Ctx->getParent()) {
+ // Linkage Spec can just be ignored
+ // FIXME: Any other DeclContext kinds that can be safely disregarded
+ if (isa<LinkageSpecDecl>(Ctx))
+ continue;
+ if (!isa<NamedDecl>(Ctx))
+ break;
if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
return true;
@@ -592,6 +651,52 @@ bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
return matchesNodeFullFast(Node);
}
+// Checks whether \p Loc points to a token with source text of \p TokenText.
+static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts,
+ StringRef Text, SourceLocation Loc) {
+ llvm::SmallString<16> Buffer;
+ bool Invalid = false;
+ // Since `Loc` may point into an expansion buffer, which has no corresponding
+ // source, we need to look at the spelling location to read the actual source.
+ StringRef TokenText = Lexer::getSpelling(SM.getSpellingLoc(Loc), Buffer, SM,
+ LangOpts, &Invalid);
+ return !Invalid && Text == TokenText;
+}
+
+llvm::Optional<SourceLocation>
+getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
+ const ASTContext &Context) {
+ auto &SM = Context.getSourceManager();
+ const LangOptions &LangOpts = Context.getLangOpts();
+ while (Loc.isMacroID()) {
+ SrcMgr::ExpansionInfo Expansion =
+ SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
+ if (Expansion.isMacroArgExpansion())
+ // Check macro argument for an expansion of the given macro. For example,
+ // `F(G(3))`, where `MacroName` is `G`.
+ if (llvm::Optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
+ MacroName, Expansion.getSpellingLoc(), Context))
+ return ArgLoc;
+ Loc = Expansion.getExpansionLocStart();
+ if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
+ return Loc;
+ }
+ return llvm::None;
+}
+
+std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
+ llvm::Regex::RegexFlags Flags,
+ StringRef MatcherID) {
+ assert(!Regex.empty() && "Empty regex string");
+ auto SharedRegex = std::make_shared<llvm::Regex>(Regex, Flags);
+ std::string Error;
+ if (!SharedRegex->isValid(Error)) {
+ llvm::WithColor::error()
+ << "building matcher '" << MatcherID << "': " << Error << "\n";
+ llvm::WithColor::note() << " input was '" << Regex << "'\n";
+ }
+ return SharedRegex;
+}
} // end namespace internal
const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>
@@ -647,6 +752,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
enumConstantDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
cxxConversionDecl;
@@ -727,6 +833,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
materializeTemporaryExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>
+ cxxNoexceptExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
arraySubscriptExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
@@ -768,6 +876,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
integerLiteral;
const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral>
+ fixedPointLiteral;
const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
userDefinedLiteral;
const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
@@ -821,12 +931,18 @@ const internal::VariadicOperatorMatcherFunc<
const internal::VariadicOperatorMatcherFunc<
2, std::numeric_limits<unsigned>::max()>
allOf = {internal::DynTypedMatcher::VO_AllOf};
-const internal::VariadicOperatorMatcherFunc<
- 1, std::numeric_limits<unsigned>::max()>
- optionally = {internal::DynTypedMatcher::VO_Optionally};
+const internal::VariadicOperatorMatcherFunc<1, 1> optionally = {
+ internal::DynTypedMatcher::VO_Optionally};
const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
internal::hasAnyNameFunc>
hasAnyName = {};
+
+const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef,
+ internal::hasAnyOperatorNameFunc>
+ hasAnyOperatorName = {};
+const internal::VariadicFunction<internal::HasOverloadOpNameMatcher, StringRef,
+ internal::hasAnyOverloadedOperatorNameFunc>
+ hasAnyOverloadedOperatorName = {};
const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,
internal::hasAnySelectorFunc>
hasAnySelector = {};
@@ -858,6 +974,8 @@ const AstTypeMatcher<BuiltinType> builtinType;
const AstTypeMatcher<ArrayType> arrayType;
const AstTypeMatcher<ComplexType> complexType;
const AstTypeMatcher<ConstantArrayType> constantArrayType;
+const AstTypeMatcher<DeducedTemplateSpecializationType>
+ deducedTemplateSpecializationType;
const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
const AstTypeMatcher<VariableArrayType> variableArrayType;