From: Fariborz Jahanian Date: Wed, 6 Aug 2014 18:13:46 +0000 (+0000) Subject: Objective-C ARC. First patch toward generating new APIs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8d3e43c6b16dadeb16e63396e05dc3497cd03aee;p=clang Objective-C ARC. First patch toward generating new APIs 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 --- diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 817c0cc431..3145549a34 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -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 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 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 VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, + ObjCMethodDecl *allocMethod, SourceRange SR); explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, @@ -294,6 +308,7 @@ public: ArrayRef 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; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 1e52e53532..97f1b88261 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -4041,10 +4041,12 @@ Stmt::child_range ObjCMessageExpr::children() { ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef 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 Elements, ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C, ArrayRef 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 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 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 * diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 8ca80808e0..a67e900a17 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -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(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. diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index a200548aa0..d1999296e6 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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()); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 126cd1527c..4a844c59d2 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -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, diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index c4e88f0f18..c22bc3eff3 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -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(Record, Idx); + E->ArrayAllocMethod = ReadDeclAs(Record, Idx); E->Range = ReadSourceRange(Record, Idx); } @@ -955,6 +956,7 @@ void ASTStmtReader::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { } } E->DictWithObjectsMethod = ReadDeclAs(Record, Idx); + E->DictAllocMethod = ReadDeclAs(Record, Idx); E->Range = ReadSourceRange(Record, Idx); } diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 462271a0ea..f77f4b947c 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -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; } diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp index 7dc53a6275..6ac48a8340 100644 --- a/tools/libclang/IndexBody.cpp +++ b/tools/libclang/IndexBody.cpp @@ -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; }