[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
//===--- FindTarget.h - What does an AST node refer to? ---------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Many clangd features are concerned with references in the AST:
|
|
|
|
// - xrefs, go-to-definition, explicitly talk about references
|
|
|
|
// - hover and code actions relate to things you "target" in the editor
|
|
|
|
// - refactoring actions need to know about entities that are referenced
|
|
|
|
// to determine whether/how the edit can be applied.
|
|
|
|
//
|
|
|
|
// Historically, we have used libIndex (IndexDataConsumer) to tie source
|
|
|
|
// locations to referenced declarations. This file defines a more decoupled
|
|
|
|
// approach based around AST nodes (DynTypedNode), and can be combined with
|
|
|
|
// SelectionTree or other traversals.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-09-25 20:54:53 +08:00
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_FINDTARGET_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_FINDTARGET_H
|
|
|
|
|
[clangd] Implement semantic highlightings via findExplicitReferences
Summary:
To keep the logic of finding locations of interesting AST nodes in one
place.
The advantage is better coverage of various AST nodes, both now and in
the future: as new nodes get added to `findExplicitReferences`, semantic
highlighting will automatically pick them up.
The drawback of this change is that we have to traverse declarations
inside our file twice in order to highlight dependent names, 'auto'
and 'decltype'. Hopefully, this should not affect the actual latency
too much, most time should be spent in building the AST and not
traversing it.
Reviewers: hokein
Reviewed By: hokein
Subscribers: nridge, merge_guards_bot, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69673
2019-11-06 02:06:12 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
#include "clang/AST/ASTTypeTraits.h"
|
2019-09-25 20:40:22 +08:00
|
|
|
#include "clang/AST/NestedNameSpecifier.h"
|
|
|
|
#include "clang/AST/Stmt.h"
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
#include "clang/Basic/SourceLocation.h"
|
2019-09-25 20:40:22 +08:00
|
|
|
#include "llvm/ADT/Optional.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
2019-09-25 20:40:22 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
|
|
|
|
#include <bitset>
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
2021-01-18 15:58:43 +08:00
|
|
|
class HeuristicResolver;
|
|
|
|
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
/// Describes the link between an AST node and a Decl it refers to.
|
|
|
|
enum class DeclRelation : unsigned;
|
|
|
|
/// A bitfield of DeclRelations.
|
|
|
|
class DeclRelationSet;
|
|
|
|
|
|
|
|
/// targetDecl() finds the declaration referred to by an AST node.
|
|
|
|
/// For example a RecordTypeLoc refers to the RecordDecl for the type.
|
|
|
|
///
|
|
|
|
/// In some cases there are multiple results, e.g. a dependent unresolved
|
|
|
|
/// OverloadExpr may have several candidates. All will be returned:
|
|
|
|
///
|
|
|
|
/// void foo(int); <-- candidate
|
|
|
|
/// void foo(double); <-- candidate
|
|
|
|
/// template <typename T> callFoo() { foo(T()); }
|
|
|
|
/// ^ OverloadExpr
|
|
|
|
///
|
|
|
|
/// In other cases, there may be choices about what "referred to" means.
|
|
|
|
/// e.g. does naming a typedef refer to the underlying type?
|
|
|
|
/// The results are marked with a set of DeclRelations, and can be filtered.
|
|
|
|
///
|
|
|
|
/// struct S{}; <-- candidate (underlying)
|
|
|
|
/// using T = S{}; <-- candidate (alias)
|
|
|
|
/// T x;
|
|
|
|
/// ^ TypedefTypeLoc
|
|
|
|
///
|
|
|
|
/// Formally, we walk a graph starting at the provided node, and return the
|
|
|
|
/// decls that were found. Certain edges in the graph have labels, and for each
|
|
|
|
/// decl we return the set of labels seen on a path to the decl.
|
|
|
|
/// For the previous example:
|
|
|
|
///
|
|
|
|
/// TypedefTypeLoc T
|
|
|
|
/// |
|
|
|
|
/// TypedefType T
|
|
|
|
/// / \
|
|
|
|
/// [underlying] [alias]
|
|
|
|
/// / \
|
|
|
|
/// RecordDecl S TypeAliasDecl T
|
|
|
|
///
|
[clangd] targetDecl() returns only NamedDecls.
Summary:
While it's perfectly reasonable for non-named decls such as
static_assert to resolve to themselves:
- nothing else ever resolves to them
- features based on references (hover, highlight, find refs etc) tend
to be uninteresting where only trivial references are possible
- returning NamedDecl is a more convenient API (we cast to it in many places)
- this aligns closer to findExplicitReferences/explicitReferenceTargets
This fixes a crash in explicitReferenceTargets: if the target is a
non-named decl then there's an invalid unchecked cast to NamedDecl.
In practice this means when hovering over e.g. a static_assert:
- before ac3f9e4842, we would show a (boring) hover card
- after ac3f9e4842, we would crash
- after this patch, we will show nothing
Reviewers: kadircet, ilya-biryukov
Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D72163
2020-01-04 00:26:33 +08:00
|
|
|
/// Note that this function only returns NamedDecls. Generally other decls
|
|
|
|
/// don't have references in this sense, just the node itself.
|
|
|
|
/// If callers want to support such decls, they should cast the node directly.
|
|
|
|
///
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
/// FIXME: some AST nodes cannot be DynTypedNodes, these cannot be specified.
|
2021-01-18 15:58:43 +08:00
|
|
|
llvm::SmallVector<const NamedDecl *, 1>
|
|
|
|
targetDecl(const DynTypedNode &, DeclRelationSet Mask,
|
|
|
|
const HeuristicResolver *Resolver);
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
|
2020-01-03 00:59:10 +08:00
|
|
|
/// Similar to targetDecl(), however instead of applying a filter, all possible
|
|
|
|
/// decls are returned along with their DeclRelationSets.
|
|
|
|
/// This is suitable for indexing, where everything is recorded and filtering
|
|
|
|
/// is applied later.
|
[clangd] targetDecl() returns only NamedDecls.
Summary:
While it's perfectly reasonable for non-named decls such as
static_assert to resolve to themselves:
- nothing else ever resolves to them
- features based on references (hover, highlight, find refs etc) tend
to be uninteresting where only trivial references are possible
- returning NamedDecl is a more convenient API (we cast to it in many places)
- this aligns closer to findExplicitReferences/explicitReferenceTargets
This fixes a crash in explicitReferenceTargets: if the target is a
non-named decl then there's an invalid unchecked cast to NamedDecl.
In practice this means when hovering over e.g. a static_assert:
- before ac3f9e4842, we would show a (boring) hover card
- after ac3f9e4842, we would crash
- after this patch, we will show nothing
Reviewers: kadircet, ilya-biryukov
Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D72163
2020-01-04 00:26:33 +08:00
|
|
|
llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1>
|
2021-01-18 15:58:43 +08:00
|
|
|
allTargetDecls(const DynTypedNode &, const HeuristicResolver *);
|
2020-01-03 00:59:10 +08:00
|
|
|
|
|
|
|
enum class DeclRelation : unsigned {
|
|
|
|
// Template options apply when the declaration is an instantiated template.
|
|
|
|
// e.g. [[vector<int>]] vec;
|
|
|
|
|
|
|
|
/// This is the template instantiation that was referred to.
|
|
|
|
/// e.g. template<> class vector<int> (the implicit specialization)
|
|
|
|
TemplateInstantiation,
|
|
|
|
/// This is the pattern the template specialization was instantiated from.
|
|
|
|
/// e.g. class vector<T> (the pattern within the primary template)
|
|
|
|
TemplatePattern,
|
|
|
|
|
|
|
|
// Alias options apply when the declaration is an alias.
|
2020-10-07 16:01:04 +08:00
|
|
|
// e.g. namespace client { [[X]] x; }
|
2020-01-03 00:59:10 +08:00
|
|
|
|
|
|
|
/// This declaration is an alias that was referred to.
|
2020-10-07 16:01:04 +08:00
|
|
|
/// e.g. using ns::X (the UsingDecl directly referenced),
|
|
|
|
/// using Z = ns::Y (the TypeAliasDecl directly referenced)
|
2020-01-03 00:59:10 +08:00
|
|
|
Alias,
|
2020-10-07 16:01:04 +08:00
|
|
|
/// This is the underlying declaration for a renaming-alias, decltype etc.
|
|
|
|
/// e.g. class ns::Y (the underlying declaration referenced).
|
|
|
|
///
|
|
|
|
/// Note that we don't treat `using ns::X` as a first-class declaration like
|
|
|
|
/// `using Z = ns::Y`. Therefore reference to X that goes through this
|
|
|
|
/// using-decl is considered a direct reference (without the Underlying bit).
|
|
|
|
/// Nevertheless, we report `using ns::X` as an Alias, so that some features
|
|
|
|
/// like go-to-definition can still target it.
|
2020-01-03 00:59:10 +08:00
|
|
|
Underlying,
|
|
|
|
};
|
|
|
|
llvm::raw_ostream &operator<<(llvm::raw_ostream &, DeclRelation);
|
|
|
|
|
2019-09-25 20:40:22 +08:00
|
|
|
/// Information about a reference written in the source code, independent of the
|
|
|
|
/// actual AST node that this reference lives in.
|
|
|
|
/// Useful for tools that are source-aware, e.g. refactorings.
|
|
|
|
struct ReferenceLoc {
|
|
|
|
/// Contains qualifier written in the code, if any, e.g. 'ns::' for 'ns::foo'.
|
|
|
|
NestedNameSpecifierLoc Qualifier;
|
|
|
|
/// Start location of the last name part, i.e. 'foo' in 'ns::foo<int>'.
|
|
|
|
SourceLocation NameLoc;
|
2019-10-18 20:07:19 +08:00
|
|
|
/// True if the reference is a declaration or definition;
|
|
|
|
bool IsDecl = false;
|
2019-09-25 20:40:22 +08:00
|
|
|
// FIXME: add info about template arguments.
|
|
|
|
/// A list of targets referenced by this name. Normally this has a single
|
|
|
|
/// element, but multiple is also possible, e.g. in case of using declarations
|
|
|
|
/// or unresolved overloaded functions.
|
|
|
|
/// For dependent and unresolved references, Targets can also be empty.
|
|
|
|
llvm::SmallVector<const NamedDecl *, 1> Targets;
|
|
|
|
};
|
|
|
|
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceLoc R);
|
|
|
|
|
|
|
|
/// Recursively traverse \p S and report all references explicitly written in
|
|
|
|
/// the code. The main use-case is refactorings that need to process all
|
|
|
|
/// references in some subrange of the file and apply simple edits, e.g. add
|
|
|
|
/// qualifiers.
|
|
|
|
/// FIXME: currently this does not report references to overloaded operators.
|
|
|
|
/// FIXME: extend to report location information about declaration names too.
|
2019-09-25 23:44:26 +08:00
|
|
|
void findExplicitReferences(const Stmt *S,
|
2021-01-18 15:58:43 +08:00
|
|
|
llvm::function_ref<void(ReferenceLoc)> Out,
|
|
|
|
const HeuristicResolver *Resolver);
|
2019-09-25 23:44:26 +08:00
|
|
|
void findExplicitReferences(const Decl *D,
|
2021-01-18 15:58:43 +08:00
|
|
|
llvm::function_ref<void(ReferenceLoc)> Out,
|
|
|
|
const HeuristicResolver *Resolver);
|
[clangd] Implement semantic highlightings via findExplicitReferences
Summary:
To keep the logic of finding locations of interesting AST nodes in one
place.
The advantage is better coverage of various AST nodes, both now and in
the future: as new nodes get added to `findExplicitReferences`, semantic
highlighting will automatically pick them up.
The drawback of this change is that we have to traverse declarations
inside our file twice in order to highlight dependent names, 'auto'
and 'decltype'. Hopefully, this should not affect the actual latency
too much, most time should be spent in building the AST and not
traversing it.
Reviewers: hokein
Reviewed By: hokein
Subscribers: nridge, merge_guards_bot, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69673
2019-11-06 02:06:12 +08:00
|
|
|
void findExplicitReferences(const ASTContext &AST,
|
2021-01-18 15:58:43 +08:00
|
|
|
llvm::function_ref<void(ReferenceLoc)> Out,
|
|
|
|
const HeuristicResolver *Resolver);
|
2019-09-25 20:40:22 +08:00
|
|
|
|
2020-01-03 00:59:10 +08:00
|
|
|
/// Find declarations explicitly referenced in the source code defined by \p N.
|
|
|
|
/// For templates, will prefer to return a template instantiation whenever
|
|
|
|
/// possible. However, can also return a template pattern if the specialization
|
|
|
|
/// cannot be picked, e.g. in dependent code or when there is no corresponding
|
2020-04-05 14:28:11 +08:00
|
|
|
/// Decl for a template instantiation, e.g. for templated using decls:
|
2020-01-03 00:59:10 +08:00
|
|
|
/// template <class T> using Ptr = T*;
|
|
|
|
/// Ptr<int> x;
|
|
|
|
/// ^~~ there is no Decl for 'Ptr<int>', so we return the template pattern.
|
|
|
|
/// \p Mask should not contain TemplatePattern or TemplateInstantiation.
|
|
|
|
llvm::SmallVector<const NamedDecl *, 1>
|
2021-01-18 15:58:43 +08:00
|
|
|
explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask,
|
|
|
|
const HeuristicResolver *Resolver);
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
|
2020-01-03 00:59:10 +08:00
|
|
|
// Boring implementation details of bitfield.
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
|
|
|
|
class DeclRelationSet {
|
|
|
|
using Set = std::bitset<static_cast<unsigned>(DeclRelation::Underlying) + 1>;
|
|
|
|
Set S;
|
|
|
|
DeclRelationSet(Set S) : S(S) {}
|
|
|
|
|
|
|
|
public:
|
|
|
|
DeclRelationSet() = default;
|
|
|
|
DeclRelationSet(DeclRelation R) { S.set(static_cast<unsigned>(R)); }
|
|
|
|
|
|
|
|
explicit operator bool() const { return S.any(); }
|
|
|
|
friend DeclRelationSet operator&(DeclRelationSet L, DeclRelationSet R) {
|
|
|
|
return L.S & R.S;
|
|
|
|
}
|
|
|
|
friend DeclRelationSet operator|(DeclRelationSet L, DeclRelationSet R) {
|
|
|
|
return L.S | R.S;
|
|
|
|
}
|
|
|
|
friend bool operator==(DeclRelationSet L, DeclRelationSet R) {
|
|
|
|
return L.S == R.S;
|
|
|
|
}
|
|
|
|
friend DeclRelationSet operator~(DeclRelationSet R) { return ~R.S; }
|
|
|
|
DeclRelationSet &operator|=(DeclRelationSet Other) {
|
|
|
|
S |= Other.S;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
DeclRelationSet &operator&=(DeclRelationSet Other) {
|
|
|
|
S &= Other.S;
|
|
|
|
return *this;
|
|
|
|
}
|
2021-01-11 09:41:50 +08:00
|
|
|
bool contains(DeclRelationSet Other) const {
|
|
|
|
return (S & Other.S) == Other.S;
|
|
|
|
}
|
[clangd] Add targetDecl(), which determines what declaration an AST node refers to.
Summary:
This is the first part of an effort to "unbundle" our libIndex use into separate
concerns (AST traversal, token<->node mapping, node<->decl mapping,
decl<->decl relationshipes).
Currently, clangd relies on libIndex to associate tokens, AST nodes, and decls.
This leads to rather convoluted implementations of e.g. hover and
extract-function, which are not naturally thought of as indexing applications.
The idea is that by decoupling different concerns, we make them easier
to use, test, and combine, and more efficient when only one part is needed.
There are some synergies between e.g. traversal and finding
relationships between decls, hopefully the benefits outweight these.
Reviewers: kadircet, ilya-biryukov
Subscribers: mgorny, MaskRay, jkorous, arphaman, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66751
llvm-svn: 370746
2019-09-03 19:35:50 +08:00
|
|
|
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, DeclRelationSet);
|
|
|
|
};
|
|
|
|
// The above operators can't be looked up if both sides are enums.
|
|
|
|
// over.match.oper.html#3.2
|
|
|
|
inline DeclRelationSet operator|(DeclRelation L, DeclRelation R) {
|
|
|
|
return DeclRelationSet(L) | DeclRelationSet(R);
|
|
|
|
}
|
|
|
|
inline DeclRelationSet operator&(DeclRelation L, DeclRelation R) {
|
|
|
|
return DeclRelationSet(L) & DeclRelationSet(R);
|
|
|
|
}
|
|
|
|
inline DeclRelationSet operator~(DeclRelation R) { return ~DeclRelationSet(R); }
|
|
|
|
llvm::raw_ostream &operator<<(llvm::raw_ostream &, DeclRelationSet);
|
|
|
|
|
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|
2019-09-25 20:54:53 +08:00
|
|
|
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_FINDTARGET_H
|