Err sorry, I was confused by them being called "objc-protocol-expression" instead of "-literal" in clang's code. Nevermind.
On Tue, Jan 8, 2013 at 11:32 AM, Nico Weber <[email protected]> wrote: > Hi Patrick, > > one question below. > > On Tue, Mar 20, 2012 at 1:50 PM, Patrick Beard <[email protected]> wrote: >> Author: pcbeard >> Date: Tue Mar 20 15:50:45 2012 >> New Revision: 153123 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=153123&view=rev >> Log: >> Objective-C literals documentation. >> >> Added: >> cfe/trunk/docs/ObjectiveCLiterals.html >> >> Added: cfe/trunk/docs/ObjectiveCLiterals.html >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ObjectiveCLiterals.html?rev=153123&view=auto >> ============================================================================== >> --- cfe/trunk/docs/ObjectiveCLiterals.html (added) >> +++ cfe/trunk/docs/ObjectiveCLiterals.html Tue Mar 20 15:50:45 2012 >> @@ -0,0 +1,314 @@ >> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" >> + "http://www.w3.org/TR/html4/strict.dtd"> >> +<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ --> >> +<html> >> +<head> >> + <META http-equiv="Content-Type" content="text/html; charset=UTF8"> >> + <title>Clang Language Extensions</title> >> + <link type="text/css" rel="stylesheet" href="../menu.css"> >> + <link type="text/css" rel="stylesheet" href="../content.css"> >> + <style type="text/css"> >> + td { >> + vertical-align: top; >> + } >> + th { background-color: #ffddaa; } >> + </style> >> +</head> >> +<body> >> + >> +<!--#include virtual="../menu.html.incl"--> >> + >> +<div id="content"> >> + >> +<h1>Objective-C Literals</h1> >> + >> +<h2>Introduction</h2> >> + >> +Three new features were introduced into clang at the same time: >> <i>NSNumber Literals</i> provide a syntax for creating <code>NSNumber</code> >> from scalar literal expressions; <i>Collection Literals</i> provide a >> short-hand for creating arrays and dictionaries; <i>Object Subscripting</i> >> provides a way to use subscripting with Objective-C objects. Users of Apple >> compiler releases can use these features starting with the Apple LLVM >> Compiler 4.0. Users of open-source LLVM.org compiler releases can use these >> features starting with clang v3.1.<p> >> + >> +These language additions simplify common Objective-C programming patterns, >> make programs more concise, and improve the safety of container creation.<p> >> + >> +This document describes how the features are implemented in clang, and how >> to use them in your own programs.<p> >> + >> +<h2>NSNumber Literals</h2> >> + >> +The framework class <code>NSNumber</code> is used to wrap scalar values >> inside objects: signed and unsigned integers (<code>char</code>, >> <code>short</code>, <code>int</code>, <code>long</code>, <code>long >> long</code>), floating point numbers (<code>float</code>, >> <code>double</code>), and boolean values (<code>BOOL</code>, C++ >> <code>bool</code>). Scalar values wrapped in objects are also known as >> <i>boxed</i> values.<p> >> + >> +In Objective-C, any character, numeric or boolean literal prefixed with the >> <code>'@'</code> character will evaluate to a pointer to an >> <code>NSNumber</code> object initialized with that value. C's type suffixes >> may be used to control the size of numeric literals. >> + >> +<h3>Examples</h3> >> + >> +The following program illustrates the rules for <code>NSNumber</code> >> literals:<p> >> + >> +<pre> >> +void main(int argc, const char *argv[]) { >> + // character literals. >> + NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber >> numberWithChar:'Z'] >> + >> + // integral literals. >> + NSNumber *fortyTwo = @42; // equivalent to [NSNumber >> numberWithInt:42] >> + NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber >> numberWithUnsignedInt:42U] >> + NSNumber *fortyTwoLong = @42L; // equivalent to [NSNumber >> numberWithLong:42L] >> + NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber >> numberWithLongLong:42LL] >> + >> + // floating point literals. >> + NSNumber *piFloat = @3.141592654F; // equivalent to [NSNumber >> numberWithFloat:3.141592654F] >> + NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber >> numberWithDouble:3.1415926535] >> + >> + // BOOL literals. >> + NSNumber *yesNumber = @YES; // equivalent to [NSNumber >> numberWithBool:YES] >> + NSNumber *noNumber = @NO; // equivalent to [NSNumber >> numberWithBool:NO] >> + >> +#ifdef __cplusplus >> + NSNumber *trueNumber = @true; // equivalent to [NSNumber >> numberWithBool:(BOOL)true] >> + NSNumber *falseNumber = @false; // equivalent to [NSNumber >> numberWithBool:(BOOL)false] >> +#endif >> +} >> +</pre> >> + >> +<h3>Discussion</h3> >> + >> +NSNumber literals only support literal scalar values after the '@'. >> Consequently, @INT_MAX works, but @INT_MIN does not, because they are >> defined like this:<p> >> + >> +<pre> >> +#define INT_MAX 2147483647 /* max value for an int */ >> +#define INT_MIN (-2147483647-1) /* min value for an int */ >> +</pre> >> + >> +The definition of INT_MIN is not a simple literal, but a parenthesized >> expression. This is by design, but may be improved in subsequent compiler >> releases.<p> >> + >> +Because <code>NSNumber</code> does not currently support wrapping >> <code>long double</code> values, the use of a <code>long double >> NSNumber</code> literal (e.g. <code>@123.23L</code>) will be rejected by the >> compiler.<p> >> + >> +Previously, the <code>BOOL</code> type was simply a typedef for >> <code>signed char</code>, and <code>YES</code> and <code>NO</code> were >> macros that expand to <code>(BOOL)1</code> and <code>(BOOL)0</code> >> respectively. To support <code>@YES</code> and <code>@NO</code> expressions, >> these macros are now defined using new language keywords in >> <code><objc/objc.h></code>:<p> >> + >> +<pre> >> +#if __has_feature(objc_bool) >> +#define YES __objc_yes >> +#define NO __objc_no >> +#else >> +#define YES ((BOOL)1) >> +#define NO ((BOOL)0) >> +#endif >> +</pre> >> + >> +The compiler implicitly converts <code>__objc_yes</code> and >> <code>__objc_no</code> to <code>(BOOL)1</code> and <code>(BOOL)0</code>. The >> keywords are used to disambiguate <code>BOOL</code> and integer literals.<p> >> + >> +Objective-C++ also supports <code>@true</code> and <code>@false</code> >> expressions, which are equivalent to <code>@YES</code> and <code>@NO</code>. >> + >> + >> +<h2>Container Literals</h2> >> + >> +Objective-C now supports a new expression syntax for creating immutable >> array and dictionary container objects. >> + >> +<h3>Examples</h3> >> + >> +Immutable array expression:<p> >> + >> + <pre> >> +NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ]; >> +</pre> >> + >> +This creates an <code>NSArray</code> with 3 elements. The comma-separated >> sub-expressions of an array literal can be any Objective-C object pointer >> typed expression.<p> >> + >> +Immutable dictionary expression:<p> >> + >> +<pre> >> +NSDictionary *dictionary = @{ >> + @"name" : NSUserName(), >> + @"date" : [NSDate date], >> + @"processInfo" : [NSProcessInfo processInfo] >> +}; >> +</pre> >> + >> +This creates an <code>NSDictionary</code> with 3 key/value pairs. Value >> sub-expressions of a dictionary literal must be Objective-C object pointer >> typed, as in array literals. Key sub-expresions must be of an Objective-C >> object pointer type that implements the <code><NSCopying></code> >> protocol.<p> >> + >> +<h3>Discussion</h3> >> + >> +Nil keys or nil values are not supported in containers. If the compiler can >> prove that a key or value is nil at compile time, then a warning will be >> emitted. Otherwise, a runtime error will occur.<p> >> + >> +Using array and dictionary literals is safer than the variadic creation >> forms commonly in use today. Array literal expressions expand to calls to >> <code>+[NSArray arrayWithObjects:count:]</code>, which validates that all >> objects are non-<code>nil</code>. The variadic form, <code>+[NSArray >> arrayWithObjects:]</code> uses <code>nil</code> as an argument list >> terminator, which can lead to malformed array objects. Dictionary literals >> are similarly created with <code>+[NSDictionary >> dictionaryWithObjects:forKeys:count:]</code> which validates all objects and >> keys, unlike <code>+[NSDictionary dictionaryWithObjectsAndKeys:]</code> >> which also uses a <code>nil</code> parameter as an argument list >> terminator.<p> >> + >> +<h2>Object Subscripting</h2> >> + >> +Objective-C object pointer values can now be used with C's subscripting >> operator.<p> >> + >> +<h3>Examples</h3> >> + >> +The following code demonstrates the use of object subscripting syntax with >> <code>NSMutableArray</code> and <code>NSMutableDictionary</code> objects:<p> >> + >> +<pre> >> +NSMutableArray *array = ...; >> +NSUInteger idx = ...; >> +id newObject = ...; >> +id oldObject = array[idx]; >> +array[idx] = newObject; // replace oldObject with >> newObject >> + >> +NSMutableDictionary *dictionary = ...; >> +NSString *key = ...; >> +oldObject = dictionary[key]; >> +dictionary[key] = newObject; // replace oldObject with newObject >> +</pre> >> + >> +The next section explains how subscripting expressions map to accessor >> methods.<p> >> + >> +<h3>Subscripting Methods</h3> >> + >> +Objective-C supports two kinds of subscript expressions: >> <i>array-style</i> subscript expressions use integer typed subscripts; >> <i>dictionary-style</i> subscript expressions use Objective-C object pointer >> typed subscripts. Each type of subscript expression is mapped to a message >> send using a predefined selector. The advantage of this design is >> flexibility: class designers are free to introduce subscripting by >> declaring methods or by adopting protocols. Moreover, because the method >> names are selected by the type of the subscript, an object can be >> subscripted using both array and dictionary styles. >> + >> +<h4>Array-Style Subscripting</h4> >> + >> +When the subscript operand has an integral type, the expression is >> rewritten to use one of two different selectors, depending on whether the >> element is being read or written. When an expression reads an element using >> an integral index, as in the following example:<p> >> + >> +<pre> >> +NSUInteger idx = ...; >> +id value = object[idx]; >> +</pre> >> + >> +it is translated into a call to <code>objectAtIndexedSubscript:</code><p> >> + >> +<pre> >> +id value = [object objectAtIndexedSubscript:idx]; >> +</pre> >> + >> +When an expression writes an element using an integral index:<p> >> + >> +<pre> >> +object[idx] = newValue; >> +</pre> >> + >> +it is translated to a call to <code>setObject:atIndexedSubscript:</code><p> >> + >> +<pre> >> +[object setObject:newValue atIndexedSubscript:idx]; >> +</pre> >> + >> +These message sends are then type-checked and performed just like explicit >> message sends. The method used for objectAtIndexedSubscript: must be >> declared with an argument of integral type and a return value of some >> Objective-C object pointer type. The method used for >> setObject:atIndexedSubscript: must be declared with its first argument >> having some Objective-C pointer type and its second argument having integral >> type.<p> >> + >> +The meaning of indexes is left up to the declaring class. The compiler will >> coerce the index to the appropriate argument type of the method it uses for >> type-checking. For an instance of <code>NSArray</code>, reading an element >> using an index outside the range <code>[0, array.count)</code> will raise an >> exception. For an instance of <code>NSMutableArray</code>, assigning to an >> element using an index within this range will replace that element, but >> assigning to an element using an index outside this range will raise an >> exception; no syntax is provided for inserting, appending, or removing >> elements for mutable arrays.<p> >> + >> +A class need not declare both methods in order to take advantage of this >> language feature. For example, the class <code>NSArray</code> declares only >> <code>objectAtIndexedSubscript:</code>, so that assignments to elements will >> fail to type-check; moreover, its subclass <code>NSMutableArray</code> >> declares <code>setObject:atIndexedSubscript:</code>. >> + >> +<h4>Dictionary-Style Subscripting</h4> >> + >> +When the subscript operand has an Objective-C object pointer type, the >> expression is rewritten to use one of two different selectors, depending on >> whether the element is being read from or written to. When an expression >> reads an element using an Objective-C object pointer subscript operand, as >> in the following example:<p> >> + >> +<pre> >> +id key = ...; >> +id value = object[key]; >> +</pre> >> + >> +it is translated into a call to the <code>objectForKeyedSubscript:</code> >> method:<p> >> + >> +<pre> >> +id value = [object objectForKeyedSubscript:key]; >> +</pre> >> + >> +When an expression writes an element using an Objective-C object pointer >> subscript:<p> >> + >> +<pre> >> +object[key] = newValue; >> +</pre> >> + >> +it is translated to a call to <code>setObject:forKeyedSubscript:</code> >> + >> +<pre> >> +[object setObject:newValue forKeyedSubscript:key]; >> +</pre> >> + >> +The behavior of <code>setObject:forKeyedSubscript:</code> is >> class-specific; but in general it should replace an existing value if one is >> already associated with a key, otherwise it should add a new value for the >> key. No syntax is provided for removing elements from mutable >> dictionaries.<p> >> + >> +<h3>Discussion</h3> >> + >> +An Objective-C subscript expression occurs when the base operand of the C >> subscript operator has an Objective-C object pointer type. Since this >> potentially collides with pointer arithmetic on the value, these expressions >> are only supported under the modern Objective-C runtime, which categorically >> forbids such arithmetic.<p> >> + >> +Currently, only subscripts of integral or Objective-C object pointer type >> are supported. In C++, a class type can be used if it has a single >> conversion function to an integral or Objective-C pointer type, in which >> case that conversion is applied and analysis continues as appropriate. >> Otherwise, the expression is ill-formed.<p> >> + >> +An Objective-C object subscript expression is always an l-value. If the >> expression appears on the left-hand side of a simple assignment operator >> (=), the element is written as described below. If the expression appears >> on the left-hand side of a compound assignment operator (e.g. +=), the >> program is ill-formed, because the result of reading an element is always an >> Objective-C object pointer and no binary operators are legal on such >> pointers. If the expression appears in any other position, the element is >> read as described below. It is an error to take the address of a subscript >> expression, or (in C++) to bind a reference to it.<p> >> + >> +Programs can use object subscripting with Objective-C object pointers of >> type <code>id</code>. Normal dynamic message send rules apply; the compiler >> must see <i>some</i> declaration of the subscripting methods, and will pick >> the declaration seen first.<p> >> + >> +<h2>Grammar Additions</h2> >> + >> +To support the new syntax described above, the Objective-C >> <code>@</code>-expression grammar has the following new productions:<p> >> + >> +<pre> >> +objc-at-expression : '@' (string-literal | encode-literal | >> selector-literal | protocol-literal | object-literal) > > ^ protocol-literal isn't defined anywhere below. Is the production > missing, or were protocol literals cut? > >> + ; >> + >> +object-literal : ('+' | '-')? numeric-constant >> + | character-constant >> + | boolean-constant >> + | array-literal >> + | dictionary-literal >> + ; >> + >> +boolean-constant : '__objc_yes' | '__objc_no' | 'true' | 'false' /* >> boolean keywords. */ >> + ; >> + >> +array-literal : '[' assignment-expression-list ']' >> + ; >> + >> +assignment-expression-list : assignment-expression (',' >> assignment-expression-list)? >> + | /* empty */ >> + ; >> + >> +dictionary-literal : '{' key-value-list '}' >> + ; >> + >> +key-value-list : key-value-pair (',' key-value-list)? >> + | /* empty */ >> + ; >> + >> +key-value-pair : assignment-expression ':' assignment-expression >> + ; >> +</pre> >> + >> +Note: <code>@true</code> and <code>@false</code> are only supported in >> Objective-C++.<p> >> + >> +<h2>Availability Checks</h2> >> + >> +Programs test for the new features by using clang's __has_feature checks. >> Here are examples of their use:<p> >> + >> +<pre> >> +#if __has_feature(objc_array_literals) >> + // new way. >> + NSArray *elements = @[ @"H", @"He", @"O", @"C" ]; >> +#else >> + // old way (equivalent). >> + id objects[] = { @"H", @"He", @"O", @"C" }; >> + NSArray *elements = [NSArray arrayWithObjects:objects count:4]; >> +#endif >> + >> +#if __has_feature(objc_dictionary_literals) >> + // new way. >> + NSDictionary *masses = @{ @"H" : @1.0078, @"He" : @4.0026, @"O" : >> @15.9990, @"C" : @12.0096 }; >> +#else >> + // old way (equivalent). >> + id keys[] = { @"H", @"He", @"O", @"C" }; >> + id values[] = { [NSNumber numberWithFloat:1.0078], [NSNumber >> numberWithFloat:4.0026], >> + [NSNumber numberWithFloat:15.9990], [NSNumber >> numberWithFloat:12.0096] }; >> + NSDictionary *masses = [NSDictionary dictionaryWithObjects:objects >> forKeys:keys count:4]; >> +#endif >> + >> +#if __has_feature(objc_subscripting) >> + NSUInteger i, count = elements.count; >> + for (i = 0; i < count; ++i) { >> + NSString *element = elements[i]; >> + NSNumber *mass = masses[element]; >> + NSLog(@"the mass of %@ is %@", element, mass); >> + } >> +#else >> + NSUInteger i, count = [elements count]; >> + for (i = 0; i < count; ++i) { >> + NSString *element = [elements objectAtIndex:i]; >> + NSNumber *mass = [masses objectForKey:element]; >> + NSLog(@"the mass of %@ is %@", element, mass); >> + } >> +#endif >> +</pre> >> + >> +Code can use also <code>__has_feature(objc_bool)</code> to check for the >> availability of numeric literals support. This checks for the new >> <code>__objc_yes / __objc_no</code> keywords, which enable the use of >> <code>@YES / @NO</code> literals.<p> >> + >> +</div> >> +</body> >> +</html> >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
