diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-07-27 23:34:35 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-10-23 18:26:01 +0000 |
commit | 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch) | |
tree | 6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/clang/lib/Frontend | |
parent | 6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff) | |
parent | ac9a064cb179f3425b310fa2847f8764ac970a4d (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend')
20 files changed, 1098 insertions, 254 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp index f09a01b5dd4a..67d4c07d1ce3 100644 --- a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp @@ -56,6 +56,7 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/CodeCompleteOptions.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaCodeCompletion.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" @@ -375,8 +376,8 @@ void ASTUnit::CacheCodeCompletionResults() { SmallVector<Result, 8> Results; CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>(); CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator); - TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, - CCTUInfo, Results); + TheSema->CodeCompletion().GatherGlobalCodeCompletions( + *CachedCompletionAllocator, CCTUInfo, Results); // Translate global code completions into cached completions. llvm::DenseMap<CanQualType, unsigned> CompletionTypes; @@ -540,7 +541,17 @@ public: if (InitializedLanguage) return false; + // FIXME: We did similar things in ReadHeaderSearchOptions too. But such + // style is not scaling. Probably we need to invite some mechanism to + // handle such patterns generally. + auto PICLevel = LangOpt.PICLevel; + auto PIE = LangOpt.PIE; + LangOpt = LangOpts; + + LangOpt.PICLevel = PICLevel; + LangOpt.PIE = PIE; + InitializedLanguage = true; updated(); @@ -790,7 +801,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( const std::string &Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, - std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls, + std::shared_ptr<HeaderSearchOptions> HSOpts, + std::shared_ptr<LangOptions> LangOpts, bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors, bool UserFilesAreVolatile, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { std::unique_ptr<ASTUnit> AST(new ASTUnit(true)); @@ -804,7 +816,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( ConfigureDiags(Diags, *AST, CaptureDiagnostics); - AST->LangOpts = std::make_shared<LangOptions>(); + AST->LangOpts = LangOpts ? LangOpts : std::make_shared<LangOptions>(); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->Diagnostics = Diags; @@ -1056,7 +1068,7 @@ public: std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); } - std::vector<serialization::DeclID> takeTopLevelDeclIDs() { + std::vector<LocalDeclID> takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -1090,7 +1102,7 @@ public: private: unsigned Hash = 0; std::vector<Decl *> TopLevelDecls; - std::vector<serialization::DeclID> TopLevelDeclIDs; + std::vector<LocalDeclID> TopLevelDeclIDs; llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags; }; @@ -1456,11 +1468,12 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { std::vector<Decl *> Resolved; Resolved.reserve(TopLevelDeclsInPreamble.size()); - ExternalASTSource &Source = *getASTContext().getExternalSource(); + // The module file of the preamble. + serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule(); for (const auto TopLevelDecl : TopLevelDeclsInPreamble) { // Resolve the declaration ID to an actual declaration, possibly // deserializing the declaration in the process. - if (Decl *D = Source.GetExternalDecl(TopLevelDecl)) + if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl)) Resolved.push_back(D); } TopLevelDeclsInPreamble.clear(); @@ -2362,8 +2375,6 @@ bool ASTUnit::serialize(raw_ostream &OS) { return serializeUnit(Writer, Buffer, getSema(), OS); } -using SLocRemap = ContinuousRangeMap<unsigned, int, 2>; - void ASTUnit::TranslateStoredDiagnostics( FileManager &FileMgr, SourceManager &SrcMgr, diff --git a/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp index a25aa88bd85e..6242b5a7d9fe 100644 --- a/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp @@ -411,8 +411,7 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags, SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef()); else SourceMgr.overrideFileContents( - FromFile, std::unique_ptr<llvm::MemoryBuffer>( - const_cast<llvm::MemoryBuffer *>(RB.second))); + FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second)); } // Remap files in the source manager (with other files). @@ -1047,6 +1046,11 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty()) llvm::EnableStatistics(false); + // Sort vectors containing toc data and no toc data variables to facilitate + // binary search later. + llvm::sort(getCodeGenOpts().TocDataVarsUserSpecified); + llvm::sort(getCodeGenOpts().NoTocDataVars); + for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { // Reset the ID tables if we are reusing the SourceManager and parsing // regular files. @@ -1061,30 +1065,7 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { } } - if (getDiagnosticOpts().ShowCarets) { - // We can have multiple diagnostics sharing one diagnostic client. - // Get the total number of warnings/errors from the client. - unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); - unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); - - if (NumWarnings) - OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); - if (NumWarnings && NumErrors) - OS << " and "; - if (NumErrors) - OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); - if (NumWarnings || NumErrors) { - OS << " generated"; - if (getLangOpts().CUDA) { - if (!getLangOpts().CUDAIsDevice) { - OS << " when compiling for host"; - } else { - OS << " when compiling for " << getTargetOpts().CPU; - } - } - OS << ".\n"; - } - } + printDiagnosticStats(); if (getFrontendOpts().ShowStats) { if (hasFileManager()) { @@ -1112,6 +1093,36 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { return !getDiagnostics().getClient()->getNumErrors(); } +void CompilerInstance::printDiagnosticStats() { + if (!getDiagnosticOpts().ShowCarets) + return; + + raw_ostream &OS = getVerboseOutputStream(); + + // We can have multiple diagnostics sharing one diagnostic client. + // Get the total number of warnings/errors from the client. + unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); + unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); + + if (NumWarnings) + OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); + if (NumWarnings && NumErrors) + OS << " and "; + if (NumErrors) + OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); + if (NumWarnings || NumErrors) { + OS << " generated"; + if (getLangOpts().CUDA) { + if (!getLangOpts().CUDAIsDevice) { + OS << " when compiling for host"; + } else { + OS << " when compiling for " << getTargetOpts().CPU; + } + } + OS << ".\n"; + } +} + void CompilerInstance::LoadRequestedPlugins() { // Load any requested plugins. for (const std::string &Path : getFrontendOpts().Plugins) { @@ -1194,16 +1205,6 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, // Note the name of the module we're building. Invocation->getLangOpts().CurrentModule = std::string(ModuleName); - // Make sure that the failed-module structure has been allocated in - // the importing instance, and propagate the pointer to the newly-created - // instance. - PreprocessorOptions &ImportingPPOpts - = ImportingInstance.getInvocation().getPreprocessorOpts(); - if (!ImportingPPOpts.FailedModules) - ImportingPPOpts.FailedModules = - std::make_shared<PreprocessorOptions::FailedModulesSet>(); - PPOpts.FailedModules = ImportingPPOpts.FailedModules; - // If there is a module map file, build the module using the module map. // Set up the inputs/outputs so that we build the module from its umbrella // header. @@ -1257,6 +1258,13 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceMgr.pushModuleBuildStack(ModuleName, FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); + // Make sure that the failed-module structure has been allocated in + // the importing instance, and propagate the pointer to the newly-created + // instance. + if (!ImportingInstance.hasFailedModulesSet()) + ImportingInstance.createFailedModulesSet(); + Instance.setFailedModulesSet(ImportingInstance.getFailedModulesSetPtr()); + // If we're collecting module dependencies, we need to share a collector // between all of the module CompilerInstances. Other than that, we don't // want to produce any dependency output from the module build. @@ -1284,6 +1292,10 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, diag::remark_module_build_done) << ModuleName; + // Propagate the statistics to the parent FileManager. + if (!FrontendOpts.ModulesShareFileManager) + ImportingInstance.getFileManager().AddStats(Instance.getFileManager()); + if (Crashed) { // Clear the ASTConsumer if it hasn't been already, in case it owns streams // that must be closed before clearing output files. @@ -1325,9 +1337,24 @@ static bool compileModule(CompilerInstance &ImportingInstance, // Get or create the module map that we'll use to build this module. ModuleMap &ModMap = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); + SourceManager &SourceMgr = ImportingInstance.getSourceManager(); bool Result; - if (OptionalFileEntryRef ModuleMapFile = - ModMap.getContainingModuleMapFile(Module)) { + if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module); + ModuleMapFID.isValid()) { + // We want to use the top-level module map. If we don't, the compiling + // instance may think the containing module map is a top-level one, while + // the importing instance knows it's included from a parent module map via + // the extern directive. This mismatch could bite us later. + SourceLocation Loc = SourceMgr.getIncludeLoc(ModuleMapFID); + while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) { + ModuleMapFID = SourceMgr.getFileID(Loc); + Loc = SourceMgr.getIncludeLoc(ModuleMapFID); + } + + OptionalFileEntryRef ModuleMapFile = + SourceMgr.getFileEntryRefForID(ModuleMapFID); + assert(ModuleMapFile && "Top-level module map with no FileID"); + // Canonicalize compilation to start with the public module map. This is // vital for submodules declarations in the private module maps to be // correctly parsed when depending on a top level module in the public one. @@ -1584,6 +1611,14 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, } } +static void checkConfigMacros(Preprocessor &PP, Module *M, + SourceLocation ImportLoc) { + clang::Module *TopModule = M->getTopLevelModule(); + for (const StringRef ConMacro : TopModule->ConfigMacros) { + checkConfigMacro(PP, ConMacro, M, ImportLoc); + } +} + /// Write a new timestamp file with the given path. static void writeTimestampFile(StringRef TimestampFile) { std::error_code EC; @@ -1822,6 +1857,13 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( Module *M = HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective); + // Check for any configuration macros that have changed. This is done + // immediately before potentially building a module in case this module + // depends on having one of its configuration macros defined to successfully + // build. If this is not done the user will never see the warning. + if (M) + checkConfigMacros(getPreprocessor(), M, ImportLoc); + // Select the source and filename for loading the named module. std::string ModuleFilename; ModuleSource Source = @@ -1950,10 +1992,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( return nullptr; } - // Check whether we have already attempted to build this module (but - // failed). - if (getPreprocessorOpts().FailedModules && - getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { + // Check whether we have already attempted to build this module (but failed). + if (FailedModules && FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return nullptr; @@ -1964,8 +2004,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( ModuleFilename)) { assert(getDiagnostics().hasErrorOccurred() && "undiagnosed error in compileModuleAndReadAST"); - if (getPreprocessorOpts().FailedModules) - getPreprocessorOpts().FailedModules->addFailed(ModuleName); + if (FailedModules) + FailedModules->addFailed(ModuleName); return nullptr; } @@ -1999,12 +2039,23 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) { // Use the cached result, which may be nullptr. Module = *MaybeModule; + // Config macros are already checked before building a module, but they need + // to be checked at each import location in case any of the config macros + // have a new value at the current `ImportLoc`. + if (Module) + checkConfigMacros(getPreprocessor(), Module, ImportLoc); } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().lookupModule( ModuleName, ImportLoc, /*AllowSearch*/ true, /*AllowExtraModuleMapSearch*/ !IsInclusionDirective); + // Config macros do not need to be checked here for two reasons. + // * This will always be textual inclusion, and thus the config macros + // actually do impact the content of the header. + // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this + // function as the `#include` or `#import` is textual. + MM.cacheModuleLoad(*Path[0].first, Module); } else { ModuleLoadResult Result = findOrCompileModuleAndReadAST( @@ -2139,18 +2190,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc); } - // Check for any configuration macros that have changed. - clang::Module *TopModule = Module->getTopLevelModule(); - for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { - checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], - Module, ImportLoc); - } - // Resolve any remaining module using export_as for this one. getPreprocessor() .getHeaderSearchInfo() .getModuleMap() - .resolveLinkAsDependencies(TopModule); + .resolveLinkAsDependencies(Module->getTopLevelModule()); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(Module); diff --git a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp index feb4de2084b8..f6b6c44a4cab 100644 --- a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp @@ -191,6 +191,17 @@ CompilerInvocationBase::shallow_copy_assign(const CompilerInvocationBase &X) { return *this; } +CompilerInvocation::CompilerInvocation(const CowCompilerInvocation &X) + : CompilerInvocationBase(EmptyConstructor{}) { + CompilerInvocationBase::deep_copy_assign(X); +} + +CompilerInvocation & +CompilerInvocation::operator=(const CowCompilerInvocation &X) { + CompilerInvocationBase::deep_copy_assign(X); + return *this; +} + namespace { template <typename T> T &ensureOwned(std::shared_ptr<T> &Storage) { @@ -522,10 +533,10 @@ static T extractMaskValue(T KeyPath) { #define PARSE_OPTION_WITH_MARSHALLING( \ ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, \ - ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, \ - NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ - if ((VISIBILITY)&options::CC1Option) { \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ + SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ + IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + if ((VISIBILITY) & options::CC1Option) { \ KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \ if (IMPLIED_CHECK) \ KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \ @@ -539,10 +550,10 @@ static T extractMaskValue(T KeyPath) { // with lifetime extension of the reference. #define GENERATE_OPTION_WITH_MARSHALLING( \ CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \ - KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \ - DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ - if ((VISIBILITY)&options::CC1Option) { \ + VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ + SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ + IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + if ((VISIBILITY) & options::CC1Option) { \ [&](const auto &Extracted) { \ if (ALWAYS_EMIT || \ (Extracted != \ @@ -599,6 +610,19 @@ static bool FixupInvocation(CompilerInvocation &Invocation, LangOpts.NewAlignOverride = 0; } + // The -f[no-]raw-string-literals option is only valid in C and in C++ + // standards before C++11. + if (LangOpts.CPlusPlus11) { + if (Args.hasArg(OPT_fraw_string_literals, OPT_fno_raw_string_literals)) { + Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals); + Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11) + << bool(LangOpts.RawStringLiterals); + } + + // Do not allow disabling raw string literals in C++11 or later. + LangOpts.RawStringLiterals = true; + } + // Prevent the user from specifying both -fsycl-is-device and -fsycl-is-host. if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost) Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device" @@ -1447,6 +1471,52 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts, Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); } +void CompilerInvocation::setDefaultPointerAuthOptions( + PointerAuthOptions &Opts, const LangOptions &LangOpts, + const llvm::Triple &Triple) { + assert(Triple.getArch() == llvm::Triple::aarch64); + if (LangOpts.PointerAuthCalls) { + using Key = PointerAuthSchema::ARM8_3Key; + using Discrimination = PointerAuthSchema::Discrimination; + // If you change anything here, be sure to update <ptrauth.h>. + Opts.FunctionPointers = PointerAuthSchema( + Key::ASIA, false, + LangOpts.PointerAuthFunctionTypeDiscrimination ? Discrimination::Type + : Discrimination::None); + + Opts.CXXVTablePointers = PointerAuthSchema( + Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination, + LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type + : Discrimination::None); + + if (LangOpts.PointerAuthTypeInfoVTPtrDiscrimination) + Opts.CXXTypeInfoVTablePointer = + PointerAuthSchema(Key::ASDA, true, Discrimination::Constant, + StdTypeInfoVTablePointerConstantDiscrimination); + else + Opts.CXXTypeInfoVTablePointer = + PointerAuthSchema(Key::ASDA, false, Discrimination::None); + + Opts.CXXVTTVTablePointers = + PointerAuthSchema(Key::ASDA, false, Discrimination::None); + Opts.CXXVirtualFunctionPointers = Opts.CXXVirtualVariadicFunctionPointers = + PointerAuthSchema(Key::ASIA, true, Discrimination::Decl); + Opts.CXXMemberFunctionPointers = + PointerAuthSchema(Key::ASIA, false, Discrimination::Type); + } + Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos; +} + +static void parsePointerAuthOptions(PointerAuthOptions &Opts, + const LangOptions &LangOpts, + const llvm::Triple &Triple, + DiagnosticsEngine &Diags) { + if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthIndirectGotos) + return; + + CompilerInvocation::setDefaultPointerAuthOptions(Opts, LangOpts, Triple); +} + void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, ArgumentConsumer Consumer, const llvm::Triple &T, @@ -1545,6 +1615,9 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, llvm::DICompileUnit::DebugNameTableKind::Default)) GenerateArg(Consumer, OPT_gpubnames); + if (Opts.DebugTemplateAlias) + GenerateArg(Consumer, OPT_gtemplate_alias); + auto TNK = Opts.getDebugSimpleTemplateNames(); if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) { if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple) @@ -1816,6 +1889,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.BinutilsVersion = std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ)); + Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias); + Opts.DebugNameTable = static_cast<unsigned>( Args.hasArg(OPT_ggnu_pubnames) ? llvm::DICompileUnit::DebugNameTableKind::GNU @@ -1953,7 +2028,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); else if (Val == llvm::FunctionReturnThunksKind::Extern && - Args.getLastArgValue(OPT_mcmodel_EQ).equals("large")) + Args.getLastArgValue(OPT_mcmodel_EQ) == "large") Diags.Report(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args); @@ -1975,14 +2050,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.LinkBitcodeFiles.push_back(F); } - if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) { - if (T.isOSAIX()) { - StringRef Name = A->getValue(); - if (Name == "local-dynamic") - Diags.Report(diag::err_aix_unsupported_tls_model) << Name; - } - } - if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) { StringRef Val = A->getValue(); Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val); @@ -2145,6 +2212,9 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); + if (!LangOpts->CUDAIsDevice) + parsePointerAuthOptions(Opts.PointerAuth, *LangOpts, T, Diags); + if (Args.hasArg(options::OPT_ffinite_loops)) Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always; else if (Args.hasArg(options::OPT_fno_finite_loops)) @@ -2399,6 +2469,9 @@ void CompilerInvocationBase::GenerateDiagnosticArgs( // This option is automatically generated from UndefPrefixes. if (Warning == "undef-prefix") continue; + // This option is automatically generated from CheckConstexprFunctionBodies. + if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr") + continue; Consumer(StringRef("-W") + Warning); } @@ -2541,6 +2614,7 @@ static const auto &getFrontendActionTable() { {frontend::DumpTokens, OPT_dump_tokens}, {frontend::EmitAssembly, OPT_S}, {frontend::EmitBC, OPT_emit_llvm_bc}, + {frontend::EmitCIR, OPT_emit_cir}, {frontend::EmitHTML, OPT_emit_html}, {frontend::EmitLLVM, OPT_emit_llvm}, {frontend::EmitLLVMOnly, OPT_emit_llvm_only}, @@ -2553,6 +2627,8 @@ static const auto &getFrontendActionTable() { {frontend::GenerateModule, OPT_emit_module}, {frontend::GenerateModuleInterface, OPT_emit_module_interface}, + {frontend::GenerateReducedModuleInterface, + OPT_emit_reduced_module_interface}, {frontend::GenerateHeaderUnit, OPT_emit_header_unit}, {frontend::GeneratePCH, OPT_emit_pch}, {frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs}, @@ -2752,6 +2828,9 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts, case Language::HLSL: Lang = "hlsl"; break; + case Language::CIR: + Lang = "cir"; + break; } GenerateArg(Consumer, OPT_x, @@ -2827,6 +2906,30 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, } Opts.ProgramAction = *ProgramAction; + + // Catch common mistakes when multiple actions are specified for cc1 (e.g. + // -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to + // support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name + // X ACTION), we suppress the error when the two actions are separated by + // -main-file-name. + // + // As an exception, accept composable -ast-dump*. + if (!A->getSpelling().starts_with("-ast-dump")) { + const Arg *SavedAction = nullptr; + for (const Arg *AA : + Args.filtered(OPT_Action_Group, OPT_main_file_name)) { + if (AA->getOption().matches(OPT_main_file_name)) { + SavedAction = nullptr; + } else if (!SavedAction) { + SavedAction = AA; + } else { + if (!A->getOption().matches(OPT_ast_dump_EQ)) + Diags.Report(diag::err_fe_invalid_multiple_actions) + << SavedAction->getSpelling() << A->getSpelling(); + break; + } + } + } } if (const Arg* A = Args.getLastArg(OPT_plugin)) { @@ -2878,6 +2981,8 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule) Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module" << "-emit-module"; + if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir)) + Opts.UseClangIRPipeline = true; if (Args.hasArg(OPT_aux_target_cpu)) Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu)); @@ -2953,6 +3058,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, .Cases("ast", "pcm", "precompiled-header", InputKind(Language::Unknown, InputKind::Precompiled)) .Case("ir", Language::LLVM_IR) + .Case("cir", Language::CIR) .Default(Language::Unknown); if (DashX.isUnknown()) @@ -3186,6 +3292,22 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, bool IsIndexHeaderMap = false; bool IsSysrootSpecified = Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); + + // Expand a leading `=` to the sysroot if one was passed (and it's not a + // framework flag). + auto PrefixHeaderPath = [IsSysrootSpecified, + &Opts](const llvm::opt::Arg *A, + bool IsFramework = false) -> std::string { + assert(A->getNumValues() && "Unexpected empty search path flag!"); + if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { + SmallString<32> Buffer; + llvm::sys::path::append(Buffer, Opts.Sysroot, + llvm::StringRef(A->getValue()).substr(1)); + return std::string(Buffer); + } + return A->getValue(); + }; + for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) { if (A->getOption().matches(OPT_index_header_map)) { // -index-header-map applies to the next -I or -F. @@ -3197,16 +3319,7 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled; bool IsFramework = A->getOption().matches(OPT_F); - std::string Path = A->getValue(); - - if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { - SmallString<32> Buffer; - llvm::sys::path::append(Buffer, Opts.Sysroot, - llvm::StringRef(A->getValue()).substr(1)); - Path = std::string(Buffer); - } - - Opts.AddPath(Path, Group, IsFramework, + Opts.AddPath(PrefixHeaderPath(A, IsFramework), Group, IsFramework, /*IgnoreSysroot*/ true); IsIndexHeaderMap = false; } @@ -3224,12 +3337,18 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, } for (const auto *A : Args.filtered(OPT_idirafter)) - Opts.AddPath(A->getValue(), frontend::After, false, true); + Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true); for (const auto *A : Args.filtered(OPT_iquote)) - Opts.AddPath(A->getValue(), frontend::Quoted, false, true); - for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) - Opts.AddPath(A->getValue(), frontend::System, false, - !A->getOption().matches(OPT_iwithsysroot)); + Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true); + + for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) { + if (A->getOption().matches(OPT_iwithsysroot)) { + Opts.AddPath(A->getValue(), frontend::System, false, + /*IgnoreSysRoot=*/false); + continue; + } + Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true); + } for (const auto *A : Args.filtered(OPT_iframework)) Opts.AddPath(A->getValue(), frontend::System, true, true); for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot)) @@ -3288,12 +3407,57 @@ static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args, Opts.ModuleSearchPaths.push_back(A->getValue()); } +static void GeneratePointerAuthArgs(const LangOptions &Opts, + ArgumentConsumer Consumer) { + if (Opts.PointerAuthIntrinsics) + GenerateArg(Consumer, OPT_fptrauth_intrinsics); + if (Opts.PointerAuthCalls) + GenerateArg(Consumer, OPT_fptrauth_calls); + if (Opts.PointerAuthReturns) + GenerateArg(Consumer, OPT_fptrauth_returns); + if (Opts.PointerAuthIndirectGotos) + GenerateArg(Consumer, OPT_fptrauth_indirect_gotos); + if (Opts.PointerAuthAuthTraps) + GenerateArg(Consumer, OPT_fptrauth_auth_traps); + if (Opts.PointerAuthVTPtrAddressDiscrimination) + GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination); + if (Opts.PointerAuthVTPtrTypeDiscrimination) + GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination); + if (Opts.PointerAuthTypeInfoVTPtrDiscrimination) + GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination); + + if (Opts.PointerAuthInitFini) + GenerateArg(Consumer, OPT_fptrauth_init_fini); + if (Opts.PointerAuthFunctionTypeDiscrimination) + GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination); +} + +static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags) { + Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics); + Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls); + Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns); + Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos); + Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps); + Opts.PointerAuthVTPtrAddressDiscrimination = + Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination); + Opts.PointerAuthVTPtrTypeDiscrimination = + Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination); + Opts.PointerAuthTypeInfoVTPtrDiscrimination = + Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination); + + Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini); + Opts.PointerAuthFunctionTypeDiscrimination = + Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination); +} + /// Check if input file kind and language standard are compatible. static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S) { switch (IK.getLanguage()) { case Language::Unknown: case Language::LLVM_IR: + case Language::CIR: llvm_unreachable("should not parse language flags for this input"); case Language::C: @@ -3359,6 +3523,8 @@ static StringRef GetInputKindName(InputKind IK) { return "Asm"; case Language::LLVM_IR: return "LLVM IR"; + case Language::CIR: + return "Clang IR"; case Language::HLSL: return "HLSL"; @@ -3374,7 +3540,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, const llvm::Triple &T, InputKind IK) { if (IK.getFormat() == InputKind::Precompiled || - IK.getLanguage() == Language::LLVM_IR) { + IK.getLanguage() == Language::LLVM_IR || + IK.getLanguage() == Language::CIR) { if (Opts.ObjCAutoRefCount) GenerateArg(Consumer, OPT_fobjc_arc); if (Opts.PICLevel != 0) @@ -3479,7 +3646,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fblocks); if (Opts.ConvergentFunctions && - !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice)) + !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice || + Opts.HLSL)) GenerateArg(Consumer, OPT_fconvergent_functions); if (Opts.NoBuiltin && !Opts.Freestanding) @@ -3617,6 +3785,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, case LangOptions::ClangABI::Ver17: GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0"); break; + case LangOptions::ClangABI::Ver18: + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0"); + break; case LangOptions::ClangABI::Latest: break; } @@ -3660,7 +3831,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, unsigned NumErrorsBefore = Diags.getNumErrors(); if (IK.getFormat() == InputKind::Precompiled || - IK.getLanguage() == Language::LLVM_IR) { + IK.getLanguage() == Language::LLVM_IR || + IK.getLanguage() == Language::CIR) { // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the // PassManager in BackendUtil.cpp. They need to be initialized no matter // what the input type is. @@ -3876,7 +4048,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.ConvergentFunctions = Args.hasArg(OPT_fconvergent_functions) || Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || - Opts.SYCLIsDevice; + Opts.SYCLIsDevice || Opts.HLSL; Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; if (!Opts.NoBuiltin) @@ -4009,6 +4181,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, if (TT.getArch() == llvm::Triple::UnknownArch || !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() || + TT.getArch() == llvm::Triple::systemz || TT.getArch() == llvm::Triple::nvptx || TT.getArch() == llvm::Triple::nvptx64 || TT.getArch() == llvm::Triple::amdgcn || @@ -4122,6 +4295,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.setClangABICompat(LangOptions::ClangABI::Ver15); else if (Major <= 17) Opts.setClangABICompat(LangOptions::ClangABI::Ver17); + else if (Major <= 18) + Opts.setClangABICompat(LangOptions::ClangABI::Ver18); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); @@ -4245,11 +4420,30 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported) << ShaderModel << T.getOSName() << T.str(); } + // Validate that if fnative-half-type is given, that + // the language standard is at least hlsl2018, and that + // the target shader model is at least 6.2. + if (Args.getLastArg(OPT_fnative_half_type)) { + const LangStandard &Std = + LangStandard::getLangStandardForKind(Opts.LangStd); + if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 && + T.getOSVersion() >= VersionTuple(6, 2))) + Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported) + << "-enable-16bit-types" << true << Std.getName() + << T.getOSVersion().getAsString(); + } } else if (T.isSPIRVLogical()) { if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) { Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported) << VulkanEnv << T.getOSName() << T.str(); } + if (Args.getLastArg(OPT_fnative_half_type)) { + const LangStandard &Std = + LangStandard::getLangStandardForKind(Opts.LangStd); + if (!(Opts.LangStd >= LangStandard::lang_hlsl2018)) + Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported) + << "-fnative-half-type" << false << Std.getName(); + } } else { llvm_unreachable("expected DXIL or SPIR-V target"); } @@ -4268,6 +4462,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::ASTView: case frontend::EmitAssembly: case frontend::EmitBC: + case frontend::EmitCIR: case frontend::EmitHTML: case frontend::EmitLLVM: case frontend::EmitLLVMOnly: @@ -4277,6 +4472,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::FixIt: case frontend::GenerateModule: case frontend::GenerateModuleInterface: + case frontend::GenerateReducedModuleInterface: case frontend::GenerateHeaderUnit: case frontend::GeneratePCH: case frontend::GenerateInterfaceStubs: @@ -4371,6 +4567,9 @@ static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts, if (Opts.DefineTargetOSMacros) GenerateArg(Consumer, OPT_fdefine_target_os_macros); + for (const auto &EmbedEntry : Opts.EmbedEntries) + GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry); + // Don't handle LexEditorPlaceholders. It is implied by the action that is // generated elsewhere. } @@ -4463,6 +4662,11 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, } } + for (const auto *A : Args.filtered(OPT_embed_dir_EQ)) { + StringRef Val = A->getValue(); + Opts.EmbedEntries.push_back(std::string(Val)); + } + // Always avoid lexing editor placeholders when we're just running the // preprocessor as we never want to emit the // "editor placeholder in source file" error in PP only mode. @@ -4606,6 +4810,8 @@ bool CompilerInvocation::CreateFromArgsImpl( Res.getFileSystemOpts().WorkingDir); ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags); + ParsePointerAuthArgs(LangOpts, Args, Diags); + ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes, Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) @@ -4763,6 +4969,7 @@ std::string CompilerInvocation::getModuleHash() const { if (hsOpts.ModulesStrictContextHash) { HBuilder.addRange(hsOpts.SystemHeaderPrefixes); HBuilder.addRange(hsOpts.UserEntries); + HBuilder.addRange(hsOpts.VFSOverlayFiles); const DiagnosticOptions &diagOpts = getDiagnosticOpts(); #define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name); @@ -4835,6 +5042,7 @@ void CompilerInvocationBase::generateCC1CommandLine( GenerateTargetArgs(getTargetOpts(), Consumer); GenerateHeaderSearchArgs(getHeaderSearchOpts(), Consumer); GenerateAPINotesArgs(getAPINotesOpts(), Consumer); + GeneratePointerAuthArgs(getLangOpts(), Consumer); GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX); GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T, getFrontendOpts().OutputFile, &getLangOpts()); diff --git a/contrib/llvm-project/clang/lib/Frontend/DependencyFile.cpp b/contrib/llvm-project/clang/lib/Frontend/DependencyFile.cpp index 19abcac2befb..528eae2c5283 100644 --- a/contrib/llvm-project/clang/lib/Frontend/DependencyFile.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/DependencyFile.cpp @@ -62,11 +62,25 @@ struct DepCollectorPPCallbacks : public PPCallbacks { /*IsMissing=*/false); } + void EmbedDirective(SourceLocation, StringRef, bool, + OptionalFileEntryRef File, + const LexEmbedParametersResult &) override { + assert(File && "expected to only be called when the file is found"); + StringRef FileName = + llvm::sys::path::remove_leading_dotslash(File->getName()); + DepCollector.maybeAddDependency(FileName, + /*FromModule*/ false, + /*IsSystem*/ false, + /*IsModuleFile*/ false, + /*IsMissing*/ false); + } + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, - StringRef RelativePath, const Module *Imported, + StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override { if (!File) DepCollector.maybeAddDependency(FileName, /*FromModule*/ false, @@ -76,6 +90,18 @@ struct DepCollectorPPCallbacks : public PPCallbacks { // Files that actually exist are handled by FileChanged. } + void HasEmbed(SourceLocation, StringRef, bool, + OptionalFileEntryRef File) override { + if (!File) + return; + StringRef Filename = + llvm::sys::path::remove_leading_dotslash(File->getName()); + DepCollector.maybeAddDependency(Filename, + /*FromModule=*/false, false, + /*IsModuleFile=*/false, + /*IsMissing=*/false); + } + void HasInclude(SourceLocation Loc, StringRef SpelledFilename, bool IsAngled, OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) override { diff --git a/contrib/llvm-project/clang/lib/Frontend/DependencyGraph.cpp b/contrib/llvm-project/clang/lib/Frontend/DependencyGraph.cpp index b471471f3528..c23ce66a40dd 100644 --- a/contrib/llvm-project/clang/lib/Frontend/DependencyGraph.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/DependencyGraph.cpp @@ -43,15 +43,20 @@ private: public: DependencyGraphCallback(const Preprocessor *_PP, StringRef OutputFile, StringRef SysRoot) - : PP(_PP), OutputFile(OutputFile.str()), SysRoot(SysRoot.str()) { } + : PP(_PP), OutputFile(OutputFile.str()), SysRoot(SysRoot.str()) {} void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, - StringRef RelativePath, const Module *Imported, + StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override; + void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled, + OptionalFileEntryRef File, + const LexEmbedParametersResult &Params) override; + void EndOfMainFile() override { OutputGraphFile(); } @@ -68,8 +73,26 @@ void clang::AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, void DependencyGraphCallback::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, - StringRef SearchPath, StringRef RelativePath, const Module *Imported, - SrcMgr::CharacteristicKind FileType) { + StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) { + if (!File) + return; + + SourceManager &SM = PP->getSourceManager(); + OptionalFileEntryRef FromFile = + SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(HashLoc))); + if (!FromFile) + return; + + Dependencies[*FromFile].push_back(*File); + + AllFiles.insert(*File); + AllFiles.insert(*FromFile); +} + +void DependencyGraphCallback::EmbedDirective(SourceLocation HashLoc, StringRef, + bool, OptionalFileEntryRef File, + const LexEmbedParametersResult &) { if (!File) return; diff --git a/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp index eff785b99a09..a9c45e525c69 100644 --- a/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp @@ -71,7 +71,7 @@ public: if (Previous) Previous->ReaderInitialized(Reader); } - void IdentifierRead(serialization::IdentID ID, + void IdentifierRead(serialization::IdentifierID ID, IdentifierInfo *II) override { if (Previous) Previous->IdentifierRead(ID, II); @@ -80,7 +80,7 @@ public: if (Previous) Previous->TypeRead(Idx, T); } - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (Previous) Previous->DeclRead(ID, D); } @@ -102,7 +102,7 @@ public: bool DeletePrevious) : DelegatingDeserializationListener(Previous, DeletePrevious) {} - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { llvm::outs() << " - "; @@ -128,7 +128,7 @@ public: : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), NamesToCheck(NamesToCheck) {} - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { unsigned DiagID @@ -535,8 +535,14 @@ static Module *prepareToBuildModule(CompilerInstance &CI, if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID( CI.getSourceManager().getMainFileID())) { M->IsInferred = true; - CI.getPreprocessor().getHeaderSearchInfo().getModuleMap() - .setInferredModuleAllowedBy(M, *OriginalModuleMap); + auto FileCharacter = + M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; + FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID( + *OriginalModuleMap, FileCharacter); + CI.getPreprocessor() + .getHeaderSearchInfo() + .getModuleMap() + .setInferredModuleAllowedBy(M, OriginalModuleMapFID); } } @@ -689,7 +695,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( std::string(InputFile), CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(), - CI.getHeaderSearchOptsPtr()); + CI.getHeaderSearchOptsPtr(), CI.getLangOptsPtr()); if (!AST) return false; @@ -751,8 +757,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // IR files bypass the rest of initialization. if (Input.getKind().getLanguage() == Language::LLVM_IR) { - assert(hasIRSupport() && - "This action does not have IR file support!"); + if (!hasIRSupport()) { + CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir) + << Input.getFile(); + return false; + } // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); diff --git a/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp index c1d6e7145536..e70210d55fe2 100644 --- a/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp @@ -184,12 +184,12 @@ bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI) { return true; } -std::unique_ptr<ASTConsumer> -GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::vector<std::unique_ptr<ASTConsumer>> +GenerateModuleAction::CreateMultiplexConsumer(CompilerInstance &CI, + StringRef InFile) { std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile); if (!OS) - return nullptr; + return {}; std::string OutputFile = CI.getFrontendOpts().OutputFile; std::string Sysroot; @@ -210,6 +210,17 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, +CI.getFrontendOpts().BuildingImplicitModule)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI, std::string(InFile), OutputFile, std::move(OS), Buffer)); + return Consumers; +} + +std::unique_ptr<ASTConsumer> +GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + std::vector<std::unique_ptr<ASTConsumer>> Consumers = + CreateMultiplexConsumer(CI, InFile); + if (Consumers.empty()) + return nullptr; + return std::make_unique<MultiplexConsumer>(std::move(Consumers)); } @@ -261,11 +272,20 @@ bool GenerateModuleInterfaceAction::BeginSourceFileAction( std::unique_ptr<ASTConsumer> GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - CI.getHeaderSearchOpts().ModulesSkipDiagnosticOptions = true; - CI.getHeaderSearchOpts().ModulesSkipHeaderSearchPaths = true; - CI.getHeaderSearchOpts().ModulesSkipPragmaDiagnosticMappings = true; + std::vector<std::unique_ptr<ASTConsumer>> Consumers; - return GenerateModuleAction::CreateASTConsumer(CI, InFile); + if (CI.getFrontendOpts().GenReducedBMI && + !CI.getFrontendOpts().ModuleOutputPath.empty()) { + Consumers.push_back(std::make_unique<ReducedBMIGenerator>( + CI.getPreprocessor(), CI.getModuleCache(), + CI.getFrontendOpts().ModuleOutputPath)); + } + + Consumers.push_back(std::make_unique<CXX20ModulesGenerator>( + CI.getPreprocessor(), CI.getModuleCache(), + CI.getFrontendOpts().OutputFile)); + + return std::make_unique<MultiplexConsumer>(std::move(Consumers)); } std::unique_ptr<raw_pwrite_stream> @@ -274,6 +294,14 @@ GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI, return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm"); } +std::unique_ptr<ASTConsumer> +GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + return std::make_unique<ReducedBMIGenerator>(CI.getPreprocessor(), + CI.getModuleCache(), + CI.getFrontendOpts().OutputFile); +} + bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) { if (!CI.getLangOpts().CPlusPlusModules) { CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules); @@ -426,6 +454,8 @@ private: return "BuildingBuiltinDumpStructCall"; case CodeSynthesisContext::BuildingDeductionGuides: return "BuildingDeductionGuides"; + case CodeSynthesisContext::TypeAliasTemplateInstantiation: + return "TypeAliasTemplateInstantiation"; } return ""; } @@ -811,9 +841,16 @@ static StringRef ModuleKindName(Module::ModuleKind MK) { } void DumpModuleInfoAction::ExecuteAction() { - assert(isCurrentFileAST() && "dumping non-AST?"); - // Set up the output file. CompilerInstance &CI = getCompilerInstance(); + + // Don't process files of type other than module to avoid crash + if (!isCurrentFileAST()) { + CI.getDiagnostics().Report(diag::err_file_is_not_module) + << getCurrentFile(); + return; + } + + // Set up the output file. StringRef OutputFileName = CI.getFrontendOpts().OutputFile; if (!OutputFileName.empty() && OutputFileName != "-") { std::error_code EC; @@ -826,8 +863,7 @@ void DumpModuleInfoAction::ExecuteAction() { auto &FileMgr = CI.getFileManager(); auto Buffer = FileMgr.getBufferForFile(getCurrentFile()); StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer(); - bool IsRaw = (Magic.size() >= 4 && Magic[0] == 'C' && Magic[1] == 'P' && - Magic[2] == 'C' && Magic[3] == 'H'); + bool IsRaw = Magic.starts_with("CPCH"); Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n"; Preprocessor &PP = CI.getPreprocessor(); @@ -840,7 +876,6 @@ void DumpModuleInfoAction::ExecuteAction() { const LangOptions &LO = getCurrentASTUnit().getLangOpts(); if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) { - ASTReader *R = getCurrentASTUnit().getASTReader().get(); unsigned SubModuleCount = R->getTotalNumSubmodules(); serialization::ModuleFile &MF = R->getModuleManager().getPrimaryModule(); @@ -1061,6 +1096,7 @@ void PrintPreambleAction::ExecuteAction() { case Language::CUDA: case Language::HIP: case Language::HLSL: + case Language::CIR: break; case Language::Unknown: diff --git a/contrib/llvm-project/clang/lib/Frontend/FrontendOptions.cpp b/contrib/llvm-project/clang/lib/Frontend/FrontendOptions.cpp index bf83b27c1367..32ed99571e85 100644 --- a/contrib/llvm-project/clang/lib/Frontend/FrontendOptions.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/FrontendOptions.cpp @@ -34,5 +34,6 @@ InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) { .Case("hip", Language::HIP) .Cases("ll", "bc", Language::LLVM_IR) .Case("hlsl", Language::HLSL) + .Case("cir", Language::CIR) .Default(Language::Unknown); } diff --git a/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp b/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp index 1b91c86f9139..920ddf7e5991 100644 --- a/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp @@ -113,7 +113,11 @@ static T PickFP(const llvm::fltSemantics *Sem, T IEEEHalfVal, T IEEESingleVal, static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix, const llvm::fltSemantics *Sem, StringRef Ext) { - const char *DenormMin, *Epsilon, *Max, *Min; + const char *DenormMin, *NormMax, *Epsilon, *Max, *Min; + NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38", + "1.7976931348623157e+308", "1.18973149535723176502e+4932", + "8.98846567431157953864652595394501e+307", + "1.18973149535723176508575932662800702e+4932"); DenormMin = PickFP(Sem, "5.9604644775390625e-8", "1.40129846e-45", "4.9406564584124654e-324", "3.64519953188247460253e-4951", "4.94065645841246544176568792868221e-324", @@ -144,6 +148,7 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix, DefPrefix += "_"; Builder.defineMacro(DefPrefix + "DENORM_MIN__", Twine(DenormMin)+Ext); + Builder.defineMacro(DefPrefix + "NORM_MAX__", Twine(NormMax)+Ext); Builder.defineMacro(DefPrefix + "HAS_DENORM__"); Builder.defineMacro(DefPrefix + "DIG__", Twine(Digits)); Builder.defineMacro(DefPrefix + "DECIMAL_DIG__", Twine(DecimalDigits)); @@ -181,14 +186,21 @@ static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, TI.isTypeSigned(Ty), Builder); } -static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty, - const TargetInfo &TI, MacroBuilder &Builder) { - bool IsSigned = TI.isTypeSigned(Ty); +static void DefineFmt(const LangOptions &LangOpts, const Twine &Prefix, + TargetInfo::IntType Ty, const TargetInfo &TI, + MacroBuilder &Builder) { StringRef FmtModifier = TI.getTypeFormatModifier(Ty); - for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) { - Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__", - Twine("\"") + FmtModifier + Twine(*Fmt) + "\""); - } + auto Emitter = [&](char Fmt) { + Builder.defineMacro(Prefix + "_FMT" + Twine(Fmt) + "__", + Twine("\"") + FmtModifier + Twine(Fmt) + "\""); + }; + bool IsSigned = TI.isTypeSigned(Ty); + llvm::for_each(StringRef(IsSigned ? "di" : "ouxX"), Emitter); + + // C23 added the b and B modifiers for printing binary output of unsigned + // integers. Conditionally define those if compiling in C23 mode. + if (LangOpts.C23 && !IsSigned) + llvm::for_each(StringRef("bB"), Emitter); } static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty, @@ -217,7 +229,8 @@ static void DefineTypeSizeAndWidth(const Twine &Prefix, TargetInfo::IntType Ty, DefineTypeWidth(Prefix + "_WIDTH__", Ty, TI, Builder); } -static void DefineExactWidthIntType(TargetInfo::IntType Ty, +static void DefineExactWidthIntType(const LangOptions &LangOpts, + TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { int TypeWidth = TI.getTypeWidth(Ty); @@ -236,7 +249,7 @@ static void DefineExactWidthIntType(TargetInfo::IntType Ty, const char *Prefix = IsSigned ? "__INT" : "__UINT"; DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); - DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); + DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder); StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty)); Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix); @@ -259,7 +272,8 @@ static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty, DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); } -static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned, +static void DefineLeastWidthIntType(const LangOptions &LangOpts, + unsigned TypeWidth, bool IsSigned, const TargetInfo &TI, MacroBuilder &Builder) { TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned); @@ -274,11 +288,12 @@ static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned, DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder); else DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); - DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); + DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder); } -static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, - const TargetInfo &TI, MacroBuilder &Builder) { +static void DefineFastIntType(const LangOptions &LangOpts, unsigned TypeWidth, + bool IsSigned, const TargetInfo &TI, + MacroBuilder &Builder) { // stdint.h currently defines the fast int types as equivalent to the least // types. TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned); @@ -293,7 +308,7 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder); else DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); - DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); + DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder); } @@ -379,8 +394,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, Twine((unsigned)LangOpts.getHLSLVersion())); if (LangOpts.NativeHalfType) - Builder.defineMacro("__HLSL_ENABLE_16_BIT", - Twine((unsigned)LangOpts.getHLSLVersion())); + Builder.defineMacro("__HLSL_ENABLE_16_BIT", "1"); // Shader target information // "enums" for shader stages @@ -423,7 +437,8 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, // [C++] Whether __STDC__ is predefined and if so, what its value is, // are implementation-defined. // (Removed in C++20.) - if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP) + if ((!LangOpts.MSVCCompat || LangOpts.MSVCEnableStdcMacro) && + !LangOpts.TraditionalCPP) Builder.defineMacro("__STDC__"); // -- __STDC_HOSTED__ // The integer literal 1 if the implementation is a hosted @@ -438,7 +453,9 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, // value is, are implementation-defined. // (Removed in C++20.) if (!LangOpts.CPlusPlus) { - if (LangOpts.C23) + if (LangOpts.C2y) + Builder.defineMacro("__STDC_VERSION__", "202400L"); + else if (LangOpts.C23) Builder.defineMacro("__STDC_VERSION__", "202311L"); else if (LangOpts.C17) Builder.defineMacro("__STDC_VERSION__", "201710L"); @@ -498,6 +515,14 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__STDC_UTF_16__", "1"); Builder.defineMacro("__STDC_UTF_32__", "1"); + // __has_embed definitions + Builder.defineMacro("__STDC_EMBED_NOT_FOUND__", + llvm::itostr(static_cast<int>(EmbedResult::NotFound))); + Builder.defineMacro("__STDC_EMBED_FOUND__", + llvm::itostr(static_cast<int>(EmbedResult::Found))); + Builder.defineMacro("__STDC_EMBED_EMPTY__", + llvm::itostr(static_cast<int>(EmbedResult::Empty))); + if (LangOpts.ObjC) Builder.defineMacro("__OBJC__"); @@ -643,7 +668,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, : "200704"); Builder.defineMacro("__cpp_constexpr_in_decltype", "201711L"); Builder.defineMacro("__cpp_range_based_for", - LangOpts.CPlusPlus17 ? "201603L" : "200907"); + LangOpts.CPlusPlus23 ? "202211L" + : LangOpts.CPlusPlus17 ? "201603L" + : "200907"); Builder.defineMacro("__cpp_static_assert", LangOpts.CPlusPlus26 ? "202306L" : LangOpts.CPlusPlus17 ? "201411L" @@ -692,7 +719,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_nested_namespace_definitions", "201411L"); Builder.defineMacro("__cpp_variadic_using", "201611L"); Builder.defineMacro("__cpp_aggregate_bases", "201603L"); - Builder.defineMacro("__cpp_structured_bindings", "201606L"); + Builder.defineMacro("__cpp_structured_bindings", "202403L"); Builder.defineMacro("__cpp_nontype_template_args", "201411L"); // (not latest) Builder.defineMacro("__cpp_fold_expressions", "201603L"); @@ -708,10 +735,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, if (LangOpts.CPlusPlus20) { Builder.defineMacro("__cpp_aggregate_paren_init", "201902L"); - // P0848 is implemented, but we're still waiting for other concepts - // issues to be addressed before bumping __cpp_concepts up to 202002L. - // Refer to the discussion of this at https://reviews.llvm.org/D128619. - Builder.defineMacro("__cpp_concepts", "201907L"); + Builder.defineMacro("__cpp_concepts", "202002"); Builder.defineMacro("__cpp_conditional_explicit", "201806L"); Builder.defineMacro("__cpp_consteval", "202211L"); Builder.defineMacro("__cpp_constexpr_dynamic_alloc", "201907L"); @@ -724,7 +748,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, } // C++23 features. if (LangOpts.CPlusPlus23) { - Builder.defineMacro("__cpp_implicit_move", "202011L"); + Builder.defineMacro("__cpp_implicit_move", "202207L"); Builder.defineMacro("__cpp_size_t_suffix", "202011L"); Builder.defineMacro("__cpp_if_consteval", "202106L"); Builder.defineMacro("__cpp_multidimensional_subscript", "202211L"); @@ -738,6 +762,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_named_character_escapes", "202207L"); Builder.defineMacro("__cpp_placeholder_variables", "202306L"); + // C++26 features supported in earlier language modes. + Builder.defineMacro("__cpp_deleted_function", "202403L"); + if (LangOpts.Char8) Builder.defineMacro("__cpp_char8_t", "202207L"); Builder.defineMacro("__cpp_impl_destroying_delete", "201806L"); @@ -766,6 +793,60 @@ void InitializeOpenCLFeatureTestMacros(const TargetInfo &TI, Builder.defineMacro("__opencl_c_int64"); } +llvm::SmallString<32> ConstructFixedPointLiteral(llvm::APFixedPoint Val, + llvm::StringRef Suffix) { + if (Val.isSigned() && Val == llvm::APFixedPoint::getMin(Val.getSemantics())) { + // When representing the min value of a signed fixed point type in source + // code, we cannot simply write `-<lowest value>`. For example, the min + // value of a `short _Fract` cannot be written as `-1.0hr`. This is because + // the parser will read this (and really any negative numerical literal) as + // a UnaryOperator that owns a FixedPointLiteral with a positive value + // rather than just a FixedPointLiteral with a negative value. Compiling + // `-1.0hr` results in an overflow to the maximal value of that fixed point + // type. The correct way to represent a signed min value is to instead split + // it into two halves, like `(-0.5hr-0.5hr)` which is what the standard + // defines SFRACT_MIN as. + llvm::SmallString<32> Literal; + Literal.push_back('('); + llvm::SmallString<32> HalfStr = + ConstructFixedPointLiteral(Val.shr(1), Suffix); + Literal += HalfStr; + Literal += HalfStr; + Literal.push_back(')'); + return Literal; + } + + llvm::SmallString<32> Str(Val.toString()); + Str += Suffix; + return Str; +} + +void DefineFixedPointMacros(const TargetInfo &TI, MacroBuilder &Builder, + llvm::StringRef TypeName, llvm::StringRef Suffix, + unsigned Width, unsigned Scale, bool Signed) { + // Saturation doesn't affect the size or scale of a fixed point type, so we + // don't need it here. + llvm::FixedPointSemantics FXSema( + Width, Scale, Signed, /*IsSaturated=*/false, + !Signed && TI.doUnsignedFixedPointTypesHavePadding()); + llvm::SmallString<32> MacroPrefix("__"); + MacroPrefix += TypeName; + Builder.defineMacro(MacroPrefix + "_EPSILON__", + ConstructFixedPointLiteral( + llvm::APFixedPoint::getEpsilon(FXSema), Suffix)); + Builder.defineMacro(MacroPrefix + "_FBIT__", Twine(Scale)); + Builder.defineMacro( + MacroPrefix + "_MAX__", + ConstructFixedPointLiteral(llvm::APFixedPoint::getMax(FXSema), Suffix)); + + // ISO/IEC TR 18037:2008 doesn't specify MIN macros for unsigned types since + // they're all just zero. + if (Signed) + Builder.defineMacro( + MacroPrefix + "_MIN__", + ConstructFixedPointLiteral(llvm::APFixedPoint::getMin(FXSema), Suffix)); +} + static void InitializePredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, @@ -860,6 +941,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.GNUCVersion && LangOpts.CPlusPlus11) Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__"); + if (TI.getTriple().isWindowsGNUEnvironment()) { + // Set ABI defining macros for libstdc++ for MinGW, where the + // default in libstdc++ differs from the defaults for this target. + Builder.defineMacro("__GXX_TYPEINFO_EQUALITY_INLINE", "0"); + } + if (LangOpts.ObjC) { if (LangOpts.ObjCRuntime.isNonFragile()) { Builder.defineMacro("__OBJC2__"); @@ -941,6 +1028,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, else if (LangOpts.hasDWARFExceptions() && (TI.getTriple().isThumb() || TI.getTriple().isARM())) Builder.defineMacro("__ARM_DWARF_EH__"); + else if (LangOpts.hasWasmExceptions() && TI.getTriple().isWasm()) + Builder.defineMacro("__WASM_EXCEPTIONS__"); if (LangOpts.Deprecated) Builder.defineMacro("__DEPRECATED"); @@ -1064,27 +1153,30 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder); DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder); - DefineFmt("__INTMAX", TI.getIntMaxType(), TI, Builder); + DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder); Builder.defineMacro("__INTMAX_C_SUFFIX__", TI.getTypeConstantSuffix(TI.getIntMaxType())); DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder); - DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder); + DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder); Builder.defineMacro("__UINTMAX_C_SUFFIX__", TI.getTypeConstantSuffix(TI.getUIntMaxType())); DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder); - DefineFmt("__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI, Builder); + DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI, + Builder); DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder); - DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder); + DefineFmt(LangOpts, "__INTPTR", TI.getIntPtrType(), TI, Builder); DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder); - DefineFmt("__SIZE", TI.getSizeType(), TI, Builder); + DefineFmt(LangOpts, "__SIZE", TI.getSizeType(), TI, Builder); DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder); DefineType("__WINT_TYPE__", TI.getWIntType(), Builder); DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder); + if (LangOpts.C23) + DefineType("__CHAR8_TYPE__", TI.UnsignedChar, Builder); DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder); DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder); DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder); - DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder); + DefineFmt(LangOpts, "__UINTPTR", TI.getUIntPtrType(), TI, Builder); // The C standard requires the width of uintptr_t and intptr_t to be the same, // per 7.20.2.4p1. Same for intmax_t and uintmax_t, per 7.20.2.5p1. @@ -1095,6 +1187,47 @@ static void InitializePredefinedMacros(const TargetInfo &TI, TI.getTypeWidth(TI.getIntMaxType()) && "uintmax_t and intmax_t have different widths?"); + if (LangOpts.FixedPoint) { + // Each unsigned type has the same width as their signed type. + DefineFixedPointMacros(TI, Builder, "SFRACT", "HR", TI.getShortFractWidth(), + TI.getShortFractScale(), /*Signed=*/true); + DefineFixedPointMacros(TI, Builder, "USFRACT", "UHR", + TI.getShortFractWidth(), + TI.getUnsignedShortFractScale(), /*Signed=*/false); + DefineFixedPointMacros(TI, Builder, "FRACT", "R", TI.getFractWidth(), + TI.getFractScale(), /*Signed=*/true); + DefineFixedPointMacros(TI, Builder, "UFRACT", "UR", TI.getFractWidth(), + TI.getUnsignedFractScale(), /*Signed=*/false); + DefineFixedPointMacros(TI, Builder, "LFRACT", "LR", TI.getLongFractWidth(), + TI.getLongFractScale(), /*Signed=*/true); + DefineFixedPointMacros(TI, Builder, "ULFRACT", "ULR", + TI.getLongFractWidth(), + TI.getUnsignedLongFractScale(), /*Signed=*/false); + DefineFixedPointMacros(TI, Builder, "SACCUM", "HK", TI.getShortAccumWidth(), + TI.getShortAccumScale(), /*Signed=*/true); + DefineFixedPointMacros(TI, Builder, "USACCUM", "UHK", + TI.getShortAccumWidth(), + TI.getUnsignedShortAccumScale(), /*Signed=*/false); + DefineFixedPointMacros(TI, Builder, "ACCUM", "K", TI.getAccumWidth(), + TI.getAccumScale(), /*Signed=*/true); + DefineFixedPointMacros(TI, Builder, "UACCUM", "UK", TI.getAccumWidth(), + TI.getUnsignedAccumScale(), /*Signed=*/false); + DefineFixedPointMacros(TI, Builder, "LACCUM", "LK", TI.getLongAccumWidth(), + TI.getLongAccumScale(), /*Signed=*/true); + DefineFixedPointMacros(TI, Builder, "ULACCUM", "ULK", + TI.getLongAccumWidth(), + TI.getUnsignedLongAccumScale(), /*Signed=*/false); + + Builder.defineMacro("__SACCUM_IBIT__", Twine(TI.getShortAccumIBits())); + Builder.defineMacro("__USACCUM_IBIT__", + Twine(TI.getUnsignedShortAccumIBits())); + Builder.defineMacro("__ACCUM_IBIT__", Twine(TI.getAccumIBits())); + Builder.defineMacro("__UACCUM_IBIT__", Twine(TI.getUnsignedAccumIBits())); + Builder.defineMacro("__LACCUM_IBIT__", Twine(TI.getLongAccumIBits())); + Builder.defineMacro("__ULACCUM_IBIT__", + Twine(TI.getUnsignedLongAccumIBits())); + } + if (TI.hasFloat16Type()) DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16"); DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F"); @@ -1119,65 +1252,66 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__WINT_UNSIGNED__"); // Define exact-width integer types for stdint.h - DefineExactWidthIntType(TargetInfo::SignedChar, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::SignedChar, TI, Builder); if (TI.getShortWidth() > TI.getCharWidth()) - DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::SignedShort, TI, Builder); if (TI.getIntWidth() > TI.getShortWidth()) - DefineExactWidthIntType(TargetInfo::SignedInt, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::SignedInt, TI, Builder); if (TI.getLongWidth() > TI.getIntWidth()) - DefineExactWidthIntType(TargetInfo::SignedLong, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::SignedLong, TI, Builder); if (TI.getLongLongWidth() > TI.getLongWidth()) - DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::SignedLongLong, TI, Builder); - DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedChar, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder); if (TI.getShortWidth() > TI.getCharWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedShort, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder); } if (TI.getIntWidth() > TI.getShortWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedInt, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder); } if (TI.getLongWidth() > TI.getIntWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder); } if (TI.getLongLongWidth() > TI.getLongWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder); + DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLongLong, TI, + Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder); } - DefineLeastWidthIntType(8, true, TI, Builder); - DefineLeastWidthIntType(8, false, TI, Builder); - DefineLeastWidthIntType(16, true, TI, Builder); - DefineLeastWidthIntType(16, false, TI, Builder); - DefineLeastWidthIntType(32, true, TI, Builder); - DefineLeastWidthIntType(32, false, TI, Builder); - DefineLeastWidthIntType(64, true, TI, Builder); - DefineLeastWidthIntType(64, false, TI, Builder); - - DefineFastIntType(8, true, TI, Builder); - DefineFastIntType(8, false, TI, Builder); - DefineFastIntType(16, true, TI, Builder); - DefineFastIntType(16, false, TI, Builder); - DefineFastIntType(32, true, TI, Builder); - DefineFastIntType(32, false, TI, Builder); - DefineFastIntType(64, true, TI, Builder); - DefineFastIntType(64, false, TI, Builder); + DefineLeastWidthIntType(LangOpts, 8, true, TI, Builder); + DefineLeastWidthIntType(LangOpts, 8, false, TI, Builder); + DefineLeastWidthIntType(LangOpts, 16, true, TI, Builder); + DefineLeastWidthIntType(LangOpts, 16, false, TI, Builder); + DefineLeastWidthIntType(LangOpts, 32, true, TI, Builder); + DefineLeastWidthIntType(LangOpts, 32, false, TI, Builder); + DefineLeastWidthIntType(LangOpts, 64, true, TI, Builder); + DefineLeastWidthIntType(LangOpts, 64, false, TI, Builder); + + DefineFastIntType(LangOpts, 8, true, TI, Builder); + DefineFastIntType(LangOpts, 8, false, TI, Builder); + DefineFastIntType(LangOpts, 16, true, TI, Builder); + DefineFastIntType(LangOpts, 16, false, TI, Builder); + DefineFastIntType(LangOpts, 32, true, TI, Builder); + DefineFastIntType(LangOpts, 32, false, TI, Builder); + DefineFastIntType(LangOpts, 64, true, TI, Builder); + DefineFastIntType(LangOpts, 64, false, TI, Builder); Builder.defineMacro("__USER_LABEL_PREFIX__", TI.getUserLabelPrefix()); @@ -1200,6 +1334,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1"); } + // GCC defines these macros in both C and C++ modes despite them being needed + // mostly for STL implementations in C++. + auto [Destructive, Constructive] = TI.hardwareInterferenceSizes(); + Builder.defineMacro("__GCC_DESTRUCTIVE_SIZE", Twine(Destructive)); + Builder.defineMacro("__GCC_CONSTRUCTIVE_SIZE", Twine(Constructive)); + // We need to use push_macro to allow users to redefine these macros from the + // command line with -D and not issue a -Wmacro-redefined warning. + Builder.append("#pragma push_macro(\"__GCC_DESTRUCTIVE_SIZE\")"); + Builder.append("#pragma push_macro(\"__GCC_CONSTRUCTIVE_SIZE\")"); + auto addLockFreeMacros = [&](const llvm::Twine &Prefix) { // Used by libc++ and libstdc++ to implement ATOMIC_<foo>_LOCK_FREE. #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ @@ -1207,8 +1351,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, getLockFreeValue(TI.get##Type##Width(), TI)); DEFINE_LOCK_FREE_MACRO(BOOL, Bool); DEFINE_LOCK_FREE_MACRO(CHAR, Char); - if (LangOpts.Char8) - DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char. + // char8_t has the same representation / width as unsigned + // char in C++ and is a typedef for unsigned char in C23 + if (LangOpts.Char8 || LangOpts.C23) + DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16); DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32); DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar); diff --git a/contrib/llvm-project/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp b/contrib/llvm-project/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp index d58f5bb09199..d7cfd23bb0a7 100644 --- a/contrib/llvm-project/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp @@ -33,7 +33,8 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer { MangledSymbol(const std::string &ParentName, uint8_t Type, uint8_t Binding, std::vector<std::string> Names) - : ParentName(ParentName), Type(Type), Binding(Binding), Names(Names) {} + : ParentName(ParentName), Type(Type), Binding(Binding), + Names(std::move(Names)) {} }; using MangledSymbols = std::map<const NamedDecl *, MangledSymbol>; @@ -295,7 +296,7 @@ public: OS << "Symbols:\n"; for (const auto &E : Symbols) { const MangledSymbol &Symbol = E.second; - for (auto Name : Symbol.Names) { + for (const auto &Name : Symbol.Names) { OS << " - { Name: \"" << (Symbol.ParentName.empty() || Instance.getLangOpts().CPlusPlus ? "" diff --git a/contrib/llvm-project/clang/lib/Frontend/ModuleDependencyCollector.cpp b/contrib/llvm-project/clang/lib/Frontend/ModuleDependencyCollector.cpp index 939e611e5489..e2883f1e027e 100644 --- a/contrib/llvm-project/clang/lib/Frontend/ModuleDependencyCollector.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/ModuleDependencyCollector.cpp @@ -55,7 +55,8 @@ struct ModuleDependencyPPCallbacks : public PPCallbacks { StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, - StringRef RelativePath, const Module *Imported, + StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override { if (!File) return; @@ -104,7 +105,7 @@ static bool isCaseSensitivePath(StringRef Path) { // already expects when sensitivity isn't setup. for (auto &C : Path) UpperDest.push_back(toUppercase(C)); - if (!llvm::sys::fs::real_path(UpperDest, RealDest) && Path.equals(RealDest)) + if (!llvm::sys::fs::real_path(UpperDest, RealDest) && Path == RealDest) return false; return true; } diff --git a/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp b/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp index 737877329c9c..651c55aeed54 100644 --- a/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp @@ -20,6 +20,9 @@ using namespace clang; namespace clang { +class NamespaceDecl; +class TranslationUnitDecl; + MultiplexASTDeserializationListener::MultiplexASTDeserializationListener( const std::vector<ASTDeserializationListener*>& L) : Listeners(L) { @@ -32,7 +35,7 @@ void MultiplexASTDeserializationListener::ReaderInitialized( } void MultiplexASTDeserializationListener::IdentifierRead( - serialization::IdentID ID, IdentifierInfo *II) { + serialization::IdentifierID ID, IdentifierInfo *II) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->IdentifierRead(ID, II); } @@ -49,8 +52,8 @@ void MultiplexASTDeserializationListener::TypeRead( Listeners[i]->TypeRead(Idx, T); } -void MultiplexASTDeserializationListener::DeclRead( - serialization::DeclID ID, const Decl *D) { +void MultiplexASTDeserializationListener::DeclRead(GlobalDeclID ID, + const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclRead(ID, D); } @@ -115,6 +118,11 @@ public: void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) override; + void EnteringModulePurview() override; + void AddedManglingNumber(const Decl *D, unsigned) override; + void AddedStaticLocalNumbers(const Decl *D, unsigned) override; + void AddedAnonymousNamespace(const TranslationUnitDecl *, + NamespaceDecl *AnonNamespace) override; private: std::vector<ASTMutationListener*> Listeners; @@ -238,6 +246,27 @@ void MultiplexASTMutationListener::AddedAttributeToRecord( L->AddedAttributeToRecord(Attr, Record); } +void MultiplexASTMutationListener::EnteringModulePurview() { + for (auto *L : Listeners) + L->EnteringModulePurview(); +} + +void MultiplexASTMutationListener::AddedManglingNumber(const Decl *D, + unsigned Number) { + for (auto *L : Listeners) + L->AddedManglingNumber(D, Number); +} +void MultiplexASTMutationListener::AddedStaticLocalNumbers(const Decl *D, + unsigned Number) { + for (auto *L : Listeners) + L->AddedStaticLocalNumbers(D, Number); +} +void MultiplexASTMutationListener::AddedAnonymousNamespace( + const TranslationUnitDecl *TU, NamespaceDecl *AnonNamespace) { + for (auto *L : Listeners) + L->AddedAnonymousNamespace(TU, AnonNamespace); +} + } // end namespace clang MultiplexConsumer::MultiplexConsumer( @@ -328,7 +357,7 @@ void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { Consumer->CompleteTentativeDefinition(D); } -void MultiplexConsumer::CompleteExternalDeclaration(VarDecl *D) { +void MultiplexConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) { for (auto &Consumer : Consumers) Consumer->CompleteExternalDeclaration(D); } diff --git a/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp b/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp index 62373b23b82e..cab5838fceb2 100644 --- a/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -28,6 +28,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/VirtualFileSystem.h" @@ -98,7 +99,8 @@ public: StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, - StringRef RelativePath, const Module *Imported, + StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override { // File is std::nullopt if it wasn't found. // (We have some false negatives if PP recovered e.g. <foo> -> "foo") @@ -289,8 +291,7 @@ private: class PrecompilePreambleConsumer : public PCHGenerator { public: - PrecompilePreambleConsumer(PrecompilePreambleAction &Action, - const Preprocessor &PP, + PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer) diff --git a/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 7f5f66906823..0592423c12ec 100644 --- a/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "clang/Frontend/Utils.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Frontend/PreprocessorOutputOptions.h" +#include "clang/Frontend/Utils.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Pragma.h" @@ -93,6 +93,7 @@ private: bool DisableLineMarkers; bool DumpDefines; bool DumpIncludeDirectives; + bool DumpEmbedDirectives; bool UseLineDirectives; bool IsFirstFileEntered; bool MinimizeWhitespace; @@ -100,6 +101,7 @@ private: bool KeepSystemIncludes; raw_ostream *OrigOS; std::unique_ptr<llvm::raw_null_ostream> NullOS; + unsigned NumToksToSkip; Token PrevTok; Token PrevPrevTok; @@ -107,14 +109,16 @@ private: public: PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream *os, bool lineMarkers, bool defines, bool DumpIncludeDirectives, - bool UseLineDirectives, bool MinimizeWhitespace, - bool DirectivesOnly, bool KeepSystemIncludes) + bool DumpEmbedDirectives, bool UseLineDirectives, + bool MinimizeWhitespace, bool DirectivesOnly, + bool KeepSystemIncludes) : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers), DumpDefines(defines), DumpIncludeDirectives(DumpIncludeDirectives), + DumpEmbedDirectives(DumpEmbedDirectives), UseLineDirectives(UseLineDirectives), MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly), - KeepSystemIncludes(KeepSystemIncludes), OrigOS(os) { + KeepSystemIncludes(KeepSystemIncludes), OrigOS(os), NumToksToSkip(0) { CurLine = 0; CurFilename += "<uninit>"; EmittedTokensOnThisLine = false; @@ -129,6 +133,10 @@ public: PrevPrevTok.startToken(); } + /// Returns true if #embed directives should be expanded into a comma- + /// delimited list of integer constants or not. + bool expandEmbedContents() const { return !DumpEmbedDirectives; } + bool isMinimizeWhitespace() const { return MinimizeWhitespace; } void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } @@ -149,11 +157,15 @@ public: void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) override; + void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled, + OptionalFileEntryRef File, + const LexEmbedParametersResult &Params) override; void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, - StringRef RelativePath, const Module *Imported, + StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override; void Ident(SourceLocation Loc, StringRef str) override; void PragmaMessage(SourceLocation Loc, StringRef Namespace, @@ -231,6 +243,9 @@ public: void BeginModule(const Module *M); void EndModule(const Module *M); + + unsigned GetNumToksToSkip() const { return NumToksToSkip; } + void ResetSkipToks() { NumToksToSkip = 0; } }; } // end anonymous namespace @@ -398,11 +413,79 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, } } +void PrintPPOutputPPCallbacks::EmbedDirective( + SourceLocation HashLoc, StringRef FileName, bool IsAngled, + OptionalFileEntryRef File, const LexEmbedParametersResult &Params) { + if (!DumpEmbedDirectives) + return; + + // The EmbedDirective() callback is called before we produce the annotation + // token stream for the directive. We skip printing the annotation tokens + // within PrintPreprocessedTokens(), but we also need to skip the prefix, + // suffix, and if_empty tokens as those are inserted directly into the token + // stream and would otherwise be printed immediately after printing the + // #embed directive. + // + // FIXME: counting tokens to skip is a kludge but we have no way to know + // which tokens were inserted as part of the embed and which ones were + // explicitly written by the user. + MoveToLine(HashLoc, /*RequireStartOfLine=*/true); + *OS << "#embed " << (IsAngled ? '<' : '"') << FileName + << (IsAngled ? '>' : '"'); + + auto PrintToks = [&](llvm::ArrayRef<Token> Toks) { + SmallString<128> SpellingBuffer; + for (const Token &T : Toks) { + if (T.hasLeadingSpace()) + *OS << " "; + *OS << PP.getSpelling(T, SpellingBuffer); + } + }; + bool SkipAnnotToks = true; + if (Params.MaybeIfEmptyParam) { + *OS << " if_empty("; + PrintToks(Params.MaybeIfEmptyParam->Tokens); + *OS << ")"; + // If the file is empty, we can skip those tokens. If the file is not + // empty, we skip the annotation tokens. + if (File && !File->getSize()) { + NumToksToSkip += Params.MaybeIfEmptyParam->Tokens.size(); + SkipAnnotToks = false; + } + } + + if (Params.MaybeLimitParam) { + *OS << " limit(" << Params.MaybeLimitParam->Limit << ")"; + } + if (Params.MaybeOffsetParam) { + *OS << " clang::offset(" << Params.MaybeOffsetParam->Offset << ")"; + } + if (Params.MaybePrefixParam) { + *OS << " prefix("; + PrintToks(Params.MaybePrefixParam->Tokens); + *OS << ")"; + NumToksToSkip += Params.MaybePrefixParam->Tokens.size(); + } + if (Params.MaybeSuffixParam) { + *OS << " suffix("; + PrintToks(Params.MaybeSuffixParam->Tokens); + *OS << ")"; + NumToksToSkip += Params.MaybeSuffixParam->Tokens.size(); + } + + // We may need to skip the annotation token. + if (SkipAnnotToks) + NumToksToSkip++; + + *OS << " /* clang -E -dE */"; + setEmittedDirectiveOnThisLine(); +} + void PrintPPOutputPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, - StringRef SearchPath, StringRef RelativePath, const Module *Imported, - SrcMgr::CharacteristicKind FileType) { + StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) { // In -dI mode, dump #include directives prior to dumping their content or // interpretation. Similar for -fkeep-system-includes. if (DumpIncludeDirectives || (KeepSystemIncludes && isSystem(FileType))) { @@ -418,14 +501,14 @@ void PrintPPOutputPPCallbacks::InclusionDirective( } // When preprocessing, turn implicit imports into module import pragmas. - if (Imported) { + if (ModuleImported) { switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { case tok::pp_include: case tok::pp_import: case tok::pp_include_next: MoveToLine(HashLoc, /*RequireStartOfLine=*/true); *OS << "#pragma clang module import " - << Imported->getFullModuleName(true) + << SuggestedModule->getFullModuleName(true) << " /* clang -E: implicit import for " << "#" << PP.getSpelling(IncludeTok) << " " << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"') @@ -677,7 +760,7 @@ void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(const Token &Tok, if (Tok.is(tok::eof) || (Tok.isAnnotation() && !Tok.is(tok::annot_header_unit) && !Tok.is(tok::annot_module_begin) && !Tok.is(tok::annot_module_end) && - !Tok.is(tok::annot_repl_input_end))) + !Tok.is(tok::annot_repl_input_end) && !Tok.is(tok::annot_embed))) return; // EmittedDirectiveOnThisLine takes priority over RequireSameLine. @@ -877,6 +960,27 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, std::string Name = M->getFullModuleName(); Callbacks->OS->write(Name.data(), Name.size()); Callbacks->HandleNewlinesInToken(Name.data(), Name.size()); + } else if (Tok.is(tok::annot_embed)) { + // Manually explode the binary data out to a stream of comma-delimited + // integer values. If the user passed -dE, that is handled by the + // EmbedDirective() callback. We should only get here if the user did not + // pass -dE. + assert(Callbacks->expandEmbedContents() && + "did not expect an embed annotation"); + auto *Data = + reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue()); + + // Loop over the contents and print them as a comma-delimited list of + // values. + bool PrintComma = false; + for (auto Iter = Data->BinaryData.begin(), End = Data->BinaryData.end(); + Iter != End; ++Iter) { + if (PrintComma) + *Callbacks->OS << ", "; + *Callbacks->OS << static_cast<unsigned>(*Iter); + PrintComma = true; + } + IsStartOfLine = true; } else if (Tok.isAnnotation()) { // Ignore annotation tokens created by pragmas - the pragmas themselves // will be reproduced in the preprocessed output. @@ -925,6 +1029,10 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, if (Tok.is(tok::eof)) break; PP.Lex(Tok); + // If lexing that token causes us to need to skip future tokens, do so now. + for (unsigned I = 0, Skip = Callbacks->GetNumToksToSkip(); I < Skip; ++I) + PP.Lex(Tok); + Callbacks->ResetSkipToks(); } } @@ -981,8 +1089,9 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks( PP, OS, !Opts.ShowLineMarkers, Opts.ShowMacros, - Opts.ShowIncludeDirectives, Opts.UseLineDirectives, - Opts.MinimizeWhitespace, Opts.DirectivesOnly, Opts.KeepSystemIncludes); + Opts.ShowIncludeDirectives, Opts.ShowEmbedDirectives, + Opts.UseLineDirectives, Opts.MinimizeWhitespace, Opts.DirectivesOnly, + Opts.KeepSystemIncludes); // Expand macros in pragmas with -fms-extensions. The assumption is that // the majority of pragmas in such a file will be Microsoft pragmas. diff --git a/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp b/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp index b6b37461089e..1462058003b3 100644 --- a/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -75,7 +75,8 @@ private: StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, - StringRef RelativePath, const Module *Imported, + StringRef RelativePath, const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override; void If(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue) override; @@ -189,9 +190,10 @@ void InclusionRewriter::InclusionDirective( StringRef /*FileName*/, bool /*IsAngled*/, CharSourceRange /*FilenameRange*/, OptionalFileEntryRef /*File*/, StringRef /*SearchPath*/, StringRef /*RelativePath*/, - const Module *Imported, SrcMgr::CharacteristicKind FileType) { - if (Imported) { - auto P = ModuleIncludes.insert(std::make_pair(HashLoc, Imported)); + const Module *SuggestedModule, bool ModuleImported, + SrcMgr::CharacteristicKind FileType) { + if (ModuleImported) { + auto P = ModuleIncludes.insert(std::make_pair(HashLoc, SuggestedModule)); (void)P; assert(P.second && "Unexpected revisitation of the same include directive"); } else diff --git a/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 1f40db785981..3849e4040b53 100644 --- a/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -273,10 +273,9 @@ namespace { std::string SStr; llvm::raw_string_ostream S(SStr); New->printPretty(S, nullptr, PrintingPolicy(LangOpts)); - const std::string &Str = S.str(); // If replacement succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { + if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, SStr)) { ReplacedNodes[Old] = New; return; } @@ -465,15 +464,15 @@ namespace { std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, std::string Tag); - std::string SynthesizeBlockFunc(BlockExpr *CE, int i, - StringRef funcName, std::string Tag); - std::string SynthesizeBlockImpl(BlockExpr *CE, - std::string Tag, std::string Desc); - std::string SynthesizeBlockDescriptor(std::string DescTag, - std::string ImplTag, - int i, StringRef funcName, - unsigned hasCopy); + StringRef funcName, + const std::string &Tag); + std::string SynthesizeBlockFunc(BlockExpr *CE, int i, StringRef funcName, + const std::string &Tag); + std::string SynthesizeBlockImpl(BlockExpr *CE, const std::string &Tag, + const std::string &Desc); + std::string SynthesizeBlockDescriptor(const std::string &DescTag, + const std::string &ImplTag, int i, + StringRef funcName, unsigned hasCopy); Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); void SynthesizeBlockLiterals(SourceLocation FunLocStart, StringRef FunName); @@ -592,7 +591,7 @@ namespace { } bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const { - IdentifierInfo* II = &Context->Idents.get("load"); + const IdentifierInfo *II = &Context->Idents.get("load"); Selector LoadSel = Context->Selectors.getSelector(0, &II); return OD->getClassMethod(LoadSel) != nullptr; } @@ -2581,7 +2580,7 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { std::string prettyBufS; llvm::raw_string_ostream prettyBuf(prettyBufS); Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts)); - Preamble += prettyBuf.str(); + Preamble += prettyBufS; Preamble += ","; Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; @@ -4037,7 +4036,7 @@ static bool HasLocalVariableExternalStorage(ValueDecl *VD) { std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, StringRef funcName, - std::string Tag) { + const std::string &Tag) { const FunctionType *AFT = CE->getFunctionType(); QualType RT = AFT->getReturnType(); std::string StructRef = "struct " + Tag; @@ -4131,9 +4130,8 @@ std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, return S; } -std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, - std::string Tag) { +std::string RewriteModernObjC::SynthesizeBlockHelperFuncs( + BlockExpr *CE, int i, StringRef funcName, const std::string &Tag) { std::string StructRef = "struct " + Tag; std::string S = "static void __"; @@ -4175,8 +4173,9 @@ std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, return S; } -std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, - std::string Desc) { +std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, + const std::string &Tag, + const std::string &Desc) { std::string S = "\nstruct " + Tag; std::string Constructor = " " + Tag; @@ -4290,10 +4289,9 @@ std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Ta return S; } -std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, - std::string ImplTag, int i, - StringRef FunName, - unsigned hasCopy) { +std::string RewriteModernObjC::SynthesizeBlockDescriptor( + const std::string &DescTag, const std::string &ImplTag, int i, + StringRef FunName, unsigned hasCopy) { std::string S = "\nstatic struct " + DescTag; S += " {\n size_t reserved;\n"; @@ -4415,7 +4413,7 @@ void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, llvm::raw_string_ostream constructorExprBuf(SStr); GlobalConstructionExp->printPretty(constructorExprBuf, nullptr, PrintingPolicy(LangOpts)); - globalBuf += constructorExprBuf.str(); + globalBuf += SStr; globalBuf += ";\n"; InsertText(FunLocStart, globalBuf); GlobalConstructionExp = nullptr; diff --git a/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index b76728acb907..0887b5a504f0 100644 --- a/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -574,7 +574,7 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, SmallString<256> diagnostic; Info.FormatDiagnostic(diagnostic); getMetaDiags()->Report( - diag::warn_fe_serialized_diag_failure_during_finalisation) + diag::warn_fe_serialized_diag_failure_during_finalization) << diagnostic; return; } diff --git a/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp b/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp index 779dead5d058..a264836a5439 100644 --- a/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp @@ -12,6 +12,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ConvertUTF.h" @@ -41,6 +42,14 @@ static const enum raw_ostream::Colors fatalColor = raw_ostream::RED; static const enum raw_ostream::Colors savedColor = raw_ostream::SAVEDCOLOR; +// Magenta is taken for 'warning'. Red is already 'error' and 'cyan' +// is already taken for 'note'. Green is already used to underline +// source ranges. White and black are bad because of the usual +// terminal backgrounds. Which leaves us only with TWO options. +static constexpr raw_ostream::Colors CommentColor = raw_ostream::YELLOW; +static constexpr raw_ostream::Colors LiteralColor = raw_ostream::GREEN; +static constexpr raw_ostream::Colors KeywordColor = raw_ostream::BLUE; + /// Add highlights to differences in template strings. static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str, bool &Normal, bool Bold) { @@ -136,7 +145,7 @@ printableTextForNextCharacter(StringRef SourceLine, size_t *I, (void)Res; assert(Res == llvm::conversionOK); assert(OriginalBegin < Begin); - assert((Begin - OriginalBegin) == CharSize); + assert(unsigned(Begin - OriginalBegin) == CharSize); (*I) += (Begin - OriginalBegin); @@ -644,10 +653,10 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str, unsigned Columns, return Wrapped; } -TextDiagnostic::TextDiagnostic(raw_ostream &OS, - const LangOptions &LangOpts, - DiagnosticOptions *DiagOpts) - : DiagnosticRenderer(LangOpts, DiagOpts), OS(OS) {} +TextDiagnostic::TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts, + DiagnosticOptions *DiagOpts, + const Preprocessor *PP) + : DiagnosticRenderer(LangOpts, DiagOpts), OS(OS), PP(PP) {} TextDiagnostic::~TextDiagnostic() {} @@ -1112,6 +1121,162 @@ prepareAndFilterRanges(const SmallVectorImpl<CharSourceRange> &Ranges, return LineRanges; } +/// Creates syntax highlighting information in form of StyleRanges. +/// +/// The returned unique ptr has always exactly size +/// (\p EndLineNumber - \p StartLineNumber + 1). Each SmallVector in there +/// corresponds to syntax highlighting information in one line. In each line, +/// the StyleRanges are non-overlapping and sorted from start to end of the +/// line. +static std::unique_ptr<llvm::SmallVector<TextDiagnostic::StyleRange>[]> +highlightLines(StringRef FileData, unsigned StartLineNumber, + unsigned EndLineNumber, const Preprocessor *PP, + const LangOptions &LangOpts, bool ShowColors, FileID FID, + const SourceManager &SM) { + assert(StartLineNumber <= EndLineNumber); + auto SnippetRanges = + std::make_unique<SmallVector<TextDiagnostic::StyleRange>[]>( + EndLineNumber - StartLineNumber + 1); + + if (!PP || !ShowColors) + return SnippetRanges; + + // Might cause emission of another diagnostic. + if (PP->getIdentifierTable().getExternalIdentifierLookup()) + return SnippetRanges; + + auto Buff = llvm::MemoryBuffer::getMemBuffer(FileData); + Lexer L{FID, *Buff, SM, LangOpts}; + L.SetKeepWhitespaceMode(true); + + const char *FirstLineStart = + FileData.data() + + SM.getDecomposedLoc(SM.translateLineCol(FID, StartLineNumber, 1)).second; + if (const char *CheckPoint = PP->getCheckPoint(FID, FirstLineStart)) { + assert(CheckPoint >= Buff->getBufferStart() && + CheckPoint <= Buff->getBufferEnd()); + assert(CheckPoint <= FirstLineStart); + size_t Offset = CheckPoint - Buff->getBufferStart(); + L.seek(Offset, /*IsAtStartOfLine=*/false); + } + + // Classify the given token and append it to the given vector. + auto appendStyle = + [PP, &LangOpts](SmallVector<TextDiagnostic::StyleRange> &Vec, + const Token &T, unsigned Start, unsigned Length) -> void { + if (T.is(tok::raw_identifier)) { + StringRef RawIdent = T.getRawIdentifier(); + // Special case true/false/nullptr/... literals, since they will otherwise + // be treated as keywords. + // FIXME: It would be good to have a programmatic way of getting this + // list. + if (llvm::StringSwitch<bool>(RawIdent) + .Case("true", true) + .Case("false", true) + .Case("nullptr", true) + .Case("__func__", true) + .Case("__objc_yes__", true) + .Case("__objc_no__", true) + .Case("__null", true) + .Case("__FUNCDNAME__", true) + .Case("__FUNCSIG__", true) + .Case("__FUNCTION__", true) + .Case("__FUNCSIG__", true) + .Default(false)) { + Vec.emplace_back(Start, Start + Length, LiteralColor); + } else { + const IdentifierInfo *II = PP->getIdentifierInfo(RawIdent); + assert(II); + if (II->isKeyword(LangOpts)) + Vec.emplace_back(Start, Start + Length, KeywordColor); + } + } else if (tok::isLiteral(T.getKind())) { + Vec.emplace_back(Start, Start + Length, LiteralColor); + } else { + assert(T.is(tok::comment)); + Vec.emplace_back(Start, Start + Length, CommentColor); + } + }; + + bool Stop = false; + while (!Stop) { + Token T; + Stop = L.LexFromRawLexer(T); + if (T.is(tok::unknown)) + continue; + + // We are only interested in identifiers, literals and comments. + if (!T.is(tok::raw_identifier) && !T.is(tok::comment) && + !tok::isLiteral(T.getKind())) + continue; + + bool Invalid = false; + unsigned TokenEndLine = SM.getSpellingLineNumber(T.getEndLoc(), &Invalid); + if (Invalid || TokenEndLine < StartLineNumber) + continue; + + assert(TokenEndLine >= StartLineNumber); + + unsigned TokenStartLine = + SM.getSpellingLineNumber(T.getLocation(), &Invalid); + if (Invalid) + continue; + // If this happens, we're done. + if (TokenStartLine > EndLineNumber) + break; + + unsigned StartCol = + SM.getSpellingColumnNumber(T.getLocation(), &Invalid) - 1; + if (Invalid) + continue; + + // Simple tokens. + if (TokenStartLine == TokenEndLine) { + SmallVector<TextDiagnostic::StyleRange> &LineRanges = + SnippetRanges[TokenStartLine - StartLineNumber]; + appendStyle(LineRanges, T, StartCol, T.getLength()); + continue; + } + assert((TokenEndLine - TokenStartLine) >= 1); + + // For tokens that span multiple lines (think multiline comments), we + // divide them into multiple StyleRanges. + unsigned EndCol = SM.getSpellingColumnNumber(T.getEndLoc(), &Invalid) - 1; + if (Invalid) + continue; + + std::string Spelling = Lexer::getSpelling(T, SM, LangOpts); + + unsigned L = TokenStartLine; + unsigned LineLength = 0; + for (unsigned I = 0; I <= Spelling.size(); ++I) { + // This line is done. + if (I == Spelling.size() || isVerticalWhitespace(Spelling[I])) { + SmallVector<TextDiagnostic::StyleRange> &LineRanges = + SnippetRanges[L - StartLineNumber]; + + if (L >= StartLineNumber) { + if (L == TokenStartLine) // First line + appendStyle(LineRanges, T, StartCol, LineLength); + else if (L == TokenEndLine) // Last line + appendStyle(LineRanges, T, 0, EndCol); + else + appendStyle(LineRanges, T, 0, LineLength); + } + + ++L; + if (L > EndLineNumber) + break; + LineLength = 0; + continue; + } + ++LineLength; + } + } + + return SnippetRanges; +} + /// Emit a code snippet and caret line. /// /// This routine emits a single line's code snippet and caret line.. @@ -1181,6 +1346,12 @@ void TextDiagnostic::emitSnippetAndCaret( OS.indent(MaxLineNoDisplayWidth + 2) << "| "; }; + // Prepare source highlighting information for the lines we're about to + // emit, starting from the first line. + std::unique_ptr<SmallVector<StyleRange>[]> SourceStyles = + highlightLines(BufData, Lines.first, Lines.second, PP, LangOpts, + DiagOpts->ShowColors, FID, SM); + SmallVector<LineRange> LineRanges = prepareAndFilterRanges(Ranges, SM, Lines, FID, LangOpts); @@ -1247,7 +1418,8 @@ void TextDiagnostic::emitSnippetAndCaret( } // Emit what we have computed. - emitSnippet(SourceLine, MaxLineNoDisplayWidth, DisplayLineNo); + emitSnippet(SourceLine, MaxLineNoDisplayWidth, LineNo, DisplayLineNo, + SourceStyles[LineNo - Lines.first]); if (!CaretLine.empty()) { indentForLineNumbers(); @@ -1277,16 +1449,18 @@ void TextDiagnostic::emitSnippetAndCaret( void TextDiagnostic::emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth, - unsigned LineNo) { + unsigned LineNo, unsigned DisplayLineNo, + ArrayRef<StyleRange> Styles) { // Emit line number. if (MaxLineNoDisplayWidth > 0) { - unsigned LineNoDisplayWidth = getNumDisplayWidth(LineNo); + unsigned LineNoDisplayWidth = getNumDisplayWidth(DisplayLineNo); OS.indent(MaxLineNoDisplayWidth - LineNoDisplayWidth + 1) - << LineNo << " | "; + << DisplayLineNo << " | "; } // Print the source line one character at a time. bool PrintReversed = false; + std::optional<llvm::raw_ostream::Colors> CurrentColor; size_t I = 0; while (I < SourceLine.size()) { auto [Str, WasPrintable] = @@ -1298,10 +1472,29 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine, PrintReversed = !PrintReversed; if (PrintReversed) OS.reverseColor(); - else + else { OS.resetColor(); + CurrentColor = std::nullopt; + } + } + + // Apply syntax highlighting information. + const auto *CharStyle = llvm::find_if(Styles, [I](const StyleRange &R) { + return (R.Start < I && R.End >= I); + }); + + if (CharStyle != Styles.end()) { + if (!CurrentColor || + (CurrentColor && *CurrentColor != CharStyle->Color)) { + OS.changeColor(CharStyle->Color, false); + CurrentColor = CharStyle->Color; + } + } else if (CurrentColor) { + OS.resetColor(); + CurrentColor = std::nullopt; } } + OS << Str; } diff --git a/contrib/llvm-project/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/contrib/llvm-project/clang/lib/Frontend/TextDiagnosticPrinter.cpp index 0ff5376098ff..b2fb76253757 100644 --- a/contrib/llvm-project/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -36,7 +36,7 @@ TextDiagnosticPrinter::~TextDiagnosticPrinter() { void TextDiagnosticPrinter::BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) { // Build the TextDiagnostic utility. - TextDiag.reset(new TextDiagnostic(OS, LO, &*DiagOpts)); + TextDiag.reset(new TextDiagnostic(OS, LO, &*DiagOpts, PP)); } void TextDiagnosticPrinter::EndSourceFile() { diff --git a/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index f508408ba706..48330e936171 100644 --- a/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -396,6 +396,12 @@ public: } }; +static std::string DetailedErrorString(const DiagnosticsEngine &Diags) { + if (Diags.getDiagnosticOptions().VerifyPrefixes.empty()) + return "expected"; + return *Diags.getDiagnosticOptions().VerifyPrefixes.begin(); +} + /// ParseDirective - Go through the comment and see if it indicates expected /// diagnostics. If so, then put them in the appropriate directive list. /// @@ -445,10 +451,9 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, // others. // Regex in initial directive token: -re - if (DToken.ends_with("-re")) { + if (DToken.consume_back("-re")) { D.RegexKind = true; KindStr = "regex"; - DToken = DToken.substr(0, DToken.size()-3); } // Type in initial directive token: -{error|warning|note|no-diagnostics} @@ -479,14 +484,14 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, if (NoDiag) { if (Status == VerifyDiagnosticConsumer::HasOtherExpectedDirectives) Diags.Report(Pos, diag::err_verify_invalid_no_diags) - << /*IsExpectedNoDiagnostics=*/true; + << DetailedErrorString(Diags) << /*IsExpectedNoDiagnostics=*/true; else Status = VerifyDiagnosticConsumer::HasExpectedNoDiagnostics; continue; } if (Status == VerifyDiagnosticConsumer::HasExpectedNoDiagnostics) { Diags.Report(Pos, diag::err_verify_invalid_no_diags) - << /*IsExpectedNoDiagnostics=*/false; + << DetailedErrorString(Diags) << /*IsExpectedNoDiagnostics=*/false; continue; } Status = VerifyDiagnosticConsumer::HasOtherExpectedDirectives; @@ -1105,7 +1110,8 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() { // Produce an error if no expected-* directives could be found in the // source file(s) processed. if (Status == HasNoDirectives) { - Diags.Report(diag::err_verify_no_directives).setForceEmit(); + Diags.Report(diag::err_verify_no_directives).setForceEmit() + << DetailedErrorString(Diags); ++NumErrors; Status = HasNoDirectivesReported; } |