1 //===--- Preamble.cpp - Reusing expensive parts of the AST ----------------===//
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
7 //===----------------------------------------------------------------------===//
13 #include "SourceCode.h"
14 #include "support/Logger.h"
15 #include "support/ThreadsafeFS.h"
16 #include "support/Trace.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/DiagnosticLex.h"
20 #include "clang/Basic/LangOptions.h"
21 #include "clang/Basic/SourceLocation.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "clang/Basic/TokenKinds.h"
24 #include "clang/Frontend/CompilerInvocation.h"
25 #include "clang/Frontend/FrontendActions.h"
26 #include "clang/Lex/HeaderSearch.h"
27 #include "clang/Lex/Lexer.h"
28 #include "clang/Lex/PPCallbacks.h"
29 #include "clang/Lex/Preprocessor.h"
30 #include "clang/Lex/PreprocessorOptions.h"
31 #include "clang/Tooling/CompilationDatabase.h"
32 #include "llvm/ADT/ArrayRef.h"
33 #include "llvm/ADT/DenseMap.h"
34 #include "llvm/ADT/IntrusiveRefCntPtr.h"
35 #include "llvm/ADT/None.h"
36 #include "llvm/ADT/STLExtras.h"
37 #include "llvm/ADT/SmallString.h"
38 #include "llvm/ADT/StringRef.h"
39 #include "llvm/Support/Error.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/Support/FormatVariadic.h"
42 #include "llvm/Support/MemoryBuffer.h"
43 #include "llvm/Support/Path.h"
44 #include "llvm/Support/VirtualFileSystem.h"
45 #include "llvm/Support/raw_ostream.h"
49 #include <system_error>
56 constexpr llvm::StringLiteral PreamblePatchHeaderName
= "__preamble_patch__.h";
58 bool compileCommandsAreEqual(const tooling::CompileCommand
&LHS
,
59 const tooling::CompileCommand
&RHS
) {
60 // We don't check for Output, it should not matter to clangd.
61 return LHS
.Directory
== RHS
.Directory
&& LHS
.Filename
== RHS
.Filename
&&
62 llvm::makeArrayRef(LHS
.CommandLine
).equals(RHS
.CommandLine
);
65 class CppFilePreambleCallbacks
: public PreambleCallbacks
{
67 CppFilePreambleCallbacks(
68 PathRef File
, PreambleParsedCallback ParsedCallback
,
69 PreambleBuildStats
*Stats
, bool ParseForwardingFunctions
,
70 std::function
<void(CompilerInstance
&)> BeforeExecuteCallback
)
71 : File(File
), ParsedCallback(ParsedCallback
), Stats(Stats
),
72 ParseForwardingFunctions(ParseForwardingFunctions
),
73 BeforeExecuteCallback(std::move(BeforeExecuteCallback
)) {}
75 IncludeStructure
takeIncludes() { return std::move(Includes
); }
77 MainFileMacros
takeMacros() { return std::move(Macros
); }
79 std::vector
<PragmaMark
> takeMarks() { return std::move(Marks
); }
81 CanonicalIncludes
takeCanonicalIncludes() { return std::move(CanonIncludes
); }
83 bool isMainFileIncludeGuarded() const { return IsMainFileIncludeGuarded
; }
85 void AfterExecute(CompilerInstance
&CI
) override
{
87 trace::Span
Tracer("Running PreambleCallback");
88 ParsedCallback(CI
.getASTContext(), CI
.getPreprocessor(), CanonIncludes
);
91 const SourceManager
&SM
= CI
.getSourceManager();
92 const FileEntry
*MainFE
= SM
.getFileEntryForID(SM
.getMainFileID());
93 IsMainFileIncludeGuarded
=
94 CI
.getPreprocessor().getHeaderSearchInfo().isFileMultipleIncludeGuarded(
98 const ASTContext
&AST
= CI
.getASTContext();
99 Stats
->BuildSize
= AST
.getASTAllocatedMemory();
100 Stats
->BuildSize
+= AST
.getSideTableAllocatedMemory();
101 Stats
->BuildSize
+= AST
.Idents
.getAllocator().getTotalMemory();
102 Stats
->BuildSize
+= AST
.Selectors
.getTotalMemory();
104 Stats
->BuildSize
+= AST
.getSourceManager().getContentCacheSize();
105 Stats
->BuildSize
+= AST
.getSourceManager().getDataStructureSizes();
107 AST
.getSourceManager().getMemoryBufferSizes().malloc_bytes
;
109 const Preprocessor
&PP
= CI
.getPreprocessor();
110 Stats
->BuildSize
+= PP
.getTotalMemory();
111 if (PreprocessingRecord
*PRec
= PP
.getPreprocessingRecord())
112 Stats
->BuildSize
+= PRec
->getTotalMemory();
113 Stats
->BuildSize
+= PP
.getHeaderSearchInfo().getTotalMemory();
117 void BeforeExecute(CompilerInstance
&CI
) override
{
118 CanonIncludes
.addSystemHeadersMapping(CI
.getLangOpts());
119 LangOpts
= &CI
.getLangOpts();
120 SourceMgr
= &CI
.getSourceManager();
121 Includes
.collect(CI
);
122 if (BeforeExecuteCallback
)
123 BeforeExecuteCallback(CI
);
126 std::unique_ptr
<PPCallbacks
> createPPCallbacks() override
{
127 assert(SourceMgr
&& LangOpts
&&
128 "SourceMgr and LangOpts must be set at this point");
130 return std::make_unique
<PPChainedCallbacks
>(
131 std::make_unique
<CollectMainFileMacros
>(*SourceMgr
, Macros
),
132 collectPragmaMarksCallback(*SourceMgr
, Marks
));
135 CommentHandler
*getCommentHandler() override
{
136 IWYUHandler
= collectIWYUHeaderMaps(&CanonIncludes
);
137 return IWYUHandler
.get();
140 static bool isLikelyForwardingFunction(FunctionTemplateDecl
*FT
) {
141 const auto *FD
= FT
->getTemplatedDecl();
142 const auto NumParams
= FD
->getNumParams();
143 // Check whether its last parameter is a parameter pack...
145 const auto *LastParam
= FD
->getParamDecl(NumParams
- 1);
146 if (const auto *PET
= dyn_cast
<PackExpansionType
>(LastParam
->getType())) {
147 // ... of the type T&&... or T...
148 const auto BaseType
= PET
->getPattern().getNonReferenceType();
149 if (const auto *TTPT
=
150 dyn_cast
<TemplateTypeParmType
>(BaseType
.getTypePtr())) {
151 // ... whose template parameter comes from the function directly
152 if (FT
->getTemplateParameters()->getDepth() == TTPT
->getDepth()) {
161 bool shouldSkipFunctionBody(Decl
*D
) override
{
162 // Usually we don't need to look inside the bodies of header functions
163 // to understand the program. However when forwarding function like
164 // emplace() forward their arguments to some other function, the
165 // interesting overload resolution happens inside the forwarding
166 // function's body. To provide more meaningful diagnostics,
167 // code completion, and parameter hints we should parse (and later
168 // instantiate) the bodies.
169 if (auto *FT
= llvm::dyn_cast
<clang::FunctionTemplateDecl
>(D
)) {
170 if (ParseForwardingFunctions
) {
171 // Don't skip parsing the body if it looks like a forwarding function
172 if (isLikelyForwardingFunction(FT
))
175 // By default, only take care of make_unique
176 // std::make_unique is trivial, and we diagnose bad constructor calls.
177 if (const auto *II
= FT
->getDeclName().getAsIdentifierInfo()) {
178 if (II
->isStr("make_unique") && FT
->isInStdNamespace())
188 PreambleParsedCallback ParsedCallback
;
189 IncludeStructure Includes
;
190 CanonicalIncludes CanonIncludes
;
191 MainFileMacros Macros
;
192 std::vector
<PragmaMark
> Marks
;
193 bool IsMainFileIncludeGuarded
= false;
194 std::unique_ptr
<CommentHandler
> IWYUHandler
= nullptr;
195 const clang::LangOptions
*LangOpts
= nullptr;
196 const SourceManager
*SourceMgr
= nullptr;
197 PreambleBuildStats
*Stats
;
198 bool ParseForwardingFunctions
;
199 std::function
<void(CompilerInstance
&)> BeforeExecuteCallback
;
202 // Represents directives other than includes, where basic textual information is
204 struct TextualPPDirective
{
205 unsigned DirectiveLine
;
206 // Full text that's representing the directive, including the `#`.
210 bool operator==(const TextualPPDirective
&RHS
) const {
211 return std::tie(DirectiveLine
, Offset
, Text
) ==
212 std::tie(RHS
.DirectiveLine
, RHS
.Offset
, RHS
.Text
);
216 // Formats a PP directive consisting of Prefix (e.g. "#define ") and Body ("X
217 // 10"). The formatting is copied so that the tokens in Body have PresumedLocs
218 // with correct columns and lines.
219 std::string
spellDirective(llvm::StringRef Prefix
,
220 CharSourceRange DirectiveRange
,
221 const LangOptions
&LangOpts
, const SourceManager
&SM
,
222 unsigned &DirectiveLine
, unsigned &Offset
) {
223 std::string SpelledDirective
;
224 llvm::raw_string_ostream
OS(SpelledDirective
);
227 // Make sure DirectiveRange is a char range and doesn't contain macro ids.
228 DirectiveRange
= SM
.getExpansionRange(DirectiveRange
);
229 if (DirectiveRange
.isTokenRange()) {
230 DirectiveRange
.setEnd(
231 Lexer::getLocForEndOfToken(DirectiveRange
.getEnd(), 0, SM
, LangOpts
));
234 auto DecompLoc
= SM
.getDecomposedLoc(DirectiveRange
.getBegin());
235 DirectiveLine
= SM
.getLineNumber(DecompLoc
.first
, DecompLoc
.second
);
236 Offset
= DecompLoc
.second
;
237 auto TargetColumn
= SM
.getColumnNumber(DecompLoc
.first
, DecompLoc
.second
) - 1;
239 // Pad with spaces before DirectiveRange to make sure it will be on right
240 // column when patched.
241 if (Prefix
.size() <= TargetColumn
) {
242 // There is enough space for Prefix and space before directive, use it.
243 // We try to squeeze the Prefix into the same line whenever we can, as
244 // putting onto a separate line won't work at the beginning of the file.
245 OS
<< std::string(TargetColumn
- Prefix
.size(), ' ');
247 // Prefix was longer than the space we had. We produce e.g.:
251 OS
<< "\\\n" << std::string(TargetColumn
, ' ');
252 // Decrement because we put an additional line break before
253 // DirectiveRange.begin().
256 OS
<< toSourceCode(SM
, DirectiveRange
.getAsRange());
260 // Collects #define directives inside the main file.
261 struct DirectiveCollector
: public PPCallbacks
{
262 DirectiveCollector(const Preprocessor
&PP
,
263 std::vector
<TextualPPDirective
> &TextualDirectives
)
264 : LangOpts(PP
.getLangOpts()), SM(PP
.getSourceManager()),
265 TextualDirectives(TextualDirectives
) {}
267 void FileChanged(SourceLocation Loc
, FileChangeReason Reason
,
268 SrcMgr::CharacteristicKind FileType
,
269 FileID PrevFID
) override
{
270 InMainFile
= SM
.isWrittenInMainFile(Loc
);
273 void MacroDefined(const Token
&MacroNameTok
,
274 const MacroDirective
*MD
) override
{
277 TextualDirectives
.emplace_back();
278 TextualPPDirective
&TD
= TextualDirectives
.back();
280 const auto *MI
= MD
->getMacroInfo();
282 spellDirective("#define ",
283 CharSourceRange::getTokenRange(
284 MI
->getDefinitionLoc(), MI
->getDefinitionEndLoc()),
285 LangOpts
, SM
, TD
.DirectiveLine
, TD
.Offset
);
289 bool InMainFile
= true;
290 const LangOptions
&LangOpts
;
291 const SourceManager
&SM
;
292 std::vector
<TextualPPDirective
> &TextualDirectives
;
295 struct ScannedPreamble
{
296 std::vector
<Inclusion
> Includes
;
297 std::vector
<TextualPPDirective
> TextualDirectives
;
298 PreambleBounds Bounds
= {0, false};
301 /// Scans the preprocessor directives in the preamble section of the file by
302 /// running preprocessor over \p Contents. Returned includes do not contain
303 /// resolved paths. \p Cmd is used to build the compiler invocation, which might
305 llvm::Expected
<ScannedPreamble
>
306 scanPreamble(llvm::StringRef Contents
, const tooling::CompileCommand
&Cmd
) {
307 class EmptyFS
: public ThreadsafeFS
{
309 llvm::IntrusiveRefCntPtr
<llvm::vfs::FileSystem
> viewImpl() const override
{
310 return new llvm::vfs::InMemoryFileSystem
;
314 // Build and run Preprocessor over the preamble.
316 PI
.Contents
= Contents
.str();
318 PI
.CompileCommand
= Cmd
;
319 IgnoringDiagConsumer IgnoreDiags
;
320 auto CI
= buildCompilerInvocation(PI
, IgnoreDiags
);
322 return error("failed to create compiler invocation");
323 CI
->getDiagnosticOpts().IgnoreWarnings
= true;
324 auto ContentsBuffer
= llvm::MemoryBuffer::getMemBuffer(Contents
);
325 // This means we're scanning (though not preprocessing) the preamble section
326 // twice. However, it's important to precisely follow the preamble bounds used
328 auto Bounds
= ComputePreambleBounds(*CI
->getLangOpts(), *ContentsBuffer
, 0);
329 auto PreambleContents
=
330 llvm::MemoryBuffer::getMemBufferCopy(Contents
.substr(0, Bounds
.Size
));
331 auto Clang
= prepareCompilerInstance(
332 std::move(CI
), nullptr, std::move(PreambleContents
),
333 // Provide an empty FS to prevent preprocessor from performing IO. This
334 // also implies missing resolved paths for includes.
335 FS
.view(llvm::None
), IgnoreDiags
);
336 if (Clang
->getFrontendOpts().Inputs
.empty())
337 return error("compiler instance had no inputs");
338 // We are only interested in main file includes.
339 Clang
->getPreprocessorOpts().SingleFileParseMode
= true;
340 Clang
->getPreprocessorOpts().UsePredefines
= false;
341 PreprocessOnlyAction Action
;
342 if (!Action
.BeginSourceFile(*Clang
, Clang
->getFrontendOpts().Inputs
[0]))
343 return error("failed BeginSourceFile");
344 Preprocessor
&PP
= Clang
->getPreprocessor();
345 IncludeStructure Includes
;
346 Includes
.collect(*Clang
);
350 std::make_unique
<DirectiveCollector
>(PP
, SP
.TextualDirectives
));
351 if (llvm::Error Err
= Action
.Execute())
352 return std::move(Err
);
353 Action
.EndSourceFile();
354 SP
.Includes
= std::move(Includes
.MainFileIncludes
);
358 const char *spellingForIncDirective(tok::PPKeywordKind IncludeDirective
) {
359 switch (IncludeDirective
) {
360 case tok::pp_include
:
364 case tok::pp_include_next
:
365 return "include_next";
369 llvm_unreachable("not an include directive");
372 // Checks whether \p FileName is a valid spelling of main file.
373 bool isMainFile(llvm::StringRef FileName
, const SourceManager
&SM
) {
374 auto FE
= SM
.getFileManager().getFile(FileName
);
375 return FE
&& *FE
== SM
.getFileEntryForID(SM
.getMainFileID());
378 // Accumulating wall time timer. Similar to llvm::Timer, but much cheaper,
379 // it only tracks wall time.
380 // Since this is a generic timer, We may want to move this to support/ if we
381 // find a use case outside of FS time tracking.
384 WallTimer() : TotalTime(std::chrono::steady_clock::duration::zero()) {}
385 // [Re-]Start the timer.
386 void startTimer() { StartTime
= std::chrono::steady_clock::now(); }
387 // Stop the timer and update total time.
389 TotalTime
+= std::chrono::steady_clock::now() - StartTime
;
391 // Return total time, in seconds.
392 double getTime() { return std::chrono::duration
<double>(TotalTime
).count(); }
395 std::chrono::steady_clock::duration TotalTime
;
396 std::chrono::steady_clock::time_point StartTime
;
399 class WallTimerRegion
{
401 WallTimerRegion(WallTimer
&T
) : T(T
) { T
.startTimer(); }
402 ~WallTimerRegion() { T
.stopTimer(); }
408 // Used by TimerFS, tracks time spent in status() and getBuffer() calls while
409 // proxying to underlying File implementation.
410 class TimerFile
: public llvm::vfs::File
{
412 TimerFile(WallTimer
&Timer
, std::unique_ptr
<File
> InnerFile
)
413 : Timer(Timer
), InnerFile(std::move(InnerFile
)) {}
415 llvm::ErrorOr
<llvm::vfs::Status
> status() override
{
416 WallTimerRegion
T(Timer
);
417 return InnerFile
->status();
419 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>>
420 getBuffer(const Twine
&Name
, int64_t FileSize
, bool RequiresNullTerminator
,
421 bool IsVolatile
) override
{
422 WallTimerRegion
T(Timer
);
423 return InnerFile
->getBuffer(Name
, FileSize
, RequiresNullTerminator
,
426 std::error_code
close() override
{
427 WallTimerRegion
T(Timer
);
428 return InnerFile
->close();
433 std::unique_ptr
<llvm::vfs::File
> InnerFile
;
436 // A wrapper for FileSystems that tracks the amount of time spent in status()
437 // and openFileForRead() calls.
438 class TimerFS
: public llvm::vfs::ProxyFileSystem
{
440 TimerFS(llvm::IntrusiveRefCntPtr
<llvm::vfs::FileSystem
> FS
)
441 : ProxyFileSystem(std::move(FS
)) {}
443 llvm::ErrorOr
<std::unique_ptr
<llvm::vfs::File
>>
444 openFileForRead(const llvm::Twine
&Path
) override
{
445 WallTimerRegion
T(Timer
);
446 auto FileOr
= getUnderlyingFS().openFileForRead(Path
);
449 return std::make_unique
<TimerFile
>(Timer
, std::move(FileOr
.get()));
452 llvm::ErrorOr
<llvm::vfs::Status
> status(const llvm::Twine
&Path
) override
{
453 WallTimerRegion
T(Timer
);
454 return getUnderlyingFS().status(Path
);
457 double getTime() { return Timer
.getTime(); }
465 std::shared_ptr
<const PreambleData
>
466 buildPreamble(PathRef FileName
, CompilerInvocation CI
,
467 const ParseInputs
&Inputs
, bool StoreInMemory
,
468 PreambleParsedCallback PreambleCallback
,
469 PreambleBuildStats
*Stats
) {
470 // Note that we don't need to copy the input contents, preamble can live
472 auto ContentsBuffer
=
473 llvm::MemoryBuffer::getMemBuffer(Inputs
.Contents
, FileName
);
474 auto Bounds
= ComputePreambleBounds(*CI
.getLangOpts(), *ContentsBuffer
, 0);
476 trace::Span
Tracer("BuildPreamble");
477 SPAN_ATTACH(Tracer
, "File", FileName
);
478 std::vector
<std::unique_ptr
<FeatureModule::ASTListener
>> ASTListeners
;
479 if (Inputs
.FeatureModules
) {
480 for (auto &M
: *Inputs
.FeatureModules
) {
481 if (auto Listener
= M
.astListeners())
482 ASTListeners
.emplace_back(std::move(Listener
));
485 StoreDiags PreambleDiagnostics
;
486 PreambleDiagnostics
.setDiagCallback(
487 [&ASTListeners
](const clang::Diagnostic
&D
, clangd::Diag
&Diag
) {
488 llvm::for_each(ASTListeners
,
489 [&](const auto &L
) { L
->sawDiagnostic(D
, Diag
); });
491 llvm::IntrusiveRefCntPtr
<DiagnosticsEngine
> PreambleDiagsEngine
=
492 CompilerInstance::createDiagnostics(&CI
.getDiagnosticOpts(),
493 &PreambleDiagnostics
, false);
494 const Config
&Cfg
= Config::current();
495 PreambleDiagnostics
.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel
,
496 const clang::Diagnostic
&Info
) {
497 if (Cfg
.Diagnostics
.SuppressAll
||
498 isBuiltinDiagnosticSuppressed(Info
.getID(), Cfg
.Diagnostics
.Suppress
,
500 return DiagnosticsEngine::Ignored
;
501 switch (Info
.getID()) {
502 case diag::warn_no_newline_eof
:
503 case diag::warn_cxx98_compat_no_newline_eof
:
504 case diag::ext_no_newline_eof
:
505 // If the preamble doesn't span the whole file, drop the no newline at
507 return Bounds
.Size
!= ContentsBuffer
->getBufferSize()
508 ? DiagnosticsEngine::Level::Ignored
514 // Skip function bodies when building the preamble to speed up building
515 // the preamble and make it smaller.
516 assert(!CI
.getFrontendOpts().SkipFunctionBodies
);
517 CI
.getFrontendOpts().SkipFunctionBodies
= true;
518 // We don't want to write comment locations into PCH. They are racy and slow
519 // to read back. We rely on dynamic index for the comments instead.
520 CI
.getPreprocessorOpts().WriteCommentListToPCH
= false;
522 CppFilePreambleCallbacks
CapturedInfo(
523 FileName
, PreambleCallback
, Stats
,
524 Inputs
.Opts
.PreambleParseForwardingFunctions
,
525 [&ASTListeners
](CompilerInstance
&CI
) {
526 for (const auto &L
: ASTListeners
)
527 L
->beforeExecute(CI
);
529 auto VFS
= Inputs
.TFS
->view(Inputs
.CompileCommand
.Directory
);
530 llvm::SmallString
<32> AbsFileName(FileName
);
531 VFS
->makeAbsolute(AbsFileName
);
532 auto StatCache
= std::make_unique
<PreambleFileStatusCache
>(AbsFileName
);
533 auto StatCacheFS
= StatCache
->getProducingFS(VFS
);
534 llvm::IntrusiveRefCntPtr
<TimerFS
> TimedFS(new TimerFS(StatCacheFS
));
536 WallTimer PreambleTimer
;
537 PreambleTimer
.startTimer();
538 auto BuiltPreamble
= PrecompiledPreamble::Build(
539 CI
, ContentsBuffer
.get(), Bounds
, *PreambleDiagsEngine
,
540 Stats
? TimedFS
: StatCacheFS
, std::make_shared
<PCHContainerOperations
>(),
541 StoreInMemory
, CapturedInfo
);
542 PreambleTimer
.stopTimer();
544 // When building the AST for the main file, we do want the function
546 CI
.getFrontendOpts().SkipFunctionBodies
= false;
548 if (Stats
!= nullptr) {
549 Stats
->TotalBuildTime
= PreambleTimer
.getTime();
550 Stats
->FileSystemTime
= TimedFS
->getTime();
551 Stats
->SerializedSize
= BuiltPreamble
? BuiltPreamble
->getSize() : 0;
555 log("Built preamble of size {0} for file {1} version {2} in {3} seconds",
556 BuiltPreamble
->getSize(), FileName
, Inputs
.Version
,
557 PreambleTimer
.getTime());
558 std::vector
<Diag
> Diags
= PreambleDiagnostics
.take();
559 auto Result
= std::make_shared
<PreambleData
>(std::move(*BuiltPreamble
));
560 Result
->Version
= Inputs
.Version
;
561 Result
->CompileCommand
= Inputs
.CompileCommand
;
562 Result
->Diags
= std::move(Diags
);
563 Result
->Includes
= CapturedInfo
.takeIncludes();
564 Result
->Macros
= CapturedInfo
.takeMacros();
565 Result
->Marks
= CapturedInfo
.takeMarks();
566 Result
->CanonIncludes
= CapturedInfo
.takeCanonicalIncludes();
567 Result
->StatCache
= std::move(StatCache
);
568 Result
->MainIsIncludeGuarded
= CapturedInfo
.isMainFileIncludeGuarded();
572 elog("Could not build a preamble for file {0} version {1}: {2}", FileName
,
573 Inputs
.Version
, BuiltPreamble
.getError().message());
577 bool isPreambleCompatible(const PreambleData
&Preamble
,
578 const ParseInputs
&Inputs
, PathRef FileName
,
579 const CompilerInvocation
&CI
) {
580 auto ContentsBuffer
=
581 llvm::MemoryBuffer::getMemBuffer(Inputs
.Contents
, FileName
);
582 auto Bounds
= ComputePreambleBounds(*CI
.getLangOpts(), *ContentsBuffer
, 0);
583 auto VFS
= Inputs
.TFS
->view(Inputs
.CompileCommand
.Directory
);
584 return compileCommandsAreEqual(Inputs
.CompileCommand
,
585 Preamble
.CompileCommand
) &&
586 Preamble
.Preamble
.CanReuse(CI
, *ContentsBuffer
, Bounds
, *VFS
);
589 void escapeBackslashAndQuotes(llvm::StringRef Text
, llvm::raw_ostream
&OS
) {
590 for (char C
: Text
) {
603 PreamblePatch
PreamblePatch::create(llvm::StringRef FileName
,
604 const ParseInputs
&Modified
,
605 const PreambleData
&Baseline
,
606 PatchType PatchType
) {
607 trace::Span
Tracer("CreatePreamblePatch");
608 SPAN_ATTACH(Tracer
, "File", FileName
);
609 assert(llvm::sys::path::is_absolute(FileName
) && "relative FileName!");
610 // First scan preprocessor directives in Baseline and Modified. These will be
611 // used to figure out newly added directives in Modified. Scanning can fail,
612 // the code just bails out and creates an empty patch in such cases, as:
613 // - If scanning for Baseline fails, no knowledge of existing includes hence
614 // patch will contain all the includes in Modified. Leading to rebuild of
615 // whole preamble, which is terribly slow.
616 // - If scanning for Modified fails, cannot figure out newly added ones so
617 // there's nothing to do but generate an empty patch.
618 auto BaselineScan
= scanPreamble(
619 // Contents needs to be null-terminated.
620 Baseline
.Preamble
.getContents().str(), Modified
.CompileCommand
);
622 elog("Failed to scan baseline of {0}: {1}", FileName
,
623 BaselineScan
.takeError());
624 return PreamblePatch::unmodified(Baseline
);
626 auto ModifiedScan
= scanPreamble(Modified
.Contents
, Modified
.CompileCommand
);
628 elog("Failed to scan modified contents of {0}: {1}", FileName
,
629 ModifiedScan
.takeError());
630 return PreamblePatch::unmodified(Baseline
);
633 bool IncludesChanged
= BaselineScan
->Includes
!= ModifiedScan
->Includes
;
634 bool DirectivesChanged
=
635 BaselineScan
->TextualDirectives
!= ModifiedScan
->TextualDirectives
;
636 if ((PatchType
== PatchType::MacroDirectives
|| !IncludesChanged
) &&
638 return PreamblePatch::unmodified(Baseline
);
641 // This shouldn't coincide with any real file name.
642 llvm::SmallString
<128> PatchName
;
643 llvm::sys::path::append(PatchName
, llvm::sys::path::parent_path(FileName
),
644 PreamblePatchHeaderName
);
645 PP
.PatchFileName
= PatchName
.str().str();
646 PP
.ModifiedBounds
= ModifiedScan
->Bounds
;
648 llvm::raw_string_ostream
Patch(PP
.PatchContents
);
649 // Set default filename for subsequent #line directives
650 Patch
<< "#line 0 \"";
651 // FileName part of a line directive is subject to backslash escaping, which
652 // might lead to problems on windows especially.
653 escapeBackslashAndQuotes(FileName
, Patch
);
656 if (IncludesChanged
&& PatchType
== PatchType::All
) {
657 // We are only interested in newly added includes, record the ones in
658 // Baseline for exclusion.
659 llvm::DenseMap
<std::pair
<tok::PPKeywordKind
, llvm::StringRef
>,
660 /*Resolved=*/llvm::StringRef
>
662 for (const auto &Inc
: Baseline
.Includes
.MainFileIncludes
)
663 ExistingIncludes
[{Inc
.Directive
, Inc
.Written
}] = Inc
.Resolved
;
664 // There might be includes coming from disabled regions, record these for
665 // exclusion too. note that we don't have resolved paths for those.
666 for (const auto &Inc
: BaselineScan
->Includes
)
667 ExistingIncludes
.try_emplace({Inc
.Directive
, Inc
.Written
});
668 // Calculate extra includes that needs to be inserted.
669 for (auto &Inc
: ModifiedScan
->Includes
) {
670 auto It
= ExistingIncludes
.find({Inc
.Directive
, Inc
.Written
});
671 // Include already present in the baseline preamble. Set resolved path and
672 // put into preamble includes.
673 if (It
!= ExistingIncludes
.end()) {
674 Inc
.Resolved
= It
->second
.str();
675 PP
.PreambleIncludes
.push_back(Inc
);
678 // Include is new in the modified preamble. Inject it into the patch and
679 // use #line to set the presumed location to where it is spelled.
680 auto LineCol
= offsetToClangLineColumn(Modified
.Contents
, Inc
.HashOffset
);
681 Patch
<< llvm::formatv("#line {0}\n", LineCol
.first
);
682 Patch
<< llvm::formatv(
683 "#{0} {1}\n", spellingForIncDirective(Inc
.Directive
), Inc
.Written
);
687 if (DirectivesChanged
) {
688 // We need to patch all the directives, since they are order dependent. e.g:
689 // #define BAR(X) NEW(X) // Newly introduced in Modified
690 // #define BAR(X) OLD(X) // Exists in the Baseline
692 // If we've patched only the first directive, the macro definition would've
693 // been wrong for the rest of the file, since patch is applied after the
694 // baseline preamble.
696 // Note that we deliberately ignore conditional directives and undefs to
697 // reduce complexity. The former might cause problems because scanning is
698 // imprecise and might pick directives from disabled regions.
699 for (const auto &TD
: ModifiedScan
->TextualDirectives
) {
700 Patch
<< "#line " << TD
.DirectiveLine
<< '\n';
701 Patch
<< TD
.Text
<< '\n';
704 dlog("Created preamble patch: {0}", Patch
.str());
709 PreamblePatch
PreamblePatch::createFullPatch(llvm::StringRef FileName
,
710 const ParseInputs
&Modified
,
711 const PreambleData
&Baseline
) {
712 return create(FileName
, Modified
, Baseline
, PatchType::All
);
715 PreamblePatch
PreamblePatch::createMacroPatch(llvm::StringRef FileName
,
716 const ParseInputs
&Modified
,
717 const PreambleData
&Baseline
) {
718 return create(FileName
, Modified
, Baseline
, PatchType::MacroDirectives
);
721 void PreamblePatch::apply(CompilerInvocation
&CI
) const {
722 // No need to map an empty file.
723 if (PatchContents
.empty())
725 auto &PPOpts
= CI
.getPreprocessorOpts();
727 // we copy here to ensure contents are still valid if CI outlives the
729 llvm::MemoryBuffer::getMemBufferCopy(PatchContents
, PatchFileName
);
730 // CI will take care of the lifetime of the buffer.
731 PPOpts
.addRemappedFile(PatchFileName
, PatchBuffer
.release());
732 // The patch will be parsed after loading the preamble ast and before parsing
734 PPOpts
.Includes
.push_back(PatchFileName
);
737 std::vector
<Inclusion
> PreamblePatch::preambleIncludes() const {
738 return PreambleIncludes
;
741 PreamblePatch
PreamblePatch::unmodified(const PreambleData
&Preamble
) {
743 PP
.PreambleIncludes
= Preamble
.Includes
.MainFileIncludes
;
744 PP
.ModifiedBounds
= Preamble
.Preamble
.getBounds();
748 SourceLocation
translatePreamblePatchLocation(SourceLocation Loc
,
749 const SourceManager
&SM
) {
750 auto DefFile
= SM
.getFileID(Loc
);
751 if (auto FE
= SM
.getFileEntryRefForID(DefFile
)) {
752 auto IncludeLoc
= SM
.getIncludeLoc(DefFile
);
753 // Preamble patch is included inside the builtin file.
754 if (IncludeLoc
.isValid() && SM
.isWrittenInBuiltinFile(IncludeLoc
) &&
755 FE
->getName().endswith(PreamblePatchHeaderName
)) {
756 auto Presumed
= SM
.getPresumedLoc(Loc
);
757 // Check that line directive is pointing at main file.
758 if (Presumed
.isValid() && Presumed
.getFileID().isInvalid() &&
759 isMainFile(Presumed
.getFilename(), SM
)) {
760 Loc
= SM
.translateLineCol(SM
.getMainFileID(), Presumed
.getLine(),
761 Presumed
.getColumn());
768 } // namespace clangd