1 //===--- Preamble.cpp - Reusing expensive parts of the AST ----------------===// 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 "Preamble.h" 10 #include "Compiler.h" 11 #include "Config.h" 12 #include "Headers.h" 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/DenseSet.h" 35 #include "llvm/ADT/IntrusiveRefCntPtr.h" 36 #include "llvm/ADT/None.h" 37 #include "llvm/ADT/Optional.h" 38 #include "llvm/ADT/STLExtras.h" 39 #include "llvm/ADT/SmallString.h" 40 #include "llvm/ADT/StringExtras.h" 41 #include "llvm/ADT/StringRef.h" 42 #include "llvm/ADT/StringSet.h" 43 #include "llvm/Support/Error.h" 44 #include "llvm/Support/ErrorHandling.h" 45 #include "llvm/Support/FormatVariadic.h" 46 #include "llvm/Support/MemoryBuffer.h" 47 #include "llvm/Support/Path.h" 48 #include "llvm/Support/VirtualFileSystem.h" 49 #include "llvm/Support/raw_ostream.h" 50 #include <iterator> 51 #include <memory> 52 #include <string> 53 #include <system_error> 54 #include <utility> 55 #include <vector> 56 57 namespace clang { 58 namespace clangd { 59 namespace { 60 constexpr llvm::StringLiteral PreamblePatchHeaderName = "__preamble_patch__.h"; 61 62 bool compileCommandsAreEqual(const tooling::CompileCommand &LHS, 63 const tooling::CompileCommand &RHS) { 64 // We don't check for Output, it should not matter to clangd. 65 return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename && 66 llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine); 67 } 68 69 class CppFilePreambleCallbacks : public PreambleCallbacks { 70 public: 71 CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) 72 : File(File), ParsedCallback(ParsedCallback) {} 73 74 IncludeStructure takeIncludes() { return std::move(Includes); } 75 76 MainFileMacros takeMacros() { return std::move(Macros); } 77 78 std::vector<PragmaMark> takeMarks() { return std::move(Marks); } 79 80 CanonicalIncludes takeCanonicalIncludes() { return std::move(CanonIncludes); } 81 82 bool isMainFileIncludeGuarded() const { return IsMainFileIncludeGuarded; } 83 84 void AfterExecute(CompilerInstance &CI) override { 85 if (ParsedCallback) { 86 trace::Span Tracer("Running PreambleCallback"); 87 ParsedCallback(CI.getASTContext(), CI.getPreprocessor(), CanonIncludes); 88 } 89 90 const SourceManager &SM = CI.getSourceManager(); 91 const FileEntry *MainFE = SM.getFileEntryForID(SM.getMainFileID()); 92 IsMainFileIncludeGuarded = 93 CI.getPreprocessor().getHeaderSearchInfo().isFileMultipleIncludeGuarded( 94 MainFE); 95 } 96 97 void BeforeExecute(CompilerInstance &CI) override { 98 CanonIncludes.addSystemHeadersMapping(CI.getLangOpts()); 99 LangOpts = &CI.getLangOpts(); 100 SourceMgr = &CI.getSourceManager(); 101 Includes.collect(CI); 102 } 103 104 std::unique_ptr<PPCallbacks> createPPCallbacks() override { 105 assert(SourceMgr && LangOpts && 106 "SourceMgr and LangOpts must be set at this point"); 107 108 return std::make_unique<PPChainedCallbacks>( 109 std::make_unique<CollectMainFileMacros>(*SourceMgr, Macros), 110 collectPragmaMarksCallback(*SourceMgr, Marks)); 111 } 112 113 CommentHandler *getCommentHandler() override { 114 IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes); 115 return IWYUHandler.get(); 116 } 117 118 bool shouldSkipFunctionBody(Decl *D) override { 119 // Generally we skip function bodies in preambles for speed. 120 // We can make exceptions for functions that are cheap to parse and 121 // instantiate, widely used, and valuable (e.g. commonly produce errors). 122 if (const auto *FT = llvm::dyn_cast<clang::FunctionTemplateDecl>(D)) { 123 if (const auto *II = FT->getDeclName().getAsIdentifierInfo()) 124 // std::make_unique is trivial, and we diagnose bad constructor calls. 125 if (II->isStr("make_unique") && FT->isInStdNamespace()) 126 return false; 127 } 128 return true; 129 } 130 131 private: 132 PathRef File; 133 PreambleParsedCallback ParsedCallback; 134 IncludeStructure Includes; 135 CanonicalIncludes CanonIncludes; 136 MainFileMacros Macros; 137 std::vector<PragmaMark> Marks; 138 bool IsMainFileIncludeGuarded = false; 139 std::unique_ptr<CommentHandler> IWYUHandler = nullptr; 140 const clang::LangOptions *LangOpts = nullptr; 141 const SourceManager *SourceMgr = nullptr; 142 }; 143 144 // Represents directives other than includes, where basic textual information is 145 // enough. 146 struct TextualPPDirective { 147 unsigned DirectiveLine; 148 // Full text that's representing the directive, including the `#`. 149 std::string Text; 150 unsigned Offset; 151 152 bool operator==(const TextualPPDirective &RHS) const { 153 return std::tie(DirectiveLine, Offset, Text) == 154 std::tie(RHS.DirectiveLine, RHS.Offset, RHS.Text); 155 } 156 }; 157 158 // Formats a PP directive consisting of Prefix (e.g. "#define ") and Body ("X 159 // 10"). The formatting is copied so that the tokens in Body have PresumedLocs 160 // with correct columns and lines. 161 std::string spellDirective(llvm::StringRef Prefix, 162 CharSourceRange DirectiveRange, 163 const LangOptions &LangOpts, const SourceManager &SM, 164 unsigned &DirectiveLine, unsigned &Offset) { 165 std::string SpelledDirective; 166 llvm::raw_string_ostream OS(SpelledDirective); 167 OS << Prefix; 168 169 // Make sure DirectiveRange is a char range and doesn't contain macro ids. 170 DirectiveRange = SM.getExpansionRange(DirectiveRange); 171 if (DirectiveRange.isTokenRange()) { 172 DirectiveRange.setEnd( 173 Lexer::getLocForEndOfToken(DirectiveRange.getEnd(), 0, SM, LangOpts)); 174 } 175 176 auto DecompLoc = SM.getDecomposedLoc(DirectiveRange.getBegin()); 177 DirectiveLine = SM.getLineNumber(DecompLoc.first, DecompLoc.second); 178 Offset = DecompLoc.second; 179 auto TargetColumn = SM.getColumnNumber(DecompLoc.first, DecompLoc.second) - 1; 180 181 // Pad with spaces before DirectiveRange to make sure it will be on right 182 // column when patched. 183 if (Prefix.size() <= TargetColumn) { 184 // There is enough space for Prefix and space before directive, use it. 185 // We try to squeeze the Prefix into the same line whenever we can, as 186 // putting onto a separate line won't work at the beginning of the file. 187 OS << std::string(TargetColumn - Prefix.size(), ' '); 188 } else { 189 // Prefix was longer than the space we had. We produce e.g.: 190 // #line N-1 191 // #define \ 192 // X 10 193 OS << "\\\n" << std::string(TargetColumn, ' '); 194 // Decrement because we put an additional line break before 195 // DirectiveRange.begin(). 196 --DirectiveLine; 197 } 198 OS << toSourceCode(SM, DirectiveRange.getAsRange()); 199 return OS.str(); 200 } 201 202 // Collects #define directives inside the main file. 203 struct DirectiveCollector : public PPCallbacks { 204 DirectiveCollector(const Preprocessor &PP, 205 std::vector<TextualPPDirective> &TextualDirectives) 206 : LangOpts(PP.getLangOpts()), SM(PP.getSourceManager()), 207 TextualDirectives(TextualDirectives) {} 208 209 void FileChanged(SourceLocation Loc, FileChangeReason Reason, 210 SrcMgr::CharacteristicKind FileType, 211 FileID PrevFID) override { 212 InMainFile = SM.isWrittenInMainFile(Loc); 213 } 214 215 void MacroDefined(const Token &MacroNameTok, 216 const MacroDirective *MD) override { 217 if (!InMainFile) 218 return; 219 TextualDirectives.emplace_back(); 220 TextualPPDirective &TD = TextualDirectives.back(); 221 222 const auto *MI = MD->getMacroInfo(); 223 TD.Text = 224 spellDirective("#define ", 225 CharSourceRange::getTokenRange( 226 MI->getDefinitionLoc(), MI->getDefinitionEndLoc()), 227 LangOpts, SM, TD.DirectiveLine, TD.Offset); 228 } 229 230 private: 231 bool InMainFile = true; 232 const LangOptions &LangOpts; 233 const SourceManager &SM; 234 std::vector<TextualPPDirective> &TextualDirectives; 235 }; 236 237 struct ScannedPreamble { 238 std::vector<Inclusion> Includes; 239 std::vector<TextualPPDirective> TextualDirectives; 240 PreambleBounds Bounds = {0, false}; 241 }; 242 243 /// Scans the preprocessor directives in the preamble section of the file by 244 /// running preprocessor over \p Contents. Returned includes do not contain 245 /// resolved paths. \p Cmd is used to build the compiler invocation, which might 246 /// stat/read files. 247 llvm::Expected<ScannedPreamble> 248 scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) { 249 class EmptyFS : public ThreadsafeFS { 250 private: 251 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> viewImpl() const override { 252 return new llvm::vfs::InMemoryFileSystem; 253 } 254 }; 255 EmptyFS FS; 256 // Build and run Preprocessor over the preamble. 257 ParseInputs PI; 258 PI.Contents = Contents.str(); 259 PI.TFS = &FS; 260 PI.CompileCommand = Cmd; 261 IgnoringDiagConsumer IgnoreDiags; 262 auto CI = buildCompilerInvocation(PI, IgnoreDiags); 263 if (!CI) 264 return error("failed to create compiler invocation"); 265 CI->getDiagnosticOpts().IgnoreWarnings = true; 266 auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Contents); 267 // This means we're scanning (though not preprocessing) the preamble section 268 // twice. However, it's important to precisely follow the preamble bounds used 269 // elsewhere. 270 auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0); 271 auto PreambleContents = 272 llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size)); 273 auto Clang = prepareCompilerInstance( 274 std::move(CI), nullptr, std::move(PreambleContents), 275 // Provide an empty FS to prevent preprocessor from performing IO. This 276 // also implies missing resolved paths for includes. 277 FS.view(llvm::None), IgnoreDiags); 278 if (Clang->getFrontendOpts().Inputs.empty()) 279 return error("compiler instance had no inputs"); 280 // We are only interested in main file includes. 281 Clang->getPreprocessorOpts().SingleFileParseMode = true; 282 PreprocessOnlyAction Action; 283 if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) 284 return error("failed BeginSourceFile"); 285 Preprocessor &PP = Clang->getPreprocessor(); 286 IncludeStructure Includes; 287 Includes.collect(*Clang); 288 ScannedPreamble SP; 289 SP.Bounds = Bounds; 290 PP.addPPCallbacks( 291 std::make_unique<DirectiveCollector>(PP, SP.TextualDirectives)); 292 if (llvm::Error Err = Action.Execute()) 293 return std::move(Err); 294 Action.EndSourceFile(); 295 SP.Includes = std::move(Includes.MainFileIncludes); 296 return SP; 297 } 298 299 const char *spellingForIncDirective(tok::PPKeywordKind IncludeDirective) { 300 switch (IncludeDirective) { 301 case tok::pp_include: 302 return "include"; 303 case tok::pp_import: 304 return "import"; 305 case tok::pp_include_next: 306 return "include_next"; 307 default: 308 break; 309 } 310 llvm_unreachable("not an include directive"); 311 } 312 313 // Checks whether \p FileName is a valid spelling of main file. 314 bool isMainFile(llvm::StringRef FileName, const SourceManager &SM) { 315 auto FE = SM.getFileManager().getFile(FileName); 316 return FE && *FE == SM.getFileEntryForID(SM.getMainFileID()); 317 } 318 319 } // namespace 320 321 std::shared_ptr<const PreambleData> 322 buildPreamble(PathRef FileName, CompilerInvocation CI, 323 const ParseInputs &Inputs, bool StoreInMemory, 324 PreambleParsedCallback PreambleCallback) { 325 // Note that we don't need to copy the input contents, preamble can live 326 // without those. 327 auto ContentsBuffer = 328 llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName); 329 auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), *ContentsBuffer, 0); 330 331 trace::Span Tracer("BuildPreamble"); 332 SPAN_ATTACH(Tracer, "File", FileName); 333 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners; 334 if (Inputs.FeatureModules) { 335 for (auto &M : *Inputs.FeatureModules) { 336 if (auto Listener = M.astListeners()) 337 ASTListeners.emplace_back(std::move(Listener)); 338 } 339 } 340 StoreDiags PreambleDiagnostics; 341 PreambleDiagnostics.setDiagCallback( 342 [&ASTListeners](const clang::Diagnostic &D, clangd::Diag &Diag) { 343 llvm::for_each(ASTListeners, 344 [&](const auto &L) { L->sawDiagnostic(D, Diag); }); 345 }); 346 llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine = 347 CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), 348 &PreambleDiagnostics, false); 349 const Config &Cfg = Config::current(); 350 PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, 351 const clang::Diagnostic &Info) { 352 if (Cfg.Diagnostics.SuppressAll || 353 isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress)) 354 return DiagnosticsEngine::Ignored; 355 switch (Info.getID()) { 356 case diag::warn_no_newline_eof: 357 case diag::warn_cxx98_compat_no_newline_eof: 358 case diag::ext_no_newline_eof: 359 // If the preamble doesn't span the whole file, drop the no newline at 360 // eof warnings. 361 return Bounds.Size != ContentsBuffer->getBufferSize() 362 ? DiagnosticsEngine::Level::Ignored 363 : DiagLevel; 364 } 365 return DiagLevel; 366 }); 367 368 // Skip function bodies when building the preamble to speed up building 369 // the preamble and make it smaller. 370 assert(!CI.getFrontendOpts().SkipFunctionBodies); 371 CI.getFrontendOpts().SkipFunctionBodies = true; 372 // We don't want to write comment locations into PCH. They are racy and slow 373 // to read back. We rely on dynamic index for the comments instead. 374 CI.getPreprocessorOpts().WriteCommentListToPCH = false; 375 376 CppFilePreambleCallbacks CapturedInfo(FileName, PreambleCallback); 377 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory); 378 llvm::SmallString<32> AbsFileName(FileName); 379 VFS->makeAbsolute(AbsFileName); 380 auto StatCache = std::make_unique<PreambleFileStatusCache>(AbsFileName); 381 auto BuiltPreamble = PrecompiledPreamble::Build( 382 CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine, 383 StatCache->getProducingFS(VFS), 384 std::make_shared<PCHContainerOperations>(), StoreInMemory, CapturedInfo); 385 386 // When building the AST for the main file, we do want the function 387 // bodies. 388 CI.getFrontendOpts().SkipFunctionBodies = false; 389 390 if (BuiltPreamble) { 391 vlog("Built preamble of size {0} for file {1} version {2}", 392 BuiltPreamble->getSize(), FileName, Inputs.Version); 393 std::vector<Diag> Diags = PreambleDiagnostics.take(); 394 auto Result = std::make_shared<PreambleData>(std::move(*BuiltPreamble)); 395 Result->Version = Inputs.Version; 396 Result->CompileCommand = Inputs.CompileCommand; 397 Result->Diags = std::move(Diags); 398 Result->Includes = CapturedInfo.takeIncludes(); 399 Result->Macros = CapturedInfo.takeMacros(); 400 Result->Marks = CapturedInfo.takeMarks(); 401 Result->CanonIncludes = CapturedInfo.takeCanonicalIncludes(); 402 Result->StatCache = std::move(StatCache); 403 Result->MainIsIncludeGuarded = CapturedInfo.isMainFileIncludeGuarded(); 404 return Result; 405 } 406 407 elog("Could not build a preamble for file {0} version {1}: {2}", FileName, 408 Inputs.Version, BuiltPreamble.getError().message()); 409 return nullptr; 410 } 411 412 bool isPreambleCompatible(const PreambleData &Preamble, 413 const ParseInputs &Inputs, PathRef FileName, 414 const CompilerInvocation &CI) { 415 auto ContentsBuffer = 416 llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName); 417 auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), *ContentsBuffer, 0); 418 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory); 419 return compileCommandsAreEqual(Inputs.CompileCommand, 420 Preamble.CompileCommand) && 421 Preamble.Preamble.CanReuse(CI, *ContentsBuffer, Bounds, *VFS); 422 } 423 424 void escapeBackslashAndQuotes(llvm::StringRef Text, llvm::raw_ostream &OS) { 425 for (char C : Text) { 426 switch (C) { 427 case '\\': 428 case '"': 429 OS << '\\'; 430 break; 431 default: 432 break; 433 } 434 OS << C; 435 } 436 } 437 438 PreamblePatch PreamblePatch::create(llvm::StringRef FileName, 439 const ParseInputs &Modified, 440 const PreambleData &Baseline, 441 PatchType PatchType) { 442 trace::Span Tracer("CreatePreamblePatch"); 443 SPAN_ATTACH(Tracer, "File", FileName); 444 assert(llvm::sys::path::is_absolute(FileName) && "relative FileName!"); 445 // First scan preprocessor directives in Baseline and Modified. These will be 446 // used to figure out newly added directives in Modified. Scanning can fail, 447 // the code just bails out and creates an empty patch in such cases, as: 448 // - If scanning for Baseline fails, no knowledge of existing includes hence 449 // patch will contain all the includes in Modified. Leading to rebuild of 450 // whole preamble, which is terribly slow. 451 // - If scanning for Modified fails, cannot figure out newly added ones so 452 // there's nothing to do but generate an empty patch. 453 auto BaselineScan = scanPreamble( 454 // Contents needs to be null-terminated. 455 Baseline.Preamble.getContents().str(), Modified.CompileCommand); 456 if (!BaselineScan) { 457 elog("Failed to scan baseline of {0}: {1}", FileName, 458 BaselineScan.takeError()); 459 return PreamblePatch::unmodified(Baseline); 460 } 461 auto ModifiedScan = scanPreamble(Modified.Contents, Modified.CompileCommand); 462 if (!ModifiedScan) { 463 elog("Failed to scan modified contents of {0}: {1}", FileName, 464 ModifiedScan.takeError()); 465 return PreamblePatch::unmodified(Baseline); 466 } 467 468 bool IncludesChanged = BaselineScan->Includes != ModifiedScan->Includes; 469 bool DirectivesChanged = 470 BaselineScan->TextualDirectives != ModifiedScan->TextualDirectives; 471 if ((PatchType == PatchType::MacroDirectives || !IncludesChanged) && 472 !DirectivesChanged) 473 return PreamblePatch::unmodified(Baseline); 474 475 PreamblePatch PP; 476 // This shouldn't coincide with any real file name. 477 llvm::SmallString<128> PatchName; 478 llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName), 479 PreamblePatchHeaderName); 480 PP.PatchFileName = PatchName.str().str(); 481 PP.ModifiedBounds = ModifiedScan->Bounds; 482 483 llvm::raw_string_ostream Patch(PP.PatchContents); 484 // Set default filename for subsequent #line directives 485 Patch << "#line 0 \""; 486 // FileName part of a line directive is subject to backslash escaping, which 487 // might lead to problems on windows especially. 488 escapeBackslashAndQuotes(FileName, Patch); 489 Patch << "\"\n"; 490 491 if (IncludesChanged && PatchType == PatchType::All) { 492 // We are only interested in newly added includes, record the ones in 493 // Baseline for exclusion. 494 llvm::DenseMap<std::pair<tok::PPKeywordKind, llvm::StringRef>, 495 /*Resolved=*/llvm::StringRef> 496 ExistingIncludes; 497 for (const auto &Inc : Baseline.Includes.MainFileIncludes) 498 ExistingIncludes[{Inc.Directive, Inc.Written}] = Inc.Resolved; 499 // There might be includes coming from disabled regions, record these for 500 // exclusion too. note that we don't have resolved paths for those. 501 for (const auto &Inc : BaselineScan->Includes) 502 ExistingIncludes.try_emplace({Inc.Directive, Inc.Written}); 503 // Calculate extra includes that needs to be inserted. 504 for (auto &Inc : ModifiedScan->Includes) { 505 auto It = ExistingIncludes.find({Inc.Directive, Inc.Written}); 506 // Include already present in the baseline preamble. Set resolved path and 507 // put into preamble includes. 508 if (It != ExistingIncludes.end()) { 509 Inc.Resolved = It->second.str(); 510 PP.PreambleIncludes.push_back(Inc); 511 continue; 512 } 513 // Include is new in the modified preamble. Inject it into the patch and 514 // use #line to set the presumed location to where it is spelled. 515 auto LineCol = offsetToClangLineColumn(Modified.Contents, Inc.HashOffset); 516 Patch << llvm::formatv("#line {0}\n", LineCol.first); 517 Patch << llvm::formatv( 518 "#{0} {1}\n", spellingForIncDirective(Inc.Directive), Inc.Written); 519 } 520 } 521 522 if (DirectivesChanged) { 523 // We need to patch all the directives, since they are order dependent. e.g: 524 // #define BAR(X) NEW(X) // Newly introduced in Modified 525 // #define BAR(X) OLD(X) // Exists in the Baseline 526 // 527 // If we've patched only the first directive, the macro definition would've 528 // been wrong for the rest of the file, since patch is applied after the 529 // baseline preamble. 530 // 531 // Note that we deliberately ignore conditional directives and undefs to 532 // reduce complexity. The former might cause problems because scanning is 533 // imprecise and might pick directives from disabled regions. 534 for (const auto &TD : ModifiedScan->TextualDirectives) { 535 Patch << "#line " << TD.DirectiveLine << '\n'; 536 Patch << TD.Text << '\n'; 537 } 538 } 539 dlog("Created preamble patch: {0}", Patch.str()); 540 Patch.flush(); 541 return PP; 542 } 543 544 PreamblePatch PreamblePatch::createFullPatch(llvm::StringRef FileName, 545 const ParseInputs &Modified, 546 const PreambleData &Baseline) { 547 return create(FileName, Modified, Baseline, PatchType::All); 548 } 549 550 PreamblePatch PreamblePatch::createMacroPatch(llvm::StringRef FileName, 551 const ParseInputs &Modified, 552 const PreambleData &Baseline) { 553 return create(FileName, Modified, Baseline, PatchType::MacroDirectives); 554 } 555 556 void PreamblePatch::apply(CompilerInvocation &CI) const { 557 // No need to map an empty file. 558 if (PatchContents.empty()) 559 return; 560 auto &PPOpts = CI.getPreprocessorOpts(); 561 auto PatchBuffer = 562 // we copy here to ensure contents are still valid if CI outlives the 563 // PreamblePatch. 564 llvm::MemoryBuffer::getMemBufferCopy(PatchContents, PatchFileName); 565 // CI will take care of the lifetime of the buffer. 566 PPOpts.addRemappedFile(PatchFileName, PatchBuffer.release()); 567 // The patch will be parsed after loading the preamble ast and before parsing 568 // the main file. 569 PPOpts.Includes.push_back(PatchFileName); 570 } 571 572 std::vector<Inclusion> PreamblePatch::preambleIncludes() const { 573 return PreambleIncludes; 574 } 575 576 PreamblePatch PreamblePatch::unmodified(const PreambleData &Preamble) { 577 PreamblePatch PP; 578 PP.PreambleIncludes = Preamble.Includes.MainFileIncludes; 579 PP.ModifiedBounds = Preamble.Preamble.getBounds(); 580 return PP; 581 } 582 583 SourceLocation translatePreamblePatchLocation(SourceLocation Loc, 584 const SourceManager &SM) { 585 auto DefFile = SM.getFileID(Loc); 586 if (auto *FE = SM.getFileEntryForID(DefFile)) { 587 auto IncludeLoc = SM.getIncludeLoc(DefFile); 588 // Preamble patch is included inside the builtin file. 589 if (IncludeLoc.isValid() && SM.isWrittenInBuiltinFile(IncludeLoc) && 590 FE->getName().endswith(PreamblePatchHeaderName)) { 591 auto Presumed = SM.getPresumedLoc(Loc); 592 // Check that line directive is pointing at main file. 593 if (Presumed.isValid() && Presumed.getFileID().isInvalid() && 594 isMainFile(Presumed.getFilename(), SM)) { 595 Loc = SM.translateLineCol(SM.getMainFileID(), Presumed.getLine(), 596 Presumed.getColumn()); 597 } 598 } 599 } 600 return Loc; 601 } 602 } // namespace clangd 603 } // namespace clang 604