1 //===--- ParsedAST.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 "ParsedAST.h" 10 #include "../clang-tidy/ClangTidyCheck.h" 11 #include "../clang-tidy/ClangTidyDiagnosticConsumer.h" 12 #include "../clang-tidy/ClangTidyModuleRegistry.h" 13 #include "AST.h" 14 #include "Compiler.h" 15 #include "Config.h" 16 #include "Diagnostics.h" 17 #include "Feature.h" 18 #include "FeatureModule.h" 19 #include "Headers.h" 20 #include "HeuristicResolver.h" 21 #include "IncludeCleaner.h" 22 #include "IncludeFixer.h" 23 #include "Preamble.h" 24 #include "SourceCode.h" 25 #include "TidyProvider.h" 26 #include "index/CanonicalIncludes.h" 27 #include "index/Index.h" 28 #include "support/Logger.h" 29 #include "support/Trace.h" 30 #include "clang/AST/ASTContext.h" 31 #include "clang/AST/Decl.h" 32 #include "clang/Basic/Diagnostic.h" 33 #include "clang/Basic/DiagnosticSema.h" 34 #include "clang/Basic/LangOptions.h" 35 #include "clang/Basic/SourceLocation.h" 36 #include "clang/Basic/SourceManager.h" 37 #include "clang/Basic/TokenKinds.h" 38 #include "clang/Frontend/CompilerInstance.h" 39 #include "clang/Frontend/CompilerInvocation.h" 40 #include "clang/Frontend/FrontendActions.h" 41 #include "clang/Lex/Lexer.h" 42 #include "clang/Lex/PPCallbacks.h" 43 #include "clang/Lex/Preprocessor.h" 44 #include "clang/Serialization/ASTWriter.h" 45 #include "clang/Tooling/CompilationDatabase.h" 46 #include "clang/Tooling/Syntax/Tokens.h" 47 #include "llvm/ADT/ArrayRef.h" 48 #include "llvm/ADT/STLExtras.h" 49 #include "llvm/ADT/SmallVector.h" 50 #include "llvm/ADT/StringRef.h" 51 #include <algorithm> 52 #include <memory> 53 #include <vector> 54 55 // Force the linker to link in Clang-tidy modules. 56 // clangd doesn't support the static analyzer. 57 #if CLANGD_TIDY_CHECKS 58 #define CLANG_TIDY_DISABLE_STATIC_ANALYZER_CHECKS 59 #include "../clang-tidy/ClangTidyForceLinker.h" 60 #endif 61 62 namespace clang { 63 namespace clangd { 64 namespace { 65 66 template <class T> std::size_t getUsedBytes(const std::vector<T> &Vec) { 67 return Vec.capacity() * sizeof(T); 68 } 69 70 class DeclTrackingASTConsumer : public ASTConsumer { 71 public: 72 DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls) 73 : TopLevelDecls(TopLevelDecls) {} 74 75 bool HandleTopLevelDecl(DeclGroupRef DG) override { 76 for (Decl *D : DG) { 77 auto &SM = D->getASTContext().getSourceManager(); 78 if (!isInsideMainFile(D->getLocation(), SM)) 79 continue; 80 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 81 if (isImplicitTemplateInstantiation(ND)) 82 continue; 83 84 // ObjCMethodDecl are not actually top-level decls. 85 if (isa<ObjCMethodDecl>(D)) 86 continue; 87 88 TopLevelDecls.push_back(D); 89 } 90 return true; 91 } 92 93 private: 94 std::vector<Decl *> &TopLevelDecls; 95 }; 96 97 class ClangdFrontendAction : public SyntaxOnlyAction { 98 public: 99 std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); } 100 101 protected: 102 std::unique_ptr<ASTConsumer> 103 CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override { 104 return std::make_unique<DeclTrackingASTConsumer>(/*ref*/ TopLevelDecls); 105 } 106 107 private: 108 std::vector<Decl *> TopLevelDecls; 109 }; 110 111 // When using a preamble, only preprocessor events outside its bounds are seen. 112 // This is almost what we want: replaying transitive preprocessing wastes time. 113 // However this confuses clang-tidy checks: they don't see any #includes! 114 // So we replay the *non-transitive* #includes that appear in the main-file. 115 // It would be nice to replay other events (macro definitions, ifdefs etc) but 116 // this addresses the most common cases fairly cheaply. 117 class ReplayPreamble : private PPCallbacks { 118 public: 119 // Attach preprocessor hooks such that preamble events will be injected at 120 // the appropriate time. 121 // Events will be delivered to the *currently registered* PP callbacks. 122 static void attach(std::vector<Inclusion> Includes, CompilerInstance &Clang, 123 const PreambleBounds &PB) { 124 auto &PP = Clang.getPreprocessor(); 125 auto *ExistingCallbacks = PP.getPPCallbacks(); 126 // No need to replay events if nobody is listening. 127 if (!ExistingCallbacks) 128 return; 129 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(new ReplayPreamble( 130 std::move(Includes), ExistingCallbacks, Clang.getSourceManager(), PP, 131 Clang.getLangOpts(), PB))); 132 // We're relying on the fact that addPPCallbacks keeps the old PPCallbacks 133 // around, creating a chaining wrapper. Guard against other implementations. 134 assert(PP.getPPCallbacks() != ExistingCallbacks && 135 "Expected chaining implementation"); 136 } 137 138 private: 139 ReplayPreamble(std::vector<Inclusion> Includes, PPCallbacks *Delegate, 140 const SourceManager &SM, Preprocessor &PP, 141 const LangOptions &LangOpts, const PreambleBounds &PB) 142 : Includes(std::move(Includes)), Delegate(Delegate), SM(SM), PP(PP) { 143 // Only tokenize the preamble section of the main file, as we are not 144 // interested in the rest of the tokens. 145 MainFileTokens = syntax::tokenize( 146 syntax::FileRange(SM.getMainFileID(), 0, PB.Size), SM, LangOpts); 147 } 148 149 // In a normal compile, the preamble traverses the following structure: 150 // 151 // mainfile.cpp 152 // <built-in> 153 // ... macro definitions like __cplusplus ... 154 // <command-line> 155 // ... macro definitions for args like -Dfoo=bar ... 156 // "header1.h" 157 // ... header file contents ... 158 // "header2.h" 159 // ... header file contents ... 160 // ... main file contents ... 161 // 162 // When using a preamble, the "header1" and "header2" subtrees get skipped. 163 // We insert them right after the built-in header, which still appears. 164 void FileChanged(SourceLocation Loc, FileChangeReason Reason, 165 SrcMgr::CharacteristicKind Kind, FileID PrevFID) override { 166 // It'd be nice if there was a better way to identify built-in headers... 167 if (Reason == FileChangeReason::ExitFile && 168 SM.getBufferOrFake(PrevFID).getBufferIdentifier() == "<built-in>") 169 replay(); 170 } 171 172 void replay() { 173 for (const auto &Inc : Includes) { 174 llvm::Optional<FileEntryRef> File; 175 if (Inc.Resolved != "") 176 File = expectedToOptional(SM.getFileManager().getFileRef(Inc.Resolved)); 177 178 // Re-lex the #include directive to find its interesting parts. 179 auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset); 180 auto HashTok = llvm::partition_point(MainFileTokens, 181 [&HashLoc](const syntax::Token &T) { 182 return T.location() < HashLoc; 183 }); 184 assert(HashTok != MainFileTokens.end() && HashTok->kind() == tok::hash); 185 186 auto IncludeTok = std::next(HashTok); 187 assert(IncludeTok != MainFileTokens.end()); 188 189 auto FileTok = std::next(IncludeTok); 190 assert(FileTok != MainFileTokens.end()); 191 192 // Create a fake import/include token, none of the callers seem to care 193 // about clang::Token::Flags. 194 Token SynthesizedIncludeTok; 195 SynthesizedIncludeTok.startToken(); 196 SynthesizedIncludeTok.setLocation(IncludeTok->location()); 197 SynthesizedIncludeTok.setLength(IncludeTok->length()); 198 SynthesizedIncludeTok.setKind(tok::raw_identifier); 199 SynthesizedIncludeTok.setRawIdentifierData(IncludeTok->text(SM).data()); 200 PP.LookUpIdentifierInfo(SynthesizedIncludeTok); 201 202 // Same here, create a fake one for Filename, including angles or quotes. 203 Token SynthesizedFilenameTok; 204 SynthesizedFilenameTok.startToken(); 205 SynthesizedFilenameTok.setLocation(FileTok->location()); 206 // Note that we can't make use of FileTok->length/text in here as in the 207 // case of angled includes this will contain tok::less instead of 208 // filename. Whereas Inc.Written contains the full header name including 209 // quotes/angles. 210 SynthesizedFilenameTok.setLength(Inc.Written.length()); 211 SynthesizedFilenameTok.setKind(tok::header_name); 212 SynthesizedFilenameTok.setLiteralData(Inc.Written.data()); 213 214 llvm::StringRef WrittenFilename = 215 llvm::StringRef(Inc.Written).drop_front().drop_back(); 216 Delegate->InclusionDirective( 217 HashTok->location(), SynthesizedIncludeTok, WrittenFilename, 218 Inc.Written.front() == '<', 219 syntax::FileRange(SM, SynthesizedFilenameTok.getLocation(), 220 SynthesizedFilenameTok.getEndLoc()) 221 .toCharRange(SM), 222 File, "SearchPath", "RelPath", 223 /*Imported=*/nullptr, Inc.FileKind); 224 if (File) 225 Delegate->FileSkipped(*File, SynthesizedFilenameTok, Inc.FileKind); 226 } 227 } 228 229 const std::vector<Inclusion> Includes; 230 PPCallbacks *Delegate; 231 const SourceManager &SM; 232 Preprocessor &PP; 233 std::vector<syntax::Token> MainFileTokens; 234 }; 235 236 // Filter for clang diagnostics groups enabled by CTOptions.Checks. 237 // 238 // These are check names like clang-diagnostics-unused. 239 // Note that unlike -Wunused, clang-diagnostics-unused does not imply 240 // subcategories like clang-diagnostics-unused-function. 241 // 242 // This is used to determine which diagnostics can be enabled by ExtraArgs in 243 // the clang-tidy configuration. 244 class TidyDiagnosticGroups { 245 // Whether all diagnostic groups are enabled by default. 246 // True if we've seen clang-diagnostic-*. 247 bool Default = false; 248 // Set of diag::Group whose enablement != Default. 249 // If Default is false, this is foo where we've seen clang-diagnostic-foo. 250 llvm::DenseSet<unsigned> Exceptions; 251 252 public: 253 TidyDiagnosticGroups(llvm::StringRef Checks) { 254 constexpr llvm::StringLiteral CDPrefix = "clang-diagnostic-"; 255 256 llvm::StringRef Check; 257 while (!Checks.empty()) { 258 std::tie(Check, Checks) = Checks.split(','); 259 if (Check.empty()) 260 continue; 261 262 bool Enable = !Check.consume_front("-"); 263 bool Glob = Check.consume_back("*"); 264 if (Glob) { 265 // Is this clang-diagnostic-*, or *, or so? 266 // (We ignore all other types of globs). 267 if (CDPrefix.startswith(Check)) { 268 Default = Enable; 269 Exceptions.clear(); 270 } 271 continue; 272 } 273 274 // In "*,clang-diagnostic-foo", the latter is a no-op. 275 if (Default == Enable) 276 continue; 277 // The only non-glob entries we care about are clang-diagnostic-foo. 278 if (!Check.consume_front(CDPrefix)) 279 continue; 280 281 if (auto Group = DiagnosticIDs::getGroupForWarningOption(Check)) 282 Exceptions.insert(static_cast<unsigned>(*Group)); 283 } 284 } 285 286 bool operator()(diag::Group GroupID) const { 287 return Exceptions.contains(static_cast<unsigned>(GroupID)) ? !Default 288 : Default; 289 } 290 }; 291 292 // Find -W<group> and -Wno-<group> options in ExtraArgs and apply them to Diags. 293 // 294 // This is used to handle ExtraArgs in clang-tidy configuration. 295 // We don't use clang's standard handling of this as we want slightly different 296 // behavior (e.g. we want to exclude these from -Wno-error). 297 void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs, 298 llvm::function_ref<bool(diag::Group)> EnabledGroups, 299 DiagnosticsEngine &Diags) { 300 for (llvm::StringRef Group : ExtraArgs) { 301 // Only handle args that are of the form -W[no-]<group>. 302 // Other flags are possible but rare and deliberately out of scope. 303 llvm::SmallVector<diag::kind> Members; 304 if (!Group.consume_front("-W") || Group.empty()) 305 continue; 306 bool Enable = !Group.consume_front("no-"); 307 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup( 308 diag::Flavor::WarningOrError, Group, Members)) 309 continue; 310 311 // Upgrade (or downgrade) the severity of each diagnostic in the group. 312 // If -Werror is on, newly added warnings will be treated as errors. 313 // We don't want this, so keep track of them to fix afterwards. 314 bool NeedsWerrorExclusion = false; 315 for (diag::kind ID : Members) { 316 if (Enable) { 317 if (Diags.getDiagnosticLevel(ID, SourceLocation()) < 318 DiagnosticsEngine::Warning) { 319 auto Group = DiagnosticIDs::getGroupForDiag(ID); 320 if (!Group || !EnabledGroups(*Group)) 321 continue; 322 Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation()); 323 if (Diags.getWarningsAsErrors()) 324 NeedsWerrorExclusion = true; 325 } 326 } else { 327 Diags.setSeverity(ID, diag::Severity::Ignored, SourceLocation()); 328 } 329 } 330 if (NeedsWerrorExclusion) { 331 // FIXME: there's no API to suppress -Werror for single diagnostics. 332 // In some cases with sub-groups, we may end up erroneously 333 // downgrading diagnostics that were -Werror in the compile command. 334 Diags.setDiagnosticGroupWarningAsError(Group, false); 335 } 336 } 337 } 338 339 } // namespace 340 341 llvm::Optional<ParsedAST> 342 ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, 343 std::unique_ptr<clang::CompilerInvocation> CI, 344 llvm::ArrayRef<Diag> CompilerInvocationDiags, 345 std::shared_ptr<const PreambleData> Preamble) { 346 trace::Span Tracer("BuildAST"); 347 SPAN_ATTACH(Tracer, "File", Filename); 348 349 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory); 350 if (Preamble && Preamble->StatCache) 351 VFS = Preamble->StatCache->getConsumingFS(std::move(VFS)); 352 353 assert(CI); 354 // Command-line parsing sets DisableFree to true by default, but we don't want 355 // to leak memory in clangd. 356 CI->getFrontendOpts().DisableFree = false; 357 const PrecompiledPreamble *PreamblePCH = 358 Preamble ? &Preamble->Preamble : nullptr; 359 360 // This is on-by-default in windows to allow parsing SDK headers, but it 361 // breaks many features. Disable it for the main-file (not preamble). 362 CI->getLangOpts()->DelayedTemplateParsing = false; 363 364 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners; 365 if (Inputs.FeatureModules) { 366 for (auto &M : *Inputs.FeatureModules) { 367 if (auto Listener = M.astListeners()) 368 ASTListeners.emplace_back(std::move(Listener)); 369 } 370 } 371 StoreDiags ASTDiags; 372 ASTDiags.setDiagCallback( 373 [&ASTListeners](const clang::Diagnostic &D, clangd::Diag &Diag) { 374 llvm::for_each(ASTListeners, 375 [&](const auto &L) { L->sawDiagnostic(D, Diag); }); 376 }); 377 378 llvm::Optional<PreamblePatch> Patch; 379 bool PreserveDiags = true; 380 // We might use an ignoring diagnostic consumer if they are going to be 381 // dropped later on to not pay for extra latency by processing them. 382 DiagnosticConsumer *DiagConsumer = &ASTDiags; 383 IgnoreDiagnostics DropDiags; 384 if (Preamble) { 385 Patch = PreamblePatch::createFullPatch(Filename, Inputs, *Preamble); 386 Patch->apply(*CI); 387 PreserveDiags = Patch->preserveDiagnostics(); 388 if (!PreserveDiags) 389 DiagConsumer = &DropDiags; 390 } 391 auto Clang = prepareCompilerInstance( 392 std::move(CI), PreamblePCH, 393 llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, Filename), VFS, 394 *DiagConsumer); 395 if (!Clang) { 396 // The last diagnostic contains information about the reason of this 397 // failure. 398 std::vector<Diag> Diags(ASTDiags.take()); 399 elog("Failed to prepare a compiler instance: {0}", 400 !Diags.empty() ? static_cast<DiagBase &>(Diags.back()).Message 401 : "unknown error"); 402 return None; 403 } 404 tidy::ClangTidyOptions ClangTidyOpts; 405 if (PreserveDiags) { 406 trace::Span Tracer("ClangTidyOpts"); 407 ClangTidyOpts = getTidyOptionsForFile(Inputs.ClangTidyProvider, Filename); 408 dlog("ClangTidy configuration for file {0}: {1}", Filename, 409 tidy::configurationAsText(ClangTidyOpts)); 410 411 // If clang-tidy is configured to emit clang warnings, we should too. 412 // 413 // Such clang-tidy configuration consists of two parts: 414 // - ExtraArgs: ["-Wfoo"] causes clang to produce the warnings 415 // - Checks: "clang-diagnostic-foo" prevents clang-tidy filtering them out 416 // 417 // In clang-tidy, diagnostics are emitted if they pass both checks. 418 // When groups contain subgroups, -Wparent includes the child, but 419 // clang-diagnostic-parent does not. 420 // 421 // We *don't* want to change the compile command directly. This can have 422 // too many unexpected effects: breaking the command, interactions with 423 // -- and -Werror, etc. Besides, we've already parsed the command. 424 // Instead we parse the -W<group> flags and handle them directly. 425 // 426 // Similarly, we don't want to use Checks to filter clang diagnostics after 427 // they are generated, as this spreads clang-tidy emulation everywhere. 428 // Instead, we just use these to filter which extra diagnostics we enable. 429 auto &Diags = Clang->getDiagnostics(); 430 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.Checks ? *ClangTidyOpts.Checks 431 : llvm::StringRef()); 432 if (ClangTidyOpts.ExtraArgsBefore) 433 applyWarningOptions(*ClangTidyOpts.ExtraArgsBefore, TidyGroups, Diags); 434 if (ClangTidyOpts.ExtraArgs) 435 applyWarningOptions(*ClangTidyOpts.ExtraArgs, TidyGroups, Diags); 436 } else { 437 // Skips some analysis. 438 Clang->getDiagnosticOpts().IgnoreWarnings = true; 439 } 440 441 auto Action = std::make_unique<ClangdFrontendAction>(); 442 const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0]; 443 if (!Action->BeginSourceFile(*Clang, MainInput)) { 444 log("BeginSourceFile() failed when building AST for {0}", 445 MainInput.getFile()); 446 return None; 447 } 448 // If we saw an include guard in the preamble section of the main file, 449 // mark the main-file as include-guarded. 450 // This information is part of the HeaderFileInfo but is not loaded from the 451 // preamble as the file's size is part of its identity and may have changed. 452 // (The rest of HeaderFileInfo is not relevant for our purposes). 453 if (Preamble && Preamble->MainIsIncludeGuarded) { 454 const SourceManager &SM = Clang->getSourceManager(); 455 const FileEntry *MainFE = SM.getFileEntryForID(SM.getMainFileID()); 456 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(MainFE); 457 } 458 459 // Set up ClangTidy. Must happen after BeginSourceFile() so ASTContext exists. 460 // Clang-tidy has some limitations to ensure reasonable performance: 461 // - checks don't see all preprocessor events in the preamble 462 // - matchers run only over the main-file top-level decls (and can't see 463 // ancestors outside this scope). 464 // In practice almost all checks work well without modifications. 465 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks; 466 ast_matchers::MatchFinder CTFinder; 467 llvm::Optional<tidy::ClangTidyContext> CTContext; 468 llvm::Optional<IncludeFixer> FixIncludes; 469 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity; 470 // No need to run clang-tidy or IncludeFixerif we are not going to surface 471 // diagnostics. 472 if (PreserveDiags) { 473 trace::Span Tracer("ClangTidyInit"); 474 tidy::ClangTidyCheckFactories CTFactories; 475 for (const auto &E : tidy::ClangTidyModuleRegistry::entries()) 476 E.instantiate()->addCheckFactories(CTFactories); 477 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>( 478 tidy::ClangTidyGlobalOptions(), ClangTidyOpts)); 479 CTContext->setDiagnosticsEngine(&Clang->getDiagnostics()); 480 CTContext->setASTContext(&Clang->getASTContext()); 481 CTContext->setCurrentFile(Filename); 482 CTContext->setSelfContainedDiags(true); 483 CTChecks = CTFactories.createChecksForLanguage(CTContext.getPointer()); 484 Preprocessor *PP = &Clang->getPreprocessor(); 485 for (const auto &Check : CTChecks) { 486 Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP); 487 Check->registerMatchers(&CTFinder); 488 } 489 490 // Clang only corrects typos for use of undeclared functions in C if that 491 // use is an error. Include fixer relies on typo correction, so pretend 492 // this is an error. (The actual typo correction is nice too). 493 // We restore the original severity in the level adjuster. 494 // FIXME: It would be better to have a real API for this, but what? 495 for (auto ID : {diag::ext_implicit_function_decl_c99, 496 diag::ext_implicit_lib_function_decl_c99, 497 diag::warn_implicit_function_decl}) { 498 OverriddenSeverity.try_emplace( 499 ID, Clang->getDiagnostics().getDiagnosticLevel(ID, SourceLocation())); 500 Clang->getDiagnostics().setSeverity(ID, diag::Severity::Error, 501 SourceLocation()); 502 } 503 504 const Config &Cfg = Config::current(); 505 ASTDiags.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, 506 const clang::Diagnostic &Info) { 507 if (Cfg.Diagnostics.SuppressAll || 508 isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress, 509 Clang->getLangOpts())) 510 return DiagnosticsEngine::Ignored; 511 512 auto It = OverriddenSeverity.find(Info.getID()); 513 if (It != OverriddenSeverity.end()) 514 DiagLevel = It->second; 515 516 if (!CTChecks.empty()) { 517 std::string CheckName = CTContext->getCheckName(Info.getID()); 518 bool IsClangTidyDiag = !CheckName.empty(); 519 if (IsClangTidyDiag) { 520 if (Cfg.Diagnostics.Suppress.contains(CheckName)) 521 return DiagnosticsEngine::Ignored; 522 // Check for suppression comment. Skip the check for diagnostics not 523 // in the main file, because we don't want that function to query the 524 // source buffer for preamble files. For the same reason, we ask 525 // shouldSuppressDiagnostic to avoid I/O. 526 // We let suppression comments take precedence over warning-as-error 527 // to match clang-tidy's behaviour. 528 bool IsInsideMainFile = 529 Info.hasSourceManager() && 530 isInsideMainFile(Info.getLocation(), Info.getSourceManager()); 531 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors; 532 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic( 533 DiagLevel, Info, TidySuppressedErrors, 534 /*AllowIO=*/false, 535 /*EnableNolintBlocks=*/true)) { 536 // FIXME: should we expose the suppression error (invalid use of 537 // NOLINT comments)? 538 return DiagnosticsEngine::Ignored; 539 } 540 541 // Check for warning-as-error. 542 if (DiagLevel == DiagnosticsEngine::Warning && 543 CTContext->treatAsError(CheckName)) { 544 return DiagnosticsEngine::Error; 545 } 546 } 547 } 548 return DiagLevel; 549 }); 550 551 // Add IncludeFixer which can recover diagnostics caused by missing includes 552 // (e.g. incomplete type) and attach include insertion fixes to diagnostics. 553 auto BuildDir = VFS->getCurrentWorkingDirectory(); 554 if (Inputs.Index && !BuildDir.getError()) { 555 auto Style = 556 getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS); 557 auto Inserter = std::make_shared<IncludeInserter>( 558 Filename, Inputs.Contents, Style, BuildDir.get(), 559 &Clang->getPreprocessor().getHeaderSearchInfo()); 560 if (Preamble) { 561 for (const auto &Inc : Preamble->Includes.MainFileIncludes) 562 Inserter->addExisting(Inc); 563 } 564 FixIncludes.emplace(Filename, Inserter, *Inputs.Index, 565 /*IndexRequestLimit=*/5); 566 ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl, 567 const clang::Diagnostic &Info) { 568 return FixIncludes->fix(DiagLevl, Info); 569 }); 570 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder()); 571 } 572 } 573 574 IncludeStructure Includes; 575 // If we are using a preamble, copy existing includes. 576 if (Preamble) { 577 Includes = Preamble->Includes; 578 Includes.MainFileIncludes = Patch->preambleIncludes(); 579 // Replay the preamble includes so that clang-tidy checks can see them. 580 ReplayPreamble::attach(Patch->preambleIncludes(), *Clang, 581 Patch->modifiedBounds()); 582 } 583 // Important: collectIncludeStructure is registered *after* ReplayPreamble! 584 // Otherwise we would collect the replayed includes again... 585 // (We can't *just* use the replayed includes, they don't have Resolved path). 586 Includes.collect(*Clang); 587 // Copy over the macros in the preamble region of the main file, and combine 588 // with non-preamble macros below. 589 MainFileMacros Macros; 590 if (Preamble) 591 Macros = Preamble->Macros; 592 Clang->getPreprocessor().addPPCallbacks( 593 std::make_unique<CollectMainFileMacros>(Clang->getSourceManager(), 594 Macros)); 595 596 std::vector<PragmaMark> Marks; 597 // FIXME: We need to patch the marks for stale preambles. 598 if (Preamble) 599 Marks = Preamble->Marks; 600 Clang->getPreprocessor().addPPCallbacks( 601 collectPragmaMarksCallback(Clang->getSourceManager(), Marks)); 602 603 // Copy over the includes from the preamble, then combine with the 604 // non-preamble includes below. 605 CanonicalIncludes CanonIncludes; 606 if (Preamble) 607 CanonIncludes = Preamble->CanonIncludes; 608 else 609 CanonIncludes.addSystemHeadersMapping(Clang->getLangOpts()); 610 std::unique_ptr<CommentHandler> IWYUHandler = 611 collectIWYUHeaderMaps(&CanonIncludes); 612 Clang->getPreprocessor().addCommentHandler(IWYUHandler.get()); 613 614 // Collect tokens of the main file. 615 syntax::TokenCollector CollectTokens(Clang->getPreprocessor()); 616 617 // To remain consistent with preamble builds, these callbacks must be called 618 // exactly here, after preprocessor is initialized and BeginSourceFile() was 619 // called already. 620 for (const auto &L : ASTListeners) 621 L->beforeExecute(*Clang); 622 623 if (llvm::Error Err = Action->Execute()) 624 log("Execute() failed when building AST for {0}: {1}", MainInput.getFile(), 625 toString(std::move(Err))); 626 627 // We have to consume the tokens before running clang-tidy to avoid collecting 628 // tokens from running the preprocessor inside the checks (only 629 // modernize-use-trailing-return-type does that today). 630 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume(); 631 // Makes SelectionTree build much faster. 632 Tokens.indexExpandedTokens(); 633 std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls(); 634 // AST traversals should exclude the preamble, to avoid performance cliffs. 635 Clang->getASTContext().setTraversalScope(ParsedDecls); 636 if (!CTChecks.empty()) { 637 // Run the AST-dependent part of the clang-tidy checks. 638 // (The preprocessor part ran already, via PPCallbacks). 639 trace::Span Tracer("ClangTidyMatch"); 640 CTFinder.matchAST(Clang->getASTContext()); 641 } 642 643 // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF. 644 // However Action->EndSourceFile() would destroy the ASTContext! 645 // So just inform the preprocessor of EOF, while keeping everything alive. 646 Clang->getPreprocessor().EndSourceFile(); 647 // UnitDiagsConsumer is local, we can not store it in CompilerInstance that 648 // has a longer lifetime. 649 Clang->getDiagnostics().setClient(new IgnoreDiagnostics); 650 // CompilerInstance won't run this callback, do it directly. 651 ASTDiags.EndSourceFile(); 652 653 llvm::Optional<std::vector<Diag>> Diags; 654 // FIXME: Also skip generation of diagnostics alltogether to speed up ast 655 // builds when we are patching a stale preamble. 656 if (PreserveDiags) { 657 Diags = CompilerInvocationDiags; 658 // Add diagnostics from the preamble, if any. 659 if (Preamble) 660 Diags->insert(Diags->end(), Preamble->Diags.begin(), 661 Preamble->Diags.end()); 662 // Finally, add diagnostics coming from the AST. 663 { 664 std::vector<Diag> D = ASTDiags.take(CTContext.getPointer()); 665 Diags->insert(Diags->end(), D.begin(), D.end()); 666 } 667 } 668 ParsedAST Result(Inputs.Version, std::move(Preamble), std::move(Clang), 669 std::move(Action), std::move(Tokens), std::move(Macros), 670 std::move(Marks), std::move(ParsedDecls), std::move(Diags), 671 std::move(Includes), std::move(CanonIncludes)); 672 if (Result.Diags) { 673 auto UnusedHeadersDiags = 674 issueUnusedIncludesDiagnostics(Result, Inputs.Contents); 675 Result.Diags->insert(Result.Diags->end(), 676 make_move_iterator(UnusedHeadersDiags.begin()), 677 make_move_iterator(UnusedHeadersDiags.end())); 678 } 679 return Result; 680 } 681 682 ParsedAST::ParsedAST(ParsedAST &&Other) = default; 683 684 ParsedAST &ParsedAST::operator=(ParsedAST &&Other) = default; 685 686 ParsedAST::~ParsedAST() { 687 if (Action) { 688 // We already notified the PP of end-of-file earlier, so detach it first. 689 // We must keep it alive until after EndSourceFile(), Sema relies on this. 690 auto PP = Clang->getPreprocessorPtr(); // Keep PP alive for now. 691 Clang->setPreprocessor(nullptr); // Detach so we don't send EOF again. 692 Action->EndSourceFile(); // Destroy ASTContext and Sema. 693 // Now Sema is gone, it's safe for PP to go out of scope. 694 } 695 } 696 697 ASTContext &ParsedAST::getASTContext() { return Clang->getASTContext(); } 698 699 const ASTContext &ParsedAST::getASTContext() const { 700 return Clang->getASTContext(); 701 } 702 703 Sema &ParsedAST::getSema() { return Clang->getSema(); } 704 705 Preprocessor &ParsedAST::getPreprocessor() { return Clang->getPreprocessor(); } 706 707 std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() { 708 return Clang->getPreprocessorPtr(); 709 } 710 711 const Preprocessor &ParsedAST::getPreprocessor() const { 712 return Clang->getPreprocessor(); 713 } 714 715 llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() { 716 return LocalTopLevelDecls; 717 } 718 719 const MainFileMacros &ParsedAST::getMacros() const { return Macros; } 720 const std::vector<PragmaMark> &ParsedAST::getMarks() const { return Marks; } 721 722 std::size_t ParsedAST::getUsedBytes() const { 723 auto &AST = getASTContext(); 724 // FIXME(ibiryukov): we do not account for the dynamically allocated part of 725 // Message and Fixes inside each diagnostic. 726 std::size_t Total = clangd::getUsedBytes(LocalTopLevelDecls) + 727 (Diags ? clangd::getUsedBytes(*Diags) : 0); 728 729 // FIXME: the rest of the function is almost a direct copy-paste from 730 // libclang's clang_getCXTUResourceUsage. We could share the implementation. 731 732 // Sum up various allocators inside the ast context and the preprocessor. 733 Total += AST.getASTAllocatedMemory(); 734 Total += AST.getSideTableAllocatedMemory(); 735 Total += AST.Idents.getAllocator().getTotalMemory(); 736 Total += AST.Selectors.getTotalMemory(); 737 738 Total += AST.getSourceManager().getContentCacheSize(); 739 Total += AST.getSourceManager().getDataStructureSizes(); 740 Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes; 741 742 if (ExternalASTSource *Ext = AST.getExternalSource()) 743 Total += Ext->getMemoryBufferSizes().malloc_bytes; 744 745 const Preprocessor &PP = getPreprocessor(); 746 Total += PP.getTotalMemory(); 747 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord()) 748 Total += PRec->getTotalMemory(); 749 Total += PP.getHeaderSearchInfo().getTotalMemory(); 750 751 return Total; 752 } 753 754 const IncludeStructure &ParsedAST::getIncludeStructure() const { 755 return Includes; 756 } 757 758 const CanonicalIncludes &ParsedAST::getCanonicalIncludes() const { 759 return CanonIncludes; 760 } 761 762 ParsedAST::ParsedAST(llvm::StringRef Version, 763 std::shared_ptr<const PreambleData> Preamble, 764 std::unique_ptr<CompilerInstance> Clang, 765 std::unique_ptr<FrontendAction> Action, 766 syntax::TokenBuffer Tokens, MainFileMacros Macros, 767 std::vector<PragmaMark> Marks, 768 std::vector<Decl *> LocalTopLevelDecls, 769 llvm::Optional<std::vector<Diag>> Diags, 770 IncludeStructure Includes, CanonicalIncludes CanonIncludes) 771 : Version(Version), Preamble(std::move(Preamble)), Clang(std::move(Clang)), 772 Action(std::move(Action)), Tokens(std::move(Tokens)), 773 Macros(std::move(Macros)), Marks(std::move(Marks)), 774 Diags(std::move(Diags)), 775 LocalTopLevelDecls(std::move(LocalTopLevelDecls)), 776 Includes(std::move(Includes)), CanonIncludes(std::move(CanonIncludes)) { 777 Resolver = std::make_unique<HeuristicResolver>(getASTContext()); 778 assert(this->Clang); 779 assert(this->Action); 780 } 781 782 llvm::Optional<llvm::StringRef> ParsedAST::preambleVersion() const { 783 if (!Preamble) 784 return llvm::None; 785 return llvm::StringRef(Preamble->Version); 786 } 787 788 } // namespace clangd 789 } // namespace clang 790