diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-24 22:00:03 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-24 22:00:03 +0000 |
commit | 480093f4440d54b30b3025afeac24b48f2ba7a2e (patch) | |
tree | 162e72994062888647caf0d875428db9445491a8 /contrib/llvm-project/clang/lib/ASTMatchers | |
parent | 489b1cf2ecf5b9b4a394857987014bfb09067726 (diff) | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-480093f4440d54b30b3025afeac24b48f2ba7a2e.tar.gz src-480093f4440d54b30b3025afeac24b48f2ba7a2e.zip |
Merge ^/vendor/lvm-project/master up to its last change (upstream commit
e26a78e70), and resolve conflicts.
Notes
Notes:
svn path=/projects/clang1000-import/; revision=357095
Diffstat (limited to 'contrib/llvm-project/clang/lib/ASTMatchers')
4 files changed, 195 insertions, 51 deletions
diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchFinder.cpp index c51fd630e64b..0d1f713db8d3 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -59,10 +59,12 @@ struct MatchKey { DynTypedMatcher::MatcherIDType MatcherID; ast_type_traits::DynTypedNode Node; BoundNodesTreeBuilder BoundNodes; + ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs; bool operator<(const MatchKey &Other) const { - return std::tie(MatcherID, Node, BoundNodes) < - std::tie(Other.MatcherID, Other.Node, Other.BoundNodes); + return std::tie(MatcherID, Node, BoundNodes, Traversal) < + std::tie(Other.MatcherID, Other.Node, Other.BoundNodes, + Other.Traversal); } }; @@ -136,18 +138,32 @@ public: ScopedIncrement ScopedDepth(&CurrentDepth); return (DeclNode == nullptr) || traverse(*DeclNode); } - bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { - // If we need to keep track of the depth, we can't perform data recursion. - if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) - Queue = nullptr; - ScopedIncrement ScopedDepth(&CurrentDepth); + Stmt *getStmtToTraverse(Stmt *StmtNode) { Stmt *StmtToTraverse = StmtNode; + if (auto *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) { + auto *LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode); + if (LambdaNode && Finder->getASTContext().getTraversalKind() == + ast_type_traits::TK_IgnoreUnlessSpelledInSource) + StmtToTraverse = LambdaNode; + else + StmtToTraverse = Finder->getASTContext().traverseIgnored(ExprNode); + } if (Traversal == ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses) { if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) StmtToTraverse = ExprNode->IgnoreParenImpCasts(); } + return StmtToTraverse; + } + + bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { + // If we need to keep track of the depth, we can't perform data recursion. + if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) + Queue = nullptr; + + ScopedIncrement ScopedDepth(&CurrentDepth); + Stmt *StmtToTraverse = getStmtToTraverse(StmtNode); if (!StmtToTraverse) return true; if (!match(*StmtToTraverse)) @@ -199,6 +215,41 @@ public: ScopedIncrement ScopedDepth(&CurrentDepth); return traverse(*CtorInit); } + bool TraverseLambdaExpr(LambdaExpr *Node) { + if (Finder->getASTContext().getTraversalKind() != + ast_type_traits::TK_IgnoreUnlessSpelledInSource) + return VisitorBase::TraverseLambdaExpr(Node); + if (!Node) + return true; + ScopedIncrement ScopedDepth(&CurrentDepth); + + for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { + const auto *C = Node->capture_begin() + I; + if (!C->isExplicit()) + continue; + if (Node->isInitCapture(C) && !match(*C->getCapturedVar())) + return false; + if (!match(*Node->capture_init_begin()[I])) + return false; + } + + if (const auto *TPL = Node->getTemplateParameterList()) { + for (const auto *TP : *TPL) { + if (!match(*TP)) + return false; + } + } + + for (const auto *P : Node->getCallOperator()->parameters()) { + if (!match(*P)) + return false; + } + + if (!match(*Node->getBody())) + return false; + + return true; + } bool shouldVisitTemplateInstantiations() const { return true; } bool shouldVisitImplicitCode() const { return true; } @@ -390,6 +441,7 @@ public: // Matches children or descendants of 'Node' with 'BaseMatcher'. bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node, + ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, int MaxDepth, ast_type_traits::TraversalKind Traversal, @@ -404,6 +456,7 @@ public: Key.Node = Node; // Note that we key on the bindings *before* the match. Key.BoundNodes = *Builder; + Key.Traversal = Ctx.getTraversalKind(); MemoizationMap::iterator I = ResultCache.find(Key); if (I != ResultCache.end()) { @@ -446,36 +499,36 @@ public: // Implements ASTMatchFinder::matchesChildOf. bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, - const DynTypedMatcher &Matcher, + ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, ast_type_traits::TraversalKind Traversal, BindKind Bind) override { if (ResultCache.size() > MaxMemoizationEntries) ResultCache.clear(); - return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal, + return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, 1, Traversal, Bind); } // Implements ASTMatchFinder::matchesDescendantOf. bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, - const DynTypedMatcher &Matcher, + ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, BindKind Bind) override { if (ResultCache.size() > MaxMemoizationEntries) ResultCache.clear(); - return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX, + return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX, ast_type_traits::TraversalKind::TK_AsIs, Bind); } // Implements ASTMatchFinder::matchesAncestorOf. bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, - const DynTypedMatcher &Matcher, + ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) override { // Reset the cache outside of the recursive call to make sure we // don't invalidate any iterators. if (ResultCache.size() > MaxMemoizationEntries) ResultCache.clear(); - return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder, + return memoizedMatchesAncestorOfRecursively(Node, Ctx, Matcher, Builder, MatchMode); } @@ -576,7 +629,7 @@ private: if (EnableCheckProfiling) Timer.setBucket(&TimeByBucket[MP.second->getID()]); BoundNodesTreeBuilder Builder; - if (MP.first.matchesNoKindCheck(DynNode, this, &Builder)) { + if (MP.first.matches(DynNode, this, &Builder)) { MatchVisitor Visitor(ActiveASTContext, MP.second); Builder.visitMatches(&Visitor); } @@ -640,16 +693,19 @@ private: // allow simple memoization on the ancestors. Thus, we only memoize as long // as there is a single parent. bool memoizedMatchesAncestorOfRecursively( - const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher, - BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) { + const ast_type_traits::DynTypedNode &Node, ASTContext &Ctx, + const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, + AncestorMatchMode MatchMode) { // For AST-nodes that don't have an identity, we can't memoize. if (!Builder->isComparable()) - return matchesAncestorOfRecursively(Node, Matcher, Builder, MatchMode); + return matchesAncestorOfRecursively(Node, Ctx, Matcher, Builder, + MatchMode); MatchKey Key; Key.MatcherID = Matcher.getID(); Key.Node = Node; Key.BoundNodes = *Builder; + Key.Traversal = Ctx.getTraversalKind(); // Note that we cannot use insert and reuse the iterator, as recursive // calls to match might invalidate the result cache iterators. @@ -661,8 +717,8 @@ private: MemoizedMatchResult Result; Result.Nodes = *Builder; - Result.ResultOfMatch = - matchesAncestorOfRecursively(Node, Matcher, &Result.Nodes, MatchMode); + Result.ResultOfMatch = matchesAncestorOfRecursively( + Node, Ctx, Matcher, &Result.Nodes, MatchMode); MemoizedMatchResult &CachedResult = ResultCache[Key]; CachedResult = std::move(Result); @@ -672,6 +728,7 @@ private: } bool matchesAncestorOfRecursively(const ast_type_traits::DynTypedNode &Node, + ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) { @@ -705,8 +762,8 @@ private: return true; } if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { - return memoizedMatchesAncestorOfRecursively(Parent, Matcher, Builder, - MatchMode); + return memoizedMatchesAncestorOfRecursively(Parent, Ctx, Matcher, + Builder, MatchMode); // Once we get back from the recursive call, the result will be the // same as the parent's result. } @@ -804,8 +861,6 @@ private: /// kind (and derived kinds) so it is a waste to try every matcher on every /// node. /// We precalculate a list of matchers that pass the toplevel restrict check. - /// This also allows us to skip the restrict check at matching time. See - /// use \c matchesNoKindCheck() above. llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap; @@ -904,8 +959,9 @@ bool MatchASTVisitor::objcClassIsDerivedFrom( if (Base.matches(*ClassDecl, this, Builder)) return true; + // Not `return false` as a temporary workaround for PR43879. if (Directly) - return false; + break; } return false; diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 4ee32fbe94b1..199a6d839e2e 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -68,6 +68,11 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers); +bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef<DynTypedMatcher> InnerMatchers); + void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { if (Bindings.empty()) Bindings.push_back(BoundNodesMap()); @@ -112,6 +117,11 @@ public: return Result; } + llvm::Optional<ast_type_traits::TraversalKind> + TraversalKind() const override { + return InnerMatcher->TraversalKind(); + } + private: const std::string ID; const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher; @@ -179,6 +189,11 @@ DynTypedMatcher DynTypedMatcher::constructVariadic( SupportedKind, RestrictKind, new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers))); + case VO_Optionally: + return DynTypedMatcher(SupportedKind, RestrictKind, + new VariadicMatcher<OptionallyVariadicOperator>( + std::move(InnerMatchers))); + case VO_UnaryNot: // FIXME: Implement the Not operator to take a single matcher instead of a // vector. @@ -189,6 +204,14 @@ DynTypedMatcher DynTypedMatcher::constructVariadic( llvm_unreachable("Invalid Op value."); } +DynTypedMatcher DynTypedMatcher::constructRestrictedWrapper( + const DynTypedMatcher &InnerMatcher, + ast_type_traits::ASTNodeKind RestrictKind) { + DynTypedMatcher Copy = InnerMatcher; + Copy.RestrictKind = RestrictKind; + return Copy; +} + DynTypedMatcher DynTypedMatcher::trueMatcher( ast_type_traits::ASTNodeKind NodeKind) { return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance); @@ -211,8 +234,13 @@ DynTypedMatcher DynTypedMatcher::dynCastTo( bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - if (RestrictKind.isBaseOf(DynNode.getNodeKind()) && - Implementation->dynMatches(DynNode, Finder, Builder)) { + TraversalKindScope RAII(Finder->getASTContext(), + Implementation->TraversalKind()); + + auto N = Finder->getASTContext().traverseIgnored(DynNode); + + if (RestrictKind.isBaseOf(N.getNodeKind()) && + Implementation->dynMatches(N, Finder, Builder)) { return true; } // Delete all bindings when a matcher does not match. @@ -225,8 +253,13 @@ bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode, bool DynTypedMatcher::matchesNoKindCheck( const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - assert(RestrictKind.isBaseOf(DynNode.getNodeKind())); - if (Implementation->dynMatches(DynNode, Finder, Builder)) { + TraversalKindScope raii(Finder->getASTContext(), + Implementation->TraversalKind()); + + auto N = Finder->getASTContext().traverseIgnored(DynNode); + + assert(RestrictKind.isBaseOf(N.getNodeKind())); + if (Implementation->dynMatches(N, Finder, Builder)) { return true; } // Delete all bindings when a matcher does not match. @@ -324,6 +357,20 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, return false; } +bool OptionallyVariadicOperator(const ast_type_traits::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); + return true; +} + inline static std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) { std::vector<std::string> Names; @@ -774,6 +821,9 @@ 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::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, internal::hasAnyNameFunc> hasAnyName = {}; diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Parser.cpp index e3b00b46832c..a0037549ca61 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Parser.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Parser.cpp @@ -38,6 +38,7 @@ struct Parser::TokenInfo { /// Different possible tokens. enum TokenKind { TK_Eof, + TK_NewLine, TK_OpenParen, TK_CloseParen, TK_Comma, @@ -65,12 +66,12 @@ const char* const Parser::TokenInfo::ID_Bind = "bind"; /// Simple tokenizer for the parser. class Parser::CodeTokenizer { public: - explicit CodeTokenizer(StringRef MatcherCode, Diagnostics *Error) + explicit CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error) : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error) { NextToken = getNextToken(); } - CodeTokenizer(StringRef MatcherCode, Diagnostics *Error, + CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error, unsigned CodeCompletionOffset) : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error), CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) { @@ -87,6 +88,19 @@ public: return ThisToken; } + TokenInfo SkipNewlines() { + while (NextToken.Kind == TokenInfo::TK_NewLine) + NextToken = getNextToken(); + return NextToken; + } + + TokenInfo consumeNextTokenIgnoreNewlines() { + SkipNewlines(); + if (NextToken.Kind == TokenInfo::TK_Eof) + return NextToken; + return consumeNextToken(); + } + TokenInfo::TokenKind nextTokenKind() const { return NextToken.Kind; } private: @@ -110,9 +124,8 @@ private: switch (Code[0]) { case '#': - Result.Kind = TokenInfo::TK_Eof; - Result.Text = ""; - return Result; + Code = Code.drop_until([](char c) { return c == '\n'; }); + return getNextToken(); case ',': Result.Kind = TokenInfo::TK_Comma; Result.Text = Code.substr(0, 1); @@ -123,6 +136,13 @@ private: Result.Text = Code.substr(0, 1); Code = Code.drop_front(); break; + case '\n': + ++Line; + StartOfLine = Code.drop_front(); + Result.Kind = TokenInfo::TK_NewLine; + Result.Text = Code.substr(0, 1); + Code = Code.drop_front(); + break; case '(': Result.Kind = TokenInfo::TK_OpenParen; Result.Text = Code.substr(0, 1); @@ -277,13 +297,10 @@ private: /// Consume all leading whitespace from \c Code. void consumeWhitespace() { - while (!Code.empty() && isWhitespace(Code[0])) { - if (Code[0] == '\n') { - ++Line; - StartOfLine = Code.drop_front(); - } - Code = Code.drop_front(); - } + Code = Code.drop_while([](char c) { + // Don't trim newlines. + return StringRef(" \t\v\f\r").contains(c); + }); } SourceLocation currentLocation() { @@ -293,7 +310,7 @@ private: return Location; } - StringRef Code; + StringRef &Code; StringRef StartOfLine; unsigned Line = 1; Diagnostics *Error; @@ -364,10 +381,19 @@ bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) { } return false; } + + if (Tokenizer->nextTokenKind() == TokenInfo::TK_NewLine) { + Error->addError(Tokenizer->peekNextToken().Range, + Error->ET_ParserNoOpenParen) + << "NewLine"; + return false; + } + // If the syntax is correct and the name is not a matcher either, report // unknown named value. if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma || Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen || + Tokenizer->nextTokenKind() == TokenInfo::TK_NewLine || Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) && !S->lookupMatcherCtor(NameToken.Text)) { Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound) @@ -377,6 +403,8 @@ bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) { // Otherwise, fallback to the matcher parser. } + Tokenizer->SkipNewlines(); + // Parse as a matcher expression. return parseMatcherExpressionImpl(NameToken, Value); } @@ -392,8 +420,8 @@ bool Parser::parseBindID(std::string &BindID) { } const TokenInfo OpenToken = Tokenizer->consumeNextToken(); - const TokenInfo IDToken = Tokenizer->consumeNextToken(); - const TokenInfo CloseToken = Tokenizer->consumeNextToken(); + const TokenInfo IDToken = Tokenizer->consumeNextTokenIgnoreNewlines(); + const TokenInfo CloseToken = Tokenizer->consumeNextTokenIgnoreNewlines(); // TODO: We could use different error codes for each/some to be more // explicit about the syntax error. @@ -443,6 +471,8 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken, std::vector<ParserValue> Args; TokenInfo EndToken; + Tokenizer->SkipNewlines(); + { ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr); @@ -466,12 +496,14 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken, NameToken.Text, NameToken.Range, Args.size() + 1); ParserValue ArgValue; + Tokenizer->SkipNewlines(); ArgValue.Text = Tokenizer->peekNextToken().Text; ArgValue.Range = Tokenizer->peekNextToken().Range; if (!parseExpressionImpl(&ArgValue.Value)) { return false; } + Tokenizer->SkipNewlines(); Args.push_back(ArgValue); SCE.nextArg(); } @@ -531,7 +563,7 @@ std::vector<MatcherCompletion> Parser::getNamedValueCompletions( } void Parser::addExpressionCompletions() { - const TokenInfo CompToken = Tokenizer->consumeNextToken(); + const TokenInfo CompToken = Tokenizer->consumeNextTokenIgnoreNewlines(); assert(CompToken.Kind == TokenInfo::TK_CodeCompletion); // We cannot complete code if there is an invalid element on the context @@ -575,14 +607,15 @@ bool Parser::parseExpressionImpl(VariantValue *Value) { case TokenInfo::TK_Error: // This error was already reported by the tokenizer. return false; - + case TokenInfo::TK_NewLine: case TokenInfo::TK_OpenParen: case TokenInfo::TK_CloseParen: case TokenInfo::TK_Comma: case TokenInfo::TK_Period: case TokenInfo::TK_InvalidChar: const TokenInfo Token = Tokenizer->consumeNextToken(); - Error->addError(Token.Range, Error->ET_ParserInvalidToken) << Token.Text; + Error->addError(Token.Range, Error->ET_ParserInvalidToken) + << (Token.Kind == TokenInfo::TK_NewLine ? "NewLine" : Token.Text); return false; } @@ -624,13 +657,14 @@ std::vector<MatcherCompletion> Parser::RegistrySema::getMatcherCompletions( return Registry::getMatcherCompletions(AcceptedTypes); } -bool Parser::parseExpression(StringRef Code, Sema *S, +bool Parser::parseExpression(StringRef &Code, Sema *S, const NamedValueMap *NamedValues, VariantValue *Value, Diagnostics *Error) { CodeTokenizer Tokenizer(Code, Error); if (!Parser(&Tokenizer, S, NamedValues, Error).parseExpressionImpl(Value)) return false; - if (Tokenizer.peekNextToken().Kind != TokenInfo::TK_Eof) { + auto NT = Tokenizer.peekNextToken(); + if (NT.Kind != TokenInfo::TK_Eof && NT.Kind != TokenInfo::TK_NewLine) { Error->addError(Tokenizer.peekNextToken().Range, Error->ET_ParserTrailingCode); return false; @@ -639,7 +673,7 @@ bool Parser::parseExpression(StringRef Code, Sema *S, } std::vector<MatcherCompletion> -Parser::completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S, +Parser::completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S, const NamedValueMap *NamedValues) { Diagnostics Error; CodeTokenizer Tokenizer(Code, &Error, CompletionOffset); @@ -659,7 +693,7 @@ Parser::completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S, } llvm::Optional<DynTypedMatcher> -Parser::parseMatcherExpression(StringRef Code, Sema *S, +Parser::parseMatcherExpression(StringRef &Code, Sema *S, const NamedValueMap *NamedValues, Diagnostics *Error) { VariantValue Value; diff --git a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 8c11e069cb05..1c0930c5983a 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -41,7 +41,8 @@ namespace { using internal::MatcherDescriptor; -using ConstructorMap = llvm::StringMap<std::unique_ptr<const MatcherDescriptor>>; +using ConstructorMap = + llvm::StringMap<std::unique_ptr<const MatcherDescriptor>>; class RegistryMaps { public: @@ -104,6 +105,7 @@ RegistryMaps::RegistryMaps() { // equalsNode REGISTER_OVERLOADED_2(callee); + REGISTER_OVERLOADED_2(hasAnyCapture); REGISTER_OVERLOADED_2(hasPrefix); REGISTER_OVERLOADED_2(hasType); REGISTER_OVERLOADED_2(ignoringParens); @@ -279,6 +281,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasIndex); REGISTER_MATCHER(hasInit); REGISTER_MATCHER(hasInitializer); + REGISTER_MATCHER(hasInitStatement); REGISTER_MATCHER(hasKeywordSelector); REGISTER_MATCHER(hasLHS); REGISTER_MATCHER(hasLocalQualifiers); @@ -454,6 +457,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(on); REGISTER_MATCHER(onImplicitObjectArgument); REGISTER_MATCHER(opaqueValueExpr); + REGISTER_MATCHER(optionally); REGISTER_MATCHER(parameterCountIs); REGISTER_MATCHER(parenExpr); REGISTER_MATCHER(parenListExpr); |