1 //===--- FrontendActions.cpp ----------------------------------------------===// 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 "clang/Frontend/FrontendActions.h" 10 #include "clang/AST/ASTConsumer.h" 11 #include "clang/AST/Decl.h" 12 #include "clang/Basic/FileManager.h" 13 #include "clang/Basic/LangStandard.h" 14 #include "clang/Basic/TargetInfo.h" 15 #include "clang/Frontend/ASTConsumers.h" 16 #include "clang/Frontend/CompilerInstance.h" 17 #include "clang/Frontend/FrontendDiagnostic.h" 18 #include "clang/Frontend/MultiplexConsumer.h" 19 #include "clang/Frontend/Utils.h" 20 #include "clang/Lex/DependencyDirectivesSourceMinimizer.h" 21 #include "clang/Lex/HeaderSearch.h" 22 #include "clang/Lex/Preprocessor.h" 23 #include "clang/Lex/PreprocessorOptions.h" 24 #include "clang/Sema/TemplateInstCallback.h" 25 #include "clang/Serialization/ASTReader.h" 26 #include "clang/Serialization/ASTWriter.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/FileSystem.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/Path.h" 31 #include "llvm/Support/YAMLTraits.h" 32 #include "llvm/Support/raw_ostream.h" 33 #include <memory> 34 #include <system_error> 35 36 using namespace clang; 37 38 namespace { 39 CodeCompleteConsumer *GetCodeCompletionConsumer(CompilerInstance &CI) { 40 return CI.hasCodeCompletionConsumer() ? &CI.getCodeCompletionConsumer() 41 : nullptr; 42 } 43 44 void EnsureSemaIsCreated(CompilerInstance &CI, FrontendAction &Action) { 45 if (Action.hasCodeCompletionSupport() && 46 !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 47 CI.createCodeCompletionConsumer(); 48 49 if (!CI.hasSema()) 50 CI.createSema(Action.getTranslationUnitKind(), 51 GetCodeCompletionConsumer(CI)); 52 } 53 } // namespace 54 55 //===----------------------------------------------------------------------===// 56 // Custom Actions 57 //===----------------------------------------------------------------------===// 58 59 std::unique_ptr<ASTConsumer> 60 InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 61 return std::make_unique<ASTConsumer>(); 62 } 63 64 void InitOnlyAction::ExecuteAction() { 65 } 66 67 // Basically PreprocessOnlyAction::ExecuteAction. 68 void ReadPCHAndPreprocessAction::ExecuteAction() { 69 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 70 71 // Ignore unknown pragmas. 72 PP.IgnorePragmas(); 73 74 Token Tok; 75 // Start parsing the specified input file. 76 PP.EnterMainSourceFile(); 77 do { 78 PP.Lex(Tok); 79 } while (Tok.isNot(tok::eof)); 80 } 81 82 std::unique_ptr<ASTConsumer> 83 ReadPCHAndPreprocessAction::CreateASTConsumer(CompilerInstance &CI, 84 StringRef InFile) { 85 return std::make_unique<ASTConsumer>(); 86 } 87 88 //===----------------------------------------------------------------------===// 89 // AST Consumer Actions 90 //===----------------------------------------------------------------------===// 91 92 std::unique_ptr<ASTConsumer> 93 ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 94 if (std::unique_ptr<raw_ostream> OS = 95 CI.createDefaultOutputFile(false, InFile)) 96 return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter); 97 return nullptr; 98 } 99 100 std::unique_ptr<ASTConsumer> 101 ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 102 const FrontendOptions &Opts = CI.getFrontendOpts(); 103 return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter, 104 Opts.ASTDumpDecls, Opts.ASTDumpAll, 105 Opts.ASTDumpLookups, Opts.ASTDumpDeclTypes, 106 Opts.ASTDumpFormat); 107 } 108 109 std::unique_ptr<ASTConsumer> 110 ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 111 return CreateASTDeclNodeLister(); 112 } 113 114 std::unique_ptr<ASTConsumer> 115 ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 116 return CreateASTViewer(); 117 } 118 119 std::unique_ptr<ASTConsumer> 120 GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 121 std::string Sysroot; 122 if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot)) 123 return nullptr; 124 125 std::string OutputFile; 126 std::unique_ptr<raw_pwrite_stream> OS = 127 CreateOutputFile(CI, InFile, /*ref*/ OutputFile); 128 if (!OS) 129 return nullptr; 130 131 if (!CI.getFrontendOpts().RelocatablePCH) 132 Sysroot.clear(); 133 134 const auto &FrontendOpts = CI.getFrontendOpts(); 135 auto Buffer = std::make_shared<PCHBuffer>(); 136 std::vector<std::unique_ptr<ASTConsumer>> Consumers; 137 Consumers.push_back(std::make_unique<PCHGenerator>( 138 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer, 139 FrontendOpts.ModuleFileExtensions, 140 CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, 141 FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH)); 142 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( 143 CI, std::string(InFile), OutputFile, std::move(OS), Buffer)); 144 145 return std::make_unique<MultiplexConsumer>(std::move(Consumers)); 146 } 147 148 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, 149 std::string &Sysroot) { 150 Sysroot = CI.getHeaderSearchOpts().Sysroot; 151 if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) { 152 CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot); 153 return false; 154 } 155 156 return true; 157 } 158 159 std::unique_ptr<llvm::raw_pwrite_stream> 160 GeneratePCHAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile, 161 std::string &OutputFile) { 162 // Because this is exposed via libclang we must disable RemoveFileOnSignal. 163 std::unique_ptr<raw_pwrite_stream> OS = CI.createDefaultOutputFile( 164 /*Binary=*/true, InFile, /*Extension=*/"", /*RemoveFileOnSignal=*/false); 165 if (!OS) 166 return nullptr; 167 168 OutputFile = CI.getFrontendOpts().OutputFile; 169 return OS; 170 } 171 172 bool GeneratePCHAction::shouldEraseOutputFiles() { 173 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors) 174 return false; 175 return ASTFrontendAction::shouldEraseOutputFiles(); 176 } 177 178 bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI) { 179 CI.getLangOpts().CompilingPCH = true; 180 return true; 181 } 182 183 std::unique_ptr<ASTConsumer> 184 GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, 185 StringRef InFile) { 186 std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile); 187 if (!OS) 188 return nullptr; 189 190 std::string OutputFile = CI.getFrontendOpts().OutputFile; 191 std::string Sysroot; 192 193 auto Buffer = std::make_shared<PCHBuffer>(); 194 std::vector<std::unique_ptr<ASTConsumer>> Consumers; 195 196 Consumers.push_back(std::make_unique<PCHGenerator>( 197 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer, 198 CI.getFrontendOpts().ModuleFileExtensions, 199 /*AllowASTWithErrors=*/ 200 +CI.getFrontendOpts().AllowPCMWithCompilerErrors, 201 /*IncludeTimestamps=*/ 202 +CI.getFrontendOpts().BuildingImplicitModule, 203 /*ShouldCacheASTInMemory=*/ 204 +CI.getFrontendOpts().BuildingImplicitModule)); 205 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( 206 CI, std::string(InFile), OutputFile, std::move(OS), Buffer)); 207 return std::make_unique<MultiplexConsumer>(std::move(Consumers)); 208 } 209 210 bool GenerateModuleAction::shouldEraseOutputFiles() { 211 return !getCompilerInstance().getFrontendOpts().AllowPCMWithCompilerErrors && 212 ASTFrontendAction::shouldEraseOutputFiles(); 213 } 214 215 bool GenerateModuleFromModuleMapAction::BeginSourceFileAction( 216 CompilerInstance &CI) { 217 if (!CI.getLangOpts().Modules) { 218 CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules); 219 return false; 220 } 221 222 return GenerateModuleAction::BeginSourceFileAction(CI); 223 } 224 225 std::unique_ptr<raw_pwrite_stream> 226 GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI, 227 StringRef InFile) { 228 // If no output file was provided, figure out where this module would go 229 // in the module cache. 230 if (CI.getFrontendOpts().OutputFile.empty()) { 231 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap; 232 if (ModuleMapFile.empty()) 233 ModuleMapFile = InFile; 234 235 HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo(); 236 CI.getFrontendOpts().OutputFile = 237 HS.getCachedModuleFileName(CI.getLangOpts().CurrentModule, 238 ModuleMapFile); 239 } 240 241 // Because this is exposed via libclang we must disable RemoveFileOnSignal. 242 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, /*Extension=*/"", 243 /*RemoveFileOnSignal=*/false, 244 /*CreateMissingDirectories=*/true, 245 /*ForceUseTemporary=*/true); 246 } 247 248 bool GenerateModuleInterfaceAction::BeginSourceFileAction( 249 CompilerInstance &CI) { 250 if (!CI.getLangOpts().ModulesTS && !CI.getLangOpts().CPlusPlusModules) { 251 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules); 252 return false; 253 } 254 255 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface); 256 257 return GenerateModuleAction::BeginSourceFileAction(CI); 258 } 259 260 std::unique_ptr<raw_pwrite_stream> 261 GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI, 262 StringRef InFile) { 263 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm"); 264 } 265 266 bool GenerateHeaderModuleAction::PrepareToExecuteAction( 267 CompilerInstance &CI) { 268 if (!CI.getLangOpts().Modules) { 269 CI.getDiagnostics().Report(diag::err_header_module_requires_modules); 270 return false; 271 } 272 273 auto &Inputs = CI.getFrontendOpts().Inputs; 274 if (Inputs.empty()) 275 return GenerateModuleAction::BeginInvocation(CI); 276 277 auto Kind = Inputs[0].getKind(); 278 279 // Convert the header file inputs into a single module input buffer. 280 SmallString<256> HeaderContents; 281 ModuleHeaders.reserve(Inputs.size()); 282 for (const FrontendInputFile &FIF : Inputs) { 283 // FIXME: We should support re-compiling from an AST file. 284 if (FIF.getKind().getFormat() != InputKind::Source || !FIF.isFile()) { 285 CI.getDiagnostics().Report(diag::err_module_header_file_not_found) 286 << (FIF.isFile() ? FIF.getFile() 287 : FIF.getBuffer().getBufferIdentifier()); 288 return true; 289 } 290 291 HeaderContents += "#include \""; 292 HeaderContents += FIF.getFile(); 293 HeaderContents += "\"\n"; 294 ModuleHeaders.push_back(std::string(FIF.getFile())); 295 } 296 Buffer = llvm::MemoryBuffer::getMemBufferCopy( 297 HeaderContents, Module::getModuleInputBufferName()); 298 299 // Set that buffer up as our "real" input. 300 Inputs.clear(); 301 Inputs.push_back( 302 FrontendInputFile(Buffer->getMemBufferRef(), Kind, /*IsSystem*/ false)); 303 304 return GenerateModuleAction::PrepareToExecuteAction(CI); 305 } 306 307 bool GenerateHeaderModuleAction::BeginSourceFileAction( 308 CompilerInstance &CI) { 309 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderModule); 310 311 // Synthesize a Module object for the given headers. 312 auto &HS = CI.getPreprocessor().getHeaderSearchInfo(); 313 SmallVector<Module::Header, 16> Headers; 314 for (StringRef Name : ModuleHeaders) { 315 Optional<FileEntryRef> FE = HS.LookupFile( 316 Name, SourceLocation(), /*Angled*/ false, nullptr, nullptr, None, 317 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); 318 if (!FE) { 319 CI.getDiagnostics().Report(diag::err_module_header_file_not_found) 320 << Name; 321 continue; 322 } 323 Headers.push_back( 324 {std::string(Name), std::string(Name), &FE->getFileEntry()}); 325 } 326 HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers); 327 328 return GenerateModuleAction::BeginSourceFileAction(CI); 329 } 330 331 std::unique_ptr<raw_pwrite_stream> 332 GenerateHeaderModuleAction::CreateOutputFile(CompilerInstance &CI, 333 StringRef InFile) { 334 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm"); 335 } 336 337 SyntaxOnlyAction::~SyntaxOnlyAction() { 338 } 339 340 std::unique_ptr<ASTConsumer> 341 SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 342 return std::make_unique<ASTConsumer>(); 343 } 344 345 std::unique_ptr<ASTConsumer> 346 DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI, 347 StringRef InFile) { 348 return std::make_unique<ASTConsumer>(); 349 } 350 351 std::unique_ptr<ASTConsumer> 352 VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 353 return std::make_unique<ASTConsumer>(); 354 } 355 356 void VerifyPCHAction::ExecuteAction() { 357 CompilerInstance &CI = getCompilerInstance(); 358 bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 359 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; 360 std::unique_ptr<ASTReader> Reader(new ASTReader( 361 CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(), 362 CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions, 363 Sysroot.empty() ? "" : Sysroot.c_str(), 364 DisableValidationForModuleKind::None, 365 /*AllowASTWithCompilerErrors*/ false, 366 /*AllowConfigurationMismatch*/ true, 367 /*ValidateSystemInputs*/ true)); 368 369 Reader->ReadAST(getCurrentFile(), 370 Preamble ? serialization::MK_Preamble 371 : serialization::MK_PCH, 372 SourceLocation(), 373 ASTReader::ARR_ConfigurationMismatch); 374 } 375 376 namespace { 377 struct TemplightEntry { 378 std::string Name; 379 std::string Kind; 380 std::string Event; 381 std::string DefinitionLocation; 382 std::string PointOfInstantiation; 383 }; 384 } // namespace 385 386 namespace llvm { 387 namespace yaml { 388 template <> struct MappingTraits<TemplightEntry> { 389 static void mapping(IO &io, TemplightEntry &fields) { 390 io.mapRequired("name", fields.Name); 391 io.mapRequired("kind", fields.Kind); 392 io.mapRequired("event", fields.Event); 393 io.mapRequired("orig", fields.DefinitionLocation); 394 io.mapRequired("poi", fields.PointOfInstantiation); 395 } 396 }; 397 } // namespace yaml 398 } // namespace llvm 399 400 namespace { 401 class DefaultTemplateInstCallback : public TemplateInstantiationCallback { 402 using CodeSynthesisContext = Sema::CodeSynthesisContext; 403 404 public: 405 void initialize(const Sema &) override {} 406 407 void finalize(const Sema &) override {} 408 409 void atTemplateBegin(const Sema &TheSema, 410 const CodeSynthesisContext &Inst) override { 411 displayTemplightEntry<true>(llvm::outs(), TheSema, Inst); 412 } 413 414 void atTemplateEnd(const Sema &TheSema, 415 const CodeSynthesisContext &Inst) override { 416 displayTemplightEntry<false>(llvm::outs(), TheSema, Inst); 417 } 418 419 private: 420 static std::string toString(CodeSynthesisContext::SynthesisKind Kind) { 421 switch (Kind) { 422 case CodeSynthesisContext::TemplateInstantiation: 423 return "TemplateInstantiation"; 424 case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: 425 return "DefaultTemplateArgumentInstantiation"; 426 case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: 427 return "DefaultFunctionArgumentInstantiation"; 428 case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: 429 return "ExplicitTemplateArgumentSubstitution"; 430 case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: 431 return "DeducedTemplateArgumentSubstitution"; 432 case CodeSynthesisContext::PriorTemplateArgumentSubstitution: 433 return "PriorTemplateArgumentSubstitution"; 434 case CodeSynthesisContext::DefaultTemplateArgumentChecking: 435 return "DefaultTemplateArgumentChecking"; 436 case CodeSynthesisContext::ExceptionSpecEvaluation: 437 return "ExceptionSpecEvaluation"; 438 case CodeSynthesisContext::ExceptionSpecInstantiation: 439 return "ExceptionSpecInstantiation"; 440 case CodeSynthesisContext::DeclaringSpecialMember: 441 return "DeclaringSpecialMember"; 442 case CodeSynthesisContext::DeclaringImplicitEqualityComparison: 443 return "DeclaringImplicitEqualityComparison"; 444 case CodeSynthesisContext::DefiningSynthesizedFunction: 445 return "DefiningSynthesizedFunction"; 446 case CodeSynthesisContext::RewritingOperatorAsSpaceship: 447 return "RewritingOperatorAsSpaceship"; 448 case CodeSynthesisContext::Memoization: 449 return "Memoization"; 450 case CodeSynthesisContext::ConstraintsCheck: 451 return "ConstraintsCheck"; 452 case CodeSynthesisContext::ConstraintSubstitution: 453 return "ConstraintSubstitution"; 454 case CodeSynthesisContext::ConstraintNormalization: 455 return "ConstraintNormalization"; 456 case CodeSynthesisContext::ParameterMappingSubstitution: 457 return "ParameterMappingSubstitution"; 458 case CodeSynthesisContext::RequirementInstantiation: 459 return "RequirementInstantiation"; 460 case CodeSynthesisContext::NestedRequirementConstraintsCheck: 461 return "NestedRequirementConstraintsCheck"; 462 case CodeSynthesisContext::InitializingStructuredBinding: 463 return "InitializingStructuredBinding"; 464 case CodeSynthesisContext::MarkingClassDllexported: 465 return "MarkingClassDllexported"; 466 } 467 return ""; 468 } 469 470 template <bool BeginInstantiation> 471 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema, 472 const CodeSynthesisContext &Inst) { 473 std::string YAML; 474 { 475 llvm::raw_string_ostream OS(YAML); 476 llvm::yaml::Output YO(OS); 477 TemplightEntry Entry = 478 getTemplightEntry<BeginInstantiation>(TheSema, Inst); 479 llvm::yaml::EmptyContext Context; 480 llvm::yaml::yamlize(YO, Entry, true, Context); 481 } 482 Out << "---" << YAML << "\n"; 483 } 484 485 static void printEntryName(const Sema &TheSema, const Decl *Entity, 486 llvm::raw_string_ostream &OS) { 487 auto *NamedTemplate = cast<NamedDecl>(Entity); 488 489 PrintingPolicy Policy = TheSema.Context.getPrintingPolicy(); 490 // FIXME: Also ask for FullyQualifiedNames? 491 Policy.SuppressDefaultTemplateArgs = false; 492 NamedTemplate->getNameForDiagnostic(OS, Policy, true); 493 494 if (!OS.str().empty()) 495 return; 496 497 Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext()); 498 NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx); 499 500 if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) { 501 if (const auto *R = dyn_cast<RecordDecl>(Decl)) { 502 if (R->isLambda()) { 503 OS << "lambda at "; 504 Decl->getLocation().print(OS, TheSema.getSourceManager()); 505 return; 506 } 507 } 508 OS << "unnamed " << Decl->getKindName(); 509 return; 510 } 511 512 if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) { 513 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex() 514 << " "; 515 if (Decl->getFunctionScopeDepth() > 0) 516 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") "; 517 OS << "of "; 518 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); 519 return; 520 } 521 522 if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) { 523 if (const Type *Ty = Decl->getTypeForDecl()) { 524 if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) { 525 OS << "unnamed template type parameter " << TTPT->getIndex() << " "; 526 if (TTPT->getDepth() > 0) 527 OS << "(at depth " << TTPT->getDepth() << ") "; 528 OS << "of "; 529 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); 530 return; 531 } 532 } 533 } 534 535 if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) { 536 OS << "unnamed template non-type parameter " << Decl->getIndex() << " "; 537 if (Decl->getDepth() > 0) 538 OS << "(at depth " << Decl->getDepth() << ") "; 539 OS << "of "; 540 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); 541 return; 542 } 543 544 if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) { 545 OS << "unnamed template template parameter " << Decl->getIndex() << " "; 546 if (Decl->getDepth() > 0) 547 OS << "(at depth " << Decl->getDepth() << ") "; 548 OS << "of "; 549 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); 550 return; 551 } 552 553 llvm_unreachable("Failed to retrieve a name for this entry!"); 554 OS << "unnamed identifier"; 555 } 556 557 template <bool BeginInstantiation> 558 static TemplightEntry getTemplightEntry(const Sema &TheSema, 559 const CodeSynthesisContext &Inst) { 560 TemplightEntry Entry; 561 Entry.Kind = toString(Inst.Kind); 562 Entry.Event = BeginInstantiation ? "Begin" : "End"; 563 llvm::raw_string_ostream OS(Entry.Name); 564 printEntryName(TheSema, Inst.Entity, OS); 565 const PresumedLoc DefLoc = 566 TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation()); 567 if (!DefLoc.isInvalid()) 568 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" + 569 std::to_string(DefLoc.getLine()) + ":" + 570 std::to_string(DefLoc.getColumn()); 571 const PresumedLoc PoiLoc = 572 TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation); 573 if (!PoiLoc.isInvalid()) { 574 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" + 575 std::to_string(PoiLoc.getLine()) + ":" + 576 std::to_string(PoiLoc.getColumn()); 577 } 578 return Entry; 579 } 580 }; 581 } // namespace 582 583 std::unique_ptr<ASTConsumer> 584 TemplightDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 585 return std::make_unique<ASTConsumer>(); 586 } 587 588 void TemplightDumpAction::ExecuteAction() { 589 CompilerInstance &CI = getCompilerInstance(); 590 591 // This part is normally done by ASTFrontEndAction, but needs to happen 592 // before Templight observers can be created 593 // FIXME: Move the truncation aspect of this into Sema, we delayed this till 594 // here so the source manager would be initialized. 595 EnsureSemaIsCreated(CI, *this); 596 597 CI.getSema().TemplateInstCallbacks.push_back( 598 std::make_unique<DefaultTemplateInstCallback>()); 599 ASTFrontendAction::ExecuteAction(); 600 } 601 602 namespace { 603 /// AST reader listener that dumps module information for a module 604 /// file. 605 class DumpModuleInfoListener : public ASTReaderListener { 606 llvm::raw_ostream &Out; 607 608 public: 609 DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { } 610 611 #define DUMP_BOOLEAN(Value, Text) \ 612 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n" 613 614 bool ReadFullVersionInformation(StringRef FullVersion) override { 615 Out.indent(2) 616 << "Generated by " 617 << (FullVersion == getClangFullRepositoryVersion()? "this" 618 : "a different") 619 << " Clang: " << FullVersion << "\n"; 620 return ASTReaderListener::ReadFullVersionInformation(FullVersion); 621 } 622 623 void ReadModuleName(StringRef ModuleName) override { 624 Out.indent(2) << "Module name: " << ModuleName << "\n"; 625 } 626 void ReadModuleMapFile(StringRef ModuleMapPath) override { 627 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n"; 628 } 629 630 bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, 631 bool AllowCompatibleDifferences) override { 632 Out.indent(2) << "Language options:\n"; 633 #define LANGOPT(Name, Bits, Default, Description) \ 634 DUMP_BOOLEAN(LangOpts.Name, Description); 635 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ 636 Out.indent(4) << Description << ": " \ 637 << static_cast<unsigned>(LangOpts.get##Name()) << "\n"; 638 #define VALUE_LANGOPT(Name, Bits, Default, Description) \ 639 Out.indent(4) << Description << ": " << LangOpts.Name << "\n"; 640 #define BENIGN_LANGOPT(Name, Bits, Default, Description) 641 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) 642 #include "clang/Basic/LangOptions.def" 643 644 if (!LangOpts.ModuleFeatures.empty()) { 645 Out.indent(4) << "Module features:\n"; 646 for (StringRef Feature : LangOpts.ModuleFeatures) 647 Out.indent(6) << Feature << "\n"; 648 } 649 650 return false; 651 } 652 653 bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, 654 bool AllowCompatibleDifferences) override { 655 Out.indent(2) << "Target options:\n"; 656 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n"; 657 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n"; 658 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n"; 659 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n"; 660 661 if (!TargetOpts.FeaturesAsWritten.empty()) { 662 Out.indent(4) << "Target features:\n"; 663 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); 664 I != N; ++I) { 665 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n"; 666 } 667 } 668 669 return false; 670 } 671 672 bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, 673 bool Complain) override { 674 Out.indent(2) << "Diagnostic options:\n"; 675 #define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name); 676 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \ 677 Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n"; 678 #define VALUE_DIAGOPT(Name, Bits, Default) \ 679 Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n"; 680 #include "clang/Basic/DiagnosticOptions.def" 681 682 Out.indent(4) << "Diagnostic flags:\n"; 683 for (const std::string &Warning : DiagOpts->Warnings) 684 Out.indent(6) << "-W" << Warning << "\n"; 685 for (const std::string &Remark : DiagOpts->Remarks) 686 Out.indent(6) << "-R" << Remark << "\n"; 687 688 return false; 689 } 690 691 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, 692 StringRef SpecificModuleCachePath, 693 bool Complain) override { 694 Out.indent(2) << "Header search options:\n"; 695 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n"; 696 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n"; 697 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n"; 698 DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes, 699 "Use builtin include directories [-nobuiltininc]"); 700 DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes, 701 "Use standard system include directories [-nostdinc]"); 702 DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes, 703 "Use standard C++ include directories [-nostdinc++]"); 704 DUMP_BOOLEAN(HSOpts.UseLibcxx, 705 "Use libc++ (rather than libstdc++) [-stdlib=]"); 706 return false; 707 } 708 709 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, 710 bool Complain, 711 std::string &SuggestedPredefines) override { 712 Out.indent(2) << "Preprocessor options:\n"; 713 DUMP_BOOLEAN(PPOpts.UsePredefines, 714 "Uses compiler/target-specific predefines [-undef]"); 715 DUMP_BOOLEAN(PPOpts.DetailedRecord, 716 "Uses detailed preprocessing record (for indexing)"); 717 718 if (!PPOpts.Macros.empty()) { 719 Out.indent(4) << "Predefined macros:\n"; 720 } 721 722 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator 723 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end(); 724 I != IEnd; ++I) { 725 Out.indent(6); 726 if (I->second) 727 Out << "-U"; 728 else 729 Out << "-D"; 730 Out << I->first << "\n"; 731 } 732 return false; 733 } 734 735 /// Indicates that a particular module file extension has been read. 736 void readModuleFileExtension( 737 const ModuleFileExtensionMetadata &Metadata) override { 738 Out.indent(2) << "Module file extension '" 739 << Metadata.BlockName << "' " << Metadata.MajorVersion 740 << "." << Metadata.MinorVersion; 741 if (!Metadata.UserInfo.empty()) { 742 Out << ": "; 743 Out.write_escaped(Metadata.UserInfo); 744 } 745 746 Out << "\n"; 747 } 748 749 /// Tells the \c ASTReaderListener that we want to receive the 750 /// input files of the AST file via \c visitInputFile. 751 bool needsInputFileVisitation() override { return true; } 752 753 /// Tells the \c ASTReaderListener that we want to receive the 754 /// input files of the AST file via \c visitInputFile. 755 bool needsSystemInputFileVisitation() override { return true; } 756 757 /// Indicates that the AST file contains particular input file. 758 /// 759 /// \returns true to continue receiving the next input file, false to stop. 760 bool visitInputFile(StringRef Filename, bool isSystem, 761 bool isOverridden, bool isExplicitModule) override { 762 763 Out.indent(2) << "Input file: " << Filename; 764 765 if (isSystem || isOverridden || isExplicitModule) { 766 Out << " ["; 767 if (isSystem) { 768 Out << "System"; 769 if (isOverridden || isExplicitModule) 770 Out << ", "; 771 } 772 if (isOverridden) { 773 Out << "Overridden"; 774 if (isExplicitModule) 775 Out << ", "; 776 } 777 if (isExplicitModule) 778 Out << "ExplicitModule"; 779 780 Out << "]"; 781 } 782 783 Out << "\n"; 784 785 return true; 786 } 787 788 /// Returns true if this \c ASTReaderListener wants to receive the 789 /// imports of the AST file via \c visitImport, false otherwise. 790 bool needsImportVisitation() const override { return true; } 791 792 /// If needsImportVisitation returns \c true, this is called for each 793 /// AST file imported by this AST file. 794 void visitImport(StringRef ModuleName, StringRef Filename) override { 795 Out.indent(2) << "Imports module '" << ModuleName 796 << "': " << Filename.str() << "\n"; 797 } 798 #undef DUMP_BOOLEAN 799 }; 800 } 801 802 bool DumpModuleInfoAction::BeginInvocation(CompilerInstance &CI) { 803 // The Object file reader also supports raw ast files and there is no point in 804 // being strict about the module file format in -module-file-info mode. 805 CI.getHeaderSearchOpts().ModuleFormat = "obj"; 806 return true; 807 } 808 809 void DumpModuleInfoAction::ExecuteAction() { 810 // Set up the output file. 811 std::unique_ptr<llvm::raw_fd_ostream> OutFile; 812 StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile; 813 if (!OutputFileName.empty() && OutputFileName != "-") { 814 std::error_code EC; 815 OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC, 816 llvm::sys::fs::OF_TextWithCRLF)); 817 } 818 llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs(); 819 820 Out << "Information for module file '" << getCurrentFile() << "':\n"; 821 auto &FileMgr = getCompilerInstance().getFileManager(); 822 auto Buffer = FileMgr.getBufferForFile(getCurrentFile()); 823 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer(); 824 bool IsRaw = (Magic.size() >= 4 && Magic[0] == 'C' && Magic[1] == 'P' && 825 Magic[2] == 'C' && Magic[3] == 'H'); 826 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n"; 827 828 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 829 DumpModuleInfoListener Listener(Out); 830 HeaderSearchOptions &HSOpts = 831 PP.getHeaderSearchInfo().getHeaderSearchOpts(); 832 ASTReader::readASTFileControlBlock( 833 getCurrentFile(), FileMgr, getCompilerInstance().getPCHContainerReader(), 834 /*FindModuleFileExtensions=*/true, Listener, 835 HSOpts.ModulesValidateDiagnosticOptions); 836 } 837 838 //===----------------------------------------------------------------------===// 839 // Preprocessor Actions 840 //===----------------------------------------------------------------------===// 841 842 void DumpRawTokensAction::ExecuteAction() { 843 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 844 SourceManager &SM = PP.getSourceManager(); 845 846 // Start lexing the specified input file. 847 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID()); 848 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts()); 849 RawLex.SetKeepWhitespaceMode(true); 850 851 Token RawTok; 852 RawLex.LexFromRawLexer(RawTok); 853 while (RawTok.isNot(tok::eof)) { 854 PP.DumpToken(RawTok, true); 855 llvm::errs() << "\n"; 856 RawLex.LexFromRawLexer(RawTok); 857 } 858 } 859 860 void DumpTokensAction::ExecuteAction() { 861 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 862 // Start preprocessing the specified input file. 863 Token Tok; 864 PP.EnterMainSourceFile(); 865 do { 866 PP.Lex(Tok); 867 PP.DumpToken(Tok, true); 868 llvm::errs() << "\n"; 869 } while (Tok.isNot(tok::eof)); 870 } 871 872 void PreprocessOnlyAction::ExecuteAction() { 873 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 874 875 // Ignore unknown pragmas. 876 PP.IgnorePragmas(); 877 878 Token Tok; 879 // Start parsing the specified input file. 880 PP.EnterMainSourceFile(); 881 do { 882 PP.Lex(Tok); 883 } while (Tok.isNot(tok::eof)); 884 } 885 886 void PrintPreprocessedAction::ExecuteAction() { 887 CompilerInstance &CI = getCompilerInstance(); 888 // Output file may need to be set to 'Binary', to avoid converting Unix style 889 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows. 890 // 891 // Look to see what type of line endings the file uses. If there's a 892 // CRLF, then we won't open the file up in binary mode. If there is 893 // just an LF or CR, then we will open the file up in binary mode. 894 // In this fashion, the output format should match the input format, unless 895 // the input format has inconsistent line endings. 896 // 897 // This should be a relatively fast operation since most files won't have 898 // all of their source code on a single line. However, that is still a 899 // concern, so if we scan for too long, we'll just assume the file should 900 // be opened in binary mode. 901 902 bool BinaryMode = false; 903 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) { 904 BinaryMode = true; 905 const SourceManager &SM = CI.getSourceManager(); 906 if (llvm::Optional<llvm::MemoryBufferRef> Buffer = 907 SM.getBufferOrNone(SM.getMainFileID())) { 908 const char *cur = Buffer->getBufferStart(); 909 const char *end = Buffer->getBufferEnd(); 910 const char *next = (cur != end) ? cur + 1 : end; 911 912 // Limit ourselves to only scanning 256 characters into the source 913 // file. This is mostly a check in case the file has no 914 // newlines whatsoever. 915 if (end - cur > 256) 916 end = cur + 256; 917 918 while (next < end) { 919 if (*cur == 0x0D) { // CR 920 if (*next == 0x0A) // CRLF 921 BinaryMode = false; 922 923 break; 924 } else if (*cur == 0x0A) // LF 925 break; 926 927 ++cur; 928 ++next; 929 } 930 } 931 } 932 933 std::unique_ptr<raw_ostream> OS = 934 CI.createDefaultOutputFile(BinaryMode, getCurrentFileOrBufferName()); 935 if (!OS) return; 936 937 // If we're preprocessing a module map, start by dumping the contents of the 938 // module itself before switching to the input buffer. 939 auto &Input = getCurrentInput(); 940 if (Input.getKind().getFormat() == InputKind::ModuleMap) { 941 if (Input.isFile()) { 942 (*OS) << "# 1 \""; 943 OS->write_escaped(Input.getFile()); 944 (*OS) << "\"\n"; 945 } 946 getCurrentModule()->print(*OS); 947 (*OS) << "#pragma clang module contents\n"; 948 } 949 950 DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(), 951 CI.getPreprocessorOutputOpts()); 952 } 953 954 void PrintPreambleAction::ExecuteAction() { 955 switch (getCurrentFileKind().getLanguage()) { 956 case Language::C: 957 case Language::CXX: 958 case Language::ObjC: 959 case Language::ObjCXX: 960 case Language::OpenCL: 961 case Language::OpenCLCXX: 962 case Language::CUDA: 963 case Language::HIP: 964 break; 965 966 case Language::Unknown: 967 case Language::Asm: 968 case Language::LLVM_IR: 969 case Language::RenderScript: 970 // We can't do anything with these. 971 return; 972 } 973 974 // We don't expect to find any #include directives in a preprocessed input. 975 if (getCurrentFileKind().isPreprocessed()) 976 return; 977 978 CompilerInstance &CI = getCompilerInstance(); 979 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile()); 980 if (Buffer) { 981 unsigned Preamble = 982 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size; 983 llvm::outs().write((*Buffer)->getBufferStart(), Preamble); 984 } 985 } 986 987 void DumpCompilerOptionsAction::ExecuteAction() { 988 CompilerInstance &CI = getCompilerInstance(); 989 std::unique_ptr<raw_ostream> OSP = 990 CI.createDefaultOutputFile(false, getCurrentFile()); 991 if (!OSP) 992 return; 993 994 raw_ostream &OS = *OSP; 995 const Preprocessor &PP = CI.getPreprocessor(); 996 const LangOptions &LangOpts = PP.getLangOpts(); 997 998 // FIXME: Rather than manually format the JSON (which is awkward due to 999 // needing to remove trailing commas), this should make use of a JSON library. 1000 // FIXME: Instead of printing enums as an integral value and specifying the 1001 // type as a separate field, use introspection to print the enumerator. 1002 1003 OS << "{\n"; 1004 OS << "\n\"features\" : [\n"; 1005 { 1006 llvm::SmallString<128> Str; 1007 #define FEATURE(Name, Predicate) \ 1008 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \ 1009 .toVector(Str); 1010 #include "clang/Basic/Features.def" 1011 #undef FEATURE 1012 // Remove the newline and comma from the last entry to ensure this remains 1013 // valid JSON. 1014 OS << Str.substr(0, Str.size() - 2); 1015 } 1016 OS << "\n],\n"; 1017 1018 OS << "\n\"extensions\" : [\n"; 1019 { 1020 llvm::SmallString<128> Str; 1021 #define EXTENSION(Name, Predicate) \ 1022 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \ 1023 .toVector(Str); 1024 #include "clang/Basic/Features.def" 1025 #undef EXTENSION 1026 // Remove the newline and comma from the last entry to ensure this remains 1027 // valid JSON. 1028 OS << Str.substr(0, Str.size() - 2); 1029 } 1030 OS << "\n]\n"; 1031 1032 OS << "}"; 1033 } 1034 1035 void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { 1036 CompilerInstance &CI = getCompilerInstance(); 1037 SourceManager &SM = CI.getPreprocessor().getSourceManager(); 1038 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID()); 1039 1040 llvm::SmallString<1024> Output; 1041 llvm::SmallVector<minimize_source_to_dependency_directives::Token, 32> Toks; 1042 if (minimizeSourceToDependencyDirectives( 1043 FromFile.getBuffer(), Output, Toks, &CI.getDiagnostics(), 1044 SM.getLocForStartOfFile(SM.getMainFileID()))) { 1045 assert(CI.getDiagnostics().hasErrorOccurred() && 1046 "no errors reported for failure"); 1047 1048 // Preprocess the source when verifying the diagnostics to capture the 1049 // 'expected' comments. 1050 if (CI.getDiagnosticOpts().VerifyDiagnostics) { 1051 // Make sure we don't emit new diagnostics! 1052 CI.getDiagnostics().setSuppressAllDiagnostics(true); 1053 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 1054 PP.EnterMainSourceFile(); 1055 Token Tok; 1056 do { 1057 PP.Lex(Tok); 1058 } while (Tok.isNot(tok::eof)); 1059 } 1060 return; 1061 } 1062 llvm::outs() << Output; 1063 } 1064 1065 void GetDependenciesByModuleNameAction::ExecuteAction() { 1066 CompilerInstance &CI = getCompilerInstance(); 1067 Preprocessor &PP = CI.getPreprocessor(); 1068 SourceManager &SM = PP.getSourceManager(); 1069 FileID MainFileID = SM.getMainFileID(); 1070 SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID); 1071 SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 1072 IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName); 1073 Path.push_back(std::make_pair(ModuleID, FileStart)); 1074 auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false); 1075 PPCallbacks *CB = PP.getPPCallbacks(); 1076 CB->moduleImport(SourceLocation(), Path, ModResult); 1077 } 1078