diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst index 8ef88225f18097..72228fcc2e0ae2 100644 --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -2920,7 +2920,7 @@ that is named after the attribute being documented. If the attribute is not for public consumption, or is an implicitly-created attribute that has no visible spelling, the documentation list can specify the -``Undocumented`` object. Otherwise, the attribute should have its documentation +``InternalOnly`` object. Otherwise, the attribute should have its documentation added to AttrDocs.td. Documentation derives from the ``Documentation`` tablegen type. All derived diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 5f77073413fbf1..cb47215f7e1d18 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -19,10 +19,19 @@ def DocCatType : DocumentationCategory<"Type Attributes">; def DocCatStmt : DocumentationCategory<"Statement Attributes">; def DocCatDecl : DocumentationCategory<"Declaration Attributes">; -// Attributes listed under the Undocumented category do not generate any public -// documentation. Ideally, this category should be used for internal-only -// attributes which contain no spellings. -def DocCatUndocumented : DocumentationCategory<"Undocumented">; +// This category is for attributes which have not yet been properly documented, +// but should be. +def DocCatUndocumented : DocumentationCategory<"Undocumented"> { + let Content = [{ +This section lists attributes which are recognized by Clang, but which are +currently missing documentation. +}]; +} + +// Attributes listed under the InternalOnly category do not generate any entry +// in the documentation. This category should be used only when we _want_ +// to not document the attribute, e.g. if the attribute has no spellings. +def DocCatInternalOnly : DocumentationCategory<"InternalOnly">; class DocDeprecated { // If the Replacement field is empty, no replacement will be listed with the @@ -48,11 +57,17 @@ class Documentation { DocDeprecated Deprecated; } -// Specifies that the attribute is explicitly undocumented. This can be a -// helpful placeholder for the attribute while working on the implementation, -// but should not be used once feature work has been completed. +// Specifies that the attribute is explicitly omitted from the documentation, +// because it is not intended to be user-facing. +def InternalOnly : Documentation { + let Category = DocCatInternalOnly; +} + +// Specifies that the attribute is undocumented, but that it _should_ have +// documentation. def Undocumented : Documentation { let Category = DocCatUndocumented; + let Content = "No documentation."; } include "clang/Basic/AttrDocs.td" @@ -626,7 +641,7 @@ class IgnoredAttr : Attr { let Ignored = 1; let ASTNode = 0; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } // @@ -706,14 +721,14 @@ def AlignMac68k : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def AlignNatural : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def AlwaysInline : DeclOrStmtAttr { @@ -1188,7 +1203,7 @@ def CUDAInvalidTarget : InheritableAttr { let Spellings = []; let Subjects = SubjectList<[Function]>; let LangOpts = [CUDA]; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def CUDALaunchBounds : InheritableAttr { @@ -1440,7 +1455,9 @@ def Final : InheritableAttr { let Spellings = [Keyword<"final">, Keyword<"sealed">]; let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>]; let SemaHandler = 0; - let Documentation = [Undocumented]; + // Omitted from docs, since this is language syntax, not an attribute, as far + // as users are concerned. + let Documentation = [InternalOnly]; } def MinSize : InheritableAttr { @@ -1502,8 +1519,6 @@ def GNUInline : InheritableAttr { def Hot : InheritableAttr { let Spellings = [GCC<"hot">]; let Subjects = SubjectList<[Function]>; - // An AST node is created for this attribute, but not actually used beyond - // semantic checking for mutual exclusion with the Cold attribute. let Documentation = [Undocumented]; let SimpleHandler = 1; } @@ -1582,7 +1597,7 @@ def MaxFieldAlignment : InheritableAttr { let Spellings = []; let Args = [UnsignedArgument<"Alignment">]; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def MayAlias : InheritableAttr { @@ -1994,7 +2009,7 @@ def TypeNullUnspecified : TypeAttr { // qualifier is as an ObjCOwnership attribute with Kind == "none". def ObjCInertUnsafeUnretained : TypeAttr { let Spellings = [Keyword<"__unsafe_unretained">]; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def ObjCKindOf : TypeAttr { @@ -2278,7 +2293,9 @@ def Overloadable : Attr { def Override : InheritableAttr { let Spellings = [Keyword<"override">]; let SemaHandler = 0; - let Documentation = [Undocumented]; + // Omitted from docs, since this is language syntax, not an attribute, as far + // as users are concerned. + let Documentation = [InternalOnly]; } def Ownership : InheritableAttr { @@ -2467,7 +2484,7 @@ def PragmaClangBSSSection : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def PragmaClangDataSection : InheritableAttr { @@ -2475,7 +2492,7 @@ def PragmaClangDataSection : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def PragmaClangRodataSection : InheritableAttr { @@ -2483,7 +2500,7 @@ def PragmaClangRodataSection : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def PragmaClangRelroSection : InheritableAttr { @@ -2491,7 +2508,7 @@ def PragmaClangRelroSection : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def StrictFP : InheritableAttr { @@ -2499,7 +2516,7 @@ def StrictFP : InheritableAttr { // Function uses strict floating point operations. let Spellings = []; let Subjects = SubjectList<[Function]>; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def PragmaClangTextSection : InheritableAttr { @@ -2507,7 +2524,7 @@ def PragmaClangTextSection : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def Sentinel : InheritableAttr { @@ -3496,7 +3513,7 @@ def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def DLLImport : InheritableAttr, TargetSpecificAttr { @@ -3522,7 +3539,7 @@ def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def SelectAny : InheritableAttr { @@ -3588,7 +3605,7 @@ def MSVtorDisp : InheritableAttr { let AdditionalMembers = [{ MSVtorDispMode getVtorDispMode() const { return MSVtorDispMode(vdm); } }]; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def InitSeg : Attr { @@ -3680,21 +3697,21 @@ def CapturedRecord : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def OMPThreadPrivateDecl : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def OMPCaptureNoInit : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def OMPCaptureKind : Attr { @@ -3702,7 +3719,7 @@ def OMPCaptureKind : Attr { let Spellings = []; let SemaHandler = 0; let Args = [UnsignedArgument<"CaptureKindVal">]; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; let AdditionalMembers = [{ llvm::omp::Clause getCaptureKind() const { return static_cast(getCaptureKindVal()); @@ -3715,7 +3732,7 @@ def OMPReferencedVar : Attr { let Spellings = []; let SemaHandler = 0; let Args = [ExprArgument<"Ref">]; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def OMPDeclareSimdDecl : Attr { @@ -3788,7 +3805,7 @@ def OMPAllocateDecl : InheritableAttr { ExprArgument<"Allocator">, ExprArgument<"Alignment"> ]; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def OMPDeclareVariant : InheritableAttr { @@ -3945,7 +3962,7 @@ def Builtin : InheritableAttr { let Args = [UnsignedArgument<"ID">]; let Subjects = SubjectList<[Function]>; let SemaHandler = 0; - let Documentation = [Undocumented]; + let Documentation = [InternalOnly]; } def EnforceTCB : InheritableAttr { diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 641dd34c742104..9d1ec9bd9d8691 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -4578,7 +4578,8 @@ static void WriteCategoryHeader(const Record *DocCategory, static std::pair GetAttributeHeadingAndSpellings(const Record &Documentation, - const Record &Attribute) { + const Record &Attribute, + StringRef Cat) { // FIXME: there is no way to have a per-spelling category for the attribute // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. @@ -4598,7 +4599,7 @@ GetAttributeHeadingAndSpellings(const Record &Documentation, else { std::set Uniques; for (auto I = Spellings.begin(), E = Spellings.end(); - I != E && Uniques.size() <= 1; ++I) { + I != E; ++I) { std::string Spelling = std::string(NormalizeNameForSpellingComparison(I->name())); Uniques.insert(Spelling); @@ -4607,6 +4608,11 @@ GetAttributeHeadingAndSpellings(const Record &Documentation, // needs. if (Uniques.size() == 1) Heading = *Uniques.begin(); + // If it's in the undocumented category, just construct a header by + // concatenating all the spellings. Might not be great, but better than + // nothing. + else if (Cat == "Undocumented") + Heading = llvm::join(Uniques.begin(), Uniques.end(), ", "); } } @@ -4701,19 +4707,19 @@ void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) { for (const auto *D : Docs) { const Record &Doc = *D; const Record *Category = Doc.getValueAsDef("Category"); - // If the category is "undocumented", then there cannot be any other - // documentation categories (otherwise, the attribute would become - // documented). + // If the category is "InternalOnly", then there cannot be any other + // documentation categories (otherwise, the attribute would be + // emitted into the docs). const StringRef Cat = Category->getValueAsString("Name"); - bool Undocumented = Cat == "Undocumented"; - if (Undocumented && Docs.size() > 1) + bool InternalOnly = Cat == "InternalOnly"; + if (InternalOnly && Docs.size() > 1) PrintFatalError(Doc.getLoc(), - "Attribute is \"Undocumented\", but has multiple " + "Attribute is \"InternalOnly\", but has multiple " "documentation categories"); - if (!Undocumented) + if (!InternalOnly) SplitDocs[Category].push_back(DocumentationData( - Doc, Attr, GetAttributeHeadingAndSpellings(Doc, Attr))); + Doc, Attr, GetAttributeHeadingAndSpellings(Doc, Attr, Cat))); } }