summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-03 06:36:51 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-03 06:36:51 +0000
commita6011e25a1c77de6eba3974737a5c21c319602c6 (patch)
treec715bcf5e42c591688aae94967cbd35b5898d130 /clang/lib
parent59ad1e3f574a33f2a2d3a1d80a1a22b657deba09 (diff)
downloadbcm5719-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.txt1
-rw-r--r--clang/lib/AST/Expr.cpp105
-rw-r--r--clang/lib/AST/SelectorLocationsKind.cpp102
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/lib/Sema/TreeTransform.h16
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp10
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp8
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;
}
OpenPOWER on IntegriCloud