[cfe-commits] r152137 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Driver/ include/clang/Frontend/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/CodeGen/ lib/Driver/ lib/Lex/ lib/Pars

Nico Weber thakis at chromium.org
Wed Mar 14 10:42:44 PDT 2012


Hi Ted,

very cool!

I noticed everything except for the subscripting support works all the
way back on 10.5. Is that something that can be relied on? Can we use
array / dictionary / number literals on code that targets 10.5?

Thanks,
Nico

On Tue, Mar 6, 2012 at 12:05 PM, Ted Kremenek <kremenek at apple.com> wrote:
> Author: kremenek
> Date: Tue Mar  6 14:05:56 2012
> New Revision: 152137
>
> URL: http://llvm.org/viewvc/llvm-project?rev=152137&view=rev
> Log:
> Add clang support for new Objective-C literal syntax for NSDictionary, NSArray,
> NSNumber, and boolean literals.  This includes both Sema and Codegen support.
> Included is also support for new Objective-C container subscripting.
>
> My apologies for the large patch.  It was very difficult to break apart.
> The patch introduces changes to the driver as well to cause clang to link
> in additional runtime support when needed to support the new language features.
>
> Docs are forthcoming to document the implementation and behavior of these features.
>
> Added:
>    cfe/trunk/include/clang/AST/NSAPI.h
>    cfe/trunk/lib/AST/NSAPI.cpp
>    cfe/trunk/test/CodeGenObjC/Inputs/
>    cfe/trunk/test/CodeGenObjC/Inputs/literal-support.h
>    cfe/trunk/test/CodeGenObjC/arc-literals.m
>    cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m
>    cfe/trunk/test/CodeGenObjC/objc-container-subscripting-1.m
>    cfe/trunk/test/CodeGenObjC/objc-container-subscripting.m
>    cfe/trunk/test/CodeGenObjC/objc-dictionary-literal.m
>    cfe/trunk/test/CodeGenObjC/objc-literal-debugger-test.m
>    cfe/trunk/test/CodeGenObjC/objc-literal-tests.m
>    cfe/trunk/test/CodeGenObjC/optimized-setter.m
>    cfe/trunk/test/CodeGenObjCXX/Inputs/
>    cfe/trunk/test/CodeGenObjCXX/Inputs/literal-support.h
>    cfe/trunk/test/CodeGenObjCXX/literals.mm
>    cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting-1.mm
>    cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting.mm
>    cfe/trunk/test/Driver/arclite-link.c
>    cfe/trunk/test/PCH/objc_container.h
>    cfe/trunk/test/PCH/objc_container.m
>    cfe/trunk/test/PCH/objc_literals.m
>    cfe/trunk/test/PCH/objc_literals.mm
>    cfe/trunk/test/PCH/subscripting-literals.m
>    cfe/trunk/test/SemaObjC/cocoa-api-usage.m
>    cfe/trunk/test/SemaObjC/cocoa-api-usage.m.fixed
>    cfe/trunk/test/SemaObjC/objc-array-literal.m
>    cfe/trunk/test/SemaObjC/objc-container-subscripting-1.m
>    cfe/trunk/test/SemaObjC/objc-container-subscripting-2.m
>    cfe/trunk/test/SemaObjC/objc-container-subscripting-3.m
>    cfe/trunk/test/SemaObjC/objc-container-subscripting.m
>    cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m
>    cfe/trunk/test/SemaObjC/objc-literal-sig.m
>    cfe/trunk/test/SemaObjCXX/literals.mm
>    cfe/trunk/test/SemaObjCXX/objc-container-subscripting.mm
> Modified:
>    cfe/trunk/include/clang/AST/ASTContext.h
>    cfe/trunk/include/clang/AST/ExprObjC.h
>    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>    cfe/trunk/include/clang/AST/Stmt.h
>    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>    cfe/trunk/include/clang/Basic/DiagnosticIDs.h
>    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>    cfe/trunk/include/clang/Basic/LangOptions.def
>    cfe/trunk/include/clang/Basic/Specifiers.h
>    cfe/trunk/include/clang/Basic/StmtNodes.td
>    cfe/trunk/include/clang/Basic/TokenKinds.def
>    cfe/trunk/include/clang/Driver/CC1Options.td
>    cfe/trunk/include/clang/Driver/ObjCRuntime.h
>    cfe/trunk/include/clang/Driver/Options.td
>    cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
>    cfe/trunk/include/clang/Parse/Parser.h
>    cfe/trunk/include/clang/Sema/Sema.h
>    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>    cfe/trunk/lib/AST/ASTContext.cpp
>    cfe/trunk/lib/AST/CMakeLists.txt
>    cfe/trunk/lib/AST/Expr.cpp
>    cfe/trunk/lib/AST/ExprClassification.cpp
>    cfe/trunk/lib/AST/ExprConstant.cpp
>    cfe/trunk/lib/AST/ItaniumMangle.cpp
>    cfe/trunk/lib/AST/StmtDumper.cpp
>    cfe/trunk/lib/AST/StmtPrinter.cpp
>    cfe/trunk/lib/AST/StmtProfile.cpp
>    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
>    cfe/trunk/lib/CodeGen/CGObjC.cpp
>    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
>    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
>    cfe/trunk/lib/CodeGen/CGObjCRuntime.h
>    cfe/trunk/lib/CodeGen/CodeGenFunction.h
>    cfe/trunk/lib/Driver/ToolChains.cpp
>    cfe/trunk/lib/Driver/ToolChains.h
>    cfe/trunk/lib/Driver/Tools.cpp
>    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
>    cfe/trunk/lib/Parse/ParseExpr.cpp
>    cfe/trunk/lib/Parse/ParseObjc.cpp
>    cfe/trunk/lib/Sema/Sema.cpp
>    cfe/trunk/lib/Sema/SemaCast.cpp
>    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
>    cfe/trunk/lib/Sema/SemaExpr.cpp
>    cfe/trunk/lib/Sema/SemaExprCXX.cpp
>    cfe/trunk/lib/Sema/SemaExprObjC.cpp
>    cfe/trunk/lib/Sema/SemaPseudoObject.cpp
>    cfe/trunk/lib/Sema/SemaStmt.cpp
>    cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>    cfe/trunk/lib/Sema/TreeTransform.h
>    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>    cfe/trunk/lib/Serialization/ASTWriter.cpp
>    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>    cfe/trunk/test/Driver/darwin-ld.c
>    cfe/trunk/test/Driver/rewrite-objc.m
>    cfe/trunk/test/SemaObjC/invalid-code.m
>    cfe/trunk/test/SemaObjC/sizeof-interface.m
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Tue Mar  6 14:05:56 2012
> @@ -564,6 +564,7 @@
>   CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
>   CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
>   CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
> +  CanQualType ObjCBuiltinBoolTy;
>
>   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
>   mutable QualType AutoDeductTy;     // Deduction against 'auto'.
>
> Modified: cfe/trunk/include/clang/AST/ExprObjC.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ExprObjC.h (original)
> +++ cfe/trunk/include/clang/AST/ExprObjC.h Tue Mar  6 14:05:56 2012
> @@ -18,6 +18,7 @@
>  #include "clang/AST/Expr.h"
>  #include "clang/AST/SelectorLocationsKind.h"
>  #include "clang/Basic/IdentifierTable.h"
> +#include "clang/Sema/Ownership.h"
>
>  namespace clang {
>   class IdentifierInfo;
> @@ -56,6 +57,281 @@
>   child_range children() { return child_range(&String, &String+1); }
>  };
>
> +/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
> +///
> +class ObjCBoolLiteralExpr : public Expr {
> +  bool Value;
> +  SourceLocation Loc;
> +public:
> +  ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
> +  Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
> +       false, false), Value(val), Loc(l) {}
> +
> +  explicit ObjCBoolLiteralExpr(EmptyShell Empty)
> +  : Expr(ObjCBoolLiteralExprClass, Empty) { }
> +
> +  bool getValue() const { return Value; }
> +  void setValue(bool V) { Value = V; }
> +
> +  SourceRange getSourceRange() const { return SourceRange(Loc); }
> +
> +  SourceLocation getLocation() const { return Loc; }
> +  void setLocation(SourceLocation L) { Loc = L; }
> +
> +  static bool classof(const Stmt *T) {
> +    return T->getStmtClass() == ObjCBoolLiteralExprClass;
> +  }
> +  static bool classof(const ObjCBoolLiteralExpr *) { return true; }
> +
> +  // Iterators
> +  child_range children() { return child_range(); }
> +};
> +
> +/// ObjCNumericLiteral - used for objective-c numeric literals;
> +/// as in: @42 or @true (c++/objc++) or @__yes (c/objc)
> +class ObjCNumericLiteral : public Expr {
> +  /// Number - expression AST node for the numeric literal
> +  Stmt *Number;
> +  ObjCMethodDecl *ObjCNumericLiteralMethod;
> +  SourceLocation AtLoc;
> +public:
> +  ObjCNumericLiteral(Stmt *NL, QualType T, ObjCMethodDecl *method,
> +                     SourceLocation L)
> +  : Expr(ObjCNumericLiteralClass, T, VK_RValue, OK_Ordinary,
> +         false, false, false, false), Number(NL),
> +    ObjCNumericLiteralMethod(method), AtLoc(L) {}
> +  explicit ObjCNumericLiteral(EmptyShell Empty)
> +  : Expr(ObjCNumericLiteralClass, Empty) {}
> +
> +  Expr *getNumber() { return cast<Expr>(Number); }
> +  const Expr *getNumber() const { return cast<Expr>(Number); }
> +
> +  ObjCMethodDecl *getObjCNumericLiteralMethod() const {
> +    return ObjCNumericLiteralMethod;
> +  }
> +
> +  SourceLocation getAtLoc() const { return AtLoc; }
> +
> +  SourceRange getSourceRange() const {
> +    return SourceRange(AtLoc, Number->getSourceRange().getEnd());
> +  }
> +
> +  static bool classof(const Stmt *T) {
> +      return T->getStmtClass() == ObjCNumericLiteralClass;
> +  }
> +  static bool classof(const ObjCNumericLiteral *) { return true; }
> +
> +  // Iterators
> +  child_range children() { return child_range(&Number, &Number+1); }
> +
> +  friend class ASTStmtReader;
> +};
> +
> +/// ObjCArrayLiteral - used for objective-c array containers; as in:
> +/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
> +class ObjCArrayLiteral : public Expr {
> +  unsigned NumElements;
> +  SourceRange Range;
> +  ObjCMethodDecl *ArrayWithObjectsMethod;
> +
> +  ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
> +                   QualType T, ObjCMethodDecl * Method,
> +                   SourceRange SR);
> +
> +  explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
> +    : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
> +
> +public:
> +  static ObjCArrayLiteral *Create(ASTContext &C,
> +                                  llvm::ArrayRef<Expr *> Elements,
> +                                  QualType T, ObjCMethodDecl * Method,
> +                                  SourceRange SR);
> +
> +  static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
> +
> +  SourceRange getSourceRange() const { return Range; }
> +
> +  static bool classof(const Stmt *T) {
> +      return T->getStmtClass() == ObjCArrayLiteralClass;
> +  }
> +  static bool classof(const ObjCArrayLiteral *) { return true; }
> +
> +  /// \brief Retrieve elements of array of literals.
> +  Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
> +
> +  /// \brief Retrieve elements of array of literals.
> +  const Expr * const *getElements() const {
> +    return reinterpret_cast<const Expr * const*>(this + 1);
> +  }
> +
> +  /// getNumElements - Return number of elements of objective-c array literal.
> +  unsigned getNumElements() const { return NumElements; }
> +
> +    /// getExpr - Return the Expr at the specified index.
> +  Expr *getElement(unsigned Index) {
> +    assert((Index < NumElements) && "Arg access out of range!");
> +    return cast<Expr>(getElements()[Index]);
> +  }
> +  const Expr *getElement(unsigned Index) const {
> +    assert((Index < NumElements) && "Arg access out of range!");
> +    return cast<Expr>(getElements()[Index]);
> +  }
> +
> +  ObjCMethodDecl *getArrayWithObjectsMethod() const {
> +    return ArrayWithObjectsMethod;
> +  }
> +
> +  // Iterators
> +  child_range children() {
> +    return child_range((Stmt **)getElements(),
> +                       (Stmt **)getElements() + NumElements);
> +  }
> +
> +  friend class ASTStmtReader;
> +};
> +
> +/// \brief An element in an Objective-C dictionary literal.
> +///
> +struct ObjCDictionaryElement {
> +  /// \brief The key for the dictionary element.
> +  Expr *Key;
> +
> +  /// \brief The value of the dictionary element.
> +  Expr *Value;
> +
> +  /// \brief The location of the ellipsis, if this is a pack expansion.
> +  SourceLocation EllipsisLoc;
> +
> +  /// \brief The number of elements this pack expansion will expand to, if
> +  /// this is a pack expansion and is known.
> +  llvm::Optional<unsigned> NumExpansions;
> +
> +  /// \brief Determines whether this dictionary element is a pack expansion.
> +  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
> +};
> +
> +/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
> +/// literals; as in:  @{@"name" : NSUserName(), @"date" : [NSDate date] };
> +class ObjCDictionaryLiteral : public Expr {
> +  /// \brief Key/value pair used to store the key and value of a given element.
> +  ///
> +  /// Objects of this type are stored directly after the expression.
> +  struct KeyValuePair {
> +    Expr *Key;
> +    Expr *Value;
> +  };
> +
> +  /// \brief Data that describes an element that is a pack expansion, used if any
> +  /// of the elements in the dictionary literal are pack expansions.
> +  struct ExpansionData {
> +    /// \brief The location of the ellipsis, if this element is a pack
> +    /// expansion.
> +    SourceLocation EllipsisLoc;
> +
> +    /// \brief If non-zero, the number of elements that this pack
> +    /// expansion will expand to (+1).
> +    unsigned NumExpansionsPlusOne;
> +  };
> +
> +  /// \brief The number of elements in this dictionary literal.
> +  unsigned NumElements : 31;
> +
> +  /// \brief Determine whether this dictionary literal has any pack expansions.
> +  ///
> +  /// If the dictionary literal has pack expansions, then there will
> +  /// be an array of pack expansion data following the array of
> +  /// key/value pairs, which provide the locations of the ellipses (if
> +  /// any) and number of elements in the expansion (if known). If
> +  /// there are no pack expansions, we optimize away this storage.
> +  unsigned HasPackExpansions : 1;
> +
> +  SourceRange Range;
> +  ObjCMethodDecl *DictWithObjectsMethod;
> +
> +  ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
> +                        bool HasPackExpansions,
> +                        QualType T, ObjCMethodDecl *method,
> +                        SourceRange SR);
> +
> +  explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
> +                                 bool HasPackExpansions)
> +    : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
> +      HasPackExpansions(HasPackExpansions) {}
> +
> +  KeyValuePair *getKeyValues() {
> +    return reinterpret_cast<KeyValuePair *>(this + 1);
> +  }
> +
> +  const KeyValuePair *getKeyValues() const {
> +    return reinterpret_cast<const KeyValuePair *>(this + 1);
> +  }
> +
> +  ExpansionData *getExpansionData() {
> +    if (!HasPackExpansions)
> +      return 0;
> +
> +    return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
> +  }
> +
> +  const ExpansionData *getExpansionData() const {
> +    if (!HasPackExpansions)
> +      return 0;
> +
> +    return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
> +  }
> +
> +public:
> +  static ObjCDictionaryLiteral *Create(ASTContext &C,
> +                                       ArrayRef<ObjCDictionaryElement> VK,
> +                                       bool HasPackExpansions,
> +                                       QualType T, ObjCMethodDecl *method,
> +                                       SourceRange SR);
> +
> +  static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C,
> +                                            unsigned NumElements,
> +                                            bool HasPackExpansions);
> +
> +  /// getNumElements - Return number of elements of objective-c dictionary
> +  /// literal.
> +  unsigned getNumElements() const { return NumElements; }
> +
> +  ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
> +    assert((Index < NumElements) && "Arg access out of range!");
> +    const KeyValuePair &KV = getKeyValues()[Index];
> +    ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(),
> +                                     llvm::Optional<unsigned>() };
> +    if (HasPackExpansions) {
> +      const ExpansionData &Expansion = getExpansionData()[Index];
> +      Result.EllipsisLoc = Expansion.EllipsisLoc;
> +      if (Expansion.NumExpansionsPlusOne > 0)
> +        Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
> +    }
> +    return Result;
> +  }
> +
> +  ObjCMethodDecl *getDictWithObjectsMethod() const
> +    { return DictWithObjectsMethod; }
> +
> +  SourceRange getSourceRange() const { return Range; }
> +
> +  static bool classof(const Stmt *T) {
> +      return T->getStmtClass() == ObjCDictionaryLiteralClass;
> +  }
> +  static bool classof(const ObjCDictionaryLiteral *) { return true; }
> +
> +  // Iterators
> +  child_range children() {
> +    // Note: we're taking advantage of the layout of the KeyValuePair struct
> +    // here. If that struct changes, this code will need to change as well.
> +    return child_range(reinterpret_cast<Stmt **>(this + 1),
> +                       reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
> +  }
> +
> +  friend class ASTStmtReader;
> +  friend class ASTStmtWriter;
> +};
> +
> +
>  /// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
>  /// and behavior as StringLiteral except that the string initializer is obtained
>  /// from ASTContext with the encoding type as an argument.
> @@ -430,6 +706,88 @@
>   void setLocation(SourceLocation L) { IdLoc = L; }
>   void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
>  };
> +
> +/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
> +/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
> +///
> +class ObjCSubscriptRefExpr : public Expr {
> +  // Location of ']' in an indexing expression.
> +  SourceLocation RBracket;
> +  // array/dictionary base expression.
> +  // for arrays, this is a numeric expression. For dictionaries, this is
> +  // an objective-c object pointer expression.
> +  enum { BASE, KEY, END_EXPR };
> +  Stmt* SubExprs[END_EXPR];
> +
> +  ObjCMethodDecl *GetAtIndexMethodDecl;
> +
> +  // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
> +  // an indexed object this is null too.
> +  ObjCMethodDecl *SetAtIndexMethodDecl;
> +
> +public:
> +
> +  ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
> +                       ExprValueKind VK, ExprObjectKind OK,
> +                       ObjCMethodDecl *getMethod,
> +                       ObjCMethodDecl *setMethod, SourceLocation RB)
> +    : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
> +           base->isTypeDependent() || key->isTypeDependent(),
> +           base->isValueDependent() || key->isValueDependent(),
> +           base->isInstantiationDependent() || key->isInstantiationDependent(),
> +           (base->containsUnexpandedParameterPack() ||
> +            key->containsUnexpandedParameterPack())),
> +      RBracket(RB),
> +  GetAtIndexMethodDecl(getMethod),
> +  SetAtIndexMethodDecl(setMethod)
> +    {SubExprs[BASE] = base; SubExprs[KEY] = key;}
> +
> +  explicit ObjCSubscriptRefExpr(EmptyShell Empty)
> +    : Expr(ObjCSubscriptRefExprClass, Empty) {}
> +
> +  static ObjCSubscriptRefExpr *Create(ASTContext &C,
> +                                      Expr *base,
> +                                      Expr *key, QualType T,
> +                                      ObjCMethodDecl *getMethod,
> +                                      ObjCMethodDecl *setMethod,
> +                                      SourceLocation RB);
> +
> +  SourceLocation getRBracket() const { return RBracket; }
> +  void setRBracket(SourceLocation RB) { RBracket = RB; }
> +  SourceRange getSourceRange() const {
> +    return SourceRange(SubExprs[BASE]->getLocStart(), RBracket);
> +  }
> +
> +  static bool classof(const Stmt *T) {
> +    return T->getStmtClass() == ObjCSubscriptRefExprClass;
> +  }
> +  static bool classof(const ObjCSubscriptRefExpr *) { return true; }
> +
> +  Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
> +  void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
> +
> +  Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
> +  void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
> +
> +  ObjCMethodDecl *getAtIndexMethodDecl() const {
> +    return GetAtIndexMethodDecl;
> +  }
> +
> +  ObjCMethodDecl *setAtIndexMethodDecl() const {
> +    return SetAtIndexMethodDecl;
> +  }
> +
> +  bool isArraySubscriptRefExpr() const {
> +    return getKeyExpr()->getType()->isIntegralOrEnumerationType();
> +  }
> +
> +  child_range children() {
> +    return child_range(SubExprs, SubExprs+END_EXPR);
> +  }
> +private:
> +  friend class ASTStmtReader;
> +};
> +
>
>  /// \brief An expression that sends a message to the given Objective-C
>  /// object or class.
>
> Added: cfe/trunk/include/clang/AST/NSAPI.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/NSAPI.h?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/include/clang/AST/NSAPI.h (added)
> +++ cfe/trunk/include/clang/AST/NSAPI.h Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,151 @@
> +//===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CLANG_AST_NSAPI_H
> +#define LLVM_CLANG_AST_NSAPI_H
> +
> +#include "clang/Basic/IdentifierTable.h"
> +#include "llvm/ADT/Optional.h"
> +
> +namespace clang {
> +  class ASTContext;
> +  class QualType;
> +
> +// \brief Provides info and caches identifiers/selectors for NSFoundation API.
> +class NSAPI {
> +public:
> +  explicit NSAPI(ASTContext &Ctx);
> +
> +  ASTContext &getASTContext() const { return Ctx; }
> +
> +  enum NSClassIdKindKind {
> +    ClassId_NSString,
> +    ClassId_NSArray,
> +    ClassId_NSMutableArray,
> +    ClassId_NSDictionary,
> +    ClassId_NSMutableDictionary,
> +    ClassId_NSNumber
> +  };
> +  static const unsigned NumClassIds = 6;
> +
> +  enum NSStringMethodKind {
> +    NSStr_stringWithString,
> +    NSStr_initWithString
> +  };
> +  static const unsigned NumNSStringMethods = 2;
> +
> +  IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
> +
> +  /// \brief The Objective-C NSString selectors.
> +  Selector getNSStringSelector(NSStringMethodKind MK) const;
> +
> +  /// \brief Enumerates the NSArray methods used to generate literals.
> +  enum NSArrayMethodKind {
> +    NSArr_array,
> +    NSArr_arrayWithArray,
> +    NSArr_arrayWithObject,
> +    NSArr_arrayWithObjects,
> +    NSArr_arrayWithObjectsCount,
> +    NSArr_initWithArray,
> +    NSArr_initWithObjects,
> +    NSArr_objectAtIndex,
> +    NSMutableArr_replaceObjectAtIndex
> +  };
> +  static const unsigned NumNSArrayMethods = 9;
> +
> +  /// \brief The Objective-C NSArray selectors.
> +  Selector getNSArraySelector(NSArrayMethodKind MK) const;
> +
> +  /// \brief Return NSArrayMethodKind if \arg Sel is such a selector.
> +  llvm::Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
> +
> +  /// \brief Enumerates the NSDictionary methods used to generate literals.
> +  enum NSDictionaryMethodKind {
> +    NSDict_dictionary,
> +    NSDict_dictionaryWithDictionary,
> +    NSDict_dictionaryWithObjectForKey,
> +    NSDict_dictionaryWithObjectsForKeys,
> +    NSDict_dictionaryWithObjectsForKeysCount,
> +    NSDict_dictionaryWithObjectsAndKeys,
> +    NSDict_initWithDictionary,
> +    NSDict_initWithObjectsAndKeys,
> +    NSDict_objectForKey,
> +    NSMutableDict_setObjectForKey
> +  };
> +  static const unsigned NumNSDictionaryMethods = 10;
> +
> +  /// \brief The Objective-C NSDictionary selectors.
> +  Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
> +
> +  /// \brief Return NSDictionaryMethodKind if \arg Sel is such a selector.
> +  llvm::Optional<NSDictionaryMethodKind>
> +      getNSDictionaryMethodKind(Selector Sel);
> +
> +  /// \brief Enumerates the NSNumber methods used to generate literals.
> +  enum NSNumberLiteralMethodKind {
> +    NSNumberWithChar,
> +    NSNumberWithUnsignedChar,
> +    NSNumberWithShort,
> +    NSNumberWithUnsignedShort,
> +    NSNumberWithInt,
> +    NSNumberWithUnsignedInt,
> +    NSNumberWithLong,
> +    NSNumberWithUnsignedLong,
> +    NSNumberWithLongLong,
> +    NSNumberWithUnsignedLongLong,
> +    NSNumberWithFloat,
> +    NSNumberWithDouble,
> +    NSNumberWithBool,
> +    NSNumberWithInteger,
> +    NSNumberWithUnsignedInteger
> +  };
> +  static const unsigned NumNSNumberLiteralMethods = 15;
> +
> +  /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
> +  /// \param Instance if true it will return the selector for the init* method
> +  /// otherwise it will return the selector for the number* method.
> +  Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
> +                                      bool Instance) const;
> +
> +  bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
> +                                 Selector Sel) const {
> +    return Sel == getNSNumberLiteralSelector(MK, false) ||
> +           Sel == getNSNumberLiteralSelector(MK, true);
> +  }
> +
> +  /// \brief Return NSNumberLiteralMethodKind if \arg Sel is such a selector.
> +  llvm::Optional<NSNumberLiteralMethodKind>
> +      getNSNumberLiteralMethodKind(Selector Sel) const;
> +
> +  /// \brief Determine the appropriate NSNumber factory method kind for a
> +  /// literal of the given type.
> +  static llvm::Optional<NSNumberLiteralMethodKind>
> +      getNSNumberFactoryMethodKind(QualType T);
> +
> +private:
> +  ASTContext &Ctx;
> +
> +  mutable IdentifierInfo *ClassIds[NumClassIds];
> +
> +  mutable Selector NSStringSelectors[NumNSStringMethods];
> +
> +  /// \brief The selectors for Objective-C NSArray methods.
> +  mutable Selector NSArraySelectors[NumNSArrayMethods];
> +
> +  /// \brief The selectors for Objective-C NSDictionary methods.
> +  mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
> +
> +  /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
> +  mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
> +  mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
> +};
> +
> +}  // end namespace clang
> +
> +#endif // LLVM_CLANG_AST_NSAPI_H
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Mar  6 14:05:56 2012
> @@ -2041,11 +2041,13 @@
>  DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
>  DEF_TRAVERSE_STMT(GNUNullExpr, { })
>  DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
> +DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { })
>  DEF_TRAVERSE_STMT(ObjCEncodeExpr, { })
>  DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
>  DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
>  DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
>  DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
> +DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
>  DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
>  DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
>  DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
> @@ -2103,7 +2105,10 @@
>  DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
>  DEF_TRAVERSE_STMT(StringLiteral, { })
>  DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
> -
> +DEF_TRAVERSE_STMT(ObjCNumericLiteral, { })
> +DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
> +DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
> +
>  // Traverse OpenCL: AsType, Convert.
>  DEF_TRAVERSE_STMT(AsTypeExpr, { })
>
>
> Modified: cfe/trunk/include/clang/AST/Stmt.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Stmt.h (original)
> +++ cfe/trunk/include/clang/AST/Stmt.h Tue Mar  6 14:05:56 2012
> @@ -141,6 +141,8 @@
>     friend class CallExpr; // ctor
>     friend class OffsetOfExpr; // ctor
>     friend class ObjCMessageExpr; // ctor
> +    friend class ObjCArrayLiteral; // ctor
> +    friend class ObjCDictionaryLiteral; // ctor
>     friend class ShuffleVectorExpr; // ctor
>     friend class ParenListExpr; // ctor
>     friend class CXXUnresolvedConstructExpr; // ctor
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Mar  6 14:05:56 2012
> @@ -379,3 +379,13 @@
>  def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
>
>  def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">;
> +
> +// ObjC API warning groups.
> +def ObjCRedundantLiteralUse : DiagGroup<"objc-redundant-literal-use">;
> +def ObjCRedundantAPIUse : DiagGroup<"objc-redundant-api-use", [
> +    ObjCRedundantLiteralUse
> +  ]>;
> +
> +def ObjCCocoaAPI : DiagGroup<"objc-cocoa-api", [
> +    ObjCRedundantAPIUse
> +  ]>;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticIDs.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticIDs.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticIDs.h (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticIDs.h Tue Mar  6 14:05:56 2012
> @@ -36,7 +36,7 @@
>       DIAG_START_SERIALIZATION = DIAG_START_FRONTEND        +  100,
>       DIAG_START_LEX           = DIAG_START_SERIALIZATION   +  120,
>       DIAG_START_PARSE         = DIAG_START_LEX             +  300,
> -      DIAG_START_AST           = DIAG_START_PARSE           +  350,
> +      DIAG_START_AST           = DIAG_START_PARSE           +  400,
>       DIAG_START_SEMA          = DIAG_START_AST             +  100,
>       DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 3000,
>       DIAG_UPPER_LIMIT         = DIAG_START_ANALYSIS        +  100
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Mar  6 14:05:56 2012
> @@ -331,6 +331,8 @@
>  def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
>  def err_illegal_super_cast : Error<
>   "cannot cast 'super' (it isn't an expression)">;
> +def err_nsnumber_nonliteral_unary : Error<
> +  "@%0 must be followed by a number to form an NSNumber object">;
>
>  let CategoryName = "ARC Parse Issue" in {
>  def err_arc_bridge_retain : Error<
> @@ -410,6 +412,8 @@
>   InGroup<CXX98Compat>, DefaultIgnore;
>  def err_expected_catch : Error<"expected catch">;
>  def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
> +def err_expected_rbrace_or_comma : Error<"expected '}' or ','">;
> +def err_expected_rsquare_or_comma : Error<"expected ']' or ','">;
>  def err_using_namespace_in_class : Error<
>   "'using namespace' is not allowed in classes">;
>  def err_destructor_tilde_identifier : Error<
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar  6 14:05:56 2012
> @@ -542,6 +542,7 @@
>   "multiple methods named %0 found">, InGroup<StrictSelector>, DefaultIgnore;
>  def warn_accessor_property_type_mismatch : Warning<
>   "type of property %0 does not match type of accessor %1">;
> +def not_conv_function_declared_at : Note<"type conversion function declared here">;
>  def note_method_declared_at : Note<"method %0 declared here">;
>  def err_setter_type_void : Error<"type of setter must be void">;
>  def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
> @@ -1484,6 +1485,39 @@
>   "the type %0 is already explicitly ownership-qualified">;
>  def err_attribute_not_string : Error<
>   "argument to %0 attribute was not a string literal">;
> +def err_undeclared_nsnumber : Error<
> +  "NSNumber must be available to use Objective-C literals">;
> +def err_invalid_nsnumber_type : Error<
> +  "%0 is not a valid literal type for NSNumber">;
> +def err_undeclared_nsarray : Error<
> +  "NSArray must be available to use Objective-C array literals">;
> +def err_undeclared_nsdictionary : Error<
> +  "NSDictionary must be available to use Objective-C dictionary "
> +  "literals">;
> +def err_undeclared_arraywithobjects : Error<
> +  "declaration of %0 is missing in NSArray class">;
> +def err_undeclared_dictwithobjects : Error<
> +  "declaration of %0 is missing in NSDictionary class">;
> +def err_undeclared_nsnumber_method : Error<
> +  "declaration of %0 is missing in NSNumber class">;
> +def err_objc_literal_method_sig : Error<
> +  "literal construction method %0 has incompatible signature">;
> +def note_objc_literal_method_param : Note<
> +  "%select{first|second|third}0 parameter has unexpected type %1 "
> +  "(should be %2)">;
> +def note_objc_literal_method_return : Note<
> +  "method returns unexpected type %0 (should be an object type)">;
> +def err_invalid_collection_element : Error<
> +  "collection element of type %0 is not an Objective-C object">;
> +def err_box_literal_collection : Error<
> +  "%select{string|character|boolean|numeric}0 literal must be prefixed by '@' "
> +  "in a collection">;
> +
> +let CategoryName = "Cocoa API Issue" in {
> +def warn_objc_redundant_literal_use : Warning<
> +  "using %0 with a literal is redundant">, InGroup<ObjCRedundantLiteralUse>;
> +}
> +
>  def err_only_annotate_after_access_spec : Error<
>   "access specifier can only have annotation attributes">;
>  def err_attribute_section_invalid_for_target : Error<
> @@ -2642,6 +2676,8 @@
>  def note_template_declared_here : Note<
>   "%select{function template|class template|type alias template|template template parameter}0 "
>   "%1 declared here">;
> +def note_parameter_type : Note<
> +  "parameter of type %0 is declared here">;
>
>  // C++11 Variadic Templates
>  def err_template_param_pack_default_arg : Error<
> @@ -3709,6 +3745,33 @@
>   "%0 is not a valid property name (accessing an object of type %1)">;
>  def err_getter_not_found : Error<
>   "expected getter method not found on object of type %0">;
> +def err_objc_subscript_method_not_found : Error<
> +  "expected method to %select{read|write}1 %select{dictionary|array}2 element not "
> +  "found on object of type %0">;
> +def err_objc_subscript_index_type : Error<
> +  "method index parameter type %0 is not integral type">;
> +def err_objc_subscript_key_type : Error<
> +  "method key parameter type %0 is not object type">;
> +def err_objc_subscript_dic_object_type : Error<
> +  "method object parameter type %0 is not object type">;
> +def err_objc_subscript_object_type : Error<
> +  "cannot assign to this %select{dictionary|array}1 because assigning method's 2nd parameter"
> +  " of type %0 is not an objective-C pointer type">;
> +def err_objc_subscript_base_type : Error<
> +  "%select{dictionary|array}1 subscript base type %0 is not an Objective-C object">;
> +def err_objc_multiple_subscript_type_conversion : Error<
> +  "indexing expression is invalid because subscript type %0 has "
> +  "multiple type conversion functions">;
> +def err_objc_subscript_type_conversion : Error<
> +  "indexing expression is invalid because subscript type %0 is not an intergal"
> +  "or objective-C pointer type">;
> +def err_objc_indexing_method_result_type : Error<
> +  "method for accessing %select{dictionary|array}1 element must have Objective-C"
> +  " object return type instead of %0">;
> +def err_objc_index_incomplete_class_type : Error<
> +  "objective-C index expression has incomplete class type %0">;
> +def err_illegal_container_subscripting_op : Error<
> +  "illegal operation on objective-c container subscripting">;
>  def err_property_not_found_forward_class : Error<
>   "property %0 cannot be found in forward class object %1">;
>  def err_property_not_as_forward_class : Error<
> @@ -4438,6 +4501,9 @@
>  def warn_unused_property_expr : Warning<
>  "property access result unused - getters should not be used for side effects">,
>   InGroup<UnusedValue>;
> +def warn_unused_container_subscript_expr : Warning<
> + "container access result unused - container access should not be used for side effects">,
> +  InGroup<UnusedValue>;
>  def warn_unused_call : Warning<
>   "ignoring return value of function declared with %0 attribute">,
>   InGroup<UnusedValue>;
>
> Modified: cfe/trunk/include/clang/Basic/LangOptions.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/LangOptions.def (original)
> +++ cfe/trunk/include/clang/Basic/LangOptions.def Tue Mar  6 14:05:56 2012
> @@ -124,6 +124,7 @@
>  BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
>  BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
>  BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
> +BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger objective-C literals and subscripting support")
>  BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled")
>  BENIGN_LANGOPT(ThreadSanitizer , 1, 0, "ThreadSanitizer enabled")
>
>
> Modified: cfe/trunk/include/clang/Basic/Specifiers.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Specifiers.h (original)
> +++ cfe/trunk/include/clang/Basic/Specifiers.h Tue Mar  6 14:05:56 2012
> @@ -113,7 +113,12 @@
>
>     /// An Objective C property is a logical field of an Objective-C
>     /// object which is read and written via Objective C method calls.
> -    OK_ObjCProperty
> +    OK_ObjCProperty,
> +
> +    /// An Objective C array/dictionary subscripting which reads an object
> +    /// or writes at the subscripted array/dictionary element via
> +    /// Objective C method calls.
> +    OK_ObjCSubscript
>   };
>
>   // \brief Describes the kind of template specialization that a
>
> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Tue Mar  6 14:05:56 2012
> @@ -132,6 +132,9 @@
>
>  // Obj-C Expressions.
>  def ObjCStringLiteral : DStmt<Expr>;
> +def ObjCNumericLiteral : DStmt<Expr>;
> +def ObjCArrayLiteral : DStmt<Expr>;
> +def ObjCDictionaryLiteral : DStmt<Expr>;
>  def ObjCEncodeExpr : DStmt<Expr>;
>  def ObjCMessageExpr : DStmt<Expr>;
>  def ObjCSelectorExpr : DStmt<Expr>;
> @@ -140,6 +143,8 @@
>  def ObjCPropertyRefExpr : DStmt<Expr>;
>  def ObjCIsaExpr : DStmt<Expr>;
>  def ObjCIndirectCopyRestoreExpr : DStmt<Expr>;
> +def ObjCBoolLiteralExpr : DStmt<Expr>;
> +def ObjCSubscriptRefExpr : DStmt<Expr>;
>
>  // Obj-C ARC Expressions.
>  def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>;
>
> Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
> +++ cfe/trunk/include/clang/Basic/TokenKinds.def Tue Mar  6 14:05:56 2012
> @@ -258,6 +258,9 @@
>  KEYWORD(_Imaginary                  , KEYALL)
>  KEYWORD(_Static_assert              , KEYALL)
>  KEYWORD(__func__                    , KEYALL)
> +KEYWORD(__objc_yes                  , KEYALL)
> +KEYWORD(__objc_no                   , KEYALL)
> +
>
>  // C++ 2.11p1: Keywords.
>  KEYWORD(asm                         , KEYCXX|KEYGNU)
>
> Modified: cfe/trunk/include/clang/Driver/CC1Options.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/CC1Options.td (original)
> +++ cfe/trunk/include/clang/Driver/CC1Options.td Tue Mar  6 14:05:56 2012
> @@ -661,6 +661,8 @@
>   HelpText<"Enable special debugger support behavior">;
>  def fdebugger_cast_result_to_id : Flag<"-fdebugger-cast-result-to-id">,
>   HelpText<"Enable casting unknown expression results to id">;
> +def fdebugger_objc_literal : Flag<"-fdebugger-objc-literal">,
> +  HelpText<"Enable special debugger support for objective-C subscripting and literals">;
>  def fdeprecated_macro : Flag<"-fdeprecated-macro">,
>   HelpText<"Defines the __DEPRECATED macro">;
>  def fno_deprecated_macro : Flag<"-fno-deprecated-macro">,
>
> Modified: cfe/trunk/include/clang/Driver/ObjCRuntime.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ObjCRuntime.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/ObjCRuntime.h (original)
> +++ cfe/trunk/include/clang/Driver/ObjCRuntime.h Tue Mar  6 14:05:56 2012
> @@ -30,6 +30,9 @@
>   /// True if the runtime supports ARC zeroing __weak.
>   unsigned HasWeak : 1;
>
> +  /// \brief True if the runtime supports subscripting methods.
> +  unsigned HasSubscripting : 1;
> +
>   /// True if the runtime provides the following entrypoint:
>   ///   void objc_terminate(void);
>   /// If available, this will be called instead of abort() when an
> @@ -37,7 +40,7 @@
>   unsigned HasTerminate : 1;
>
>   ObjCRuntime() : RuntimeKind(NeXT), HasARC(false), HasWeak(false),
> -    HasTerminate(false) {}
> +    HasSubscripting(false), HasTerminate(false) {}
>  };
>
>  }
>
> Modified: cfe/trunk/include/clang/Driver/Options.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/Options.td (original)
> +++ cfe/trunk/include/clang/Driver/Options.td Tue Mar  6 14:05:56 2012
> @@ -463,6 +463,7 @@
>                                       Group<f_Group>;
>  def fno_objc_infer_related_result_type : Flag<
>   "-fno-objc-infer-related-result-type">, Group<f_Group>;
> +def fobjc_link_runtime: Flag<"-fobjc-link-runtime">, Group<f_Group>;
>
>  // Objective-C ABI options.
>  def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>;
>
> Modified: cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PreprocessorOptions.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Frontend/PreprocessorOptions.h (original)
> +++ cfe/trunk/include/clang/Frontend/PreprocessorOptions.h Tue Mar  6 14:05:56 2012
> @@ -10,6 +10,7 @@
>  #ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
>  #define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
>
> +#include "llvm/ADT/SmallVector.h"
>  #include "llvm/ADT/StringRef.h"
>  #include <cassert>
>  #include <string>
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Tue Mar  6 14:05:56 2012
> @@ -1362,6 +1362,8 @@
>   ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
>
>   ExprResult ParseGenericSelectionExpression();
> +
> +  ExprResult ParseObjCBoolLiteral();
>
>   //===--------------------------------------------------------------------===//
>   // C++ Expressions
> @@ -1490,6 +1492,11 @@
>   // Objective-C Expressions
>   ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
>   ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
> +  ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
> +  ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
> +  ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
> +  ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
> +  ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
>   ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
>   ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
>   ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
> @@ -1503,7 +1510,7 @@
>       SourceLocation LBracloc, SourceLocation SuperLoc,
>       ParsedType ReceiverType, ExprArg ReceiverExpr);
>   bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
> -
> +
>   //===--------------------------------------------------------------------===//
>   // C99 6.8: Statements and Blocks.
>
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar  6 14:05:56 2012
> @@ -25,9 +25,11 @@
>  #include "clang/Sema/TypoCorrection.h"
>  #include "clang/Sema/Weak.h"
>  #include "clang/AST/Expr.h"
> +#include "clang/AST/ExprObjC.h"
>  #include "clang/AST/DeclarationName.h"
>  #include "clang/AST/ExternalASTSource.h"
>  #include "clang/AST/TypeLoc.h"
> +#include "clang/AST/NSAPI.h"
>  #include "clang/Lex/ModuleLoader.h"
>  #include "clang/Basic/Specifiers.h"
>  #include "clang/Basic/TemplateKinds.h"
> @@ -511,11 +513,34 @@
>   /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files.
>   RecordDecl *MSVCGuidDecl;
>
> +  /// \brief Caches identifiers/selectors for NSFoundation APIs.
> +  llvm::OwningPtr<NSAPI> NSAPIObj;
> +
> +  /// \brief The declaration of the Objective-C NSNumber class.
> +  ObjCInterfaceDecl *NSNumberDecl;
> +
> +  /// \brief The Objective-C NSNumber methods used to create NSNumber literals.
> +  ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
> +
> +  /// \brief The declaration of the Objective-C NSArray class.
> +  ObjCInterfaceDecl *NSArrayDecl;
> +
> +  /// \brief The declaration of the arrayWithObjects:count: method.
> +  ObjCMethodDecl *ArrayWithObjectsMethod;
> +
> +  /// \brief The declaration of the Objective-C NSDictionary class.
> +  ObjCInterfaceDecl *NSDictionaryDecl;
> +
> +  /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method.
> +  ObjCMethodDecl *DictionaryWithObjectsMethod;
> +
> +  /// \brief id<NSCopying> type.
> +  QualType QIDNSCopying;
> +
>   /// A flag to remember whether the implicit forms of operator new and delete
>   /// have been declared.
>   bool GlobalNewDeleteDeclared;
>
> -
>   /// A flag that is set when parsing a -dealloc method and no [super dealloc]
>   /// call was found yet.
>   bool ObjCShouldCallSuperDealloc;
> @@ -1500,6 +1525,12 @@
>                                      const PartialDiagnostic &AmbigNote,
>                                      const PartialDiagnostic &ConvDiag,
>                                      bool AllowScopedEnumerations);
> +  enum ObjCSubscriptKind {
> +    OS_Array,
> +    OS_Dictionary,
> +    OS_Error
> +  };
> +  ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE);
>
>   ExprResult PerformObjectMemberConversion(Expr *From,
>                                            NestedNameSpecifier *Qualifier,
> @@ -2515,6 +2546,7 @@
>                                       NamedDecl *D);
>
>   ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
> +  ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
>   ExprResult ActOnNumericConstant(const Token &Tok);
>   ExprResult ActOnCharacterConstant(const Token &Tok);
>   ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
> @@ -3232,6 +3264,10 @@
>
>   /// ActOnCXXBoolLiteral - Parse {true,false} literals.
>   ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
> +
> +
> +  /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
> +  ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
>
>   /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
>   ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
> @@ -3664,7 +3700,26 @@
>   ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
>                                     Expr **Strings,
>                                     unsigned NumStrings);
> -
> +
> +  ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S);
> +
> +  /// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the
> +  /// numeric literal expression. Type of the expression will be "NSNumber *"
> +  /// or "id" if NSNumber is unavailable.
> +  ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number);
> +  ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc,
> +                                  bool Value);
> +  ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements);
> +
> +  ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
> +                                          Expr *IndexExpr,
> +                                          ObjCMethodDecl *getterMethod,
> +                                          ObjCMethodDecl *setterMethod);
> +
> +  ExprResult BuildObjCDictionaryLiteral(SourceRange SR,
> +                                        ObjCDictionaryElement *Elements,
> +                                        unsigned NumElements);
> +
>   ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc,
>                                   TypeSourceInfo *EncodedTypeInfo,
>                                   SourceLocation RParenLoc);
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Mar  6 14:05:56 2012
> @@ -1065,6 +1065,12 @@
>
>       /// \brief An ObjCStringLiteral record.
>       EXPR_OBJC_STRING_LITERAL,
> +
> +      EXPR_OBJC_NUMERIC_LITERAL,
> +      EXPR_OBJC_ARRAY_LITERAL,
> +      EXPR_OBJC_DICTIONARY_LITERAL,
> +
> +
>       /// \brief An ObjCEncodeExpr record.
>       EXPR_OBJC_ENCODE,
>       /// \brief An ObjCSelectorExpr record.
> @@ -1075,6 +1081,8 @@
>       EXPR_OBJC_IVAR_REF_EXPR,
>       /// \brief An ObjCPropertyRefExpr record.
>       EXPR_OBJC_PROPERTY_REF_EXPR,
> +      /// \brief An ObjCSubscriptRefExpr record.
> +      EXPR_OBJC_SUBSCRIPT_REF_EXPR,
>       /// \brief UNUSED
>       EXPR_OBJC_KVC_REF_EXPR,
>       /// \brief An ObjCMessageExpr record.
> @@ -1098,6 +1106,8 @@
>       STMT_OBJC_AT_THROW,
>       /// \brief An ObjCAutoreleasePoolStmt record.
>       STMT_OBJC_AUTORELEASE_POOL,
> +      /// \brief A ObjCBoolLiteralExpr record.
> +      EXPR_OBJC_BOOL_LITERAL,
>
>       // C++
>
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Tue Mar  6 14:05:56 2012
> @@ -477,7 +477,10 @@
>   InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
>   InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
>   InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
> -
> +
> +  // Builtin type for __objc_yes and __objc_no
> +  ObjCBuiltinBoolTy = SignedCharTy;
> +
>   ObjCConstantStringType = QualType();
>
>   // void * type
>
> Modified: cfe/trunk/lib/AST/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/CMakeLists.txt (original)
> +++ cfe/trunk/lib/AST/CMakeLists.txt Tue Mar  6 14:05:56 2012
> @@ -33,6 +33,7 @@
>   MicrosoftCXXABI.cpp
>   MicrosoftMangle.cpp
>   NestedNameSpecifier.cpp
> +  NSAPI.cpp
>   ParentMap.cpp
>   RecordLayout.cpp
>   RecordLayoutBuilder.cpp
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Tue Mar  6 14:05:56 2012
> @@ -2089,6 +2089,16 @@
>     // specs.
>   case ObjCMessageExprClass:
>   case ObjCPropertyRefExprClass:
> +  case ObjCSubscriptRefExprClass:
> +    return CT_Can;
> +
> +    // All the ObjC literals that are implemented as calls are
> +    // potentially throwing unless we decide to close off that
> +    // possibility.
> +  case ObjCArrayLiteralClass:
> +  case ObjCBoolLiteralExprClass:
> +  case ObjCDictionaryLiteralClass:
> +  case ObjCNumericLiteralClass:
>     return CT_Can;
>
>     // Many other things have subexpressions, so we have to test those.
> @@ -3637,6 +3647,117 @@
>   ExprBits.InstantiationDependent = InstantiationDependent;
>  }
>
> +ObjCArrayLiteral::ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
> +                                   QualType T, ObjCMethodDecl *Method,
> +                                   SourceRange SR)
> +  : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary,
> +         false, false, false, false),
> +    NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method)
> +{
> +  Expr **SaveElements = getElements();
> +  for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
> +    if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
> +      ExprBits.ValueDependent = true;
> +    if (Elements[I]->isInstantiationDependent())
> +      ExprBits.InstantiationDependent = true;
> +    if (Elements[I]->containsUnexpandedParameterPack())
> +      ExprBits.ContainsUnexpandedParameterPack = true;
> +
> +    SaveElements[I] = Elements[I];
> +  }
> +}
> +
> +ObjCArrayLiteral *ObjCArrayLiteral::Create(ASTContext &C,
> +                                           llvm::ArrayRef<Expr *> Elements,
> +                                           QualType T, ObjCMethodDecl * Method,
> +                                           SourceRange SR) {
> +  void *Mem = C.Allocate(sizeof(ObjCArrayLiteral)
> +                         + Elements.size() * sizeof(Expr *));
> +  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
> +}
> +
> +ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(ASTContext &C,
> +                                                unsigned NumElements) {
> +
> +  void *Mem = C.Allocate(sizeof(ObjCArrayLiteral)
> +                         + NumElements * sizeof(Expr *));
> +  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
> +}
> +
> +ObjCDictionaryLiteral::ObjCDictionaryLiteral(
> +                                             ArrayRef<ObjCDictionaryElement> VK,
> +                                             bool HasPackExpansions,
> +                                             QualType T, ObjCMethodDecl *method,
> +                                             SourceRange SR)
> +  : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
> +         false, false),
> +    NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
> +    DictWithObjectsMethod(method)
> +{
> +  KeyValuePair *KeyValues = getKeyValues();
> +  ExpansionData *Expansions = getExpansionData();
> +  for (unsigned I = 0; I < NumElements; I++) {
> +    if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
> +        VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
> +      ExprBits.ValueDependent = true;
> +    if (VK[I].Key->isInstantiationDependent() ||
> +        VK[I].Value->isInstantiationDependent())
> +      ExprBits.InstantiationDependent = true;
> +    if (VK[I].EllipsisLoc.isInvalid() &&
> +        (VK[I].Key->containsUnexpandedParameterPack() ||
> +         VK[I].Value->containsUnexpandedParameterPack()))
> +      ExprBits.ContainsUnexpandedParameterPack = true;
> +
> +    KeyValues[I].Key = VK[I].Key;
> +    KeyValues[I].Value = VK[I].Value;
> +    if (Expansions) {
> +      Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
> +      if (VK[I].NumExpansions)
> +        Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
> +      else
> +        Expansions[I].NumExpansionsPlusOne = 0;
> +    }
> +  }
> +}
> +
> +ObjCDictionaryLiteral *
> +ObjCDictionaryLiteral::Create(ASTContext &C,
> +                              ArrayRef<ObjCDictionaryElement> VK,
> +                              bool HasPackExpansions,
> +                              QualType T, ObjCMethodDecl *method,
> +                              SourceRange SR) {
> +  unsigned ExpansionsSize = 0;
> +  if (HasPackExpansions)
> +    ExpansionsSize = sizeof(ExpansionData) * VK.size();
> +
> +  void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
> +                         sizeof(KeyValuePair) * VK.size() + ExpansionsSize);
> +  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
> +}
> +
> +ObjCDictionaryLiteral *
> +ObjCDictionaryLiteral::CreateEmpty(ASTContext &C, unsigned NumElements,
> +                                   bool HasPackExpansions) {
> +  unsigned ExpansionsSize = 0;
> +  if (HasPackExpansions)
> +    ExpansionsSize = sizeof(ExpansionData) * NumElements;
> +  void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
> +                         sizeof(KeyValuePair) * NumElements + ExpansionsSize);
> +  return new (Mem) ObjCDictionaryLiteral(EmptyShell(), NumElements,
> +                                         HasPackExpansions);
> +}
> +
> +ObjCSubscriptRefExpr *ObjCSubscriptRefExpr::Create(ASTContext &C,
> +                                                   Expr *base,
> +                                                   Expr *key, QualType T,
> +                                                   ObjCMethodDecl *getMethod,
> +                                                   ObjCMethodDecl *setMethod,
> +                                                   SourceLocation RB) {
> +  void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr));
> +  return new (Mem) ObjCSubscriptRefExpr(base, key, T, VK_LValue,
> +                                        OK_ObjCSubscript,
> +                                        getMethod, setMethod, RB);
> +}
>
>  AtomicExpr::AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr,
>                        QualType t, AtomicOp op, SourceLocation RP)
>
> Modified: cfe/trunk/lib/AST/ExprClassification.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprClassification.cpp (original)
> +++ cfe/trunk/lib/AST/ExprClassification.cpp Tue Mar  6 14:05:56 2012
> @@ -108,6 +108,7 @@
>     // __func__ and friends are too.
>   case Expr::PredefinedExprClass:
>     // Property references are lvalues
> +  case Expr::ObjCSubscriptRefExprClass:
>   case Expr::ObjCPropertyRefExprClass:
>     // C++ [expr.typeid]p1: The result of a typeid expression is an lvalue of...
>   case Expr::CXXTypeidExprClass:
> @@ -157,6 +158,10 @@
>   case Expr::ObjCSelectorExprClass:
>   case Expr::ObjCProtocolExprClass:
>   case Expr::ObjCStringLiteralClass:
> +  case Expr::ObjCNumericLiteralClass:
> +  case Expr::ObjCArrayLiteralClass:
> +  case Expr::ObjCDictionaryLiteralClass:
> +  case Expr::ObjCBoolLiteralExprClass:
>   case Expr::ParenListExprClass:
>   case Expr::SizeOfPackExprClass:
>   case Expr::SubstNonTypeTemplateParmPackExprClass:
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Mar  6 14:05:56 2012
> @@ -3058,6 +3058,8 @@
>   bool VisitUnaryAddrOf(const UnaryOperator *E);
>   bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
>       { return Success(E); }
> +  bool VisitObjCNumericLiteral(const ObjCNumericLiteral *E)
> +      { return Success(E); }
>   bool VisitAddrLabelExpr(const AddrLabelExpr *E)
>       { return Success(E); }
>   bool VisitCallExpr(const CallExpr *E);
> @@ -4051,6 +4053,10 @@
>     return Success(E->getValue(), E);
>   }
>
> +  bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
> +    return Success(E->getValue(), E);
> +  }
> +
>   // Note, GNU defines __null as an integer, not a pointer.
>   bool VisitGNUNullExpr(const GNUNullExpr *E) {
>     return ZeroInitialization(E);
> @@ -6256,12 +6262,16 @@
>   case Expr::CXXDependentScopeMemberExprClass:
>   case Expr::UnresolvedMemberExprClass:
>   case Expr::ObjCStringLiteralClass:
> +  case Expr::ObjCNumericLiteralClass:
> +  case Expr::ObjCArrayLiteralClass:
> +  case Expr::ObjCDictionaryLiteralClass:
>   case Expr::ObjCEncodeExprClass:
>   case Expr::ObjCMessageExprClass:
>   case Expr::ObjCSelectorExprClass:
>   case Expr::ObjCProtocolExprClass:
>   case Expr::ObjCIvarRefExprClass:
>   case Expr::ObjCPropertyRefExprClass:
> +  case Expr::ObjCSubscriptRefExprClass:
>   case Expr::ObjCIsaExprClass:
>   case Expr::ShuffleVectorExprClass:
>   case Expr::BlockExprClass:
> @@ -6294,6 +6304,7 @@
>     return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
>   case Expr::IntegerLiteralClass:
>   case Expr::CharacterLiteralClass:
> +  case Expr::ObjCBoolLiteralExprClass:
>   case Expr::CXXBoolLiteralExprClass:
>   case Expr::CXXScalarValueInitExprClass:
>   case Expr::UnaryTypeTraitExprClass:
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Mar  6 14:05:56 2012
> @@ -2374,6 +2374,10 @@
>   case Expr::ObjCProtocolExprClass:
>   case Expr::ObjCSelectorExprClass:
>   case Expr::ObjCStringLiteralClass:
> +  case Expr::ObjCNumericLiteralClass:
> +  case Expr::ObjCArrayLiteralClass:
> +  case Expr::ObjCDictionaryLiteralClass:
> +  case Expr::ObjCSubscriptRefExprClass:
>   case Expr::ObjCIndirectCopyRestoreExprClass:
>   case Expr::OffsetOfExprClass:
>   case Expr::PredefinedExprClass:
> @@ -2814,6 +2818,13 @@
>     Out << 'E';
>     break;
>
> +  // FIXME. __objc_yes/__objc_no are mangled same as true/false
> +  case Expr::ObjCBoolLiteralExprClass:
> +    Out << "Lb";
> +    Out << (cast<ObjCBoolLiteralExpr>(E)->getValue() ? '1' : '0');
> +    Out << 'E';
> +    break;
> +
>   case Expr::CXXBoolLiteralExprClass:
>     Out << "Lb";
>     Out << (cast<CXXBoolLiteralExpr>(E)->getValue() ? '1' : '0');
>
> Added: cfe/trunk/lib/AST/NSAPI.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NSAPI.cpp?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/lib/AST/NSAPI.cpp (added)
> +++ cfe/trunk/lib/AST/NSAPI.cpp Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,311 @@
> +//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "clang/AST/NSAPI.h"
> +#include "clang/AST/ASTContext.h"
> +
> +using namespace clang;
> +
> +NSAPI::NSAPI(ASTContext &ctx)
> +  : Ctx(ctx), ClassIds() {
> +}
> +
> +IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
> +  static const char *ClassName[NumClassIds] = {
> +    "NSString",
> +    "NSArray",
> +    "NSMutableArray",
> +    "NSDictionary",
> +    "NSMutableDictionary",
> +    "NSNumber"
> +  };
> +
> +  if (!ClassIds[K])
> +    return (ClassIds[K] = &Ctx.Idents.get(ClassName[K]));
> +
> +  return ClassIds[K];
> +}
> +
> +Selector NSAPI::getNSStringSelector(NSStringMethodKind MK) const {
> +  if (NSStringSelectors[MK].isNull()) {
> +    Selector Sel;
> +    switch (MK) {
> +    case NSStr_stringWithString:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("stringWithString"));
> +      break;
> +    case NSStr_initWithString:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithString"));
> +      break;
> +    }
> +    return (NSStringSelectors[MK] = Sel);
> +  }
> +
> +  return NSStringSelectors[MK];
> +}
> +
> +Selector NSAPI::getNSArraySelector(NSArrayMethodKind MK) const {
> +  if (NSArraySelectors[MK].isNull()) {
> +    Selector Sel;
> +    switch (MK) {
> +    case NSArr_array:
> +      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("array"));
> +      break;
> +    case NSArr_arrayWithArray:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithArray"));
> +      break;
> +    case NSArr_arrayWithObject:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObject"));
> +      break;
> +    case NSArr_arrayWithObjects:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("arrayWithObjects"));
> +      break;
> +    case NSArr_arrayWithObjectsCount: {
> +      IdentifierInfo *KeyIdents[] = {
> +        &Ctx.Idents.get("arrayWithObjects"),
> +        &Ctx.Idents.get("count")
> +      };
> +      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
> +      break;
> +    }
> +    case NSArr_initWithArray:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithArray"));
> +      break;
> +    case NSArr_initWithObjects:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("initWithObjects"));
> +      break;
> +    case NSArr_objectAtIndex:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectAtIndex"));
> +      break;
> +    case NSMutableArr_replaceObjectAtIndex: {
> +      IdentifierInfo *KeyIdents[] = {
> +        &Ctx.Idents.get("replaceObjectAtIndex"),
> +        &Ctx.Idents.get("withObject")
> +      };
> +      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
> +      break;
> +    }
> +    }
> +    return (NSArraySelectors[MK] = Sel);
> +  }
> +
> +  return NSArraySelectors[MK];
> +}
> +
> +llvm::Optional<NSAPI::NSArrayMethodKind>
> +NSAPI::getNSArrayMethodKind(Selector Sel) {
> +  for (unsigned i = 0; i != NumNSArrayMethods; ++i) {
> +    NSArrayMethodKind MK = NSArrayMethodKind(i);
> +    if (Sel == getNSArraySelector(MK))
> +      return MK;
> +  }
> +
> +  return llvm::Optional<NSArrayMethodKind>();
> +}
> +
> +Selector NSAPI::getNSDictionarySelector(
> +                                       NSDictionaryMethodKind MK) const {
> +  if (NSDictionarySelectors[MK].isNull()) {
> +    Selector Sel;
> +    switch (MK) {
> +    case NSDict_dictionary:
> +      Sel = Ctx.Selectors.getNullarySelector(&Ctx.Idents.get("dictionary"));
> +      break;
> +    case NSDict_dictionaryWithDictionary:
> +      Sel = Ctx.Selectors.getUnarySelector(
> +                                   &Ctx.Idents.get("dictionaryWithDictionary"));
> +      break;
> +    case NSDict_dictionaryWithObjectForKey: {
> +      IdentifierInfo *KeyIdents[] = {
> +        &Ctx.Idents.get("dictionaryWithObject"),
> +        &Ctx.Idents.get("forKey")
> +      };
> +      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
> +      break;
> +    }
> +    case NSDict_dictionaryWithObjectsForKeys: {
> +      IdentifierInfo *KeyIdents[] = {
> +        &Ctx.Idents.get("dictionaryWithObjects"),
> +        &Ctx.Idents.get("forKeys")
> +      };
> +      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
> +      break;
> +    }
> +    case NSDict_dictionaryWithObjectsForKeysCount: {
> +      IdentifierInfo *KeyIdents[] = {
> +        &Ctx.Idents.get("dictionaryWithObjects"),
> +        &Ctx.Idents.get("forKeys"),
> +        &Ctx.Idents.get("count")
> +      };
> +      Sel = Ctx.Selectors.getSelector(3, KeyIdents);
> +      break;
> +    }
> +    case NSDict_dictionaryWithObjectsAndKeys:
> +      Sel = Ctx.Selectors.getUnarySelector(
> +                               &Ctx.Idents.get("dictionaryWithObjectsAndKeys"));
> +      break;
> +    case NSDict_initWithDictionary:
> +      Sel = Ctx.Selectors.getUnarySelector(
> +                                         &Ctx.Idents.get("initWithDictionary"));
> +      break;
> +    case NSDict_initWithObjectsAndKeys:
> +      Sel = Ctx.Selectors.getUnarySelector(
> +                                     &Ctx.Idents.get("initWithObjectsAndKeys"));
> +      break;
> +    case NSDict_objectForKey:
> +      Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("objectForKey"));
> +      break;
> +    case NSMutableDict_setObjectForKey: {
> +      IdentifierInfo *KeyIdents[] = {
> +        &Ctx.Idents.get("setObject"),
> +        &Ctx.Idents.get("forKey")
> +      };
> +      Sel = Ctx.Selectors.getSelector(2, KeyIdents);
> +      break;
> +    }
> +    }
> +    return (NSDictionarySelectors[MK] = Sel);
> +  }
> +
> +  return NSDictionarySelectors[MK];
> +}
> +
> +llvm::Optional<NSAPI::NSDictionaryMethodKind>
> +NSAPI::getNSDictionaryMethodKind(Selector Sel) {
> +  for (unsigned i = 0; i != NumNSDictionaryMethods; ++i) {
> +    NSDictionaryMethodKind MK = NSDictionaryMethodKind(i);
> +    if (Sel == getNSDictionarySelector(MK))
> +      return MK;
> +  }
> +
> +  return llvm::Optional<NSDictionaryMethodKind>();
> +}
> +
> +Selector NSAPI::getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
> +                                           bool Instance) const {
> +  static const char *ClassSelectorName[NumNSNumberLiteralMethods] = {
> +    "numberWithChar",
> +    "numberWithUnsignedChar",
> +    "numberWithShort",
> +    "numberWithUnsignedShort",
> +    "numberWithInt",
> +    "numberWithUnsignedInt",
> +    "numberWithLong",
> +    "numberWithUnsignedLong",
> +    "numberWithLongLong",
> +    "numberWithUnsignedLongLong",
> +    "numberWithFloat",
> +    "numberWithDouble",
> +    "numberWithBool",
> +    "numberWithInteger",
> +    "numberWithUnsignedInteger"
> +  };
> +  static const char *InstanceSelectorName[NumNSNumberLiteralMethods] = {
> +    "initWithChar",
> +    "initWithUnsignedChar",
> +    "initWithShort",
> +    "initWithUnsignedShort",
> +    "initWithInt",
> +    "initWithUnsignedInt",
> +    "initWithLong",
> +    "initWithUnsignedLong",
> +    "initWithLongLong",
> +    "initWithUnsignedLongLong",
> +    "initWithFloat",
> +    "initWithDouble",
> +    "initWithBool",
> +    "initWithInteger",
> +    "initWithUnsignedInteger"
> +  };
> +
> +  Selector *Sels;
> +  const char **Names;
> +  if (Instance) {
> +    Sels = NSNumberInstanceSelectors;
> +    Names = InstanceSelectorName;
> +  } else {
> +    Sels = NSNumberClassSelectors;
> +    Names = ClassSelectorName;
> +  }
> +
> +  if (Sels[MK].isNull())
> +    Sels[MK] = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(Names[MK]));
> +  return Sels[MK];
> +}
> +
> +llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
> +NSAPI::getNSNumberLiteralMethodKind(Selector Sel) const {
> +  for (unsigned i = 0; i != NumNSNumberLiteralMethods; ++i) {
> +    NSNumberLiteralMethodKind MK = NSNumberLiteralMethodKind(i);
> +    if (isNSNumberLiteralSelector(MK, Sel))
> +      return MK;
> +  }
> +
> +  return llvm::Optional<NSNumberLiteralMethodKind>();
> +}
> +
> +llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
> +NSAPI::getNSNumberFactoryMethodKind(QualType T) {
> +  const BuiltinType *BT = T->getAs<BuiltinType>();
> +  if (!BT)
> +    return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
> +
> +  switch (BT->getKind()) {
> +  case BuiltinType::Char_S:
> +  case BuiltinType::SChar:
> +    return NSAPI::NSNumberWithChar;
> +  case BuiltinType::Char_U:
> +  case BuiltinType::UChar:
> +    return NSAPI::NSNumberWithUnsignedChar;
> +  case BuiltinType::Short:
> +    return NSAPI::NSNumberWithShort;
> +  case BuiltinType::UShort:
> +    return NSAPI::NSNumberWithUnsignedShort;
> +  case BuiltinType::Int:
> +    return NSAPI::NSNumberWithInt;
> +  case BuiltinType::UInt:
> +    return NSAPI::NSNumberWithUnsignedInt;
> +  case BuiltinType::Long:
> +    return NSAPI::NSNumberWithLong;
> +  case BuiltinType::ULong:
> +    return NSAPI::NSNumberWithUnsignedLong;
> +  case BuiltinType::LongLong:
> +    return NSAPI::NSNumberWithLongLong;
> +  case BuiltinType::ULongLong:
> +    return NSAPI::NSNumberWithUnsignedLongLong;
> +  case BuiltinType::Float:
> +    return NSAPI::NSNumberWithFloat;
> +  case BuiltinType::Double:
> +    return NSAPI::NSNumberWithDouble;
> +  case BuiltinType::Bool:
> +    return NSAPI::NSNumberWithBool;
> +
> +  case BuiltinType::Void:
> +  case BuiltinType::WChar_U:
> +  case BuiltinType::WChar_S:
> +  case BuiltinType::Char16:
> +  case BuiltinType::Char32:
> +  case BuiltinType::Int128:
> +  case BuiltinType::LongDouble:
> +  case BuiltinType::UInt128:
> +  case BuiltinType::NullPtr:
> +  case BuiltinType::ObjCClass:
> +  case BuiltinType::ObjCId:
> +  case BuiltinType::ObjCSel:
> +  case BuiltinType::BoundMember:
> +  case BuiltinType::Dependent:
> +  case BuiltinType::Overload:
> +  case BuiltinType::UnknownAny:
> +  case BuiltinType::ARCUnbridgedCast:
> +  case BuiltinType::Half:
> +  case BuiltinType::PseudoObject:
> +    break;
> +  }
> +
> +  return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
> +}
>
> Modified: cfe/trunk/lib/AST/StmtDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtDumper.cpp (original)
> +++ cfe/trunk/lib/AST/StmtDumper.cpp Tue Mar  6 14:05:56 2012
> @@ -112,6 +112,7 @@
>       case OK_Ordinary: break;
>       case OK_BitField: OS << " bitfield"; break;
>       case OK_ObjCProperty: OS << " objcproperty"; break;
> +      case OK_ObjCSubscript: OS << " objcsubscript"; break;
>       case OK_VectorComponent: OS << " vectorcomponent"; break;
>       }
>     }
> @@ -168,7 +169,9 @@
>     void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
>     void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
>     void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
> +    void VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node);
>     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
> +    void VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node);
>   };
>  }
>
> @@ -682,6 +685,32 @@
>     OS << " super";
>  }
>
> +void StmtDumper::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
> +  DumpExpr(Node);
> +  if (Node->isArraySubscriptRefExpr())
> +    OS << " Kind=ArraySubscript GetterForArray=\"";
> +  else
> +    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
> +  if (Node->getAtIndexMethodDecl())
> +    OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
> +  else
> +    OS << "(null)";
> +
> +  if (Node->isArraySubscriptRefExpr())
> +    OS << "\" SetterForArray=\"";
> +  else
> +    OS << "\" SetterForDictionary=\"";
> +  if (Node->setAtIndexMethodDecl())
> +    OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
> +  else
> +    OS << "(null)";
> +}
> +
> +void StmtDumper::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
> +  DumpExpr(Node);
> +  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
> +}
> +
>  //===----------------------------------------------------------------------===//
>  // Stmt method implementations
>  //===----------------------------------------------------------------------===//
>
> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Mar  6 14:05:56 2012
> @@ -603,6 +603,14 @@
>     OS << Node->getExplicitProperty()->getName();
>  }
>
> +void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
> +
> +  PrintExpr(Node->getBaseExpr());
> +  OS << "[";
> +  PrintExpr(Node->getKeyExpr());
> +  OS << "]";
> +}
> +
>  void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
>   switch (Node->getIdentType()) {
>     default:
> @@ -1646,6 +1654,41 @@
>   VisitStringLiteral(Node->getString());
>  }
>
> +void StmtPrinter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
> +  OS << "@";
> +  Visit(E->getNumber());
> +}
> +
> +void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
> +  OS << "@[ ";
> +  StmtRange ch = E->children();
> +  if (ch.first != ch.second) {
> +    while (1) {
> +      Visit(*ch.first);
> +      ++ch.first;
> +      if (ch.first == ch.second) break;
> +      OS << ", ";
> +    }
> +  }
> +  OS << " ]";
> +}
> +
> +void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
> +  OS << "@{ ";
> +  for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
> +    if (I > 0)
> +      OS << ", ";
> +
> +    ObjCDictionaryElement Element = E->getKeyValueElement(I);
> +    Visit(Element.Key);
> +    OS << " : ";
> +    Visit(Element.Value);
> +    if (Element.isPackExpansion())
> +      OS << "...";
> +  }
> +  OS << " }";
> +}
> +
>  void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
>   OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')';
>  }
> @@ -1696,6 +1739,10 @@
>   OS << "]";
>  }
>
> +void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
> +  OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
> +}
> +
>  void
>  StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
>   PrintExpr(E->getSubExpr());
>
> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
> +++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Mar  6 14:05:56 2012
> @@ -978,6 +978,18 @@
>   VisitExpr(S);
>  }
>
> +void StmtProfiler::VisitObjCNumericLiteral(const ObjCNumericLiteral *E) {
> +  VisitExpr(E);
> +}
> +
> +void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
> +  VisitExpr(E);
> +}
> +
> +void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
> +  VisitExpr(E);
> +}
> +
>  void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
>   VisitExpr(S);
>   VisitType(S->getEncodedType());
> @@ -1014,6 +1026,12 @@
>   }
>  }
>
> +void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
> +  VisitExpr(S);
> +  VisitDecl(S->getAtIndexMethodDecl());
> +  VisitDecl(S->setAtIndexMethodDecl());
> +}
> +
>  void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
>   VisitExpr(S);
>   VisitName(S->getSelector());
> @@ -1025,6 +1043,11 @@
>   ID.AddBoolean(S->isArrow());
>  }
>
> +void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
> +  VisitExpr(S);
> +  ID.AddBoolean(S->getValue());
> +}
> +
>  void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
>     const ObjCIndirectCopyRestoreExpr *S) {
>   VisitExpr(S);
>
> Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Mar  6 14:05:56 2012
> @@ -177,6 +177,9 @@
>   Value *VisitCharacterLiteral(const CharacterLiteral *E) {
>     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
>   }
> +  Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
> +    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
> +  }
>   Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
>     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
>   }
> @@ -519,6 +522,15 @@
>   Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
>     return CGF.EmitObjCStringLiteral(E);
>   }
> +  Value *VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
> +    return CGF.EmitObjCNumericLiteral(E);
> +  }
> +  Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
> +    return CGF.EmitObjCArrayLiteral(E);
> +  }
> +  Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
> +    return CGF.EmitObjCDictionaryLiteral(E);
> +  }
>   Value *VisitAsTypeExpr(AsTypeExpr *CE);
>   Value *VisitAtomicExpr(AtomicExpr *AE);
>  };
>
> Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Mar  6 14:05:56 2012
> @@ -29,6 +29,10 @@
>  typedef llvm::PointerIntPair<llvm::Value*,1,bool> TryEmitResult;
>  static TryEmitResult
>  tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e);
> +static RValue AdjustRelatedResultType(CodeGenFunction &CGF,
> +                                      const Expr *E,
> +                                      const ObjCMethodDecl *Method,
> +                                      RValue Result);
>
>  /// Given the address of a variable of pointer type, find the correct
>  /// null to store into it.
> @@ -47,6 +51,138 @@
>   return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
>  }
>
> +/// EmitObjCNumericLiteral - This routine generates code for
> +/// the appropriate +[NSNumber numberWith<Type>:] method.
> +///
> +llvm::Value *CodeGenFunction::EmitObjCNumericLiteral(const ObjCNumericLiteral *E) {
> +  // Generate the correct selector for this literal's concrete type.
> +  const Expr *NL = E->getNumber();
> +  // Get the method.
> +  const ObjCMethodDecl *Method = E->getObjCNumericLiteralMethod();
> +  assert(Method && "NSNumber method is null");
> +  Selector Sel = Method->getSelector();
> +
> +  // Generate a reference to the class pointer, which will be the receiver.
> +  QualType ResultType = E->getType(); // should be NSNumber *
> +  const ObjCObjectPointerType *InterfacePointerType =
> +    ResultType->getAsObjCInterfacePointerType();
> +  ObjCInterfaceDecl *NSNumberDecl =
> +    InterfacePointerType->getObjectType()->getInterface();
> +  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
> +  llvm::Value *Receiver = Runtime.GetClass(Builder, NSNumberDecl);
> +
> +  const ParmVarDecl *argDecl = *Method->param_begin();
> +  QualType ArgQT = argDecl->getType().getUnqualifiedType();
> +  RValue RV = EmitAnyExpr(NL);
> +  CallArgList Args;
> +  Args.add(RV, ArgQT);
> +
> +  RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
> +                                              ResultType, Sel, Receiver, Args,
> +                                              NSNumberDecl, Method);
> +  return Builder.CreateBitCast(result.getScalarVal(),
> +                               ConvertType(E->getType()));
> +}
> +
> +llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
> +                                    const ObjCMethodDecl *MethodWithObjects) {
> +  ASTContext &Context = CGM.getContext();
> +  const ObjCDictionaryLiteral *DLE = 0;
> +  const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E);
> +  if (!ALE)
> +    DLE = cast<ObjCDictionaryLiteral>(E);
> +
> +  // Compute the type of the array we're initializing.
> +  uint64_t NumElements =
> +    ALE ? ALE->getNumElements() : DLE->getNumElements();
> +  llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()),
> +                            NumElements);
> +  QualType ElementType = Context.getObjCIdType().withConst();
> +  QualType ElementArrayType
> +    = Context.getConstantArrayType(ElementType, APNumElements,
> +                                   ArrayType::Normal, /*IndexTypeQuals=*/0);
> +
> +  // Allocate the temporary array(s).
> +  llvm::Value *Objects = CreateMemTemp(ElementArrayType, "objects");
> +  llvm::Value *Keys = 0;
> +  if (DLE)
> +    Keys = CreateMemTemp(ElementArrayType, "keys");
> +
> +  // Perform the actual initialialization of the array(s).
> +  for (uint64_t i = 0; i < NumElements; i++) {
> +    if (ALE) {
> +      // Emit the initializer.
> +      const Expr *Rhs = ALE->getElement(i);
> +      LValue LV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i),
> +                                   ElementType,
> +                                   Context.getTypeAlignInChars(Rhs->getType()),
> +                                   Context);
> +      EmitScalarInit(Rhs, /*D=*/0, LV, /*capturedByInit=*/false);
> +    } else {
> +      // Emit the key initializer.
> +      const Expr *Key = DLE->getKeyValueElement(i).Key;
> +      LValue KeyLV = LValue::MakeAddr(Builder.CreateStructGEP(Keys, i),
> +                                      ElementType,
> +                                    Context.getTypeAlignInChars(Key->getType()),
> +                                      Context);
> +      EmitScalarInit(Key, /*D=*/0, KeyLV, /*capturedByInit=*/false);
> +
> +      // Emit the value initializer.
> +      const Expr *Value = DLE->getKeyValueElement(i).Value;
> +      LValue ValueLV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i),
> +                                        ElementType,
> +                                  Context.getTypeAlignInChars(Value->getType()),
> +                                        Context);
> +      EmitScalarInit(Value, /*D=*/0, ValueLV, /*capturedByInit=*/false);
> +    }
> +  }
> +
> +  // Generate the argument list.
> +  CallArgList Args;
> +  ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin();
> +  const ParmVarDecl *argDecl = *PI++;
> +  QualType ArgQT = argDecl->getType().getUnqualifiedType();
> +  Args.add(RValue::get(Objects), ArgQT);
> +  if (DLE) {
> +    argDecl = *PI++;
> +    ArgQT = argDecl->getType().getUnqualifiedType();
> +    Args.add(RValue::get(Keys), ArgQT);
> +  }
> +  argDecl = *PI;
> +  ArgQT = argDecl->getType().getUnqualifiedType();
> +  llvm::Value *Count =
> +    llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements);
> +  Args.add(RValue::get(Count), ArgQT);
> +
> +  // Generate a reference to the class pointer, which will be the receiver.
> +  Selector Sel = MethodWithObjects->getSelector();
> +  QualType ResultType = E->getType();
> +  const ObjCObjectPointerType *InterfacePointerType
> +    = ResultType->getAsObjCInterfacePointerType();
> +  ObjCInterfaceDecl *Class
> +    = InterfacePointerType->getObjectType()->getInterface();
> +  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
> +  llvm::Value *Receiver = Runtime.GetClass(Builder, Class);
> +
> +  // Generate the message send.
> +  RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
> +                                              MethodWithObjects->getResultType(),
> +                                              Sel,
> +                                              Receiver, Args, Class,
> +                                              MethodWithObjects);
> +  return Builder.CreateBitCast(result.getScalarVal(),
> +                               ConvertType(E->getType()));
> +}
> +
> +llvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) {
> +  return EmitObjCCollectionLiteral(E, E->getArrayWithObjectsMethod());
> +}
> +
> +llvm::Value *CodeGenFunction::EmitObjCDictionaryLiteral(
> +                                            const ObjCDictionaryLiteral *E) {
> +  return EmitObjCCollectionLiteral(E, E->getDictWithObjectsMethod());
> +}
> +
>  /// Emit a selector.
>  llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
>   // Untyped selector.
> @@ -884,6 +1020,26 @@
>   return false;
>  }
>
> +bool UseOptimizedSetter(CodeGenModule &CGM) {
> +  if (CGM.getLangOptions().getGC() != LangOptions::NonGC)
> +    return false;
> +  const TargetInfo &Target = CGM.getContext().getTargetInfo();
> +  StringRef TargetPlatform = Target.getPlatformName();
> +  if (TargetPlatform.empty())
> +    return false;
> +  VersionTuple TargetMinVersion = Target.getPlatformMinVersion();
> +
> +  if (TargetPlatform.compare("macosx") ||
> +      TargetMinVersion.getMajor() <= 9)
> +    return false;
> +
> +  unsigned minor = 0;
> +  if (llvm::Optional<unsigned> Minor = TargetMinVersion.getMinor())
> +    minor = *Minor;
> +
> +  return (minor >= 8);
> +}
> +
>  void
>  CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
>                                         const ObjCPropertyImplDecl *propImpl,
> @@ -937,13 +1093,27 @@
>
>   case PropertyImplStrategy::GetSetProperty:
>   case PropertyImplStrategy::SetPropertyAndExpressionGet: {
> -    llvm::Value *setPropertyFn =
> -      CGM.getObjCRuntime().GetPropertySetFunction();
> -    if (!setPropertyFn) {
> -      CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
> -      return;
> +
> +    llvm::Value *setOptimizedPropertyFn = 0;
> +    llvm::Value *setPropertyFn = 0;
> +    if (UseOptimizedSetter(CGM)) {
> +      // 10.8 code and GC is off
> +      setOptimizedPropertyFn =
> +        CGM.getObjCRuntime().GetOptimizedPropertySetFunction(strategy.isAtomic(),
> +                                                             strategy.isCopy());
> +      if (!setOptimizedPropertyFn) {
> +        CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");
> +        return;
> +      }
>     }
> -
> +    else {
> +      setPropertyFn = CGM.getObjCRuntime().GetPropertySetFunction();
> +      if (!setPropertyFn) {
> +        CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
> +        return;
> +      }
> +    }
> +
>     // Emit objc_setProperty((id) self, _cmd, offset, arg,
>     //                       <is-atomic>, <is-copy>).
>     llvm::Value *cmd =
> @@ -958,18 +1128,28 @@
>     CallArgList args;
>     args.add(RValue::get(self), getContext().getObjCIdType());
>     args.add(RValue::get(cmd), getContext().getObjCSelType());
> -    args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
> -    args.add(RValue::get(arg), getContext().getObjCIdType());
> -    args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
> -             getContext().BoolTy);
> -    args.add(RValue::get(Builder.getInt1(strategy.isCopy())),
> -             getContext().BoolTy);
> -    // FIXME: We shouldn't need to get the function info here, the runtime
> -    // already should have computed it to build the function.
> -    EmitCall(getTypes().arrangeFunctionCall(getContext().VoidTy, args,
> -                                            FunctionType::ExtInfo(),
> -                                            RequiredArgs::All),
> -             setPropertyFn, ReturnValueSlot(), args);
> +    if (setOptimizedPropertyFn) {
> +      args.add(RValue::get(arg), getContext().getObjCIdType());
> +      args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
> +      EmitCall(getTypes().arrangeFunctionCall(getContext().VoidTy, args,
> +                                              FunctionType::ExtInfo(),
> +                                              RequiredArgs::All),
> +               setOptimizedPropertyFn, ReturnValueSlot(), args);
> +    } else {
> +      args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
> +      args.add(RValue::get(arg), getContext().getObjCIdType());
> +      args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
> +               getContext().BoolTy);
> +      args.add(RValue::get(Builder.getInt1(strategy.isCopy())),
> +               getContext().BoolTy);
> +      // FIXME: We shouldn't need to get the function info here, the runtime
> +      // already should have computed it to build the function.
> +      EmitCall(getTypes().arrangeFunctionCall(getContext().VoidTy, args,
> +                                              FunctionType::ExtInfo(),
> +                                              RequiredArgs::All),
> +               setPropertyFn, ReturnValueSlot(), args);
> +    }
> +
>     return;
>   }
>
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Tue Mar  6 14:05:56 2012
> @@ -472,6 +472,8 @@
>   virtual llvm::Function *ModuleInitFunction();
>   virtual llvm::Constant *GetPropertyGetFunction();
>   virtual llvm::Constant *GetPropertySetFunction();
> +  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
> +                                                          bool copy);
>   virtual llvm::Constant *GetSetStructFunction();
>   virtual llvm::Constant *GetCppAtomicObjectFunction();
>   virtual llvm::Constant *GetGetStructFunction();
> @@ -2427,6 +2429,11 @@
>   return SetPropertyFn;
>  }
>
> +llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic,
> +                                                           bool copy) {
> +  return 0;
> +}
> +
>  llvm::Constant *CGObjCGNU::GetGetStructFunction() {
>   return GetStructPropertyFn;
>  }
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Mar  6 14:05:56 2012
> @@ -267,6 +267,41 @@
>     return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
>   }
>
> +  llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
> +    CodeGen::CodeGenTypes &Types = CGM.getTypes();
> +    ASTContext &Ctx = CGM.getContext();
> +    // void objc_setProperty_atomic(id self, SEL _cmd,
> +    //                              id newValue, ptrdiff_t offset);
> +    // void objc_setProperty_nonatomic(id self, SEL _cmd,
> +    //                                 id newValue, ptrdiff_t offset);
> +    // void objc_setProperty_atomic_copy(id self, SEL _cmd,
> +    //                                   id newValue, ptrdiff_t offset);
> +    // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
> +    //                                      id newValue, ptrdiff_t offset);
> +
> +    SmallVector<CanQualType,4> Params;
> +    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
> +    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
> +    Params.push_back(IdType);
> +    Params.push_back(SelType);
> +    Params.push_back(IdType);
> +    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
> +    llvm::FunctionType *FTy =
> +    Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
> +                                                    FunctionType::ExtInfo(),
> +                                                    RequiredArgs::All));
> +    const char *name;
> +    if (atomic && copy)
> +      name = "objc_setProperty_atomic_copy";
> +    else if (atomic && !copy)
> +      name = "objc_setProperty_atomic";
> +    else if (!atomic && copy)
> +      name = "objc_setProperty_nonatomic_copy";
> +    else
> +      name = "objc_setProperty_nonatomic";
> +
> +    return CGM.CreateRuntimeFunction(FTy, name);
> +  }
>
>   llvm::Constant *getCopyStructFn() {
>     CodeGen::CodeGenTypes &Types = CGM.getTypes();
> @@ -906,7 +941,7 @@
>     CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
>
>   virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
> -
> +
>   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
>                                          const ObjCContainerDecl *CD=0);
>
> @@ -1087,6 +1122,8 @@
>
>   virtual llvm::Constant *GetPropertyGetFunction();
>   virtual llvm::Constant *GetPropertySetFunction();
> +  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
> +                                                          bool copy);
>   virtual llvm::Constant *GetGetStructFunction();
>   virtual llvm::Constant *GetSetStructFunction();
>   virtual llvm::Constant *GetCppAtomicObjectFunction();
> @@ -1349,6 +1386,11 @@
>     return ObjCTypes.getSetPropertyFn();
>   }
>
> +  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
> +                                                          bool copy) {
> +    return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
> +  }
> +
>   virtual llvm::Constant *GetSetStructFunction() {
>     return ObjCTypes.getCopyStructFn();
>   }
> @@ -1578,6 +1620,10 @@
>           CGM.GetAddrOfConstantString(SL));
>  }
>
> +enum {
> +  kCFTaggedObjectID_Integer = (1 << 1) + 1
> +};
> +
>  /// Generates a message send where the super is the receiver.  This is
>  /// a message send to self with special delivery semantics indicating
>  /// which class's method should be called.
> @@ -2723,6 +2769,11 @@
>   return ObjCTypes.getSetPropertyFn();
>  }
>
> +llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
> +                                                           bool copy) {
> +  return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
> +}
> +
>  llvm::Constant *CGObjCMac::GetGetStructFunction() {
>   return ObjCTypes.getCopyStructFn();
>  }
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Tue Mar  6 14:05:56 2012
> @@ -135,7 +135,7 @@
>
>   /// Generate a constant string object.
>   virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
> -
> +
>   /// Generate a category.  A category contains a list of methods (and
>   /// accompanying metadata) and a list of protocols.
>   virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
> @@ -202,6 +202,10 @@
>   /// Return the runtime function for setting properties.
>   virtual llvm::Constant *GetPropertySetFunction() = 0;
>
> +  /// Return the runtime function for optimized setting properties.
> +  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
> +                                                          bool copy) = 0;
> +
>   // API for atomic copying of qualified aggregates in getter.
>   virtual llvm::Constant *GetGetStructFunction() = 0;
>   // API for atomic copying of qualified aggregates in setter.
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Mar  6 14:05:56 2012
> @@ -2238,6 +2238,11 @@
>
>   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
>   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
> +  llvm::Value *EmitObjCNumericLiteral(const ObjCNumericLiteral *E);
> +  llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
> +  llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
> +  llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
> +                                const ObjCMethodDecl *MethodWithObjects);
>   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
>   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
>                              ReturnValueSlot Return = ReturnValueSlot());
>
> Modified: cfe/trunk/lib/Driver/ToolChains.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Driver/ToolChains.cpp (original)
> +++ cfe/trunk/lib/Driver/ToolChains.cpp Tue Mar  6 14:05:56 2012
> @@ -93,12 +93,17 @@
>     return !isMacosxVersionLT(10, 7);
>  }
>
> +bool Darwin::hasSubscriptingRuntime() const {
> +    return !isTargetIPhoneOS() && !isMacosxVersionLT(10, 8);
> +}
> +
>  /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
>  void Darwin::configureObjCRuntime(ObjCRuntime &runtime) const {
>   if (runtime.getKind() != ObjCRuntime::NeXT)
>     return ToolChain::configureObjCRuntime(runtime);
>
>   runtime.HasARC = runtime.HasWeak = hasARCRuntime();
> +  runtime.HasSubscripting = hasSubscriptingRuntime();
>
>   // So far, objc_terminate is only available in iOS 5.
>   // FIXME: do the simulator logic properly.
>
> Modified: cfe/trunk/lib/Driver/ToolChains.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Driver/ToolChains.h (original)
> +++ cfe/trunk/lib/Driver/ToolChains.h Tue Mar  6 14:05:56 2012
> @@ -205,6 +205,7 @@
>   std::string MacosxVersionMin;
>
>   bool hasARCRuntime() const;
> +  bool hasSubscriptingRuntime() const;
>
>  private:
>   void AddDeploymentTarget(DerivedArgList &Args) const;
> @@ -252,6 +253,12 @@
>     return TargetIsIPhoneOSSimulator;
>   }
>
> +  bool isTargetMacOS() const {
> +    return !isTargetIOSSimulator() &&
> +           !isTargetIPhoneOS() &&
> +           ARCRuntimeForSimulator == ARCSimulator_None;
> +  }
> +
>   bool isTargetInitialized() const { return TargetInitialized; }
>
>   void getTargetVersion(unsigned (&Res)[3]) const {
>
> Modified: cfe/trunk/lib/Driver/Tools.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Driver/Tools.cpp (original)
> +++ cfe/trunk/lib/Driver/Tools.cpp Tue Mar  6 14:05:56 2012
> @@ -136,6 +136,13 @@
>   return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
>  }
>
> +/// \brief Determine whether we are linking the ObjC runtime.
> +static bool isObjCRuntimeLinked(const ArgList &Args) {
> +  if (isObjCAutoRefCount(Args))
> +    return true;
> +  return Args.hasArg(options::OPT_fobjc_link_runtime);
> +}
> +
>  static void addProfileRT(const ToolChain &TC, const ArgList &Args,
>                          ArgStringList &CmdArgs,
>                          llvm::Triple Triple) {
> @@ -4025,7 +4032,7 @@
>                 CmdArgs.push_back("-lcrt1.o");
>               else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
>                 CmdArgs.push_back("-lcrt1.10.5.o");
> -              else
> +              else if (getDarwinToolChain().isMacosxVersionLT(10, 8))
>                 CmdArgs.push_back("-lcrt1.10.6.o");
>
>               // darwin_crt2 spec is empty.
> @@ -4064,14 +4071,24 @@
>
>   getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
>
> -  // In ARC, if we don't have runtime support, link in the runtime
> -  // stubs.  We have to do this *before* adding any of the normal
> -  // linker inputs so that its initializer gets run first.
> -  if (isObjCAutoRefCount(Args)) {
> -    ObjCRuntime runtime;
> -    getDarwinToolChain().configureObjCRuntime(runtime);
> -    if (!runtime.HasARC)
> -      getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
> +  if (isObjCRuntimeLinked(Args)) {
> +    // Avoid linking compatibility stubs on i386 mac.
> +    if (!getDarwinToolChain().isTargetMacOS() ||
> +        getDarwinToolChain().getArchName() != "i386") {
> +      // If we don't have ARC or subscripting runtime support, link in the
> +      // runtime stubs.  We have to do this *before* adding any of the normal
> +      // linker inputs so that its initializer gets run first.
> +      ObjCRuntime runtime;
> +      getDarwinToolChain().configureObjCRuntime(runtime);
> +      // We use arclite library for both ARC and subscripting support.
> +      if ((!runtime.HasARC && isObjCAutoRefCount(Args)) ||
> +          !runtime.HasSubscripting)
> +        getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
> +      CmdArgs.push_back("-framework");
> +      CmdArgs.push_back("Foundation");
> +    }
> +    // Link libobj.
> +    CmdArgs.push_back("-lobjc");
>   }
>
>   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
>
> Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
> +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Mar  6 14:05:56 2012
> @@ -630,6 +630,10 @@
>            .Case("ownership_holds", true)
>            .Case("ownership_returns", true)
>            .Case("ownership_takes", true)
> +           .Case("objc_bool", true)
> +           .Case("objc_subscripting", LangOpts.ObjCNonFragileABI)
> +           .Case("objc_array_literals", LangOpts.ObjC2)
> +           .Case("objc_dictionary_literals", LangOpts.ObjC2)
>            .Case("arc_cf_code_audited", true)
>            // C11 features
>            .Case("c_alignas", LangOpts.C11)
>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Mar  6 14:05:56 2012
> @@ -707,6 +707,10 @@
>   case tok::kw_true:
>   case tok::kw_false:
>     return ParseCXXBoolLiteral();
> +
> +  case tok::kw___objc_yes:
> +  case tok::kw___objc_no:
> +      return ParseObjCBoolLiteral();
>
>   case tok::kw_nullptr:
>     Diag(Tok, diag::warn_cxx98_compat_nullptr);
> @@ -2403,3 +2407,12 @@
>     Actions.ActOnBlockError(CaretLoc, getCurScope());
>   return move(Result);
>  }
> +
> +/// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
> +///
> +///         '__objc_yes'
> +///         '__objc_no'
> +ExprResult Parser::ParseObjCBoolLiteral() {
> +  tok::TokenKind Kind = Tok.getKind();
> +  return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind);
> +}
>
> Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Mar  6 14:05:56 2012
> @@ -2009,11 +2009,64 @@
>     cutOffParsing();
>     return ExprError();
>
> +  case tok::minus:
> +  case tok::plus: {
> +    tok::TokenKind Kind = Tok.getKind();
> +    SourceLocation OpLoc = ConsumeToken();
> +
> +    if (!Tok.is(tok::numeric_constant)) {
> +      const char *Symbol = 0;
> +      switch (Kind) {
> +      case tok::minus: Symbol = "-"; break;
> +      case tok::plus: Symbol = "+"; break;
> +      default: llvm_unreachable("missing unary operator case");
> +      }
> +      Diag(Tok, diag::err_nsnumber_nonliteral_unary)
> +        << Symbol;
> +      return ExprError();
> +    }
> +
> +    ExprResult Lit(Actions.ActOnNumericConstant(Tok));
> +    if (Lit.isInvalid()) {
> +      return move(Lit);
> +    }
> +    SourceLocation EndLoc = ConsumeToken();         // consume the literal token.
> +
> +    Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.take());
> +    if (Lit.isInvalid())
> +      return move(Lit);
> +
> +    return ParsePostfixExpressionSuffix(
> +             Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
> +  }
> +
>   case tok::string_literal:    // primary-expression: string-literal
>   case tok::wide_string_literal:
>     if (Tok.hasUDSuffix())
>       return ExprError(Diag(Tok, diag::err_invalid_string_udl));
>     return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
> +
> +  case tok::char_constant:
> +    return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
> +
> +  case tok::numeric_constant:
> +    return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
> +
> +  case tok::kw_true:  // Objective-C++, etc.
> +  case tok::kw___objc_yes: // c/c++/objc/objc++ __objc_yes
> +    return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, true));
> +  case tok::kw_false: // Objective-C++, etc.
> +  case tok::kw___objc_no: // c/c++/objc/objc++ __objc_no
> +    return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, false));
> +
> +  case tok::l_square:
> +    // Objective-C array literal
> +    return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
> +
> +  case tok::l_brace:
> +    // Objective-C dictionary literal
> +    return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
> +
>   default:
>     if (Tok.getIdentifierInfo() == 0)
>       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
> @@ -2491,6 +2544,134 @@
>                                               AtStrings.size()));
>  }
>
> +/// ParseObjCBooleanLiteral -
> +/// objc-scalar-literal : '@' boolean-keyword
> +///                        ;
> +/// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
> +///                        ;
> +ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
> +                                           bool ArgValue) {
> +  SourceLocation EndLoc = ConsumeToken();             // consume the keyword.
> +  return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
> +}
> +
> +/// ParseObjCCharacterLiteral -
> +/// objc-scalar-literal : '@' character-literal
> +///                        ;
> +ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
> +  ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
> +  if (Lit.isInvalid()) {
> +    return move(Lit);
> +  }
> +  SourceLocation EndLoc = ConsumeToken();         // consume the literal token.
> +  return Owned(Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
> +}
> +
> +/// ParseObjCNumericLiteral -
> +/// objc-scalar-literal : '@' scalar-literal
> +///                        ;
> +/// scalar-literal : | numeric-constant                        /* any numeric constant. */
> +///                    ;
> +ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
> +  ExprResult Lit(Actions.ActOnNumericConstant(Tok));
> +  if (Lit.isInvalid()) {
> +    return move(Lit);
> +  }
> +  SourceLocation EndLoc = ConsumeToken();         // consume the literal token.
> +  return Owned(Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
> +}
> +
> +ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
> +  ExprVector ElementExprs(Actions);                   // array elements.
> +  ConsumeBracket(); // consume the l_square.
> +
> +  while (Tok.isNot(tok::r_square)) {
> +    // Parse list of array element expressions (all must be id types).
> +    ExprResult Res(ParseAssignmentExpression());
> +    if (Res.isInvalid()) {
> +      // We must manually skip to a ']', otherwise the expression skipper will
> +      // stop at the ']' when it skips to the ';'.  We want it to skip beyond
> +      // the enclosing expression.
> +      SkipUntil(tok::r_square);
> +      return move(Res);
> +    }
> +
> +    // Parse the ellipsis that indicates a pack expansion.
> +    if (Tok.is(tok::ellipsis))
> +      Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken());
> +    if (Res.isInvalid())
> +      return true;
> +
> +    ElementExprs.push_back(Res.release());
> +
> +    if (Tok.is(tok::comma))
> +      ConsumeToken(); // Eat the ','.
> +    else if (Tok.isNot(tok::r_square))
> +     return ExprError(Diag(Tok, diag::err_expected_rsquare_or_comma));
> +  }
> +  SourceLocation EndLoc = ConsumeBracket(); // location of ']'
> +  MultiExprArg Args(Actions, ElementExprs.take(), ElementExprs.size());
> +  return Owned(Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args));
> +}
> +
> +ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
> +  SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements.
> +  ConsumeBrace(); // consume the l_square.
> +  while (Tok.isNot(tok::r_brace)) {
> +    // Parse the comma separated key : value expressions.
> +    ExprResult KeyExpr;
> +    {
> +      ColonProtectionRAIIObject X(*this);
> +      KeyExpr = ParseAssignmentExpression();
> +      if (KeyExpr.isInvalid()) {
> +        // We must manually skip to a '}', otherwise the expression skipper will
> +        // stop at the '}' when it skips to the ';'.  We want it to skip beyond
> +        // the enclosing expression.
> +        SkipUntil(tok::r_brace);
> +        return move(KeyExpr);
> +      }
> +    }
> +
> +    if (Tok.is(tok::colon)) {
> +      ConsumeToken();
> +    } else {
> +      return ExprError(Diag(Tok, diag::err_expected_colon));
> +    }
> +
> +    ExprResult ValueExpr(ParseAssignmentExpression());
> +    if (ValueExpr.isInvalid()) {
> +      // We must manually skip to a '}', otherwise the expression skipper will
> +      // stop at the '}' when it skips to the ';'.  We want it to skip beyond
> +      // the enclosing expression.
> +      SkipUntil(tok::r_brace);
> +      return move(ValueExpr);
> +    }
> +
> +    // Parse the ellipsis that designates this as a pack expansion.
> +    SourceLocation EllipsisLoc;
> +    if (Tok.is(tok::ellipsis) && getLang().CPlusPlus)
> +      EllipsisLoc = ConsumeToken();
> +
> +    // We have a valid expression. Collect it in a vector so we can
> +    // build the argument list.
> +    ObjCDictionaryElement Element = {
> +      KeyExpr.get(), ValueExpr.get(), EllipsisLoc, llvm::Optional<unsigned>()
> +    };
> +    Elements.push_back(Element);
> +
> +    if (Tok.is(tok::comma))
> +      ConsumeToken(); // Eat the ','.
> +    else if (Tok.isNot(tok::r_brace))
> +      return ExprError(Diag(Tok, diag::err_expected_rbrace_or_comma));
> +  }
> +  SourceLocation EndLoc = ConsumeBrace();
> +
> +  // Create the ObjCDictionaryLiteral.
> +  return Owned(Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
> +                                                  Elements.data(),
> +                                                  Elements.size()));
> +}
> +
>  ///    objc-encode-expression:
>  ///      @encode ( type-name )
>  ExprResult
>
> Modified: cfe/trunk/lib/Sema/Sema.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/Sema.cpp (original)
> +++ cfe/trunk/lib/Sema/Sema.cpp Tue Mar  6 14:05:56 2012
> @@ -90,6 +90,8 @@
>     PackContext(0), MSStructPragmaOn(false), VisContext(0),
>     ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
>     IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
> +    NSNumberDecl(0), NSArrayDecl(0), ArrayWithObjectsMethod(0),
> +    NSDictionaryDecl(0), DictionaryWithObjectsMethod(0),
>     GlobalNewDeleteDeclared(false),
>     ObjCShouldCallSuperDealloc(false),
>     ObjCShouldCallSuperFinalize(false),
> @@ -102,7 +104,12 @@
>  {
>   TUScope = 0;
>   LoadedExternalKnownNamespaces = false;
> -
> +  for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I)
> +    NSNumberLiteralMethods[I] = 0;
> +
> +  if (getLangOptions().ObjC1)
> +    NSAPIObj.reset(new NSAPI(Context));
> +
>   if (getLangOptions().CPlusPlus)
>     FieldCollector.reset(new CXXFieldCollector());
>
>
> Modified: cfe/trunk/lib/Sema/SemaCast.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaCast.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaCast.cpp Tue Mar  6 14:05:56 2012
> @@ -1528,6 +1528,8 @@
>     case OK_BitField:        inappropriate = "bit-field";           break;
>     case OK_VectorComponent: inappropriate = "vector element";      break;
>     case OK_ObjCProperty:    inappropriate = "property expression"; break;
> +    case OK_ObjCSubscript:   inappropriate = "container subscripting expression";
> +                             break;
>     }
>     if (inappropriate) {
>       Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)
>
> Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Mar  6 14:05:56 2012
> @@ -4392,6 +4392,26 @@
>   Builder.AddPlaceholderChunk("selector");
>   Builder.AddChunk(CodeCompletionString::CK_RightParen);
>   Results.AddResult(Result(Builder.TakeString()));
> +
> +  // @[ objects, ... ]
> +  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,[));
> +  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
> +  Builder.AddPlaceholderChunk("objects, ...");
> +  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
> +  Builder.AddChunk(CodeCompletionString::CK_RightBracket);
> +  Results.AddResult(Result(Builder.TakeString()));
> +
> +  // @{ key : object, ... }
> +  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,{));
> +  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
> +  Builder.AddPlaceholderChunk("key");
> +  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
> +  Builder.AddChunk(CodeCompletionString::CK_Colon);
> +  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
> +  Builder.AddPlaceholderChunk("object, ...");
> +  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
> +  Builder.AddChunk(CodeCompletionString::CK_RightBrace);
> +  Results.AddResult(Result(Builder.TakeString()));
>  }
>
>  static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Mar  6 14:05:56 2012
> @@ -2390,14 +2390,18 @@
>                                               Tok.getLocation()));
>  }
>
> +ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
> +  unsigned IntSize = Context.getTargetInfo().getIntWidth();
> +  return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
> +                                      Context.IntTy, Loc));
> +}
> +
>  ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
>   // Fast path for a single digit (which is quite common).  A single digit
>   // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
>   if (Tok.getLength() == 1) {
>     const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
> -    unsigned IntSize = Context.getTargetInfo().getIntWidth();
> -    return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'),
> -                    Context.IntTy, Tok.getLocation()));
> +    return ActOnIntegerConstant(Tok.getLocation(), Val-'0');
>   }
>
>   SmallString<512> IntegerBuffer;
> @@ -2926,7 +2930,8 @@
>       (LHSExp->getType()->isRecordType() ||
>        LHSExp->getType()->isEnumeralType() ||
>        RHSExp->getType()->isRecordType() ||
> -       RHSExp->getType()->isEnumeralType())) {
> +       RHSExp->getType()->isEnumeralType()) &&
> +      !LHSExp->getType()->isObjCObjectPointerType()) {
>     return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx);
>   }
>
> @@ -2979,6 +2984,9 @@
>                LHSTy->getAs<ObjCObjectPointerType>()) {
>     BaseExpr = LHSExp;
>     IndexExpr = RHSExp;
> +    Result = BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0);
> +    if (!Result.isInvalid())
> +      return Owned(Result.take());
>     ResultType = PTy->getPointeeType();
>   } else if (const ObjCObjectPointerType *PTy =
>                RHSTy->getAs<ObjCObjectPointerType>()) {
> @@ -11001,3 +11009,12 @@
>     return E->getType()->isIntegralOrEnumerationType();
>   return false;
>  }
> +
> +/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
> +ExprResult
> +Sema::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
> +  assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
> +         "Unknown Objective-C Boolean value!");
> +  return Owned(new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes,
> +                                        Context.ObjCBuiltinBoolTy, OpLoc));
> +}
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Mar  6 14:05:56 2012
> @@ -4456,11 +4456,27 @@
>     } else if (isa<StmtExpr>(E)) {
>       ReturnsRetained = true;
>
> +    // We hit this case with the lambda conversion-to-block optimization;
> +    // we don't want any extra casts here.
> +    } else if (isa<CastExpr>(E) &&
> +               isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
> +      return Owned(E);
> +
>     // For message sends and property references, we try to find an
>     // actual method.  FIXME: we should infer retention by selector in
>     // cases where we don't have an actual method.
> -    } else if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
> -      ObjCMethodDecl *D = Send->getMethodDecl();
> +    } else {
> +      ObjCMethodDecl *D = 0;
> +      if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
> +        D = Send->getMethodDecl();
> +      } else if (ObjCNumericLiteral *NumLit = dyn_cast<ObjCNumericLiteral>(E)) {
> +        D = NumLit->getObjCNumericLiteralMethod();
> +      } else if (ObjCArrayLiteral *ArrayLit = dyn_cast<ObjCArrayLiteral>(E)) {
> +        D = ArrayLit->getArrayWithObjectsMethod();
> +      } else if (ObjCDictionaryLiteral *DictLit
> +                                        = dyn_cast<ObjCDictionaryLiteral>(E)) {
> +        D = DictLit->getDictWithObjectsMethod();
> +      }
>
>       ReturnsRetained = (D && D->hasAttr<NSReturnsRetainedAttr>());
>
> @@ -4470,13 +4486,6 @@
>       if (!ReturnsRetained &&
>           D && D->getMethodFamily() == OMF_performSelector)
>         return Owned(E);
> -    } else if (isa<CastExpr>(E) &&
> -               isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
> -      // We hit this case with the lambda conversion-to-block optimization;
> -      // we don't want any extra casts here.
> -      return Owned(E);
> -    } else {
> -      ReturnsRetained = false;
>     }
>
>     // Don't reclaim an object of Class type.
>
> Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Mar  6 14:05:56 2012
> @@ -17,6 +17,8 @@
>  #include "clang/Sema/ScopeInfo.h"
>  #include "clang/Sema/Initialization.h"
>  #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
> +#include "clang/Edit/Rewriters.h"
> +#include "clang/Edit/Commit.h"
>  #include "clang/AST/ASTContext.h"
>  #include "clang/AST/DeclObjC.h"
>  #include "clang/AST/ExprObjC.h"
> @@ -70,7 +72,11 @@
>                               Context.getPointerType(Context.CharTy),
>                               &StrLocs[0], StrLocs.size());
>   }
> +
> +  return BuildObjCStringLiteral(AtLocs[0], S);
> +}
>
> +ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){
>   // Verify that this composite string is acceptable for ObjC strings.
>   if (CheckObjCString(S))
>     return true;
> @@ -91,7 +97,7 @@
>     else
>       NSIdent = &Context.Idents.get(StringClass);
>
> -    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
> +    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc,
>                                      LookupOrdinaryName);
>     if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
>       Context.setObjCConstantStringInterface(StrIF);
> @@ -106,7 +112,7 @@
>     }
>   } else {
>     IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
> -    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
> +    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc,
>                                      LookupOrdinaryName);
>     if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
>       Context.setObjCConstantStringInterface(StrIF);
> @@ -131,7 +137,613 @@
>     }
>   }
>
> -  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
> +  return new (Context) ObjCStringLiteral(S, Ty, AtLoc);
> +}
> +
> +/// \brief Retrieve the NSNumber factory method that should be used to create
> +/// an Objective-C literal for the given type.
> +static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
> +                                                QualType T, QualType ReturnType,
> +                                                SourceRange Range) {
> +  llvm::Optional<NSAPI::NSNumberLiteralMethodKind> Kind
> +    = S.NSAPIObj->getNSNumberFactoryMethodKind(T);
> +
> +  if (!Kind) {
> +    S.Diag(Loc, diag::err_invalid_nsnumber_type)
> +      << T << Range;
> +    return 0;
> +  }
> +
> +  // If we already looked up this method, we're done.
> +  if (S.NSNumberLiteralMethods[*Kind])
> +    return S.NSNumberLiteralMethods[*Kind];
> +
> +  Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
> +                                                        /*Instance=*/false);
> +
> +  // Look for the appropriate method within NSNumber.
> +  ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);;
> +  if (!Method && S.getLangOptions().DebuggerObjCLiteral) {
> +    TypeSourceInfo *ResultTInfo = 0;
> +    Method = ObjCMethodDecl::Create(S.Context, SourceLocation(), SourceLocation(), Sel,
> +                           ReturnType,
> +                           ResultTInfo,
> +                           S.Context.getTranslationUnitDecl(),
> +                           false /*Instance*/, false/*isVariadic*/,
> +                           /*isSynthesized=*/false,
> +                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
> +                           ObjCMethodDecl::Required,
> +                           false);
> +    ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method,
> +                                             SourceLocation(), SourceLocation(),
> +                                             &S.Context.Idents.get("value"),
> +                                             T, /*TInfo=*/0, SC_None, SC_None, 0);
> +    Method->setMethodParams(S.Context, value, ArrayRef<SourceLocation>());
> +  }
> +
> +  if (!Method) {
> +    S.Diag(Loc, diag::err_undeclared_nsnumber_method) << Sel;
> +    return 0;
> +  }
> +
> +  // Make sure the return type is reasonable.
> +  if (!Method->getResultType()->isObjCObjectPointerType()) {
> +    S.Diag(Loc, diag::err_objc_literal_method_sig)
> +      << Sel;
> +    S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)
> +      << Method->getResultType();
> +    return 0;
> +  }
> +
> +  // Note: if the parameter type is out-of-line, we'll catch it later in the
> +  // implicit conversion.
> +
> +  S.NSNumberLiteralMethods[*Kind] = Method;
> +  return Method;
> +}
> +
> +/// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the
> +/// numeric literal expression. Type of the expression will be "NSNumber *"
> +/// or "id" if NSNumber is unavailable.
> +ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) {
> +  // Look up the NSNumber class, if we haven't done so already.
> +  if (!NSNumberDecl) {
> +    NamedDecl *IF = LookupSingleName(TUScope,
> +                                NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber),
> +                                AtLoc, LookupOrdinaryName);
> +    NSNumberDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
> +
> +    if (!NSNumberDecl && getLangOptions().DebuggerObjCLiteral)
> +      NSNumberDecl =  ObjCInterfaceDecl::Create (Context,
> +                        Context.getTranslationUnitDecl(),
> +                        SourceLocation(),
> +                        NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber),
> +                        0, SourceLocation());
> +    if (!NSNumberDecl) {
> +      Diag(AtLoc, diag::err_undeclared_nsnumber);
> +      return ExprError();
> +    }
> +  }
> +
> +  // Determine the type of the literal.
> +  QualType NumberType = Number->getType();
> +  if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {
> +    // In C, character literals have type 'int'. That's not the type we want
> +    // to use to determine the Objective-c literal kind.
> +    switch (Char->getKind()) {
> +    case CharacterLiteral::Ascii:
> +      NumberType = Context.CharTy;
> +      break;
> +
> +    case CharacterLiteral::Wide:
> +      NumberType = Context.getWCharType();
> +      break;
> +
> +    case CharacterLiteral::UTF16:
> +      NumberType = Context.Char16Ty;
> +      break;
> +
> +    case CharacterLiteral::UTF32:
> +      NumberType = Context.Char32Ty;
> +      break;
> +    }
> +  }
> +
> +  ObjCMethodDecl *Method = 0;
> +  // Look for the appropriate method within NSNumber.
> +  // Construct the literal.
> +  QualType Ty
> +    = Context.getObjCObjectPointerType(
> +                                    Context.getObjCInterfaceType(NSNumberDecl));
> +  Method  = getNSNumberFactoryMethod(*this, AtLoc,
> +                                     NumberType, Ty,
> +                                     Number->getSourceRange());
> +
> +  if (!Method)
> +    return ExprError();
> +
> +  // Convert the number to the type that the parameter expects.
> +  QualType ElementT = Method->param_begin()[0]->getType();
> +  ExprResult ConvertedNumber = PerformImplicitConversion(Number, ElementT,
> +                                                         AA_Sending);
> +  if (ConvertedNumber.isInvalid())
> +    return ExprError();
> +  Number = ConvertedNumber.get();
> +
> +  return MaybeBindToTemporary(
> +           new (Context) ObjCNumericLiteral(Number, Ty, Method, AtLoc));
> +}
> +
> +ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc,
> +                                      SourceLocation ValueLoc,
> +                                      bool Value) {
> +  ExprResult Inner;
> +  if (getLangOptions().CPlusPlus) {
> +    Inner = ActOnCXXBoolLiteral(ValueLoc, Value? tok::kw_true : tok::kw_false);
> +  } else {
> +    // C doesn't actually have a way to represent literal values of type
> +    // _Bool. So, we'll use 0/1 and implicit cast to _Bool.
> +    Inner = ActOnIntegerConstant(ValueLoc, Value? 1 : 0);
> +    Inner = ImpCastExprToType(Inner.get(), Context.BoolTy,
> +                              CK_IntegralToBoolean);
> +  }
> +
> +  return BuildObjCNumericLiteral(AtLoc, Inner.get());
> +}
> +
> +/// \brief Check that the given expression is a valid element of an Objective-C
> +/// collection literal.
> +static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,
> +                                                    QualType T) {
> +  // If the expression is type-dependent, there's nothing for us to do.
> +  if (Element->isTypeDependent())
> +    return Element;
> +
> +  ExprResult Result = S.CheckPlaceholderExpr(Element);
> +  if (Result.isInvalid())
> +    return ExprError();
> +  Element = Result.get();
> +
> +  // In C++, check for an implicit conversion to an Objective-C object pointer
> +  // type.
> +  if (S.getLangOptions().CPlusPlus && Element->getType()->isRecordType()) {
> +    InitializedEntity Entity
> +      = InitializedEntity::InitializeParameter(S.Context, T, /*Consumed=*/false);
> +    InitializationKind Kind
> +      = InitializationKind::CreateCopy(Element->getLocStart(), SourceLocation());
> +    InitializationSequence Seq(S, Entity, Kind, &Element, 1);
> +    if (!Seq.Failed())
> +      return Seq.Perform(S, Entity, Kind, MultiExprArg(S, &Element, 1));
> +  }
> +
> +  Expr *OrigElement = Element;
> +
> +  // Perform lvalue-to-rvalue conversion.
> +  Result = S.DefaultLvalueConversion(Element);
> +  if (Result.isInvalid())
> +    return ExprError();
> +  Element = Result.get();
> +
> +  // Make sure that we have an Objective-C pointer type or block.
> +  if (!Element->getType()->isObjCObjectPointerType() &&
> +      !Element->getType()->isBlockPointerType()) {
> +    bool Recovered = false;
> +
> +    // If this is potentially an Objective-C numeric literal, add the '@'.
> +    if (isa<IntegerLiteral>(OrigElement) ||
> +        isa<CharacterLiteral>(OrigElement) ||
> +        isa<FloatingLiteral>(OrigElement) ||
> +        isa<ObjCBoolLiteralExpr>(OrigElement) ||
> +        isa<CXXBoolLiteralExpr>(OrigElement)) {
> +      if (S.NSAPIObj->getNSNumberFactoryMethodKind(OrigElement->getType())) {
> +        int Which = isa<CharacterLiteral>(OrigElement) ? 1
> +                  : (isa<CXXBoolLiteralExpr>(OrigElement) ||
> +                     isa<ObjCBoolLiteralExpr>(OrigElement)) ? 2
> +                  : 3;
> +
> +        S.Diag(OrigElement->getLocStart(), diag::err_box_literal_collection)
> +          << Which << OrigElement->getSourceRange()
> +          << FixItHint::CreateInsertion(OrigElement->getLocStart(), "@");
> +
> +        Result = S.BuildObjCNumericLiteral(OrigElement->getLocStart(),
> +                                           OrigElement);
> +        if (Result.isInvalid())
> +          return ExprError();
> +
> +        Element = Result.get();
> +        Recovered = true;
> +      }
> +    }
> +    // If this is potentially an Objective-C string literal, add the '@'.
> +    else if (StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {
> +      if (String->isAscii()) {
> +        S.Diag(OrigElement->getLocStart(), diag::err_box_literal_collection)
> +          << 0 << OrigElement->getSourceRange()
> +          << FixItHint::CreateInsertion(OrigElement->getLocStart(), "@");
> +
> +        Result = S.BuildObjCStringLiteral(OrigElement->getLocStart(), String);
> +        if (Result.isInvalid())
> +          return ExprError();
> +
> +        Element = Result.get();
> +        Recovered = true;
> +      }
> +    }
> +
> +    if (!Recovered) {
> +      S.Diag(Element->getLocStart(), diag::err_invalid_collection_element)
> +        << Element->getType();
> +      return ExprError();
> +    }
> +  }
> +
> +  // Make sure that the element has the type that the container factory
> +  // function expects.
> +  return S.PerformCopyInitialization(
> +           InitializedEntity::InitializeParameter(S.Context, T,
> +                                                  /*Consumed=*/false),
> +           Element->getLocStart(), Element);
> +}
> +
> +ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
> +                                        Expr *IndexExpr,
> +                                        ObjCMethodDecl *getterMethod,
> +                                        ObjCMethodDecl *setterMethod) {
> +  // Feature support is for modern abi.
> +  if (!LangOpts.ObjCNonFragileABI)
> +    return ExprError();
> +  // If the expression is type-dependent, there's nothing for us to do.
> +  assert ((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
> +          "base or index cannot have dependent type here");
> +  ExprResult Result = CheckPlaceholderExpr(IndexExpr);
> +  if (Result.isInvalid())
> +    return ExprError();
> +  IndexExpr = Result.get();
> +
> +  // Perform lvalue-to-rvalue conversion.
> +  Result = DefaultLvalueConversion(BaseExpr);
> +  if (Result.isInvalid())
> +    return ExprError();
> +  BaseExpr = Result.get();
> +  return Owned(ObjCSubscriptRefExpr::Create(Context,
> +                                            BaseExpr,
> +                                            IndexExpr,
> +                                            Context.PseudoObjectTy,
> +                                            getterMethod,
> +                                            setterMethod, RB));
> +
> +}
> +
> +ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
> +  // Look up the NSArray class, if we haven't done so already.
> +  if (!NSArrayDecl) {
> +    NamedDecl *IF = LookupSingleName(TUScope,
> +                                 NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
> +                                 SR.getBegin(),
> +                                 LookupOrdinaryName);
> +    NSArrayDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
> +    if (!NSArrayDecl && getLangOptions().DebuggerObjCLiteral)
> +      NSArrayDecl =  ObjCInterfaceDecl::Create (Context,
> +                            Context.getTranslationUnitDecl(),
> +                            SourceLocation(),
> +                            NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
> +                            0, SourceLocation());
> +
> +    if (!NSArrayDecl) {
> +      Diag(SR.getBegin(), diag::err_undeclared_nsarray);
> +      return ExprError();
> +    }
> +  }
> +
> +  // Find the arrayWithObjects:count: method, if we haven't done so already.
> +  QualType IdT = Context.getObjCIdType();
> +  if (!ArrayWithObjectsMethod) {
> +    Selector
> +      Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
> +    ArrayWithObjectsMethod = NSArrayDecl->lookupClassMethod(Sel);
> +    if (!ArrayWithObjectsMethod && getLangOptions().DebuggerObjCLiteral) {
> +      TypeSourceInfo *ResultTInfo = 0;
> +      ArrayWithObjectsMethod =
> +                         ObjCMethodDecl::Create(Context,
> +                           SourceLocation(), SourceLocation(), Sel,
> +                           IdT,
> +                           ResultTInfo,
> +                           Context.getTranslationUnitDecl(),
> +                           false /*Instance*/, false/*isVariadic*/,
> +                           /*isSynthesized=*/false,
> +                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
> +                           ObjCMethodDecl::Required,
> +                           false);
> +      SmallVector<ParmVarDecl *, 2> Params;
> +      ParmVarDecl *objects = ParmVarDecl::Create(Context, ArrayWithObjectsMethod,
> +                                                SourceLocation(), SourceLocation(),
> +                                                &Context.Idents.get("objects"),
> +                                                Context.getPointerType(IdT),
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +      Params.push_back(objects);
> +      ParmVarDecl *cnt = ParmVarDecl::Create(Context, ArrayWithObjectsMethod,
> +                                                SourceLocation(), SourceLocation(),
> +                                                &Context.Idents.get("cnt"),
> +                                                Context.UnsignedLongTy,
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +      Params.push_back(cnt);
> +      ArrayWithObjectsMethod->setMethodParams(Context, Params,
> +                                              ArrayRef<SourceLocation>());
> +
> +
> +    }
> +
> +    if (!ArrayWithObjectsMethod) {
> +      Diag(SR.getBegin(), diag::err_undeclared_arraywithobjects) << Sel;
> +      return ExprError();
> +    }
> +  }
> +
> +  // Make sure the return type is reasonable.
> +  if (!ArrayWithObjectsMethod->getResultType()->isObjCObjectPointerType()) {
> +    Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +      << ArrayWithObjectsMethod->getSelector();
> +    Diag(ArrayWithObjectsMethod->getLocation(),
> +         diag::note_objc_literal_method_return)
> +      << ArrayWithObjectsMethod->getResultType();
> +    return ExprError();
> +  }
> +
> +  // Dig out the type that all elements should be converted to.
> +  QualType T = ArrayWithObjectsMethod->param_begin()[0]->getType();
> +  const PointerType *PtrT = T->getAs<PointerType>();
> +  if (!PtrT ||
> +      !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
> +    Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +      << ArrayWithObjectsMethod->getSelector();
> +    Diag(ArrayWithObjectsMethod->param_begin()[0]->getLocation(),
> +         diag::note_objc_literal_method_param)
> +      << 0 << T
> +      << Context.getPointerType(IdT.withConst());
> +    return ExprError();
> +  }
> +  T = PtrT->getPointeeType();
> +
> +  // Check that the 'count' parameter is integral.
> +  if (!ArrayWithObjectsMethod->param_begin()[1]->getType()->isIntegerType()) {
> +    Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +      << ArrayWithObjectsMethod->getSelector();
> +    Diag(ArrayWithObjectsMethod->param_begin()[1]->getLocation(),
> +         diag::note_objc_literal_method_param)
> +      << 1
> +      << ArrayWithObjectsMethod->param_begin()[1]->getType()
> +      << "integral";
> +    return ExprError();
> +  }
> +
> +  // Check that each of the elements provided is valid in a collection literal,
> +  // performing conversions as necessary.
> +  Expr **ElementsBuffer = Elements.get();
> +  for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
> +    ExprResult Converted = CheckObjCCollectionLiteralElement(*this,
> +                                                             ElementsBuffer[I],
> +                                                             T);
> +    if (Converted.isInvalid())
> +      return ExprError();
> +
> +    ElementsBuffer[I] = Converted.get();
> +  }
> +
> +  QualType Ty
> +    = Context.getObjCObjectPointerType(
> +                                    Context.getObjCInterfaceType(NSArrayDecl));
> +
> +  return MaybeBindToTemporary(
> +           ObjCArrayLiteral::Create(Context,
> +                                    llvm::makeArrayRef(Elements.get(),
> +                                                       Elements.size()),
> +                                    Ty, ArrayWithObjectsMethod, SR));
> +}
> +
> +ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
> +                                            ObjCDictionaryElement *Elements,
> +                                            unsigned NumElements) {
> +  // Look up the NSDictionary class, if we haven't done so already.
> +  if (!NSDictionaryDecl) {
> +    NamedDecl *IF = LookupSingleName(TUScope,
> +                            NSAPIObj->getNSClassId(NSAPI::ClassId_NSDictionary),
> +                            SR.getBegin(), LookupOrdinaryName);
> +    NSDictionaryDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
> +    if (!NSDictionaryDecl && getLangOptions().DebuggerObjCLiteral)
> +      NSDictionaryDecl =  ObjCInterfaceDecl::Create (Context,
> +                            Context.getTranslationUnitDecl(),
> +                            SourceLocation(),
> +                            NSAPIObj->getNSClassId(NSAPI::ClassId_NSDictionary),
> +                            0, SourceLocation());
> +
> +    if (!NSDictionaryDecl) {
> +      Diag(SR.getBegin(), diag::err_undeclared_nsdictionary);
> +      return ExprError();
> +    }
> +  }
> +
> +  // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
> +  // so already.
> +  QualType IdT = Context.getObjCIdType();
> +  if (!DictionaryWithObjectsMethod) {
> +    Selector Sel = NSAPIObj->getNSDictionarySelector(
> +                                    NSAPI::NSDict_dictionaryWithObjectsForKeysCount);
> +    DictionaryWithObjectsMethod = NSDictionaryDecl->lookupClassMethod(Sel);
> +    if (!DictionaryWithObjectsMethod && getLangOptions().DebuggerObjCLiteral) {
> +      DictionaryWithObjectsMethod =
> +                         ObjCMethodDecl::Create(Context,
> +                           SourceLocation(), SourceLocation(), Sel,
> +                           IdT,
> +                           0 /*TypeSourceInfo */,
> +                           Context.getTranslationUnitDecl(),
> +                           false /*Instance*/, false/*isVariadic*/,
> +                           /*isSynthesized=*/false,
> +                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
> +                           ObjCMethodDecl::Required,
> +                           false);
> +      SmallVector<ParmVarDecl *, 3> Params;
> +      ParmVarDecl *objects = ParmVarDecl::Create(Context, DictionaryWithObjectsMethod,
> +                                                SourceLocation(), SourceLocation(),
> +                                                &Context.Idents.get("objects"),
> +                                                Context.getPointerType(IdT),
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +      Params.push_back(objects);
> +      ParmVarDecl *keys = ParmVarDecl::Create(Context, DictionaryWithObjectsMethod,
> +                                                SourceLocation(), SourceLocation(),
> +                                                &Context.Idents.get("keys"),
> +                                                Context.getPointerType(IdT),
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +      Params.push_back(keys);
> +      ParmVarDecl *cnt = ParmVarDecl::Create(Context, DictionaryWithObjectsMethod,
> +                                                SourceLocation(), SourceLocation(),
> +                                                &Context.Idents.get("cnt"),
> +                                                Context.UnsignedLongTy,
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +      Params.push_back(cnt);
> +      DictionaryWithObjectsMethod->setMethodParams(Context, Params,
> +                                                   ArrayRef<SourceLocation>());
> +    }
> +
> +    if (!DictionaryWithObjectsMethod) {
> +      Diag(SR.getBegin(), diag::err_undeclared_dictwithobjects) << Sel;
> +      return ExprError();
> +    }
> +  }
> +
> +  // Make sure the return type is reasonable.
> +  if (!DictionaryWithObjectsMethod->getResultType()->isObjCObjectPointerType()){
> +    Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +    << DictionaryWithObjectsMethod->getSelector();
> +    Diag(DictionaryWithObjectsMethod->getLocation(),
> +         diag::note_objc_literal_method_return)
> +    << DictionaryWithObjectsMethod->getResultType();
> +    return ExprError();
> +  }
> +
> +  // Dig out the type that all values should be converted to.
> +  QualType ValueT =  DictionaryWithObjectsMethod->param_begin()[0]->getType();
> +  const PointerType *PtrValue = ValueT->getAs<PointerType>();
> +  if (!PtrValue ||
> +      !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
> +    Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +      << DictionaryWithObjectsMethod->getSelector();
> +    Diag(DictionaryWithObjectsMethod->param_begin()[0]->getLocation(),
> +         diag::note_objc_literal_method_param)
> +      << 0 << ValueT
> +      << Context.getPointerType(IdT.withConst());
> +    return ExprError();
> +  }
> +  ValueT = PtrValue->getPointeeType();
> +
> +  // Dig out the type that all keys should be converted to.
> +  QualType KeyT = DictionaryWithObjectsMethod->param_begin()[1]->getType();
> +  const PointerType *PtrKey = KeyT->getAs<PointerType>();
> +  if (!PtrKey ||
> +      !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
> +                                      IdT)) {
> +    bool err = true;
> +    if (PtrKey) {
> +      if (QIDNSCopying.isNull()) {
> +        // key argument of selector is id<NSCopying>?
> +        if (ObjCProtocolDecl *NSCopyingPDecl =
> +            LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {
> +          ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};
> +          QIDNSCopying =
> +            Context.getObjCObjectType(Context.ObjCBuiltinIdTy,
> +                                      (ObjCProtocolDecl**) PQ,1);
> +          QIDNSCopying = Context.getObjCObjectPointerType(QIDNSCopying);
> +        }
> +      }
> +      if (!QIDNSCopying.isNull())
> +        err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
> +                                              QIDNSCopying);
> +    }
> +
> +    if (err) {
> +      Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +        << DictionaryWithObjectsMethod->getSelector();
> +      Diag(DictionaryWithObjectsMethod->param_begin()[1]->getLocation(),
> +           diag::note_objc_literal_method_param)
> +        << 1 << KeyT
> +        << Context.getPointerType(IdT.withConst());
> +      return ExprError();
> +    }
> +  }
> +  KeyT = PtrKey->getPointeeType();
> +
> +  // Check that the 'count' parameter is integral.
> +  if (!DictionaryWithObjectsMethod->param_begin()[2]->getType()
> +                                                            ->isIntegerType()) {
> +    Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
> +      << DictionaryWithObjectsMethod->getSelector();
> +    Diag(DictionaryWithObjectsMethod->param_begin()[2]->getLocation(),
> +         diag::note_objc_literal_method_param)
> +      << 2
> +      << DictionaryWithObjectsMethod->param_begin()[2]->getType()
> +      << "integral";
> +    return ExprError();
> +  }
> +
> +  // Check that each of the keys and values provided is valid in a collection
> +  // literal, performing conversions as necessary.
> +  bool HasPackExpansions = false;
> +  for (unsigned I = 0, N = NumElements; I != N; ++I) {
> +    // Check the key.
> +    ExprResult Key = CheckObjCCollectionLiteralElement(*this, Elements[I].Key,
> +                                                       KeyT);
> +    if (Key.isInvalid())
> +      return ExprError();
> +
> +    // Check the value.
> +    ExprResult Value
> +      = CheckObjCCollectionLiteralElement(*this, Elements[I].Value, ValueT);
> +    if (Value.isInvalid())
> +      return ExprError();
> +
> +    Elements[I].Key = Key.get();
> +    Elements[I].Value = Value.get();
> +
> +    if (Elements[I].EllipsisLoc.isInvalid())
> +      continue;
> +
> +    if (!Elements[I].Key->containsUnexpandedParameterPack() &&
> +        !Elements[I].Value->containsUnexpandedParameterPack()) {
> +      Diag(Elements[I].EllipsisLoc,
> +           diag::err_pack_expansion_without_parameter_packs)
> +        << SourceRange(Elements[I].Key->getLocStart(),
> +                       Elements[I].Value->getLocEnd());
> +      return ExprError();
> +    }
> +
> +    HasPackExpansions = true;
> +  }
> +
> +
> +  QualType Ty
> +    = Context.getObjCObjectPointerType(
> +                                Context.getObjCInterfaceType(NSDictionaryDecl));
> +  return MaybeBindToTemporary(
> +           ObjCDictionaryLiteral::Create(Context,
> +                                         llvm::makeArrayRef(Elements,
> +                                                            NumElements),
> +                                         HasPackExpansions,
> +                                         Ty,
> +                                         DictionaryWithObjectsMethod, SR));
>  }
>
>  ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
> @@ -1030,6 +1642,50 @@
>
>  }
>
> +static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,
> +                               unsigned DiagID,
> +                               bool (*refactor)(const ObjCMessageExpr *,
> +                                              const NSAPI &, edit::Commit &)) {
> +  SourceLocation MsgLoc = Msg->getExprLoc();
> +  if (S.Diags.getDiagnosticLevel(DiagID, MsgLoc) == DiagnosticsEngine::Ignored)
> +    return;
> +
> +  SourceManager &SM = S.SourceMgr;
> +  edit::Commit ECommit(SM, S.LangOpts);
> +  if (refactor(Msg,*S.NSAPIObj, ECommit)) {
> +    DiagnosticBuilder Builder = S.Diag(MsgLoc, DiagID)
> +                        << Msg->getSelector() << Msg->getSourceRange();
> +    // FIXME: Don't emit diagnostic at all if fixits are non-commitable.
> +    if (!ECommit.isCommitable())
> +      return;
> +    for (edit::Commit::edit_iterator
> +           I = ECommit.edit_begin(), E = ECommit.edit_end(); I != E; ++I) {
> +      const edit::Commit::Edit &Edit = *I;
> +      switch (Edit.Kind) {
> +      case edit::Commit::Act_Insert:
> +        Builder.AddFixItHint(FixItHint::CreateInsertion(Edit.OrigLoc,
> +                                                        Edit.Text,
> +                                                        Edit.BeforePrev));
> +        break;
> +      case edit::Commit::Act_InsertFromRange:
> +        Builder.AddFixItHint(
> +            FixItHint::CreateInsertionFromRange(Edit.OrigLoc,
> +                                                Edit.getInsertFromRange(SM),
> +                                                Edit.BeforePrev));
> +        break;
> +      case edit::Commit::Act_Remove:
> +        Builder.AddFixItHint(FixItHint::CreateRemoval(Edit.getFileRange(SM)));
> +        break;
> +      }
> +    }
> +  }
> +}
> +
> +static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {
> +  applyCocoaAPICheck(S, Msg, diag::warn_objc_redundant_literal_use,
> +                     edit::rewriteObjCRedundantCallWithLiteral);
> +}
> +
>  /// \brief Build an Objective-C class message expression.
>  ///
>  /// This routine takes care of both normal class messages and
> @@ -1146,18 +1802,21 @@
>     return ExprError();
>
>   // Construct the appropriate ObjCMessageExpr.
> -  Expr *Result;
> +  ObjCMessageExpr *Result;
>   if (SuperLoc.isValid())
>     Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
>                                      SuperLoc, /*IsInstanceSuper=*/false,
>                                      ReceiverType, Sel, SelectorLocs,
>                                      Method, makeArrayRef(Args, NumArgs),
>                                      RBracLoc, isImplicit);
> -  else
> +  else {
>     Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
>                                      ReceiverTypeInfo, Sel, SelectorLocs,
>                                      Method, makeArrayRef(Args, NumArgs),
>                                      RBracLoc, isImplicit);
> +    if (!isImplicit)
> +      checkCocoaAPI(*this, Result);
> +  }
>   return MaybeBindToTemporary(Result);
>  }
>
> @@ -1563,11 +2222,14 @@
>                                      ReceiverType, Sel, SelectorLocs, Method,
>                                      makeArrayRef(Args, NumArgs), RBracLoc,
>                                      isImplicit);
> -  else
> +  else {
>     Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
>                                      Receiver, Sel, SelectorLocs, Method,
>                                      makeArrayRef(Args, NumArgs), RBracLoc,
>                                      isImplicit);
> +    if (!isImplicit)
> +      checkCocoaAPI(*this, Result);
> +  }
>
>   if (getLangOptions().ObjCAutoRefCount) {
>     // In ARC, annotate delegate init calls.
>
> Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Tue Mar  6 14:05:56 2012
> @@ -130,6 +130,28 @@
>     }
>   };
>
> +  struct ObjCSubscriptRefRebuilder : Rebuilder<ObjCSubscriptRefRebuilder> {
> +    Expr *NewBase;
> +    Expr *NewKeyExpr;
> +    ObjCSubscriptRefRebuilder(Sema &S, Expr *newBase, Expr *newKeyExpr)
> +    : Rebuilder<ObjCSubscriptRefRebuilder>(S),
> +      NewBase(newBase), NewKeyExpr(newKeyExpr) {}
> +
> +    typedef ObjCSubscriptRefExpr specific_type;
> +    Expr *rebuildSpecific(ObjCSubscriptRefExpr *refExpr) {
> +      assert(refExpr->getBaseExpr());
> +      assert(refExpr->getKeyExpr());
> +
> +      return new (S.Context)
> +        ObjCSubscriptRefExpr(NewBase,
> +                             NewKeyExpr,
> +                             refExpr->getType(), refExpr->getValueKind(),
> +                             refExpr->getObjectKind(),refExpr->getAtIndexMethodDecl(),
> +                             refExpr->setAtIndexMethodDecl(),
> +                             refExpr->getRBracket());
> +    }
> +  };
> +
>   class PseudoOpBuilder {
>   public:
>     Sema &S;
> @@ -215,6 +237,39 @@
>     ExprResult buildGet();
>     ExprResult buildSet(Expr *op, SourceLocation, bool);
>   };
> +
> + /// A PseudoOpBuilder for Objective-C array/dictionary indexing.
> + class ObjCSubscriptOpBuilder : public PseudoOpBuilder {
> +   ObjCSubscriptRefExpr *RefExpr;
> +   OpaqueValueExpr *InstanceBase;
> +   OpaqueValueExpr *InstanceKey;
> +   ObjCMethodDecl *AtIndexGetter;
> +   Selector AtIndexGetterSelector;
> +
> +   ObjCMethodDecl *AtIndexSetter;
> +   Selector AtIndexSetterSelector;
> +
> + public:
> +    ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) :
> +      PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
> +      RefExpr(refExpr),
> +    InstanceBase(0), InstanceKey(0),
> +    AtIndexGetter(0), AtIndexSetter(0) { }
> +
> +   ExprResult buildRValueOperation(Expr *op);
> +   ExprResult buildAssignmentOperation(Scope *Sc,
> +                                       SourceLocation opLoc,
> +                                       BinaryOperatorKind opcode,
> +                                       Expr *LHS, Expr *RHS);
> +   Expr *rebuildAndCaptureObject(Expr *syntacticBase);
> +
> +   bool findAtIndexGetter();
> +   bool findAtIndexSetter();
> +
> +   ExprResult buildGet();
> +   ExprResult buildSet(Expr *op, SourceLocation, bool);
> + };
> +
>  }
>
>  /// Capture the given expression in an OpaqueValueExpr.
> @@ -718,6 +773,438 @@
>   return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
>  }
>
> +// ObjCSubscript build stuff.
> +//
> +
> +/// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
> +/// conversion.
> +/// FIXME. Remove this routine if it is proven that no additional
> +/// specifity is needed.
> +ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
> +  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
> +  if (result.isInvalid()) return ExprError();
> +  return result;
> +}
> +
> +/// objective-c subscripting-specific  behavior for doing assignments.
> +ExprResult
> +ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
> +                                                SourceLocation opcLoc,
> +                                                BinaryOperatorKind opcode,
> +                                                Expr *LHS, Expr *RHS) {
> +  assert(BinaryOperator::isAssignmentOp(opcode));
> +  // There must be a method to do the Index'ed assignment.
> +  if (!findAtIndexSetter())
> +    return ExprError();
> +
> +  // Verify that we can do a compound assignment.
> +  if (opcode != BO_Assign && !findAtIndexGetter())
> +    return ExprError();
> +
> +  ExprResult result =
> +  PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
> +  if (result.isInvalid()) return ExprError();
> +
> +  // Various warnings about objc Index'ed assignments in ARC.
> +  if (S.getLangOptions().ObjCAutoRefCount && InstanceBase) {
> +    S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
> +    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
> +  }
> +
> +  return result;
> +}
> +
> +/// Capture the base object of an Objective-C Index'ed expression.
> +Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
> +  assert(InstanceBase == 0);
> +
> +  // Capture base expression in an OVE and rebuild the syntactic
> +  // form to use the OVE as its base expression.
> +  InstanceBase = capture(RefExpr->getBaseExpr());
> +  InstanceKey = capture(RefExpr->getKeyExpr());
> +
> +  syntacticBase =
> +    ObjCSubscriptRefRebuilder(S, InstanceBase,
> +                              InstanceKey).rebuild(syntacticBase);
> +
> +  return syntacticBase;
> +}
> +
> +/// CheckSubscriptingKind - This routine decide what type
> +/// of indexing represented by "FromE" is being done.
> +Sema::ObjCSubscriptKind
> +  Sema::CheckSubscriptingKind(Expr *FromE) {
> +  // If the expression already has integral or enumeration type, we're golden.
> +  QualType T = FromE->getType();
> +  if (T->isIntegralOrEnumerationType())
> +    return OS_Array;
> +
> +  // If we don't have a class type in C++, there's no way we can get an
> +  // expression of integral or enumeration type.
> +  const RecordType *RecordTy = T->getAs<RecordType>();
> +  if (!RecordTy)
> +    // All other scalar cases are assumed to be dictionary indexing which
> +    // caller handles, with diagnostics if needed.
> +    return OS_Dictionary;
> +  if (!getLangOptions().CPlusPlus || RecordTy->isIncompleteType()) {
> +    // No indexing can be done. Issue diagnostics and quit.
> +    Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
> +    << FromE->getType();
> +    return OS_Error;
> +  }
> +
> +  // We must have a complete class type.
> +  if (RequireCompleteType(FromE->getExprLoc(), T,
> +                          PDiag(diag::err_objc_index_incomplete_class_type)
> +                          << FromE->getSourceRange()))
> +    return OS_Error;
> +
> +  // Look for a conversion to an integral, enumeration type, or
> +  // objective-C pointer type.
> +  UnresolvedSet<4> ViableConversions;
> +  UnresolvedSet<4> ExplicitConversions;
> +  const UnresolvedSetImpl *Conversions
> +    = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
> +
> +  int NoIntegrals=0, NoObjCIdPointers=0;
> +  SmallVector<CXXConversionDecl *, 4> ConversionDecls;
> +
> +  for (UnresolvedSetImpl::iterator I = Conversions->begin(),
> +       E = Conversions->end();
> +       I != E;
> +       ++I) {
> +    if (CXXConversionDecl *Conversion
> +        = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
> +      QualType CT = Conversion->getConversionType().getNonReferenceType();
> +      if (CT->isIntegralOrEnumerationType()) {
> +        ++NoIntegrals;
> +        ConversionDecls.push_back(Conversion);
> +      }
> +      else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
> +        ++NoObjCIdPointers;
> +        ConversionDecls.push_back(Conversion);
> +      }
> +    }
> +  }
> +  if (NoIntegrals ==1 && NoObjCIdPointers == 0)
> +    return OS_Array;
> +  if (NoIntegrals == 0 && NoObjCIdPointers == 1)
> +    return OS_Dictionary;
> +  if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
> +    // No conversion function was found. Issue diagnostic and return.
> +    Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
> +      << FromE->getType();
> +    return OS_Error;
> +  }
> +  Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
> +      << FromE->getType();
> +  for (unsigned int i = 0; i < ConversionDecls.size(); i++)
> +    Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
> +
> +  return OS_Error;
> +}
> +
> +bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
> +  if (AtIndexGetter)
> +    return true;
> +
> +  Expr *BaseExpr = RefExpr->getBaseExpr();
> +  QualType BaseT = BaseExpr->getType();
> +
> +  QualType ResultType;
> +  if (const ObjCObjectPointerType *PTy =
> +      BaseT->getAs<ObjCObjectPointerType>()) {
> +    ResultType = PTy->getPointeeType();
> +    if (const ObjCObjectType *iQFaceTy =
> +        ResultType->getAsObjCQualifiedInterfaceType())
> +      ResultType = iQFaceTy->getBaseType();
> +  }
> +  Sema::ObjCSubscriptKind Res =
> +    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
> +  if (Res == Sema::OS_Error)
> +    return false;
> +  bool arrayRef = (Res == Sema::OS_Array);
> +
> +  if (ResultType.isNull()) {
> +    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
> +      << BaseExpr->getType() << arrayRef;
> +    return false;
> +  }
> +  if (!arrayRef) {
> +    // dictionary subscripting.
> +    // - (id)objectForKeyedSubscript:(id)key;
> +    IdentifierInfo *KeyIdents[] = {
> +      &S.Context.Idents.get("objectForKeyedSubscript")
> +    };
> +    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
> +  }
> +  else {
> +    // - (id)objectAtIndexedSubscript:(size_t)index;
> +    IdentifierInfo *KeyIdents[] = {
> +      &S.Context.Idents.get("objectAtIndexedSubscript")
> +    };
> +
> +    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
> +  }
> +
> +  AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType,
> +                                             true /*instance*/);
> +  bool receiverIdType = (BaseT->isObjCIdType() ||
> +                         BaseT->isObjCQualifiedIdType());
> +
> +  if (!AtIndexGetter && S.getLangOptions().DebuggerObjCLiteral) {
> +    AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
> +                           SourceLocation(), AtIndexGetterSelector,
> +                           S.Context.getObjCIdType() /*ReturnType*/,
> +                           0 /*TypeSourceInfo */,
> +                           S.Context.getTranslationUnitDecl(),
> +                           true /*Instance*/, false/*isVariadic*/,
> +                           /*isSynthesized=*/false,
> +                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
> +                           ObjCMethodDecl::Required,
> +                           false);
> +    ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
> +                                                SourceLocation(), SourceLocation(),
> +                                                arrayRef ? &S.Context.Idents.get("index")
> +                                                         : &S.Context.Idents.get("key"),
> +                                                arrayRef ? S.Context.UnsignedLongTy
> +                                                         : S.Context.getObjCIdType(),
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +    AtIndexGetter->setMethodParams(S.Context, Argument,
> +                                   ArrayRef<SourceLocation>());
> +  }
> +
> +  if (!AtIndexGetter) {
> +    if (!receiverIdType) {
> +      S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
> +      << BaseExpr->getType() << 0 << arrayRef;
> +      return false;
> +    }
> +    AtIndexGetter =
> +      S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector,
> +                                         RefExpr->getSourceRange(),
> +                                         true, false);
> +  }
> +
> +  if (AtIndexGetter) {
> +    QualType T = AtIndexGetter->param_begin()[0]->getType();
> +    if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
> +        (!arrayRef && !T->isObjCObjectPointerType())) {
> +      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
> +             arrayRef ? diag::err_objc_subscript_index_type
> +                      : diag::err_objc_subscript_key_type) << T;
> +      S.Diag(AtIndexGetter->param_begin()[0]->getLocation(),
> +             diag::note_parameter_type) << T;
> +      return false;
> +    }
> +    QualType R = AtIndexGetter->getResultType();
> +    if (!R->isObjCObjectPointerType()) {
> +      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
> +             diag::err_objc_indexing_method_result_type) << R << arrayRef;
> +      S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
> +        AtIndexGetter->getDeclName();
> +    }
> +  }
> +  return true;
> +}
> +
> +bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
> +  if (AtIndexSetter)
> +    return true;
> +
> +  Expr *BaseExpr = RefExpr->getBaseExpr();
> +  QualType BaseT = BaseExpr->getType();
> +
> +  QualType ResultType;
> +  if (const ObjCObjectPointerType *PTy =
> +      BaseT->getAs<ObjCObjectPointerType>()) {
> +    ResultType = PTy->getPointeeType();
> +    if (const ObjCObjectType *iQFaceTy =
> +        ResultType->getAsObjCQualifiedInterfaceType())
> +      ResultType = iQFaceTy->getBaseType();
> +  }
> +
> +  Sema::ObjCSubscriptKind Res =
> +    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
> +  if (Res == Sema::OS_Error)
> +    return false;
> +  bool arrayRef = (Res == Sema::OS_Array);
> +
> +  if (ResultType.isNull()) {
> +    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
> +      << BaseExpr->getType() << arrayRef;
> +    return false;
> +  }
> +
> +  if (!arrayRef) {
> +    // dictionary subscripting.
> +    // - (void)setObject:(id)object forKeyedSubscript:(id)key;
> +    IdentifierInfo *KeyIdents[] = {
> +      &S.Context.Idents.get("setObject"),
> +      &S.Context.Idents.get("forKeyedSubscript")
> +    };
> +    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
> +  }
> +  else {
> +    // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
> +    IdentifierInfo *KeyIdents[] = {
> +      &S.Context.Idents.get("setObject"),
> +      &S.Context.Idents.get("atIndexedSubscript")
> +    };
> +    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
> +  }
> +  AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType,
> +                                             true /*instance*/);
> +
> +  bool receiverIdType = (BaseT->isObjCIdType() ||
> +                         BaseT->isObjCQualifiedIdType());
> +
> +  if (!AtIndexSetter && S.getLangOptions().DebuggerObjCLiteral) {
> +    TypeSourceInfo *ResultTInfo = 0;
> +    QualType ReturnType = S.Context.VoidTy;
> +    AtIndexSetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
> +                           SourceLocation(), AtIndexSetterSelector,
> +                           ReturnType,
> +                           ResultTInfo,
> +                           S.Context.getTranslationUnitDecl(),
> +                           true /*Instance*/, false/*isVariadic*/,
> +                           /*isSynthesized=*/false,
> +                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
> +                           ObjCMethodDecl::Required,
> +                           false);
> +    SmallVector<ParmVarDecl *, 2> Params;
> +    ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
> +                                                SourceLocation(), SourceLocation(),
> +                                                &S.Context.Idents.get("object"),
> +                                                S.Context.getObjCIdType(),
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +    Params.push_back(object);
> +    ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
> +                                                SourceLocation(), SourceLocation(),
> +                                                arrayRef ?  &S.Context.Idents.get("index")
> +                                                         :  &S.Context.Idents.get("key"),
> +                                                arrayRef ? S.Context.UnsignedLongTy
> +                                                         : S.Context.getObjCIdType(),
> +                                                /*TInfo=*/0,
> +                                                SC_None,
> +                                                SC_None,
> +                                                0);
> +    Params.push_back(key);
> +    AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
> +  }
> +
> +  if (!AtIndexSetter) {
> +    if (!receiverIdType) {
> +      S.Diag(BaseExpr->getExprLoc(),
> +             diag::err_objc_subscript_method_not_found)
> +      << BaseExpr->getType() << 1 << arrayRef;
> +      return false;
> +    }
> +    AtIndexSetter =
> +      S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector,
> +                                         RefExpr->getSourceRange(),
> +                                         true, false);
> +  }
> +
> +  bool err = false;
> +  if (AtIndexSetter && arrayRef) {
> +    QualType T = AtIndexSetter->param_begin()[1]->getType();
> +    if (!T->isIntegralOrEnumerationType()) {
> +      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
> +             diag::err_objc_subscript_index_type) << T;
> +      S.Diag(AtIndexSetter->param_begin()[1]->getLocation(),
> +             diag::note_parameter_type) << T;
> +      err = true;
> +    }
> +    T = AtIndexSetter->param_begin()[0]->getType();
> +    if (!T->isObjCObjectPointerType()) {
> +      S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
> +             diag::err_objc_subscript_object_type) << T << arrayRef;
> +      S.Diag(AtIndexSetter->param_begin()[0]->getLocation(),
> +             diag::note_parameter_type) << T;
> +      err = true;
> +    }
> +  }
> +  else if (AtIndexSetter && !arrayRef)
> +    for (unsigned i=0; i <2; i++) {
> +      QualType T = AtIndexSetter->param_begin()[i]->getType();
> +      if (!T->isObjCObjectPointerType()) {
> +        if (i == 1)
> +          S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
> +                 diag::err_objc_subscript_key_type) << T;
> +        else
> +          S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
> +                 diag::err_objc_subscript_dic_object_type) << T;
> +        S.Diag(AtIndexSetter->param_begin()[i]->getLocation(),
> +               diag::note_parameter_type) << T;
> +        err = true;
> +      }
> +    }
> +
> +  return !err;
> +}
> +
> +// Get the object at "Index" position in the container.
> +// [BaseExpr objectAtIndexedSubscript : IndexExpr];
> +ExprResult ObjCSubscriptOpBuilder::buildGet() {
> +  if (!findAtIndexGetter())
> +    return ExprError();
> +
> +  QualType receiverType = InstanceBase->getType();
> +
> +  // Build a message-send.
> +  ExprResult msg;
> +  Expr *Index = InstanceKey;
> +
> +  // Arguments.
> +  Expr *args[] = { Index };
> +  assert(InstanceBase);
> +  msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
> +                                       GenericLoc,
> +                                       AtIndexGetterSelector, AtIndexGetter,
> +                                       MultiExprArg(args, 1));
> +  return msg;
> +}
> +
> +/// Store into the container the "op" object at "Index"'ed location
> +/// by building this messaging expression:
> +/// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
> +/// \param bindSetValueAsResult - If true, capture the actual
> +///   value being set as the value of the property operation.
> +ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
> +                                           bool captureSetValueAsResult) {
> +  if (!findAtIndexSetter())
> +    return ExprError();
> +
> +  QualType receiverType = InstanceBase->getType();
> +  Expr *Index = InstanceKey;
> +
> +  // Arguments.
> +  Expr *args[] = { op, Index };
> +
> +  // Build a message-send.
> +  ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
> +                                                  GenericLoc,
> +                                                  AtIndexSetterSelector,
> +                                                  AtIndexSetter,
> +                                                  MultiExprArg(args, 2));
> +
> +  if (!msg.isInvalid() && captureSetValueAsResult) {
> +    ObjCMessageExpr *msgExpr =
> +      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
> +    Expr *arg = msgExpr->getArg(0);
> +    msgExpr->setArg(0, captureValueAsResult(arg));
> +  }
> +
> +  return msg;
> +}
> +
>  //===----------------------------------------------------------------------===//
>  //  General Sema routines.
>  //===----------------------------------------------------------------------===//
> @@ -728,6 +1215,11 @@
>         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
>     ObjCPropertyOpBuilder builder(*this, refExpr);
>     return builder.buildRValueOperation(E);
> +  }
> +  else if (ObjCSubscriptRefExpr *refExpr
> +           = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
> +    ObjCSubscriptOpBuilder builder(*this, refExpr);
> +    return builder.buildRValueOperation(E);
>   } else {
>     llvm_unreachable("unknown pseudo-object kind!");
>   }
> @@ -747,6 +1239,9 @@
>         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
>     ObjCPropertyOpBuilder builder(*this, refExpr);
>     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
> +  } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
> +    Diag(opcLoc, diag::err_illegal_container_subscripting_op);
> +    return ExprError();
>   } else {
>     llvm_unreachable("unknown pseudo-object kind!");
>   }
> @@ -772,6 +1267,10 @@
>         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
>     ObjCPropertyOpBuilder builder(*this, refExpr);
>     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
> +  } else if (ObjCSubscriptRefExpr *refExpr
> +             = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
> +    ObjCSubscriptOpBuilder builder(*this, refExpr);
> +    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
>   } else {
>     llvm_unreachable("unknown pseudo-object kind!");
>   }
> @@ -786,6 +1285,12 @@
>         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
>     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
>     return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
> +  } else if (ObjCSubscriptRefExpr *refExpr
> +               = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
> +    OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
> +    OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
> +    return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
> +                                     keyOVE->getSourceExpr()).rebuild(E);
>   } else {
>     llvm_unreachable("unknown pseudo-object kind!");
>   }
>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue Mar  6 14:05:56 2012
> @@ -199,8 +199,12 @@
>       Diag(Loc, diag::warn_unused_result) << R1 << R2;
>       return;
>     }
> -  } else if (isa<PseudoObjectExpr>(E)) {
> -    DiagID = diag::warn_unused_property_expr;
> +  } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
> +    const Expr *Source = POE->getSyntacticForm();
> +    if (isa<ObjCSubscriptRefExpr>(Source))
> +      DiagID = diag::warn_unused_container_subscript_expr;
> +    else
> +      DiagID = diag::warn_unused_property_expr;
>   } else if (const CXXFunctionalCastExpr *FC
>                                        = dyn_cast<CXXFunctionalCastExpr>(E)) {
>     if (isa<CXXConstructExpr>(FC->getSubExpr()) ||
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Tue Mar  6 14:05:56 2012
> @@ -93,6 +93,22 @@
>       return inherited::TraverseTemplateName(Template);
>     }
>
> +    /// \brief Suppress traversal into Objective-C container literal
> +    /// elements that are pack expansions.
> +    bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
> +      if (!E->containsUnexpandedParameterPack())
> +        return true;
> +
> +      for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
> +        ObjCDictionaryElement Element = E->getKeyValueElement(I);
> +        if (Element.isPackExpansion())
> +          continue;
> +
> +        TraverseStmt(Element.Key);
> +        TraverseStmt(Element.Value);
> +      }
> +      return true;
> +    }
>     //------------------------------------------------------------------------
>     // Pruning the search for unexpanded parameter packs.
>     //------------------------------------------------------------------------
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Tue Mar  6 14:05:56 2012
> @@ -2210,7 +2210,35 @@
>                                                 OperatorLoc, Pack, PackLoc,
>                                                 RParenLoc);
>   }
> -
> +
> +  /// \brief Build a new Objective-C array literal.
> +  ///
> +  /// By default, performs semantic analysis to build the new expression.
> +  /// Subclasses may override this routine to provide different behavior.
> +  ExprResult RebuildObjCArrayLiteral(SourceRange Range,
> +                                     Expr **Elements, unsigned NumElements) {
> +    return getSema().BuildObjCArrayLiteral(Range,
> +                                           MultiExprArg(Elements, NumElements));
> +  }
> +
> +  ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
> +                                         Expr *Base, Expr *Key,
> +                                         ObjCMethodDecl *getterMethod,
> +                                         ObjCMethodDecl *setterMethod) {
> +    return  getSema().BuildObjCSubscriptExpression(RB, Base, Key,
> +                                                   getterMethod, setterMethod);
> +  }
> +
> +  /// \brief Build a new Objective-C dictionary literal.
> +  ///
> +  /// By default, performs semantic analysis to build the new expression.
> +  /// Subclasses may override this routine to provide different behavior.
> +  ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
> +                                          ObjCDictionaryElement *Elements,
> +                                          unsigned NumElements) {
> +    return getSema().BuildObjCDictionaryLiteral(Range, Elements, NumElements);
> +  }
> +
>   /// \brief Build a new Objective-C @encode expression.
>   ///
>   /// By default, performs semantic analysis to build the new expression.
> @@ -8253,7 +8281,159 @@
>  template<typename Derived>
>  ExprResult
>  TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
> -  return SemaRef.Owned(E);
> +  return SemaRef.MaybeBindToTemporary(E);
> +}
> +
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
> +  return SemaRef.MaybeBindToTemporary(E);
> +}
> +
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformObjCNumericLiteral(ObjCNumericLiteral *E) {
> +  return SemaRef.MaybeBindToTemporary(E);
> +}
> +
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
> +  // Transform each of the elements.
> +  llvm::SmallVector<Expr *, 8> Elements;
> +  bool ArgChanged = false;
> +  if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
> +                                  /*IsCall=*/false, Elements, &ArgChanged))
> +    return ExprError();
> +
> +  if (!getDerived().AlwaysRebuild() && !ArgChanged)
> +    return SemaRef.MaybeBindToTemporary(E);
> +
> +  return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
> +                                              Elements.data(),
> +                                              Elements.size());
> +}
> +
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformObjCDictionaryLiteral(
> +                                                    ObjCDictionaryLiteral *E) {
> +  // Transform each of the elements.
> +  llvm::SmallVector<ObjCDictionaryElement, 8> Elements;
> +  bool ArgChanged = false;
> +  for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
> +    ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
> +
> +    if (OrigElement.isPackExpansion()) {
> +      // This key/value element is a pack expansion.
> +      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
> +      getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
> +      getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
> +      assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
> +
> +      // Determine whether the set of unexpanded parameter packs can
> +      // and should be expanded.
> +      bool Expand = true;
> +      bool RetainExpansion = false;
> +      llvm::Optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
> +      llvm::Optional<unsigned> NumExpansions = OrigNumExpansions;
> +      SourceRange PatternRange(OrigElement.Key->getLocStart(),
> +                               OrigElement.Value->getLocEnd());
> +     if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
> +                                               PatternRange,
> +                                               Unexpanded,
> +                                               Expand, RetainExpansion,
> +                                               NumExpansions))
> +        return ExprError();
> +
> +      if (!Expand) {
> +        // The transform has determined that we should perform a simple
> +        // transformation on the pack expansion, producing another pack
> +        // expansion.
> +        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
> +        ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
> +        if (Key.isInvalid())
> +          return ExprError();
> +
> +        if (Key.get() != OrigElement.Key)
> +          ArgChanged = true;
> +
> +        ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
> +        if (Value.isInvalid())
> +          return ExprError();
> +
> +        if (Value.get() != OrigElement.Value)
> +          ArgChanged = true;
> +
> +        ObjCDictionaryElement Expansion = {
> +          Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
> +        };
> +        Elements.push_back(Expansion);
> +        continue;
> +      }
> +
> +      // Record right away that the argument was changed.  This needs
> +      // to happen even if the array expands to nothing.
> +      ArgChanged = true;
> +
> +      // The transform has determined that we should perform an elementwise
> +      // expansion of the pattern. Do so.
> +      for (unsigned I = 0; I != *NumExpansions; ++I) {
> +        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
> +        ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
> +        if (Key.isInvalid())
> +          return ExprError();
> +
> +        ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
> +        if (Value.isInvalid())
> +          return ExprError();
> +
> +        ObjCDictionaryElement Element = {
> +          Key.get(), Value.get(), SourceLocation(), NumExpansions
> +        };
> +
> +        // If any unexpanded parameter packs remain, we still have a
> +        // pack expansion.
> +        if (Key.get()->containsUnexpandedParameterPack() ||
> +            Value.get()->containsUnexpandedParameterPack())
> +          Element.EllipsisLoc = OrigElement.EllipsisLoc;
> +
> +        Elements.push_back(Element);
> +      }
> +
> +      // We've finished with this pack expansion.
> +      continue;
> +    }
> +
> +    // Transform and check key.
> +    ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
> +    if (Key.isInvalid())
> +      return ExprError();
> +
> +    if (Key.get() != OrigElement.Key)
> +      ArgChanged = true;
> +
> +    // Transform and check value.
> +    ExprResult Value
> +      = getDerived().TransformExpr(OrigElement.Value);
> +    if (Value.isInvalid())
> +      return ExprError();
> +
> +    if (Value.get() != OrigElement.Value)
> +      ArgChanged = true;
> +
> +    ObjCDictionaryElement Element = {
> +      Key.get(), Value.get(), SourceLocation(), llvm::Optional<unsigned>()
> +    };
> +    Elements.push_back(Element);
> +  }
> +
> +  if (!getDerived().AlwaysRebuild() && !ArgChanged)
> +    return SemaRef.MaybeBindToTemporary(E);
> +
> +  return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
> +                                                   Elements.data(),
> +                                                   Elements.size());
>  }
>
>  template<typename Derived>
> @@ -8436,6 +8616,30 @@
>
>  template<typename Derived>
>  ExprResult
> +TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
> +  // Transform the base expression.
> +  ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
> +  if (Base.isInvalid())
> +    return ExprError();
> +
> +  // Transform the key expression.
> +  ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
> +  if (Key.isInvalid())
> +    return ExprError();
> +
> +  // If nothing changed, just retain the existing expression.
> +  if (!getDerived().AlwaysRebuild() &&
> +      Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
> +    return SemaRef.Owned(E);
> +
> +  return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
> +                                                  Base.get(), Key.get(),
> +                                                  E->getAtIndexMethodDecl(),
> +                                                  E->setAtIndexMethodDecl());
> +}
> +
> +template<typename Derived>
> +ExprResult
>  TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
>   // Transform the base expression.
>   ExprResult Base = getDerived().TransformExpr(E->getBase());
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Mar  6 14:05:56 2012
> @@ -823,6 +823,45 @@
>   E->setAtLoc(ReadSourceLocation(Record, Idx));
>  }
>
> +void ASTStmtReader::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
> +  VisitExpr(E);
> +  // could be one of several IntegerLiteral, FloatLiteral, etc.
> +  E->Number = Reader.ReadSubStmt();
> +  E->ObjCNumericLiteralMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
> +  E->AtLoc = ReadSourceLocation(Record, Idx);
> +}
> +
> +void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
> +  VisitExpr(E);
> +  unsigned NumElements = Record[Idx++];
> +  assert(NumElements == E->getNumElements() && "Wrong number of elements");
> +  Expr **Elements = E->getElements();
> +  for (unsigned I = 0, N = NumElements; I != N; ++I)
> +    Elements[I] = Reader.ReadSubExpr();
> +  E->ArrayWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
> +  E->Range = ReadSourceRange(Record, Idx);
> +}
> +
> +void ASTStmtReader::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
> +  VisitExpr(E);
> +  unsigned NumElements = Record[Idx++];
> +  assert(NumElements == E->getNumElements() && "Wrong number of elements");
> +  bool HasPackExpansions = Record[Idx++];
> +  assert(HasPackExpansions == E->HasPackExpansions &&"Pack expansion mismatch");
> +  ObjCDictionaryLiteral::KeyValuePair *KeyValues = E->getKeyValues();
> +  ObjCDictionaryLiteral::ExpansionData *Expansions = E->getExpansionData();
> +  for (unsigned I = 0; I != NumElements; ++I) {
> +    KeyValues[I].Key = Reader.ReadSubExpr();
> +    KeyValues[I].Value = Reader.ReadSubExpr();
> +    if (HasPackExpansions) {
> +      Expansions[I].EllipsisLoc = ReadSourceLocation(Record, Idx);
> +      Expansions[I].NumExpansionsPlusOne = Record[Idx++];
> +    }
> +  }
> +  E->DictWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
> +  E->Range = ReadSourceRange(Record, Idx);
> +}
> +
>  void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
>   VisitExpr(E);
>   E->setEncodedTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
> @@ -878,6 +917,15 @@
>   }
>  }
>
> +void ASTStmtReader::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
> +  VisitExpr(E);
> +  E->setRBracket(ReadSourceLocation(Record, Idx));
> +  E->setBaseExpr(Reader.ReadSubExpr());
> +  E->setKeyExpr(Reader.ReadSubExpr());
> +  E->GetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
> +  E->SetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
> +}
> +
>  void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
>   VisitExpr(E);
>   assert(Record[Idx] == E->getNumArgs());
> @@ -980,6 +1028,12 @@
>   S->setThrowLoc(ReadSourceLocation(Record, Idx));
>  }
>
> +void ASTStmtReader::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
> +  VisitExpr(E);
> +  E->setValue(Record[Idx++]);
> +  E->setLocation(ReadSourceLocation(Record, Idx));
> +}
> +
>  //===----------------------------------------------------------------------===//
>  // C++ Expressions and Statements
>  //===----------------------------------------------------------------------===//
> @@ -1834,6 +1888,18 @@
>     case EXPR_OBJC_STRING_LITERAL:
>       S = new (Context) ObjCStringLiteral(Empty);
>       break;
> +    case EXPR_OBJC_NUMERIC_LITERAL:
> +      S = new (Context) ObjCNumericLiteral(Empty);
> +      break;
> +    case EXPR_OBJC_ARRAY_LITERAL:
> +      S = ObjCArrayLiteral::CreateEmpty(Context,
> +                                        Record[ASTStmtReader::NumExprFields]);
> +      break;
> +    case EXPR_OBJC_DICTIONARY_LITERAL:
> +      S = ObjCDictionaryLiteral::CreateEmpty(Context,
> +            Record[ASTStmtReader::NumExprFields],
> +            Record[ASTStmtReader::NumExprFields + 1]);
> +      break;
>     case EXPR_OBJC_ENCODE:
>       S = new (Context) ObjCEncodeExpr(Empty);
>       break;
> @@ -1849,6 +1915,9 @@
>     case EXPR_OBJC_PROPERTY_REF_EXPR:
>       S = new (Context) ObjCPropertyRefExpr(Empty);
>       break;
> +    case EXPR_OBJC_SUBSCRIPT_REF_EXPR:
> +      S = new (Context) ObjCSubscriptRefExpr(Empty);
> +      break;
>     case EXPR_OBJC_KVC_REF_EXPR:
>       llvm_unreachable("mismatching AST file");
>     case EXPR_OBJC_MESSAGE_EXPR:
> @@ -1888,6 +1957,9 @@
>     case STMT_OBJC_AUTORELEASE_POOL:
>       S = new (Context) ObjCAutoreleasePoolStmt(Empty);
>       break;
> +    case EXPR_OBJC_BOOL_LITERAL:
> +      S = new (Context) ObjCBoolLiteralExpr(Empty);
> +      break;
>     case STMT_SEH_EXCEPT:
>       S = new (Context) SEHExceptStmt(Empty);
>       break;
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar  6 14:05:56 2012
> @@ -696,6 +696,9 @@
>   RECORD(EXPR_BLOCK_DECL_REF);
>   RECORD(EXPR_GENERIC_SELECTION);
>   RECORD(EXPR_OBJC_STRING_LITERAL);
> +  RECORD(EXPR_OBJC_NUMERIC_LITERAL);
> +  RECORD(EXPR_OBJC_ARRAY_LITERAL);
> +  RECORD(EXPR_OBJC_DICTIONARY_LITERAL);
>   RECORD(EXPR_OBJC_ENCODE);
>   RECORD(EXPR_OBJC_SELECTOR_EXPR);
>   RECORD(EXPR_OBJC_PROTOCOL_EXPR);
> @@ -709,6 +712,7 @@
>   RECORD(STMT_OBJC_AT_TRY);
>   RECORD(STMT_OBJC_AT_SYNCHRONIZED);
>   RECORD(STMT_OBJC_AT_THROW);
> +  RECORD(EXPR_OBJC_BOOL_LITERAL);
>   RECORD(EXPR_CXX_OPERATOR_CALL);
>   RECORD(EXPR_CXX_CONSTRUCT);
>   RECORD(EXPR_CXX_STATIC_CAST);
>
> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Mar  6 14:05:56 2012
> @@ -753,7 +753,6 @@
>          i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
>     Writer.AddStmt(*i);
>   }
> -
>   Code = serialization::EXPR_PSEUDO_OBJECT;
>  }
>
> @@ -770,7 +769,6 @@
>   }
>   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
>   Writer.AddSourceLocation(E->getRParenLoc(), Record);
> -
>   Code = serialization::EXPR_ATOMIC;
>  }
>
> @@ -785,6 +783,46 @@
>   Code = serialization::EXPR_OBJC_STRING_LITERAL;
>  }
>
> +void ASTStmtWriter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
> +  VisitExpr(E);
> +  Writer.AddStmt(E->getNumber());
> +  Writer.AddDeclRef(E->getObjCNumericLiteralMethod(), Record);
> +  Writer.AddSourceLocation(E->getAtLoc(), Record);
> +  Code = serialization::EXPR_OBJC_NUMERIC_LITERAL;
> +}
> +
> +void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
> +  VisitExpr(E);
> +  Record.push_back(E->getNumElements());
> +  for (unsigned i = 0; i < E->getNumElements(); i++)
> +    Writer.AddStmt(E->getElement(i));
> +  Writer.AddDeclRef(E->getArrayWithObjectsMethod(), Record);
> +  Writer.AddSourceRange(E->getSourceRange(), Record);
> +  Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
> +}
> +
> +void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
> +  VisitExpr(E);
> +  Record.push_back(E->getNumElements());
> +  Record.push_back(E->HasPackExpansions);
> +  for (unsigned i = 0; i < E->getNumElements(); i++) {
> +    ObjCDictionaryElement Element = E->getKeyValueElement(i);
> +    Writer.AddStmt(Element.Key);
> +    Writer.AddStmt(Element.Value);
> +    if (E->HasPackExpansions) {
> +      Writer.AddSourceLocation(Element.EllipsisLoc, Record);
> +      unsigned NumExpansions = 0;
> +      if (Element.NumExpansions)
> +        NumExpansions = *Element.NumExpansions + 1;
> +      Record.push_back(NumExpansions);
> +    }
> +  }
> +
> +  Writer.AddDeclRef(E->getDictWithObjectsMethod(), Record);
> +  Writer.AddSourceRange(E->getSourceRange(), Record);
> +  Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
> +}
> +
>  void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
>   VisitExpr(E);
>   Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
> @@ -844,6 +882,17 @@
>   Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
>  }
>
> +void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
> +  VisitExpr(E);
> +  Writer.AddSourceLocation(E->getRBracket(), Record);
> +  Writer.AddStmt(E->getBaseExpr());
> +  Writer.AddStmt(E->getKeyExpr());
> +  Writer.AddDeclRef(E->getAtIndexMethodDecl(), Record);
> +  Writer.AddDeclRef(E->setAtIndexMethodDecl(), Record);
> +
> +  Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
> +}
> +
>  void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
>   VisitExpr(E);
>   Record.push_back(E->getNumArgs());
> @@ -945,6 +994,13 @@
>   Code = serialization::STMT_OBJC_AT_THROW;
>  }
>
> +void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
> +  VisitExpr(E);
> +  Record.push_back(E->getValue());
> +  Writer.AddSourceLocation(E->getLocation(), Record);
> +  Code = serialization::EXPR_OBJC_BOOL_LITERAL;
> +}
> +
>  //===----------------------------------------------------------------------===//
>  // C++ Expressions and Statements.
>  //===----------------------------------------------------------------------===//
>
> Added: cfe/trunk/test/CodeGenObjC/Inputs/literal-support.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/Inputs/literal-support.h?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/Inputs/literal-support.h (added)
> +++ cfe/trunk/test/CodeGenObjC/Inputs/literal-support.h Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,35 @@
> +#ifndef OBJC_LITERAL_SUPPORT_H
> +#define OBJC_LITERAL_SUPPORT_H
> +
> +typedef unsigned char BOOL;
> +
> + at interface NSNumber @end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (NSNumber *)numberWithBool:(BOOL)value;
> + at end
> +
> + at interface NSArray
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> + at end
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> + at end
> +
> +#endif // OBJC_LITERAL_SUPPORT_H
>
> Added: cfe/trunk/test/CodeGenObjC/arc-literals.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-literals.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/arc-literals.m (added)
> +++ cfe/trunk/test/CodeGenObjC/arc-literals.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,121 @@
> +// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
> +
> +#include "literal-support.h"
> +
> +// Check the various selector names we'll be using, in order.
> +
> +// CHECK: c"numberWithInt:\00"
> +// CHECK: c"numberWithUnsignedInt:\00"
> +// CHECK: c"numberWithUnsignedLongLong:\00"
> +// CHECK: c"numberWithChar:\00"
> +// CHECK: c"arrayWithObjects:count:\00"
> +// CHECK: c"dictionaryWithObjects:forKeys:count:\00"
> +// CHECK: c"prop\00"
> +
> +// CHECK: define void @test_numeric()
> +void test_numeric() {
> +  // CHECK: {{call.*objc_msgSend.*i32 17}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id ilit = @17;
> +  // CHECK: {{call.*objc_msgSend.*i32 25}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id ulit = @25u;
> +  // CHECK: {{call.*objc_msgSend.*i64 42}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id ulllit = @42ull;
> +  // CHECK: {{call.*objc_msgSend.*i8 signext 97}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id charlit = @'a';
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: ret void
> +}
> +
> +// CHECK: define void @test_array
> +void test_array(id a, id b) {
> +  // Retaining parameters
> +  // CHECK: call i8* @objc_retain(i8*
> +  // CHECK: call i8* @objc_retain(i8*
> +
> +  // Constructing the array
> +  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
> +  // CHECK: store i8*
> +  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
> +  // CHECK: store i8*
> +
> +  // CHECK: {{call i8*.*objc_msgSend.*i64 2}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id arr = @[a, b];
> +
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: ret void
> +}
> +
> +// CHECK: define void @test_dictionary
> +void test_dictionary(id k1, id o1, id k2, id o2) {
> +  // Retaining parameters
> +  // CHECK: call i8* @objc_retain(i8*
> +  // CHECK: call i8* @objc_retain(i8*
> +  // CHECK: call i8* @objc_retain(i8*
> +  // CHECK: call i8* @objc_retain(i8*
> +
> +  // Constructing the arrays
> +  // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0
> +  // CHECK: store i8*
> +  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
> +  // CHECK: store i8*
> +  // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1
> +  // CHECK: store i8*
> +  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
> +  // CHECK: store i8*
> +
> +  // Constructing the dictionary
> +  // CHECK: {{call i8.*@objc_msgSend}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id dict = @{ k1 : o1, k2 : o2 };
> +
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: ret void
> +}
> +
> + at interface A
> + at end
> +
> + at interface B
> + at property (retain) A* prop;
> + at end
> +
> +// CHECK: define void @test_property
> +void test_property(B *b) {
> +  // Retain parameter
> +  // CHECK: call i8* @objc_retain
> +
> +  // Invoke 'prop'
> +  // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
> +  // CHECK: {{call.*@objc_msgSend}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +
> +  // Invoke arrayWithObjects:count:
> +  // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
> +  // CHECK: {{call.*objc_msgSend}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id arr = @[ b.prop ];
> +
> +  // Release b.prop
> +  // CHECK: call void @objc_release
> +
> +  // Destroy arr
> +  // CHECK: call void @objc_release
> +
> +  // Destroy b
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: ret void
> +}
>
> Added: cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m (added)
> +++ cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,21 @@
> +// RUN: %clang_cc1 -fobjc-arc -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(int)index;
> +- (void)setObject:(id)object atIndexedSubscript:(int)index;
> + at end
> +
> +id func() {
> +  NSMutableArray *array;
> +  array[3] = 0;
> +  return array[3];
> +}
> +
> +// CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
> +// CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) nounwind
> +// CHECK: [[ARRAY:%.*]] = load %0**
> +// CHECK: [[ARRAY_CASTED:%.*]] = bitcast{{.*}}[[ARRAY]] to i8*
> +// CHECK: call void @objc_release(i8* [[ARRAY_CASTED]])
> +// CHECK: [[EIGHT:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) nounwind
> +// CHECK: ret i8* [[EIGHT]]
> +
>
> Added: cfe/trunk/test/CodeGenObjC/objc-container-subscripting-1.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-container-subscripting-1.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/objc-container-subscripting-1.m (added)
> +++ cfe/trunk/test/CodeGenObjC/objc-container-subscripting-1.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,56 @@
> +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(size_t)index;
> +- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
> + at end
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> +int main() {
> +  NSMutableArray *array;
> +  id val;
> +
> +  id oldObject = array[10];
> +// CHECK: [[ARR:%.*]] = load {{%.*}} [[array:%.*]], align 8
> +// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_"
> +// CHECK-NEXT: [[ARRC:%.*]] = bitcast {{%.*}} [[ARR]] to i8*
> +// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* [[ARRC]], i8* [[SEL]], i32 10)
> +// CHECK-NEXT: store i8* [[CALL]], i8** [[OLDOBJ:%.*]], align 8
> +
> +  val = (array[10] = oldObject);
> +// CHECK: [[THREE:%.*]] = load {{%.*}} [[array:%.*]], align 8
> +// CHECK-NEXT: [[FOUR:%.*]] = load i8** [[oldObject:%.*]], align 8
> +// CHECK-NEXT: [[FIVE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2"
> +// CHECK-NEXT: [[SIX:%.*]] = bitcast {{%.*}} [[THREE]] to i8*
> +// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i32)*)(i8* [[SIX]], i8* [[FIVE]], i8* [[FOUR]], i32 10)
> +// CHECK-NEXT: store i8* [[FOUR]], i8** [[val:%.*]]
> +
> +  NSMutableDictionary *dictionary;
> +  id key;
> +  id newObject;
> +  oldObject = dictionary[key];
> +// CHECK:  [[SEVEN:%.*]] = load {{%.*}} [[DICTIONARY:%.*]], align 8
> +// CHECK-NEXT:  [[EIGHT:%.*]] = load i8** [[KEY:%.*]], align 8
> +// CHECK-NEXT:  [[TEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_4"
> +// CHECK-NEXT:  [[ELEVEN:%.*]] = bitcast {{%.*}} [[SEVEN]] to i8*
> +// CHECK-NEXT:  [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[ELEVEN]], i8* [[TEN]], i8* [[EIGHT]])
> +// CHECK-NEXT:  store i8* [[CALL1]], i8** [[oldObject:%.*]], align 8
> +
> +
> +  val = (dictionary[key] = newObject);
> +// CHECK: [[TWELVE:%.*]] = load {{%.*}} [[DICTIONARY]], align 8
> +// CHECK-NEXT:  [[THIRTEEN:%.*]] = load i8** [[KEY]], align 8
> +// CHECK-NEXT:  [[FOURTEEN:%.*]] = load i8** [[NEWOBJECT:%.*]], align 8
> +// CHECK-NEXT:  [[SIXTEEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_6"
> +// CHECK-NEXT:  [[SEVENTEEN:%.*]] = bitcast {{%.*}} [[TWELVE]] to i8*
> +// CHECK-NEXT:  call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i8*)*)(i8* [[SEVENTEEN]], i8* [[SIXTEEN]], i8* [[FOURTEEN]], i8* [[THIRTEEN]])
> +// CHECK-NEXT: store i8* [[FOURTEEN]], i8** [[val:%.*]]
> +}
> +
>
> Added: cfe/trunk/test/CodeGenObjC/objc-container-subscripting.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-container-subscripting.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/objc-container-subscripting.m (added)
> +++ cfe/trunk/test/CodeGenObjC/objc-container-subscripting.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,45 @@
> +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o /dev/null
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> +
> + at interface NSMutableArray
> +#if __has_feature(objc_subscripting)
> +- (id)objectAtIndexedSubscript:(size_t)index;
> +- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
> +#endif
> + at end
> +
> +#if __has_feature(objc_subscripting)
> + at interface XNSMutableArray
> +- (id)objectAtIndexedSubscript:(size_t)index;
> +- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
> +#endif
> + at end
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> + at class NSString;
> +
> +int main() {
> +  NSMutableArray<P> * array;
> +  id oldObject = array[10];
> +
> +  array[10] = oldObject;
> +
> +  id unknown_array;
> +  oldObject = unknown_array[1];
> +
> +  unknown_array[1] = oldObject;
> +
> +  NSMutableDictionary *dictionary;
> +  NSString *key;
> +  id newObject;
> +  oldObject = dictionary[key];
> +  dictionary[key] = newObject; // replace oldObject with newObject
> +
> +}
> +
>
> Added: cfe/trunk/test/CodeGenObjC/objc-dictionary-literal.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-dictionary-literal.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/objc-dictionary-literal.m (added)
> +++ cfe/trunk/test/CodeGenObjC/objc-dictionary-literal.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,25 @@
> +// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o /dev/null
> +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o /dev/null
> +// rdar://10614657
> +
> + at interface NSNumber
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> + at end
> +
> + at protocol NSCopying @end
> +typedef unsigned long NSUInteger;
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
> + at end
> +
> + at interface NSString<NSCopying>
> + at end
> +
> +int main() {
> +       NSDictionary *dict = @{ @"name":@666 };
> +       NSDictionary *dict1 = @{ @"name":@666 };
> +       NSDictionary *dict2 = @{ @"name":@666 };
> +       return 0;
> +}
>
> Added: cfe/trunk/test/CodeGenObjC/objc-literal-debugger-test.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-literal-debugger-test.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/objc-literal-debugger-test.m (added)
> +++ cfe/trunk/test/CodeGenObjC/objc-literal-debugger-test.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,16 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdebugger-objc-literal -emit-llvm -o - %s | FileCheck %s
> +
> +int main() {
> +  id l = @'a';
> +  l = @'a';
> +  l = @42;
> +  l = @-42;
> +  l = @42u;
> +  l = @3.141592654f;
> +  l = @__objc_yes;
> +  l = @__objc_no;
> +  l = @{ @"name":@666 };
> +  l = @[ @"foo", @"bar" ];
> +}
> +
> +// CHECK: declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
>
> Added: cfe/trunk/test/CodeGenObjC/objc-literal-tests.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-literal-tests.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/objc-literal-tests.m (added)
> +++ cfe/trunk/test/CodeGenObjC/objc-literal-tests.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,95 @@
> +// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o - | FileCheck %s
> +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o - | FileCheck %s
> +// rdar://10111397
> +
> +#if __has_feature(objc_bool)
> +#define YES __objc_yes
> +#define NO __objc_no
> +#else
> +#define YES             ((BOOL)1)
> +#define NO              ((BOOL)0)
> +#endif
> +
> +#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
> +typedef unsigned long NSUInteger;
> +typedef long NSInteger;
> +#else
> +typedef unsigned int NSUInteger;
> +typedef int NSInteger;
> +#endif
> +typedef signed char BOOL;
> +
> + at interface NSNumber @end
> +
> + at interface NSNumber (NSNumberCreation)
> +#if __has_feature(objc_array_literals)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (NSNumber *)numberWithBool:(BOOL)value;
> ++ (NSNumber *)numberWithInteger:(NSInteger)value ;
> ++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ;
> +#endif
> + at end
> +
> + at interface NSDate
> ++ (NSDate *) date;
> + at end
> +
> +#if __has_feature(objc_dictionary_literals)
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt;
> + at end
> +#endif
> +
> +id NSUserName();
> +
> +// CHECK: define i32 @main() nounwind
> +int main() {
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 97
> +  NSNumber *aNumber = @'a';
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42
> +  NSNumber *fortyTwo = @42;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 -42
> +  NSNumber *negativeFortyTwo = @-42;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42
> +  NSNumber *positiveFortyTwo = @+42;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42
> +  NSNumber *fortyTwoUnsigned = @42u;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i64 42
> +  NSNumber *fortyTwoLong = @42l;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i64 42
> +  NSNumber *fortyTwoLongLong = @42ll;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}float 0x400921FB60000000
> +  NSNumber *piFloat = @3.141592654f;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}double 0x400921FB54411744
> +  NSNumber *piDouble = @3.1415926535;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 1
> +  NSNumber *yesNumber = @__objc_yes;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 0
> +  NSNumber *noNumber = @__objc_no;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 1
> +  NSNumber *yesNumber1 = @YES;
> +  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 0
> +  NSNumber *noNumber1 = @NO;
> +NSDictionary *dictionary = @{@"name" : NSUserName(),
> +                             @"date" : [NSDate date] };
> +  return __objc_yes == __objc_no;
> +}
> +
> +// rdar://10579122
> +typedef BOOL (^foo)(void);
> +extern void bar(foo a);
> +
> +void baz(void) {
> +  bar(^(void) { return YES; });
> +}
>
> Added: cfe/trunk/test/CodeGenObjC/optimized-setter.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/optimized-setter.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/optimized-setter.m (added)
> +++ cfe/trunk/test/CodeGenObjC/optimized-setter.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,33 @@
> +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.8.0 -o - | FileCheck %s
> +// rdar://10179974
> +
> + at interface I
> +// void objc_setProperty_nonatomic(id self, SEL _cmd, id newValue, ptrdiff_t offset);
> +// objc_setProperty(..., NO, NO)
> + at property (nonatomic, retain) id nonatomicProperty;
> +
> +// void objc_setProperty_nonatomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset);
> +// objc_setProperty(..., NO, YES)
> + at property (nonatomic, copy) id nonatomicPropertyCopy;
> +
> +// void objc_setProperty_atomic(id self, SEL _cmd, id newValue, ptrdiff_t offset);
> +// objc_setProperty(..., YES, NO)
> + at property (retain) id atomicProperty;
> +
> +// void objc_setProperty_atomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset);
> +// objc_setProperty(..., YES, YES)
> + at property (copy) id atomicPropertyCopy;
> + at end
> +
> + at implementation I
> + at synthesize nonatomicProperty;
> + at synthesize nonatomicPropertyCopy;
> + at synthesize atomicProperty;
> + at synthesize atomicPropertyCopy;
> + at end
> +
> +// CHECK: call void @objc_setProperty_nonatomic
> +// CHECK: call void @objc_setProperty_nonatomic_copy
> +// CHECK: call void @objc_setProperty_atomic
> +// CHECK: call void @objc_setProperty_atomic_copy
> +
>
> Added: cfe/trunk/test/CodeGenObjCXX/Inputs/literal-support.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/Inputs/literal-support.h?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/Inputs/literal-support.h (added)
> +++ cfe/trunk/test/CodeGenObjCXX/Inputs/literal-support.h Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,35 @@
> +#ifndef OBJC_LITERAL_SUPPORT_H
> +#define OBJC_LITERAL_SUPPORT_H
> +
> +typedef unsigned char BOOL;
> +
> + at interface NSNumber @end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (NSNumber *)numberWithBool:(BOOL)value;
> + at end
> +
> + at interface NSArray
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> + at end
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> + at end
> +
> +#endif // OBJC_LITERAL_SUPPORT_H
>
> Added: cfe/trunk/test/CodeGenObjCXX/literals.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/literals.mm?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/literals.mm (added)
> +++ cfe/trunk/test/CodeGenObjCXX/literals.mm Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,111 @@
> +// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-optzns -o - %s | FileCheck %s
> +
> +#include "literal-support.h"
> +
> +struct X {
> +  X();
> +  ~X();
> +  operator id() const;
> +};
> +
> +struct Y {
> +  Y();
> +  ~Y();
> +  operator id() const;
> +};
> +
> +// CHECK: define void @_Z10test_arrayv
> +void test_array() {
> +  // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
> +
> +  // Initializing first element
> +  // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 0
> +  // CHECK-NEXT: call void @_ZN1XC1Ev
> +  // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
> +  // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]])
> +  // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
> +
> +  // Initializing the second element
> +  // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
> +  // CHECK-NEXT: invoke void @_ZN1YC1Ev
> +  // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
> +  // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]])
> +  // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
> +
> +  // Build the array
> +  // CHECK: {{invoke.*@objc_msgSend}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id arr = @[ X(), Y() ];
> +
> +  // Destroy temporaries
> +  // CHECK-NOT: ret void
> +  // CHECK: call void @objc_release
> +  // CHECK-NOT: ret void
> +  // CHECK: invoke void @_ZN1YD1Ev
> +  // CHECK-NOT: ret void
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: call void @_ZN1XD1Ev
> +  // CHECK-NOT: ret void
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: ret void
> +
> +  // Check cleanups
> +  // CHECK: call void @objc_release
> +  // CHECK-NOT: call void @objc_release
> +  // CHECK: invoke void @_ZN1YD1Ev
> +  // CHECK: call void @objc_release
> +  // CHECK-NOT: call void @objc_release
> +  // CHECK: invoke void @_ZN1XD1Ev
> +  // CHECK-NOT: call void @objc_release
> +  // CHECK: unreachable
> +}
> +
> +// CHECK: define weak_odr void @_Z24test_array_instantiationIiEvv
> +template<typename T>
> +void test_array_instantiation() {
> +  // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
> +
> +  // Initializing first element
> +  // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 0
> +  // CHECK-NEXT: call void @_ZN1XC1Ev
> +  // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
> +  // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]])
> +  // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
> +
> +  // Initializing the second element
> +  // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
> +  // CHECK-NEXT: invoke void @_ZN1YC1Ev
> +  // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
> +  // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]])
> +  // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
> +
> +  // Build the array
> +  // CHECK: {{invoke.*@objc_msgSend}}
> +  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
> +  id arr = @[ X(), Y() ];
> +
> +  // Destroy temporaries
> +  // CHECK-NOT: ret void
> +  // CHECK: call void @objc_release
> +  // CHECK-NOT: ret void
> +  // CHECK: invoke void @_ZN1YD1Ev
> +  // CHECK-NOT: ret void
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: call void @_ZN1XD1Ev
> +  // CHECK-NOT: ret void
> +  // CHECK: call void @objc_release
> +  // CHECK-NEXT: ret void
> +
> +  // Check cleanups
> +  // CHECK: call void @objc_release
> +  // CHECK-NOT: call void @objc_release
> +  // CHECK: invoke void @_ZN1YD1Ev
> +  // CHECK: call void @objc_release
> +  // CHECK-NOT: call void @objc_release
> +  // CHECK: invoke void @_ZN1XD1Ev
> +  // CHECK-NOT: call void @objc_release
> +  // CHECK: unreachable
> +}
> +
> +template void test_array_instantiation<int>();
> +
>
> Added: cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting-1.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting-1.mm?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting-1.mm (added)
> +++ cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting-1.mm Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,50 @@
> +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> + at protocol NSCopying @end
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(size_t)index;
> +- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
> + at end
> +
> +struct S {
> +  operator unsigned int ();
> +  operator id ();
> +};
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id<NSCopying>)key;
> +- (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)key;
> + at end
> +
> +int main() {
> +  NSMutableArray<P> * array;
> +  S s;
> +  id oldObject = array[(int)s];
> +
> +  NSMutableDictionary<P> *dict;
> +  dict[(id)s] = oldObject;
> +  oldObject = dict[(id)s];
> +
> +}
> +
> +template <class T> void test2(NSMutableArray *a) {
> +  a[10] = 0;
> +}
> +template void test2<int>(NSMutableArray*);
> +// CHECK: define weak_odr void @_Z5test2IiEvP14NSMutableArray
> +// CHECK: @objc_msgSend
> +// CHECK: ret void
> +
> +
> +template <class T> void test3(NSMutableArray *a) {
> +  a[sizeof(T)] = 0;
> +}
> +
> +template void test3<int>(NSMutableArray*);
> +// CHECK: define weak_odr void @_Z5test3IiEvP14NSMutableArray
> +// CHECK: @objc_msgSend
> +// CHECK: ret void
> +
>
> Added: cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting.mm?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting.mm (added)
> +++ cfe/trunk/test/CodeGenObjCXX/objc-container-subscripting.mm Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,57 @@
> +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(size_t)index;
> +- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
> + at end
> +
> +struct S {
> +  operator unsigned int ();
> +  operator id ();
> +};
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> +int main() {
> +  NSMutableArray<P> * array;
> +  S s;
> +  id oldObject = array[(int)s];
> +
> +  NSMutableDictionary<P> *dict;
> +  dict[(id)s] = oldObject;
> +  oldObject = dict[(id)s];
> +
> +}
> +
> +template <class T> void test2(NSMutableArray *a) {
> +  a[10] = 0;
> +}
> +template void test2<int>(NSMutableArray*);
> +// CHECK: define weak_odr void @_Z5test2IiEvP14NSMutableArray
> +// CHECK: @objc_msgSend
> +// CHECK: ret void
> +
> +
> +template <class T> void test3(NSMutableArray *a) {
> +  a[sizeof(T)] = 0;
> +}
> +
> +template void test3<int>(NSMutableArray*);
> +// CHECK: define weak_odr void @_Z5test3IiEvP14NSMutableArray
> +// CHECK: @objc_msgSend
> +// CHECK: ret void
> +
> +// CHECK: define void @_Z11static_dataP14NSMutableArray
> +void static_data(NSMutableArray *array) {
> +  // CHECK: call i32 @__cxa_guard_acquire
> +  // CHECK: {{call i8*.*@objc_msgSend }}
> +  // CHECK: call void @__cxa_guard_release
> +  static id x = array[4];
> +  // CHECK: ret void
> +}
>
> Added: cfe/trunk/test/Driver/arclite-link.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/arclite-link.c?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/Driver/arclite-link.c (added)
> +++ cfe/trunk/test/Driver/arclite-link.c Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,8 @@
> +// RUN: touch %t.o
> +// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.7 %t.o 2>&1 | FileCheck -check-prefix=CHECK-ARCLITE-OSX %s
> +// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.8 %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOARCLITE %s
> +// RUN: %clang -### -target i386-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.7 %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOARCLITE %s
> +
> +// CHECK-ARCLITE-OSX: libarclite_macosx.a
> +// CHECK-ARCLITE-OSX: -lobjc
> +// CHECK-NOARCLITE-NOT: libarclite
>
> Modified: cfe/trunk/test/Driver/darwin-ld.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/darwin-ld.c?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/test/Driver/darwin-ld.c (original)
> +++ cfe/trunk/test/Driver/darwin-ld.c Tue Mar  6 14:05:56 2012
> @@ -117,3 +117,7 @@
>  // LINK_VERSION_MIN: "-macosx_version_min" "10.6.0"
>  // LINK_VERSION_MIN: {{ld(.exe)?"}}
>  // LINK_VERSION_MIN: "-macosx_version_min" "10.7.0"
> +
> +// RUN: %clang -target x86_64-apple-darwin12 -### %t.o 2> %t.log
> +// RUN: FileCheck -check-prefix=LINK_NO_CRT1 %s < %t.log
> +// LINK_NO_CRT1-NOT: crt
>
> Modified: cfe/trunk/test/Driver/rewrite-objc.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/rewrite-objc.m?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/test/Driver/rewrite-objc.m (original)
> +++ cfe/trunk/test/Driver/rewrite-objc.m Tue Mar  6 14:05:56 2012
> @@ -3,7 +3,7 @@
>  // TEST0: clang{{.*}}" "-cc1"
>  // TEST0: "-rewrite-objc"
>  // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead.
> -// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option"
> +// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fobjc-default-synthesize-properties" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option"
>  // TEST0: rewrite-objc.m"
>
>  // RUN: not %clang -ccc-no-clang -target unknown -rewrite-objc %s -o - -### 2>&1 | \
>
> Added: cfe/trunk/test/PCH/objc_container.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_container.h?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/PCH/objc_container.h (added)
> +++ cfe/trunk/test/PCH/objc_container.h Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,26 @@
> + at protocol P @end
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(unsigned int)index;
> +- (void)setObject:(id)object atIndexedSubscript:(unsigned int)index;
> + at end
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> +void all() {
> +  NSMutableArray *array;
> +  id oldObject = array[10];
> +
> +  array[10] = oldObject;
> +
> +  NSMutableDictionary *dictionary;
> +  id key;
> +  id newObject;
> +  oldObject = dictionary[key];
> +
> +  dictionary[key] = newObject;
> +}
> +
>
> Added: cfe/trunk/test/PCH/objc_container.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_container.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/PCH/objc_container.m (added)
> +++ cfe/trunk/test/PCH/objc_container.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,20 @@
> +// Test this without pch.
> +// RUN: %clang_cc1 -include %S/objc_container.h -fsyntax-only -verify %s
> +
> +// Test with pch.
> +// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_container.h
> +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
> +// RUN: %clang -cc1 -include-pch %t -ast-print %s | FileCheck -check-prefix=PRINT %s
> +// RUN: %clang -cc1 -include-pch %t -emit-llvm -o - %s | FileCheck -check-prefix=IR %s
> +
> +// CHECK-PRINT: id oldObject = array[10];
> +// CHECK-PRINT: array[10] = oldObject;
> +// CHECK-PRINT: oldObject = dictionary[key];
> +// CHECK-PRINT: dictionary[key] = newObject;
> +
> +// CHECK-IR: define void @all() nounwind
> +// CHECK-IR: {{call.*objc_msgSend}}
> +// CHECK-IR: {{call.*objc_msgSend}}
> +// CHECK-IR: {{call.*objc_msgSend}}
> +// CHECK-IR: {{call.*objc_msgSend}}
> +// CHECK-IR: ret void
>
> Added: cfe/trunk/test/PCH/objc_literals.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_literals.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/PCH/objc_literals.m (added)
> +++ cfe/trunk/test/PCH/objc_literals.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,66 @@
> +// RUN: %clang -cc1 -emit-pch -o %t %s
> +// RUN: %clang -cc1 -include-pch %t -verify %s
> +// RUN: %clang -cc1 -include-pch %t -ast-print %s | FileCheck -check-prefix=PRINT %s
> +// RUN: %clang -cc1 -include-pch %t -emit-llvm -o - %s | FileCheck -check-prefix=IR %s
> +
> +#ifndef HEADER
> +#define HEADER
> +
> +typedef unsigned char BOOL;
> +
> + at interface NSNumber @end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (NSNumber *)numberWithBool:(BOOL)value;
> + at end
> +
> + at interface NSArray
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> + at end
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> + at end
> +
> +// CHECK-IR: define internal void @test_numeric_literals()
> +static inline void test_numeric_literals() {
> +  // CHECK-PRINT: id intlit = @17
> +  // CHECK-IR: {{call.*17}}
> +  id intlit = @17;
> +  // CHECK-PRINT: id floatlit = @17.45
> +  // CHECK-IR: {{call.*1.745}}
> +  id floatlit = @17.45;
> +}
> +
> +static inline void test_array_literals() {
> +  // CHECK-PRINT: id arraylit = @[ @17, @17.45
> +  id arraylit = @[@17, @17.45];
> +}
> +
> +static inline void test_dictionary_literals() {
> +  // CHECK-PRINT: id dictlit = @{ @17 : {{@17.45[^,]*}}, @"hello" : @"world" };
> +  id dictlit = @{@17 : @17.45, @"hello" : @"world" };
> +}
> +
> +#else
> +void test_all() {
> +  test_numeric_literals();
> +  test_array_literals();
> +  test_dictionary_literals();
> +}
> +#endif
>
> Added: cfe/trunk/test/PCH/objc_literals.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_literals.mm?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/PCH/objc_literals.mm (added)
> +++ cfe/trunk/test/PCH/objc_literals.mm Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,65 @@
> +// RUN: %clang -cc1 -emit-pch -x objective-c++ -std=c++0x -o %t %s
> +// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x  -verify %s
> +// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x  -ast-print %s | FileCheck -check-prefix=PRINT %s
> +// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x  -emit-llvm -o - %s | FileCheck -check-prefix=IR %s
> +
> +#ifndef HEADER
> +#define HEADER
> +
> +typedef unsigned char BOOL;
> +
> + at interface NSNumber @end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (NSNumber *)numberWithBool:(BOOL)value;
> + at end
> +
> + at interface NSArray
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> + at end
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> + at end
> +
> +template<typename T, typename U>
> +struct pair {
> +  T first;
> +  U second;
> +};
> +
> +template<typename T, typename U>
> +pair<T, U> make_pair(const T& first, const U& second) {
> +  return { first, second };
> +}
> +
> +// CHECK-IR: define linkonce_odr void @_Z29variadic_dictionary_expansionIJP8NSStringS1_EJP8NSNumberS3_EEvDp4pairIT_T0_E
> +template<typename ...Ts, typename ... Us>
> +void variadic_dictionary_expansion(pair<Ts, Us>... key_values) {
> +  // CHECK-PRINT: id dict = @{ key_values.first : key_values.second... };
> +  // CHECK-IR: {{call.*objc_msgSend}}
> +  // CHECK-IR: ret void
> +  id dict = @{ key_values.first : key_values.second ... };
> +}
> +
> +#else
> +void test_all() {
> +  variadic_dictionary_expansion(make_pair(@"Seventeen", @17),
> +                                make_pair(@"YES", @true));
> +}
> +#endif
>
> Added: cfe/trunk/test/PCH/subscripting-literals.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/subscripting-literals.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/PCH/subscripting-literals.m (added)
> +++ cfe/trunk/test/PCH/subscripting-literals.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,47 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o %t.nopch.ll %s
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-pch -o %t.pch %s
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o %t.pch.ll %s -include-pch %t.pch
> +// RUN: diff %t.nopch.ll %t.pch.ll
> +
> +#ifndef HEADER
> +#define HEADER
> +
> + at interface NSArray
> +- (id)objectAtIndexedSubscript:(int)index;
> ++ (id)arrayWithObjects:(id *)objects count:(unsigned)count;
> + at end
> +
> + at interface NSMutableArray : NSArray
> +- (void)setObject:(id)object atIndexedSubscript:(int)index;
> + at end
> +
> + at interface NSDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> ++ (id)dictionaryWithObjects:(id *)objects forKeys:(id *)keys count:(unsigned)count;
> + at end
> +
> + at interface NSMutableDictionary : NSDictionary
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> + at interface NSNumber
> ++ (NSNumber *)numberWithInt:(int)value;
> + at end
> +
> + at class NSString;
> +
> +id testArray(int idx, id p) {
> +  NSMutableArray *array;
> +  array[idx] = p;
> +  NSArray *arr = @[ p, @7 ];
> +  return array[idx];
> +}
> +
> +void testDict(NSString *key, id newObject, id oldObject) {
> +  NSMutableDictionary *dictionary;
> +  oldObject = dictionary[key];
> +  dictionary[key] = newObject;
> +  NSDictionary *dict = @{ key: newObject, key: oldObject };
> +}
> +
> +#endif
>
> Added: cfe/trunk/test/SemaObjC/cocoa-api-usage.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/cocoa-api-usage.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/cocoa-api-usage.m (added)
> +++ cfe/trunk/test/SemaObjC/cocoa-api-usage.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,88 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only
> +// RUN: cp %s %t.m
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api
> +// RUN: diff %s.fixed %t.m
> +// RUN: cp %s %t.m
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api
> +// RUN: diff %s.fixed %t.m
> +
> +typedef signed char BOOL;
> +#define nil ((void*) 0)
> +
> + at interface NSObject
> ++ (id)alloc;
> + at end
> +
> + at interface NSString : NSObject
> ++ (id)stringWithString:(NSString *)string;
> +- (id)initWithString:(NSString *)aString;
> + at end
> +
> + at interface NSArray : NSObject
> +- (id)objectAtIndex:(unsigned long)index;
> +- (id)objectAtIndexedSubscript:(int)index;
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)array;
> ++ (id)arrayWithObject:(id)anObject;
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> ++ (id)arrayWithObjects:(id)firstObj, ...;
> ++ (id)arrayWithArray:(NSArray *)array;
> +
> +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
> +- (id)initWithObjects:(id)firstObj, ...;
> +- (id)initWithArray:(NSArray *)array;
> +
> +- (id)objectAtIndex:(unsigned long)index;
> + at end
> +
> + at interface NSMutableArray : NSArray
> +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject;
> +- (void)setObject:(id)object atIndexedSubscript:(int)index;
> + at end
> +
> + at interface NSDictionary : NSObject
> +- (id)objectForKeyedSubscript:(id)key;
> + at end
> +
> + at interface NSDictionary (NSDictionaryCreation)
> ++ (id)dictionary;
> ++ (id)dictionaryWithObject:(id)object forKey:(id)key;
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> ++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
> ++ (id)dictionaryWithDictionary:(NSDictionary *)dict;
> ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
> +
> +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> +- (id)initWithObjectsAndKeys:(id)firstObject, ...;
> +- (id)initWithDictionary:(NSDictionary *)otherDictionary;
> +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
> +
> +- (id)objectForKey:(id)aKey;
> + at end
> +
> + at interface NSMutableDictionary : NSDictionary
> +- (void)setObject:(id)anObject forKey:(id)aKey;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> + at interface NSNumber : NSObject
> + at end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithInt:(int)value;
> + at end
> +
> +#define M(x) (x)
> +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
> +#define TWO(x) ((x), (x))
> +
> +void foo() {
> +  NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}}
> +  str = [[NSString alloc] initWithString:@"foo"];
> +  NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}}
> +  NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}}
> +}
>
> Added: cfe/trunk/test/SemaObjC/cocoa-api-usage.m.fixed
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/cocoa-api-usage.m.fixed?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/cocoa-api-usage.m.fixed (added)
> +++ cfe/trunk/test/SemaObjC/cocoa-api-usage.m.fixed Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,88 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only
> +// RUN: cp %s %t.m
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api
> +// RUN: diff %s.fixed %t.m
> +// RUN: cp %s %t.m
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api
> +// RUN: diff %s.fixed %t.m
> +
> +typedef signed char BOOL;
> +#define nil ((void*) 0)
> +
> + at interface NSObject
> ++ (id)alloc;
> + at end
> +
> + at interface NSString : NSObject
> ++ (id)stringWithString:(NSString *)string;
> +- (id)initWithString:(NSString *)aString;
> + at end
> +
> + at interface NSArray : NSObject
> +- (id)objectAtIndex:(unsigned long)index;
> +- (id)objectAtIndexedSubscript:(int)index;
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)array;
> ++ (id)arrayWithObject:(id)anObject;
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> ++ (id)arrayWithObjects:(id)firstObj, ...;
> ++ (id)arrayWithArray:(NSArray *)array;
> +
> +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
> +- (id)initWithObjects:(id)firstObj, ...;
> +- (id)initWithArray:(NSArray *)array;
> +
> +- (id)objectAtIndex:(unsigned long)index;
> + at end
> +
> + at interface NSMutableArray : NSArray
> +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject;
> +- (void)setObject:(id)object atIndexedSubscript:(int)index;
> + at end
> +
> + at interface NSDictionary : NSObject
> +- (id)objectForKeyedSubscript:(id)key;
> + at end
> +
> + at interface NSDictionary (NSDictionaryCreation)
> ++ (id)dictionary;
> ++ (id)dictionaryWithObject:(id)object forKey:(id)key;
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> ++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
> ++ (id)dictionaryWithDictionary:(NSDictionary *)dict;
> ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
> +
> +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
> +- (id)initWithObjectsAndKeys:(id)firstObject, ...;
> +- (id)initWithDictionary:(NSDictionary *)otherDictionary;
> +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
> +
> +- (id)objectForKey:(id)aKey;
> + at end
> +
> + at interface NSMutableDictionary : NSDictionary
> +- (void)setObject:(id)anObject forKey:(id)aKey;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key;
> + at end
> +
> + at interface NSNumber : NSObject
> + at end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithInt:(int)value;
> + at end
> +
> +#define M(x) (x)
> +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
> +#define TWO(x) ((x), (x))
> +
> +void foo() {
> +  NSString *str = M(@"foo"); // expected-warning {{redundant}}
> +  str = [[NSString alloc] initWithString:@"foo"];
> +  NSArray *arr = @[str]; // expected-warning {{redundant}}
> +  NSDictionary *dict = @{str: arr}; // expected-warning {{redundant}}
> +}
>
> Modified: cfe/trunk/test/SemaObjC/invalid-code.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/invalid-code.m?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/invalid-code.m (original)
> +++ cfe/trunk/test/SemaObjC/invalid-code.m Tue Mar  6 14:05:56 2012
> @@ -2,7 +2,8 @@
>
>  // rdar://6124613
>  void test1() {
> -  void *p = @1; // expected-error {{unexpected '@' in program}}
> +  void *xyzzy = 0;
> +  void *p = @xyzzy; // expected-error {{unexpected '@' in program}}
>  }
>
>  // <rdar://problem/7495713>
>
> Added: cfe/trunk/test/SemaObjC/objc-array-literal.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-array-literal.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-array-literal.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-array-literal.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,41 @@
> +// RUN: %clang_cc1  -fsyntax-only -verify %s
> +// rdar://10111397
> +
> +#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
> +typedef unsigned long NSUInteger;
> +#else
> +typedef unsigned int NSUInteger;
> +#endif
> +
> + at class NSString;
> +
> +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
> +
> + at class NSFastEnumerationState;
> +
> + at protocol NSFastEnumeration
> +
> +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len;
> +
> + at end
> +
> + at interface NSNumber
> ++ (NSNumber *)numberWithInt:(int)value;
> + at end
> +
> + at interface NSArray <NSFastEnumeration>
> ++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
> + at end
> +
> +
> +int main() {
> + NSArray *array = @[@"Hello", @"There", @"How Are You", [NSNumber numberWithInt:42]];
> +
> +  for (id string in array)
> +    NSLog(@"%@\n", string);
> +
> +  NSArray *array1 = @["Forgot"]; // expected-error {{string literal must be prefixed by '@' in a collection}}
> +
> +  const char *blah;
> +  NSArray *array2 = @[blah]; // expected-error{{collection element of type 'const char *' is not an Objective-C object}}
> +}
>
> Added: cfe/trunk/test/SemaObjC/objc-container-subscripting-1.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-container-subscripting-1.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-container-subscripting-1.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-container-subscripting-1.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,23 @@
> +// RUN: %clang_cc1  -fsyntax-only -verify %s
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> +
> + at interface NSMutableArray
> + at end
> +
> + at interface XNSMutableArray
> + at end
> +
> +int main() {
> +id array;
> +id oldObject = array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}}
> +
> +array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}}
> +
> +id<P> p_array;
> +oldObject = p_array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}}
> +
> +p_array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}}
> +}
> +
>
> Added: cfe/trunk/test/SemaObjC/objc-container-subscripting-2.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-container-subscripting-2.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-container-subscripting-2.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-container-subscripting-2.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,30 @@
> +// RUN: %clang_cc1  -fsyntax-only -verify %s
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(size_t)index;
> +- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
> + at end
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> +- (void)setObject:(id)object forKeyedSubscript:(size_t)key;
> + at end
> +
> +id func() {
> +  NSMutableArray *array;
> +  float f;
> +  array[f] = array; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}}
> +  return array[3.14]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}}
> +}
> +
> +void test_unused() {
> +  NSMutableArray *array;
> +  array[10]; // expected-warning {{container access result unused - container access should not be used for side effects}}
> +
> +  NSMutableDictionary *dict;
> +  dict[array]; // expected-warning {{container access result unused - container access should not be used for side effects}}
> +}
> +
>
> Added: cfe/trunk/test/SemaObjC/objc-container-subscripting-3.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-container-subscripting-3.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-container-subscripting-3.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-container-subscripting-3.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,25 @@
> +// RUN: %clang_cc1  -fsyntax-only -verify %s
> +// rdar://10904488
> +
> + at interface Test
> +- (int)objectAtIndexedSubscript:(int)index; // expected-note {{method 'objectAtIndexedSubscript:' declared here}}
> +- (void)setObject:(int)object atIndexedSubscript:(int)index; // expected-note {{parameter of type 'int' is declared here}}
> + at end
> +
> + at interface NSMutableDictionary
> +- (int)objectForKeyedSubscript:(id)key; // expected-note {{method 'objectForKeyedSubscript:' declared here}}
> +- (void)setObject:(int)object forKeyedSubscript:(id)key; // expected-note {{parameter of type 'int' is declared here}}
> + at end
> +
> +int main() {
> +   Test *array;
> +   int i = array[10]; // expected-error {{method for accessing array element must have Objective-C object return type instead of 'int'}}
> +   array[2] = i;     // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'int' is not an objective-C pointer type}}
> +
> +   NSMutableDictionary *dict;
> +   id key, val;
> +   val = dict[key]; // expected-error {{method for accessing dictionary element must have Objective-C object return type instead of 'int'}} \
> +                    // expected-warning {{incompatible integer to pointer conversion assigning to 'id' from 'int'}}
> +   dict[key] = val; // expected-error {{method object parameter type 'int' is not object type}}
> +}
> +
>
> Added: cfe/trunk/test/SemaObjC/objc-container-subscripting.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-container-subscripting.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-container-subscripting.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-container-subscripting.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,42 @@
> +// RUN: %clang_cc1  -fsyntax-only -verify %s
> +
> +typedef unsigned int size_t;
> + at protocol P @end
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(double)index; // expected-note {{parameter of type 'double' is declared here}}
> +- (void)setObject:(id *)object atIndexedSubscript:(void *)index; // expected-note {{parameter of type 'void *' is declared here}} \
> +                                                                // expected-note {{parameter of type 'id *' is declared here}}
> + at end
> + at interface I @end
> +
> +int main() {
> +  NSMutableArray<P> * array;
> +  id  oldObject = array[10]; // expected-error {{method index parameter type 'double' is not integral type}}
> +  array[3] = 0; // expected-error {{method index parameter type 'void *' is not integral type}} \
> +                // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'id *' is not an objective-C pointer type}}
> +
> +  I* iarray;
> +  iarray[3] = 0; // expected-error {{expected method to write array element not found on object of type 'I *'}}
> +  I* p = iarray[4]; // expected-error {{expected method to read array element not found on object of type 'I *'}}
> +
> +  oldObject = array[10]++; // expected-error {{illegal operation on objective-c container subscripting}}
> +  oldObject = array[10]--; // expected-error {{illegal operation on objective-c container subscripting}}
> +  oldObject = --array[10]; // expected-error {{illegal operation on objective-c container subscripting}}
> +}
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id*)key; // expected-note {{parameter of type 'id *' is declared here}}
> +- (void)setObject:(void*)object forKeyedSubscript:(id*)key; // expected-note {{parameter of type 'void *' is declared here}} \
> +                                                            // expected-note {{parameter of type 'id *' is declared here}}
> + at end
> + at class NSString;
> +
> +void testDict() {
> +  NSMutableDictionary *dictionary;
> +  NSString *key;
> +  id newObject, oldObject;
> +  oldObject = dictionary[key];  // expected-error {{method key parameter type 'id *' is not object type}}
> +  dictionary[key] = newObject;  // expected-error {{method object parameter type 'void *' is not object type}} \
> +                                // expected-error {{method key parameter type 'id *' is not object type}}
> +}
>
> Added: cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,78 @@
> +// RUN: %clang_cc1  -fsyntax-only -fblocks -verify %s
> +// rdar://10111397
> +
> +#if __LP64__
> +typedef unsigned long NSUInteger;
> +#else
> +typedef unsigned int NSUInteger;
> +#endif
> +
> + at interface NSObject
> ++ (NSObject*)nsobject;
> + at end
> +
> + at interface NSNumber : NSObject
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> + at end
> +
> +int main() {
> +  NSNumber * N = @3.1415926535;  // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}}
> +  NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}}
> +  NSNumber * NInt = @1000;
> +  NSNumber * NLongDouble = @1000.0l; // expected-error{{'long double' is not a valid literal type for NSNumber}}
> +  id character = @ 'a';
> +
> +  NSNumber *NNegativeInt = @-1000;
> +  NSNumber *NPositiveInt = @+1000;
> +  NSNumber *NNegativeFloat = @-1000.1f;
> +  NSNumber *NPositiveFloat = @+1000.1f;
> +
> +  int five = 5;
> +  @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}}
> +  @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}}
> +}
> +
> +// Dictionary test
> + at class NSDictionary;
> +
> +NSDictionary *err() {
> +  return @{@"name" : @"value"}; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}}
> +}
> +
> + at interface NSDate : NSObject
> ++ (NSDate *) date;
> + at end
> +
> + at protocol NSCopying
> +- copy;
> + at end
> +
> + at interface NSDictionary : NSObject
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt;
> + at end
> +
> + at interface NSString<NSCopying>
> + at end
> +
> +id NSUserName();
> +
> +int Int();
> +
> +NSDictionary * blocks() {
> +  return @{ @"task" : ^ { return 17; } };
> +}
> +
> +NSDictionary * warn() {
> +  NSDictionary *dictionary = @{@"name" : NSUserName(),
> +                               @"date" : [NSDate date],
> +                               @"name2" : @"other",
> +                               NSObject.nsobject : @"nsobject" }; // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}}
> +  NSDictionary *dictionary2 = @{@"name" : Int()}; // expected-error {{collection element of type 'int' is not an Objective-C object}}
> +
> +  NSObject *o;
> +  NSDictionary *dictionary3 = @{o : o, // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}}
> +                               @"date" : [NSDate date] };
> +  return dictionary3;
> +}
>
> Added: cfe/trunk/test/SemaObjC/objc-literal-sig.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-literal-sig.m?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/objc-literal-sig.m (added)
> +++ cfe/trunk/test/SemaObjC/objc-literal-sig.m Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,40 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s
> +typedef _Bool BOOL;
> +
> + at interface NSNumber @end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (int)numberWithBool:(BOOL)value; // expected-note{{method returns unexpected type 'int' (should be an object type)}}
> + at end
> +
> + at interface NSArray
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)arrayWithObjects:(const int [])objects // expected-note{{first parameter has unexpected type 'const int *' (should be 'const id *')}}
> +                 count:(unsigned long)cnt;
> + at end
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects
> +                    forKeys:(const int [])keys // expected-note{{second parameter has unexpected type 'const int *' (should be 'const id *')}}
> +                      count:(unsigned long)cnt;
> + at end
> +
> +void test_sig() {
> +  (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}}
> +  id array = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}}
> +  id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}}
> +}
>
> Modified: cfe/trunk/test/SemaObjC/sizeof-interface.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/sizeof-interface.m?rev=152137&r1=152136&r2=152137&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/sizeof-interface.m (original)
> +++ cfe/trunk/test/SemaObjC/sizeof-interface.m Tue Mar  6 14:05:56 2012
> @@ -1,6 +1,6 @@
>  // RUN: %clang_cc1 -verify -fsyntax-only %s
>
> - at class I0; // expected-note 3{{forward declaration of class here}}
> + at class I0; // expected-note 2{{forward declaration of class here}}
>
>  // rdar://6811884
>  int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an incomplete type 'I0'}}
> @@ -9,7 +9,7 @@
>  void *g3(I0 *P) {
>   P = P+5;        // expected-error {{arithmetic on a pointer to an incomplete type 'I0'}}
>
> -  return &P[4];   // expected-error{{subscript of pointer to incomplete type 'I0'}}
> +  return &P[4];   // expected-error{{expected method to read array element not found on object of type 'I0 *'}}
>  }
>
>
> @@ -55,7 +55,7 @@
>   P = 5+P;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
>   P = P-5;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
>
> -  return P[4].x[2];  // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}}
> +  return P[4].x[2];  // expected-error {{expected method to read array element not found on object of type 'I0 *'}}
>  }
>
>
>
> Added: cfe/trunk/test/SemaObjCXX/literals.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/literals.mm?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjCXX/literals.mm (added)
> +++ cfe/trunk/test/SemaObjCXX/literals.mm Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,178 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fblocks %s
> +
> +typedef unsigned char BOOL;
> +
> + at protocol NSCopying
> +- copy;
> + at end
> +
> + at interface NSObject
> + at end
> +
> + at interface NSNumber : NSObject <NSCopying>
> +-copy;
> + at end
> +
> + at interface NSNumber (NSNumberCreation)
> ++ (NSNumber *)numberWithChar:(char)value;
> ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
> ++ (NSNumber *)numberWithShort:(short)value;
> ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
> ++ (NSNumber *)numberWithInt:(int)value;
> ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
> ++ (NSNumber *)numberWithLong:(long)value;
> ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
> ++ (NSNumber *)numberWithLongLong:(long long)value;
> ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
> ++ (NSNumber *)numberWithFloat:(float)value;
> ++ (NSNumber *)numberWithDouble:(double)value;
> ++ (NSNumber *)numberWithBool:(BOOL)value;
> + at end
> +
> + at interface NSArray : NSObject <NSCopying>
> +-copy;
> + at end
> +
> + at interface NSArray (NSArrayCreation)
> ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
> + at end
> +
> + at interface NSDictionary
> ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt;
> + at end
> +
> +template<typename T>
> +struct ConvertibleTo {
> +  operator T();
> +};
> +
> +template<typename T>
> +struct ExplicitlyConvertibleTo {
> +  explicit operator T();
> +};
> +
> +template<typename T>
> +class PrivateConvertibleTo {
> +private:
> +  operator T(); // expected-note{{declared private here}}
> +};
> +
> +template<typename T> ConvertibleTo<T> makeConvertible();
> +
> +struct X {
> +  ConvertibleTo<id> x;
> +  ConvertibleTo<id> get();
> +};
> +
> +template<typename T> T test_numeric_instantiation() {
> +  return @-17.42;
> +}
> +
> +template id test_numeric_instantiation();
> +
> +void test_convertibility(ConvertibleTo<NSArray*> toArray,
> +                         ConvertibleTo<id> toId,
> +                         ConvertibleTo<int (^)(int)> toBlock,
> +                         ConvertibleTo<int> toInt,
> +                         ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) {
> +  id array = @[
> +               toArray,
> +               toId,
> +               toBlock,
> +               toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}}
> +              ];
> +  id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}}
> +
> +  id array3 = @[
> +                makeConvertible<id>(),
> +                               makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}}
> +               ];
> +
> +  X x;
> +  id array4 = @[ x.x ];
> +  id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}}
> +  id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}}
> +}
> +
> +template<typename T>
> +void test_array_literals(T t) {
> +  id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
> +}
> +
> +template void test_array_literals(id);
> +template void test_array_literals(NSArray*);
> +template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}}
> +
> +template<typename T, typename U>
> +void test_dictionary_literals(T t, U u) {
> +  NSObject *object;
> +  id dict = @{
> +    @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}}
> +    u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}}
> +  };
> +
> +  id dict2 = @{
> +    object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}}
> +  };
> +}
> +
> +template void test_dictionary_literals(id, NSArray*);
> +template void test_dictionary_literals(NSArray*, id);
> +template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}}
> +template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}}
> +
> +template<typename ...Args>
> +void test_bad_variadic_array_literal(Args ...args) {
> +  id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
> +}
> +
> +template<typename ...Args>
> +void test_variadic_array_literal(Args ...args) {
> +  id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
> +}
> +template void test_variadic_array_literal(id);
> +template void test_variadic_array_literal(id, NSArray*);
> +template void test_variadic_array_literal(id, int, NSArray*); // expected-note{{in instantiation of function template specialization 'test_variadic_array_literal<id, int, NSArray *>' requested here}}
> +
> +template<typename ...Args>
> +void test_bad_variadic_dictionary_literal(Args ...args) {
> +  id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
> +}
> +
> +// Test array literal pack expansions.
> +template<typename T, typename U>
> +struct pair {
> +  T first;
> +  U second;
> +};
> +
> +template<typename T, typename ...Ts, typename ... Us>
> +void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) {
> +  id dict = @{
> +    t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}}
> +    key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}}
> +    key_values.second : t ...
> +  };
> +}
> +
> +template void test_variadic_dictionary_expansion(id,
> +                                                 pair<NSNumber*, id>,
> +                                                 pair<id, ConvertibleTo<id>>);
> +template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
> +                                                 pair<NSNumber*, int>,
> +                                                 pair<id, ConvertibleTo<id>>);
> +template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
> +                                                 pair<NSNumber*, id>,
> +                                                 pair<float, ConvertibleTo<id>>);
> +
> +// Test parsing
> +struct key {
> +  static id value;
> +};
> +
> +id key;
> +id value;
> +
> +void test_dictionary_colon() {
> +  id dict = @{ key : value };
> +}
>
> Added: cfe/trunk/test/SemaObjCXX/objc-container-subscripting.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/objc-container-subscripting.mm?rev=152137&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjCXX/objc-container-subscripting.mm (added)
> +++ cfe/trunk/test/SemaObjCXX/objc-container-subscripting.mm Tue Mar  6 14:05:56 2012
> @@ -0,0 +1,138 @@
> +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin11 -fsyntax-only -std=c++11 -verify %s
> +
> + at class NSArray;
> +
> + at interface NSMutableDictionary
> +- (id)objectForKeyedSubscript:(id)key;
> +- (void)setObject:(id)object forKeyedSubscript:(id)key; // expected-note {{passing argument to parameter 'object' here}}
> + at end
> +
> +template<typename T, typename U, typename O>
> +void test_dictionary_subscripts(T base, U key, O obj) {
> +  base[key] = obj; // expected-error {{expected method to write array element not found on object of type 'NSMutableDictionary *'}} \
> +                   // expected-error {{cannot initialize a parameter of type 'id' with an lvalue of type 'int'}}
> +  obj = base[key];  // expected-error {{expected method to read array element not found on object of type 'NSMutableDictionary *'}} \
> +                    // expected-error {{assigning to 'int' from incompatible type 'id'}}
> +
> +}
> +
> +template void test_dictionary_subscripts(NSMutableDictionary*, id, NSArray *ns);
> +
> +template void test_dictionary_subscripts(NSMutableDictionary*, NSArray *ns, id);
> +
> +template void test_dictionary_subscripts(NSMutableDictionary*, int, id); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, int, id>' requested here}}
> +
> +template void test_dictionary_subscripts(NSMutableDictionary*, id, int); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, id, int>' requested here}}
> +
> +
> + at interface NSMutableArray
> +- (id)objectAtIndexedSubscript:(int)index;
> +- (void)setObject:(id)object atIndexedSubscript:(int)index;
> + at end
> +
> +template<typename T, typename U, typename O>
> +void test_array_subscripts(T base, U index, O obj) {
> +  base[index] = obj; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}}
> +  obj = base[index]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}}
> +}
> +
> +template void  test_array_subscripts(NSMutableArray *, int, id);
> +template void  test_array_subscripts(NSMutableArray *, short, id);
> +enum E { e };
> +
> +template void  test_array_subscripts(NSMutableArray *, E, id);
> +
> +template void  test_array_subscripts(NSMutableArray *, double, id); // expected-note {{in instantiation of function template specialization 'test_array_subscripts<NSMutableArray *, double, id>' requested here}}
> +
> +template<typename T>
> +struct ConvertibleTo {
> +  operator T();
> +};
> +
> +template<typename T>
> +struct ExplicitlyConvertibleTo {
> +  explicit operator T();
> +};
> +
> +template<typename T> ConvertibleTo<T> makeConvertible();
> +
> +struct X {
> +  ConvertibleTo<id> x;
> +  ConvertibleTo<id> get();
> +};
> +
> +NSMutableArray *test_array_convertibility(ConvertibleTo<NSMutableArray*> toArray,
> +                         ConvertibleTo<id> toId,
> +                         ConvertibleTo<int (^)(int)> toBlock,
> +                         ConvertibleTo<int> toInt,
> +                         ExplicitlyConvertibleTo<NSMutableArray *> toArrayExplicit) {
> +  id array;
> +
> +  array[1] = toArray;
> +
> +  array[4] = array[1];
> +
> +  toArrayExplicit[2] = toId; // expected-error {{type 'ExplicitlyConvertibleTo<NSMutableArray *>' does not provide a subscript operator}}
> +
> +  return array[toInt];
> +
> +}
> +
> +id test_dict_convertibility(ConvertibleTo<NSMutableDictionary*> toDict,
> +                         ConvertibleTo<id> toId,
> +                         ConvertibleTo<int (^)(int)> toBlock,
> +                         ConvertibleTo<int> toInt,
> +                         ExplicitlyConvertibleTo<NSMutableDictionary *> toDictExplicit) {
> +
> +
> +  NSMutableDictionary *Dict;
> +  id Id;
> +  Dict[toId] = toBlock;
> +
> +  Dict[toBlock] = toBlock;
> +
> +  Dict[toBlock] = Dict[toId] = Dict[toBlock];
> +
> +  Id = toDictExplicit[toId] = Id; // expected-error {{no viable overloaded operator[] for type 'ExplicitlyConvertibleTo<NSMutableDictionary *>'}}
> +
> +  return Dict[toBlock];
> +}
> +
> +
> +template<typename ...Args>
> +void test_bad_variadic_array_subscripting(Args ...args) {
> +  id arr1;
> +  arr1[3] = args; // expected-error {{expression contains unexpanded parameter pack 'args'}}
> +}
> +
> +template<typename ...Args>
> +void test_variadic_array_subscripting(Args ...args) {
> +  id arr[] = {args[3]...}; // which means: {a[3], b[3], c[3]};
> +}
> +
> +template void test_variadic_array_subscripting(id arg1, NSMutableArray* arg2, id arg3);
> +
> + at class Key;
> +
> +template<typename Index, typename ...Args>
> +void test_variadic_dictionary_subscripting(Index I, Args ...args) {
> +  id arr[] = {args[I]...}; // which means: {a[3], b[3], c[3]};
> +}
> +
> +template void test_variadic_dictionary_subscripting(Key *key, id arg1, NSMutableDictionary* arg2, id arg3);
> +
> +template<int N>
> +id get(NSMutableArray *array) {
> + return array[N]; // array[N] should be a value- and instantiation-dependent ObjCSubscriptRefExpr
> +}
> +
> +struct WeirdIndex {
> +   operator int(); // expected-note {{type conversion function declared here}}
> +   operator id(); // expected-note {{type conversion function declared here}}
> +};
> +
> +id FUNC(WeirdIndex w) {
> +  NSMutableArray *array;
> +  return array[w]; // expected-error {{indexing expression is invalid because subscript type 'WeirdIndex' has multiple type conversion functions}}
> +}
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list