clang-tools  15.0.0git
Headers.cpp
Go to the documentation of this file.
1 //===--- Headers.cpp - Include headers ---------------------------*- 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 "Headers.h"
10 #include "Preamble.h"
11 #include "SourceCode.h"
12 #include "clang/Basic/SourceLocation.h"
13 #include "clang/Basic/SourceManager.h"
14 #include "clang/Frontend/CompilerInstance.h"
15 #include "clang/Lex/HeaderSearch.h"
16 #include "clang/Lex/PPCallbacks.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/Path.h"
20 #include <cstring>
21 
22 namespace clang {
23 namespace clangd {
24 
25 const char IWYUPragmaKeep[] = "// IWYU pragma: keep";
26 const char IWYUPragmaExport[] = "// IWYU pragma: export";
27 const char IWYUPragmaBeginExports[] = "// IWYU pragma: begin_exports";
28 
30  public CommentHandler {
31 public:
32  RecordHeaders(const CompilerInstance &CI, IncludeStructure *Out)
33  : SM(CI.getSourceManager()),
34  HeaderInfo(CI.getPreprocessor().getHeaderSearchInfo()), Out(Out) {}
35 
36  // Record existing #includes - both written and resolved paths. Only #includes
37  // in the main file are collected.
38  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
39  llvm::StringRef FileName, bool IsAngled,
40  CharSourceRange /*FilenameRange*/,
41  Optional<FileEntryRef> File,
42  llvm::StringRef /*SearchPath*/,
43  llvm::StringRef /*RelativePath*/,
44  const clang::Module * /*Imported*/,
45  SrcMgr::CharacteristicKind FileKind) override {
46  auto MainFID = SM.getMainFileID();
47  // If an include is part of the preamble patch, translate #line directives.
48  if (InBuiltinFile)
49  HashLoc = translatePreamblePatchLocation(HashLoc, SM);
50 
51  // Record main-file inclusions (including those mapped from the preamble
52  // patch).
53  if (isInsideMainFile(HashLoc, SM)) {
54  Out->MainFileIncludes.emplace_back();
55  auto &Inc = Out->MainFileIncludes.back();
56  Inc.Written =
57  (IsAngled ? "<" + FileName + ">" : "\"" + FileName + "\"").str();
58  Inc.Resolved =
59  std::string(File ? File->getFileEntry().tryGetRealPathName() : "");
60  Inc.HashOffset = SM.getFileOffset(HashLoc);
61  Inc.HashLine =
62  SM.getLineNumber(SM.getFileID(HashLoc), Inc.HashOffset) - 1;
63  Inc.FileKind = FileKind;
64  Inc.Directive = IncludeTok.getIdentifierInfo()->getPPKeywordID();
65  if (LastPragmaKeepInMainFileLine == Inc.HashLine)
66  Inc.BehindPragmaKeep = true;
67  if (File) {
68  IncludeStructure::HeaderID HID = Out->getOrCreateID(*File);
69  Inc.HeaderID = static_cast<unsigned>(HID);
70  if (IsAngled)
71  if (auto StdlibHeader = tooling::stdlib::Header::named(Inc.Written)) {
72  auto &IDs = Out->StdlibHeaders[*StdlibHeader];
73  // Few physical files for one stdlib header name, linear scan is ok.
74  if (!llvm::is_contained(IDs, HID))
75  IDs.push_back(HID);
76  }
77  }
78  }
79 
80  // Record include graph (not just for main-file includes)
81  if (File) {
82  auto IncludingFileEntry = SM.getFileEntryRefForID(SM.getFileID(HashLoc));
83  if (!IncludingFileEntry) {
84  assert(SM.getBufferName(HashLoc).startswith("<") &&
85  "Expected #include location to be a file or <built-in>");
86  // Treat as if included from the main file.
87  IncludingFileEntry = SM.getFileEntryRefForID(MainFID);
88  }
89  auto IncludingID = Out->getOrCreateID(*IncludingFileEntry),
90  IncludedID = Out->getOrCreateID(*File);
91  Out->IncludeChildren[IncludingID].push_back(IncludedID);
92  }
93  }
94 
95  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
96  SrcMgr::CharacteristicKind FileType,
97  FileID PrevFID) override {
98  switch (Reason) {
99  case PPCallbacks::EnterFile:
100  ++Level;
101  if (BuiltinFile.isInvalid() && SM.isWrittenInBuiltinFile(Loc)) {
102  BuiltinFile = SM.getFileID(Loc);
103  InBuiltinFile = true;
104  }
105  break;
106  case PPCallbacks::ExitFile: {
107  --Level;
108  if (PrevFID == BuiltinFile)
109  InBuiltinFile = false;
110  // At file exit time HeaderSearchInfo is valid and can be used to
111  // determine whether the file was a self-contained header or not.
112  if (const FileEntry *FE = SM.getFileEntryForID(PrevFID)) {
113  // isSelfContainedHeader only returns true once the full header-guard
114  // structure has been seen, i.e. when exiting the *outer* copy of the
115  // file. So last result wins.
116  if (isSelfContainedHeader(FE, PrevFID, SM, HeaderInfo))
117  Out->NonSelfContained.erase(
118  *Out->getID(SM.getFileEntryForID(PrevFID)));
119  else
120  Out->NonSelfContained.insert(
121  *Out->getID(SM.getFileEntryForID(PrevFID)));
122  }
123  break;
124  }
125  case PPCallbacks::RenameFile:
126  case PPCallbacks::SystemHeaderPragma:
127  break;
128  }
129  }
130 
131  bool HandleComment(Preprocessor &PP, SourceRange Range) override {
132  bool Err = false;
133  llvm::StringRef Text = SM.getCharacterData(Range.getBegin(), &Err);
134  if (Err)
135  return false;
136  if (inMainFile()) {
137  // Given:
138  //
139  // #include "foo.h"
140  // #include "bar.h" // IWYU pragma: keep
141  //
142  // The order in which the callbacks will be triggered:
143  //
144  // 1. InclusionDirective("foo.h")
145  // 2. handleCommentInMainFile("// IWYU pragma: keep")
146  // 3. InclusionDirective("bar.h")
147  //
148  // This code stores the last location of "IWYU pragma: keep" (or export)
149  // comment in the main file, so that when InclusionDirective is called, it
150  // will know that the next inclusion is behind the IWYU pragma.
151  // FIXME: Support "IWYU pragma: begin_exports" and "IWYU pragma:
152  // end_exports".
153  if (!Text.startswith(IWYUPragmaExport) &&
154  !Text.startswith(IWYUPragmaKeep))
155  return false;
156  unsigned Offset = SM.getFileOffset(Range.getBegin());
157  LastPragmaKeepInMainFileLine =
158  SM.getLineNumber(SM.getMainFileID(), Offset) - 1;
159  } else {
160  // Memorize headers that that have export pragmas in them. Include Cleaner
161  // does not support them properly yet, so they will be not marked as
162  // unused.
163  // FIXME: Once IncludeCleaner supports export pragmas, remove this.
164  if (!Text.startswith(IWYUPragmaExport) &&
165  !Text.startswith(IWYUPragmaBeginExports))
166  return false;
167  Out->HasIWYUExport.insert(
168  *Out->getID(SM.getFileEntryForID(SM.getFileID(Range.getBegin()))));
169  }
170  return false;
171  }
172 
173 private:
174  // Keeps track of include depth for the current file. It's 1 for main file.
175  int Level = 0;
176  bool inMainFile() const { return Level == 1; }
177 
178  const SourceManager &SM;
179  HeaderSearch &HeaderInfo;
180  // Set after entering the <built-in> file.
181  FileID BuiltinFile;
182  // Indicates whether <built-in> file is part of include stack.
183  bool InBuiltinFile = false;
184 
185  IncludeStructure *Out;
186 
187  // The last line "IWYU pragma: keep" was seen in the main file, 0-indexed.
188  int LastPragmaKeepInMainFileLine = -1;
189 };
190 
191 bool isLiteralInclude(llvm::StringRef Include) {
192  return Include.startswith("<") || Include.startswith("\"");
193 }
194 
195 bool HeaderFile::valid() const {
196  return (Verbatim && isLiteralInclude(File)) ||
197  (!Verbatim && llvm::sys::path::is_absolute(File));
198 }
199 
200 llvm::Expected<HeaderFile> toHeaderFile(llvm::StringRef Header,
201  llvm::StringRef HintPath) {
202  if (isLiteralInclude(Header))
203  return HeaderFile{Header.str(), /*Verbatim=*/true};
204  auto U = URI::parse(Header);
205  if (!U)
206  return U.takeError();
207 
208  auto IncludePath = URI::includeSpelling(*U);
209  if (!IncludePath)
210  return IncludePath.takeError();
211  if (!IncludePath->empty())
212  return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true};
213 
214  auto Resolved = URI::resolve(*U, HintPath);
215  if (!Resolved)
216  return Resolved.takeError();
217  return HeaderFile{std::move(*Resolved), /*Verbatim=*/false};
218 }
219 
220 llvm::SmallVector<llvm::StringRef, 1> getRankedIncludes(const Symbol &Sym) {
221  auto Includes = Sym.IncludeHeaders;
222  // Sort in descending order by reference count and header length.
223  llvm::sort(Includes, [](const Symbol::IncludeHeaderWithReferences &LHS,
225  if (LHS.References == RHS.References)
226  return LHS.IncludeHeader.size() < RHS.IncludeHeader.size();
227  return LHS.References > RHS.References;
228  });
229  llvm::SmallVector<llvm::StringRef, 1> Headers;
230  for (const auto &Include : Includes)
231  Headers.push_back(Include.IncludeHeader);
232  return Headers;
233 }
234 
235 void IncludeStructure::collect(const CompilerInstance &CI) {
236  auto &SM = CI.getSourceManager();
237  MainFileEntry = SM.getFileEntryForID(SM.getMainFileID());
238  auto Collector = std::make_unique<RecordHeaders>(CI, this);
239  CI.getPreprocessor().addCommentHandler(Collector.get());
240  CI.getPreprocessor().addPPCallbacks(std::move(Collector));
241 }
242 
243 llvm::Optional<IncludeStructure::HeaderID>
244 IncludeStructure::getID(const FileEntry *Entry) const {
245  // HeaderID of the main file is always 0;
246  if (Entry == MainFileEntry) {
247  return static_cast<IncludeStructure::HeaderID>(0u);
248  }
249  auto It = UIDToIndex.find(Entry->getUniqueID());
250  if (It == UIDToIndex.end())
251  return llvm::None;
252  return It->second;
253 }
254 
256  // Main file's FileEntry was not known at IncludeStructure creation time.
257  if (&Entry.getFileEntry() == MainFileEntry) {
258  if (RealPathNames.front().empty())
259  RealPathNames.front() = MainFileEntry->tryGetRealPathName().str();
260  return MainFileID;
261  }
262  auto R = UIDToIndex.try_emplace(
263  Entry.getUniqueID(),
264  static_cast<IncludeStructure::HeaderID>(RealPathNames.size()));
265  if (R.second)
266  RealPathNames.emplace_back();
267  IncludeStructure::HeaderID Result = R.first->getSecond();
268  std::string &RealPathName = RealPathNames[static_cast<unsigned>(Result)];
269  if (RealPathName.empty())
270  RealPathName = Entry.getFileEntry().tryGetRealPathName().str();
271  return Result;
272 }
273 
274 llvm::DenseMap<IncludeStructure::HeaderID, unsigned>
276  // Include depth 0 is the main file only.
277  llvm::DenseMap<HeaderID, unsigned> Result;
278  assert(static_cast<unsigned>(Root) < RealPathNames.size());
279  Result[Root] = 0;
280  std::vector<IncludeStructure::HeaderID> CurrentLevel;
281  CurrentLevel.push_back(Root);
282  llvm::DenseSet<IncludeStructure::HeaderID> Seen;
283  Seen.insert(Root);
284 
285  // Each round of BFS traversal finds the next depth level.
286  std::vector<IncludeStructure::HeaderID> PreviousLevel;
287  for (unsigned Level = 1; !CurrentLevel.empty(); ++Level) {
288  PreviousLevel.clear();
289  PreviousLevel.swap(CurrentLevel);
290  for (const auto &Parent : PreviousLevel) {
291  for (const auto &Child : IncludeChildren.lookup(Parent)) {
292  if (Seen.insert(Child).second) {
293  CurrentLevel.push_back(Child);
294  Result[Child] = Level;
295  }
296  }
297  }
298  }
299  return Result;
300 }
301 
303  IncludedHeaders.insert(Inc.Written);
304  if (!Inc.Resolved.empty())
305  IncludedHeaders.insert(Inc.Resolved);
306 }
307 
308 /// FIXME(ioeric): we might not want to insert an absolute include path if the
309 /// path is not shortened.
311  PathRef DeclaringHeader, const HeaderFile &InsertedHeader) const {
312  assert(InsertedHeader.valid());
313  if (!HeaderSearchInfo && !InsertedHeader.Verbatim)
314  return false;
315  if (FileName == DeclaringHeader || FileName == InsertedHeader.File)
316  return false;
317  auto Included = [&](llvm::StringRef Header) {
318  return IncludedHeaders.find(Header) != IncludedHeaders.end();
319  };
320  return !Included(DeclaringHeader) && !Included(InsertedHeader.File);
321 }
322 
323 llvm::Optional<std::string>
325  llvm::StringRef IncludingFile) const {
326  assert(InsertedHeader.valid());
327  if (InsertedHeader.Verbatim)
328  return InsertedHeader.File;
329  bool IsSystem = false;
330  std::string Suggested;
331  if (HeaderSearchInfo) {
332  Suggested = HeaderSearchInfo->suggestPathToFileForDiagnostics(
333  InsertedHeader.File, BuildDir, IncludingFile, &IsSystem);
334  } else {
335  // Calculate include relative to including file only.
336  StringRef IncludingDir = llvm::sys::path::parent_path(IncludingFile);
337  SmallString<256> RelFile(InsertedHeader.File);
338  // Replacing with "" leaves "/RelFile" if IncludingDir doesn't end in "/".
339  llvm::sys::path::replace_path_prefix(RelFile, IncludingDir, "./");
340  Suggested = llvm::sys::path::convert_to_slash(
341  llvm::sys::path::remove_leading_dotslash(RelFile));
342  }
343  // FIXME: should we allow (some limited number of) "../header.h"?
344  if (llvm::sys::path::is_absolute(Suggested))
345  return None;
346  if (IsSystem)
347  Suggested = "<" + Suggested + ">";
348  else
349  Suggested = "\"" + Suggested + "\"";
350  return Suggested;
351 }
352 
353 llvm::Optional<TextEdit>
354 IncludeInserter::insert(llvm::StringRef VerbatimHeader) const {
355  llvm::Optional<TextEdit> Edit = None;
356  if (auto Insertion = Inserter.insert(VerbatimHeader.trim("\"<>"),
357  VerbatimHeader.startswith("<")))
358  Edit = replacementToEdit(Code, *Insertion);
359  return Edit;
360 }
361 
362 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Inclusion &Inc) {
363  return OS << Inc.Written << " = "
364  << (!Inc.Resolved.empty() ? Inc.Resolved : "[unresolved]")
365  << " at line" << Inc.HashLine;
366 }
367 
368 bool operator==(const Inclusion &LHS, const Inclusion &RHS) {
369  return std::tie(LHS.Directive, LHS.FileKind, LHS.HashOffset, LHS.HashLine,
370  LHS.Resolved, LHS.Written) ==
371  std::tie(RHS.Directive, RHS.FileKind, RHS.HashOffset, RHS.HashLine,
372  RHS.Resolved, RHS.Written);
373 }
374 
375 } // namespace clangd
376 } // namespace clang
clang::clangd::IncludeStructure::collect
void collect(const CompilerInstance &CI)
Definition: Headers.cpp:235
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
clang::clangd::HeaderFile
Represents a header file to be #include'd.
Definition: Headers.h:39
Headers.h
clang::clangd::Edit
A set of edits generated for a single file.
Definition: SourceCode.h:184
clang::clangd::IWYUPragmaBeginExports
const char IWYUPragmaBeginExports[]
Definition: Headers.cpp:27
clang::clangd::IncludeStructure::getID
llvm::Optional< HeaderID > getID(const FileEntry *Entry) const
Definition: Headers.cpp:244
CI
std::unique_ptr< CompilerInvocation > CI
Definition: TUScheduler.cpp:491
Root
ASTNode Root
Definition: DumpAST.cpp:332
Preamble.h
clang::clangd::IncludeStructure::RecordHeaders::InclusionDirective
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, CharSourceRange, Optional< FileEntryRef > File, llvm::StringRef, llvm::StringRef, const clang::Module *, SrcMgr::CharacteristicKind FileKind) override
Definition: Headers.cpp:38
Text
std::string Text
Definition: HTMLGenerator.cpp:80
clang::clangd::HeaderFile::valid
bool valid() const
Definition: Headers.cpp:195
clang::clangd::IncludeStructure::HeaderID
HeaderID
Definition: Headers.h:134
clang::clangd::IncludeStructure::RecordHeaders::RecordHeaders
RecordHeaders(const CompilerInstance &CI, IncludeStructure *Out)
Definition: Headers.cpp:32
clang::clangd::IncludeInserter::calculateIncludePath
llvm::Optional< std::string > calculateIncludePath(const HeaderFile &InsertedHeader, llvm::StringRef IncludingFile) const
Determines the preferred way to #include a file, taking into account the search path.
Definition: Headers.cpp:324
clang::clangd::IncludeStructure::MainFileIncludes
std::vector< Inclusion > MainFileIncludes
Definition: Headers.h:168
clang::clangd::URI::parse
static llvm::Expected< URI > parse(llvm::StringRef Uri)
Parse a URI string "<scheme>:[//<authority>/]<path>".
Definition: URI.cpp:177
clang::clangd::replacementToEdit
TextEdit replacementToEdit(llvm::StringRef Code, const tooling::Replacement &R)
Definition: SourceCode.cpp:495
clang::clangd::IncludeInserter::shouldInsertInclude
bool shouldInsertInclude(PathRef DeclaringHeader, const HeaderFile &InsertedHeader) const
Checks whether to add an #include of the header into File.
Definition: Headers.cpp:310
clang::clangd::IncludeStructure
Definition: Headers.h:119
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:1222
clang::clangd::getRankedIncludes
llvm::SmallVector< llvm::StringRef, 1 > getRankedIncludes(const Symbol &Sym)
Definition: Headers.cpp:220
clang::clangd::URI::resolve
static llvm::Expected< std::string > resolve(const URI &U, llvm::StringRef HintPath="")
Resolves the absolute path of U.
Definition: URI.cpp:245
Offset
size_t Offset
Definition: CodeComplete.cpp:1203
clang::clangd::Inclusion::Directive
tok::PPKeywordKind Directive
Definition: Headers.h:59
clang::clangd::IncludeStructure::RecordHeaders
Definition: Headers.cpp:29
clang::clangd::Inclusion::HashLine
int HashLine
Definition: Headers.h:63
clang::clangd::Inclusion::Written
std::string Written
Definition: Headers.h:60
clang::clangd::Symbol
The class presents a C++ symbol, e.g.
Definition: Symbol.h:36
clang::clangd::URI::includeSpelling
static llvm::Expected< std::string > includeSpelling(const URI &U)
Gets the preferred spelling of this file for #include, if there is one, e.g.
Definition: URI.cpp:273
FileName
StringRef FileName
Definition: KernelNameRestrictionCheck.cpp:46
clang::clangd::toHeaderFile
llvm::Expected< HeaderFile > toHeaderFile(llvm::StringRef Header, llvm::StringRef HintPath)
Creates a HeaderFile from Header which can be either a URI or a literal include.
Definition: Headers.cpp:200
clang::clangd::IncludeStructure::StdlibHeaders
llvm::DenseMap< tooling::stdlib::Header, llvm::SmallVector< HeaderID > > StdlibHeaders
Definition: Headers.h:166
clang::clangd::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
Definition: CodeComplete.cpp:2172
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:29
Parent
const Node * Parent
Definition: ExtractFunction.cpp:157
Entry
Definition: Modularize.cpp:428
SourceCode.h
clang::clangd::IncludeStructure::includeDepth
llvm::DenseMap< HeaderID, unsigned > includeDepth(HeaderID Root=MainFileID) const
Definition: Headers.cpp:275
IsAngled
bool IsAngled
true if this was an include with angle brackets
Definition: IncludeOrderCheck.cpp:40
Collector
std::shared_ptr< SymbolCollector > Collector
Definition: SymbolCollectorTests.cpp:258
clang::clangd::Inclusion
Definition: Headers.h:58
clang::clangd::isLiteralInclude
bool isLiteralInclude(llvm::StringRef Include)
Returns true if Include is literal include like "path" or <path>.
Definition: Headers.cpp:191
clang::clangd::Symbol::IncludeHeaderWithReferences
Definition: Symbol.h:87
clang::clangd::IncludeInserter::addExisting
void addExisting(const Inclusion &Inc)
Definition: Headers.cpp:302
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
clang::clangd::Inclusion::Resolved
Path Resolved
Definition: Headers.h:61
clang::clangd::IncludeStructure::MainFileID
static const HeaderID MainFileID
Definition: Headers.h:173
clang::clangd::IncludeStructure::getOrCreateID
HeaderID getOrCreateID(FileEntryRef Entry)
Definition: Headers.cpp:255
clang::clangd::IncludeInserter::insert
llvm::Optional< TextEdit > insert(llvm::StringRef VerbatimHeader) const
Calculates an edit that inserts VerbatimHeader into code.
Definition: Headers.cpp:354
clang::clangd::Inclusion::FileKind
SrcMgr::CharacteristicKind FileKind
Definition: Headers.h:64
clang::clangd::Range
Definition: Protocol.h:182
clang::clangd::Symbol::IncludeHeaderWithReferences::References
unsigned References
The number of translation units that reference this symbol and include this header.
Definition: Symbol.h:104
PPCallbacks
clang::clangd::IWYUPragmaKeep
const char IWYUPragmaKeep[]
Definition: Headers.cpp:25
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
clang::clangd::isInsideMainFile
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
Definition: SourceCode.cpp:414
clang::clangd::IWYUPragmaExport
const char IWYUPragmaExport[]
Definition: Headers.cpp:26
clang::clangd::Inclusion::HashOffset
unsigned HashOffset
Definition: Headers.h:62
clang::clangd::operator==
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
Definition: Headers.cpp:368
clang::clangd::IncludeStructure::RecordHeaders::FileChanged
void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) override
Definition: Headers.cpp:95
Out
CompiledFragmentImpl & Out
Definition: ConfigCompile.cpp:99
clang::clangd::HeaderFile::File
std::string File
Definition: Headers.h:40
clang::clangd::Symbol::IncludeHeaders
llvm::SmallVector< IncludeHeaderWithReferences, 1 > IncludeHeaders
One Symbol can potentially be included via different headers.
Definition: Symbol.h:111
clang::clangd::Symbol::IncludeHeaderWithReferences::IncludeHeader
llvm::StringRef IncludeHeader
This can be either a URI of the header to be #include'd for this symbol, or a literal header quoted w...
Definition: Symbol.h:101
clang::clangd::IncludeStructure::IncludeChildren
llvm::DenseMap< HeaderID, SmallVector< HeaderID > > IncludeChildren
Definition: Headers.h:163
clang::clangd::HeaderFile::Verbatim
bool Verbatim
If this is true, File is a literal string quoted with <> or "" that can be #included directly; otherw...
Definition: Headers.h:43
clang::clangd::translatePreamblePatchLocation
SourceLocation translatePreamblePatchLocation(SourceLocation Loc, const SourceManager &SM)
Translates locations inside preamble patch to their main-file equivalent using presumed locations.
Definition: Preamble.cpp:748
clang::clangd::IncludeStructure::RecordHeaders::HandleComment
bool HandleComment(Preprocessor &PP, SourceRange Range) override
Definition: Headers.cpp:131