diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-10-03 06:36:51 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-10-03 06:36:51 +0000 |
commit | a6011e25a1c77de6eba3974737a5c21c319602c6 (patch) | |
tree | c715bcf5e42c591688aae94967cbd35b5898d130 /clang/lib | |
parent | 59ad1e3f574a33f2a2d3a1d80a1a22b657deba09 (diff) | |
download | bcm5719-llvm-a6011e25a1c77de6eba3974737a5c21c319602c6.tar.gz bcm5719-llvm-a6011e25a1c77de6eba3974737a5c21c319602c6.zip |
Allow getting all source locations of selector identifiers in a ObjCMessageExpr.
Instead of always storing all source locations for the selector identifiers
we check whether all the identifiers are in a "standard" position; "standard" position is
-Immediately before the arguments: [foo first:1 second:2]
-With a space between the arguments: [foo first: 1 second: 2]
-For nullary selectors, immediately before ']': [foo release]
In such cases we infer the locations instead of storing them.
llvm-svn: 140987
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 105 | ||||
-rw-r--r-- | clang/lib/AST/SelectorLocationsKind.cpp | 102 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 16 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 8 |
7 files changed, 191 insertions, 53 deletions
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 00fad798ef2..1f0100a580a 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -35,6 +35,7 @@ add_clang_library(clangAST ParentMap.cpp RecordLayout.cpp RecordLayoutBuilder.cpp + SelectorLocationsKind.cpp Stmt.cpp StmtDumper.cpp StmtIterator.cpp diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index f93ce72d254..b7276aa82f4 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2716,7 +2716,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, bool IsInstanceSuper, QualType SuperType, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, SourceLocation RBracLoc) @@ -2728,12 +2729,10 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method : Sel.getAsOpaquePtr())), - SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) + LBracLoc(LBracLoc), RBracLoc(RBracLoc) { - setNumArgs(Args.size()); + initArgsAndSelLocs(Args, SelLocs, SelLocsK); setReceiverPointer(SuperType.getAsOpaquePtr()); - if (!Args.empty()) - std::copy(Args.begin(), Args.end(), getArgs()); } ObjCMessageExpr::ObjCMessageExpr(QualType T, @@ -2741,7 +2740,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, SourceLocation RBracLoc) @@ -2752,23 +2752,10 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, HasMethod(Method != 0), IsDelegateInitCall(false), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method : Sel.getAsOpaquePtr())), - SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) + LBracLoc(LBracLoc), RBracLoc(RBracLoc) { - setNumArgs(Args.size()); + initArgsAndSelLocs(Args, SelLocs, SelLocsK); setReceiverPointer(Receiver); - Expr **MyArgs = getArgs(); - for (unsigned I = 0; I != Args.size(); ++I) { - if (Args[I]->isTypeDependent()) - ExprBits.TypeDependent = true; - if (Args[I]->isValueDependent()) - ExprBits.ValueDependent = true; - if (Args[I]->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (Args[I]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; - - MyArgs[I] = Args[I]; - } } ObjCMessageExpr::ObjCMessageExpr(QualType T, @@ -2776,7 +2763,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, SourceLocation RBracLoc) @@ -2788,10 +2776,16 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, HasMethod(Method != 0), IsDelegateInitCall(false), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method : Sel.getAsOpaquePtr())), - SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) + LBracLoc(LBracLoc), RBracLoc(RBracLoc) { - setNumArgs(Args.size()); + initArgsAndSelLocs(Args, SelLocs, SelLocsK); setReceiverPointer(Receiver); +} + +void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK) { + setNumArgs(Args.size()); Expr **MyArgs = getArgs(); for (unsigned I = 0; I != Args.size(); ++I) { if (Args[I]->isTypeDependent()) @@ -2805,6 +2799,10 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, MyArgs[I] = Args[I]; } + + SelLocsKind = SelLocsK; + if (SelLocsK == SelLoc_NonStandard) + std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, @@ -2818,12 +2816,11 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, SourceLocation RBracLoc) { - unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + - Args.size() * sizeof(Expr *); - void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); + SelectorLocationsKind SelLocsK; + ObjCMessageExpr *Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, - SuperType, Sel, SelLocs.front(), Method, - Args, RBracLoc); + SuperType, Sel, SelLocs, SelLocsK, + Method, Args, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, @@ -2835,12 +2832,10 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, SourceLocation RBracLoc) { - unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + - Args.size() * sizeof(Expr *); - void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); + SelectorLocationsKind SelLocsK; + ObjCMessageExpr *Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, - SelLocs.front(), - Method, Args, RBracLoc); + SelLocs, SelLocsK, Method, Args, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, @@ -2852,22 +2847,46 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, SourceLocation RBracLoc) { - unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + - Args.size() * sizeof(Expr *); - void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); + SelectorLocationsKind SelLocsK; + ObjCMessageExpr *Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, - SelLocs.front(), - Method, Args, RBracLoc); + SelLocs, SelLocsK, Method, Args, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(ASTContext &Context, - unsigned NumArgs) { - unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + - NumArgs * sizeof(Expr *); - void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); + unsigned NumArgs, + unsigned NumStoredSelLocs) { + ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); } +ObjCMessageExpr *ObjCMessageExpr::alloc(ASTContext &C, + ArrayRef<Expr *> Args, + SourceLocation RBraceLoc, + ArrayRef<SourceLocation> SelLocs, + Selector Sel, + SelectorLocationsKind &SelLocsK) { + SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); + unsigned NumStoredSelLocs = (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() + : 0; + return alloc(C, Args.size(), NumStoredSelLocs); +} + +ObjCMessageExpr *ObjCMessageExpr::alloc(ASTContext &C, + unsigned NumArgs, + unsigned NumStoredSelLocs) { + unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + + NumArgs * sizeof(Expr *) + NumStoredSelLocs * sizeof(SourceLocation); + return (ObjCMessageExpr *)C.Allocate(Size, + llvm::AlignOf<ObjCMessageExpr>::Alignment); +} + +void ObjCMessageExpr::getSelectorLocs( + SmallVectorImpl<SourceLocation> &SelLocs) const { + for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) + SelLocs.push_back(getSelectorLoc(i)); +} + SourceRange ObjCMessageExpr::getReceiverRange() const { switch (getReceiverKind()) { case Instance: diff --git a/clang/lib/AST/SelectorLocationsKind.cpp b/clang/lib/AST/SelectorLocationsKind.cpp new file mode 100644 index 00000000000..cafb105e996 --- /dev/null +++ b/clang/lib/AST/SelectorLocationsKind.cpp @@ -0,0 +1,102 @@ +//===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Describes whether the identifier locations for a selector are "standard" +// or not. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/SelectorLocationsKind.h" +#include "clang/AST/Expr.h" + +using namespace clang; + +static SourceLocation getStandardSelLoc(unsigned Index, + Selector Sel, + bool WithArgSpace, + SourceLocation ArgLoc, + SourceLocation EndLoc) { + unsigned NumSelArgs = Sel.getNumArgs(); + if (NumSelArgs == 0) { + assert(Index == 0); + if (EndLoc.isInvalid()) + return SourceLocation(); + IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0); + unsigned Len = II ? II->getLength() : 0; + return EndLoc.getLocWithOffset(-Len); + } + + assert(Index < NumSelArgs); + if (ArgLoc.isInvalid()) + return SourceLocation(); + IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index); + unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1; + if (WithArgSpace) + ++Len; + return ArgLoc.getLocWithOffset(-Len); +} + +namespace { + +template <typename T> +SourceLocation getArgLoc(T* Arg); + +template <> +SourceLocation getArgLoc<Expr>(Expr *Arg) { + return Arg->getLocStart(); +} + +template <typename T> +SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) { + return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation(); +} + +template <typename T> +SelectorLocationsKind hasStandardSelLocs(Selector Sel, + ArrayRef<SourceLocation> SelLocs, + ArrayRef<T *> Args, + SourceLocation EndLoc) { + // Are selector locations in standard position with no space between args ? + unsigned i; + for (i = 0; i != SelLocs.size(); ++i) { + if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false, + Args, EndLoc)) + break; + } + if (i == SelLocs.size()) + return SelLoc_StandardNoSpace; + + // Are selector locations in standard position with space between args ? + for (i = 0; i != SelLocs.size(); ++i) { + if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true, + Args, EndLoc)) + return SelLoc_NonStandard; + } + + return SelLoc_StandardWithSpace; +} + +} // anonymous namespace + +SelectorLocationsKind +clang::hasStandardSelectorLocs(Selector Sel, + ArrayRef<SourceLocation> SelLocs, + ArrayRef<Expr *> Args, + SourceLocation EndLoc) { + return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); +} + +SourceLocation clang::getStandardSelectorLoc(unsigned Index, + Selector Sel, + bool WithArgSpace, + ArrayRef<Expr *> Args, + SourceLocation EndLoc) { + return getStandardSelLoc(Index, Sel, WithArgSpace, + getArgLoc(Index, Args), EndLoc); +} diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 824e82b9d33..d5d073fd6fa 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10129,7 +10129,7 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { d = mem->getMemberDecl(); } else if (ObjCMessageExpr *msg = dyn_cast<ObjCMessageExpr>(E)) { diagID = diag::err_uncasted_call_of_unknown_any; - loc = msg->getSelectorLoc(); + loc = msg->getSelectorStartLoc(); d = msg->getMethodDecl(); if (!d) { S.Diag(loc, diag::err_uncasted_send_to_unknown_any_method) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 509c450ced7..99ddd239129 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2152,7 +2152,7 @@ public: /// \brief Build a new Objective-C class message. ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo, Selector Sel, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, @@ -2160,14 +2160,14 @@ public: return SemaRef.BuildClassMessage(ReceiverTypeInfo, ReceiverTypeInfo->getType(), /*SuperLoc=*/SourceLocation(), - Sel, Method, LBracLoc, SelectorLoc, + Sel, Method, LBracLoc, SelectorLocs, RBracLoc, move(Args)); } /// \brief Build a new Objective-C instance message. ExprResult RebuildObjCMessageExpr(Expr *Receiver, Selector Sel, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, @@ -2175,7 +2175,7 @@ public: return SemaRef.BuildInstanceMessage(Receiver, Receiver->getType(), /*SuperLoc=*/SourceLocation(), - Sel, Method, LBracLoc, SelectorLoc, + Sel, Method, LBracLoc, SelectorLocs, RBracLoc, move(Args)); } @@ -7794,9 +7794,11 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { return SemaRef.Owned(E); // Build a new class message send. + SmallVector<SourceLocation, 16> SelLocs; + E->getSelectorLocs(SelLocs); return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo, E->getSelector(), - E->getSelectorLoc(), + SelLocs, E->getMethodDecl(), E->getLeftLoc(), move_arg(Args), @@ -7817,9 +7819,11 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { return SemaRef.Owned(E); // Build a new instance message send. + SmallVector<SourceLocation, 16> SelLocs; + E->getSelectorLocs(SelLocs); return getDerived().RebuildObjCMessageExpr(Receiver.get(), E->getSelector(), - E->getSelectorLoc(), + SelLocs, E->getMethodDecl(), E->getLeftLoc(), move_arg(Args), diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 0571c10666e..e2a78e9d1ea 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -841,6 +841,8 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { VisitExpr(E); assert(Record[Idx] == E->getNumArgs()); ++Idx; + unsigned NumStoredSelLocs = Record[Idx++]; + E->SelLocsKind = Record[Idx++]; E->setDelegateInitCall(Record[Idx++]); ObjCMessageExpr::ReceiverKind Kind = static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]); @@ -871,10 +873,13 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { E->LBracLoc = ReadSourceLocation(Record, Idx); E->RBracLoc = ReadSourceLocation(Record, Idx); - E->SelectorLoc = ReadSourceLocation(Record, Idx); for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, Reader.ReadSubExpr()); + + SourceLocation *Locs = E->getStoredSelLocs(); + for (unsigned I = 0; I != NumStoredSelLocs; ++I) + Locs[I] = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { @@ -1747,7 +1752,8 @@ Stmt *ASTReader::ReadStmtFromStream(Module &F) { break; case EXPR_OBJC_MESSAGE_EXPR: S = ObjCMessageExpr::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); + Record[ASTStmtReader::NumExprFields], + Record[ASTStmtReader::NumExprFields + 1]); break; case EXPR_OBJC_ISA: S = new (Context) ObjCIsaExpr(Empty); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index a8c02a557f0..b7d7afdfa84 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -806,6 +806,8 @@ void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); + Record.push_back(E->getNumStoredSelLocs()); + Record.push_back(E->SelLocsKind); Record.push_back(E->isDelegateInitCall()); Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding switch (E->getReceiverKind()) { @@ -834,11 +836,15 @@ void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { Writer.AddSourceLocation(E->getLeftLoc(), Record); Writer.AddSourceLocation(E->getRightLoc(), Record); - Writer.AddSourceLocation(E->getSelectorLoc(), Record); for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); Arg != ArgEnd; ++Arg) Writer.AddStmt(*Arg); + + SourceLocation *Locs = E->getStoredSelLocs(); + for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i) + Writer.AddSourceLocation(Locs[i], Record); + Code = serialization::EXPR_OBJC_MESSAGE_EXPR; } |