llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Maryam Moghadas (maryammo) <details> <summary>Changes</summary> Add -mcsect[=<qualifier>]/-mno-csect and #pragma csect(code|static, "name") for z/OS. Clang emits the CSECT names as zos_csect_code/zos_csect_static module flags; backend support will follow in a separate patch. --- Patch is 22.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/234368.diff 18 Files Affected: - (modified) clang/docs/LanguageExtensions.md (+38) - (modified) clang/include/clang/AST/ASTContext.h (+4) - (modified) clang/include/clang/Basic/CodeGenOptions.h (+3) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4) - (modified) clang/include/clang/Basic/TokenKinds.def (+3) - (modified) clang/include/clang/Options/Options.td (+5) - (modified) clang/include/clang/Parse/Parser.h (+5) - (modified) clang/include/clang/Sema/Sema.h (+4) - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+22) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+25) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+10) - (modified) clang/lib/Parse/ParsePragma.cpp (+110) - (modified) clang/lib/Parse/Parser.cpp (+3) - (modified) clang/lib/Sema/SemaAttr.cpp (+20) - (added) clang/test/CodeGen/SystemZ/zos-csect-option-pragma.c (+29) - (added) clang/test/CodeGen/SystemZ/zos-csect-option.c (+19) - (added) clang/test/CodeGen/SystemZ/zos-csect-pragma-diag.c (+13) - (added) clang/test/CodeGen/SystemZ/zos-csect-pragma.c (+11) ``````````diff diff --git a/clang/docs/LanguageExtensions.md b/clang/docs/LanguageExtensions.md index 3db8d083c40756..e9dc6530a61aec 100644 --- a/clang/docs/LanguageExtensions.md +++ b/clang/docs/LanguageExtensions.md @@ -5650,6 +5650,44 @@ The builtins return 0 if the values are equal, or 1 if they are unequal. Generates a 16-byte compare-and-swap using the CDSG instruction. +#### z/OS CSECT pragma + +Clang supports the `-mcsect`, `-mcsect=<qualifier>`, and `-mno-csect` options, +and the `#pragma csect` directive, to control CSECT (control section) names in +the output object module on z/OS. + +The CSECT name specified by the option has the following syntax: + +`qualifier#basename#suffix` + +- `qualifier` is the `<qualifier>` specified by `-mcsect=<qualifier>`. +- `basename` is the output file name with path information and the right-most + extension information removed. If `qualifier` is empty, the syntax becomes + just `basename#suffix`. +- `suffix` is `C` for the code section and `S` for the static section. + +Specifying `-mcsect=` is equivalent to specifying `-mcsect`. +`-mno-csect` is the default. + +The `#pragma csect` directive, which must appear at file scope, sets the CSECT +name for the code or static section: + +```c +#pragma csect(code, "name") +#pragma csect(static, "name") +``` + +There can be at most one `#pragma csect` directive for each section type +(code or static) per translation unit; duplicates are warned and ignored. + +The code and static section names set by `#pragma csect` must be different; +using the same name for both results in an error. + +`#pragma csect(test, "name")` is accepted and ignored. + +When both `#pragma csect` and the `-mcsect` option are specified, the +`#pragma csect` overrides the names generated by the option. + ## Extensions for Static Analysis Clang supports additional attributes that are useful for documenting program diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 1349637273d1e7..e8cf4a0f3f0ea0 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3978,6 +3978,10 @@ OPT_LIST(V) llvm::StringMap<SectionInfo> SectionInfos; + /// Names set by '#pragma csect(code/static, "name")' on z/OS. + std::string PragmaCsectStatic; + std::string PragmaCsectCode; + /// Return a new OMPTraitInfo object owned by this context. OMPTraitInfo &getNewOMPTraitInfo(); diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index ecd1a63d6de4f3..e77a334445ddb1 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -624,6 +624,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// If threshold option is not specified, it is disabled by default. std::optional<uint64_t> DiagnosticsHotnessThreshold = 0; + /// Specifies the csect name (qualifier & basename) on z/OS. + std::optional<std::string> CsectName; + /// The maximum percentage profiling weights can deviate from the expected /// values in order to be included in misexpect diagnostics. std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 48b166d2a48a05..090bf2bdc78bb7 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1296,6 +1296,10 @@ def note_surrounding_namespace_starts_here : Note< def warn_failed_to_resolve_pragma : Warning< "failed to resolve '#pragma %0' to a declaration">, InGroup<IgnoredPragmas>; +def warn_duplicate_pragma : Warning<"duplicate '#pragma %0' is ignored">, + InGroup<IgnoredPragmas>; +def err_conflicting_pragma : Error< + "external name '%0' in pragma %1 conflicts with another csect name">; def warn_pragma_not_applied : Warning< "#pragma %0 is applicable to symbols with external linkage only; " "not applied to %1">, diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 528825ad68b8dc..5608871d4fb260 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -902,6 +902,9 @@ PRAGMA_ANNOTATION(pragma_attribute) // Annotation for C/C++ #pragma export(ident) PRAGMA_ANNOTATION(pragma_export) +// Annotation for #pragma csect(ident, str lit) +PRAGMA_ANNOTATION(pragma_csect) + // Annotation for the riscv pragma directives - #pragma clang riscv intrinsic ... PRAGMA_ANNOTATION(pragma_riscv) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 09f614b1e8b078..d35912bec0a345 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -5629,6 +5629,11 @@ def march_EQ : Joined<["-"], "march=">, Group<m_Group>, Flags<[TargetSpecific]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"For a list of available architectures for the target use '-mcpu=help'">; def mzos_target_EQ : Joined<["-"], "mzos-target=">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Set the z/OS release of the runtime environment">; +def mcsect_EQ : Joined<["-"], "mcsect=">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Set CSECT names in the output object module">; +def mcsect : Flag<["-"], "mcsect">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, Alias<mcsect_EQ>; +def mno_csect : Flag<["-"], "mno-csect">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Do not set CSECT names in the output object module">; def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Visibility<[ClangOption, FlangOption]>; def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 9a1abd4f3872de..ae18aea25f978f 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -7188,6 +7188,7 @@ class Parser : public CodeCompletionHandler { std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler; std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler; std::unique_ptr<PragmaHandler> ExportHandler; + std::unique_ptr<PragmaHandler> CsectHandler; std::unique_ptr<PragmaHandler> RISCVPragmaHandler; /// Initialize all pragma handlers. @@ -7315,6 +7316,10 @@ class Parser : public CodeCompletionHandler { /// #pragma export ... void HandlePragmaExport(); + /// Handle the annotation token produced for + /// #pragma csect(...) + void HandlePragmaCsect(); + ///@} // diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 711e083e4cedd5..ef061647d93f53 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2391,6 +2391,10 @@ class Sema final : public SemaBase { void ActOnPragmaExport(IdentifierInfo *IdentId, SourceLocation ExportNameLoc, Scope *curScope); + /// ActOnPragmaCsect - called on well-formed '\#pragma csect' + void ActOnPragmaCsect(StringRef SectionKind, SourceLocation SectionLoc, + StringRef SectionName); + /// Only called on function definitions; if there is a pragma in scope /// with the effect of a range-based optnone, consider marking the function /// with attribute optnone. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bf03e10f9fb422..125a83592d05e8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1533,6 +1533,28 @@ void CodeGenModule::Release() { // Multiple modes will be supported here. getModule().addModuleFlag(llvm::Module::Error, "zos_le_char_mode", llvm::MDString::get(VMContext, "ascii")); + + if (!Context.PragmaCsectCode.empty()) { + getModule().addModuleFlag( + llvm::Module::Error, "zos_csect_code", + llvm::MDString::get(VMContext, Context.PragmaCsectCode)); + } else if (getCodeGenOpts().CsectName) { + getModule().addModuleFlag( + llvm::Module::Error, "zos_csect_code", + llvm::MDString::get(VMContext, + StringRef(*(getCodeGenOpts().CsectName) + "C"))); + } + + if (!Context.PragmaCsectStatic.empty()) { + getModule().addModuleFlag( + llvm::Module::Error, "zos_csect_static", + llvm::MDString::get(VMContext, Context.PragmaCsectStatic)); + } else if (getCodeGenOpts().CsectName) { + getModule().addModuleFlag( + llvm::Module::Error, "zos_csect_static", + llvm::MDString::get(VMContext, + StringRef(*(getCodeGenOpts().CsectName) + "S"))); + } } llvm::Triple T = Context.getTargetInfo().getTriple(); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index eb7bd3ad1ad5e2..163fb27c46fb5e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5954,6 +5954,31 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (RawTriple.isOSzOS()) { + if (Args.hasFlag(options::OPT_mcsect_EQ, options::OPT_mno_csect, false)) { + SmallString<256> CsectArg("-mcsect="); + StringRef Qualifier; + if (const Arg *A = Args.getLastArg(options::OPT_mcsect_EQ)) + Qualifier = A->getValue(); + if (!Qualifier.empty()) { + CsectArg += Qualifier; + CsectArg += "#"; + } + + SmallString<64> OutputName; + if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) + OutputName = OutputOpt->getValue(); + else if (Output.isFilename()) + OutputName = Output.getFilename(); + + CsectArg += llvm::sys::path::stem(OutputName); + CsectArg += "#"; + CmdArgs.push_back(Args.MakeArgString(CsectArg)); + } else { + CmdArgs.push_back("-mno-csect"); + } + } + llvm::Reloc::Model RelocationModel; unsigned PICLevel; bool IsPIE; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index c9281c2a6d6b41..34a73f07eaf352 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1828,6 +1828,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, break; } + if (Opts.CsectName) + GenerateArg(Consumer, OPT_mcsect_EQ, Twine(*Opts.CsectName)); + else + GenerateArg(Consumer, OPT_mno_csect); + if (Opts.StaticClosure) GenerateArg(Consumer, OPT_static_libclosure); } @@ -2331,6 +2336,11 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs) Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans); + if (Args.hasFlag(OPT_mcsect_EQ, OPT_mno_csect, false)) { + const Arg *A = Args.getLastArg(OPT_mcsect_EQ); + Opts.CsectName = A->getValue(); + } + Opts.StaticClosure = Args.hasArg(options::OPT_static_libclosure); if (!Opts.HLSLRecordCommandLine.empty()) { diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 04e7bb5a9b7dd9..3c6ecbef98cbd0 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -395,6 +395,12 @@ struct PragmaExportHandler : public PragmaHandler { Token &FirstToken) override; }; +struct PragmaCsectHandler : public PragmaHandler { + PragmaCsectHandler() : PragmaHandler("csect") {} + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, + Token &Tok) override; +}; + struct PragmaRISCVHandler : public PragmaHandler { PragmaRISCVHandler(Sema &Actions) : PragmaHandler("riscv"), Actions(Actions) {} @@ -562,6 +568,8 @@ void Parser::initializePragmaHandlers() { if (getLangOpts().ZOSExt) { ExportHandler = std::make_unique<PragmaExportHandler>(); PP.AddPragmaHandler(ExportHandler.get()); + CsectHandler = std::make_unique<PragmaCsectHandler>(); + PP.AddPragmaHandler(CsectHandler.get()); } if (getTargetInfo().getTriple().isRISCV()) { @@ -702,6 +710,8 @@ void Parser::resetPragmaHandlers() { if (getLangOpts().ZOSExt) { PP.RemovePragmaHandler(ExportHandler.get()); ExportHandler.reset(); + PP.RemovePragmaHandler(CsectHandler.get()); + CsectHandler.reset(); } if (getTargetInfo().getTriple().isRISCV()) { @@ -1464,6 +1474,19 @@ void Parser::HandlePragmaExport() { zOSHandlePragmaHelper(tok::annot_pragma_export); } +void Parser::HandlePragmaCsect() { + assert(Tok.is(tok::annot_pragma_csect)); + StringRef *SectionName = static_cast<StringRef *>(Tok.getAnnotationValue()); + assert(SectionName); + SourceLocation PragmaLoc = Tok.getLocation(); + + ConsumeAnnotationToken(); + + llvm::StringRef SectionKind = Tok.getIdentifierInfo()->getName(); + ConsumeToken(); + Actions.ActOnPragmaCsect(SectionKind, PragmaLoc, *SectionName); +} + static std::string PragmaLoopHintString(Token PragmaName, Token Option) { StringRef Str = PragmaName.getIdentifierInfo()->getName(); std::string ClangLoopStr("clang loop "); @@ -4259,3 +4282,90 @@ void PragmaRISCVHandler::HandlePragma(Preprocessor &PP, else if (II->isStr("andes_vector")) Actions.RISCV().DeclareAndesVectorBuiltins = true; } + +/// Handle #pragma csect. +void PragmaCsectHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducer Introducer, Token &Tok) { + SourceLocation CSectLoc = Tok.getLocation(); + + PP.Lex(Tok); + if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "csect"; + return; + } + + PP.LexUnexpandedToken(Tok); + bool ValidPragma = false; + bool AcceptAndIgnore = false; + switch (Tok.getKind()) { + case tok::kw_static: + ValidPragma = true; + break; + case tok::identifier: { + assert(Tok.getIdentifierInfo()); + StringRef Section = Tok.getIdentifierInfo()->getName(); + AcceptAndIgnore = Section.equals_insensitive("test"); + if (AcceptAndIgnore || Section.equals_insensitive("code") || + Section.equals_insensitive("static")) + ValidPragma = true; + break; + } + default: + break; + } + if (!ValidPragma) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << "csect"; + return; + } + Token SectionKind = Tok; + + PP.Lex(Tok); + if (Tok.isNot(tok::comma)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "csect"; + return; + } + + PP.Lex(Tok); + if (Tok.isNot(tok::string_literal)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "csect"; + return; + } + + std::string SectionName; + if (!PP.FinishLexStringLiteral(Tok, SectionName, "pragma csect", + /*AllowMacroExpansion*/ false)) { + return; + } + + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "csect"; + return; + } + + PP.Lex(Tok); + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << "csect"; + return; + } + + if (AcceptAndIgnore) { + // accept and ignore #pragma csect(test, "STRING LITERAL"); + return; + } + + auto *SectionNameRef = new (PP.getPreprocessorAllocator()) + StringRef(StringRef(SectionName).copy(PP.getPreprocessorAllocator())); + + MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(2), + 2); + Toks[0].startToken(); + Toks[0].setKind(tok::annot_pragma_csect); + Toks[0].setLocation(CSectLoc); + Toks[0].setAnnotationValue(static_cast<void *>(SectionNameRef)); + Toks[1] = SectionKind; + + PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, + /*IsReinject=*/false); +} diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index c5d6a17fbfcd34..d5e5a982f24302 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -823,6 +823,9 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs, case tok::annot_pragma_export: HandlePragmaExport(); return nullptr; + case tok::annot_pragma_csect: + HandlePragmaCsect(); + return nullptr; case tok::semi: // Either a C++11 empty-declaration or attribute-declaration. SingleDecl = diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 35d14a4444595a..6aa71f331d1fdb 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1676,3 +1676,23 @@ bool Sema::checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A, bool SkipArgCountCheck) { return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck); } + +void Sema::ActOnPragmaCsect(StringRef SectionKind, SourceLocation SectionLoc, + StringRef SectionName) { + if (SectionKind.equals_insensitive("static")) { + if (!Context.PragmaCsectStatic.empty()) + Diag(SectionLoc, diag::warn_duplicate_pragma) << "csect"; + else if (Context.PragmaCsectCode == SectionName) + Diag(SectionLoc, diag::err_conflicting_pragma) << SectionName << "csect"; + else + Context.PragmaCsectStatic = SectionName.str(); + } else if (SectionKind.equals_insensitive("code")) { + if (!Context.PragmaCsectCode.empty()) + Diag(SectionLoc, diag::warn_duplicate_pragma) << "csect"; + else if (Context.PragmaCsectStatic == SectionName) + Diag(SectionLoc, diag::err_conflicting_pragma) << SectionName << "csect"; + else + Context.PragmaCsectCode = SectionName.str(); + } else + llvm_unreachable("invalid Csect kind"); +} diff --git a/clang/test/CodeGen/SystemZ/zos-csect-option-pragma.c b/clang/test/CodeGen/SystemZ/zos-csect-option-pragma.c new file mode 100644 index 00000000000000..76d1c78902f19b --- /dev/null +++ b/clang/test/CodeGen/SystemZ/zos-csect-option-pragma.c @@ -0,0 +1,29 @@ +// REQUIRES: systemz-registered-target + +// RUN: %clang -S -emit-llvm --target=s390x-none-zos %s -o outputfile2.ll && cat outputfile2.ll | FileCheck %s --check-prefix=CHECK-NOCSECT +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mcsect %s -o outputfile2.ll && cat outputfile2.ll | FileCheck %s +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mcsect= %s -o outputfile2.ll && cat outputfile2.ll | FileCheck %s +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mcsect=abc %s -o outputfile2.ll && cat outputfile2.ll | FileCheck %s --check-prefix=CHECK-QUALIFIER +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mno-csect %s -o outputfile2.ll && cat outputfile2.ll | FileCheck %s --check-prefix=CHECK-NOCSECT +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mcsect %s && cat zos-csect-option-pragma.ll | FileCheck %s --check-prefix=CHECK-NOOUTFILE +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mcsect= %s && cat zos-csect-option-pragma.ll | FileCheck %s --check-prefix=CHECK-NOOUTFILE +// RUN: %clang -S -emit-llvm --target=s390x-none-zos -mcsect=cde %s && cat zos-csect-option-pragma.ll | FileCheck %s --check-prefix=CHECK-NOOUTFILE-QUALIFIER + +#pragma csect(code, "csectcode") + +int main() { return 0; } + +// CHECK: !{i32 1, !"zos_csect_code", !"csectcode"} +// CHECK: !{i32 1, !"zos_csect_static", !"outputfile2#S"} + +// CHECK-QUALIFIER: !{i32 1, !"zos_csect_code", !"csectcode"} +// CHECK-QUALIFIER: !{i32 1, !"zos_csect_static", !"abc#outputfile2#S"} + +// CHECK-NOCSECT: !{i32 1, !"zos_csect_code", !"csectcode"} +// CHECK-NOCSECT-NOT: zos_csect_static + +// CHECK-NOOUTFILE: !{i32 1, !"zos_csect_code", !"csectcode"} +// CHECK-NOOUTFILE: !{i32 1, !"zos_csect_static", !"zos-csect-option-pragma#S"} + +// CHECK-NOOUTFILE-QUALIFIER: !{i32 1, !"zos_csect_code", !"csectcode"} +// CHECK-NOOUTFILE-QUALIFIER: !{i32 1, !"zos_csect_static", !"cde#zos-csect-option-pragma#S"} diff --git a/clang/test/CodeGen/SystemZ/zos-csect-option.c b/clang/test/CodeGen/SystemZ/zos-csect-option.c new file mode 100644 index 00000000000000..a515099949a53a --- /dev/null +++ b/clang/test/CodeGen/SystemZ/zos-csect-option.c @@ -0,0 +1,19 @@ +// REQUIRES: systemz-registered-target + +// RUN: %clang -S -emit-llvm --target=s390x-none-zos %s -o outputfile.ll && cat outputfile.ll | FileCheck... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/234368 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
