r201677 - Moving the documentation for the enable_if attribute into AttrDocs. Removed the "clang introduces" phrase for style consistency, but otherwise the documentation is identical.

Aaron Ballman aaron at aaronballman.com
Wed Feb 19 06:48:32 PST 2014


Author: aaronballman
Date: Wed Feb 19 08:48:31 2014
New Revision: 201677

URL: http://llvm.org/viewvc/llvm-project?rev=201677&view=rev
Log:
Moving the documentation for the enable_if attribute into AttrDocs. Removed the "clang introduces" phrase for style consistency, but otherwise the documentation is identical.

Modified:
    cfe/trunk/docs/LanguageExtensions.rst
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/AttrDocs.td

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=201677&r1=201676&r2=201677&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Wed Feb 19 08:48:31 2014
@@ -1420,85 +1420,6 @@ caveats to this use of name mangling:
 
 Query for this feature with ``__has_extension(attribute_overloadable)``.
 
-Controlling Overload Resolution
-===============================
-
-Clang introduces the ``enable_if`` attribute, which can be placed on function
-declarations to control which overload is selected based on the values of the
-function's arguments. When combined with the
-:ref:`overloadable<langext-overloading>` attribute, this feature is also
-available in C.
-
-.. code-block:: c++
-
-  int isdigit(int c);
-  int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
-  
-  void foo(char c) {
-    isdigit(c);
-    isdigit(10);
-    isdigit(-10);  // results in a compile-time error.
-  }
-
-The enable_if attribute takes two arguments, the first is an expression written
-in terms of the function parameters, the second is a string explaining why this
-overload candidate could not be selected to be displayed in diagnostics. The
-expression is part of the function signature for the purposes of determining
-whether it is a redeclaration (following the rules used when determining
-whether a C++ template specialization is ODR-equivalent), but is not part of
-the type.
-
-The enable_if expression is evaluated as if it were the body of a
-bool-returning constexpr function declared with the arguments of the function
-it is being applied to, then called with the parameters at the callsite. If the
-result is false or could not be determined through constant expression
-evaluation, then this overload will not be chosen and the provided string may
-be used in a diagnostic if the compile fails as a result.
-
-Because the enable_if expression is an unevaluated context, there are no global
-state changes, nor the ability to pass information from the enable_if
-expression to the function body. For example, suppose we want calls to
-strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
-strbuf) only if the size of strbuf can be determined:
-
-.. code-block:: c++
-
-  __attribute__((always_inline))
-  static inline size_t strnlen(const char *s, size_t maxlen)
-    __attribute__((overloadable))
-    __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
-                             "chosen when the buffer size is known but 'maxlen' is not")))
-  {
-    return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
-  }
-
-Multiple enable_if attributes may be applied to a single declaration. In this
-case, the enable_if expressions are evaluated from left to right in the
-following manner. First, the candidates whose enable_if expressions evaluate to
-false or cannot be evaluated are discarded. If the remaining candidates do not
-share ODR-equivalent enable_if expressions, the overload resolution is
-ambiguous. Otherwise, enable_if overload resolution continues with the next
-enable_if attribute on the candidates that have not been discarded and have
-remaining enable_if attributes. In this way, we pick the most specific
-overload out of a number of viable overloads using enable_if.
-
-.. code-block:: c++
-
-  void f() __attribute__((enable_if(true, "")));  // #1
-  void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, "")));  // #2
-  
-  void g(int i, int j) __attribute__((enable_if(i, "")));  // #1
-  void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true)));  // #2
-
-In this example, a call to f() is always resolved to #2, as the first enable_if
-expression is ODR-equivalent for both declarations, but #1 does not have another
-enable_if expression to continue evaluating, so the next round of evaluation has
-only a single candidate. In a call to g(1, 1), the call is ambiguous even though
-#2 has more enable_if attributes, because the first enable_if expressions are
-not ODR-equivalent.
-
-Query for this feature with ``__has_attribute(enable_if)``.
-
 Initializer lists for complex numbers in C
 ==========================================
 

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=201677&r1=201676&r2=201677&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Feb 19 08:48:31 2014
@@ -627,7 +627,7 @@ def EnableIf : InheritableAttr {
   let Subjects = SubjectList<[Function]>;
   let Args = [ExprArgument<"Cond">, StringArgument<"Message">];
   let TemplateDependent = 1;
-  let Documentation = [Undocumented];
+  let Documentation = [EnableIfDocs];
 }
 
 def ExtVectorType : Attr {

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=201677&r1=201676&r2=201677&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Feb 19 08:48:31 2014
@@ -75,4 +75,84 @@ A function declared as ``[[noreturn]]``
 compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
 that appears to be capable of returning to its caller.
   }];
-}
\ No newline at end of file
+}
+
+def EnableIfDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``enable_if`` attribute can be placed on function declarations to control
+which overload is selected based on the values of the function's arguments.
+When combined with the ``overloadable`` attribute, this feature is also
+available in C.
+
+.. code-block:: c++
+
+  int isdigit(int c);
+  int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
+  
+  void foo(char c) {
+    isdigit(c);
+    isdigit(10);
+    isdigit(-10);  // results in a compile-time error.
+  }
+
+The enable_if attribute takes two arguments, the first is an expression written
+in terms of the function parameters, the second is a string explaining why this
+overload candidate could not be selected to be displayed in diagnostics. The
+expression is part of the function signature for the purposes of determining
+whether it is a redeclaration (following the rules used when determining
+whether a C++ template specialization is ODR-equivalent), but is not part of
+the type.
+
+The enable_if expression is evaluated as if it were the body of a
+bool-returning constexpr function declared with the arguments of the function
+it is being applied to, then called with the parameters at the callsite. If the
+result is false or could not be determined through constant expression
+evaluation, then this overload will not be chosen and the provided string may
+be used in a diagnostic if the compile fails as a result.
+
+Because the enable_if expression is an unevaluated context, there are no global
+state changes, nor the ability to pass information from the enable_if
+expression to the function body. For example, suppose we want calls to
+strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
+strbuf) only if the size of strbuf can be determined:
+
+.. code-block:: c++
+
+  __attribute__((always_inline))
+  static inline size_t strnlen(const char *s, size_t maxlen)
+    __attribute__((overloadable))
+    __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
+                             "chosen when the buffer size is known but 'maxlen' is not")))
+  {
+    return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
+  }
+
+Multiple enable_if attributes may be applied to a single declaration. In this
+case, the enable_if expressions are evaluated from left to right in the
+following manner. First, the candidates whose enable_if expressions evaluate to
+false or cannot be evaluated are discarded. If the remaining candidates do not
+share ODR-equivalent enable_if expressions, the overload resolution is
+ambiguous. Otherwise, enable_if overload resolution continues with the next
+enable_if attribute on the candidates that have not been discarded and have
+remaining enable_if attributes. In this way, we pick the most specific
+overload out of a number of viable overloads using enable_if.
+
+.. code-block:: c++
+
+  void f() __attribute__((enable_if(true, "")));  // #1
+  void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, "")));  // #2
+  
+  void g(int i, int j) __attribute__((enable_if(i, "")));  // #1
+  void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true)));  // #2
+
+In this example, a call to f() is always resolved to #2, as the first enable_if
+expression is ODR-equivalent for both declarations, but #1 does not have another
+enable_if expression to continue evaluating, so the next round of evaluation has
+only a single candidate. In a call to g(1, 1), the call is ambiguous even though
+#2 has more enable_if attributes, because the first enable_if expressions are
+not ODR-equivalent.
+
+Query for this feature with ``__has_attribute(enable_if)``.
+  }];
+}





More information about the cfe-commits mailing list