forked from OSchip/llvm-project
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
This commit is contained in:
parent
59ad1e3f57
commit
a6011e25a1
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/SelectorLocationsKind.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -471,6 +472,10 @@ class ObjCMessageExpr : public Expr {
|
|||
/// \brief Whether this message send is a "delegate init call",
|
||||
/// i.e. a call of an init method on self from within an init method.
|
||||
unsigned IsDelegateInitCall : 1;
|
||||
|
||||
/// \brief Whether the locations of the selector identifiers are in a
|
||||
/// "standard" position, a enum SelectorLocationsKind.
|
||||
unsigned SelLocsKind : 2;
|
||||
|
||||
/// \brief When the message expression is a send to 'super', this is
|
||||
/// the location of the 'super' keyword.
|
||||
|
@ -481,9 +486,6 @@ class ObjCMessageExpr : public Expr {
|
|||
/// referring to the method that we type-checked against.
|
||||
uintptr_t SelectorOrMethod;
|
||||
|
||||
/// \brief Location of the selector.
|
||||
SourceLocation SelectorLoc;
|
||||
|
||||
/// \brief The source locations of the open and close square
|
||||
/// brackets ('[' and ']', respectively).
|
||||
SourceLocation LBracLoc, RBracLoc;
|
||||
|
@ -500,7 +502,8 @@ class ObjCMessageExpr : public Expr {
|
|||
bool IsInstanceSuper,
|
||||
QualType SuperType,
|
||||
Selector Sel,
|
||||
SourceLocation SelLoc,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
SelectorLocationsKind SelLocsK,
|
||||
ObjCMethodDecl *Method,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation RBracLoc);
|
||||
|
@ -508,7 +511,8 @@ class ObjCMessageExpr : public Expr {
|
|||
SourceLocation LBracLoc,
|
||||
TypeSourceInfo *Receiver,
|
||||
Selector Sel,
|
||||
SourceLocation SelLoc,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
SelectorLocationsKind SelLocsK,
|
||||
ObjCMethodDecl *Method,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation RBracLoc);
|
||||
|
@ -516,11 +520,16 @@ class ObjCMessageExpr : public Expr {
|
|||
SourceLocation LBracLoc,
|
||||
Expr *Receiver,
|
||||
Selector Sel,
|
||||
SourceLocation SelLoc,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
SelectorLocationsKind SelLocsK,
|
||||
ObjCMethodDecl *Method,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation RBracLoc);
|
||||
|
||||
void initArgsAndSelLocs(ArrayRef<Expr *> Args,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
SelectorLocationsKind SelLocsK);
|
||||
|
||||
/// \brief Retrieve the pointer value of the message receiver.
|
||||
void *getReceiverPointer() const {
|
||||
return *const_cast<void **>(
|
||||
|
@ -532,6 +541,40 @@ class ObjCMessageExpr : public Expr {
|
|||
*reinterpret_cast<void **>(this + 1) = Value;
|
||||
}
|
||||
|
||||
SelectorLocationsKind getSelLocsKind() const {
|
||||
return (SelectorLocationsKind)SelLocsKind;
|
||||
}
|
||||
bool hasStandardSelLocs() const {
|
||||
return getSelLocsKind() != SelLoc_NonStandard;
|
||||
}
|
||||
|
||||
/// \brief Get a pointer to the stored selector identifiers locations array.
|
||||
/// No locations will be stored if HasStandardSelLocs is true.
|
||||
SourceLocation *getStoredSelLocs() {
|
||||
return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
|
||||
}
|
||||
const SourceLocation *getStoredSelLocs() const {
|
||||
return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
|
||||
}
|
||||
|
||||
/// \brief Get the number of stored selector identifiers locations.
|
||||
/// No locations will be stored if HasStandardSelLocs is true.
|
||||
unsigned getNumStoredSelLocs() const {
|
||||
if (hasStandardSelLocs())
|
||||
return 0;
|
||||
return getNumSelectorLocs();
|
||||
}
|
||||
|
||||
static ObjCMessageExpr *alloc(ASTContext &C,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation RBraceLoc,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
Selector Sel,
|
||||
SelectorLocationsKind &SelLocsK);
|
||||
static ObjCMessageExpr *alloc(ASTContext &C,
|
||||
unsigned NumArgs,
|
||||
unsigned NumStoredSelLocs);
|
||||
|
||||
public:
|
||||
/// \brief The kind of receiver this message is sending to.
|
||||
enum ReceiverKind {
|
||||
|
@ -661,7 +704,9 @@ public:
|
|||
///
|
||||
/// \param NumArgs The number of message arguments, not including
|
||||
/// the receiver.
|
||||
static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
|
||||
static ObjCMessageExpr *CreateEmpty(ASTContext &Context,
|
||||
unsigned NumArgs,
|
||||
unsigned NumStoredSelLocs);
|
||||
|
||||
/// \brief Determine the kind of receiver that this message is being
|
||||
/// sent to.
|
||||
|
@ -831,7 +876,27 @@ public:
|
|||
|
||||
SourceLocation getLeftLoc() const { return LBracLoc; }
|
||||
SourceLocation getRightLoc() const { return RBracLoc; }
|
||||
SourceLocation getSelectorLoc() const { return SelectorLoc; }
|
||||
|
||||
SourceLocation getSelectorStartLoc() const { return getSelectorLoc(0); }
|
||||
SourceLocation getSelectorLoc(unsigned Index) const {
|
||||
assert(Index < getNumSelectorLocs() && "Index out of range!");
|
||||
if (hasStandardSelLocs())
|
||||
return getStandardSelectorLoc(Index, getSelector(),
|
||||
getSelLocsKind() == SelLoc_StandardWithSpace,
|
||||
llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
|
||||
getNumArgs()),
|
||||
RBracLoc);
|
||||
return getStoredSelLocs()[Index];
|
||||
}
|
||||
|
||||
void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
|
||||
|
||||
unsigned getNumSelectorLocs() const {
|
||||
Selector Sel = getSelector();
|
||||
if (Sel.isUnarySelector())
|
||||
return 1;
|
||||
return Sel.getNumArgs();
|
||||
}
|
||||
|
||||
void setSourceRange(SourceRange R) {
|
||||
LBracLoc = R.getBegin();
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//===--- SelectorLocationsKind.h - 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
|
||||
#define LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
|
||||
namespace clang {
|
||||
class Selector;
|
||||
class SourceLocation;
|
||||
class Expr;
|
||||
|
||||
/// \brief Whether all locations of the selector identifiers are in a
|
||||
/// "standard" position.
|
||||
enum SelectorLocationsKind {
|
||||
/// \brief Non-standard.
|
||||
SelLoc_NonStandard = 0,
|
||||
|
||||
/// \brief For nullary selectors, immediately before the end:
|
||||
/// "[foo release]" / "-(void)release;"
|
||||
/// Or immediately before the arguments:
|
||||
/// "[foo first:1 second:2]" / "-(id)first:(int)x second:(int)y;
|
||||
SelLoc_StandardNoSpace = 1,
|
||||
|
||||
/// \brief For nullary selectors, immediately before the end:
|
||||
/// "[foo release]" / "-(void)release;"
|
||||
/// Or with a space between the arguments:
|
||||
/// "[foo first: 1 second: 2]" / "-(id)first: (int)x second: (int)y;
|
||||
SelLoc_StandardWithSpace = 2
|
||||
};
|
||||
|
||||
/// \brief Returns true if all \arg SelLocs are in a "standard" location.
|
||||
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
|
||||
ArrayRef<SourceLocation> SelLocs,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
/// \brief Get the "standard" location of a selector identifier, e.g:
|
||||
/// For nullary selectors, immediately before ']': "[foo release]"
|
||||
///
|
||||
/// \param WithArgSpace if true the standard location is with a space apart
|
||||
/// before arguments: "[foo first: 1 second: 2]"
|
||||
/// If false: "[foo first:1 second:2]"
|
||||
SourceLocation getStandardSelectorLoc(unsigned Index,
|
||||
Selector Sel,
|
||||
bool WithArgSpace,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
|
@ -35,6 +35,7 @@ add_clang_library(clangAST
|
|||
ParentMap.cpp
|
||||
RecordLayout.cpp
|
||||
RecordLayoutBuilder.cpp
|
||||
SelectorLocationsKind.cpp
|
||||
Stmt.cpp
|
||||
StmtDumper.cpp
|
||||
StmtIterator.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:
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue