This is v2 of the patch; v1 was here:
  https://gcc.gnu.org/pipermail/gcc-patches/2024-June/655541.html

Changed in v2:
* added a new TARGET_DOCUMENTATION_NAME hook for figuring out which
  documentation URL to use when there are multiple per-target docs,
  such as for __attribute__((interrupt)); implemented this for all
  targets that have target-specific attributes
* moved attribute_urlifier and its support code to a new
  gcc-attribute-urlifier.cc since it needs to use targetm for the
  above; gcc-urlifier.o is used by the driver.
* fixed extend.texi so that some attributes that failed to appear in
  attr-urls.def now do so (affected nvptx "kernel" and "shared" attrs)
* regenerated attr-urls.def for the above fix, and bringing in
  attributes added since v1 of the patch

In r14-5118-gc5db4d8ba5f3de I added a mechanism to automatically add
documentation URLs to quoted strings in diagnostics.
In r14-6920-g9e49746da303b8 I added a mechanism to generate URLs for
mentions of command-line options in quoted strings in diagnostics.

This patch does a similar thing for attributes.  It adds a new Python 3
script to scrape the generated HTML looking for documentation of
attributes, and uses this to (re)generate a new gcc/attr-urls.def file.

Running "make regenerate-attr-urls" after rebuilding the HTML docs will
regenerate gcc/attr-urls.def in the source directory.

The patch uses this to optionally add doc URLs for attributes in any
diagnostic emitted during the lifetime of a auto_urlify_attributes
instance, and adds such instances everywhere that a diagnostic refers
to a diagnostic within quotes (based on grepping the source tree
for references to attributes in strings and in code).

For example, given:

$ ./xgcc -B. -S ../../src/gcc/testsuite/gcc.dg/attr-access-2.c
../../src/gcc/testsuite/gcc.dg/attr-access-2.c:14:16: warning:
attribute ‘access(read_write, 2, 3)’ positional argument 2 conflicts
with previous designation by argument 1 [-Wattributes]

with this patch the quoted text `access(read_write, 2, 3)'
automatically gains the URL for our docs for "access":
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-access-function-attribute
in a sufficiently modern terminal.

Like r14-6920-g9e49746da303b8 this avoids the Makefile target
depending on the generated HTML, since a missing URL is a minor
problem, whereas requiring all users to build HTML docs seems more
involved.  Doing so also avoids Python 3 as a build requirement for
everyone, but instead just for developers addding attributes.
Like the options, we could add a CI test for this.

The patch gathers both general and target-specific attributes.
For example, the function attribute "interrupt" has 19 URLs within our
docs: one common, and 18 target-specific ones.
The patch adds a new target hook used when selecting the most
appropriate one.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for trunk?

Signed-off-by: David Malcolm <dmalc...@redhat.com>

gcc/ChangeLog:
        * Makefile.in (OBJS): Add -attribute-urlifier.o.
        (ATTR_URLS_HTML_DEPS): New.
        (regenerate-attr-urls): New.
        (regenerate-attr-urls-unit-test): New.
        * attr-urls.def: New file.
        * attribs.cc: Include "gcc-urlifier.h".
        (decl_attributes): Use auto_urlify_attributes.
        * config/aarch64/aarch64.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/arc/arc.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/arm/arm.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/bfin/bfin.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/bpf/bpf.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/epiphany/epiphany.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/gcn/gcn.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/h8300/h8300.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/i386/i386.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/ia64/ia64.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/m32c/m32c.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/m32r/m32r.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/m68k/m68k.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/mcore/mcore.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/microblaze/microblaze.cc (TARGET_DOCUMENTATION_NAME):
        New.
        * config/mips/mips.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/msp430/msp430.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/nds32/nds32.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/nvptx/nvptx.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/riscv/riscv.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/rl78/rl78.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/rs6000/rs6000.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/rx/rx.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/s390/s390.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/sh/sh.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/stormy16/stormy16.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/v850/v850.cc (TARGET_DOCUMENTATION_NAME): New.
        * config/visium/visium.cc (TARGET_DOCUMENTATION_NAME): New.

gcc/analyzer/ChangeLog:
        * region-model.cc: Include "gcc-urlifier.h".
        (reason_attr_access::emit): Use auto_urlify_attributes.
        * sm-taint.cc: Include "gcc-urlifier.h".
        (tainted_access_attrib_size::emit): Use auto_urlify_attributes.

gcc/c-family/ChangeLog:
        * c-attribs.cc: Include "gcc-urlifier.h".
        (positional_argument): Use auto_urlify_attributes.
        * c-common.cc: Include "gcc-urlifier.h".
        (parse_optimize_options): Use auto_urlify_attributes with
        OPT_Wattributes.
        (attribute_fallthrough_p): Use auto_urlify_attributes.
        * c-warn.cc: Include "gcc-urlifier.h".
        (diagnose_mismatched_attributes): Use auto_urlify_attributes.

gcc/c/ChangeLog:
        * c-decl.cc: Include "gcc-urlifier.h".
        (start_decl): Use auto_urlify_attributes with OPT_Wattributes.
        (start_function): Likewise.
        * c-parser.cc: Include "gcc-urlifier.h".
        (c_parser_statement_after_labels): Use auto_urlify_attributes with
        OPT_Wattributes.
        * c-typeck.cc: Include "gcc-urlifier.h".
        (maybe_warn_nodiscard): Use auto_urlify_attributes with
        OPT_Wunused_result.

gcc/cp/ChangeLog:
        * cp-gimplify.cc: Include "gcc-urlifier.h".
        (process_stmt_hotness_attribute): Use auto_urlify_attributes with
        OPT_Wattributes.
        * cvt.cc: Include "gcc-urlifier.h".
        (maybe_warn_nodiscard): Use auto_urlify_attributes with
        OPT_Wunused_result.
        * decl.cc: Include "gcc-urlifier.h".
        (start_decl): Use auto_urlify_attributes.
        (start_preparsed_function): Likewise.

gcc/ChangeLog:
        * diagnostic.cc (diagnostic_context::override_urlifier): New.
        * diagnostic.h (diagnostic_context::override_urlifier): New decl.
        * doc/extend.texi (Nvidia PTX Function Attributes): Update
        @cindex to specify that "kernel" is a function attribute and
        "shared" is a variable attribute, so that these entries are
        recognized by the regex in regenerate-attr-urls.py.
        * doc/tm.texi: Regenerate.
        * doc/tm.texi.in (TARGET_DOCUMENTATION_NAME): New.
        * gcc-attribute-urlifier.cc: New file.
        * gcc-urlifier.cc: Include diagnostic.h.
        (gcc_urlifier::make_doc): Convert to...
        (make_doc_url): ...this.
        (auto_override_urlifier::auto_override_urlifier): New.
        (auto_override_urlifier::~auto_override_urlifier): New.
        (selftest::gcc_urlifier_cc_tests): Split out body into...
        (selftest::test_gcc_urlifier): ...this.
        * gcc-urlifier.h: Include "pretty-print-urlifier.h" and "label-text.h".
        (make_doc_url): New decl.
        (class auto_override_urlifier): New.
        (class attribute_urlifier): New.
        (class auto_urlify_attributes): New.
        * gimple-ssa-warn-access.cc: Include "gcc-urlifier.h".
        (pass_waccess::execute): Use auto_urlify_attributes.
        * gimplify.cc: Include "gcc-urlifier.h".
        (expand_FALLTHROUGH): Use auto_urlify_attributes.
        * internal-fn.cc: Define INCLUDE_MEMORY and include
        "gcc-urlifier.h.
        (expand_FALLTHROUGH): Use auto_urlify_attributes.
        * ipa-pure-const.cc: Include "gcc-urlifier.h.
        (suggest_attribute): Use auto_urlify_attributes.
        * ipa-strub.cc: Include "gcc-urlifier.h.
        (can_strub_p): Use auto_urlify_attributes.
        * regenerate-attr-urls.py: New file.
        * selftest-run-tests.cc (selftest::run_tests): Call
        gcc_attribute_urlifier_cc_tests.
        * selftest.h (selftest::gcc_attribute_urlifier_cc_tests): New
        decl.
        * target.def (documentation_name): New DEFHOOKPOD.
        * tree-cfg.cc: Include "gcc-urlifier.h.
        (do_warn_unused_result): Use auto_urlify_attributes.
        * tree-ssa-uninit.cc: Include "gcc-urlifier.h.
        (maybe_warn_read_write_only): Use auto_urlify_attributes.
        (maybe_warn_pass_by_reference): Likewise.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/Makefile.in                     |  13 +
 gcc/analyzer/region-model.cc        |   2 +
 gcc/analyzer/sm-taint.cc            |   2 +
 gcc/attr-urls.def                   | 377 ++++++++++++++++++++++++++++
 gcc/attribs.cc                      |   3 +
 gcc/c-family/c-attribs.cc           |   3 +
 gcc/c-family/c-common.cc            |  18 +-
 gcc/c-family/c-warn.cc              |   2 +
 gcc/c/c-decl.cc                     |  17 +-
 gcc/c/c-parser.cc                   |  20 +-
 gcc/c/c-typeck.cc                   |   3 +
 gcc/config/aarch64/aarch64.cc       |   3 +
 gcc/config/arc/arc.cc               |   3 +
 gcc/config/arm/arm.cc               |   3 +
 gcc/config/bfin/bfin.cc             |   3 +
 gcc/config/bpf/bpf.cc               |   3 +
 gcc/config/epiphany/epiphany.cc     |   3 +
 gcc/config/gcn/gcn.cc               |   3 +
 gcc/config/h8300/h8300.cc           |   3 +
 gcc/config/i386/i386.cc             |   3 +
 gcc/config/ia64/ia64.cc             |   3 +
 gcc/config/m32c/m32c.cc             |   3 +
 gcc/config/m32r/m32r.cc             |   3 +
 gcc/config/m68k/m68k.cc             |   3 +
 gcc/config/mcore/mcore.cc           |   3 +
 gcc/config/microblaze/microblaze.cc |   3 +
 gcc/config/mips/mips.cc             |   3 +
 gcc/config/msp430/msp430.cc         |   3 +
 gcc/config/nds32/nds32.cc           |   3 +
 gcc/config/nvptx/nvptx.cc           |   3 +
 gcc/config/riscv/riscv.cc           |   3 +
 gcc/config/rl78/rl78.cc             |   3 +
 gcc/config/rs6000/rs6000.cc         |   3 +
 gcc/config/rx/rx.cc                 |   3 +
 gcc/config/s390/s390.cc             |   3 +
 gcc/config/sh/sh.cc                 |   3 +
 gcc/config/stormy16/stormy16.cc     |   3 +
 gcc/config/v850/v850.cc             |   2 +
 gcc/config/visium/visium.cc         |   3 +
 gcc/cp/cp-gimplify.cc               |   8 +-
 gcc/cp/cvt.cc                       |   4 +
 gcc/cp/decl.cc                      |  15 +-
 gcc/diagnostic.cc                   |   8 +
 gcc/diagnostic.h                    |   2 +
 gcc/doc/extend.texi                 |   4 +-
 gcc/doc/tm.texi                     |   5 +
 gcc/doc/tm.texi.in                  |   2 +
 gcc/gcc-attribute-urlifier.cc       | 243 ++++++++++++++++++
 gcc/gcc-urlifier.cc                 |  49 ++--
 gcc/gcc-urlifier.h                  |  57 +++++
 gcc/gimple-ssa-warn-access.cc       |   3 +
 gcc/gimplify.cc                     |   3 +
 gcc/internal-fn.cc                  |   3 +
 gcc/ipa-pure-const.cc               |   2 +
 gcc/ipa-strub.cc                    |   3 +
 gcc/regenerate-attr-urls.py         | 209 +++++++++++++++
 gcc/selftest-run-tests.cc           |   1 +
 gcc/selftest.h                      |   1 +
 gcc/target.def                      |   9 +
 gcc/tree-cfg.cc                     |   3 +
 gcc/tree-ssa-uninit.cc              |   3 +
 61 files changed, 1140 insertions(+), 40 deletions(-)
 create mode 100644 gcc/attr-urls.def
 create mode 100644 gcc/gcc-attribute-urlifier.cc
 create mode 100755 gcc/regenerate-attr-urls.py

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0cbb3633e01e..9a889b44df78 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1473,6 +1473,7 @@ OBJS = \
        function-abi.o \
        function-tests.o \
        fwprop.o \
+       gcc-attribute-urlifier.o \
        gcc-rich-location.o \
        gcc-urlifier.o \
        gcse.o \
@@ -3802,6 +3803,18 @@ regenerate-opt-urls: $(srcdir)/regenerate-opt-urls.py 
$(OPT_URLS_HTML_DEPS)
 regenerate-opt-urls-unit-test: $(OPT_URLS_HTML_DEPS)
        $(srcdir)/regenerate-opt-urls.py $(build_htmldir) $(shell dirname 
$(srcdir)) --unit-test
 
+# Regenerate attr-urls.def from the generated html.
+.PHONY: regenerate-attr-urls
+ATTR_URLS_HTML_DEPS = $(build_htmldir)/gcc/Concept-and-Symbol-Index.html
+
+regenerate-attr-urls: $(srcdir)/regenerate-attr-urls.py $(ATTR_URLS_HTML_DEPS)
+       $(srcdir)/regenerate-attr-urls.py $(build_htmldir) $(shell dirname 
$(srcdir))
+
+# Run the unit tests for regenerate-attr-urls.py
+.PHONY: regenerate-attr-urls-unit-test
+regenerate-attr-urls-unit-test: $(ATTR_URLS_HTML_DEPS)
+       $(srcdir)/regenerate-attr-urls.py $(build_htmldir) $(shell dirname 
$(srcdir)) --unit-test
+
 MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 \
            doc/fsf-funding.7 doc/gcov-tool.1 doc/gcov-dump.1 \
           $(if $(filter yes,@enable_lto@),doc/lto-dump.1)
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index aa4e9982c891..ede277a0ff10 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "analyzer/record-layout.h"
 #include "diagnostic-format-sarif.h"
 #include "text-art/tree-widget.h"
+#include "gcc-urlifier.h"
 
 #if ENABLE_ANALYZER
 
@@ -2061,6 +2062,7 @@ public:
 
   void emit () const final override
   {
+    auto_urlify_attributes sentinel;
     inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
            "parameter %i of %qD marked with attribute %qs",
            m_ptr_argno + 1, m_callee_fndecl, m_access_str);
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index ecea46feddad..bb788b515eb7 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/constraint-manager.h"
 #include "diagnostic-format-sarif.h"
+#include "gcc-urlifier.h"
 
 #if ENABLE_ANALYZER
 
@@ -659,6 +660,7 @@ public:
     bool warned = tainted_size::emit (ctxt);
     if (warned)
       {
+       auto_urlify_attributes sentinel;
        inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
                "parameter %i of %qD marked as a size via attribute %qs",
                m_size_argno + 1, m_callee_fndecl, m_access_str);
diff --git a/gcc/attr-urls.def b/gcc/attr-urls.def
new file mode 100644
index 000000000000..f2ebd7b82a5e
--- /dev/null
+++ b/gcc/attr-urls.def
@@ -0,0 +1,377 @@
+/* Autogenerated by regenerate-attr-urls.py.  */
+
+const attr_url_entry enumerator_attrs[] = {
+ { "deprecated", 
"gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute", "", 10},
+ { "unavailable", 
"gcc/Enumerator-Attributes.html#index-unavailable-enumerator-attribute", "", 
11},
+};
+
+const attr_url_entry function_attrs[] = {
+ { "OS_main", 
"gcc/AVR-Function-Attributes.html#index-OS_005fmain-function-attribute_002c-AVR",
 "AVR", 7},
+ { "OS_task", 
"gcc/AVR-Function-Attributes.html#index-OS_005ftask-function-attribute_002c-AVR",
 "AVR", 7},
+ { "abi_tag", 
"gcc/C_002b_002b-Attributes.html#index-abi_005ftag-function-attribute", "", 7},
+ { "access", 
"gcc/Common-Function-Attributes.html#index-access-function-attribute", "", 6},
+ { "alias", 
"gcc/Common-Function-Attributes.html#index-alias-function-attribute", "", 5},
+ { "aligned", 
"gcc/Common-Function-Attributes.html#index-aligned-function-attribute", "", 7},
+ { "alloc_align", 
"gcc/Common-Function-Attributes.html#index-alloc_005falign-function-attribute", 
"", 11},
+ { "alloc_size", 
"gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute", 
"", 10},
+ { "always_inline", 
"gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute",
 "", 13},
+ { "amdgpu_hsa_kernel", 
"gcc/AMD-GCN-Function-Attributes.html#index-amdgpu_005fhsa_005fkernel-function-attribute_002c-AMD-GCN",
 "AMD GCN", 17},
+ { "arch=", 
"gcc/AArch64-Function-Attributes.html#index-arch_003d-function-attribute_002c-AArch64",
 "AArch64", 5},
+ { "arch=", 
"gcc/ARM-Function-Attributes.html#index-arch_003d-function-attribute_002c-ARM", 
"ARM", 5},
+ { "arch=", 
"gcc/RISC-V-Function-Attributes.html#index-arch_003d-function-attribute_002c-RISC-V",
 "RISC-V", 5},
+ { "artificial", 
"gcc/Common-Function-Attributes.html#index-artificial-function-attribute", "", 
10},
+ { "assume_aligned", 
"gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute",
 "", 14},
+ { "bank_switch", 
"gcc/M32C-Function-Attributes.html#index-bank_005fswitch-function-attribute_002c-M32C",
 "M32C", 11},
+ { "branch-protection", 
"gcc/AArch64-Function-Attributes.html#index-branch-protection-function-attribute_002c-AArch64",
 "AArch64", 17},
+ { "break_handler", 
"gcc/MicroBlaze-Function-Attributes.html#index-break_005fhandler-function-attribute_002c-MicroBlaze",
 "MicroBlaze", 13},
+ { "brk_interrupt", 
"gcc/RL78-Function-Attributes.html#index-brk_005finterrupt-function-attribute_002c-RL78",
 "RL78", 13},
+ { "callee_pop_aggregate_return", 
"gcc/x86-Function-Attributes.html#index-callee_005fpop_005faggregate_005freturn-function-attribute_002c-x86",
 "x86", 27},
+ { "cdecl", 
"gcc/x86-Function-Attributes.html#index-cdecl-function-attribute_002c-x86-32", 
"x86-32", 5},
+ { "cf_check", 
"gcc/x86-Function-Attributes.html#index-cf_005fcheck-function-attribute_002c-x86",
 "x86", 8},
+ { "cmodel=", 
"gcc/AArch64-Function-Attributes.html#index-cmodel_003d-function-attribute_002c-AArch64",
 "AArch64", 7},
+ { "code_readable", 
"gcc/MIPS-Function-Attributes.html#index-code_005freadable-function-attribute_002c-MIPS",
 "MIPS", 13},
+ { "cold", 
"gcc/Common-Function-Attributes.html#index-cold-function-attribute", "", 4},
+ { "const", 
"gcc/Common-Function-Attributes.html#index-const-function-attribute", "", 5},
+ { "constructor", 
"gcc/Common-Function-Attributes.html#index-constructor-function-attribute", "", 
11},
+ { "copy", 
"gcc/Common-Function-Attributes.html#index-copy-function-attribute", "", 4},
+ { "cpu=", 
"gcc/AArch64-Function-Attributes.html#index-cpu_003d-function-attribute_002c-AArch64",
 "AArch64", 4},
+ { "cpu=", 
"gcc/RISC-V-Function-Attributes.html#index-cpu_003d-function-attribute_002c-RISC-V",
 "RISC-V", 4},
+ { "critical", 
"gcc/MSP430-Function-Attributes.html#index-critical-function-attribute_002c-MSP430",
 "MSP430", 8},
+ { "deprecated", 
"gcc/Common-Function-Attributes.html#index-deprecated-function-attribute", "", 
10},
+ { "destructor", 
"gcc/Common-Function-Attributes.html#index-destructor-function-attribute", "", 
10},
+ { "disinterrupt", 
"gcc/Epiphany-Function-Attributes.html#index-disinterrupt-function-attribute_002c-Epiphany",
 "Epiphany", 12},
+ { "dllexport", 
"gcc/Microsoft-Windows-Function-Attributes.html#index-dllexport-function-attribute",
 "", 9},
+ { "dllimport", 
"gcc/Microsoft-Windows-Function-Attributes.html#index-dllimport-function-attribute",
 "", 9},
+ { "either", 
"gcc/MSP430-Function-Attributes.html#index-either-function-attribute_002c-MSP430",
 "MSP430", 6},
+ { "error", 
"gcc/Common-Function-Attributes.html#index-error-function-attribute", "", 5},
+ { "exception", 
"gcc/NDS32-Function-Attributes.html#index-exception-function-attribute", "", 9},
+ { "exception_handler", 
"gcc/Blackfin-Function-Attributes.html#index-exception_005fhandler-function-attribute",
 "", 17},
+ { "expected_throw", 
"gcc/Common-Function-Attributes.html#index-expected_005fthrow-function-attribute",
 "", 14},
+ { "externally_visible", 
"gcc/Common-Function-Attributes.html#index-externally_005fvisible-function-attribute",
 "", 18},
+ { "far", 
"gcc/MIPS-Function-Attributes.html#index-far-function-attribute_002c-MIPS", 
"MIPS", 3},
+ { "fast_interrupt", 
"gcc/M32C-Function-Attributes.html#index-fast_005finterrupt-function-attribute_002c-M32C",
 "M32C", 14},
+ { "fast_interrupt", 
"gcc/MicroBlaze-Function-Attributes.html#index-fast_005finterrupt-function-attribute_002c-MicroBlaze",
 "MicroBlaze", 14},
+ { "fast_interrupt", 
"gcc/RX-Function-Attributes.html#index-fast_005finterrupt-function-attribute_002c-RX",
 "RX", 14},
+ { "fastcall", 
"gcc/x86-Function-Attributes.html#index-fastcall-function-attribute_002c-x86-32",
 "x86-32", 8},
+ { "fd_arg", 
"gcc/Common-Function-Attributes.html#index-fd_005farg-function-attribute", "", 
6},
+ { "fd_arg_read", 
"gcc/Common-Function-Attributes.html#index-fd_005farg_005fread-function-attribute",
 "", 11},
+ { "fd_arg_write", 
"gcc/Common-Function-Attributes.html#index-fd_005farg_005fwrite-function-attribute",
 "", 12},
+ { "fentry_name", 
"gcc/x86-Function-Attributes.html#index-fentry_005fname-function-attribute_002c-x86",
 "x86", 11},
+ { "fentry_section", 
"gcc/x86-Function-Attributes.html#index-fentry_005fsection-function-attribute_002c-x86",
 "x86", 14},
+ { "fix-cortex-a53-835769", 
"gcc/AArch64-Function-Attributes.html#index-fix-cortex-a53-835769-function-attribute_002c-AArch64",
 "AArch64", 21},
+ { "flatten", 
"gcc/Common-Function-Attributes.html#index-flatten-function-attribute", "", 7},
+ { "force_align_arg_pointer", 
"gcc/x86-Function-Attributes.html#index-force_005falign_005farg_005fpointer-function-attribute_002c-x86",
 "x86", 23},
+ { "format", 
"gcc/Common-Function-Attributes.html#index-format-function-attribute", "", 6},
+ { "format_arg", 
"gcc/Common-Function-Attributes.html#index-format_005farg-function-attribute", 
"", 10},
+ { "forwarder_section", 
"gcc/Epiphany-Function-Attributes.html#index-forwarder_005fsection-function-attribute_002c-Epiphany",
 "Epiphany", 17},
+ { "function_return", 
"gcc/x86-Function-Attributes.html#index-function_005freturn-function-attribute_002c-x86",
 "x86", 15},
+ { "function_vector", 
"gcc/H8_002f300-Function-Attributes.html#index-function_005fvector-function-attribute_002c-H8_002f300",
 "H8/300", 15},
+ { "function_vector", 
"gcc/M32C-Function-Attributes.html#index-function_005fvector-function-attribute_002c-M16C_002fM32C",
 "M16C/M32C", 15},
+ { "function_vector", 
"gcc/SH-Function-Attributes.html#index-function_005fvector-function-attribute_002c-SH",
 "SH", 15},
+ { "general-regs-only", 
"gcc/AArch64-Function-Attributes.html#index-general-regs-only-function-attribute_002c-AArch64",
 "AArch64", 17},
+ { "general-regs-only", 
"gcc/ARM-Function-Attributes.html#index-general-regs-only-function-attribute_002c-ARM",
 "ARM", 17},
+ { "gnu_inline", 
"gcc/Common-Function-Attributes.html#index-gnu_005finline-function-attribute", 
"", 10},
+ { "hot", "gcc/Common-Function-Attributes.html#index-hot-function-attribute", 
"", 3},
+ { "hotpatch", 
"gcc/S_002f390-Function-Attributes.html#index-hotpatch-function-attribute_002c-S_002f390",
 "S/390", 8},
+ { "ifunc", 
"gcc/Common-Function-Attributes.html#index-ifunc-function-attribute", "", 5},
+ { "indirect_branch", 
"gcc/x86-Function-Attributes.html#index-indirect_005fbranch-function-attribute_002c-x86",
 "x86", 15},
+ { "indirect_return", 
"gcc/x86-Function-Attributes.html#index-indirect_005freturn-function-attribute_002c-x86",
 "x86", 15},
+ { "interrupt", 
"gcc/ARC-Function-Attributes.html#index-interrupt-function-attribute_002c-ARC", 
"ARC", 9},
+ { "interrupt", 
"gcc/ARM-Function-Attributes.html#index-interrupt-function-attribute_002c-ARM", 
"ARM", 9},
+ { "interrupt", 
"gcc/AVR-Function-Attributes.html#index-interrupt-function-attribute_002c-AVR", 
"AVR", 9},
+ { "interrupt", 
"gcc/C-SKY-Function-Attributes.html#index-interrupt-function-attribute_002c-C-SKY",
 "C-SKY", 9},
+ { "interrupt", 
"gcc/Common-Function-Attributes.html#index-interrupt-function-attribute", "", 
9},
+ { "interrupt", 
"gcc/Epiphany-Function-Attributes.html#index-interrupt-function-attribute_002c-Epiphany",
 "Epiphany", 9},
+ { "interrupt", 
"gcc/M32C-Function-Attributes.html#index-interrupt-function-attribute_002c-M32C",
 "M32C", 9},
+ { "interrupt", 
"gcc/M32R_002fD-Function-Attributes.html#index-interrupt-function-attribute_002c-M32R_002fD",
 "M32R/D", 9},
+ { "interrupt", 
"gcc/MIPS-Function-Attributes.html#index-interrupt-function-attribute_002c-MIPS",
 "MIPS", 9},
+ { "interrupt", 
"gcc/MSP430-Function-Attributes.html#index-interrupt-function-attribute_002c-MSP430",
 "MSP430", 9},
+ { "interrupt", 
"gcc/NDS32-Function-Attributes.html#index-interrupt-function-attribute_002c-NDS32",
 "NDS32", 9},
+ { "interrupt", 
"gcc/RISC-V-Function-Attributes.html#index-interrupt-function-attribute_002c-RISC-V",
 "RISC-V", 9},
+ { "interrupt", 
"gcc/RL78-Function-Attributes.html#index-interrupt-function-attribute_002c-RL78",
 "RL78", 9},
+ { "interrupt", 
"gcc/RX-Function-Attributes.html#index-interrupt-function-attribute_002c-RX", 
"RX", 9},
+ { "interrupt", 
"gcc/V850-Function-Attributes.html#index-interrupt-function-attribute_002c-V850",
 "V850", 9},
+ { "interrupt", 
"gcc/Visium-Function-Attributes.html#index-interrupt-function-attribute_002c-Visium",
 "Visium", 9},
+ { "interrupt", 
"gcc/Xstormy16-Function-Attributes.html#index-interrupt-function-attribute_002c-Xstormy16",
 "Xstormy16", 9},
+ { "interrupt", 
"gcc/m68k-Function-Attributes.html#index-interrupt-function-attribute_002c-m68k",
 "m68k", 9},
+ { "interrupt", 
"gcc/x86-Function-Attributes.html#index-interrupt-function-attribute_002c-x86", 
"x86", 9},
+ { "interrupt_handler", 
"gcc/Blackfin-Function-Attributes.html#index-interrupt_005fhandler-function-attribute_002c-Blackfin",
 "Blackfin", 17},
+ { "interrupt_handler", 
"gcc/Common-Function-Attributes.html#index-interrupt_005fhandler-function-attribute",
 "", 17},
+ { "interrupt_handler", 
"gcc/H8_002f300-Function-Attributes.html#index-interrupt_005fhandler-function-attribute_002c-H8_002f300",
 "H8/300", 17},
+ { "interrupt_handler", 
"gcc/MicroBlaze-Function-Attributes.html#index-interrupt_005fhandler-function-attribute_002c-MicroBlaze",
 "MicroBlaze", 17},
+ { "interrupt_handler", 
"gcc/SH-Function-Attributes.html#index-interrupt_005fhandler-function-attribute_002c-SH",
 "SH", 17},
+ { "interrupt_handler", 
"gcc/V850-Function-Attributes.html#index-interrupt_005fhandler-function-attribute_002c-V850",
 "V850", 17},
+ { "interrupt_handler", 
"gcc/m68k-Function-Attributes.html#index-interrupt_005fhandler-function-attribute_002c-m68k",
 "m68k", 17},
+ { "interrupt_thread", 
"gcc/m68k-Function-Attributes.html#index-interrupt_005fthread-function-attribute_002c-fido",
 "fido", 16},
+ { "isr", 
"gcc/ARM-Function-Attributes.html#index-isr-function-attribute_002c-ARM", 
"ARM", 3},
+ { "isr", 
"gcc/C-SKY-Function-Attributes.html#index-isr-function-attribute_002c-C-SKY", 
"C-SKY", 3},
+ { "jli_always", 
"gcc/ARC-Function-Attributes.html#index-jli_005falways-function-attribute_002c-ARC",
 "ARC", 10},
+ { "jli_fixed", 
"gcc/ARC-Function-Attributes.html#index-jli_005ffixed-function-attribute_002c-ARC",
 "ARC", 9},
+ { "keep_interrupts_masked", 
"gcc/MIPS-Function-Attributes.html#index-keep_005finterrupts_005fmasked-function-attribute_002c-MIPS",
 "MIPS", 22},
+ { "kernel", 
"gcc/Nvidia-PTX-Function-Attributes.html#index-kernel-function-attribute_002c-Nvidia-PTX",
 "Nvidia PTX", 6},
+ { "kspisusp", 
"gcc/Blackfin-Function-Attributes.html#index-kspisusp-function-attribute_002c-Blackfin",
 "Blackfin", 8},
+ { "l1_text", 
"gcc/Blackfin-Function-Attributes.html#index-l1_005ftext-function-attribute_002c-Blackfin",
 "Blackfin", 7},
+ { "l2", 
"gcc/Blackfin-Function-Attributes.html#index-l2-function-attribute_002c-Blackfin",
 "Blackfin", 2},
+ { "leaf", 
"gcc/Common-Function-Attributes.html#index-leaf-function-attribute", "", 4},
+ { "long_call", 
"gcc/ARC-Function-Attributes.html#index-long_005fcall-function-attribute_002c-ARC",
 "ARC", 9},
+ { "long_call", 
"gcc/ARM-Function-Attributes.html#index-long_005fcall-function-attribute_002c-ARM",
 "ARM", 9},
+ { "long_call", 
"gcc/Epiphany-Function-Attributes.html#index-long_005fcall-function-attribute_002c-Epiphany",
 "Epiphany", 9},
+ { "long_call", 
"gcc/MIPS-Function-Attributes.html#index-long_005fcall-function-attribute_002c-MIPS",
 "MIPS", 9},
+ { "longcall", 
"gcc/Blackfin-Function-Attributes.html#index-longcall-function-attribute_002c-Blackfin",
 "Blackfin", 8},
+ { "longcall", 
"gcc/PowerPC-Function-Attributes.html#index-longcall-function-attribute_002c-PowerPC",
 "PowerPC", 8},
+ { "lower", 
"gcc/MSP430-Function-Attributes.html#index-lower-function-attribute_002c-MSP430",
 "MSP430", 5},
+ { "malloc", 
"gcc/Common-Function-Attributes.html#index-malloc-function-attribute", "", 6},
+ { "medium_call", 
"gcc/ARC-Function-Attributes.html#index-medium_005fcall-function-attribute_002c-ARC",
 "ARC", 11},
+ { "micromips", 
"gcc/MIPS-Function-Attributes.html#index-micromips-function-attribute", "", 9},
+ { "mips16", 
"gcc/MIPS-Function-Attributes.html#index-mips16-function-attribute_002c-MIPS", 
"MIPS", 6},
+ { "model", 
"gcc/M32R_002fD-Function-Attributes.html#index-model-function-attribute_002c-M32R_002fD",
 "M32R/D", 5},
+ { "ms_abi", 
"gcc/x86-Function-Attributes.html#index-ms_005fabi-function-attribute_002c-x86",
 "x86", 6},
+ { "ms_hook_prologue", 
"gcc/x86-Function-Attributes.html#index-ms_005fhook_005fprologue-function-attribute_002c-x86",
 "x86", 16},
+ { "naked", 
"gcc/ARC-Function-Attributes.html#index-naked-function-attribute_002c-ARC", 
"ARC", 5},
+ { "naked", 
"gcc/ARM-Function-Attributes.html#index-naked-function-attribute_002c-ARM", 
"ARM", 5},
+ { "naked", 
"gcc/AVR-Function-Attributes.html#index-naked-function-attribute_002c-AVR", 
"AVR", 5},
+ { "naked", 
"gcc/BPF-Function-Attributes.html#index-naked-function-attribute_002c-BPF", 
"BPF", 5},
+ { "naked", 
"gcc/C-SKY-Function-Attributes.html#index-naked-function-attribute_002c-C-SKY", 
"C-SKY", 5},
+ { "naked", 
"gcc/MCORE-Function-Attributes.html#index-naked-function-attribute_002c-MCORE", 
"MCORE", 5},
+ { "naked", 
"gcc/MSP430-Function-Attributes.html#index-naked-function-attribute_002c-MSP430",
 "MSP430", 5},
+ { "naked", 
"gcc/NDS32-Function-Attributes.html#index-naked-function-attribute_002c-NDS32", 
"NDS32", 5},
+ { "naked", 
"gcc/RISC-V-Function-Attributes.html#index-naked-function-attribute_002c-RISC-V",
 "RISC-V", 5},
+ { "naked", 
"gcc/RL78-Function-Attributes.html#index-naked-function-attribute_002c-RL78", 
"RL78", 5},
+ { "naked", 
"gcc/RX-Function-Attributes.html#index-naked-function-attribute_002c-RX", "RX", 
5},
+ { "naked", 
"gcc/x86-Function-Attributes.html#index-naked-function-attribute_002c-x86", 
"x86", 5},
+ { "near", 
"gcc/MIPS-Function-Attributes.html#index-near-function-attribute_002c-MIPS", 
"MIPS", 4},
+ { "nested", 
"gcc/NDS32-Function-Attributes.html#index-nested-function-attribute_002c-NDS32",
 "NDS32", 6},
+ { "nested_ready", 
"gcc/NDS32-Function-Attributes.html#index-nested_005fready-function-attribute_002c-NDS32",
 "NDS32", 12},
+ { "nesting", 
"gcc/Blackfin-Function-Attributes.html#index-nesting-function-attribute_002c-Blackfin",
 "Blackfin", 7},
+ { "nmi", 
"gcc/NDS32-Function-Attributes.html#index-nmi-function-attribute_002c-NDS32", 
"NDS32", 3},
+ { "nmi_handler", 
"gcc/Blackfin-Function-Attributes.html#index-nmi_005fhandler-function-attribute_002c-Blackfin",
 "Blackfin", 11},
+ { "no_callee_saved_registers", 
"gcc/x86-Function-Attributes.html#index-no_005fcallee_005fsaved_005fregisters-function-attribute_002c-x86",
 "x86", 25},
+ { "no_caller_saved_registers", 
"gcc/x86-Function-Attributes.html#index-no_005fcaller_005fsaved_005fregisters-function-attribute_002c-x86",
 "x86", 25},
+ { "no_dangling", 
"gcc/C_002b_002b-Attributes.html#index-no_005fdangling-function-attribute", "", 
11},
+ { "no_gccisr", 
"gcc/AVR-Function-Attributes.html#index-no_005fgccisr-function-attribute_002c-AVR",
 "AVR", 9},
+ { "no_icf", 
"gcc/Common-Function-Attributes.html#index-no_005ficf-function-attribute", "", 
6},
+ { "no_instrument_function", 
"gcc/Common-Function-Attributes.html#index-no_005finstrument_005ffunction-function-attribute",
 "", 22},
+ { "no_profile_instrument_function", 
"gcc/Common-Function-Attributes.html#index-no_005fprofile_005finstrument_005ffunction-function-attribute",
 "", 30},
+ { "no_reorder", 
"gcc/Common-Function-Attributes.html#index-no_005freorder-function-attribute", 
"", 10},
+ { "no_sanitize", 
"gcc/Common-Function-Attributes.html#index-no_005fsanitize-function-attribute", 
"", 11},
+ { "no_sanitize_address", 
"gcc/Common-Function-Attributes.html#index-no_005fsanitize_005faddress-function-attribute",
 "", 19},
+ { "no_sanitize_coverage", 
"gcc/Common-Function-Attributes.html#index-no_005fsanitize_005fcoverage-function-attribute",
 "", 20},
+ { "no_sanitize_thread", 
"gcc/Common-Function-Attributes.html#index-no_005fsanitize_005fthread-function-attribute",
 "", 18},
+ { "no_sanitize_undefined", 
"gcc/Common-Function-Attributes.html#index-no_005fsanitize_005fundefined-function-attribute",
 "", 21},
+ { "no_split_stack", 
"gcc/Common-Function-Attributes.html#index-no_005fsplit_005fstack-function-attribute",
 "", 14},
+ { "no_stack_limit", 
"gcc/Common-Function-Attributes.html#index-no_005fstack_005flimit-function-attribute",
 "", 14},
+ { "no_stack_protector", 
"gcc/Common-Function-Attributes.html#index-no_005fstack_005fprotector-function-attribute",
 "", 18},
+ { "noblock", 
"gcc/AVR-Function-Attributes.html#index-noblock-function-attribute_002c-AVR", 
"AVR", 7},
+ { "nocf_check", 
"gcc/x86-Function-Attributes.html#index-nocf_005fcheck-function-attribute", "", 
10},
+ { "noclone", 
"gcc/Common-Function-Attributes.html#index-noclone-function-attribute", "", 7},
+ { "nocompression", 
"gcc/MIPS-Function-Attributes.html#index-nocompression-function-attribute_002c-MIPS",
 "MIPS", 13},
+ { "nodirect_extern_access", 
"gcc/x86-Function-Attributes.html#index-nodirect_005fextern_005faccess-function-attribute",
 "", 22},
+ { "noinline", 
"gcc/Common-Function-Attributes.html#index-noinline-function-attribute", "", 8},
+ { "noipa", 
"gcc/Common-Function-Attributes.html#index-noipa-function-attribute", "", 5},
+ { "nomicromips", 
"gcc/MIPS-Function-Attributes.html#index-nomicromips-function-attribute", "", 
11},
+ { "nomips16", 
"gcc/MIPS-Function-Attributes.html#index-nomips16-function-attribute_002c-MIPS",
 "MIPS", 8},
+ { "nonnull", 
"gcc/Common-Function-Attributes.html#index-nonnull-function-attribute", "", 7},
+ { "noplt", 
"gcc/Common-Function-Attributes.html#index-noplt-function-attribute", "", 5},
+ { "noreturn", 
"gcc/Common-Function-Attributes.html#index-noreturn-function-attribute", "", 8},
+ { "nosave_low_regs", 
"gcc/SH-Function-Attributes.html#index-nosave_005flow_005fregs-function-attribute_002c-SH",
 "SH", 15},
+ { "not_nested", 
"gcc/NDS32-Function-Attributes.html#index-not_005fnested-function-attribute_002c-NDS32",
 "NDS32", 10},
+ { "nothrow", 
"gcc/Common-Function-Attributes.html#index-nothrow-function-attribute", "", 7},
+ { "null_terminated_string_arg", 
"gcc/Common-Function-Attributes.html#index-null_005fterminated_005fstring_005farg-function-attribute",
 "", 26},
+ { "omit-leaf-frame-pointer", 
"gcc/AArch64-Function-Attributes.html#index-omit-leaf-frame-pointer-function-attribute_002c-AArch64",
 "AArch64", 23},
+ { "optimize", 
"gcc/Common-Function-Attributes.html#index-optimize-function-attribute", "", 8},
+ { "outline-atomics", 
"gcc/AArch64-Function-Attributes.html#index-outline-atomics-function-attribute_002c-AArch64",
 "AArch64", 15},
+ { "partial_save", 
"gcc/NDS32-Function-Attributes.html#index-partial_005fsave-function-attribute_002c-NDS32",
 "NDS32", 12},
+ { "patchable_function_entry", 
"gcc/Common-Function-Attributes.html#index-patchable_005ffunction_005fentry-function-attribute",
 "", 24},
+ { "pcs", 
"gcc/ARM-Function-Attributes.html#index-pcs-function-attribute_002c-ARM", 
"ARM", 3},
+ { "prefer-vector-width", 
"gcc/x86-Function-Attributes.html#index-prefer-vector-width-function-attribute_002c-x86",
 "x86", 19},
+ { "pure", 
"gcc/Common-Function-Attributes.html#index-pure-function-attribute", "", 4},
+ { "reentrant", 
"gcc/MSP430-Function-Attributes.html#index-reentrant-function-attribute_002c-MSP430",
 "MSP430", 9},
+ { "regparm", 
"gcc/x86-Function-Attributes.html#index-regparm-function-attribute_002c-x86", 
"x86", 7},
+ { "renesas", 
"gcc/SH-Function-Attributes.html#index-renesas-function-attribute_002c-SH", 
"SH", 7},
+ { "resbank", 
"gcc/SH-Function-Attributes.html#index-resbank-function-attribute_002c-SH", 
"SH", 7},
+ { "reset", 
"gcc/NDS32-Function-Attributes.html#index-reset-function-attribute_002c-NDS32", 
"NDS32", 5},
+ { "retain", 
"gcc/Common-Function-Attributes.html#index-retain-function-attribute", "", 6},
+ { "returns_nonnull", 
"gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute",
 "", 15},
+ { "returns_twice", 
"gcc/Common-Function-Attributes.html#index-returns_005ftwice-function-attribute",
 "", 13},
+ { "riscv_vector_cc", 
"gcc/RISC-V-Function-Attributes.html#index-riscv_005fvector_005fcc-function-attribute_002c-RISC-V",
 "RISC-V", 15},
+ { "save_all", 
"gcc/NDS32-Function-Attributes.html#index-save_005fall-function-attribute_002c-NDS32",
 "NDS32", 8},
+ { "save_volatiles", 
"gcc/MicroBlaze-Function-Attributes.html#index-save_005fvolatiles-function-attribute_002c-MicroBlaze",
 "MicroBlaze", 14},
+ { "saveall", 
"gcc/Blackfin-Function-Attributes.html#index-saveall-function-attribute_002c-Blackfin",
 "Blackfin", 7},
+ { "saveall", 
"gcc/H8_002f300-Function-Attributes.html#index-saveall-function-attribute_002c-H8_002f300",
 "H8/300", 7},
+ { "section", 
"gcc/Common-Function-Attributes.html#index-section-function-attribute", "", 7},
+ { "secure_call", 
"gcc/ARC-Function-Attributes.html#index-secure_005fcall-function-attribute_002c-ARC",
 "ARC", 11},
+ { "sentinel", 
"gcc/Common-Function-Attributes.html#index-sentinel-function-attribute", "", 8},
+ { "short_call", 
"gcc/ARC-Function-Attributes.html#index-short_005fcall-function-attribute_002c-ARC",
 "ARC", 10},
+ { "short_call", 
"gcc/ARM-Function-Attributes.html#index-short_005fcall-function-attribute_002c-ARM",
 "ARM", 10},
+ { "short_call", 
"gcc/Epiphany-Function-Attributes.html#index-short_005fcall-function-attribute_002c-Epiphany",
 "Epiphany", 10},
+ { "short_call", 
"gcc/MIPS-Function-Attributes.html#index-short_005fcall-function-attribute_002c-MIPS",
 "MIPS", 10},
+ { "shortcall", 
"gcc/Blackfin-Function-Attributes.html#index-shortcall-function-attribute_002c-Blackfin",
 "Blackfin", 9},
+ { "shortcall", 
"gcc/PowerPC-Function-Attributes.html#index-shortcall-function-attribute_002c-PowerPC",
 "PowerPC", 9},
+ { "sign-return-address", 
"gcc/AArch64-Function-Attributes.html#index-sign-return-address-function-attribute_002c-AArch64",
 "AArch64", 19},
+ { "signal", 
"gcc/AVR-Function-Attributes.html#index-signal-function-attribute_002c-AVR", 
"AVR", 6},
+ { "simd", 
"gcc/Common-Function-Attributes.html#index-simd-function-attribute", "", 4},
+ { "sp_switch", 
"gcc/SH-Function-Attributes.html#index-sp_005fswitch-function-attribute_002c-SH",
 "SH", 9},
+ { "sseregparm", 
"gcc/x86-Function-Attributes.html#index-sseregparm-function-attribute_002c-x86",
 "x86", 10},
+ { "stack_protect", 
"gcc/Common-Function-Attributes.html#index-stack_005fprotect-function-attribute",
 "", 13},
+ { "stdcall", 
"gcc/x86-Function-Attributes.html#index-stdcall-function-attribute_002c-x86-32",
 "x86-32", 7},
+ { "strict-align", 
"gcc/AArch64-Function-Attributes.html#index-strict-align-function-attribute_002c-AArch64",
 "AArch64", 12},
+ { "symver", 
"gcc/Common-Function-Attributes.html#index-symver-function-attribute", "", 6},
+ { "syscall_linkage", 
"gcc/IA-64-Function-Attributes.html#index-syscall_005flinkage-function-attribute_002c-IA-64",
 "IA-64", 15},
+ { "sysv_abi", 
"gcc/x86-Function-Attributes.html#index-sysv_005fabi-function-attribute_002c-x86",
 "x86", 8},
+ { "tainted_args", 
"gcc/Common-Function-Attributes.html#index-tainted_005fargs-function-attribute",
 "", 12},
+ { "target", 
"gcc/ARM-Function-Attributes.html#index-target-function-attribute-1", "", 6},
+ { "target", 
"gcc/Common-Function-Attributes.html#index-target-function-attribute", "", 6},
+ { "target", 
"gcc/Nios-II-Function-Attributes.html#index-target-function-attribute-2", "", 
6},
+ { "target", 
"gcc/PowerPC-Function-Attributes.html#index-target-function-attribute-3", "", 
6},
+ { "target", 
"gcc/S_002f390-Function-Attributes.html#index-target-function-attribute-4", "", 
6},
+ { "target", 
"gcc/x86-Function-Attributes.html#index-target-function-attribute-5", "", 6},
+ { "target_clones", 
"gcc/Common-Function-Attributes.html#index-target_005fclones-function-attribute",
 "", 13},
+ { "thiscall", 
"gcc/x86-Function-Attributes.html#index-thiscall-function-attribute_002c-x86-32",
 "x86-32", 8},
+ { "tls-dialect=", 
"gcc/AArch64-Function-Attributes.html#index-tls-dialect_003d-function-attribute_002c-AArch64",
 "AArch64", 12},
+ { "trap_exit", 
"gcc/SH-Function-Attributes.html#index-trap_005fexit-function-attribute_002c-SH",
 "SH", 9},
+ { "trapa_handler", 
"gcc/SH-Function-Attributes.html#index-trapa_005fhandler-function-attribute_002c-SH",
 "SH", 13},
+ { "tune=", 
"gcc/AArch64-Function-Attributes.html#index-tune_003d-function-attribute_002c-AArch64",
 "AArch64", 5},
+ { "tune=", 
"gcc/RISC-V-Function-Attributes.html#index-tune_003d-function-attribute_002c-RISC-V",
 "RISC-V", 5},
+ { "unavailable", 
"gcc/Common-Function-Attributes.html#index-unavailable-function-attribute", "", 
11},
+ { "unused", 
"gcc/Common-Function-Attributes.html#index-unused-function-attribute", "", 6},
+ { "upper", 
"gcc/MSP430-Function-Attributes.html#index-upper-function-attribute_002c-MSP430",
 "MSP430", 5},
+ { "use_debug_exception_return", 
"gcc/MIPS-Function-Attributes.html#index-use_005fdebug_005fexception_005freturn-function-attribute_002c-MIPS",
 "MIPS", 26},
+ { "use_hazard_barrier_return", 
"gcc/MIPS-Function-Attributes.html#index-use_005fhazard_005fbarrier_005freturn-function-attribute_002c-MIPS",
 "MIPS", 25},
+ { "use_shadow_register_set", 
"gcc/MIPS-Function-Attributes.html#index-use_005fshadow_005fregister_005fset-function-attribute_002c-MIPS",
 "MIPS", 23},
+ { "used", 
"gcc/Common-Function-Attributes.html#index-used-function-attribute", "", 4},
+ { "vector", 
"gcc/RX-Function-Attributes.html#index-vector-function-attribute_002c-RX", 
"RX", 6},
+ { "version_id", 
"gcc/IA-64-Function-Attributes.html#index-version_005fid-function-attribute_002c-IA-64",
 "IA-64", 10},
+ { "visibility", 
"gcc/Common-Function-Attributes.html#index-visibility-function-attribute", "", 
10},
+ { "wakeup", 
"gcc/MSP430-Function-Attributes.html#index-wakeup-function-attribute_002c-MSP430",
 "MSP430", 6},
+ { "warm", 
"gcc/NDS32-Function-Attributes.html#index-warm-function-attribute_002c-NDS32", 
"NDS32", 4},
+ { "warn_unused_result", 
"gcc/Common-Function-Attributes.html#index-warn_005funused_005fresult-function-attribute",
 "", 18},
+ { "warning", 
"gcc/Common-Function-Attributes.html#index-warning-function-attribute", "", 7},
+ { "weak", 
"gcc/Common-Function-Attributes.html#index-weak-function-attribute", "", 4},
+ { "weakref", 
"gcc/Common-Function-Attributes.html#index-weakref-function-attribute", "", 7},
+ { "zero_call_used_regs", 
"gcc/Common-Function-Attributes.html#index-zero_005fcall_005fused_005fregs-function-attribute",
 "", 19},
+};
+
+const attr_url_entry label_attrs[] = {
+ { "cold", "gcc/Label-Attributes.html#index-cold-label-attribute", "", 4},
+ { "hot", "gcc/Label-Attributes.html#index-hot-label-attribute", "", 3},
+ { "unused", "gcc/Label-Attributes.html#index-unused-label-attribute", "", 6},
+};
+
+const attr_url_entry statement_attrs[] = {
+ { "assume", "gcc/Statement-Attributes.html#index-assume-statement-attribute", 
"", 6},
+ { "fallthrough", 
"gcc/Statement-Attributes.html#index-fallthrough-statement-attribute", "", 11},
+ { "musttail", 
"gcc/Statement-Attributes.html#index-musttail-statement-attribute", "", 8},
+};
+
+const attr_url_entry type_attrs[] = {
+ { "abi_tag", 
"gcc/C_002b_002b-Attributes.html#index-abi_005ftag-type-attribute", "", 7},
+ { "aligned", "gcc/Common-Type-Attributes.html#index-aligned-type-attribute", 
"", 7},
+ { "alloc_size", 
"gcc/Common-Type-Attributes.html#index-alloc_005fsize-type-attribute", "", 10},
+ { "altivec", 
"gcc/PowerPC-Type-Attributes.html#index-altivec-type-attribute_002c-PowerPC", 
"PowerPC", 7},
+ { "cold", "gcc/C_002b_002b-Attributes.html#index-cold-type-attribute", "", 4},
+ { "copy", "gcc/Common-Type-Attributes.html#index-copy-type-attribute", "", 4},
+ { "deprecated", 
"gcc/Common-Type-Attributes.html#index-deprecated-type-attribute", "", 10},
+ { "designated_init", 
"gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute", "", 
15},
+ { "flag_enum", 
"gcc/Common-Type-Attributes.html#index-flag_005fenum-type-attribute", "", 9},
+ { "gcc_struct", 
"gcc/PowerPC-Type-Attributes.html#index-gcc_005fstruct-type-attribute_002c-PowerPC",
 "PowerPC", 10},
+ { "gcc_struct", 
"gcc/x86-Type-Attributes.html#index-gcc_005fstruct-type-attribute_002c-x86", 
"x86", 10},
+ { "hardbool", 
"gcc/Common-Type-Attributes.html#index-hardbool-type-attribute", "", 8},
+ { "hot", "gcc/C_002b_002b-Attributes.html#index-hot-type-attribute", "", 3},
+ { "may_alias", 
"gcc/Common-Type-Attributes.html#index-may_005falias-type-attribute", "", 9},
+ { "mode", "gcc/Common-Type-Attributes.html#index-mode-type-attribute", "", 4},
+ { "ms_struct", 
"gcc/PowerPC-Type-Attributes.html#index-ms_005fstruct-type-attribute_002c-PowerPC",
 "PowerPC", 9},
+ { "ms_struct", 
"gcc/x86-Type-Attributes.html#index-ms_005fstruct-type-attribute_002c-x86", 
"x86", 9},
+ { "no_dangling", 
"gcc/C_002b_002b-Attributes.html#index-no_005fdangling-type-attribute", "", 11},
+ { "notshared", 
"gcc/ARM-Type-Attributes.html#index-notshared-type-attribute_002c-ARM", "ARM", 
9},
+ { "objc_root_class", 
"gcc/Common-Type-Attributes.html#index-objc_005froot_005fclass-type-attribute", 
"", 15},
+ { "packed", "gcc/Common-Type-Attributes.html#index-packed-type-attribute", 
"", 6},
+ { "preserve_access_index", 
"gcc/BPF-Type-Attributes.html#index-preserve_005faccess_005findex-type-attribute_002c-BPF",
 "BPF", 21},
+ { "scalar_storage_order", 
"gcc/Common-Type-Attributes.html#index-scalar_005fstorage_005forder-type-attribute",
 "", 20},
+ { "strub", "gcc/Common-Type-Attributes.html#index-strub-type-attribute", "", 
5},
+ { "transparent_union", 
"gcc/Common-Type-Attributes.html#index-transparent_005funion-type-attribute", 
"", 17},
+ { "unavailable", 
"gcc/Common-Type-Attributes.html#index-unavailable-type-attribute", "", 11},
+ { "uncached", 
"gcc/ARC-Type-Attributes.html#index-uncached-type-attribute_002c-ARC", "ARC", 
8},
+ { "unused", "gcc/Common-Type-Attributes.html#index-unused-type-attribute", 
"", 6},
+ { "vector_size", 
"gcc/Common-Type-Attributes.html#index-vector_005fsize-type-attribute", "", 11},
+ { "visibility", 
"gcc/Common-Type-Attributes.html#index-visibility-type-attribute", "", 10},
+ { "warn_if_not_aligned", 
"gcc/Common-Type-Attributes.html#index-warn_005fif_005fnot_005faligned-type-attribute",
 "", 19},
+ { "warn_unused", 
"gcc/C_002b_002b-Attributes.html#index-warn_005funused-type-attribute", "", 11},
+};
+
+const attr_url_entry variable_attrs[] = {
+ { "abi_tag", 
"gcc/C_002b_002b-Attributes.html#index-abi_005ftag-variable-attribute", "", 7},
+ { "absdata", 
"gcc/AVR-Variable-Attributes.html#index-absdata-variable-attribute_002c-AVR", 
"AVR", 7},
+ { "address", 
"gcc/AVR-Variable-Attributes.html#index-address-variable-attribute_002c-AVR", 
"AVR", 7},
+ { "alias", 
"gcc/Common-Variable-Attributes.html#index-alias-variable-attribute", "", 5},
+ { "aligned", 
"gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute", "", 7},
+ { "alloc_size", 
"gcc/Common-Variable-Attributes.html#index-alloc_005fsize-variable-attribute", 
"", 10},
+ { "altivec", 
"gcc/PowerPC-Variable-Attributes.html#index-altivec-variable-attribute_002c-PowerPC",
 "PowerPC", 7},
+ { "aux", 
"gcc/ARC-Variable-Attributes.html#index-aux-variable-attribute_002c-ARC", 
"ARC", 3},
+ { "below100", 
"gcc/Xstormy16-Variable-Attributes.html#index-below100-variable-attribute_002c-Xstormy16",
 "Xstormy16", 8},
+ { "cleanup", 
"gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute", "", 7},
+ { "common", 
"gcc/Common-Variable-Attributes.html#index-common-variable-attribute", "", 6},
+ { "copy", 
"gcc/Common-Variable-Attributes.html#index-copy-variable-attribute", "", 4},
+ { "counted_by", 
"gcc/Common-Variable-Attributes.html#index-counted_005fby-variable-attribute", 
"", 10},
+ { "deprecated", 
"gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute", "", 
10},
+ { "dllexport", 
"gcc/Microsoft-Windows-Variable-Attributes.html#index-dllexport-variable-attribute",
 "", 9},
+ { "dllimport", 
"gcc/Microsoft-Windows-Variable-Attributes.html#index-dllimport-variable-attribute",
 "", 9},
+ { "eightbit_data", 
"gcc/H8_002f300-Variable-Attributes.html#index-eightbit_005fdata-variable-attribute_002c-H8_002f300",
 "H8/300", 13},
+ { "either", 
"gcc/MSP430-Variable-Attributes.html#index-either-variable-attribute_002c-MSP430",
 "MSP430", 6},
+ { "gcc_struct", 
"gcc/PowerPC-Variable-Attributes.html#index-gcc_005fstruct-variable-attribute_002c-PowerPC",
 "PowerPC", 10},
+ { "gcc_struct", 
"gcc/x86-Variable-Attributes.html#index-gcc_005fstruct-variable-attribute_002c-x86",
 "x86", 10},
+ { "init_priority", 
"gcc/C_002b_002b-Attributes.html#index-init_005fpriority-variable-attribute", 
"", 13},
+ { "io", 
"gcc/AVR-Variable-Attributes.html#index-io-variable-attribute_002c-AVR", "AVR", 
2},
+ { "io_low", 
"gcc/AVR-Variable-Attributes.html#index-io_005flow-variable-attribute_002c-AVR",
 "AVR", 6},
+ { "l1_data", 
"gcc/Blackfin-Variable-Attributes.html#index-l1_005fdata-variable-attribute_002c-Blackfin",
 "Blackfin", 7},
+ { "l1_data_A", 
"gcc/Blackfin-Variable-Attributes.html#index-l1_005fdata_005fA-variable-attribute_002c-Blackfin",
 "Blackfin", 9},
+ { "l1_data_B", 
"gcc/Blackfin-Variable-Attributes.html#index-l1_005fdata_005fB-variable-attribute_002c-Blackfin",
 "Blackfin", 9},
+ { "l2", 
"gcc/Blackfin-Variable-Attributes.html#index-l2-variable-attribute_002c-Blackfin",
 "Blackfin", 2},
+ { "lower", 
"gcc/MSP430-Variable-Attributes.html#index-lower-variable-attribute_002c-MSP430",
 "MSP430", 5},
+ { "mode", 
"gcc/Common-Variable-Attributes.html#index-mode-variable-attribute", "", 4},
+ { "model", 
"gcc/IA-64-Variable-Attributes.html#index-model-variable-attribute_002c-IA-64", 
"IA-64", 5},
+ { "model", 
"gcc/LoongArch-Variable-Attributes.html#index-model-variable-attribute_002c-LoongArch",
 "LoongArch", 5},
+ { "model-name", 
"gcc/M32R_002fD-Variable-Attributes.html#index-model-name-variable-attribute_002c-M32R_002fD",
 "M32R/D", 10},
+ { "ms_struct", 
"gcc/PowerPC-Variable-Attributes.html#index-ms_005fstruct-variable-attribute_002c-PowerPC",
 "PowerPC", 9},
+ { "ms_struct", 
"gcc/x86-Variable-Attributes.html#index-ms_005fstruct-variable-attribute_002c-x86",
 "x86", 9},
+ { "no_icf", 
"gcc/Common-Variable-Attributes.html#index-no_005ficf-variable-attribute", "", 
6},
+ { "nocommon", 
"gcc/Common-Variable-Attributes.html#index-nocommon-variable-attribute", "", 8},
+ { "noinit", 
"gcc/Common-Variable-Attributes.html#index-noinit-variable-attribute", "", 6},
+ { "nonstring", 
"gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute", "", 
9},
+ { "objc_nullability", 
"gcc/Common-Variable-Attributes.html#index-objc_005fnullability-variable-attribute",
 "", 16},
+ { "packed", 
"gcc/Common-Variable-Attributes.html#index-packed-variable-attribute", "", 6},
+ { "persistent", 
"gcc/Common-Variable-Attributes.html#index-persistent-variable-attribute", "", 
10},
+ { "progmem", 
"gcc/AVR-Variable-Attributes.html#index-progmem-variable-attribute_002c-AVR", 
"AVR", 7},
+ { "retain", 
"gcc/Common-Variable-Attributes.html#index-retain-variable-attribute", "", 6},
+ { "saddr", 
"gcc/RL78-Variable-Attributes.html#index-saddr-variable-attribute_002c-RL78", 
"RL78", 5},
+ { "sda", 
"gcc/V850-Variable-Attributes.html#index-sda-variable-attribute_002c-V850", 
"V850", 3},
+ { "section", 
"gcc/Common-Variable-Attributes.html#index-section-variable-attribute", "", 7},
+ { "selectany", 
"gcc/Microsoft-Windows-Variable-Attributes.html#index-selectany-variable-attribute",
 "", 9},
+ { "shared", 
"gcc/Microsoft-Windows-Variable-Attributes.html#index-shared-variable-attribute",
 "", 6},
+ { "shared", 
"gcc/Nvidia-PTX-Variable-Attributes.html#index-shared-variable-attribute_002c-Nvidia-PTX",
 "Nvidia PTX", 6},
+ { "strict_flex_array", 
"gcc/Common-Variable-Attributes.html#index-strict_005fflex_005farray-variable-attribute",
 "", 17},
+ { "tda", 
"gcc/V850-Variable-Attributes.html#index-tda-variable-attribute_002c-V850", 
"V850", 3},
+ { "tiny_data", 
"gcc/H8_002f300-Variable-Attributes.html#index-tiny_005fdata-variable-attribute_002c-H8_002f300",
 "H8/300", 9},
+ { "tls_model", 
"gcc/Common-Variable-Attributes.html#index-tls_005fmodel-variable-attribute", 
"", 9},
+ { "unavailable", 
"gcc/Common-Variable-Attributes.html#index-unavailable-variable-attribute", "", 
11},
+ { "uninitialized", 
"gcc/Common-Variable-Attributes.html#index-uninitialized-variable-attribute", 
"", 13},
+ { "unused", 
"gcc/Common-Variable-Attributes.html#index-unused-variable-attribute", "", 6},
+ { "upper", 
"gcc/MSP430-Variable-Attributes.html#index-upper-variable-attribute_002c-MSP430",
 "MSP430", 5},
+ { "used", 
"gcc/Common-Variable-Attributes.html#index-used-variable-attribute", "", 4},
+ { "vector_size", 
"gcc/Common-Variable-Attributes.html#index-vector_005fsize-variable-attribute", 
"", 11},
+ { "visibility", 
"gcc/Common-Variable-Attributes.html#index-visibility-variable-attribute", "", 
10},
+ { "warn_if_not_aligned", 
"gcc/Common-Variable-Attributes.html#index-warn_005fif_005fnot_005faligned-variable-attribute",
 "", 19},
+ { "weak", 
"gcc/Common-Variable-Attributes.html#index-weak-variable-attribute", "", 4},
+ { "zda", 
"gcc/V850-Variable-Attributes.html#index-zda-variable-attribute_002c-V850", 
"V850", 3},
+};
+
+static const struct attr_url_table {
+  const attr_url_entry *m_table;
+  const size_t m_table_sz;
+} attr_url_tables[] = {
+  { enumerator_attrs, ARRAY_SIZE (enumerator_attrs) },
+  { function_attrs, ARRAY_SIZE (function_attrs) },
+  { label_attrs, ARRAY_SIZE (label_attrs) },
+  { statement_attrs, ARRAY_SIZE (statement_attrs) },
+  { type_attrs, ARRAY_SIZE (type_attrs) },
+  { variable_attrs, ARRAY_SIZE (variable_attrs) },
+};
diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 1d6589835a16..a97901edb1e1 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "pretty-print-markup.h"
 #include "tree-pretty-print.h"
 #include "intl.h"
+#include "gcc-urlifier.h"
 
 /* Table of the tables of attributes (common, language, format, machine)
    searched.  */
@@ -632,6 +633,8 @@ decl_attributes (tree *node, tree attributes, int flags,
   if (!attributes_initialized)
     init_attributes ();
 
+  auto_urlify_attributes sentinel;
+
   /* If this is a function and the user used #pragma GCC optimize, add the
      options to the attribute((optimize(...))) list.  */
   if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index a1c5d0c895be..17e5cfe862a7 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimplify.h"
 #include "tree-pretty-print.h"
 #include "gcc-rich-location.h"
+#include "gcc-urlifier.h"
 
 static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
@@ -734,6 +735,8 @@ positional_argument (const_tree fn, const_tree atname, tree 
&pos,
                     tree_code code, int argno /* = 0 */,
                     int flags /* = posargflags () */)
 {
+  auto_urlify_attributes sentinel;
+
   const_tree fndecl = TYPE_P (fn) ? NULL_TREE : fn;
   const_tree fntype = TYPE_P (fn) ? fn : TREE_TYPE (fn);
   if (pos && TREE_CODE (pos) != IDENTIFIER_NODE
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 367a9b07c872..1ffc63afbd3a 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-vector-builder.h"
 #include "vec-perm-indices.h"
 #include "tree-pretty-print-markup.h"
+#include "gcc-urlifier.h"
 
 cpp_reader *parse_in;          /* Declared in c-pragma.h.  */
 
@@ -6074,8 +6075,11 @@ parse_optimize_options (tree args, bool attr_p)
                {
                  ret = false;
                  if (attr_p)
-                   warning (OPT_Wattributes,
-                            "bad option %qs to attribute %<optimize%>", p);
+                   {
+                     auto_urlify_attributes sentinel;
+                     warning (OPT_Wattributes,
+                              "bad option %qs to attribute %<optimize%>", p);
+                   }
                  else
                    warning (OPT_Wpragmas,
                             "bad option %qs to pragma %<optimize%>", p);
@@ -6124,9 +6128,12 @@ parse_optimize_options (tree args, bool attr_p)
        {
          ret = false;
          if (attr_p)
-           warning (OPT_Wattributes,
-                    "bad option %qs to attribute %<optimize%>",
-                    decoded_options[i].orig_option_with_args_text);
+           {
+             auto_urlify_attributes sentinel;
+             warning (OPT_Wattributes,
+                      "bad option %qs to attribute %<optimize%>",
+                      decoded_options[i].orig_option_with_args_text);
+           }
          else
            warning (OPT_Wpragmas,
                     "bad option %qs to pragma %<optimize%>",
@@ -6174,6 +6181,7 @@ attribute_fallthrough_p (tree attr)
   tree t = lookup_attribute ("", "fallthrough", attr);
   if (t == NULL_TREE)
     return false;
+  auto_urlify_attributes sentinel;
   /* It is no longer true that "this attribute shall appear at most once in
      each attribute-list", but we still give a warning.  */
   if (lookup_attribute ("", "fallthrough", TREE_CHAIN (t)))
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 8c94888bda0b..dc3f5fe563e6 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stor-layout.h"
 #include "tree-pretty-print.h"
 #include "langhooks.h"
+#include "gcc-urlifier.h"
 
 /* Print a warning if a constant expression had overflow in folding.
    Invoke this function on every expression that the language
@@ -2677,6 +2678,7 @@ warn_duplicated_cond_add_or_warn (location_t loc, tree 
cond, vec<tree> **chain)
 bool
 diagnose_mismatched_attributes (tree olddecl, tree newdecl)
 {
+  auto_urlify_attributes sentinel;
   bool warned = false;
 
   tree a1 = lookup_attribute ("optimize", DECL_ATTRIBUTES (olddecl));
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c58ff4ab2488..541b8ccbebdb 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "omp-general.h"
 #include "omp-offload.h"  /* For offload_vars.  */
 #include "c-parser.h"
+#include "gcc-urlifier.h"
 
 #include "tree-pretty-print.h"
 
@@ -5733,8 +5734,11 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
-    warning (OPT_Wattributes, "inline function %q+D given attribute %qs",
-            decl, "noinline");
+    {
+      auto_urlify_attributes sentinel;
+      warning (OPT_Wattributes, "inline function %q+D given attribute %qs",
+              decl, "noinline");
+    }
 
   /* C99 6.7.4p3: An inline definition of a function with external
      linkage shall not contain a definition of a modifiable object
@@ -10653,9 +10657,12 @@ start_function (struct c_declspecs *declspecs, struct 
c_declarator *declarator,
   if (DECL_DECLARED_INLINE_P (decl1)
       && DECL_UNINLINABLE (decl1)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
-    warning_at (loc, OPT_Wattributes,
-               "inline function %qD given attribute %qs",
-               decl1, "noinline");
+    {
+      auto_urlify_attributes sentinel;
+      warning_at (loc, OPT_Wattributes,
+                 "inline function %qD given attribute %qs",
+                 decl1, "noinline");
+    }
 
   /* Handle gnu_inline attribute.  */
   if (declspecs->inline_p
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index f716c567e819..1b4b16c70533 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "asan.h"
 #include "c-family/c-ubsan.h"
+#include "gcc-urlifier.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -8026,6 +8027,7 @@ c_parser_statement_after_labels (c_parser *parser, bool 
*if_p,
                  attrs = handle_assume_attribute (loc, attrs, true);
                else
                  {
+                   auto_urlify_attributes sentinel;
                    warning_at (loc, OPT_Wattributes,
                                "%<assume%> attribute not followed by %<;%>");
                    has_assume = false;
@@ -8043,17 +8045,23 @@ c_parser_statement_after_labels (c_parser *parser, bool 
*if_p,
                    c_parser_consume_token (parser);
                  }
                else
-                 warning_at (loc, OPT_Wattributes,
-                             "%<fallthrough%> attribute not followed "
-                             "by %<;%>");
+                 {
+                   auto_urlify_attributes sentinel;
+                   warning_at (loc, OPT_Wattributes,
+                               "%<fallthrough%> attribute not followed "
+                               "by %<;%>");
+                 }
              }
            else if (has_assume)
              /* Eat the ';'.  */
              c_parser_consume_token (parser);
            else if (attrs != NULL_TREE)
-             warning_at (loc, OPT_Wattributes,
-                         "only attribute %<fallthrough%> or %<assume%> can "
-                         "be applied to a null statement");
+             {
+               auto_urlify_attributes sentinel;
+               warning_at (loc, OPT_Wattributes,
+                           "only attribute %<fallthrough%> or %<assume%> can "
+                           "be applied to a null statement");
+             }
            break;
          }
        default:
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index dd6caf642aaa..8960c55aef3b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "asan.h"
 #include "realmpfr.h"
 #include "tree-pretty-print-markup.h"
+#include "gcc-urlifier.h"
 
 /* Possible cases of implicit conversions.  Used to select diagnostic messages
    and control folding initializers in convert_for_assignment.  */
@@ -6394,6 +6395,7 @@ maybe_warn_nodiscard (location_t loc, tree expr)
       if (args)
        args = TREE_VALUE (args);
       auto_diagnostic_group d;
+      auto_urlify_attributes sentinel;
       int warned;
       if (args)
        warned = warning_at (loc, OPT_Wunused_result,
@@ -6416,6 +6418,7 @@ maybe_warn_nodiscard (location_t loc, tree expr)
       if (args)
        args = TREE_VALUE (args);
       auto_diagnostic_group d;
+      auto_urlify_attributes sentinel;
       int warned;
       if (args)
        warned = warning_at (loc, OPT_Wunused_result,
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 3b95ac50bbc8..e1b0ced138a0 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31765,6 +31765,9 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
 #define TARGET_MANGLE_DECL_ASSEMBLER_NAME aarch64_mangle_decl_assembler_name
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "AArch64"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-aarch64.h"
diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index 95d3285a5859..be5a3b77a012 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -11574,6 +11574,9 @@ arc_libm_function_max_error (unsigned cfn, machine_mode 
mode,
 #undef  TARGET_LIBM_FUNCTION_MAX_ERROR
 #define TARGET_LIBM_FUNCTION_MAX_ERROR arc_libm_function_max_error
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "ARC"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-arc.h"
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index fd7b4dc14beb..79ed6687bb49 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -36096,6 +36096,9 @@ arm_mode_base_reg_class (machine_mode mode)
   return MODE_BASE_REG_REG_CLASS (mode);
 }
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "ARM"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Implement TARGET_VECTORIZE_GET_MASK_MODE.  */
diff --git a/gcc/config/bfin/bfin.cc b/gcc/config/bfin/bfin.cc
index 13d2e10e3203..2d0de83afa87 100644
--- a/gcc/config/bfin/bfin.cc
+++ b/gcc/config/bfin/bfin.cc
@@ -5881,4 +5881,7 @@ bfin_conditional_register_usage (void)
 #undef TARGET_CONSTANT_ALIGNMENT
 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "Blackfin"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index aa00d149c4d3..a17e1ae18877 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1450,6 +1450,9 @@ bpf_expand_setmem (rtx *operands)
   return true;
 }
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "BPF"
+
 /* Finally, build the GCC target.  */
 
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc
index 56e7cf9d7dc4..de0a7ad0345a 100644
--- a/gcc/config/epiphany/epiphany.cc
+++ b/gcc/config/epiphany/epiphany.cc
@@ -3045,4 +3045,7 @@ epiphany_starting_frame_offset (void)
   return epiphany_stack_offset;
 }
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "Epiphany"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index d078392eeaf1..8fce1c9234ac 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -7935,6 +7935,9 @@ gcn_dwarf_register_span (rtx rtl)
 #undef  TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P gcn_vector_mode_supported_p
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "AMD GCN"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-gcn.h"
diff --git a/gcc/config/h8300/h8300.cc b/gcc/config/h8300/h8300.cc
index 17c6e911f4c3..da8dd87372c9 100644
--- a/gcc/config/h8300/h8300.cc
+++ b/gcc/config/h8300/h8300.cc
@@ -5736,4 +5736,7 @@ pre_incdec_with_reg (rtx op, unsigned int reg)
 #undef TARGET_C_MODE_FOR_FLOATING_TYPE
 #define TARGET_C_MODE_FOR_FLOATING_TYPE h8300_c_mode_for_floating_type
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "H8/300"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index c7e70c21999e..d3fd524d699b 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -27360,6 +27360,9 @@ ix86_cannot_copy_insn_p (rtx_insn *insn)
 #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
 #endif /* #if CHECKING_P */
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "x86"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-i386.h"
diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
index 4acbd82bc65c..51226f33e8ce 100644
--- a/gcc/config/ia64/ia64.cc
+++ b/gcc/config/ia64/ia64.cc
@@ -686,6 +686,9 @@ static const scoped_attribute_specs *const 
ia64_attribute_table[] =
 #undef TARGET_CONSTANT_ALIGNMENT
 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "IA-64"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
diff --git a/gcc/config/m32c/m32c.cc b/gcc/config/m32c/m32c.cc
index d27538ebb6b7..5922f7a62e11 100644
--- a/gcc/config/m32c/m32c.cc
+++ b/gcc/config/m32c/m32c.cc
@@ -4501,6 +4501,9 @@ m32c_output_compare (rtx_insn *insn, rtx *operands)
 #undef TARGET_CAN_CHANGE_MODE_CLASS
 #define TARGET_CAN_CHANGE_MODE_CLASS m32c_can_change_mode_class
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "M32C"
+
 /* The Global `targetm' Variable. */
 
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/m32r/m32r.cc b/gcc/config/m32r/m32r.cc
index 4742cebc8127..f1dd909502a3 100644
--- a/gcc/config/m32r/m32r.cc
+++ b/gcc/config/m32r/m32r.cc
@@ -227,6 +227,9 @@ TARGET_GNU_ATTRIBUTES (m32r_attribute_table,
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "M32R/D"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Called by m32r_option_override to initialize various things.  */
diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc
index d642bcb52bb7..050ac096e55f 100644
--- a/gcc/config/m68k/m68k.cc
+++ b/gcc/config/m68k/m68k.cc
@@ -382,6 +382,9 @@ TARGET_GNU_ATTRIBUTES (m68k_attribute_table,
     m68k_handle_fndecl_attribute, NULL }
 });
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "m68k"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Base flags for 68k ISAs.  */
diff --git a/gcc/config/mcore/mcore.cc b/gcc/config/mcore/mcore.cc
index 99c0a6cb0c68..455679f2f0fc 100644
--- a/gcc/config/mcore/mcore.cc
+++ b/gcc/config/mcore/mcore.cc
@@ -255,6 +255,9 @@ TARGET_GNU_ATTRIBUTES (mcore_attribute_table,
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "MCORE"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Adjust the stack and return the number of bytes taken to do it.  */
diff --git a/gcc/config/microblaze/microblaze.cc 
b/gcc/config/microblaze/microblaze.cc
index c03696990a56..b1c172374780 100644
--- a/gcc/config/microblaze/microblaze.cc
+++ b/gcc/config/microblaze/microblaze.cc
@@ -4070,6 +4070,9 @@ microblaze_starting_frame_offset (void)
 #undef TARGET_STARTING_FRAME_OFFSET
 #define TARGET_STARTING_FRAME_OFFSET microblaze_starting_frame_offset
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "MicroBlaze"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-microblaze.h"
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 392755316eb3..54f810e5c20e 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -23625,6 +23625,9 @@ mips_bit_clear_p (enum machine_mode mode, unsigned 
HOST_WIDE_INT m)
 #undef TARGET_C_MODE_FOR_FLOATING_TYPE
 #define TARGET_C_MODE_FOR_FLOATING_TYPE mips_c_mode_for_floating_type
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "MIPS"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-mips.h"
diff --git a/gcc/config/msp430/msp430.cc b/gcc/config/msp430/msp430.cc
index 21be7f1e6e13..4299111507c1 100644
--- a/gcc/config/msp430/msp430.cc
+++ b/gcc/config/msp430/msp430.cc
@@ -4516,6 +4516,9 @@ msp430_can_change_mode_class (machine_mode from, 
machine_mode to, reg_class_t)
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "MSP430"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-msp430.h"
diff --git a/gcc/config/nds32/nds32.cc b/gcc/config/nds32/nds32.cc
index f5ea1daad404..a9b359c37a61 100644
--- a/gcc/config/nds32/nds32.cc
+++ b/gcc/config/nds32/nds32.cc
@@ -5881,6 +5881,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode,
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "NDS32"
+
 
 /* ------------------------------------------------------------------------ */
 
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 3072d3729a89..3c79fc8190f1 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -7816,6 +7816,9 @@ nvptx_asm_output_def_from_decls (FILE *stream, tree name,
 #undef TARGET_HAVE_STRUB_SUPPORT_FOR
 #define TARGET_HAVE_STRUB_SUPPORT_FOR hook_bool_tree_false
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "Nvidia PTX"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-nvptx.h"
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index b423344d4d6b..8b2a0423d383 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13853,6 +13853,9 @@ riscv_use_by_pieces_infrastructure_p (unsigned 
HOST_WIDE_INT size,
 #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
   riscv_get_function_versions_dispatcher
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "RISC-V"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-riscv.h"
diff --git a/gcc/config/rl78/rl78.cc b/gcc/config/rl78/rl78.cc
index 8ce9331d2fba..964137e7ac4e 100644
--- a/gcc/config/rl78/rl78.cc
+++ b/gcc/config/rl78/rl78.cc
@@ -4993,6 +4993,9 @@ rl78_c_mode_for_floating_type (enum tree_index ti)
 #undef TARGET_HAVE_STRUB_SUPPORT_FOR
 #define TARGET_HAVE_STRUB_SUPPORT_FOR hook_bool_tree_false
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "RL78"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-rl78.h"
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index fa0e2ce8eea5..97bdbae78956 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -29288,6 +29288,9 @@ rs6000_opaque_type_invalid_use_p (gimple *stmt)
   return false;
 }
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "PowerPC"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-rs6000.h"
diff --git a/gcc/config/rx/rx.cc b/gcc/config/rx/rx.cc
index 00242e8a19df..daf03ca8fa55 100644
--- a/gcc/config/rx/rx.cc
+++ b/gcc/config/rx/rx.cc
@@ -3821,6 +3821,9 @@ rx_c_mode_for_floating_type (enum tree_index ti)
 #undef TARGET_C_MODE_FOR_FLOATING_TYPE
 #define TARGET_C_MODE_FOR_FLOATING_TYPE rx_c_mode_for_floating_type
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "RX"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-rx.h"
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 874b11274a43..2207e60cdaf9 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -18568,6 +18568,9 @@ s390_c_mode_for_floating_type (enum tree_index ti)
 #undef TARGET_C_MODE_FOR_FLOATING_TYPE
 #define TARGET_C_MODE_FOR_FLOATING_TYPE s390_c_mode_for_floating_type
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "S/390"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-s390.h"
diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index 663c99085fcf..43c56b1956dd 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -668,6 +668,9 @@ TARGET_GNU_ATTRIBUTES (sh_attribute_table,
 #undef TARGET_C_MODE_FOR_FLOATING_TYPE
 #define TARGET_C_MODE_FOR_FLOATING_TYPE sh_c_mode_for_floating_type
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "SH"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
diff --git a/gcc/config/stormy16/stormy16.cc b/gcc/config/stormy16/stormy16.cc
index d04af9a752d0..5b360255e226 100644
--- a/gcc/config/stormy16/stormy16.cc
+++ b/gcc/config/stormy16/stormy16.cc
@@ -2915,6 +2915,9 @@ xstormy16_push_rounding (poly_int64 bytes)
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "Xstormy16"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-stormy16.h"
diff --git a/gcc/config/v850/v850.cc b/gcc/config/v850/v850.cc
index b39343c6ff48..2ac58c08691c 100644
--- a/gcc/config/v850/v850.cc
+++ b/gcc/config/v850/v850.cc
@@ -3336,6 +3336,8 @@ v850_can_inline_p (tree caller, tree callee)
 #undef TARGET_CAN_INLINE_P
 #define TARGET_CAN_INLINE_P v850_can_inline_p
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "V850"
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
diff --git a/gcc/config/visium/visium.cc b/gcc/config/visium/visium.cc
index 0368a0f40de2..6cc93dccfd2f 100644
--- a/gcc/config/visium/visium.cc
+++ b/gcc/config/visium/visium.cc
@@ -373,6 +373,9 @@ static HOST_WIDE_INT visium_constant_alignment (const_tree, 
HOST_WIDE_INT);
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_DOCUMENTATION_NAME
+#define TARGET_DOCUMENTATION_NAME "Visium"
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 namespace {
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 68f651e96051..f1aad01effc9 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "omp-general.h"
 #include "opts.h"
+#include "gcc-urlifier.h"
 
 /* Keep track of forward references to immediate-escalating functions in
    case they become consteval.  This vector contains ADDR_EXPRs and
@@ -3625,8 +3626,11 @@ process_stmt_hotness_attribute (tree std_attrs, 
location_t attrs_loc)
       SET_EXPR_LOCATION (pred, attrs_loc);
       add_stmt (pred);
       if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
-       warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
-                get_attribute_name (other), name);
+       {
+         auto_urlify_attributes sentinel;
+         warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
+                  get_attribute_name (other), name);
+       }
       std_attrs = remove_hotness_attribute (std_attrs);
     }
   return std_attrs;
diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index 75e7f0607163..a4007c70daa8 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "escaped_string.h"
+#include "gcc-urlifier.h"
 
 static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
 static tree build_type_conversion (tree, tree);
@@ -1092,6 +1093,7 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
                "declared with attribute %<nodiscard%>%s"));
       const char *raw_msg = msg ? (const char *) msg : "";
       auto_diagnostic_group d;
+      auto_urlify_attributes sentinel;
       if (warning_at (loc, OPT_Wunused_result, format, fn, raw_msg))
        inform (DECL_SOURCE_LOCATION (fn), "declared here");
     }
@@ -1110,6 +1112,7 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
                "declared with attribute %<nodiscard%>%s"));
       const char *raw_msg = msg ? (const char *) msg : "";
       auto_diagnostic_group d;
+      auto_urlify_attributes sentinel;
       if (warning_at (loc, OPT_Wunused_result, format, rettype, raw_msg))
        {
          if (fn)
@@ -1124,6 +1127,7 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
     {
       /* The TARGET_EXPR confuses do_warn_unused_result into thinking that the
         result is used, so handle that case here.  */
+      auto_urlify_attributes sentinel;
       if (fn)
        {
          auto_diagnostic_group d;
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 1ed1113f9e39..f4a305932855 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -61,6 +61,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts.h"
 #include "langhooks-def.h"  /* For lhd_simulate_record_decl  */
 #include "coroutines.h"
+#include "gcc-urlifier.h"
 
 /* Possible cases of bad specifiers type used by bad_specifiers. */
 enum bad_spec_place {
@@ -6023,8 +6024,11 @@ start_decl (const cp_declarator *declarator,
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
-    warning_at (DECL_SOURCE_LOCATION (decl), 0,
-               "inline function %qD given attribute %qs", decl, "noinline");
+    {
+      auto_urlify_attributes sentinel;
+      warning_at (DECL_SOURCE_LOCATION (decl), 0,
+                 "inline function %qD given attribute %qs", decl, "noinline");
+    }
 
   if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
     {
@@ -18046,8 +18050,11 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
 
   if (DECL_DECLARED_INLINE_P (decl1)
       && lookup_attribute ("noinline", attrs))
-    warning_at (DECL_SOURCE_LOCATION (decl1), 0,
-               "inline function %qD given attribute %qs", decl1, "noinline");
+    {
+      auto_urlify_attributes sentinel;
+      warning_at (DECL_SOURCE_LOCATION (decl1), 0,
+                 "inline function %qD given attribute %qs", decl1, "noinline");
+    }
 
   /* Handle gnu_inline attribute.  */
   if (GNU_INLINE_P (decl1))
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index cc642b017d22..32424f64d816 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -588,6 +588,14 @@ diagnostic_context::set_prefixing_rule 
(diagnostic_prefixing_rule_t rule)
       pp_prefixing_rule (sink->get_printer ()) = rule;
 }
 
+/* Set the urlifier without deleting the existing one.  */
+
+void
+diagnostic_context::override_urlifier (urlifier *urlifier)
+{
+  m_urlifier = urlifier;
+}
+
 void
 diagnostic_context::create_edit_context ()
 {
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index f32d404c7a4d..0197f7987a60 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -615,6 +615,7 @@ public:
   void set_text_art_charset (enum diagnostic_text_art_charset charset);
   void set_client_data_hooks (std::unique_ptr<diagnostic_client_data_hooks> 
hooks);
   void set_urlifier (std::unique_ptr<urlifier>);
+  void override_urlifier (urlifier *);
   void create_edit_context ();
   void set_warning_as_error_requested (bool val)
   {
@@ -672,6 +673,7 @@ public:
     return m_client_data_hooks;
   }
   urlifier *get_urlifier () const { return m_urlifier; }
+
   text_art::theme *get_diagram_theme () const { return m_diagrams.m_theme; }
 
   int &diagnostic_count (diagnostic_t kind)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 59644606261c..c134ecb7b2ca 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6235,7 +6235,7 @@ named @var{name}.
 These function attributes are supported by the Nvidia PTX back end:
 
 @table @code
-@cindex @code{kernel} attribute, Nvidia PTX
+@cindex @code{kernel} function attribute, Nvidia PTX
 @item kernel
 This attribute indicates that the corresponding function should be compiled
 as a kernel function, which can be invoked from the host via the CUDA RT 
@@ -8886,7 +8886,7 @@ will be used, and the @code{.lower} prefix will not be 
added.
 These variable attributes are supported by the Nvidia PTX back end:
 
 @table @code
-@cindex @code{shared} attribute, Nvidia PTX
+@cindex @code{shared} variable attribute, Nvidia PTX
 @item shared
 Use this attribute to place a variable in the @code{.shared} memory space.
 This memory space is private to each cooperative thread array; only threads
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 109e40384b68..02d27d2a0ed1 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -12836,3 +12836,8 @@ This value is true if the target platform supports
 This value is true if the target platform supports
 libatomic.  The default value is false.
 @end deftypevr
+
+@deftypevr {Target Hook} {const char *} TARGET_DOCUMENTATION_NAME
+If non-NULL, this value is a string used for locating target-specific 
documentation for this target.
+The default value is NULL.
+@end deftypevr
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 93bcd747e374..f7d3c6d1126e 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -8131,3 +8131,5 @@ maintainer is familiar with.
 @hook TARGET_HAVE_SHADOW_CALL_STACK
 
 @hook TARGET_HAVE_LIBATOMIC
+
+@hook TARGET_DOCUMENTATION_NAME
diff --git a/gcc/gcc-attribute-urlifier.cc b/gcc/gcc-attribute-urlifier.cc
new file mode 100644
index 000000000000..66903155fa72
--- /dev/null
+++ b/gcc/gcc-attribute-urlifier.cc
@@ -0,0 +1,243 @@
+/* Automatic generation of links into GCC's documentation.
+   Copyright (C) 2023-2024 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalc...@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#define INCLUDE_MEMORY
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "pretty-print.h"
+#include "pretty-print-urlifier.h"
+#include "gcc-urlifier.h"
+#include "opts.h"
+#include "options.h"
+#include "diagnostic.h"
+#include "selftest.h"
+#include "make-unique.h"
+#include "target.h"
+
+/* class attribute_urlifier : public urlifier.  */
+
+/* By default, use the target's documentation name.  */
+
+attribute_urlifier::attribute_urlifier ()
+: m_target_docs_name (targetm.documentation_name)
+{
+}
+
+/* Explicitly specify a target's documentation name, for use in selftests.  */
+
+attribute_urlifier::attribute_urlifier (const char *target_docs_name)
+: m_target_docs_name (target_docs_name)
+{
+}
+
+struct attr_url_entry
+{
+  const char *m_name;
+  const char *m_url_suffix;
+  const char *m_target_docs_name;
+  size_t m_name_len;
+};
+
+#include "attr-urls.def"
+
+/* We look in two passes: first for an exact match on target name (if any).
+   Otherwise, we look for one with an empty target name.  */
+
+/* Search for STR, LEN in the given TABLE.
+   If TARGET_DOCS_NAME is non-null, then look for an exact match on target 
name.
+   If TARGET_DOCS_NAME is null, then look for an empty string for the
+   target name.  */
+
+
+static const attr_url_entry *
+find_attr_url_entry (const char *str,
+                    size_t str_len,
+                    const char *target_docs_name,
+                    const attr_url_entry *table,
+                    size_t table_sz)
+{
+  /* This is linear search, but TABLE_SZ ought not to be very large.  */
+  for (size_t i = 0; i < table_sz; i++)
+    if (str_len == table[i].m_name_len)
+      if (0 == strncmp (str, table[i].m_name, str_len))
+       {
+         if (target_docs_name)
+           {
+             /* Reject entries with m_target_docs_name that doesn't match.  */
+             if (strcmp (target_docs_name, table[i].m_target_docs_name))
+               continue;
+           }
+         else
+           {
+             /* Reject entries for which m_target_docs_name is non-empty.  */
+             if (table[i].m_target_docs_name[0])
+               continue;
+           }
+         return &table[i];
+       }
+
+  return nullptr;
+}
+
+/* Search for STR, LEN in all of the attribute tables, in order.
+   TARGET_DOCS_NAME works as above.  */
+
+static const attr_url_entry *
+find_attr_url_entry (const char *str,
+                    size_t str_len,
+                    const char *target_docs_name)
+{
+  for (size_t table_idx = 0; table_idx < ARRAY_SIZE (attr_url_tables);
+       table_idx++)
+    if (const attr_url_entry *entry
+         = find_attr_url_entry (str, str_len, target_docs_name,
+                                attr_url_tables[table_idx].m_table,
+                                attr_url_tables[table_idx].m_table_sz))
+      return entry;
+
+  return nullptr;
+}
+
+char *
+attribute_urlifier::get_url_for_quoted_text (const char *p,
+                                            size_t sz) const
+{
+  label_text url_suffix = get_url_suffix_for_quoted_text (p, sz);
+  if (url_suffix.get ())
+    return make_doc_url (url_suffix.get ());
+  return nullptr;
+}
+
+label_text
+attribute_urlifier::get_url_suffix_for_quoted_text (const char *p,
+                                                   size_t sz) const
+{
+  /* Skip any text after a non-identifier character, so that
+     e.g. given "access(read_write, 2, 3)" we only compare
+     against "access".  */
+  for (size_t i = 0; i < sz; i++)
+    if (!ISIDNUM (p[i]))
+      {
+       /* Truncate to p[0..i).  */
+       sz = i;
+       break;
+      }
+
+  if (m_target_docs_name)
+    if (const attr_url_entry *entry
+         = find_attr_url_entry (p, sz, m_target_docs_name))
+      return label_text::borrow (entry->m_url_suffix);
+
+  if (const attr_url_entry *entry = find_attr_url_entry (p, sz, nullptr))
+    return label_text::borrow (entry->m_url_suffix);
+
+  return label_text ();
+}
+
+label_text
+attribute_urlifier::get_url_suffix_for_quoted_text (const char *p) const
+{
+  return get_url_suffix_for_quoted_text (p, strlen (p));
+}
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Selftests.  */
+
+static void
+test_attribute_urlifier ()
+{
+  attribute_urlifier u;
+
+  ASSERT_EQ (u.get_url_suffix_for_quoted_text ("").get (), nullptr);
+  ASSERT_EQ (u.get_url_suffix_for_quoted_text (")").get (), nullptr);
+
+  /* Examples of function attributes.  */
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("alias").get (),
+               "gcc/Common-Function-Attributes.html"
+               "#index-alias-function-attribute");
+
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text
+                 ("access(read_write, 2, 3)").get (),
+               "gcc/Common-Function-Attributes.html"
+               "#index-access-function-attribute");
+
+  /* Example of enumerator attribute.  */
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("deprecated").get (),
+               "gcc/Enumerator-Attributes.html"
+               "#index-deprecated-enumerator-attribute");
+
+  /* We don't yet have an example of a label attribute, since all
+     label attributes have a matching function attribute of the same
+     name, which is found first.  */
+
+  /* Example of statement attribute.  */
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("assume").get (),
+               "gcc/Statement-Attributes.html"
+               "#index-assume-statement-attribute");
+
+  /* Examples of type attributes.  */
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("hardbool").get (),
+               "gcc/Common-Type-Attributes.html"
+               "#index-hardbool-type-attribute");
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text
+                 ("packed").get (),
+               "gcc/Common-Type-Attributes.html"
+               "#index-packed-type-attribute");
+
+  /* Example of variable attribute.  */
+  ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("nonstring").get (),
+               "gcc/Common-Variable-Attributes.html"
+               "#index-nonstring-variable-attribute");
+
+  /* Example of target-specific attributes.
+     For example, "interrupt" has many target-specific documentation URLs.  */
+  {
+    attribute_urlifier u_rl78 ("RL78");
+    attribute_urlifier u_x86 ("x86");
+    attribute_urlifier u_unrecognized ("not-a-target");
+
+    ASSERT_STREQ (u_rl78.get_url_suffix_for_quoted_text ("interrupt").get (),
+                 "gcc/RL78-Function-Attributes.html"
+                 "#index-interrupt-function-attribute_002c-RL78");
+    ASSERT_STREQ (u_x86.get_url_suffix_for_quoted_text ("interrupt").get (),
+                 "gcc/x86-Function-Attributes.html"
+                 "#index-interrupt-function-attribute_002c-x86");
+    ASSERT_STREQ (u_unrecognized.get_url_suffix_for_quoted_text
+                   ("interrupt").get (),
+                 "gcc/Common-Function-Attributes.html"
+                 "#index-interrupt-function-attribute");
+  }
+}
+
+/* Run all of the selftests within this file.  */
+
+void
+gcc_attribute_urlifier_cc_tests ()
+{
+  test_attribute_urlifier ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/gcc-urlifier.cc b/gcc/gcc-urlifier.cc
index 0db5429395eb..12e002337903 100644
--- a/gcc/gcc-urlifier.cc
+++ b/gcc/gcc-urlifier.cc
@@ -27,9 +27,19 @@ along with GCC; see the file COPYING3.  If not see
 #include "gcc-urlifier.h"
 #include "opts.h"
 #include "options.h"
+#include "diagnostic.h"
 #include "selftest.h"
 #include "make-unique.h"
 
+char *
+make_doc_url (const char *doc_url_suffix)
+{
+  if (!doc_url_suffix)
+    return nullptr;
+
+  return concat (DOCUMENTATION_ROOT_URL, doc_url_suffix, nullptr);
+}
+
 namespace {
 
 /* Concrete subclass of urlifier for generating links into
@@ -51,9 +61,6 @@ public:
 private:
   label_text get_url_suffix_for_option (const char *p, size_t sz) const;
 
-  static char *
-  make_doc_url (const char *doc_url_suffix);
-
   unsigned int m_lang_mask;
 };
 
@@ -204,15 +211,6 @@ gcc_urlifier::get_url_suffix_for_option (const char *p, 
size_t sz) const
   return get_option_url_suffix (opt, m_lang_mask);
 }
 
-char *
-gcc_urlifier::make_doc_url (const char *doc_url_suffix)
-{
-  if (!doc_url_suffix)
-    return nullptr;
-
-  return concat (DOCUMENTATION_ROOT_URL, doc_url_suffix, nullptr);
-}
-
 } // anonymous namespace
 
 std::unique_ptr<urlifier>
@@ -221,16 +219,27 @@ make_gcc_urlifier (unsigned int lang_mask)
   return ::make_unique<gcc_urlifier> (lang_mask);
 }
 
+/* class auto_override_urlifier.  */
+
+auto_override_urlifier::auto_override_urlifier (urlifier *new_urlifier)
+: m_old_urlifier (global_dc->get_urlifier ())
+{
+  global_dc->override_urlifier (new_urlifier);
+}
+
+auto_override_urlifier::~auto_override_urlifier ()
+{
+  global_dc->override_urlifier (m_old_urlifier);
+}
+
 #if CHECKING_P
 
 namespace selftest {
 
 /* Selftests.  */
 
-/* Run all of the selftests within this file.  */
-
-void
-gcc_urlifier_cc_tests ()
+static void
+test_gcc_urlifier ()
 {
   /* Check that doc_urls.quoted_text is sorted.  */
   for (size_t idx = 1; idx < ARRAY_SIZE (doc_urls); idx++)
@@ -264,6 +273,14 @@ gcc_urlifier_cc_tests ()
                "gcc/Optimize-Options.html#index-finline");
 }
 
+/* Run all of the selftests within this file.  */
+
+void
+gcc_urlifier_cc_tests ()
+{
+  test_gcc_urlifier ();
+}
+
 } // namespace selftest
 
 #endif /* #if CHECKING_P */
diff --git a/gcc/gcc-urlifier.h b/gcc/gcc-urlifier.h
index c4cd03cc34ae..1262bf5c190f 100644
--- a/gcc/gcc-urlifier.h
+++ b/gcc/gcc-urlifier.h
@@ -21,6 +21,63 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_GCC_URLIFIER_H
 #define GCC_GCC_URLIFIER_H
 
+#include "pretty-print-urlifier.h"
+#include "label-text.h"
+
 extern std::unique_ptr<urlifier> make_gcc_urlifier (unsigned int lang_mask);
+extern char *make_doc_url (const char *doc_url_suffix);
+
+/* RAII class to temporarily override global_dc's urlifier
+   with another one (possibly nullptr).  */
+
+class auto_override_urlifier
+{
+public:
+  auto_override_urlifier (urlifier *new_urlifier);
+  ~auto_override_urlifier ();
+
+protected:
+  urlifier * const m_old_urlifier;
+};
+
+/* Subclass of urlifier that attempts to add URLs to quoted strings
+   containing names of attributes.  */
+
+class attribute_urlifier : public urlifier
+{
+public:
+  attribute_urlifier ();
+  attribute_urlifier (const char *target_docs_name);
+
+  char *
+  get_url_for_quoted_text (const char *p, size_t sz) const final override;
+
+  label_text
+  get_url_suffix_for_quoted_text (const char *p, size_t sz) const;
+
+  /* We use ATTRIBUTE_UNUSED as this helper is called only from ASSERTs.  */
+  label_text
+  get_url_suffix_for_quoted_text (const char *p) const ATTRIBUTE_UNUSED;
+
+private:
+  const char *m_target_docs_name;
+};
+
+/* RAII class: during the lifetime of instances, global_dc will attempt
+   to auto-generate documentation links for any attributes mentioned in
+   quotes in diagnostics .  */
+
+class auto_urlify_attributes
+{
+public:
+  auto_urlify_attributes ()
+  : m_override (&m_urlifier)
+  {
+  }
+
+private:
+  attribute_urlifier m_urlifier;
+  auto_override_urlifier m_override;
+};
 
 #endif /* GCC_GCC_URLIFIER_H */
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 902bb70de031..5964184182e4 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -57,6 +57,7 @@
 #include "attr-fnspec.h"
 #include "pointer-query.h"
 #include "pretty-print-markup.h"
+#include "gcc-urlifier.h"
 
 /* Return true if tree node X has an associated location.  */
 
@@ -4749,6 +4750,8 @@ pass_waccess::check_call_dangling (gcall *call)
 unsigned
 pass_waccess::execute (function *fun)
 {
+  auto_urlify_attributes sentinel;
+
   calculate_dominance_info (CDI_DOMINATORS);
   calculate_dominance_info (CDI_POST_DOMINATORS);
 
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 0899b279513a..245bb4336606 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -71,6 +71,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "omp-offload.h"
 #include "context.h"
 #include "tree-nested.h"
+#include "gcc-urlifier.h"
 
 /* Identifier for a basic condition, mapping it to other basic conditions of
    its Boolean expression.  Basic conditions given the same uid (in the same
@@ -2913,6 +2914,8 @@ expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool 
*handled_ops_p,
 static void
 expand_FALLTHROUGH (gimple_seq *seq_p)
 {
+  auto_urlify_attributes sentinel;
+
   struct walk_stmt_info wi;
   location_t loc[2];
   memset (&wi, 0, sizeof (wi));
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index a45b32918000..ec3721546026 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
@@ -55,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "fold-const-call.h"
 #include "tree-ssa-live.h"
 #include "tree-outof-ssa.h"
+#include "gcc-urlifier.h"
 
 /* For lang_hooks.types.type_for_mode.  */
 #include "langhooks.h"
@@ -887,6 +889,7 @@ expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
 static void
 expand_FALLTHROUGH (internal_fn, gcall *call)
 {
+  auto_urlify_attributes sentinel;
   error_at (gimple_location (call),
            "invalid use of attribute %<fallthrough%>");
 }
diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
index 52b88f2535fc..a2bbe0aef6ed 100644
--- a/gcc/ipa-pure-const.cc
+++ b/gcc/ipa-pure-const.cc
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-fnsummary.h"
 #include "symtab-thunks.h"
 #include "dbgcnt.h"
+#include "gcc-urlifier.h"
 
 /* Lattice values for const and pure functions.  Everything starts out
    being const, then may drop to pure and then neither depending on
@@ -216,6 +217,7 @@ suggest_attribute (diagnostic_option_id option, tree decl, 
bool known_finite,
   if (warned_about->contains (decl))
     return warned_about;
   warned_about->add (decl);
+  auto_urlify_attributes sentinel;
   warning_at (DECL_SOURCE_LOCATION (decl),
              option,
              known_finite
diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
index 6dbef204de60..02e7df548f14 100644
--- a/gcc/ipa-strub.cc
+++ b/gcc/ipa-strub.cc
@@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "symtab-thunks.h"
 #include "attr-fnspec.h"
 #include "target.h"
+#include "gcc-urlifier.h"
 
 /* This file introduces two passes that, together, implement
    machine-independent stack scrubbing, strub for short.  It arranges
@@ -676,6 +677,8 @@ can_strub_p (cgraph_node *node, bool report = false)
   if (!report && (!result || strub_always_inline_p (node)))
     return result;
 
+  auto_urlify_attributes sentinel;
+
   if (flag_split_stack)
     {
       result = false;
diff --git a/gcc/regenerate-attr-urls.py b/gcc/regenerate-attr-urls.py
new file mode 100755
index 000000000000..04a04b863507
--- /dev/null
+++ b/gcc/regenerate-attr-urls.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2023-2024 Free Software Foundation, Inc.
+#
+# Script to regenerate attr-urls.def from generated HTML.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.  */
+
+DESCRIPTION = """
+Parses the generated HTML (from "make html") to locate anchors
+for attributes, and generates a gcc/attr-urls.def file in the source tree,
+giving URLs for each attribute, where it can.
+
+Usage (from build/gcc subdirectory):
+  ../../src/gcc/regenerate-attr-urls.py HTML/gcc-15.0.0/ ../../src
+
+To run unit tests:
+  ../../src/gcc/regenerate-attr-urls.py HTML/gcc-15.0.0/ ../../src --unit-test
+"""
+
+import argparse
+import json
+import os
+from pathlib import Path
+from pprint import pprint
+import sys
+import re
+import unittest
+
+class Index:
+    def __init__(self):
+        self.entries = []
+        self.entries_by_kind = {}
+
+    def add_entry(self, url_suffix, name, kind, extra_text, verbose=False):
+        #if len(self.entries) > 5:
+        #    return
+        self.entries.append( (url_suffix, name, kind, extra_text) )
+
+        if kind in self.entries_by_kind:
+            by_kind = self.entries_by_kind[kind]
+        else:
+            by_kind = []
+            self.entries_by_kind[kind] = by_kind
+        by_kind.append( (name, url_suffix, extra_text) )
+
+    def parse_attribute_index(self, input_filename, verbose=False):
+        with open(input_filename) as f:
+            for line in f:
+                self.parse_html_line_attribute_index(line, verbose)
+
+    def parse_html_line_attribute_index(self, line, verbose=False):
+        if verbose:
+            print(repr(line))
+
+        # Update for this in the GCC website's bin/preprocess 
process_html_file:
+        #   | sed -e 's/_002d/-/g' -e 's/_002a/*/g' \
+        line = line.replace('_002d', '-')
+        line = line.replace('_002a', '*')
+
+        # e.g. <a 
href="Common-Function-Attributes.html#index-access-function-attribute"><code>access</code>
 function attribute</a>
+        # e.g. <a 
href="MIPS-Function-Attributes.html#index-nocompression-function-attribute_002c-MIPS"><code
 class="code">nocompression</code> function attribute, MIPS</a>
+        m = re.search(r'<a href="([\S]+)"><code[^>]*>([\S]+)</code> (\S+) 
attribute([^<]*)</a>', line)
+        if not m:
+            return
+        if verbose:
+            print(m.groups())
+
+        url_suffix, name, kind, extra_text = m.groups()
+
+        if extra_text.startswith(', '):
+            extra_text = extra_text[2:]
+
+        # Reject anchors where the name contains a paren
+        # e.g. 'target(&quot;3dnowa&quot;)':
+        if '(' in name:
+            return
+
+        self.add_entry(url_suffix, name, kind, extra_text)
+
+    def generate_file(self, dstpath):
+        with open(dstpath, 'w') as outf:
+            self.write_file(outf)
+
+    def write_file(self, outf):
+        outf.write("/* Autogenerated by regenerate-attr-urls.py.  */\n\n")
+
+        for kind in sorted(self.entries_by_kind.keys()):
+            by_kind = self.entries_by_kind[kind]
+            outf.write("const attr_url_entry %s_attrs[] = {\n" % kind)
+            for name, url_suffix, extra_text in 
sorted(self.entries_by_kind[kind]):
+                outf.write(' { "%s", "gcc/%s", "%s", %i},\n'
+                           % (name, url_suffix, extra_text, len(name)))
+            outf.write("};\n\n")
+
+        outf.write('static const struct attr_url_table {\n')
+        outf.write('  const attr_url_entry *m_table;\n')
+        outf.write('  const size_t m_table_sz;\n')
+        outf.write('} attr_url_tables[] = {\n')
+        for kind in sorted(self.entries_by_kind.keys()):
+            outf.write("  { %s_attrs, ARRAY_SIZE (%s_attrs) },\n" % (kind, 
kind))
+        outf.write("};\n")
+
+INDEX_REL_PATH = 'gcc/Concept-and-Symbol-Index.html'
+
+class TestParsingIndex(unittest.TestCase):
+    def test_function_attribute(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="Common-Function-Attributes.html#index-access-function-attribute"><code>access</code>
 function attribute</a>')
+        self.assertEqual(index.entries, 
[('Common-Function-Attributes.html#index-access-function-attribute',
+                                          'access',
+                                          'function',
+                                          '')])
+
+    def test_function_attribute_with_target(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="MIPS-Function-Attributes.html#index-nocompression-function-attribute_002c-MIPS"><code
 class="code">nocompression</code> function attribute, MIPS</a>')
+        self.assertEqual(index.entries, 
[('MIPS-Function-Attributes.html#index-nocompression-function-attribute_002c-MIPS',
+                                          'nocompression',
+                                          'function',
+                                          'MIPS')])
+
+    def test_reject_parens(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="x86-Function-Attributes.html#index-target_0028_00223dnow_0022_0029-function-attribute_002c-x86"><code>target(&quot;3dnow&quot;)</code>
 function attribute, x86</a>')
+        self.assertEqual(len(index.entries), 0)
+
+    def test_type_attribute(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="Common-Type-Attributes.html#index-aligned-type-attribute"><code>aligned</code>
 type attribute</a>')
+        self.assertEqual(index.entries, 
[('Common-Type-Attributes.html#index-aligned-type-attribute',
+                                          'aligned',
+                                          'type',
+                                          '')])
+
+    def test_enumerator_attribute(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="Enumerator-Attributes.html#index-deprecated-enumerator-attribute"><code>deprecated</code>
 enumerator attribute</a>')
+        self.assertEqual(index.entries, 
[('Enumerator-Attributes.html#index-deprecated-enumerator-attribute',
+                                          'deprecated',
+                                          'enumerator',
+                                          '')])
+    def test_label_attribute(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="Label-Attributes.html#index-cold-label-attribute"><code>cold</code> label 
attribute</a>')
+        self.assertEqual(index.entries, 
[('Label-Attributes.html#index-cold-label-attribute',
+                                          'cold',
+                                          'label',
+                                          '')])
+
+    def test_statement_attribute(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="Statement-Attributes.html#index-assume-statement-attribute"><code>assume</code>
 statement attribute</a>')
+        self.assertEqual(index.entries, 
[('Statement-Attributes.html#index-assume-statement-attribute',
+                                          'assume',
+                                          'statement',
+                                          '')])
+
+    def test_variable_attribute(self):
+        index = Index()
+        index.parse_html_line_attribute_index('<a 
href="AVR-Variable-Attributes.html#index-absdata-variable-attribute_002c-AVR"><code>absdata</code>
 variable attribute, AVR</a>')
+        self.assertEqual(index.entries, 
[('AVR-Variable-Attributes.html#index-absdata-variable-attribute_002c-AVR',
+                                          'absdata',
+                                          'variable',
+                                          'AVR')])
+
+    def test_parse_attribute_index(self):
+        index = Index()
+        index.parse_attribute_index(INPUT_HTML_PATH / INDEX_REL_PATH)
+        self.assertEqual(index.entries_by_kind['enumerator'][0],
+                         ('deprecated',
+                          
'Enumerator-Attributes.html#index-deprecated-enumerator-attribute',
+                          ''))
+        self.assertEqual(index.entries_by_kind['label'][0],
+                         ('cold', 
'Label-Attributes.html#index-cold-label-attribute', ''))
+
+def main(args):
+    index = Index()
+    index.parse_attribute_index(args.base_html_dir / INDEX_REL_PATH)
+    dstpath = args.src_gcc_dir / 'gcc' / 'attr-urls.def'
+    index.generate_file(dstpath)
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description=DESCRIPTION,
+                                     
formatter_class=argparse.RawDescriptionHelpFormatter)
+    parser.add_argument('base_html_dir', type=Path)
+    parser.add_argument('src_gcc_dir', type=Path)
+    parser.add_argument('--unit-test', action='store_true')
+    args = parser.parse_args()
+
+    if args.unit_test:
+        INPUT_HTML_PATH = args.base_html_dir
+        unittest.main(argv=[sys.argv[0], '-v'])
+    else:
+        main(args)
diff --git a/gcc/selftest-run-tests.cc b/gcc/selftest-run-tests.cc
index 9ea2a4591e03..8a12fd716c2f 100644
--- a/gcc/selftest-run-tests.cc
+++ b/gcc/selftest-run-tests.cc
@@ -127,6 +127,7 @@ selftest::run_tests ()
 
   text_art_tests ();
   gcc_urlifier_cc_tests ();
+  gcc_attribute_urlifier_cc_tests ();
 
   /* Run the analyzer selftests (if enabled).  */
   ana::selftest::run_analyzer_selftests ();
diff --git a/gcc/selftest.h b/gcc/selftest.h
index c6206e55428d..9a593146deb5 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -232,6 +232,7 @@ extern void et_forest_cc_tests ();
 extern void fibonacci_heap_cc_tests ();
 extern void fold_const_cc_tests ();
 extern void function_tests_cc_tests ();
+extern void gcc_attribute_urlifier_cc_tests ();
 extern void gcc_urlifier_cc_tests ();
 extern void ggc_tests_cc_tests ();
 extern void gimple_cc_tests ();
diff --git a/gcc/target.def b/gcc/target.def
index 523ae7ec9aaa..1df0e8c05ccc 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -7460,6 +7460,15 @@ DEFHOOKPOD
 libatomic.  The default value is false.",
  bool, false)
 
+/* This value represents whether libatomic is available on
+   the target platform.  */
+DEFHOOKPOD
+(documentation_name,
+ "If non-NULL, this value is a string used for locating target-specific\
+ documentation for this target.\n\
+The default value is NULL.",
+ const char *, NULL)
+
 /* Close the 'struct gcc_target' definition.  */
 HOOK_VECTOR_END (C90_EMPTY_HACK)
 
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index c2100a51a7a5..d69828cf3bf7 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "asan.h"
 #include "profile.h"
 #include "sreal.h"
+#include "gcc-urlifier.h"
 
 /* This file contains functions for building the Control Flow Graph (CFG)
    for a function tree.  */
@@ -9938,6 +9939,8 @@ do_warn_unused_result (gimple_seq seq)
 
          if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
            {
+             auto_urlify_attributes sentinel;
+
              location_t loc = gimple_location (g);
 
              if (fdecl)
diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc
index 9c3c6878ac96..a0cc9219ff86 100644
--- a/gcc/tree-ssa-uninit.cc
+++ b/gcc/tree-ssa-uninit.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "domwalk.h"
 #include "tree-ssa-sccvn.h"
 #include "cfganal.h"
+#include "gcc-urlifier.h"
 
 /* This implements the pass that does predicate aware warning on uses of
    possibly uninitialized variables.  The pass first collects the set of
@@ -456,6 +457,7 @@ maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree 
arg, tree ptr)
       const char* const access_str =
        TREE_STRING_POINTER (access->to_external_string ());
 
+      auto_urlify_attributes sentinel;
       location_t parmloc = DECL_SOURCE_LOCATION (parm);
       inform (parmloc, "accessing argument %u of a function declared with "
              "attribute %<%s%>",
@@ -877,6 +879,7 @@ maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
          const char* const access_str =
            TREE_STRING_POINTER (access->to_external_string ());
 
+         auto_urlify_attributes sentinel;
          if (fndecl)
            {
              location_t loc = DECL_SOURCE_LOCATION (fndecl);
-- 
2.26.3

Reply via email to