clang-tools  14.0.0git
SymbolCollector.cpp
Go to the documentation of this file.
1 //===--- SymbolCollector.cpp -------------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "SymbolCollector.h"
10 #include "AST.h"
11 #include "CanonicalIncludes.h"
12 #include "CodeComplete.h"
13 #include "CodeCompletionStrings.h"
14 #include "ExpectedTypes.h"
15 #include "SourceCode.h"
16 #include "SymbolLocation.h"
17 #include "URI.h"
18 #include "index/Relation.h"
19 #include "index/SymbolID.h"
20 #include "support/Logger.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclBase.h"
23 #include "clang/AST/DeclCXX.h"
24 #include "clang/AST/DeclObjC.h"
25 #include "clang/AST/DeclTemplate.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "clang/Basic/SourceManager.h"
28 #include "clang/Basic/Specifiers.h"
29 #include "clang/Index/IndexSymbol.h"
30 #include "clang/Index/IndexingAction.h"
31 #include "clang/Index/USRGeneration.h"
32 #include "clang/Lex/Preprocessor.h"
33 #include "clang/Tooling/Syntax/Tokens.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/FileSystem.h"
36 #include "llvm/Support/MemoryBuffer.h"
37 #include "llvm/Support/Path.h"
38 
39 namespace clang {
40 namespace clangd {
41 namespace {
42 
43 /// If \p ND is a template specialization, returns the described template.
44 /// Otherwise, returns \p ND.
45 const NamedDecl &getTemplateOrThis(const NamedDecl &ND) {
46  if (auto T = ND.getDescribedTemplate())
47  return *T;
48  return ND;
49 }
50 
51 // Checks whether the decl is a private symbol in a header generated by
52 // protobuf compiler.
53 // FIXME: make filtering extensible when there are more use cases for symbol
54 // filters.
55 bool isPrivateProtoDecl(const NamedDecl &ND) {
56  const auto &SM = ND.getASTContext().getSourceManager();
57  if (!isProtoFile(nameLocation(ND, SM), SM))
58  return false;
59 
60  // ND without identifier can be operators.
61  if (ND.getIdentifier() == nullptr)
62  return false;
63  auto Name = ND.getIdentifier()->getName();
64  if (!Name.contains('_'))
65  return false;
66  // Nested proto entities (e.g. Message::Nested) have top-level decls
67  // that shouldn't be used (Message_Nested). Ignore them completely.
68  // The nested entities are dangling type aliases, we may want to reconsider
69  // including them in the future.
70  // For enum constants, SOME_ENUM_CONSTANT is not private and should be
71  // indexed. Outer_INNER is private. This heuristic relies on naming style, it
72  // will include OUTER_INNER and exclude some_enum_constant.
73  // FIXME: the heuristic relies on naming style (i.e. no underscore in
74  // user-defined names) and can be improved.
75  return (ND.getKind() != Decl::EnumConstant) || llvm::any_of(Name, islower);
76 }
77 
78 // We only collect #include paths for symbols that are suitable for global code
79 // completion, except for namespaces since #include path for a namespace is hard
80 // to define.
81 bool shouldCollectIncludePath(index::SymbolKind Kind) {
82  using SK = index::SymbolKind;
83  switch (Kind) {
84  case SK::Macro:
85  case SK::Enum:
86  case SK::Struct:
87  case SK::Class:
88  case SK::Union:
89  case SK::TypeAlias:
90  case SK::Using:
91  case SK::Function:
92  case SK::Variable:
93  case SK::EnumConstant:
94  return true;
95  default:
96  return false;
97  }
98 }
99 
100 // Return the symbol range of the token at \p TokLoc.
101 std::pair<SymbolLocation::Position, SymbolLocation::Position>
102 getTokenRange(SourceLocation TokLoc, const SourceManager &SM,
103  const LangOptions &LangOpts) {
104  auto CreatePosition = [&SM](SourceLocation Loc) {
105  auto LSPLoc = sourceLocToPosition(SM, Loc);
106  SymbolLocation::Position Pos;
107  Pos.setLine(LSPLoc.line);
108  Pos.setColumn(LSPLoc.character);
109  return Pos;
110  };
111 
112  auto TokenLength = clang::Lexer::MeasureTokenLength(TokLoc, SM, LangOpts);
113  return {CreatePosition(TokLoc),
114  CreatePosition(TokLoc.getLocWithOffset(TokenLength))};
115 }
116 
117 // Checks whether \p ND is a good candidate to be the *canonical* declaration of
118 // its symbol (e.g. a go-to-declaration target). This overrides the default of
119 // using Clang's canonical declaration, which is the first in the TU.
120 //
121 // Example: preferring a class declaration over its forward declaration.
122 bool isPreferredDeclaration(const NamedDecl &ND, index::SymbolRoleSet Roles) {
123  const auto &SM = ND.getASTContext().getSourceManager();
124  if (isa<TagDecl>(ND))
125  return (Roles & static_cast<unsigned>(index::SymbolRole::Definition)) &&
126  !isInsideMainFile(ND.getLocation(), SM);
127  if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(&ND))
128  return ID->isThisDeclarationADefinition();
129  if (const auto *PD = dyn_cast<ObjCProtocolDecl>(&ND))
130  return PD->isThisDeclarationADefinition();
131  return false;
132 }
133 
134 RefKind toRefKind(index::SymbolRoleSet Roles, bool Spelled = false) {
135  RefKind Result = RefKind::Unknown;
136  if (Roles & static_cast<unsigned>(index::SymbolRole::Declaration))
137  Result |= RefKind::Declaration;
138  if (Roles & static_cast<unsigned>(index::SymbolRole::Definition))
139  Result |= RefKind::Definition;
140  if (Roles & static_cast<unsigned>(index::SymbolRole::Reference))
141  Result |= RefKind::Reference;
142  if (Spelled)
143  Result |= RefKind::Spelled;
144  return Result;
145 }
146 
147 llvm::Optional<RelationKind> indexableRelation(const index::SymbolRelation &R) {
148  if (R.Roles & static_cast<unsigned>(index::SymbolRole::RelationBaseOf))
149  return RelationKind::BaseOf;
150  if (R.Roles & static_cast<unsigned>(index::SymbolRole::RelationOverrideOf))
152  return None;
153 }
154 
155 // Given a ref contained in enclosing decl `Enclosing`, return
156 // the decl that should be used as that ref's Ref::Container. This is
157 // usually `Enclosing` itself, but in cases where `Enclosing` is not
158 // indexed, we walk further up because Ref::Container should always be
159 // an indexed symbol.
160 // Note: we don't use DeclContext as the container as in some cases
161 // it's useful to use a Decl which is not a DeclContext. For example,
162 // for a ref occurring in the initializer of a namespace-scope variable,
163 // it's useful to use that variable as the container, as otherwise the
164 // next enclosing DeclContext would be a NamespaceDecl or TranslationUnitDecl,
165 // which are both not indexed and less granular than we'd like for use cases
166 // like call hierarchy.
167 const Decl *getRefContainer(const Decl *Enclosing,
168  const SymbolCollector::Options &Opts) {
169  while (Enclosing) {
170  const auto *ND = dyn_cast<NamedDecl>(Enclosing);
171  if (ND && SymbolCollector::shouldCollectSymbol(*ND, ND->getASTContext(),
172  Opts, true)) {
173  break;
174  }
175  Enclosing = dyn_cast_or_null<Decl>(Enclosing->getDeclContext());
176  }
177  return Enclosing;
178 }
179 
180 } // namespace
181 
182 // Encapsulates decisions about how to record header paths in the index,
183 // including filename normalization, URI conversion etc.
184 // Expensive checks are cached internally.
186  // Weird double-indirect access to PP, which might not be ready yet when
187  // HeaderFiles is created but will be by the time it's used.
188  // (IndexDataConsumer::setPreprocessor can happen before or after initialize)
189  Preprocessor *&PP;
190  const SourceManager &SM;
191  const CanonicalIncludes *Includes;
192  llvm::StringRef FallbackDir;
193  llvm::DenseMap<const FileEntry *, const std::string *> CacheFEToURI;
194  llvm::StringMap<std::string> CachePathToURI;
195  llvm::DenseMap<FileID, llvm::StringRef> CacheFIDToInclude;
196 
197 public:
198  HeaderFileURICache(Preprocessor *&PP, const SourceManager &SM,
199  const SymbolCollector::Options &Opts)
200  : PP(PP), SM(SM), Includes(Opts.Includes), FallbackDir(Opts.FallbackDir) {
201  }
202 
203  // Returns a canonical URI for the file \p FE.
204  // We attempt to make the path absolute first.
205  const std::string &toURI(const FileEntry *FE) {
206  auto R = CacheFEToURI.try_emplace(FE);
207  if (R.second) {
208  auto CanonPath = getCanonicalPath(FE, SM);
209  R.first->second = &toURIInternal(CanonPath ? *CanonPath : FE->getName());
210  }
211  return *R.first->second;
212  }
213 
214  // Returns a canonical URI for \p Path.
215  // If the file is in the FileManager, use that to canonicalize the path.
216  // We attempt to make the path absolute in any case.
217  const std::string &toURI(llvm::StringRef Path) {
218  if (auto File = SM.getFileManager().getFile(Path))
219  return toURI(*File);
220  return toURIInternal(Path);
221  }
222 
223  // Gets a canonical include (URI of the header or <header> or "header") for
224  // header of \p FID (which should usually be the *expansion* file).
225  // This does not account for any per-symbol overrides!
226  // Returns "" if includes should not be inserted for this file.
227  llvm::StringRef getIncludeHeader(FileID FID) {
228  auto R = CacheFIDToInclude.try_emplace(FID);
229  if (R.second)
230  R.first->second = getIncludeHeaderUncached(FID);
231  return R.first->second;
232  }
233 
234 private:
235  // This takes care of making paths absolute and path->URI caching, but no
236  // FileManager-based canonicalization.
237  const std::string &toURIInternal(llvm::StringRef Path) {
238  auto R = CachePathToURI.try_emplace(Path);
239  if (R.second) {
240  llvm::SmallString<256> AbsPath = Path;
241  if (!llvm::sys::path::is_absolute(AbsPath) && !FallbackDir.empty())
242  llvm::sys::fs::make_absolute(FallbackDir, AbsPath);
243  assert(llvm::sys::path::is_absolute(AbsPath) &&
244  "If the VFS can't make paths absolute, a FallbackDir must be "
245  "provided");
246  llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
247  R.first->second = URI::create(AbsPath).toString();
248  }
249  return R.first->second;
250  }
251 
252  llvm::StringRef getIncludeHeaderUncached(FileID FID) {
253  const FileEntry *FE = SM.getFileEntryForID(FID);
254  if (!FE || FE->getName().empty())
255  return "";
256  llvm::StringRef Filename = FE->getName();
257  // If a file is mapped by canonical headers, use that mapping, regardless
258  // of whether it's an otherwise-good header (header guards etc).
259  if (Includes) {
260  llvm::StringRef Canonical = Includes->mapHeader(Filename);
261  if (!Canonical.empty()) {
262  // If we had a mapping, always use it.
263  if (Canonical.startswith("<") || Canonical.startswith("\""))
264  return Canonical;
265  return toURI(Canonical);
266  }
267  }
268  if (!isSelfContainedHeader(FE, FID, PP->getSourceManager(),
269  PP->getHeaderSearchInfo())) {
270  // A .inc or .def file is often included into a real header to define
271  // symbols (e.g. LLVM tablegen files).
272  if (Filename.endswith(".inc") || Filename.endswith(".def"))
273  // Don't use cache reentrantly due to iterator invalidation.
274  return getIncludeHeaderUncached(SM.getFileID(SM.getIncludeLoc(FID)));
275  // Conservatively refuse to insert #includes to files without guards.
276  return "";
277  }
278  // Standard case: just insert the file itself.
279  return toURI(FE);
280  }
281 };
282 
283 // Return the symbol location of the token at \p TokLoc.
284 llvm::Optional<SymbolLocation>
285 SymbolCollector::getTokenLocation(SourceLocation TokLoc) {
286  const auto &SM = ASTCtx->getSourceManager();
287  auto *FE = SM.getFileEntryForID(SM.getFileID(TokLoc));
288  if (!FE)
289  return None;
290 
291  SymbolLocation Result;
292  Result.FileURI = HeaderFileURIs->toURI(FE).c_str();
293  auto Range = getTokenRange(TokLoc, SM, ASTCtx->getLangOpts());
294  Result.Start = Range.first;
295  Result.End = Range.second;
296 
297  return Result;
298 }
299 
300 SymbolCollector::SymbolCollector(Options Opts) : Opts(std::move(Opts)) {}
302 
303 void SymbolCollector::initialize(ASTContext &Ctx) {
304  ASTCtx = &Ctx;
305  HeaderFileURIs = std::make_unique<HeaderFileURICache>(
306  this->PP, ASTCtx->getSourceManager(), Opts);
307  CompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
308  CompletionTUInfo =
309  std::make_unique<CodeCompletionTUInfo>(CompletionAllocator);
310 }
311 
312 bool SymbolCollector::shouldCollectSymbol(const NamedDecl &ND,
313  const ASTContext &ASTCtx,
314  const Options &Opts,
315  bool IsMainFileOnly) {
316  // Skip anonymous declarations, e.g (anonymous enum/class/struct).
317  if (ND.getDeclName().isEmpty())
318  return false;
319 
320  // Skip main-file symbols if we are not collecting them.
321  if (IsMainFileOnly && !Opts.CollectMainFileSymbols)
322  return false;
323 
324  // Skip symbols in anonymous namespaces in header files.
325  if (!IsMainFileOnly && ND.isInAnonymousNamespace())
326  return false;
327 
328  // For function local symbols, index only classes and its member functions.
329  if (index::isFunctionLocalSymbol(&ND))
330  return isa<RecordDecl>(ND) ||
331  (ND.isCXXInstanceMember() && ND.isFunctionOrFunctionTemplate());
332 
333  // We want most things but not "local" symbols such as symbols inside
334  // FunctionDecl, BlockDecl, ObjCMethodDecl and OMPDeclareReductionDecl.
335  // FIXME: Need a matcher for ExportDecl in order to include symbols declared
336  // within an export.
337  const auto *DeclCtx = ND.getDeclContext();
338  switch (DeclCtx->getDeclKind()) {
339  case Decl::TranslationUnit:
340  case Decl::Namespace:
341  case Decl::LinkageSpec:
342  case Decl::Enum:
343  case Decl::ObjCProtocol:
344  case Decl::ObjCInterface:
345  case Decl::ObjCCategory:
346  case Decl::ObjCCategoryImpl:
347  case Decl::ObjCImplementation:
348  break;
349  default:
350  // Record has a few derivations (e.g. CXXRecord, Class specialization), it's
351  // easier to cast.
352  if (!isa<RecordDecl>(DeclCtx))
353  return false;
354  }
355 
356  // Avoid indexing internal symbols in protobuf generated headers.
357  if (isPrivateProtoDecl(ND))
358  return false;
359  if (!Opts.CollectReserved &&
360  (hasReservedName(ND) || hasReservedScope(*ND.getDeclContext())))
361  return false;
362 
363  return true;
364 }
365 
366 // Always return true to continue indexing.
368  const Decl *D, index::SymbolRoleSet Roles,
369  llvm::ArrayRef<index::SymbolRelation> Relations, SourceLocation Loc,
370  index::IndexDataConsumer::ASTNodeInfo ASTNode) {
371  assert(ASTCtx && PP && HeaderFileURIs);
372  assert(CompletionAllocator && CompletionTUInfo);
373  assert(ASTNode.OrigD);
374  // Indexing API puts canonical decl into D, which might not have a valid
375  // source location for implicit/built-in decls. Fallback to original decl in
376  // such cases.
377  if (D->getLocation().isInvalid())
378  D = ASTNode.OrigD;
379  // If OrigD is an declaration associated with a friend declaration and it's
380  // not a definition, skip it. Note that OrigD is the occurrence that the
381  // collector is currently visiting.
382  if ((ASTNode.OrigD->getFriendObjectKind() !=
383  Decl::FriendObjectKind::FOK_None) &&
384  !(Roles & static_cast<unsigned>(index::SymbolRole::Definition)))
385  return true;
386  // A declaration created for a friend declaration should not be used as the
387  // canonical declaration in the index. Use OrigD instead, unless we've already
388  // picked a replacement for D
389  if (D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None)
390  D = CanonicalDecls.try_emplace(D, ASTNode.OrigD).first->second;
391  // Flag to mark that D should be considered canonical meaning its declaration
392  // will override any previous declaration for the Symbol.
393  bool DeclIsCanonical = false;
394  // Avoid treating ObjCImplementationDecl as a canonical declaration if it has
395  // a corresponding non-implicit and non-forward declared ObjcInterfaceDecl.
396  if (const auto *IID = dyn_cast<ObjCImplementationDecl>(D)) {
397  DeclIsCanonical = true;
398  if (const auto *CID = IID->getClassInterface())
399  if (const auto *DD = CID->getDefinition())
400  if (!DD->isImplicitInterfaceDecl())
401  D = DD;
402  }
403  // Avoid treating ObjCCategoryImplDecl as a canonical declaration in favor of
404  // its ObjCCategoryDecl if it has one.
405  if (const auto *CID = dyn_cast<ObjCCategoryImplDecl>(D)) {
406  DeclIsCanonical = true;
407  if (const auto *CD = CID->getCategoryDecl())
408  D = CD;
409  }
410  const NamedDecl *ND = dyn_cast<NamedDecl>(D);
411  if (!ND)
412  return true;
413 
414  // Mark D as referenced if this is a reference coming from the main file.
415  // D may not be an interesting symbol, but it's cheaper to check at the end.
416  auto &SM = ASTCtx->getSourceManager();
417  if (Opts.CountReferences &&
418  (Roles & static_cast<unsigned>(index::SymbolRole::Reference)) &&
419  SM.getFileID(SM.getSpellingLoc(Loc)) == SM.getMainFileID())
420  ReferencedDecls.insert(ND);
421 
422  auto ID = getSymbolID(ND);
423  if (!ID)
424  return true;
425 
426  // ND is the canonical (i.e. first) declaration. If it's in the main file
427  // (which is not a header), then no public declaration was visible, so assume
428  // it's main-file only.
429  bool IsMainFileOnly =
430  SM.isWrittenInMainFile(SM.getExpansionLoc(ND->getBeginLoc())) &&
431  !isHeaderFile(SM.getFileEntryForID(SM.getMainFileID())->getName(),
432  ASTCtx->getLangOpts());
433  // In C, printf is a redecl of an implicit builtin! So check OrigD instead.
434  if (ASTNode.OrigD->isImplicit() ||
435  !shouldCollectSymbol(*ND, *ASTCtx, Opts, IsMainFileOnly))
436  return true;
437 
438  // Note: we need to process relations for all decl occurrences, including
439  // refs, because the indexing code only populates relations for specific
440  // occurrences. For example, RelationBaseOf is only populated for the
441  // occurrence inside the base-specifier.
442  processRelations(*ND, ID, Relations);
443 
444  bool CollectRef = static_cast<bool>(Opts.RefFilter & toRefKind(Roles));
445  bool IsOnlyRef =
446  !(Roles & (static_cast<unsigned>(index::SymbolRole::Declaration) |
447  static_cast<unsigned>(index::SymbolRole::Definition)));
448 
449  if (IsOnlyRef && !CollectRef)
450  return true;
451 
452  // Unlike other fields, e.g. Symbols (which use spelling locations), we use
453  // file locations for references (as it aligns the behavior of clangd's
454  // AST-based xref).
455  // FIXME: we should try to use the file locations for other fields.
456  if (CollectRef &&
457  (!IsMainFileOnly || Opts.CollectMainFileRefs ||
458  ND->isExternallyVisible()) &&
459  !isa<NamespaceDecl>(ND) &&
460  (Opts.RefsInHeaders ||
461  SM.getFileID(SM.getFileLoc(Loc)) == SM.getMainFileID()))
462  DeclRefs[ND].push_back(SymbolRef{SM.getFileLoc(Loc), Roles,
463  getRefContainer(ASTNode.Parent, Opts)});
464  // Don't continue indexing if this is a mere reference.
465  if (IsOnlyRef)
466  return true;
467 
468  // FIXME: ObjCPropertyDecl are not properly indexed here:
469  // - ObjCPropertyDecl may have an OrigD of ObjCPropertyImplDecl, which is
470  // not a NamedDecl.
471  auto *OriginalDecl = dyn_cast<NamedDecl>(ASTNode.OrigD);
472  if (!OriginalDecl)
473  return true;
474 
475  const Symbol *BasicSymbol = Symbols.find(ID);
476  if (isPreferredDeclaration(*OriginalDecl, Roles))
477  // If OriginalDecl is preferred, replace/create the existing canonical
478  // declaration (e.g. a class forward declaration). There should be at most
479  // one duplicate as we expect to see only one preferred declaration per
480  // TU, because in practice they are definitions.
481  BasicSymbol = addDeclaration(*OriginalDecl, std::move(ID), IsMainFileOnly);
482  else if (!BasicSymbol || DeclIsCanonical)
483  BasicSymbol = addDeclaration(*ND, std::move(ID), IsMainFileOnly);
484 
485  if (Roles & static_cast<unsigned>(index::SymbolRole::Definition))
486  addDefinition(*OriginalDecl, *BasicSymbol);
487 
488  return true;
489 }
490 
491 void SymbolCollector::handleMacros(const MainFileMacros &MacroRefsToIndex) {
492  assert(HeaderFileURIs && PP);
493  const auto &SM = PP->getSourceManager();
494  const auto *MainFileEntry = SM.getFileEntryForID(SM.getMainFileID());
495  assert(MainFileEntry);
496 
497  const std::string &MainFileURI = HeaderFileURIs->toURI(MainFileEntry);
498  // Add macro references.
499  for (const auto &IDToRefs : MacroRefsToIndex.MacroRefs) {
500  for (const auto &MacroRef : IDToRefs.second) {
501  const auto &Range = MacroRef.Rng;
502  bool IsDefinition = MacroRef.IsDefinition;
503  Ref R;
508  R.Location.FileURI = MainFileURI.c_str();
509  R.Kind = IsDefinition ? RefKind::Definition : RefKind::Reference;
510  Refs.insert(IDToRefs.first, R);
511  if (IsDefinition) {
512  Symbol S;
513  S.ID = IDToRefs.first;
514  auto StartLoc = cantFail(sourceLocationInMainFile(SM, Range.start));
515  auto EndLoc = cantFail(sourceLocationInMainFile(SM, Range.end));
516  S.Name = toSourceCode(SM, SourceRange(StartLoc, EndLoc));
517  S.SymInfo.Kind = index::SymbolKind::Macro;
518  S.SymInfo.SubKind = index::SymbolSubKind::None;
519  S.SymInfo.Properties = index::SymbolPropertySet();
521  S.Origin = Opts.Origin;
523  // Make the macro visible for code completion if main file is an
524  // include-able header.
525  if (!HeaderFileURIs->getIncludeHeader(SM.getMainFileID()).empty()) {
528  }
529  Symbols.insert(S);
530  }
531  }
532  }
533 }
534 
535 bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name,
536  const MacroInfo *MI,
537  index::SymbolRoleSet Roles,
538  SourceLocation Loc) {
539  assert(PP);
540  // Builtin macros don't have useful locations and aren't needed in completion.
541  if (MI->isBuiltinMacro())
542  return true;
543 
544  const auto &SM = PP->getSourceManager();
545  auto DefLoc = MI->getDefinitionLoc();
546  // Also avoid storing predefined macros like __DBL_MIN__.
547  if (SM.isWrittenInBuiltinFile(DefLoc) ||
548  Name->getName() == "__GCC_HAVE_DWARF2_CFI_ASM")
549  return true;
550 
551  auto ID = getSymbolID(Name->getName(), MI, SM);
552  if (!ID)
553  return true;
554 
555  auto SpellingLoc = SM.getSpellingLoc(Loc);
556  bool IsMainFileOnly =
557  SM.isInMainFile(SM.getExpansionLoc(DefLoc)) &&
558  !isHeaderFile(SM.getFileEntryForID(SM.getMainFileID())->getName(),
559  ASTCtx->getLangOpts());
560  // Do not store references to main-file macros.
561  if ((static_cast<unsigned>(Opts.RefFilter) & Roles) && !IsMainFileOnly &&
562  (Opts.RefsInHeaders || SM.getFileID(SpellingLoc) == SM.getMainFileID()))
563  // FIXME: Populate container information for macro references.
564  MacroRefs[ID].push_back({Loc, Roles, /*Container=*/nullptr});
565 
566  // Collect symbols.
567  if (!Opts.CollectMacro)
568  return true;
569 
570  // Skip main-file macros if we are not collecting them.
571  if (IsMainFileOnly && !Opts.CollectMainFileSymbols)
572  return false;
573 
574  // Mark the macro as referenced if this is a reference coming from the main
575  // file. The macro may not be an interesting symbol, but it's cheaper to check
576  // at the end.
577  if (Opts.CountReferences &&
578  (Roles & static_cast<unsigned>(index::SymbolRole::Reference)) &&
579  SM.getFileID(SpellingLoc) == SM.getMainFileID())
580  ReferencedMacros.insert(Name);
581 
582  // Don't continue indexing if this is a mere reference.
583  // FIXME: remove macro with ID if it is undefined.
584  if (!(Roles & static_cast<unsigned>(index::SymbolRole::Declaration) ||
585  Roles & static_cast<unsigned>(index::SymbolRole::Definition)))
586  return true;
587 
588  // Only collect one instance in case there are multiple.
589  if (Symbols.find(ID) != nullptr)
590  return true;
591 
592  Symbol S;
593  S.ID = std::move(ID);
594  S.Name = Name->getName();
595  if (!IsMainFileOnly) {
598  }
599  S.SymInfo = index::getSymbolInfoForMacro(*MI);
600  S.Origin = Opts.Origin;
601  // FIXME: use the result to filter out symbols.
602  shouldIndexFile(SM.getFileID(Loc));
603  if (auto DeclLoc = getTokenLocation(DefLoc))
604  S.CanonicalDeclaration = *DeclLoc;
605 
606  CodeCompletionResult SymbolCompletion(Name);
607  const auto *CCS = SymbolCompletion.CreateCodeCompletionStringForMacro(
608  *PP, *CompletionAllocator, *CompletionTUInfo);
609  std::string Signature;
610  std::string SnippetSuffix;
612  S.Signature = Signature;
614 
615  IndexedMacros.insert(Name);
616  setIncludeLocation(S, DefLoc);
617  Symbols.insert(S);
618  return true;
619 }
620 
621 void SymbolCollector::processRelations(
622  const NamedDecl &ND, const SymbolID &ID,
623  ArrayRef<index::SymbolRelation> Relations) {
624  for (const auto &R : Relations) {
625  auto RKind = indexableRelation(R);
626  if (!RKind)
627  continue;
628  const Decl *Object = R.RelatedSymbol;
629 
630  auto ObjectID = getSymbolID(Object);
631  if (!ObjectID)
632  continue;
633 
634  // Record the relation.
635  // TODO: There may be cases where the object decl is not indexed for some
636  // reason. Those cases should probably be removed in due course, but for
637  // now there are two possible ways to handle it:
638  // (A) Avoid storing the relation in such cases.
639  // (B) Store it anyways. Clients will likely lookup() the SymbolID
640  // in the index and find nothing, but that's a situation they
641  // probably need to handle for other reasons anyways.
642  // We currently do (B) because it's simpler.
643  if (*RKind == RelationKind::BaseOf)
644  this->Relations.insert({ID, *RKind, ObjectID});
645  else if (*RKind == RelationKind::OverriddenBy)
646  this->Relations.insert({ObjectID, *RKind, ID});
647  }
648 }
649 
650 void SymbolCollector::setIncludeLocation(const Symbol &S, SourceLocation Loc) {
651  if (Opts.CollectIncludePath)
652  if (shouldCollectIncludePath(S.SymInfo.Kind))
653  // Use the expansion location to get the #include header since this is
654  // where the symbol is exposed.
655  IncludeFiles[S.ID] =
656  PP->getSourceManager().getDecomposedExpansionLoc(Loc).first;
657 }
658 
660  // At the end of the TU, add 1 to the refcount of all referenced symbols.
661  auto IncRef = [this](const SymbolID &ID) {
662  if (const auto *S = Symbols.find(ID)) {
663  Symbol Inc = *S;
664  ++Inc.References;
665  Symbols.insert(Inc);
666  }
667  };
668  for (const NamedDecl *ND : ReferencedDecls) {
669  if (auto ID = getSymbolID(ND)) {
670  IncRef(ID);
671  }
672  }
673  if (Opts.CollectMacro) {
674  assert(PP);
675  // First, drop header guards. We can't identify these until EOF.
676  for (const IdentifierInfo *II : IndexedMacros) {
677  if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo())
678  if (auto ID = getSymbolID(II->getName(), MI, PP->getSourceManager()))
679  if (MI->isUsedForHeaderGuard())
680  Symbols.erase(ID);
681  }
682  // Now increment refcounts.
683  for (const IdentifierInfo *II : ReferencedMacros) {
684  if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo())
685  if (auto ID = getSymbolID(II->getName(), MI, PP->getSourceManager()))
686  IncRef(ID);
687  }
688  }
689  // Fill in IncludeHeaders.
690  // We delay this until end of TU so header guards are all resolved.
691  llvm::SmallString<128> QName;
692  for (const auto &Entry : IncludeFiles) {
693  if (const Symbol *S = Symbols.find(Entry.first)) {
694  llvm::StringRef IncludeHeader;
695  // Look for an overridden include header for this symbol specifically.
696  if (Opts.Includes) {
697  QName = S->Scope;
698  QName.append(S->Name);
699  IncludeHeader = Opts.Includes->mapSymbol(QName);
700  if (!IncludeHeader.empty()) {
701  if (IncludeHeader.front() != '"' && IncludeHeader.front() != '<')
702  IncludeHeader = HeaderFileURIs->toURI(IncludeHeader);
703  else if (IncludeHeader == "<utility>" && QName == "std::move" &&
704  S->Signature.contains(','))
705  IncludeHeader = "<algorithm>";
706  }
707  }
708  // Otherwise find the approprate include header for the defining file.
709  if (IncludeHeader.empty())
710  IncludeHeader = HeaderFileURIs->getIncludeHeader(Entry.second);
711 
712  // Symbols in slabs aren't mutable, insert() has to walk all the strings
713  if (!IncludeHeader.empty()) {
714  Symbol NewSym = *S;
715  NewSym.IncludeHeaders.push_back({IncludeHeader, 1});
716  Symbols.insert(NewSym);
717  }
718  }
719  }
720 
721  const auto &SM = ASTCtx->getSourceManager();
722  auto CollectRef = [&](SymbolID ID, const SymbolRef &LocAndRole,
723  bool Spelled = false) {
724  auto FileID = SM.getFileID(LocAndRole.Loc);
725  // FIXME: use the result to filter out references.
726  shouldIndexFile(FileID);
727  if (const auto *FE = SM.getFileEntryForID(FileID)) {
728  auto Range = getTokenRange(LocAndRole.Loc, SM, ASTCtx->getLangOpts());
729  Ref R;
730  R.Location.Start = Range.first;
731  R.Location.End = Range.second;
732  R.Location.FileURI = HeaderFileURIs->toURI(FE).c_str();
733  R.Kind = toRefKind(LocAndRole.Roles, Spelled);
734  R.Container = getSymbolID(LocAndRole.Container);
735  Refs.insert(ID, R);
736  }
737  };
738  // Populate Refs slab from MacroRefs.
739  // FIXME: All MacroRefs are marked as Spelled now, but this should be checked.
740  for (const auto &IDAndRefs : MacroRefs)
741  for (const auto &LocAndRole : IDAndRefs.second)
742  CollectRef(IDAndRefs.first, LocAndRole, /*Spelled=*/true);
743  // Populate Refs slab from DeclRefs.
744  llvm::DenseMap<FileID, std::vector<syntax::Token>> FilesToTokensCache;
745  for (auto &DeclAndRef : DeclRefs) {
746  if (auto ID = getSymbolID(DeclAndRef.first)) {
747  for (auto &LocAndRole : DeclAndRef.second) {
748  const auto FileID = SM.getFileID(LocAndRole.Loc);
749  // FIXME: It's better to use TokenBuffer by passing spelled tokens from
750  // the caller of SymbolCollector.
751  if (!FilesToTokensCache.count(FileID))
752  FilesToTokensCache[FileID] =
753  syntax::tokenize(FileID, SM, ASTCtx->getLangOpts());
754  llvm::ArrayRef<syntax::Token> Tokens = FilesToTokensCache[FileID];
755  // Check if the referenced symbol is spelled exactly the same way the
756  // corresponding NamedDecl is. If it is, mark this reference as spelled.
757  const auto *IdentifierToken =
758  spelledIdentifierTouching(LocAndRole.Loc, Tokens);
759  DeclarationName Name = DeclAndRef.first->getDeclName();
760  const auto NameKind = Name.getNameKind();
761  bool IsTargetKind = NameKind == DeclarationName::Identifier ||
762  NameKind == DeclarationName::CXXConstructorName;
763  bool Spelled = IdentifierToken && IsTargetKind &&
764  Name.getAsString() == IdentifierToken->text(SM);
765  CollectRef(ID, LocAndRole, Spelled);
766  }
767  }
768  }
769 
770  ReferencedDecls.clear();
771  ReferencedMacros.clear();
772  DeclRefs.clear();
773  IncludeFiles.clear();
774 }
775 
776 const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID,
777  bool IsMainFileOnly) {
778  auto &Ctx = ND.getASTContext();
779  auto &SM = Ctx.getSourceManager();
780 
781  Symbol S;
782  S.ID = std::move(ID);
783  std::string QName = printQualifiedName(ND);
784  // FIXME: this returns foo:bar: for objective-C methods, we prefer only foo:
785  // for consistency with CodeCompletionString and a clean name/signature split.
786  std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
787  std::string TemplateSpecializationArgs = printTemplateSpecializationArgs(ND);
788  S.TemplateSpecializationArgs = TemplateSpecializationArgs;
789 
790  // We collect main-file symbols, but do not use them for code completion.
791  if (!IsMainFileOnly && isIndexedForCodeCompletion(ND, Ctx))
793  if (isImplementationDetail(&ND))
795  if (!IsMainFileOnly)
797  S.SymInfo = index::getSymbolInfo(&ND);
798  auto Loc = nameLocation(ND, SM);
799  assert(Loc.isValid() && "Invalid source location for NamedDecl");
800  // FIXME: use the result to filter out symbols.
801  shouldIndexFile(SM.getFileID(Loc));
802  if (auto DeclLoc = getTokenLocation(Loc))
803  S.CanonicalDeclaration = *DeclLoc;
804 
805  S.Origin = Opts.Origin;
806  if (ND.getAvailability() == AR_Deprecated)
808 
809  // Add completion info.
810  // FIXME: we may want to choose a different redecl, or combine from several.
811  assert(ASTCtx && PP && "ASTContext and Preprocessor must be set.");
812  // We use the primary template, as clang does during code completion.
813  CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
814  const auto *CCS = SymbolCompletion.CreateCodeCompletionString(
815  *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
816  *CompletionTUInfo,
817  /*IncludeBriefComments*/ false);
818  std::string Documentation =
819  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
820  /*CommentsFromHeaders=*/true));
822  if (Opts.StoreAllDocumentation)
823  S.Documentation = Documentation;
824  Symbols.insert(S);
825  return Symbols.find(S.ID);
826  }
827  S.Documentation = Documentation;
828  std::string Signature;
829  std::string SnippetSuffix;
831  S.Signature = Signature;
833  std::string ReturnType = getReturnType(*CCS);
835 
836  llvm::Optional<OpaqueType> TypeStorage;
838  TypeStorage = OpaqueType::fromCompletionResult(*ASTCtx, SymbolCompletion);
839  if (TypeStorage)
840  S.Type = TypeStorage->raw();
841  }
842 
843  Symbols.insert(S);
844  setIncludeLocation(S, ND.getLocation());
845  return Symbols.find(S.ID);
846 }
847 
848 void SymbolCollector::addDefinition(const NamedDecl &ND,
849  const Symbol &DeclSym) {
850  if (DeclSym.Definition)
851  return;
852  // If we saw some forward declaration, we end up copying the symbol.
853  // This is not ideal, but avoids duplicating the "is this a definition" check
854  // in clang::index. We should only see one definition.
855  Symbol S = DeclSym;
856  const auto &SM = ND.getASTContext().getSourceManager();
857  auto Loc = nameLocation(ND, SM);
858  // FIXME: use the result to filter out symbols.
859  shouldIndexFile(SM.getFileID(Loc));
860  if (auto DefLoc = getTokenLocation(Loc))
861  S.Definition = *DefLoc;
862  Symbols.insert(S);
863 }
864 
866  if (!Opts.FileFilter)
867  return true;
868  auto I = FilesToIndexCache.try_emplace(FID);
869  if (I.second)
870  I.first->second = Opts.FileFilter(ASTCtx->getSourceManager(), FID);
871  return I.first->second;
872 }
873 
874 } // namespace clangd
875 } // namespace clang
clang::clangd::Ref::Kind
RefKind Kind
Definition: Ref.h:90
clang::clangd::Symbol::IndexedForCodeCompletion
@ IndexedForCodeCompletion
Whether or not this symbol is meant to be used for the code completion.
Definition: Symbol.h:119
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
SymbolID.h
clang::clangd::RelationKind::BaseOf
@ BaseOf
clang::clangd::SymbolCollector::HeaderFileURICache::toURI
const std::string & toURI(llvm::StringRef Path)
Definition: SymbolCollector.cpp:217
clang::clangd::SymbolLocation::End
Position End
Definition: SymbolLocation.h:54
CodeComplete.h
clang::clangd::Symbol::ID
SymbolID ID
The ID of the symbol.
Definition: Symbol.h:38
clang::clangd::RefKind::Unknown
@ Unknown
clang::clangd::SymbolCollector::handleMacros
void handleMacros(const MainFileMacros &MacroRefsToIndex)
Definition: SymbolCollector.cpp:491
clang::clangd::RefKind::Declaration
@ Declaration
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:26
clang::clangd::SymbolCollector::HeaderFileURICache::getIncludeHeader
llvm::StringRef getIncludeHeader(FileID FID)
Definition: SymbolCollector.cpp:227
SymbolLocation.h
clang::clangd::SymbolCollector::shouldCollectSymbol
static bool shouldCollectSymbol(const NamedDecl &ND, const ASTContext &ASTCtx, const Options &Opts, bool IsMainFileSymbol)
Returns true is ND should be collected.
Definition: SymbolCollector.cpp:312
clang::clangd::SymbolCollector::handleDeclOccurrence
bool handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef< index::SymbolRelation > Relations, SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override
Definition: SymbolCollector.cpp:367
clang::clangd::SymbolKind::Object
@ Object
clang::clangd::splitQualifiedName
std::pair< StringRef, StringRef > splitQualifiedName(StringRef QName)
Definition: SourceCode.cpp:492
clang::clangd::RefKind
RefKind
Describes the kind of a cross-reference.
Definition: Ref.h:30
clang::clangd::SymbolSlab::Builder::erase
void erase(const SymbolID &ID)
Removes the symbol with an ID, if it exists.
Definition: Symbol.h:209
clang::clangd::SymbolSlab::Builder::find
const Symbol * find(const SymbolID &ID)
Returns the symbol with an ID, if it exists. Valid until insert/remove.
Definition: Symbol.h:212
clang::clangd::URI::create
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
Definition: URI.cpp:211
clang::clangd::OpaqueType::fromCompletionResult
static llvm::Optional< OpaqueType > fromCompletionResult(ASTContext &Ctx, const CodeCompletionResult &R)
Create a type from a code completion result.
Definition: ExpectedTypes.cpp:87
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:59
clang::clangd::SymbolLocation::Start
Position Start
The symbol range, using half-open range [Start, End).
Definition: SymbolLocation.h:53
Filename
std::string Filename
Filename as a string.
Definition: IncludeOrderCheck.cpp:39
clang::clangd::Symbol::Deprecated
@ Deprecated
Indicates if the symbol is deprecated.
Definition: Symbol.h:121
clang::clangd::Range::start
Position start
The range's start position.
Definition: Protocol.h:184
clang::clangd::SymbolCollector::shouldIndexFile
bool shouldIndexFile(FileID FID)
Returns true if we are interested in references and declarations from FID.
Definition: SymbolCollector.cpp:865
Ctx
Context Ctx
Definition: TUScheduler.cpp:460
clang::clangd::Symbol::VisibleOutsideFile
@ VisibleOutsideFile
Symbol is visible to other files (not e.g. a static helper function).
Definition: Symbol.h:125
clang::clangd::MainFileMacros::MacroRefs
llvm::DenseMap< SymbolID, std::vector< MacroOccurrence > > MacroRefs
Definition: CollectMacros.h:33
clang::clangd::SymbolCollector::finish
void finish() override
Definition: SymbolCollector.cpp:659
clang::clangd::nameLocation
SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM)
Find the source location of the identifier for D.
Definition: AST.cpp:167
clang::clangd::sourceLocToPosition
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
Definition: SourceCode.cpp:217
clang::clangd::SymbolCollector::HeaderFileURICache
Definition: SymbolCollector.cpp:185
clang::clangd::getDocComment
std::string getDocComment(const ASTContext &Ctx, const CodeCompletionResult &Result, bool CommentsFromHeaders)
Gets a minimally formatted documentation comment of Result, with comment markers stripped.
Definition: CodeCompletionStrings.cpp:62
clang::clangd::Position::line
int line
Line position in a document (zero-based).
Definition: Protocol.h:155
run-clang-tidy.make_absolute
def make_absolute(f, directory)
Definition: run-clang-tidy.py:76
clang::clangd::Symbol::References
unsigned References
The number of translation units that reference this symbol from their main file.
Definition: Symbol.h:59
clang::clangd::isSelfContainedHeader
bool isSelfContainedHeader(const FileEntry *FE, FileID FID, const SourceManager &SM, HeaderSearch &HeaderInfo)
This scans source code, and should not be called when using a preamble.
Definition: SourceCode.cpp:1226
clang::clangd::formatDocumentation
std::string formatDocumentation(const CodeCompletionString &CCS, llvm::StringRef DocComment)
Assembles formatted documentation for a completion result.
Definition: CodeCompletionStrings.cpp:242
Relation.h
clang::clangd::Symbol::ReturnType
llvm::StringRef ReturnType
Type when this symbol is used in an expression.
Definition: Symbol.h:80
CanonicalIncludes.h
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
clang::clangd::SymbolCollector::HeaderFileURICache::toURI
const std::string & toURI(const FileEntry *FE)
Definition: SymbolCollector.cpp:205
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
CodeCompletionStrings.h
clang::clangd::getCanonicalPath
llvm::Optional< std::string > getCanonicalPath(const FileEntry *F, const SourceManager &SourceMgr)
Get the canonical path of F.
Definition: SourceCode.cpp:515
clang::clangd::Ref::Container
SymbolID Container
The ID of the symbol whose definition contains this reference.
Definition: Ref.h:94
clang::clangd::CanonicalIncludes
Maps a definition location onto an #include file, based on a set of filename rules.
Definition: CanonicalIncludes.h:36
clang::clangd::Ref::Location
SymbolLocation Location
The source location where the symbol is named.
Definition: Ref.h:89
clang::clangd::printQualifiedName
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:174
clang::clangd::Symbol::Origin
SymbolOrigin Origin
Where this symbol came from. Usually an index provides a constant value.
Definition: Symbol.h:61
clang::clangd::Symbol::ImplementationDetail
@ ImplementationDetail
Symbol is an implementation detail.
Definition: Symbol.h:123
Logger.h
clang::clangd::getSymbolInfo
std::vector< SymbolDetails > getSymbolInfo(ParsedAST &AST, Position Pos)
Get info about symbols at Pos.
Definition: XRefs.cpp:1515
clang::clangd::MainFileMacros
Definition: CollectMacros.h:31
clang::clangd::Symbol
The class presents a C++ symbol, e.g.
Definition: Symbol.h:36
clang::clangd::Symbol::Flags
SymbolFlag Flags
Definition: Symbol.h:128
clang::clangd::Symbol::SymInfo
index::SymbolInfo SymInfo
The symbol information, like symbol kind.
Definition: Symbol.h:40
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
clang::clangd::printTemplateSpecializationArgs
std::string printTemplateSpecializationArgs(const NamedDecl &ND)
Prints template arguments of a decl as written in the source code, including enclosing '<' and '>',...
Definition: AST.cpp:254
clang::clangd::SymbolLocation::FileURI
const char * FileURI
Definition: SymbolLocation.h:64
ExpectedTypes.h
clang::clangd::SymbolLocation::Position::setColumn
void setColumn(uint32_t Column)
Definition: SymbolLocation.cpp:22
SnippetSuffix
std::string SnippetSuffix
Definition: CodeComplete.cpp:447
clang::clangd::Position::character
int character
Character offset on a line in a document (zero-based).
Definition: Protocol.h:160
clang::clangd::hasReservedScope
bool hasReservedScope(const DeclContext &DC)
Returns true if this scope would be written with a reserved name.
Definition: AST.cpp:386
clang::clangd::RefKind::Reference
@ Reference
clang::clangd::RefSlab::Builder::insert
void insert(const SymbolID &ID, const Ref &S)
Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
Definition: Ref.cpp:36
clang::clangd::Range::end
Position end
The range's end position.
Definition: Protocol.h:187
clang::clangd::Symbol::Name
llvm::StringRef Name
The unqualified name of the symbol, e.g. "bar" (for ns::bar).
Definition: Symbol.h:42
clang::clangd::isIndexedForCodeCompletion
bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx)
Definition: CodeComplete.cpp:2065
SymbolKind
clang::find_all_symbols::SymbolInfo::SymbolKind SymbolKind
Definition: SymbolInfo.cpp:19
clang::clangd::Symbol::CanonicalDeclaration
SymbolLocation CanonicalDeclaration
The location of the preferred declaration of the symbol.
Definition: Symbol.h:56
clang::clangd::isProtoFile
bool isProtoFile(SourceLocation Loc, const SourceManager &SM)
Returns true if the given location is in a generated protobuf file.
Definition: SourceCode.cpp:1174
Entry
Definition: Modularize.cpp:428
clang::clangd::getSymbolID
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Definition: AST.cpp:337
SourceCode.h
clang::clangd::Symbol::CompletionSnippetSuffix
llvm::StringRef CompletionSnippetSuffix
What to insert when completing this symbol, after the symbol name.
Definition: Symbol.h:74
clang::clangd::SymbolCollector::handleMacroOccurrence
bool handleMacroOccurrence(const IdentifierInfo *Name, const MacroInfo *MI, index::SymbolRoleSet Roles, SourceLocation Loc) override
Definition: SymbolCollector.cpp:535
clang::clangd::isHeaderFile
bool isHeaderFile(llvm::StringRef FileName, llvm::Optional< LangOptions > LangOpts)
Infers whether this is a header from the FileName and LangOpts (if presents).
Definition: SourceCode.cpp:1162
clang::clangd::RefKind::Spelled
@ Spelled
ID
static char ID
Definition: Logger.cpp:74
clang::clangd::Ref
Represents a symbol occurrence in the source file.
Definition: Ref.h:87
clang::clangd::getSignature
void getSignature(const CodeCompletionString &CCS, std::string *Signature, std::string *Snippet, std::string *RequiredQualifiers, bool CompletingPattern)
Formats the signature for an item, as a display string and snippet.
Definition: CodeCompletionStrings.cpp:98
clang::clangd::SymbolCollector::initialize
void initialize(ASTContext &Ctx) override
Definition: SymbolCollector.cpp:303
clang::clangd::Symbol::TemplateSpecializationArgs
llvm::StringRef TemplateSpecializationArgs
Argument list in human-readable format, will be displayed to help disambiguate between different spec...
Definition: Symbol.h:69
clang::tidy::bugprone::model::MixFlags::None
@ None
Mix between the two parameters is not possible.
clang::clangd::Range
Definition: Protocol.h:182
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang::clangd::SymbolLocation::Position::setLine
void setLine(uint32_t Line)
Definition: SymbolLocation.cpp:17
clang::clangd::Symbol::Scope
llvm::StringRef Scope
The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
Definition: Symbol.h:44
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::isInsideMainFile
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
Definition: SourceCode.cpp:418
clang::clangd::SymbolCollector::Options
Definition: SymbolCollector.h:48
SymbolCollector.h
clang::clangd::SymbolCollector::HeaderFileURICache::HeaderFileURICache
HeaderFileURICache(Preprocessor *&PP, const SourceManager &SM, const SymbolCollector::Options &Opts)
Definition: SymbolCollector.cpp:198
clang::clangd::getReturnType
std::string getReturnType(const CodeCompletionString &CCS)
Gets detail to be used as the detail field in an LSP completion item.
Definition: CodeCompletionStrings.cpp:272
clang::clangd::hasReservedName
bool hasReservedName(const Decl &D)
Returns true if this is a NamedDecl with a reserved name.
Definition: AST.cpp:379
clang::clangd::isImplementationDetail
bool isImplementationDetail(const Decl *D)
Returns true if the declaration is considered implementation detail based on heuristics.
Definition: AST.cpp:162
ReturnType
std::string ReturnType
Definition: CodeComplete.cpp:449
Pos
Position Pos
Definition: SourceCode.cpp:658
URI.h
clang::clangd::SymbolID
Definition: SymbolID.h:32
clang::clangd::Symbol::Signature
llvm::StringRef Signature
A brief description of the symbol that can be appended in the completion candidate list.
Definition: Symbol.h:65
clang::clangd::RefKind::Definition
@ Definition
clang::clangd::Symbol::Type
llvm::StringRef Type
Raw representation of the OpaqueType of the symbol, used for scoring purposes.
Definition: Symbol.h:85
clang::clangd::SymbolCollector::SymbolCollector
SymbolCollector(Options Opts)
Definition: SymbolCollector.cpp:300
clang::clangd::Symbol::IncludeHeaders
llvm::SmallVector< IncludeHeaderWithReferences, 1 > IncludeHeaders
One Symbol can potentially be included via different headers.
Definition: Symbol.h:111
clang::clangd::RelationKind::OverriddenBy
@ OverriddenBy
clang::clangd::toSourceCode
llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R)
Returns the source code covered by the source range.
Definition: SourceCode.cpp:447
clang::clangd::ASTNode
Simplified description of a clang AST node.
Definition: Protocol.h:1782
clang::clangd::Symbol::Documentation
llvm::StringRef Documentation
Documentation including comment for the symbol declaration.
Definition: Symbol.h:76
clang::clangd::sourceLocationInMainFile
llvm::Expected< SourceLocation > sourceLocationInMainFile(const SourceManager &SM, Position P)
Return the file location, corresponding to P.
Definition: SourceCode.cpp:457
clang::clangd::SymbolSlab::Builder::insert
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
Definition: Symbol.cpp:50
Signature
std::string Signature
Definition: CodeComplete.cpp:448
AST.h
clang::clangd::SymbolCollector::~SymbolCollector
~SymbolCollector()