-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Add support for referencable labels for attribute documentation #118428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang Author: Oliver Hunt (ojhunt) ChangesThe existing mechanism being used is to manually add a reference in the documentation. These references link to the beginning of the text rather than the heading for the attribute which is what this PR allows. Full diff: https://github.com/llvm/llvm-project/pull/118428.diff 3 Files Affected:
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 618252f3e75247..522821a79063ac 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -55,6 +55,9 @@ class Documentation {
// When set, specifies that the attribute is deprecated and can optionally
// specify a replacement attribute.
DocDeprecated Deprecated;
+
+ // When set, specifies a label that can be used to reference the documentation
+ string Label = "";
}
// Specifies that the attribute is explicitly omitted from the documentation,
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 5de39be4805600..7a82b8fa320590 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3360,9 +3360,8 @@ def NoSanitizeAddressDocs : Documentation {
// This function has multiple distinct spellings, and so it requires a custom
// heading to be specified. The most common spelling is sufficient.
let Heading = "no_sanitize_address, no_address_safety_analysis";
+ let Label = "langext-address_sanitizer";
let Content = [{
-.. _langext-address_sanitizer:
-
Use ``__attribute__((no_sanitize_address))`` on a function or a global
variable declaration to specify that address safety instrumentation
(e.g. AddressSanitizer) should not be applied.
@@ -3372,9 +3371,8 @@ variable declaration to specify that address safety instrumentation
def NoSanitizeThreadDocs : Documentation {
let Category = DocCatFunction;
let Heading = "no_sanitize_thread";
+ let Label = "langext-thread_sanitizer";
let Content = [{
-.. _langext-thread_sanitizer:
-
Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
specify that checks for data races on plain (non-atomic) memory accesses should
not be inserted by ThreadSanitizer. The function is still instrumented by the
@@ -3385,9 +3383,8 @@ tool to avoid false positives and provide meaningful stack traces.
def NoSanitizeMemoryDocs : Documentation {
let Category = DocCatFunction;
let Heading = "no_sanitize_memory";
+ let Label = "langext-memory_sanitizer";
let Content = [{
-.. _langext-memory_sanitizer:
-
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
specify that checks for uninitialized memory should not be inserted
(e.g. by MemorySanitizer). The function may still be instrumented by the tool
@@ -3398,9 +3395,8 @@ to avoid false positives in other places.
def CFICanonicalJumpTableDocs : Documentation {
let Category = DocCatFunction;
let Heading = "cfi_canonical_jump_table";
+ let Label = "langext-cfi_canonical_jump_table";
let Content = [{
-.. _langext-cfi_canonical_jump_table:
-
Use ``__attribute__((cfi_canonical_jump_table))`` on a function declaration to
make the function's CFI jump table canonical. See :ref:`the CFI documentation
<cfi-canonical-jump-tables>` for more details.
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 534bf2d01d7957..a66868ba2cc044 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -5178,6 +5178,8 @@ GetAttributeHeadingAndSpellings(const Record &Documentation,
static void WriteDocumentation(const RecordKeeper &Records,
const DocumentationData &Doc, raw_ostream &OS) {
+ if (const StringRef label = Doc.Documentation->getValueAsString("Label"); !label.empty())
+ OS << ".. _" << label << ":\n\n";
OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n";
// List what spelling syntaxes the attribute supports.
|
The existing mechanism being used is to manually add a reference in the documentation. These references link to the beginning of the text rather than the heading for the attribute which is what this PR allows.
35fb507 to
aea2b40
Compare
Sirraide
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation seems fine to me; I can’t speak as to whether this is a necessary addition though.
|
|
||
| static void WriteDocumentation(const RecordKeeper &Records, | ||
| const DocumentationData &Doc, raw_ostream &OS) { | ||
| if (const StringRef label = Doc.Documentation->getValueAsString("Label"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (const StringRef label = Doc.Documentation->getValueAsString("Label"); | |
| if (StringRef label = Doc.Documentation->getValueAsString("Label"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: label -> Label per our usual naming rules.
|
I have no idea what is going on here... @AaronBallman probably needs to take a better look. Else, could the author please give me an ELI5 sorta thing here or show me what the change looks like on the generated stuff? |
AaronBallman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why does the existing mechanism not suffice?
clang/include/clang/Basic/Attr.td
Outdated
| // specify a replacement attribute. | ||
| DocDeprecated Deprecated; | ||
|
|
||
| // When set, specifies a label that can be used to reference the documentation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // When set, specifies a label that can be used to reference the documentation | |
| // When set, specifies a label that can be used to reference the documentation. |
|
|
||
| static void WriteDocumentation(const RecordKeeper &Records, | ||
| const DocumentationData &Doc, raw_ostream &OS) { | ||
| if (const StringRef label = Doc.Documentation->getValueAsString("Label"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: label -> Label per our usual naming rules.
Sure! This example will cover the docs used in the above screenshot So currently the documentation for the attribute is: def NoSanitizeMemoryDocs : Documentation {
let Category = DocCatFunction;
let Heading = "no_sanitize_memory";
let Content = [{
.. _langext-memory_sanitizer:
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
....
}];
}this results in generated docs like this: no_sanitize_memory
------------------
.. csv-table:: Supported Syntaxes
:header: "GNU", "C++11", "C23", "``__declspec``", "Keyword", "``#pragma``", "HLSL Annotation", "``#pragma clang attribute``"
"``no_address_safety_analysis`` |br| ``no_sanitize_address`` |br| ``no_sanitize_thread`` |br| ``no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","","","","","Yes"
.. _langext-memory_sanitizer: <!-- NOTE: This is where the manually specified label is -->
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
...The result is that a This change simply adds a .. _langext-memory_sanitizer: <!-- NOTE: This is where the manually specified label is now -->
no_sanitize_memory
------------------
.. csv-table:: Supported Syntaxes
:header: "GNU", "C++11", "C23", "``__declspec``", "Keyword", "``#pragma``", "HLSL Annotation", "``#pragma clang attribute``"
"``no_address_safety_analysis`` |br| ``no_sanitize_address`` |br| ``no_sanitize_thread`` |br| ``no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","","","","","Yes"
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
...This has no impact on the visual appearance of the resultant html documentation, but places the anchor in a much better location for cross linking documentation. |
I see, I did’t quite pick up on that part because I don’t know RST very well, but I feel like that’s a reasonable addition then. |
Sirraide
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after fixing one more thing.
I personally think this is a reasonable addition now, but please wait for Aaron or Erich to approve this too before merging.
|
Also, if/when this is merged, it would be nice if someone could go through the rest of the docs and apply this wherever possible (assuming there are any other places where we still need to do that). |
yeah, I wanted to isolate this for now to just the attribute docs as these are the only cases I could find, and I found them while working on the docs for #117428. I'm kind of surprised I couldn't find other labels anywhere, but it could just be because other docs don't reference each other due to the inability to easily do so? |
Co-authored-by: Sirraide <[email protected]>
Righto, I've committed the change, is |
Yeah, we generally don’t use top-level |
AaronBallman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thank you for the more detailed explanation, this makes sense to me. LG!
|
Yeah, agreed, thanks for the ELI5. When it comes to RST/HTML, I'm roughly 5 :) LGTM as well. |

The existing mechanism being used is to manually add a reference in the documentation. These references link to the beginning of the text rather than the heading for the attribute which is what this PR allows.