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
