Author: aaronballman
Date: Wed Feb 19 16:59:32 2014
New Revision: 201732
URL: http://llvm.org/viewvc/llvm-project?rev=201732&view=rev
Log:
Refactored the way attribute category headers are handled so that it is
possible to use custom categories. This allows for moving the consumable
attributes (consumable, callable_when, return_typestate, etc) to be grouped
together, with a content heading, like they were in the language extensions
documentation. Moved the consumable attribute documentation from the language
extensions into the attribute documentation table.
Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
Modified: cfe/trunk/docs/LanguageExtensions.rst
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=201732&r1=201731&r2=201732&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Wed Feb 19 16:59:32 2014
@@ -1697,64 +1697,6 @@ The complete list of thread safety attri
frequently asked questions, can be found in the main documentation: see
:doc:`ThreadSafetyAnalysis`.
-
-Consumed Annotation Checking
-============================
-
-Clang supports additional attributes for checking basic resource management
-properties, specifically for unique objects that have a single owning
reference.
-The following attributes are currently supported, although **the implementation
-for these annotations is currently in development and are subject to change.**
-
-``consumable``
---------------
-
-Each class that uses any of the following annotations must first be marked
-using the consumable attribute. Failure to do so will result in a warning.
-
-``set_typestate(new_state)``
-----------------------------
-
-Annotate methods that transition an object into a new state with
-``__attribute__((set_typestate(new_state)))``. The new new state must be
-unconsumed, consumed, or unknown.
-
-``callable_when(...)``
-----------------------
-
-Use ``__attribute__((callable_when(...)))`` to indicate what states a method
-may be called in. Valid states are unconsumed, consumed, or unknown. Each
-argument to this attribute must be a quoted string. E.g.:
-
-``__attribute__((callable_when("unconsumed", "unknown")))``
-
-``tests_typestate(tested_state)``
----------------------------------
-
-Use ``__attribute__((tests_typestate(tested_state)))`` to indicate that a
method
-returns true if the object is in the specified state..
-
-``param_typestate(expected_state)``
------------------------------------
-
-This attribute specifies expectations about function parameters. Calls to an
-function with annotated parameters will issue a warning if the corresponding
-argument isn't in the expected state. The attribute is also used to set the
-initial state of the parameter when analyzing the function's body.
-
-``return_typestate(ret_state)``
--------------------------------
-
-The ``return_typestate`` attribute can be applied to functions or parameters.
-When applied to a function the attribute specifies the state of the returned
-value. The function's body is checked to ensure that it always returns a value
-in the specified state. On the caller side, values returned by the annotated
-function are initialized to the given state.
-
-If the attribute is applied to a function parameter it modifies the state of
-an argument after a call to the function returns. The function's body is
-checked to ensure that the parameter is in the expected state before
returning.
-
Type Safety Checking
====================
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=201732&r1=201731&r2=201732&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Feb 19 16:59:32 2014
@@ -11,11 +11,12 @@
// specific documentation that is collated within the larger document.
class DocumentationCategory<string name> {
string Name = name;
+ code Content = [{}];
}
-def DocCatFunction : DocumentationCategory<"Functions">;
-def DocCatVariable : DocumentationCategory<"Variables">;
-def DocCatType : DocumentationCategory<"Types">;
-def DocCatStmt : DocumentationCategory<"Statements">;
+def DocCatFunction : DocumentationCategory<"Function Attributes">;
+def DocCatVariable : DocumentationCategory<"Variable Attributes">;
+def DocCatType : DocumentationCategory<"Type Attributes">;
+def DocCatStmt : DocumentationCategory<"Statement 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.
@@ -1484,7 +1485,7 @@ def Consumable : InheritableAttr {
let Args = [EnumArgument<"DefaultState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [Undocumented];
+ let Documentation = [ConsumableDocs];
}
def ConsumableAutoCast : InheritableAttr {
@@ -1505,7 +1506,7 @@ def CallableWhen : InheritableAttr {
let Args = [VariadicEnumArgument<"CallableState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [Undocumented];
+ let Documentation = [CallableWhenDocs];
}
def ParamTypestate : InheritableAttr {
@@ -1514,7 +1515,7 @@ def ParamTypestate : InheritableAttr {
let Args = [EnumArgument<"ParamState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [Undocumented];
+ let Documentation = [ParamTypestateDocs];
}
def ReturnTypestate : InheritableAttr {
@@ -1523,7 +1524,7 @@ def ReturnTypestate : InheritableAttr {
let Args = [EnumArgument<"State", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [Undocumented];
+ let Documentation = [ReturnTypestateDocs];
}
def SetTypestate : InheritableAttr {
@@ -1532,7 +1533,7 @@ def SetTypestate : InheritableAttr {
let Args = [EnumArgument<"NewState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
- let Documentation = [Undocumented];
+ let Documentation = [SetTypestateDocs];
}
def TestTypestate : InheritableAttr {
@@ -1541,7 +1542,7 @@ def TestTypestate : InheritableAttr {
let Args = [EnumArgument<"TestState", "ConsumedState",
["consumed", "unconsumed"],
["Consumed", "Unconsumed"]>];
- let Documentation = [Undocumented];
+ let Documentation = [TestTypestateDocs];
}
// Type safety attributes for `void *' pointers and type tags.
Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=201732&r1=201731&r2=201732&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Feb 19 16:59:32 2014
@@ -498,3 +498,76 @@ The semantics are as follows:
a sequence equivalent to "movs pc, lr" will be used.
}];
}
+
+def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
+ let Content = [{
+Clang supports additional attributes for checking basic resource management
+properties, specifically for unique objects that have a single owning
reference.
+The following attributes are currently supported, although **the implementation
+for these annotations is currently in development and are subject to change.**
+ }];
+}
+
+def SetTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Annotate methods that transition an object into a new state with
+``__attribute__((set_typestate(new_state)))``. The new new state must be
+unconsumed, consumed, or unknown.
+ }];
+}
+
+def CallableWhenDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Use ``__attribute__((callable_when(...)))`` to indicate what states a method
+may be called in. Valid states are unconsumed, consumed, or unknown. Each
+argument to this attribute must be a quoted string. E.g.:
+
+``__attribute__((callable_when("unconsumed", "unknown")))``
+ }];
+}
+
+def TestTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method
+returns true if the object is in the specified state..
+ }];
+}
+
+def ParamTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+This attribute specifies expectations about function parameters. Calls to an
+function with annotated parameters will issue a warning if the corresponding
+argument isn't in the expected state. The attribute is also used to set the
+initial state of the parameter when analyzing the function's body.
+ }];
+}
+
+def ReturnTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+The ``return_typestate`` attribute can be applied to functions or parameters.
+When applied to a function the attribute specifies the state of the returned
+value. The function's body is checked to ensure that it always returns a value
+in the specified state. On the caller side, values returned by the annotated
+function are initialized to the given state.
+
+When applied to a function parameter it modifies the state of an argument after
+a call to the function returns. The function's body is checked to ensure that
+the parameter is in the expected state before returning.
+ }];
+}
+
+def ConsumableDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Each ``class`` that uses any of the typestate annotations must first be marked
+using the ``consumable`` attribute. Failure to do so will result in a warning.
+
+This attribute accepts a single parameter that must be one of the following:
+``unknown``, ``consumed``, or ``unconsumed``.
+ }];
+}
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=201732&r1=201731&r2=201732&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Wed Feb 19 16:59:32 2014
@@ -2648,49 +2648,32 @@ void EmitClangAttrParserStringSwitches(R
class DocumentationData {
public:
- enum DocCategory {
- Function,
- Variable,
- Type,
- Statement,
- Undocumented
- };
-
- DocCategory Category;
const Record *Documentation;
const Record *Attribute;
- DocumentationData(DocCategory Category, const Record &Documentation,
- const Record &Attribute)
- : Category(Category), Documentation(&Documentation),
- Attribute(&Attribute) {}
+ DocumentationData(const Record &Documentation, const Record &Attribute)
+ : Documentation(&Documentation), Attribute(&Attribute) {}
};
-static void WriteCategoryHeader(DocumentationData::DocCategory Category,
+static void WriteCategoryHeader(const Record *DocCategory,
raw_ostream &OS) {
- OS << "\n";
- switch (Category) {
- case DocumentationData::Undocumented:
- assert(false && "Undocumented attributes are not documented!");
- break;
- case DocumentationData::Function:
- OS << "Function Attributes\n";
- OS << "===================\n";
- break;
- case DocumentationData::Variable:
- OS << "Variable Attributes\n";
- OS << "===================\n";
- break;
- case DocumentationData::Type:
- OS << "Type Attributes\n";
- OS << "===============\n";
- break;
- case DocumentationData::Statement:
- OS << "Statement Attributes\n";
- OS << "====================\n";
- break;
+ const std::string &Name = DocCategory->getValueAsString("Name");
+ OS << Name << "\n" << std::string(Name.length(), '=') << "\n";
+
+ // If there is content, print that as well.
+ std::string ContentStr = DocCategory->getValueAsString("Content");
+ if (!ContentStr.empty()) {
+ // Trim leading and trailing newlines and spaces.
+ StringRef Content(ContentStr);
+ while (Content.startswith("\r") || Content.startswith("\n") ||
+ Content.startswith(" ") || Content.startswith("\t"))
+ Content = Content.substr(1);
+ while (Content.endswith("\r") || Content.endswith("\n") ||
+ Content.endswith(" ") || Content.endswith("\t"))
+ Content = Content.substr(0, Content.size() - 1);
+ OS << Content;
}
- OS << "\n";
+ OS << "\n\n";
}
enum SpellingKind {
@@ -2828,9 +2811,9 @@ void EmitClangAttrDocs(RecordKeeper &Rec
return;
}
- OS << Documentation->getValueAsString("Intro");
+ OS << Documentation->getValueAsString("Intro") << "\n";
- typedef std::map<DocumentationData::DocCategory,
+ typedef std::map<const Record *,
std::vector<DocumentationData> > CategoryMap;
CategoryMap SplitDocs;
@@ -2844,26 +2827,19 @@ void EmitClangAttrDocs(RecordKeeper &Rec
for (std::vector<Record *>::const_iterator DI = Docs.begin(),
DE = Docs.end(); DI != DE; ++DI) {
const Record &Doc = **DI;
- DocumentationData::DocCategory Cat =
- StringSwitch<DocumentationData::DocCategory>(
- Doc.getValueAsDef("Category")->getValueAsString("Name"))
- .Case("Functions", DocumentationData::Function)
- .Case("Variables", DocumentationData::Variable)
- .Case("Types", DocumentationData::Type)
- .Case("Statements", DocumentationData::Statement)
- .Case("Undocumented", DocumentationData::Undocumented);
-
+ 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).
- bool Undocumented = DocumentationData::Undocumented == Cat;
+ std::string Cat = Category->getValueAsString("Name");
+ bool Undocumented = Cat == "Undocumented";
if (Undocumented && Docs.size() > 1)
PrintFatalError(Doc.getLoc(),
"Attribute is \"Undocumented\", but has multiple "
"documentation categories");
if (!Undocumented)
- SplitDocs[Cat].push_back(DocumentationData(Cat, Doc, Attr));
+ SplitDocs[Category].push_back(DocumentationData(Doc, Attr));
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits