]> granicus.if.org Git - clang/commitdiff
Objective-C ARC. First patch toward generating new APIs
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 6 Aug 2014 18:13:46 +0000 (18:13 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 6 Aug 2014 18:13:46 +0000 (18:13 +0000)
for Objective-C's array and dictionary literals.
rdar://17554063. This is wip.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214983 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprObjC.h
lib/AST/Expr.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.h
lib/Sema/SemaExprObjC.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
tools/libclang/IndexBody.cpp

index 817c0cc431311556ad8af44917e2c2168bd89b97..3145549a3409d55ffb6e6f25905b19eb246b02c3 100644 (file)
@@ -134,9 +134,13 @@ class ObjCArrayLiteral : public Expr {
   unsigned NumElements;
   SourceRange Range;
   ObjCMethodDecl *ArrayWithObjectsMethod;
+  /// \brief in arc mode, this field holds array allocation method declaration.
+  /// In MRR mode, it is null
+  ObjCMethodDecl *ArrayAllocMethod;
   
   ObjCArrayLiteral(ArrayRef<Expr *> Elements,
                    QualType T, ObjCMethodDecl * Method,
+                   ObjCMethodDecl *allocMethod,
                    SourceRange SR);
   
   explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
@@ -146,6 +150,7 @@ public:
   static ObjCArrayLiteral *Create(const ASTContext &C,
                                   ArrayRef<Expr *> Elements,
                                   QualType T, ObjCMethodDecl * Method,
+                                  ObjCMethodDecl *allocMethod,
                                   SourceRange SR);
 
   static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
@@ -184,6 +189,10 @@ public:
     return ArrayWithObjectsMethod; 
   }
     
+  ObjCMethodDecl *getArrayAllocMethod() const {
+    return ArrayAllocMethod;
+  }
+    
   // Iterators
   child_range children() { 
     return child_range((Stmt **)getElements(), 
@@ -256,10 +265,15 @@ class ObjCDictionaryLiteral : public Expr {
   
   SourceRange Range;
   ObjCMethodDecl *DictWithObjectsMethod;
+
+  /// \brief for arc-specific dictionary literals, this field is used to store
+  /// NSDictionary allocation method declaration. It is null for MRR mode.
+  ObjCMethodDecl *DictAllocMethod;
     
   ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 
                         bool HasPackExpansions,
                         QualType T, ObjCMethodDecl *method,
+                        ObjCMethodDecl *allocMethod,
                         SourceRange SR);
 
   explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
@@ -294,6 +308,7 @@ public:
                                        ArrayRef<ObjCDictionaryElement> VK, 
                                        bool HasPackExpansions,
                                        QualType T, ObjCMethodDecl *method,
+                                       ObjCMethodDecl *allocMethod,
                                        SourceRange SR);
   
   static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
@@ -320,6 +335,9 @@ public:
   ObjCMethodDecl *getDictWithObjectsMethod() const
     { return DictWithObjectsMethod; }
 
+  ObjCMethodDecl *getDictAllocMethod() const
+    { return DictAllocMethod; }
+
   SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
   SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
index 1e52e535329a52611ff06759cf32ccdeb0e66981..97f1b8826193909e41889380c01776cfae92dd3c 100644 (file)
@@ -4041,10 +4041,12 @@ Stmt::child_range ObjCMessageExpr::children() {
 
 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, 
                                    QualType T, ObjCMethodDecl *Method,
+                                   ObjCMethodDecl *AllocMethod,
                                    SourceRange SR)
   : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, 
          false, false, false, false), 
-    NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method)
+    NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method),
+    ArrayAllocMethod(AllocMethod)
 {
   Expr **SaveElements = getElements();
   for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
@@ -4062,10 +4064,11 @@ ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements,
 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
                                            ArrayRef<Expr *> Elements,
                                            QualType T, ObjCMethodDecl * Method,
+                                           ObjCMethodDecl *allocMethod,
                                            SourceRange SR) {
   void *Mem = C.Allocate(sizeof(ObjCArrayLiteral) 
                          + Elements.size() * sizeof(Expr *));
-  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
+  return new (Mem) ObjCArrayLiteral(Elements, T, Method, allocMethod, SR);
 }
 
 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
@@ -4080,11 +4083,13 @@ ObjCDictionaryLiteral::ObjCDictionaryLiteral(
                                              ArrayRef<ObjCDictionaryElement> VK, 
                                              bool HasPackExpansions,
                                              QualType T, ObjCMethodDecl *method,
+                                             ObjCMethodDecl *allocMethod,
                                              SourceRange SR)
   : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
          false, false),
     NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR), 
-    DictWithObjectsMethod(method)
+    DictWithObjectsMethod(method),
+    DictAllocMethod(allocMethod)
 {
   KeyValuePair *KeyValues = getKeyValues();
   ExpansionData *Expansions = getExpansionData();
@@ -4117,6 +4122,7 @@ ObjCDictionaryLiteral::Create(const ASTContext &C,
                               ArrayRef<ObjCDictionaryElement> VK, 
                               bool HasPackExpansions,
                               QualType T, ObjCMethodDecl *method,
+                              ObjCMethodDecl *allocMethod,
                               SourceRange SR) {
   unsigned ExpansionsSize = 0;
   if (HasPackExpansions)
@@ -4124,7 +4130,8 @@ ObjCDictionaryLiteral::Create(const ASTContext &C,
     
   void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + 
                          sizeof(KeyValuePair) * VK.size() + ExpansionsSize);
-  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
+  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T,
+                                         method, allocMethod, SR);
 }
 
 ObjCDictionaryLiteral *
index 8ca80808e007fd32355afb271016963646d787bb..a67e900a1793034598f08fdf2426ebb5d44f3c12 100644 (file)
@@ -88,7 +88,8 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {
 }
 
 llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
-                                    const ObjCMethodDecl *MethodWithObjects) {
+                                    const ObjCMethodDecl *MethodWithObjects,
+                                    const ObjCMethodDecl *AllocMethod) {
   ASTContext &Context = CGM.getContext();
   const ObjCDictionaryLiteral *DLE = nullptr;
   const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E);
@@ -203,12 +204,14 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
 }
 
 llvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) {
-  return EmitObjCCollectionLiteral(E, E->getArrayWithObjectsMethod());
+  return EmitObjCCollectionLiteral(E, E->getArrayWithObjectsMethod(),
+                                      E->getArrayAllocMethod());
 }
 
 llvm::Value *CodeGenFunction::EmitObjCDictionaryLiteral(
                                             const ObjCDictionaryLiteral *E) {
-  return EmitObjCCollectionLiteral(E, E->getDictWithObjectsMethod());
+  return EmitObjCCollectionLiteral(E, E->getDictWithObjectsMethod(),
+                                      E->getDictAllocMethod());
 }
 
 /// Emit a selector.
index a200548aa0e6c873196038a49ffc45af12c963c9..d1999296e6916d82e728e369e44222118f99c01c 100644 (file)
@@ -2304,7 +2304,8 @@ public:
   llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
   llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
   llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
-                                const ObjCMethodDecl *MethodWithObjects);
+                                const ObjCMethodDecl *MethodWithObjects,
+                                const ObjCMethodDecl *AllocMethod);
   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
                              ReturnValueSlot Return = ReturnValueSlot());
index 126cd1527c03c03d026ff61489767e1ceaaca4f9..4a844c59d29f6b80aff41fd518a5aa840c86112c 100644 (file)
@@ -740,7 +740,7 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
 
   return MaybeBindToTemporary(
            ObjCArrayLiteral::Create(Context, Elements, Ty,
-                                    ArrayWithObjectsMethod, SR));
+                                    ArrayWithObjectsMethod, nullptr, SR));
 }
 
 ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, 
@@ -925,7 +925,7 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
                                 Context.getObjCInterfaceType(NSDictionaryDecl));
   return MaybeBindToTemporary(ObjCDictionaryLiteral::Create(
       Context, makeArrayRef(Elements, NumElements), HasPackExpansions, Ty,
-      DictionaryWithObjectsMethod, SR));
+      DictionaryWithObjectsMethod, nullptr, SR));
 }
 
 ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
index c4e88f0f18d35645b0673909e0bff173bb9f8cfa..c22bc3eff337afa85bfcfcf7f2faaf7cb2afa069 100644 (file)
@@ -935,6 +935,7 @@ void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
   for (unsigned I = 0, N = NumElements; I != N; ++I)
     Elements[I] = Reader.ReadSubExpr();
   E->ArrayWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
+  E->ArrayAllocMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
   E->Range = ReadSourceRange(Record, Idx);
 }
 
@@ -955,6 +956,7 @@ void ASTStmtReader::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
     }
   }
   E->DictWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
+  E->DictAllocMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
   E->Range = ReadSourceRange(Record, Idx);
 }
 
index 462271a0ea72c047011a8d02638cfa696664e9f5..f77f4b947c1ac43c9107f86fbe5cf2a4406bee56 100644 (file)
@@ -878,6 +878,7 @@ void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
   for (unsigned i = 0; i < E->getNumElements(); i++)
     Writer.AddStmt(E->getElement(i));
   Writer.AddDeclRef(E->getArrayWithObjectsMethod(), Record);
+  Writer.AddDeclRef(E->getArrayAllocMethod(), Record);
   Writer.AddSourceRange(E->getSourceRange(), Record);
   Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
 }
@@ -900,6 +901,7 @@ void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
   }
     
   Writer.AddDeclRef(E->getDictWithObjectsMethod(), Record);
+  Writer.AddDeclRef(E->getDictAllocMethod(), Record);
   Writer.AddSourceRange(E->getSourceRange(), Record);
   Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
 }
index 7dc53a627533a65c708d74f6dbcc463d8faedf21..6ac48a8340006f3bffaafa57119f1439aea827a3 100644 (file)
@@ -109,6 +109,9 @@ public:
     if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
       IndexCtx.handleReference(MD, E->getLocStart(),
                                Parent, ParentDC, E, CXIdxEntityRef_Implicit);
+    if (ObjCMethodDecl *MD = E->getDictAllocMethod())
+      IndexCtx.handleReference(MD, E->getLocStart(),
+                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
     return true;
   }
 
@@ -116,6 +119,9 @@ public:
     if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
       IndexCtx.handleReference(MD, E->getLocStart(),
                                Parent, ParentDC, E, CXIdxEntityRef_Implicit);
+    if (ObjCMethodDecl *MD = E->getArrayAllocMethod())
+      IndexCtx.handleReference(MD, E->getLocStart(),
+                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
     return true;
   }