diff options
| author | Mingming Liu <mingmingl@google.com> | 2025-09-10 15:25:31 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-10 15:25:31 -0700 |
| commit | 1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch) | |
| tree | 57f4b1f313c8cf74eed8819870f39c36ea263c68 /clang/lib/Frontend | |
| parent | 898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff) | |
| parent | b8cefcb601ddaa18482555c4ff363c01a270c2fe (diff) | |
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'clang/lib/Frontend')
| -rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 218 | ||||
| -rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 48 | ||||
| -rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 40 | ||||
| -rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 101 | ||||
| -rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Frontend/LayoutOverrideSource.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp | 61 | ||||
| -rw-r--r-- | clang/lib/Frontend/Rewrite/RewriteObjC.cpp | 5 |
8 files changed, 247 insertions, 233 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 9f99edadbb70..0a23e0b08ad7 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -57,6 +57,8 @@ #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/Timer.h" #include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Support/VirtualOutputBackends.h" +#include "llvm/Support/VirtualOutputError.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" #include <optional> @@ -522,6 +524,10 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { collectVFSEntries(*this, ModuleDepCollector); } + // Modules need an output manager. + if (!hasOutputManager()) + createOutputManager(); + for (auto &Listener : DependencyCollectors) Listener->attachToPreprocessor(*PP); @@ -547,10 +553,25 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { PP->setDependencyDirectivesGetter(*GetDependencyDirectives); } +void CompilerInstance::normalizeModuleCachePath( + FileManager &FileMgr, StringRef Path, + SmallVectorImpl<char> &NormalizedPath) { + NormalizedPath.assign(Path.begin(), Path.end()); + FileMgr.makeAbsolutePath(NormalizedPath); + llvm::sys::path::remove_dots(NormalizedPath); +} + std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) { + assert(FileMgr && "Specific module cache path requires a FileManager"); + + if (getHeaderSearchOpts().ModuleCachePath.empty()) + return ""; + // Set up the module path, including the hash for the module-creation options. - SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath); - if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) + SmallString<256> SpecificModuleCache; + normalizeModuleCachePath(*FileMgr, getHeaderSearchOpts().ModuleCachePath, + SpecificModuleCache); + if (!getHeaderSearchOpts().DisableModuleHash) llvm::sys::path::append(SpecificModuleCache, ModuleHash); return std::string(SpecificModuleCache); } @@ -778,32 +799,23 @@ void CompilerInstance::createSema(TranslationUnitKind TUKind, void CompilerInstance::clearOutputFiles(bool EraseFiles) { // The ASTConsumer can own streams that write to the output files. assert(!hasASTConsumer() && "ASTConsumer should be reset"); - // Ignore errors that occur when trying to discard the temp file. - for (OutputFile &OF : OutputFiles) { - if (EraseFiles) { - if (OF.File) - consumeError(OF.File->discard()); - if (!OF.Filename.empty()) - llvm::sys::fs::remove(OF.Filename); - continue; - } - - if (!OF.File) - continue; - - if (OF.File->TmpName.empty()) { - consumeError(OF.File->discard()); - continue; - } - - llvm::Error E = OF.File->keep(OF.Filename); - if (!E) - continue; - - getDiagnostics().Report(diag::err_unable_to_rename_temp) - << OF.File->TmpName << OF.Filename << std::move(E); - - llvm::sys::fs::remove(OF.File->TmpName); + if (!EraseFiles) { + for (auto &O : OutputFiles) + llvm::handleAllErrors( + O.keep(), + [&](const llvm::vfs::TempFileOutputError &E) { + getDiagnostics().Report(diag::err_unable_to_rename_temp) + << E.getTempPath() << E.getOutputPath() + << E.convertToErrorCode().message(); + }, + [&](const llvm::vfs::OutputError &E) { + getDiagnostics().Report(diag::err_fe_unable_to_open_output) + << E.getOutputPath() << E.convertToErrorCode().message(); + }, + [&](const llvm::ErrorInfoBase &EIB) { // Handle any remaining error + getDiagnostics().Report(diag::err_fe_unable_to_open_output) + << O.getPath() << EIB.message(); + }); } OutputFiles.clear(); if (DeleteBuiltModules) { @@ -837,6 +849,30 @@ std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { return std::make_unique<llvm::raw_null_ostream>(); } +// Output Manager + +void CompilerInstance::setOutputManager( + IntrusiveRefCntPtr<llvm::vfs::OutputBackend> NewOutputs) { + assert(!OutputMgr && "Already has an output manager"); + OutputMgr = std::move(NewOutputs); +} + +void CompilerInstance::createOutputManager() { + assert(!OutputMgr && "Already has an output manager"); + OutputMgr = llvm::makeIntrusiveRefCnt<llvm::vfs::OnDiskOutputBackend>(); +} + +llvm::vfs::OutputBackend &CompilerInstance::getOutputManager() { + assert(OutputMgr); + return *OutputMgr; +} + +llvm::vfs::OutputBackend &CompilerInstance::getOrCreateOutputManager() { + if (!hasOutputManager()) + createOutputManager(); + return getOutputManager(); +} + std::unique_ptr<raw_pwrite_stream> CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, bool UseTemporary, @@ -871,98 +907,20 @@ CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary, OutputPath = *AbsPath; } - std::unique_ptr<llvm::raw_fd_ostream> OS; - std::optional<StringRef> OSFile; - - if (UseTemporary) { - if (OutputPath == "-") - UseTemporary = false; - else { - llvm::sys::fs::file_status Status; - llvm::sys::fs::status(OutputPath, Status); - if (llvm::sys::fs::exists(Status)) { - // Fail early if we can't write to the final destination. - if (!llvm::sys::fs::can_write(OutputPath)) - return llvm::errorCodeToError( - make_error_code(llvm::errc::operation_not_permitted)); - - // Don't use a temporary if the output is a special file. This handles - // things like '-o /dev/null' - if (!llvm::sys::fs::is_regular_file(Status)) - UseTemporary = false; - } - } - } - - std::optional<llvm::sys::fs::TempFile> Temp; - if (UseTemporary) { - // Create a temporary file. - // Insert -%%%%%%%% before the extension (if any), and because some tools - // (noticeable, clang's own GlobalModuleIndex.cpp) glob for build - // artifacts, also append .tmp. - StringRef OutputExtension = llvm::sys::path::extension(OutputPath); - SmallString<128> TempPath = - StringRef(OutputPath).drop_back(OutputExtension.size()); - TempPath += "-%%%%%%%%"; - TempPath += OutputExtension; - TempPath += ".tmp"; - llvm::sys::fs::OpenFlags BinaryFlags = - Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text; - Expected<llvm::sys::fs::TempFile> ExpectedFile = - llvm::sys::fs::TempFile::create( - TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write, - BinaryFlags); - - llvm::Error E = handleErrors( - ExpectedFile.takeError(), [&](const llvm::ECError &E) -> llvm::Error { - std::error_code EC = E.convertToErrorCode(); - if (CreateMissingDirectories && - EC == llvm::errc::no_such_file_or_directory) { - StringRef Parent = llvm::sys::path::parent_path(OutputPath); - EC = llvm::sys::fs::create_directories(Parent); - if (!EC) { - ExpectedFile = llvm::sys::fs::TempFile::create( - TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write, - BinaryFlags); - if (!ExpectedFile) - return llvm::errorCodeToError( - llvm::errc::no_such_file_or_directory); - } - } - return llvm::errorCodeToError(EC); - }); - - if (E) { - consumeError(std::move(E)); - } else { - Temp = std::move(ExpectedFile.get()); - OS.reset(new llvm::raw_fd_ostream(Temp->FD, /*shouldClose=*/false)); - OSFile = Temp->TmpName; - } - // If we failed to create the temporary, fallback to writing to the file - // directly. This handles the corner case where we cannot write to the - // directory, but can write to the file. - } - - if (!OS) { - OSFile = OutputPath; - std::error_code EC; - OS.reset(new llvm::raw_fd_ostream( - *OSFile, EC, - (Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_TextWithCRLF))); - if (EC) - return llvm::errorCodeToError(EC); - } + using namespace llvm::vfs; + Expected<OutputFile> O = getOrCreateOutputManager().createFile( + OutputPath, + OutputConfig() + .setTextWithCRLF(!Binary) + .setDiscardOnSignal(RemoveFileOnSignal) + .setAtomicWrite(UseTemporary) + .setImplyCreateDirectories(UseTemporary && CreateMissingDirectories)); + if (!O) + return O.takeError(); - // Add the output file -- but don't try to remove "-", since this means we are - // using stdin. - OutputFiles.emplace_back(((OutputPath != "-") ? OutputPath : "").str(), - std::move(Temp)); - - if (!Binary || OS->supportsSeeking()) - return std::move(OS); - - return std::make_unique<llvm::buffer_unique_ostream>(std::move(OS)); + O->discardOnDestroy([](llvm::Error E) { consumeError(std::move(E)); }); + OutputFiles.push_back(std::move(*O)); + return OutputFiles.back().createProxy(); } // Initialization Utilities @@ -1473,16 +1431,18 @@ static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName) { - auto Instance = ImportingInstance.cloneForModuleCompile(ModuleNameLoc, Module, - ModuleFileName); - - if (!ImportingInstance.compileModule(ModuleNameLoc, - Module->getTopLevelModuleName(), - ModuleFileName, *Instance)) { - ImportingInstance.getDiagnostics().Report(ModuleNameLoc, - diag::err_module_not_built) - << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); - return false; + { + auto Instance = ImportingInstance.cloneForModuleCompile( + ModuleNameLoc, Module, ModuleFileName); + + if (!ImportingInstance.compileModule(ModuleNameLoc, + Module->getTopLevelModuleName(), + ModuleFileName, *Instance)) { + ImportingInstance.getDiagnostics().Report(ModuleNameLoc, + diag::err_module_not_built) + << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); + return false; + } } // The module is built successfully, we can update its timestamp now. diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index da96352e1d82..931766db4b0c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -623,6 +623,9 @@ static bool FixupInvocation(CompilerInvocation &Invocation, LangOpts.RawStringLiterals = true; } + LangOpts.NamedLoops = + Args.hasFlag(OPT_fnamed_loops, OPT_fno_named_loops, LangOpts.C2y); + // 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" @@ -640,6 +643,10 @@ static bool FixupInvocation(CompilerInvocation &Invocation, Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fdx-rootsignature-version" << GetInputKindName(IK); + if (Args.hasArg(OPT_fdx_rootsignature_define) && !LangOpts.HLSL) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << "-fdx-rootsignature-define" << GetInputKindName(IK); + if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP) Diags.Report(diag::warn_ignored_hip_only_option) << Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args); @@ -1315,15 +1322,6 @@ static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions) Diags->Report(diag::err_analyzer_config_invalid_input) << "track-conditions-debug" << "'track-conditions' to also be enabled"; - - if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir)) - Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir" - << "a filename"; - - if (!AnOpts.ModelPath.empty() && - !llvm::sys::fs::is_directory(AnOpts.ModelPath)) - Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path" - << "a filename"; } /// Generate a remark argument. This is an inverse of `ParseOptimizationRemark`. @@ -3317,9 +3315,6 @@ static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, if (Opts.UseLibcxx) GenerateArg(Consumer, OPT_stdlib_EQ, "libc++"); - if (!Opts.ModuleCachePath.empty()) - GenerateArg(Consumer, OPT_fmodules_cache_path, Opts.ModuleCachePath); - for (const auto &File : Opts.PrebuiltModuleFiles) GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second); @@ -3422,8 +3417,7 @@ static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, } static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, - DiagnosticsEngine &Diags, - const std::string &WorkingDir) { + DiagnosticsEngine &Diags) { unsigned NumErrorsBefore = Diags.getNumErrors(); HeaderSearchOptions *HeaderSearchOpts = &Opts; @@ -3436,17 +3430,6 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ)) Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0); - // Canonicalize -fmodules-cache-path before storing it. - SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path)); - if (!(P.empty() || llvm::sys::path::is_absolute(P))) { - if (WorkingDir.empty()) - llvm::sys::fs::make_absolute(P); - else - llvm::sys::fs::make_absolute(WorkingDir, P); - } - llvm::sys::path::remove_dots(P); - Opts.ModuleCachePath = std::string(P); - // Only the -fmodule-file=<name>=<file> form. for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); @@ -3921,9 +3904,6 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_offload_targets_EQ, Targets); } - if (!Opts.OMPHostIRFile.empty()) - GenerateArg(Consumer, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile); - if (Opts.OpenMPCUDAMode) GenerateArg(Consumer, OPT_fopenmp_cuda_mode); @@ -4390,15 +4370,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, } } - // Get OpenMP host file path if any and report if a non existent file is - // found - if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) { - Opts.OMPHostIRFile = A->getValue(); - if (!llvm::sys::fs::exists(Opts.OMPHostIRFile)) - Diags.Report(diag::err_drv_omp_host_ir_file_not_found) - << Opts.OMPHostIRFile; - } - // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()) && @@ -5035,8 +5006,7 @@ bool CompilerInvocation::CreateFromArgsImpl( InputKind DashX = Res.getFrontendOpts().DashX; ParseTargetArgs(Res.getTargetOpts(), Args, Diags); llvm::Triple T(Res.getTargetOpts().Triple); - ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags, - Res.getFileSystemOpts().WorkingDir); + ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags); if (Res.getFrontendOpts().GenReducedBMI || Res.getFrontendOpts().ProgramAction == frontend::GenerateReducedModuleInterface || diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index a7d6a068fe2d..6b1fcac75ac2 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -623,7 +623,7 @@ static std::error_code collectModuleHeaderIncludes( llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative); llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); - SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers; + SmallVector<std::pair<std::string, std::string>, 8> HeaderPaths; for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End; Dir != End && !EC; Dir.increment(EC)) { // Check whether this entry has an extension typically associated with @@ -633,17 +633,6 @@ static std::error_code collectModuleHeaderIncludes( .Default(false)) continue; - auto Header = FileMgr.getOptionalFileRef(Dir->path()); - // FIXME: This shouldn't happen unless there is a file system race. Is - // that worth diagnosing? - if (!Header) - continue; - - // If this header is marked 'unavailable' in this module, don't include - // it. - if (ModMap.isHeaderUnavailableInModule(*Header, Module)) - continue; - // Compute the relative path from the directory to this file. SmallVector<StringRef, 16> Components; auto PathIt = llvm::sys::path::rbegin(Dir->path()); @@ -655,20 +644,33 @@ static std::error_code collectModuleHeaderIncludes( ++It) llvm::sys::path::append(RelativeHeader, *It); - std::string RelName = RelativeHeader.c_str(); - Headers.push_back(std::make_pair(RelName, *Header)); + HeaderPaths.push_back( + std::make_pair(Dir->path().str(), RelativeHeader.c_str())); } if (EC) return EC; // Sort header paths and make the header inclusion order deterministic - // across different OSs and filesystems. - llvm::sort(Headers, llvm::less_first()); - for (auto &H : Headers) { + // across different OSs and filesystems. As the header search table + // serialization order depends on the file reference UID, we need to create + // file references in deterministic order too. + llvm::sort(HeaderPaths, llvm::less_first()); + for (auto &[Path, RelPath] : HeaderPaths) { + auto Header = FileMgr.getOptionalFileRef(Path); + // FIXME: This shouldn't happen unless there is a file system race. Is + // that worth diagnosing? + if (!Header) + continue; + + // If this header is marked 'unavailable' in this module, don't include + // it. + if (ModMap.isHeaderUnavailableInModule(*Header, Module)) + continue; + // Include this header as part of the umbrella directory. - Module->addTopHeader(H.second); - addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC); + Module->addTopHeader(*Header); + addHeaderInclude(RelPath, Includes, LangOpts, Module->IsExternC); } } diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 685a9bbf2cde..7424958d4661 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -22,6 +22,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "clang/Parse/ParseHLSLRootSignature.h" #include "clang/Sema/TemplateInstCallback.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" @@ -795,9 +796,10 @@ namespace { /// Indicates that the AST file contains particular input file. /// /// \returns true to continue receiving the next input file, false to stop. - bool visitInputFile(StringRef FilenameAsRequested, StringRef Filename, - bool isSystem, bool isOverridden, - bool isExplicitModule) override { + bool visitInputFileAsRequested(StringRef FilenameAsRequested, + StringRef Filename, bool isSystem, + bool isOverridden, + bool isExplicitModule) override { Out.indent(2) << "Input file: " << FilenameAsRequested; @@ -1241,3 +1243,96 @@ void GetDependenciesByModuleNameAction::ExecuteAction() { PPCallbacks *CB = PP.getPPCallbacks(); CB->moduleImport(SourceLocation(), Path, ModResult); } + +//===----------------------------------------------------------------------===// +// HLSL Specific Actions +//===----------------------------------------------------------------------===// + +class InjectRootSignatureCallback : public PPCallbacks { +private: + Sema &Actions; + StringRef RootSigName; + llvm::dxbc::RootSignatureVersion Version; + + std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) { + for (Token Tok : Tokens) + if (!tok::isStringLiteral(Tok.getKind())) + return std::nullopt; + + ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens); + if (StringResult.isInvalid()) + return std::nullopt; + + if (auto Signature = dyn_cast<StringLiteral>(StringResult.get())) + return Signature; + + return std::nullopt; + } + +public: + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { + if (RootSigName != MacroNameTok.getIdentifierInfo()->getName()) + return; + + const MacroInfo *MI = MD->getMacroInfo(); + auto Signature = processStringLiteral(MI->tokens()); + if (!Signature.has_value()) { + Actions.getDiagnostics().Report(MI->getDefinitionLoc(), + diag::err_expected_string_literal) + << /*in attributes...*/ 4 << "RootSignature"; + return; + } + + IdentifierInfo *DeclIdent = + hlsl::ParseHLSLRootSignature(Actions, Version, *Signature); + Actions.HLSL().SetRootSignatureOverride(DeclIdent); + } + + InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName, + llvm::dxbc::RootSignatureVersion Version) + : PPCallbacks(), Actions(Actions), RootSigName(RootSigName), + Version(Version) {} +}; + +void HLSLFrontendAction::ExecuteAction() { + // Pre-requisites to invoke + CompilerInstance &CI = getCompilerInstance(); + if (!CI.hasASTContext() || !CI.hasPreprocessor()) + return WrapperFrontendAction::ExecuteAction(); + + // InjectRootSignatureCallback requires access to invoke Sema to lookup/ + // register a root signature declaration. The wrapped action is required to + // account for this by only creating a Sema if one doesn't already exist + // (like we have done, and, ASTFrontendAction::ExecuteAction) + if (!CI.hasSema()) + CI.createSema(getTranslationUnitKind(), + /*CodeCompleteConsumer=*/nullptr); + Sema &S = CI.getSema(); + + auto &TargetInfo = CI.getASTContext().getTargetInfo(); + bool IsRootSignatureTarget = + TargetInfo.getTriple().getEnvironment() == llvm::Triple::RootSignature; + StringRef HLSLEntry = TargetInfo.getTargetOpts().HLSLEntry; + + // Register HLSL specific callbacks + auto LangOpts = CI.getLangOpts(); + StringRef RootSigName = + IsRootSignatureTarget ? HLSLEntry : LangOpts.HLSLRootSigOverride; + + auto MacroCallback = std::make_unique<InjectRootSignatureCallback>( + S, RootSigName, LangOpts.HLSLRootSigVer); + + Preprocessor &PP = CI.getPreprocessor(); + PP.addPPCallbacks(std::move(MacroCallback)); + + // If we are targeting a root signature, invoke custom handling + if (IsRootSignatureTarget) + return hlsl::HandleRootSignatureTarget(S, HLSLEntry); + else // otherwise, invoke as normal + return WrapperFrontendAction::ExecuteAction(); +} + +HLSLFrontendAction::HLSLFrontendAction( + std::unique_ptr<FrontendAction> WrappedAction) + : WrapperFrontendAction(std::move(WrappedAction)) {} diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 4865c0b88904..e65c8b4f6fac 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1519,9 +1519,11 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (TI.getTriple().isOSBinFormatELF()) Builder.defineMacro("__ELF__"); - if (LangOpts.Sanitize.has(SanitizerKind::Address)) + if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Address | + SanitizerKind::KernelAddress)) Builder.defineMacro("__SANITIZE_ADDRESS__"); - if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) + if (LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)) Builder.defineMacro("__SANITIZE_HWADDRESS__"); if (LangOpts.Sanitize.has(SanitizerKind::Thread)) Builder.defineMacro("__SANITIZE_THREAD__"); diff --git a/clang/lib/Frontend/LayoutOverrideSource.cpp b/clang/lib/Frontend/LayoutOverrideSource.cpp index a1866ec09c9d..0a60e00e5cb1 100644 --- a/clang/lib/Frontend/LayoutOverrideSource.cpp +++ b/clang/lib/Frontend/LayoutOverrideSource.cpp @@ -8,6 +8,7 @@ #include "clang/Frontend/LayoutOverrideSource.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" #include "llvm/Support/raw_ostream.h" #include <fstream> diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 2b55820b3880..42f2d6591b21 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -852,7 +852,7 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); if (!IvarT->getAs<TypedefType>() && IvarT->isRecordType()) { - RecordDecl *RD = IvarT->castAs<RecordType>()->getOriginalDecl(); + RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getOriginalDecl(); RD = RD->getDefinition(); if (RD && !RD->getDeclName().getAsIdentifierInfo()) { // decltype(((Foo_IMPL*)0)->bar) * @@ -3638,8 +3638,7 @@ bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, return RewriteObjCFieldDeclType(ElemTy, Result); } else if (Type->isRecordType()) { - RecordDecl *RD = - Type->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf(); + auto *RD = Type->castAsRecordDecl(); if (RD->isCompleteDefinition()) { if (RD->isStruct()) Result += "\n\tstruct "; @@ -3660,28 +3659,26 @@ bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, Result += "\t} "; return true; } - } - else if (Type->isEnumeralType()) { - EnumDecl *ED = - Type->castAs<EnumType>()->getOriginalDecl()->getDefinitionOrSelf(); - if (ED->isCompleteDefinition()) { - Result += "\n\tenum "; - Result += ED->getName(); - if (GlobalDefinedTags.count(ED)) { - // Enum is globall defined, use it. - Result += " "; - return true; - } - - Result += " {\n"; - for (const auto *EC : ED->enumerators()) { - Result += "\t"; Result += EC->getName(); Result += " = "; - Result += toString(EC->getInitVal(), 10); - Result += ",\n"; - } - Result += "\t} "; + } else if (auto *ED = Type->getAsEnumDecl(); + ED && ED->isCompleteDefinition()) { + Result += "\n\tenum "; + Result += ED->getName(); + if (GlobalDefinedTags.count(ED)) { + // Enum is globall defined, use it. + Result += " "; return true; } + + Result += " {\n"; + for (const auto *EC : ED->enumerators()) { + Result += "\t"; + Result += EC->getName(); + Result += " = "; + Result += toString(EC->getInitVal(), 10); + Result += ",\n"; + } + Result += "\t} "; + return true; } Result += "\t"; @@ -3733,15 +3730,7 @@ void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDec auto *IDecl = dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext()); - TagDecl *TD = nullptr; - if (Type->isRecordType()) { - TD = Type->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf(); - } - else if (Type->isEnumeralType()) { - TD = Type->castAs<EnumType>()->getOriginalDecl()->getDefinitionOrSelf(); - } - - if (TD) { + if (auto *TD = Type->getAsTagDecl()) { if (GlobalDefinedTags.count(TD)) return; @@ -5723,10 +5712,7 @@ void RewriteModernObjC::HandleDeclInMainFile(Decl *D) { } } } else if (VD->getType()->isRecordType()) { - RecordDecl *RD = VD->getType() - ->castAs<RecordType>() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = VD->getType()->castAsRecordDecl(); if (RD->isCompleteDefinition()) RewriteRecordBody(RD); } @@ -7467,7 +7453,8 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); if (!IvarT->getAs<TypedefType>() && IvarT->isRecordType()) { - RecordDecl *RD = IvarT->castAs<RecordType>()->getOriginalDecl(); + RecordDecl *RD = + IvarT->castAsCanonical<RecordType>()->getOriginalDecl(); RD = RD->getDefinition(); if (RD && !RD->getDeclName().getAsIdentifierInfo()) { // decltype(((Foo_IMPL*)0)->bar) * diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 0242fc1f6e82..b9c025de8773 100644 --- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -4835,10 +4835,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { } } } else if (VD->getType()->isRecordType()) { - RecordDecl *RD = VD->getType() - ->castAs<RecordType>() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = VD->getType()->castAsRecordDecl(); if (RD->isCompleteDefinition()) RewriteRecordBody(RD); } |
