hasDeclaration(DeclMatcher),
unless(templateSpecializationType()))))),
hasParent(nestedNameSpecifierLoc()),
- hasAncestor(decl(isImplicit())),
+ hasAncestor(isImplicit()),
hasAncestor(UsingShadowDeclInClass),
hasAncestor(functionDecl(isDefaulted())))),
hasAncestor(decl().bind("dc")))
hasAncestor(decl(IsInMovedNs).bind("dc")),
loc(nestedNameSpecifier(
specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"))))),
- unless(anyOf(hasAncestor(decl(isImplicit())),
+ unless(anyOf(hasAncestor(isImplicit()),
hasAncestor(UsingShadowDeclInClass),
hasAncestor(functionDecl(isDefaulted())),
hasAncestor(typeLoc(loc(qualType(hasDeclaration(
hasAncestor(cxxRecordDecl()))),
hasParent(namespaceDecl()));
Finder->addMatcher(expr(hasAncestor(decl().bind("dc")), IsInMovedNs,
- unless(hasAncestor(decl(isImplicit()))),
+ unless(hasAncestor(isImplicit())),
anyOf(callExpr(callee(FuncMatcher)).bind("call"),
declRefExpr(to(FuncMatcher.bind("func_decl")))
.bind("func_ref"))),
void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
// Note: if a struct contains an array member, the compiler-generated
// constructor has an arraySubscriptExpr.
- Finder->addMatcher(arraySubscriptExpr(hasBase(ignoringImpCasts(hasType(
- constantArrayType().bind("type")))),
- hasIndex(expr().bind("index")),
- unless(hasAncestor(decl(isImplicit()))))
- .bind("expr"),
- this);
+ Finder->addMatcher(
+ arraySubscriptExpr(
+ hasBase(ignoringImpCasts(hasType(constantArrayType().bind("type")))),
+ hasIndex(expr().bind("index")), unless(hasAncestor(isImplicit())))
+ .bind("expr"),
+ this);
Finder->addMatcher(
cxxOperatorCallExpr(
</pre></td></tr>
-<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Attr.html">Attr</a>></td><td class="name" onclick="toggle('attr0')"><a name="attr0Anchor">attr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Attr.html">Attr</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="attr0"><pre>Matches attributes.
-Attributes may be attached with a variety of different syntaxes (including
-keywords, C++11 attributes, GNU ``__attribute``` and MSVC `__declspec``,
-and ``#pragma``s). They may also be implicit.
-
-Given
- struct [[nodiscard]] Foo{};
- void bar(int * __attribute__((nonnull)) );
- __declspec(noinline) void baz();
-
- #pragma omp declare simd
- int min();
-attr()
- matches "nodiscard", "nonnull", "noinline", and the whole "#pragma" line.
-</pre></td></tr>
-
-
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('cxxCtorInitializer0')"><a name="cxxCtorInitializer0Anchor">cxxCtorInitializer</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="cxxCtorInitializer0"><pre>Matches constructor initializers.
</pre></td></tr>
-<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Attr.html">Attr</a>></td><td class="name" onclick="toggle('isImplicit1')"><a name="isImplicit1Anchor">isImplicit</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isImplicit1"><pre>Matches an entity that has been implicitly added by the compiler (e.g.
-implicit default/copy constructors).
-</pre></td></tr>
-
-
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasAnyOperatorName0')"><a name="hasAnyOperatorName0Anchor">hasAnyOperatorName</a></td><td>StringRef, ..., StringRef</td></tr>
<tr><td colspan="4" class="doc" id="hasAnyOperatorName0"><pre>Matches operator expressions (binary or unary) that have any of the
specified names.
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches an entity that has been implicitly added by the compiler (e.g.
-implicit default/copy constructors).
+<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a declaration that has been implicitly added
+by the compiler (eg. implicit default/copy constructors).
</pre></td></tr>
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) class Class;
#include "llvm/Frontend/OpenMP/OMP.inc"
-class Attr;
-#define ATTR(A) class A##Attr;
-#include "clang/Basic/AttrList.inc"
} // end namespace clang
#include "llvm/Support/AlignOf.h"
namespace llvm {
+
class raw_ostream;
-} // namespace llvm
+
+}
namespace clang {
static ASTNodeKind getFromNode(const Stmt &S);
static ASTNodeKind getFromNode(const Type &T);
static ASTNodeKind getFromNode(const OMPClause &C);
- static ASTNodeKind getFromNode(const Attr &A);
/// \}
/// Returns \c true if \c this and \c Other represent the same kind.
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
#include "llvm/Frontend/OpenMP/OMP.inc"
- NKI_Attr,
-#define ATTR(A) NKI_##A##Attr,
-#include "clang/Basic/AttrList.inc"
NKI_NumberOfKinds
};
KIND_TO_KIND_ID(Stmt)
KIND_TO_KIND_ID(Type)
KIND_TO_KIND_ID(OMPClause)
-KIND_TO_KIND_ID(Attr)
KIND_TO_KIND_ID(CXXBaseSpecifier)
#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
#include "clang/AST/DeclNodes.inc"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
#include "llvm/Frontend/OpenMP/OMP.inc"
-#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
-#include "clang/Basic/AttrList.inc"
#undef KIND_TO_KIND_ID
inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
: public DynCastPtrConverter<T, OMPClause> {};
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
- : public DynCastPtrConverter<T, Attr> {};
-
template <>
struct DynTypedNode::BaseConverter<
NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
MatchCallback *Action);
void addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
MatchCallback *Action);
- void addMatcher(const AttrMatcher &NodeMatch, MatchCallback *Action);
/// @}
/// Adds a matcher to execute when running over the AST.
std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
std::vector<std::pair<TemplateArgumentLocMatcher, MatchCallback *>>
TemplateArgumentLoc;
- std::vector<std::pair<AttrMatcher, MatchCallback *>> Attr;
/// All the callbacks in one container to simplify iteration.
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
};
using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
using TemplateArgumentMatcher = internal::Matcher<TemplateArgument>;
using TemplateArgumentLocMatcher = internal::Matcher<TemplateArgumentLoc>;
-using AttrMatcher = internal::Matcher<Attr>;
/// @}
/// Matches any node.
InnerMatcher.matches(*Decl, Finder, Builder));
}
-/// Matches an entity that has been implicitly added by the compiler (e.g.
-/// implicit default/copy constructors).
-AST_POLYMORPHIC_MATCHER(isImplicit,
- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Attr)) {
+/// Matches a declaration that has been implicitly added
+/// by the compiler (eg. implicit default/copy constructors).
+AST_MATCHER(Decl, isImplicit) {
return Node.isImplicit();
}
/// Usable as: Any Matcher
extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasParentMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
hasParent;
/// Matches AST nodes that have an ancestor that matches the provided
/// Usable as: Any Matcher
extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasAncestorMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
hasAncestor;
/// Matches if the provided matcher does not match.
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}
-/// Matches attributes.
-/// Attributes may be attached with a variety of different syntaxes (including
-/// keywords, C++11 attributes, GNU ``__attribute``` and MSVC `__declspec``,
-/// and ``#pragma``s). They may also be implicit.
-///
-/// Given
-/// \code
-/// struct [[nodiscard]] Foo{};
-/// void bar(int * __attribute__((nonnull)) );
-/// __declspec(noinline) void baz();
-///
-/// #pragma omp declare simd
-/// int min();
-/// \endcode
-/// attr()
-/// matches "nodiscard", "nonnull", "noinline", and the whole "#pragma" line.
-extern const internal::VariadicAllOfMatcher<Attr> attr;
-
/// Overloads for the \c equalsNode matcher.
/// FIXME: Implement for other node types.
/// @{
std::is_base_of<NestedNameSpecifier, T>::value ||
std::is_base_of<NestedNameSpecifierLoc, T>::value ||
std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<QualType, T>::value ||
- std::is_base_of<Attr, T>::value,
+ std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
Builder, Bind);
std::is_base_of<NestedNameSpecifier, T>::value ||
std::is_base_of<NestedNameSpecifierLoc, T>::value ||
std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<QualType, T>::value ||
- std::is_base_of<Attr, T>::value,
+ std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
Matcher, Builder, Bind);
static_assert(std::is_base_of<Decl, T>::value ||
std::is_base_of<NestedNameSpecifierLoc, T>::value ||
std::is_base_of<Stmt, T>::value ||
- std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<Attr, T>::value,
+ std::is_base_of<TypeLoc, T>::value,
"type not allowed for recursive matching");
return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
Matcher, Builder, MatchMode);
bool matchesNode(const NamedDecl &Node) const override;
-private:
+ private:
/// Unqualified match routine.
///
/// It is much faster than the full match, but it only works for unqualified
std::is_same<T, NestedNameSpecifier>::value ||
std::is_same<T, NestedNameSpecifierLoc>::value ||
std::is_same<T, CXXCtorInitializer>::value ||
- std::is_same<T, TemplateArgumentLoc>::value ||
- std::is_same<T, Attr>::value;
+ std::is_same<T, TemplateArgumentLoc>::value;
};
template <typename T>
const bool IsBaseType<T>::value;
/// Useful for matchers like \c anything and \c unless.
using AllNodeBaseTypes =
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
- Type, TypeLoc, CXXCtorInitializer, Attr>;
+ Type, TypeLoc, CXXCtorInitializer>;
/// Helper meta-function to extract the argument out of a function of
/// type void(Arg).
using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
using AdaptativeDefaultToTypes =
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
- QualType, Attr>;
+ QualType>;
/// All types that are supported by HasDeclarationMatcher above.
using HasDeclarationSupportedTypes =
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class},
#include "llvm/Frontend/OpenMP/OMP.inc"
- {NKI_None, "Attr"},
-#define ATTR(A) {NKI_Attr, #A "Attr"},
-#include "clang/Basic/AttrList.inc"
};
bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
llvm_unreachable("unexpected OpenMP clause kind");
#include "llvm/Frontend/OpenMP/OMP.inc"
}
- llvm_unreachable("invalid omp clause kind");
-}
-
-ASTNodeKind ASTNodeKind::getFromNode(const Attr &A) {
- switch (A.getKind()) {
-#define ATTR(A) \
- case attr::A: \
- return ASTNodeKind(NKI_##A##Attr);
-#include "clang/Basic/AttrList.inc"
- }
- llvm_unreachable("invalid attr kind");
+ llvm_unreachable("invalid stmt kind");
}
void DynTypedNode::print(llvm::raw_ostream &OS,
S->printPretty(OS, nullptr, PP);
else if (const Type *T = get<Type>())
QualType(T, 0).print(OS, PP);
- else if (const Attr *A = get<Attr>())
- A->printPretty(OS, PP);
else
OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
}
return SourceRange(C->getBeginLoc(), C->getEndLoc());
if (const auto *CBS = get<CXXBaseSpecifier>())
return CBS->getSourceRange();
- if (const auto *A = get<Attr>())
- return A->getRange();
return SourceRange();
}
[&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
&Map.OtherParents);
}
- bool TraverseAttr(Attr *AttrNode) {
- return TraverseNode(
- AttrNode, AttrNode, [&] { return VisitorBase::TraverseAttr(AttrNode); },
- &Map.PointerParents);
- }
// Using generic TraverseNode for Stmt would prevent data-recursion.
bool dataTraverseStmtPre(Stmt *StmtNode) {
else if (const TemplateArgumentLoc *TALoc =
DynNode.get<TemplateArgumentLoc>())
traverse(*TALoc);
- else if (const Attr *A = DynNode.get<Attr>())
- traverse(*A);
// FIXME: Add other base types after adding tests.
// It's OK to always overwrite the bound nodes, as if there was
return match(*Node->getLHS()) && match(*Node->getRHS());
}
- bool TraverseAttr(Attr *A) {
- if (A == nullptr ||
- (A->isImplicit() &&
- Finder->getASTContext().getParentMapContext().getTraversalKind() ==
- TK_IgnoreUnlessSpelledInSource))
- return true;
- ScopedIncrement ScopedDepth(&CurrentDepth);
- return traverse(*A);
- }
bool TraverseLambdaExpr(LambdaExpr *Node) {
if (!Finder->isTraversalIgnoringImplicitNodes())
return VisitorBase::TraverseLambdaExpr(Node);
bool baseTraverse(TemplateArgumentLoc TAL) {
return VisitorBase::TraverseTemplateArgumentLoc(TAL);
}
- bool baseTraverse(const Attr &AttrNode) {
- return VisitorBase::TraverseAttr(const_cast<Attr *>(&AttrNode));
- }
// Sets 'Matched' to true if 'Matcher' matches 'Node' and:
// 0 < CurrentDepth <= MaxDepth.
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL);
- bool TraverseAttr(Attr *AttrNode);
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {
if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) {
match(*N);
} else if (auto *N = Node.get<TemplateArgumentLoc>()) {
match(*N);
- } else if (auto *N = Node.get<Attr>()) {
- match(*N);
}
}
void matchDispatch(const TemplateArgumentLoc *Node) {
matchWithoutFilter(*Node, Matchers->TemplateArgumentLoc);
}
- void matchDispatch(const Attr *Node) {
- matchWithoutFilter(*Node, Matchers->Attr);
- }
void matchDispatch(const void *) { /* Do nothing. */ }
/// @}
return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateArgumentLoc(Loc);
}
-bool MatchASTVisitor::TraverseAttr(Attr *AttrNode) {
- match(*AttrNode);
- return RecursiveASTVisitor<MatchASTVisitor>::TraverseAttr(AttrNode);
-}
-
class MatchASTConsumer : public ASTConsumer {
public:
MatchASTConsumer(MatchFinder *Finder,
Matchers.AllCallbacks.insert(Action);
}
-void MatchFinder::addMatcher(const AttrMatcher &AttrMatch,
- MatchCallback *Action) {
- Matchers.Attr.emplace_back(AttrMatch, Action);
- Matchers.AllCallbacks.insert(Action);
-}
-
bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
MatchCallback *Action) {
if (NodeMatch.canConvertTo<Decl>()) {
} else if (NodeMatch.canConvertTo<TemplateArgumentLoc>()) {
addMatcher(NodeMatch.convertTo<TemplateArgumentLoc>(), Action);
return true;
- } else if (NodeMatch.canConvertTo<Attr>()) {
- addMatcher(NodeMatch.convertTo<Attr>(), Action);
- return true;
}
return false;
}
forEachDescendant = {};
const internal::ArgumentAdaptingMatcherFunc<
internal::HasParentMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
hasParent = {};
const internal::ArgumentAdaptingMatcherFunc<
internal::HasAncestorMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
hasAncestor = {};
const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
internal::DynTypedMatcher::VO_UnaryNot};
const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
nestedNameSpecifierLoc;
-const internal::VariadicAllOfMatcher<Attr> attr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
cudaKernelCallExpr;
const AstTypeMatcher<BuiltinType> builtinType;
REGISTER_MATCHER(asmStmt);
REGISTER_MATCHER(atomicExpr);
REGISTER_MATCHER(atomicType);
- REGISTER_MATCHER(attr);
REGISTER_MATCHER(autoType);
REGISTER_MATCHER(autoreleasePoolStmt)
REGISTER_MATCHER(binaryConditionalOperator);
VERIFY_NAME(CallExpr);
VERIFY_NAME(Type);
VERIFY_NAME(ConstantArrayType);
- VERIFY_NAME(NonNullAttr);
#undef VERIFY_NAME
}
nestedNameSpecifierLoc()));
}
-TEST(DynTypedNode, AttrSourceRange) {
- RangeVerifier<DynTypedNode> Verifier;
- Verifier.expectRange(1, 31, 1, 31);
- EXPECT_TRUE(Verifier.match("void x(char *y __attribute__((nonnull)) );",
- ast_matchers::attr()));
-}
-
TEST(DynTypedNode, DeclDump) {
DumpVerifier Verifier;
Verifier.expectSubstring("FunctionDecl");
nestedNameSpecifier()));
}
-TEST_P(ASTMatchersTest, Attr) {
- // Windows adds some implicit attributes.
- bool AutomaticAttributes = StringRef(GetParam().Target).contains("win32");
- if (GetParam().isCXX11OrLater()) {
- EXPECT_TRUE(matches("struct [[clang::warn_unused_result]] F{};", attr()));
-
- // Unknown attributes are not parsed into an AST node.
- if (!AutomaticAttributes)
- EXPECT_TRUE(notMatches("int x [[unknownattr]];", attr()));
- }
- }
- if (GetParam().isCXX17OrLater()) {
- EXPECT_TRUE(matches("struct [[nodiscard]] F{};", attr()));
- }
- EXPECT_TRUE(matches("int x(int * __attribute__((nonnull)) );", attr()));
- if (!AutomaticAttributes) {
- EXPECT_TRUE(notMatches("struct F{}; int x(int *);", attr()));
- // Some known attributes are not parsed into an AST node.
- EXPECT_TRUE(notMatches("typedef int x __attribute__((ext_vector_type(1)));",
- attr()));
- }
-}
-
TEST_P(ASTMatchersTest, NullStmt) {
EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
// Some tests use typeof, which is a gnu extension. Using an explicit
// unknown-unknown triple is good for a large speedup, because it lets us
// avoid constructing a full system triple.
- std::vector<std::string> Args = {"-std=gnu++11", "-target",
+ std::vector<std::string> Args = {"-std=gnu++98", "-target",
"i386-unknown-unknown"};
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) {
return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
//===----------------------------------------------------------------------===//
#include "ASTMatchersTest.h"
-#include "clang/AST/Attrs.inc"
#include "clang/AST/PrettyPrinter.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit");
EXPECT_TRUE(matchAndVerifyResultTrue(
Code, traverse(TK_AsIs, M),
- std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 6)));
+ std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 7)));
EXPECT_TRUE(matchAndVerifyResultTrue(
Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
auto M = expr().bind("allExprs");
EXPECT_TRUE(matchAndVerifyResultTrue(
Code, traverse(TK_AsIs, M),
- std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 6)));
+ std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 7)));
EXPECT_TRUE(matchAndVerifyResultTrue(
Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1)));
// Nested names: a, a::A and a::A::B.
std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3)));
}
-
-TEST(Attr, AttrsAsDescendants) {
- StringRef Fragment = "namespace a { struct [[clang::warn_unused_result]] "
- "F{}; [[noreturn]] void foo(); }";
- EXPECT_TRUE(matches(Fragment, namespaceDecl(hasDescendant(attr()))));
- EXPECT_TRUE(matchAndVerifyResultTrue(
- Fragment,
- namespaceDecl(hasName("a"),
- forEachDescendant(attr(unless(isImplicit())).bind("x"))),
- std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2)));
-}
-
-TEST(Attr, ParentsOfAttrs) {
- StringRef Fragment =
- "namespace a { struct [[clang::warn_unused_result]] F{}; }";
- EXPECT_TRUE(matches(Fragment, attr(hasAncestor(namespaceDecl()))));
-}
-
template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
public:
VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,