зеркало из https://github.com/microsoft/clang-1.git
This is a large/messy diff that unifies the ObjC AST's with DeclContext.
- ObjCContainerDecl's (ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl), ObjCCategoryImpl, & ObjCImplementation are all DeclContexts. - ObjCMethodDecl is now a ScopedDecl (so it can play nicely with DeclContext). - ObjCContainerDecl now does iteration/lookup using DeclContext infrastructure (no more linear search:-) - Removed ASTContext argument to DeclContext::lookup(). It wasn't being used and complicated it's use from an ObjC AST perspective. - Added Sema::ProcessPropertyDecl() and removed Sema::diagnosePropertySetterGetterMismatch(). - Simplified Sema::ActOnAtEnd() considerably. Still more work to do. - Fixed an incorrect casting assumption in Sema::getCurFunctionOrMethodDecl(), now that ObjCMethodDecl is a ScopedDecl. - Removed addPropertyMethods from ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl. This passes all the tests on my machine. Since many of the changes are central to the way ObjC finds it's methods, I expect some fallout (and there are still a handful of FIXME's). Nevertheless, this should be a step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61929 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7e5d6ed47d
Коммит
0701bbb228
|
@ -881,9 +881,8 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
|
|||
NameStr += OMD->getClassInterface()->getNameAsString();
|
||||
NameStr += "_";
|
||||
|
||||
NamedDecl *MethodContext = OMD->getMethodContext();
|
||||
if (ObjCCategoryImplDecl *CID =
|
||||
dyn_cast<ObjCCategoryImplDecl>(MethodContext)) {
|
||||
dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
|
||||
NameStr += CID->getNameAsString();
|
||||
NameStr += "_";
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@ class CXXRecordDecl;
|
|||
class EnumDecl;
|
||||
class ObjCMethodDecl;
|
||||
class ObjCInterfaceDecl;
|
||||
class ObjCCategoryDecl;
|
||||
class ObjCProtocolDecl;
|
||||
class ObjCImplementationDecl;
|
||||
class ObjCCategoryImplDecl;
|
||||
class LinkageSpecDecl;
|
||||
class BlockDecl;
|
||||
class DeclarationName;
|
||||
|
@ -49,14 +53,13 @@ public:
|
|||
// Decl
|
||||
TranslationUnit, // [DeclContext]
|
||||
// NamedDecl
|
||||
// ObjCContainerDecl
|
||||
// ObjCContainerDecl // [DeclContext]
|
||||
ObjCCategory,
|
||||
ObjCProtocol,
|
||||
ObjCInterface, // [DeclContext]
|
||||
ObjCInterface,
|
||||
OverloadedFunction,
|
||||
ObjCCategoryImpl,
|
||||
ObjCImplementation,
|
||||
ObjCMethod, // [DeclContext]
|
||||
ObjCCategoryImpl, // [DeclContext]
|
||||
ObjCImplementation, // [DeclContext]
|
||||
ObjCProperty,
|
||||
// ScopedDecl
|
||||
Field,
|
||||
|
@ -84,6 +87,7 @@ public:
|
|||
OriginalParmVar,
|
||||
NonTypeTemplateParm,
|
||||
LinkageSpec, // [DeclContext]
|
||||
ObjCMethod, // [DeclContext]
|
||||
ObjCCompatibleAlias,
|
||||
ObjCClass,
|
||||
ObjCForwardProtocol,
|
||||
|
@ -95,7 +99,7 @@ public:
|
|||
// of the class, to allow efficient classof.
|
||||
NamedFirst = OverloadedFunction , NamedLast = NonTypeTemplateParm,
|
||||
FieldFirst = Field , FieldLast = ObjCAtDefsField,
|
||||
ScopedFirst = Field , ScopedLast = LinkageSpec,
|
||||
ScopedFirst = Field , ScopedLast = ObjCMethod,
|
||||
TypeFirst = Typedef , TypeLast = TemplateTypeParm,
|
||||
TagFirst = Enum , TagLast = CXXRecord,
|
||||
RecordFirst = Record , RecordLast = CXXRecord,
|
||||
|
@ -329,6 +333,14 @@ class DeclContext {
|
|||
return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCInterface:
|
||||
return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCCategory:
|
||||
return static_cast<ObjCCategoryDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCProtocol:
|
||||
return static_cast<ObjCProtocolDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCImplementation:
|
||||
return static_cast<ObjCImplementationDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCCategoryImpl:
|
||||
return static_cast<ObjCCategoryImplDecl*>(const_cast<From*>(D));
|
||||
case Decl::LinkageSpec:
|
||||
return static_cast<LinkageSpecDecl*>(const_cast<From*>(D));
|
||||
case Decl::Block:
|
||||
|
@ -434,7 +446,7 @@ public:
|
|||
/// a different set of declarations. This routine returns the
|
||||
/// "primary" DeclContext structure, which will contain the
|
||||
/// information needed to perform name lookup into this context.
|
||||
DeclContext *getPrimaryContext(ASTContext &Context);
|
||||
DeclContext *getPrimaryContext();
|
||||
|
||||
/// getLookupContext - Retrieve the innermost non-transparent
|
||||
/// context of this context, which corresponds to the innermost
|
||||
|
@ -481,7 +493,7 @@ public:
|
|||
/// declaration into data structure for name lookup.
|
||||
void addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup = true);
|
||||
|
||||
void buildLookup(ASTContext &Context, DeclContext *DCtx);
|
||||
void buildLookup(DeclContext *DCtx);
|
||||
|
||||
/// lookup_iterator - An iterator that provides access to the results
|
||||
/// of looking up a name within this context.
|
||||
|
@ -503,8 +515,8 @@ public:
|
|||
/// declaration in the "tag" identifier namespace (e.g., values
|
||||
/// before types). Note that this routine will not look into parent
|
||||
/// contexts.
|
||||
lookup_result lookup(ASTContext &Context, DeclarationName Name);
|
||||
lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const;
|
||||
lookup_result lookup(DeclarationName Name);
|
||||
lookup_const_result lookup(DeclarationName Name) const;
|
||||
|
||||
/// insert - Insert the declaration D into this context. Up to two
|
||||
/// declarations with the same name can be inserted into a single
|
||||
|
@ -527,6 +539,10 @@ public:
|
|||
case Decl::CXXRecord:
|
||||
case Decl::ObjCMethod:
|
||||
case Decl::ObjCInterface:
|
||||
case Decl::ObjCCategory:
|
||||
case Decl::ObjCProtocol:
|
||||
case Decl::ObjCImplementation:
|
||||
case Decl::ObjCCategoryImpl:
|
||||
case Decl::LinkageSpec:
|
||||
case Decl::Block:
|
||||
return true;
|
||||
|
@ -546,6 +562,10 @@ public:
|
|||
static bool classof(const EnumDecl *D) { return true; }
|
||||
static bool classof(const ObjCMethodDecl *D) { return true; }
|
||||
static bool classof(const ObjCInterfaceDecl *D) { return true; }
|
||||
static bool classof(const ObjCCategoryDecl *D) { return true; }
|
||||
static bool classof(const ObjCProtocolDecl *D) { return true; }
|
||||
static bool classof(const ObjCImplementationDecl *D) { return true; }
|
||||
static bool classof(const ObjCCategoryImplDecl *D) { return true; }
|
||||
static bool classof(const LinkageSpecDecl *D) { return true; }
|
||||
static bool classof(const BlockDecl *D) { return true; }
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
/// A selector represents a unique name for a method. The selector names for
|
||||
/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
|
||||
///
|
||||
class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
class ObjCMethodDecl : public ScopedDecl, public DeclContext {
|
||||
public:
|
||||
enum ImplementationControl { None, Required, Optional };
|
||||
private:
|
||||
|
@ -115,7 +115,7 @@ private:
|
|||
unsigned objcDeclQualifier : 6;
|
||||
|
||||
// Context this method is declared in.
|
||||
NamedDecl *MethodContext;
|
||||
DeclContext *MethodContext;
|
||||
|
||||
// Type of this method.
|
||||
QualType MethodDeclType;
|
||||
|
@ -140,17 +140,17 @@ private:
|
|||
|
||||
ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
|
||||
Selector SelInfo, QualType T,
|
||||
Decl *contextDecl,
|
||||
DeclContext *contextDecl,
|
||||
bool isInstance = true,
|
||||
bool isVariadic = false,
|
||||
bool isSynthesized = false,
|
||||
ImplementationControl impControl = None)
|
||||
: NamedDecl(ObjCMethod, beginLoc, SelInfo),
|
||||
: ScopedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo, 0),
|
||||
DeclContext(ObjCMethod),
|
||||
IsInstance(isInstance), IsVariadic(isVariadic),
|
||||
IsSynthesized(isSynthesized),
|
||||
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
|
||||
MethodContext(static_cast<NamedDecl*>(contextDecl)),
|
||||
MethodContext(contextDecl),
|
||||
MethodDeclType(T),
|
||||
ParamInfo(0), NumMethodParams(0),
|
||||
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
|
||||
|
@ -165,7 +165,7 @@ public:
|
|||
static ObjCMethodDecl *Create(ASTContext &C,
|
||||
SourceLocation beginLoc,
|
||||
SourceLocation endLoc, Selector SelInfo,
|
||||
QualType T, Decl *contextDecl,
|
||||
QualType T, DeclContext *contextDecl,
|
||||
bool isInstance = true,
|
||||
bool isVariadic = false,
|
||||
bool isSynthesized = false,
|
||||
|
@ -183,7 +183,7 @@ public:
|
|||
return SourceRange(getLocation(), EndLoc);
|
||||
}
|
||||
|
||||
NamedDecl *getMethodContext() const { return MethodContext; }
|
||||
DeclContext *getMethodContext() const { return MethodContext; }
|
||||
|
||||
ObjCInterfaceDecl *getClassInterface();
|
||||
const ObjCInterfaceDecl *getClassInterface() const {
|
||||
|
@ -252,68 +252,177 @@ public:
|
|||
|
||||
/// ObjCContainerDecl - Represents a container for method declarations.
|
||||
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and
|
||||
/// ObjCProtocolDecl. FIXME: Use for ObjC implementation decls.
|
||||
/// STILL UNDER CONSTRUCTION...
|
||||
/// ObjCProtocolDecl.
|
||||
/// FIXME: Use for ObjC implementation decls.
|
||||
/// FIXME: Consider properties.
|
||||
/// FIXME: It would be nice to reduce amount of "boilerplate" iterator code
|
||||
/// below. For now, the iterators are modeled after RecordDecl::field_iterator().
|
||||
/// If DeclContext ends up providing some support for creating more strongly
|
||||
/// typed iterators, the code below should be reduced considerably.
|
||||
///
|
||||
class ObjCContainerDecl : public NamedDecl {
|
||||
/// instance methods
|
||||
ObjCMethodDecl **InstanceMethods; // Null if not defined
|
||||
unsigned NumInstanceMethods; // 0 if none.
|
||||
|
||||
/// class methods
|
||||
ObjCMethodDecl **ClassMethods; // Null if not defined
|
||||
unsigned NumClassMethods; // 0 if none
|
||||
|
||||
class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||
SourceLocation AtEndLoc; // marks the end of the method container.
|
||||
public:
|
||||
|
||||
ObjCContainerDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
|
||||
: NamedDecl(DK, L, Id),
|
||||
InstanceMethods(0), NumInstanceMethods(0),
|
||||
ClassMethods(0), NumClassMethods(0) {}
|
||||
: NamedDecl(DK, L, Id), DeclContext(DK) {}
|
||||
|
||||
virtual ~ObjCContainerDecl();
|
||||
|
||||
typedef ObjCMethodDecl * const * instmeth_iterator;
|
||||
instmeth_iterator instmeth_begin() const { return InstanceMethods; }
|
||||
instmeth_iterator instmeth_end() const {
|
||||
return InstanceMethods+NumInstanceMethods;
|
||||
// Iterator access to instance/class methods.
|
||||
class method_iterator {
|
||||
protected:
|
||||
/// Current - Current position within the sequence of declarations
|
||||
/// in this record.
|
||||
DeclContext::decl_iterator Current;
|
||||
|
||||
/// End - Last position in the sequence of declarations in this
|
||||
/// record.
|
||||
DeclContext::decl_iterator End;
|
||||
|
||||
/// IsInstance - If true, we are iterating through instance methods.
|
||||
/// If false, we are iteratring through class methods.
|
||||
bool IsInstance;
|
||||
|
||||
/// SkipToNextMethod - Advances the current position up to the next
|
||||
/// ObjCMethodDecl.
|
||||
void SkipToNextMethod() {
|
||||
while (Current != End) {
|
||||
ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(*Current);
|
||||
if (M &&
|
||||
(IsInstance && M->isInstance() || !IsInstance && !M->isInstance()))
|
||||
return;
|
||||
++Current;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
typedef ObjCMethodDecl const * value_type;
|
||||
typedef ObjCMethodDecl const * reference;
|
||||
typedef ObjCMethodDecl const * pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
method_iterator() : Current(), End(), IsInstance(true) { }
|
||||
|
||||
method_iterator(DeclContext::decl_iterator C,
|
||||
DeclContext::decl_iterator E, bool I)
|
||||
: Current(C), End(E), IsInstance(I) {
|
||||
SkipToNextMethod();
|
||||
}
|
||||
|
||||
reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
|
||||
|
||||
pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
|
||||
|
||||
method_iterator& operator++() {
|
||||
++Current;
|
||||
SkipToNextMethod();
|
||||
return *this;
|
||||
}
|
||||
|
||||
method_iterator operator++(int) {
|
||||
method_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator==(const method_iterator& x, const method_iterator& y) {
|
||||
return x.Current == y.Current;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(const method_iterator& x, const method_iterator& y) {
|
||||
return x.Current != y.Current;
|
||||
}
|
||||
};
|
||||
|
||||
class instmeth_iterator : public method_iterator {
|
||||
public:
|
||||
typedef ObjCMethodDecl* value_type;
|
||||
typedef ObjCMethodDecl* reference;
|
||||
typedef ObjCMethodDecl* pointer;
|
||||
|
||||
instmeth_iterator() : method_iterator() { }
|
||||
|
||||
instmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
|
||||
: method_iterator(C, E, true) { }
|
||||
|
||||
reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
|
||||
|
||||
pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
|
||||
|
||||
instmeth_iterator& operator++() {
|
||||
++Current;
|
||||
SkipToNextMethod();
|
||||
return *this;
|
||||
}
|
||||
|
||||
instmeth_iterator operator++(int) {
|
||||
instmeth_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
instmeth_iterator instmeth_begin() const {
|
||||
return instmeth_iterator(decls_begin(), decls_end());
|
||||
}
|
||||
|
||||
typedef ObjCMethodDecl * const * classmeth_iterator;
|
||||
classmeth_iterator classmeth_begin() const { return ClassMethods; }
|
||||
classmeth_iterator classmeth_end() const {
|
||||
return ClassMethods+NumClassMethods;
|
||||
instmeth_iterator instmeth_end() const {
|
||||
return instmeth_iterator(decls_end(), decls_end());
|
||||
}
|
||||
|
||||
// Get the local instance method declared in this interface.
|
||||
ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
|
||||
for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
|
||||
I != E; ++I) {
|
||||
if ((*I)->getSelector() == Sel)
|
||||
return *I;
|
||||
class classmeth_iterator : public method_iterator {
|
||||
public:
|
||||
typedef ObjCMethodDecl* value_type;
|
||||
typedef ObjCMethodDecl* reference;
|
||||
typedef ObjCMethodDecl* pointer;
|
||||
|
||||
classmeth_iterator() : method_iterator() { }
|
||||
|
||||
classmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
|
||||
: method_iterator(C, E, false) { }
|
||||
|
||||
reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
|
||||
|
||||
pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
|
||||
|
||||
classmeth_iterator& operator++() {
|
||||
++Current;
|
||||
SkipToNextMethod();
|
||||
return *this;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Get the local class method declared in this interface.
|
||||
ObjCMethodDecl *getClassMethod(Selector Sel) const {
|
||||
for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
|
||||
I != E; ++I) {
|
||||
if ((*I)->getSelector() == Sel)
|
||||
return *I;
|
||||
|
||||
classmeth_iterator operator++(int) {
|
||||
classmeth_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
classmeth_iterator classmeth_begin() const {
|
||||
return classmeth_iterator(decls_begin(), decls_end());
|
||||
}
|
||||
classmeth_iterator classmeth_end() const {
|
||||
return classmeth_iterator(decls_end(), decls_end());
|
||||
}
|
||||
|
||||
// Get the local instance/class method declared in this interface.
|
||||
ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
|
||||
ObjCMethodDecl *getClassMethod(Selector Sel) const;
|
||||
|
||||
void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
|
||||
ObjCMethodDecl **clsMethods, unsigned numClsMembers,
|
||||
SourceLocation AtEndLoc);
|
||||
|
||||
unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
|
||||
unsigned getNumClassMethods() const { return NumClassMethods; }
|
||||
// Get the number of instance/class methods.
|
||||
unsigned getNumInstanceMethods() const;
|
||||
unsigned getNumClassMethods() const;
|
||||
|
||||
// Marks the end of the container.
|
||||
SourceLocation getAtEndLoc() const { return AtEndLoc; }
|
||||
void setAtEndLoc(SourceLocation L) { AtEndLoc = L; }
|
||||
|
||||
// This method synthesizes the getter/setter method for the property.
|
||||
// FIXME: Shouldn't this be part of Sema?.
|
||||
void getPropertyMethods(ASTContext &Context, ObjCPropertyDecl* Property,
|
||||
ObjCMethodDecl *& Getter, ObjCMethodDecl *&Setter);
|
||||
};
|
||||
|
||||
/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
|
||||
|
@ -337,7 +446,7 @@ public:
|
|||
/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
|
||||
/// typically inherit from NSObject (an exception is NSProxy).
|
||||
///
|
||||
class ObjCInterfaceDecl : public ObjCContainerDecl, public DeclContext {
|
||||
class ObjCInterfaceDecl : public ObjCContainerDecl {
|
||||
/// TypeForDecl - This indicates the Type object that represents this
|
||||
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
|
||||
Type *TypeForDecl;
|
||||
|
@ -369,7 +478,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl, public DeclContext {
|
|||
|
||||
ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
|
||||
SourceLocation CLoc, bool FD, bool isInternal)
|
||||
: ObjCContainerDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
|
||||
: ObjCContainerDecl(ObjCInterface, atLoc, Id),
|
||||
TypeForDecl(0), SuperClass(0),
|
||||
Ivars(0), NumIvars(0),
|
||||
CategoryList(0), PropertyDecl(0), NumPropertyDecl(0),
|
||||
|
@ -424,11 +533,6 @@ public:
|
|||
|
||||
void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
|
||||
|
||||
void addPropertyMethods(ASTContext &Context,
|
||||
ObjCPropertyDecl* Property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
|
||||
|
||||
typedef ObjCPropertyDecl * const * classprop_iterator;
|
||||
classprop_iterator classprop_begin() const { return PropertyDecl; }
|
||||
classprop_iterator classprop_end() const {
|
||||
|
@ -644,11 +748,6 @@ public:
|
|||
|
||||
void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
|
||||
|
||||
void addPropertyMethods(ASTContext &Context,
|
||||
ObjCPropertyDecl* Property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
|
||||
|
||||
typedef ObjCPropertyDecl * const * classprop_iterator;
|
||||
classprop_iterator classprop_begin() const { return PropertyDecl; }
|
||||
classprop_iterator classprop_end() const {
|
||||
|
@ -839,11 +938,6 @@ public:
|
|||
|
||||
void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
|
||||
|
||||
void addPropertyMethods(ASTContext &Context,
|
||||
ObjCPropertyDecl* Property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
|
||||
|
||||
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
|
||||
|
||||
typedef ObjCPropertyDecl * const * classprop_iterator;
|
||||
|
@ -878,7 +972,7 @@ public:
|
|||
/// @dynamic p1,d1;
|
||||
/// @end
|
||||
///
|
||||
class ObjCCategoryImplDecl : public NamedDecl {
|
||||
class ObjCCategoryImplDecl : public NamedDecl, public DeclContext {
|
||||
/// Class interface for this category implementation
|
||||
ObjCInterfaceDecl *ClassInterface;
|
||||
|
||||
|
@ -895,7 +989,8 @@ class ObjCCategoryImplDecl : public NamedDecl {
|
|||
|
||||
ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
|
||||
ObjCInterfaceDecl *classInterface)
|
||||
: NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
|
||||
: NamedDecl(ObjCCategoryImpl, L, Id), DeclContext(ObjCCategoryImpl),
|
||||
ClassInterface(classInterface) {}
|
||||
public:
|
||||
static ObjCCategoryImplDecl *Create(ASTContext &C,
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
|
@ -974,7 +1069,7 @@ public:
|
|||
/// the legacy semantics and allow developers to move private ivar declarations
|
||||
/// from the class interface to the class implementation (but I digress:-)
|
||||
///
|
||||
class ObjCImplementationDecl : public NamedDecl {
|
||||
class ObjCImplementationDecl : public NamedDecl, public DeclContext {
|
||||
/// Class interface for this implementation
|
||||
ObjCInterfaceDecl *ClassInterface;
|
||||
|
||||
|
@ -999,7 +1094,7 @@ class ObjCImplementationDecl : public NamedDecl {
|
|||
ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
|
||||
ObjCInterfaceDecl *classInterface,
|
||||
ObjCInterfaceDecl *superDecl)
|
||||
: NamedDecl(ObjCImplementation, L, Id),
|
||||
: NamedDecl(ObjCImplementation, L, Id), DeclContext(ObjCImplementation),
|
||||
ClassInterface(classInterface), SuperClass(superDecl),
|
||||
Ivars(0), NumIvars(0) {}
|
||||
public:
|
||||
|
|
|
@ -419,7 +419,7 @@ bool DeclContext::isTransparentContext() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
|
||||
DeclContext *DeclContext::getPrimaryContext() {
|
||||
switch (DeclKind) {
|
||||
case Decl::TranslationUnit:
|
||||
case Decl::LinkageSpec:
|
||||
|
@ -468,9 +468,15 @@ DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
|
|||
return this;
|
||||
|
||||
case Decl::ObjCInterface:
|
||||
case Decl::ObjCProtocol:
|
||||
case Decl::ObjCCategory:
|
||||
// FIXME: Can Objective-C interfaces be forward-declared?
|
||||
return this;
|
||||
|
||||
case Decl::ObjCImplementation:
|
||||
case Decl::ObjCCategoryImpl:
|
||||
return this;
|
||||
|
||||
default:
|
||||
assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
|
||||
"Unknown DeclContext kind");
|
||||
|
@ -486,6 +492,10 @@ DeclContext *DeclContext::getNextContext() {
|
|||
case Decl::CXXRecord:
|
||||
case Decl::ObjCMethod:
|
||||
case Decl::ObjCInterface:
|
||||
case Decl::ObjCCategory:
|
||||
case Decl::ObjCProtocol:
|
||||
case Decl::ObjCImplementation:
|
||||
case Decl::ObjCCategoryImpl:
|
||||
case Decl::LinkageSpec:
|
||||
case Decl::Block:
|
||||
// There is only one DeclContext for these entities.
|
||||
|
@ -511,7 +521,7 @@ void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup)
|
|||
/// buildLookup - Build the lookup data structure with all of the
|
||||
/// declarations in DCtx (and any other contexts linked to it or
|
||||
/// transparent contexts nested within it).
|
||||
void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
|
||||
void DeclContext::buildLookup(DeclContext *DCtx) {
|
||||
for (; DCtx; DCtx = DCtx->getNextContext()) {
|
||||
for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end();
|
||||
D != DEnd; ++D) {
|
||||
|
@ -522,22 +532,22 @@ void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
|
|||
// add its members (recursively).
|
||||
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
|
||||
if (InnerCtx->isTransparentContext())
|
||||
buildLookup(Context, InnerCtx->getPrimaryContext(Context));
|
||||
buildLookup(InnerCtx->getPrimaryContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeclContext::lookup_result
|
||||
DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
|
||||
DeclContext *PrimaryContext = getPrimaryContext(Context);
|
||||
DeclContext::lookup(DeclarationName Name) {
|
||||
DeclContext *PrimaryContext = getPrimaryContext();
|
||||
if (PrimaryContext != this)
|
||||
return PrimaryContext->lookup(Context, Name);
|
||||
return PrimaryContext->lookup(Name);
|
||||
|
||||
/// If there is no lookup data structure, build one now by walking
|
||||
/// all of the linked DeclContexts (in declaration order!) and
|
||||
/// inserting their values.
|
||||
if (LookupPtr.getPointer() == 0)
|
||||
buildLookup(Context, this);
|
||||
buildLookup(this);
|
||||
|
||||
if (isLookupMap()) {
|
||||
StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
|
||||
|
@ -563,8 +573,8 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
|
|||
}
|
||||
|
||||
DeclContext::lookup_const_result
|
||||
DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
|
||||
return const_cast<DeclContext*>(this)->lookup(Context, Name);
|
||||
DeclContext::lookup(DeclarationName Name) const {
|
||||
return const_cast<DeclContext*>(this)->lookup(Name);
|
||||
}
|
||||
|
||||
const DeclContext *DeclContext::getLookupContext() const {
|
||||
|
@ -575,7 +585,7 @@ const DeclContext *DeclContext::getLookupContext() const {
|
|||
}
|
||||
|
||||
void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
|
||||
DeclContext *PrimaryContext = getPrimaryContext(Context);
|
||||
DeclContext *PrimaryContext = getPrimaryContext();
|
||||
if (PrimaryContext != this) {
|
||||
PrimaryContext->insert(Context, D);
|
||||
return;
|
||||
|
|
|
@ -98,7 +98,7 @@ bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
|
|||
Context.getCanonicalType(ClassType));
|
||||
unsigned TypeQuals;
|
||||
DeclContext::lookup_const_iterator Con, ConEnd;
|
||||
for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
|
||||
for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
|
||||
Con != ConEnd; ++Con) {
|
||||
if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
|
||||
(TypeQuals & QualType::Const) != 0)
|
||||
|
@ -114,7 +114,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
|
|||
DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
|
||||
|
||||
DeclContext::lookup_const_iterator Op, OpEnd;
|
||||
for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
|
||||
for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
|
||||
Op != OpEnd; ++Op) {
|
||||
// C++ [class.copy]p9:
|
||||
// A user-declared copy assignment operator is a non-static non-template
|
||||
|
|
|
@ -24,7 +24,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
|
|||
SourceLocation beginLoc,
|
||||
SourceLocation endLoc,
|
||||
Selector SelInfo, QualType T,
|
||||
Decl *contextDecl,
|
||||
DeclContext *contextDecl,
|
||||
bool isInstance,
|
||||
bool isVariadic,
|
||||
bool isSynthesized,
|
||||
|
@ -61,8 +61,6 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
|
|||
}
|
||||
|
||||
ObjCContainerDecl::~ObjCContainerDecl() {
|
||||
delete [] InstanceMethods;
|
||||
delete [] ClassMethods;
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl::~ObjCInterfaceDecl() {
|
||||
|
@ -362,7 +360,7 @@ FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
|
|||
assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
|
||||
DeclarationName Member = ivar->getDeclName();
|
||||
DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
|
||||
->lookup(Context, Member);
|
||||
->lookup(Member);
|
||||
assert((Lookup.first != Lookup.second) && "field decl not found");
|
||||
FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
|
||||
assert(MemberDecl && "field decl not found");
|
||||
|
@ -382,27 +380,6 @@ void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
|
|||
}
|
||||
}
|
||||
|
||||
/// addMethods - Insert instance and methods declarations into
|
||||
/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
|
||||
///
|
||||
void ObjCContainerDecl::addMethods(ObjCMethodDecl **insMethods,
|
||||
unsigned numInsMembers,
|
||||
ObjCMethodDecl **clsMethods,
|
||||
unsigned numClsMembers,
|
||||
SourceLocation endLoc) {
|
||||
NumInstanceMethods = numInsMembers;
|
||||
if (numInsMembers) {
|
||||
InstanceMethods = new ObjCMethodDecl*[numInsMembers];
|
||||
memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
|
||||
}
|
||||
NumClassMethods = numClsMembers;
|
||||
if (numClsMembers) {
|
||||
ClassMethods = new ObjCMethodDecl*[numClsMembers];
|
||||
memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
|
||||
}
|
||||
AtEndLoc = endLoc;
|
||||
}
|
||||
|
||||
/// addProperties - Insert property declaration AST nodes into
|
||||
/// ObjCInterfaceDecl's PropertyDecl field.
|
||||
///
|
||||
|
@ -440,18 +417,45 @@ void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
addPropertyMethods(Decl *D,
|
||||
ASTContext &Context,
|
||||
ObjCPropertyDecl *property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
|
||||
ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
|
||||
|
||||
GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
|
||||
if (!property->isReadOnly())
|
||||
SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
|
||||
|
||||
// Get the local instance method declared in this interface.
|
||||
// FIXME: handle overloading, instance & class methods can have the same name.
|
||||
ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
|
||||
lookup_const_result MethodResult = lookup(Sel);
|
||||
if (MethodResult.first)
|
||||
return const_cast<ObjCMethodDecl*>(
|
||||
dyn_cast<ObjCMethodDecl>(*MethodResult.first));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the local class method declared in this interface.
|
||||
ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
|
||||
lookup_const_result MethodResult = lookup(Sel);
|
||||
if (MethodResult.first)
|
||||
return const_cast<ObjCMethodDecl*>(
|
||||
dyn_cast<ObjCMethodDecl>(*MethodResult.first));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned ObjCContainerDecl::getNumInstanceMethods() const {
|
||||
unsigned sum = 0;
|
||||
for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
|
||||
sum++;
|
||||
return sum;
|
||||
}
|
||||
unsigned ObjCContainerDecl::getNumClassMethods() const {
|
||||
unsigned sum = 0;
|
||||
for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
|
||||
sum++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// addPropertyMethods - Goes through list of properties declared in this class
|
||||
/// and builds setter/getter method declartions depending on the setter/getter
|
||||
/// attributes of the property.
|
||||
///
|
||||
void ObjCContainerDecl::getPropertyMethods(
|
||||
ASTContext &Context, ObjCPropertyDecl *property,
|
||||
ObjCMethodDecl *& GetterDecl, ObjCMethodDecl *&SetterDecl) {
|
||||
// FIXME: The synthesized property we set here is misleading. We
|
||||
// almost always synthesize these methods unless the user explicitly
|
||||
// provided prototypes (which is odd, but allowed). Sema should be
|
||||
|
@ -467,15 +471,12 @@ addPropertyMethods(Decl *D,
|
|||
ObjCMethodDecl::Create(Context, property->getLocation(),
|
||||
property->getLocation(),
|
||||
property->getGetterName(),
|
||||
property->getType(),
|
||||
D,
|
||||
property->getType(), this,
|
||||
true, false, true,
|
||||
(property->getPropertyImplementation() ==
|
||||
ObjCPropertyDecl::Optional) ?
|
||||
ObjCMethodDecl::Optional :
|
||||
ObjCMethodDecl::Required);
|
||||
insMethods.push_back(GetterDecl);
|
||||
InsMap[property->getGetterName()] = GetterDecl;
|
||||
}
|
||||
else
|
||||
// A user declared getter will be synthesize when @synthesize of
|
||||
|
@ -496,15 +497,12 @@ addPropertyMethods(Decl *D,
|
|||
ObjCMethodDecl::Create(Context, property->getLocation(),
|
||||
property->getLocation(),
|
||||
property->getSetterName(),
|
||||
Context.VoidTy,
|
||||
D,
|
||||
Context.VoidTy, this,
|
||||
true, false, true,
|
||||
(property->getPropertyImplementation() ==
|
||||
ObjCPropertyDecl::Optional) ?
|
||||
ObjCMethodDecl::Optional :
|
||||
ObjCMethodDecl::Required);
|
||||
insMethods.push_back(SetterDecl);
|
||||
InsMap[property->getSetterName()] = SetterDecl;
|
||||
// Invent the arguments for the setter. We don't bother making a
|
||||
// nice name for the argument.
|
||||
ParmVarDecl *Argument = ParmVarDecl::Create(Context,
|
||||
|
@ -523,30 +521,6 @@ addPropertyMethods(Decl *D,
|
|||
property->setSetterMethodDecl(SetterDecl);
|
||||
}
|
||||
|
||||
/// addPropertyMethods - Goes through list of properties declared in this class
|
||||
/// and builds setter/getter method declartions depending on the setter/getter
|
||||
/// attributes of the property.
|
||||
///
|
||||
void ObjCInterfaceDecl::addPropertyMethods(
|
||||
ASTContext &Context,
|
||||
ObjCPropertyDecl *property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
|
||||
::addPropertyMethods(this, Context, property, insMethods, InsMap);
|
||||
}
|
||||
|
||||
/// addPropertyMethods - Goes through list of properties declared in this class
|
||||
/// and builds setter/getter method declartions depending on the setter/getter
|
||||
/// attributes of the property.
|
||||
///
|
||||
void ObjCCategoryDecl::addPropertyMethods(
|
||||
ASTContext &Context,
|
||||
ObjCPropertyDecl *property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
|
||||
::addPropertyMethods(this, Context, property, insMethods, InsMap);
|
||||
}
|
||||
|
||||
/// mergeProperties - Adds properties to the end of list of current properties
|
||||
/// for this category.
|
||||
|
||||
|
@ -572,18 +546,6 @@ void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties,
|
|||
}
|
||||
}
|
||||
|
||||
/// addPropertyMethods - Goes through list of properties declared in this class
|
||||
/// and builds setter/getter method declartions depending on the setter/getter
|
||||
/// attributes of the property.
|
||||
///
|
||||
void ObjCProtocolDecl::addPropertyMethods(
|
||||
ASTContext &Context,
|
||||
ObjCPropertyDecl *property,
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
|
||||
::addPropertyMethods(this, Context, property, insMethods, InsMap);
|
||||
}
|
||||
|
||||
/// addProperties - Insert property declaration AST nodes into
|
||||
/// ObjCProtocolDecl's PropertyDecl field.
|
||||
///
|
||||
|
@ -850,9 +812,8 @@ unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
|
|||
// Get length of this name.
|
||||
unsigned length = 3; // _I_ or _C_
|
||||
length += getClassInterface()->getNameAsString().size()+1; // extra for _
|
||||
NamedDecl *MethodContext = getMethodContext();
|
||||
if (ObjCCategoryImplDecl *CID =
|
||||
dyn_cast<ObjCCategoryImplDecl>(MethodContext))
|
||||
dyn_cast<ObjCCategoryImplDecl>(getMethodContext()))
|
||||
length += CID->getNameAsString().size()+1;
|
||||
length += getSelector().getAsString().size(); // selector name
|
||||
return length;
|
||||
|
|
|
@ -630,7 +630,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
// Collect information about instance methods
|
||||
llvm::SmallVector<Selector, 16> InstanceMethodSels;
|
||||
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
|
||||
for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(),
|
||||
for (ObjCCategoryImplDecl::instmeth_iterator iter = OCD->instmeth_begin(),
|
||||
endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
|
||||
InstanceMethodSels.push_back((*iter)->getSelector());
|
||||
std::string TypeStr;
|
||||
|
@ -641,7 +641,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
// Collect information about class methods
|
||||
llvm::SmallVector<Selector, 16> ClassMethodSels;
|
||||
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
|
||||
for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(),
|
||||
for (ObjCCategoryImplDecl::classmeth_iterator iter = OCD->classmeth_begin(),
|
||||
endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
|
||||
ClassMethodSels.push_back((*iter)->getSelector());
|
||||
std::string TypeStr;
|
||||
|
|
|
@ -161,7 +161,7 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
return LookupContext(D) == LookupContext(Ctx->getPrimaryContext(Context));
|
||||
return LookupContext(D) == LookupContext(Ctx->getPrimaryContext());
|
||||
}
|
||||
|
||||
/// AddDecl - Link the decl to its shadowed decl chain.
|
||||
|
|
|
@ -223,7 +223,7 @@ NamedDecl *Sema::getCurFunctionOrMethodDecl() {
|
|||
while (isa<BlockDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
|
||||
return cast<NamedDecl>(DC);
|
||||
return cast<ScopedDecl>(DC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace clang {
|
|||
class ObjCIvarDecl;
|
||||
class ObjCMethodDecl;
|
||||
class ObjCPropertyDecl;
|
||||
class ObjCContainerDecl;
|
||||
struct BlockSemaInfo;
|
||||
class BasePaths;
|
||||
|
||||
|
@ -1166,9 +1167,7 @@ public:
|
|||
void CheckObjCPropertyAttributes(QualType PropertyTy,
|
||||
SourceLocation Loc,
|
||||
unsigned &Attributes);
|
||||
void diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
|
||||
const ObjCMethodDecl *GetterMethod,
|
||||
const ObjCMethodDecl *SetterMethod);
|
||||
void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
|
||||
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
|
||||
ObjCPropertyDecl *SuperProperty,
|
||||
const IdentifierInfo *Name);
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace {
|
|||
if (LookupCtx && !LookInParentCtx) {
|
||||
IdIsUndeclared = true;
|
||||
DeclContext::lookup_const_iterator I, E;
|
||||
for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) {
|
||||
for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) {
|
||||
IdIsUndeclared = false;
|
||||
if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag) ||
|
||||
isa<TypedefDecl>(*I))
|
||||
|
|
|
@ -287,7 +287,7 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
|||
// Perform qualified name lookup into the LookupCtx.
|
||||
// FIXME: Will need to look into base classes and such.
|
||||
DeclContext::lookup_const_iterator I, E;
|
||||
for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I)
|
||||
for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
|
||||
if ((*I)->isInIdentifierNamespace(NS)) {
|
||||
// Ignore non-namespace names if we're only looking for namespaces.
|
||||
if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) continue;
|
||||
|
@ -334,7 +334,7 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
|||
while (Ctx && (Ctx->isNamespace() || Ctx->isRecord())) {
|
||||
// Look for declarations of this name in this scope.
|
||||
DeclContext::lookup_const_iterator I, E;
|
||||
for (llvm::tie(I, E) = Ctx->lookup(Context, Name); I != E; ++I) {
|
||||
for (llvm::tie(I, E) = Ctx->lookup(Name); I != E; ++I) {
|
||||
// FIXME: Cache this result in the IdResolver
|
||||
if ((*I)->isInIdentifierNamespace(NS)) {
|
||||
if (NamespaceNameOnly && !isa<NamespaceDecl>(*I))
|
||||
|
|
|
@ -681,7 +681,7 @@ Sema::ActOnMemInitializer(DeclTy *ConstructorD,
|
|||
// using a qualified name. ]
|
||||
// Look for a member, first.
|
||||
FieldDecl *Member = 0;
|
||||
DeclContext::lookup_result Result = ClassDecl->lookup(Context, MemberOrBase);
|
||||
DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase);
|
||||
if (Result.first != Result.second)
|
||||
Member = dyn_cast<FieldDecl>(*Result.first);
|
||||
|
||||
|
@ -1590,7 +1590,7 @@ Sema::PerformInitializationByConstructor(QualType ClassType,
|
|||
= Context.DeclarationNames.getCXXConstructorName(
|
||||
Context.getCanonicalType(ClassType.getUnqualifiedType()));
|
||||
DeclContext::lookup_const_iterator Con, ConEnd;
|
||||
for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName);
|
||||
for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName);
|
||||
Con != ConEnd; ++Con) {
|
||||
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
|
||||
if ((Kind == IK_Direct) ||
|
||||
|
|
|
@ -1001,14 +1001,18 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
|
|||
}
|
||||
}
|
||||
|
||||
/// diagnosePropertySetterGetterMismatch - Make sure that use-defined
|
||||
/// setter/getter methods have the property type and issue diagnostics
|
||||
/// if they don't.
|
||||
///
|
||||
void
|
||||
Sema::diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
|
||||
const ObjCMethodDecl *GetterMethod,
|
||||
const ObjCMethodDecl *SetterMethod) {
|
||||
/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
|
||||
/// have the property type and issue diagnostics if they don't.
|
||||
/// Also synthesize a getter/setter method if none exist (and update the
|
||||
/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
|
||||
/// methods is the "right" thing to do.
|
||||
void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
|
||||
ObjCContainerDecl *CD) {
|
||||
ObjCMethodDecl *GetterMethod, *SetterMethod;
|
||||
|
||||
GetterMethod = CD->getInstanceMethod(property->getGetterName());
|
||||
SetterMethod = CD->getInstanceMethod(property->getSetterName());
|
||||
|
||||
if (GetterMethod &&
|
||||
GetterMethod->getResultType() != property->getType()) {
|
||||
Diag(property->getLocation(),
|
||||
|
@ -1031,6 +1035,29 @@ Sema::diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
|
|||
Diag(SetterMethod->getLocation(), diag::note_declared_at);
|
||||
}
|
||||
}
|
||||
|
||||
// Synthesize getter/setter methods if none exist.
|
||||
// Add any synthesized methods to the global pool. This allows us to
|
||||
// handle the following, which is supported by GCC (and part of the design).
|
||||
//
|
||||
// @interface Foo
|
||||
// @property double bar;
|
||||
// @end
|
||||
//
|
||||
// void thisIsUnfortunate() {
|
||||
// id foo;
|
||||
// double bar = [foo bar];
|
||||
// }
|
||||
//
|
||||
CD->getPropertyMethods(Context, property, GetterMethod, SetterMethod);
|
||||
if (GetterMethod) {
|
||||
CD->addDecl(Context, GetterMethod);
|
||||
AddInstanceMethodToGlobalPool(GetterMethod);
|
||||
}
|
||||
if (SetterMethod) {
|
||||
CD->addDecl(Context, SetterMethod);
|
||||
AddInstanceMethodToGlobalPool(SetterMethod);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: For class/category implemenations, allMethods/allProperties is
|
||||
|
@ -1046,17 +1073,12 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
if (!ClassDecl)
|
||||
return;
|
||||
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> insMethods;
|
||||
llvm::SmallVector<ObjCMethodDecl*, 16> clsMethods;
|
||||
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
|
||||
|
||||
bool isInterfaceDeclKind =
|
||||
isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
|
||||
|| isa<ObjCProtocolDecl>(ClassDecl);
|
||||
bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
|
||||
|
||||
|
||||
if (pNum != 0) {
|
||||
if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
|
||||
IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
|
||||
|
@ -1067,7 +1089,14 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
else
|
||||
assert(false && "ActOnAtEnd - property declaration misplaced");
|
||||
}
|
||||
|
||||
|
||||
DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
|
||||
assert(DC && "Missing DeclContext");
|
||||
|
||||
// FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
|
||||
llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
|
||||
|
||||
for (unsigned i = 0; i < allNum; i++ ) {
|
||||
ObjCMethodDecl *Method =
|
||||
cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i]));
|
||||
|
@ -1084,7 +1113,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
<< Method->getDeclName();
|
||||
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
|
||||
} else {
|
||||
insMethods.push_back(Method);
|
||||
DC->addDecl(Context, Method);
|
||||
InsMap[Method->getSelector()] = Method;
|
||||
/// The following allows us to typecheck messages to "id".
|
||||
AddInstanceMethodToGlobalPool(Method);
|
||||
|
@ -1101,17 +1130,13 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
<< Method->getDeclName();
|
||||
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
|
||||
} else {
|
||||
clsMethods.push_back(Method);
|
||||
DC->addDecl(Context, Method);
|
||||
ClsMap[Method->getSelector()] = Method;
|
||||
/// The following allows us to typecheck messages to "Class".
|
||||
AddFactoryMethodToGlobalPool(Method);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save the size so we can detect if we've added any property methods.
|
||||
unsigned int insMethodsSizePriorToPropAdds = insMethods.size();
|
||||
unsigned int clsMethodsSizePriorToPropAdds = clsMethods.size();
|
||||
|
||||
if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
|
||||
// Compares properties declared in this class to those of its
|
||||
// super class.
|
||||
|
@ -1119,22 +1144,15 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
MergeProtocolPropertiesIntoClass(I, I);
|
||||
for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
|
||||
e = I->classprop_end(); i != e; ++i) {
|
||||
diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
|
||||
InsMap[(*i)->getSetterName()]);
|
||||
I->addPropertyMethods(Context, *i, insMethods, InsMap);
|
||||
ProcessPropertyDecl((*i), I);
|
||||
}
|
||||
I->addMethods(&insMethods[0], insMethods.size(),
|
||||
&clsMethods[0], clsMethods.size(), AtEndLoc);
|
||||
|
||||
I->setAtEndLoc(AtEndLoc);
|
||||
} else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
|
||||
for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
|
||||
e = P->classprop_end(); i != e; ++i) {
|
||||
diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
|
||||
InsMap[(*i)->getSetterName()]);
|
||||
P->addPropertyMethods(Context, *i, insMethods, InsMap);
|
||||
ProcessPropertyDecl((*i), P);
|
||||
}
|
||||
P->addMethods(&insMethods[0], insMethods.size(),
|
||||
&clsMethods[0], clsMethods.size(), AtEndLoc);
|
||||
P->setAtEndLoc(AtEndLoc);
|
||||
}
|
||||
else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
|
||||
// Categories are used to extend the class by declaring new methods.
|
||||
|
@ -1145,12 +1163,9 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
MergeProtocolPropertiesIntoClass(C, C);
|
||||
for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
|
||||
e = C->classprop_end(); i != e; ++i) {
|
||||
diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
|
||||
InsMap[(*i)->getSetterName()]);
|
||||
C->addPropertyMethods(Context, *i, insMethods, InsMap);
|
||||
ProcessPropertyDecl((*i), C);
|
||||
}
|
||||
C->addMethods(&insMethods[0], insMethods.size(),
|
||||
&clsMethods[0], clsMethods.size(), AtEndLoc);
|
||||
C->setAtEndLoc(AtEndLoc);
|
||||
}
|
||||
else if (ObjCImplementationDecl *IC =
|
||||
dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
|
||||
|
@ -1173,24 +1188,6 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
}
|
||||
}
|
||||
}
|
||||
// Add any synthesized methods to the global pool. This allows us to
|
||||
// handle the following, which is supported by GCC (and part of the design).
|
||||
//
|
||||
// @interface Foo
|
||||
// @property double bar;
|
||||
// @end
|
||||
//
|
||||
// void thisIsUnfortunate() {
|
||||
// id foo;
|
||||
// double bar = [foo bar];
|
||||
// }
|
||||
//
|
||||
if (insMethodsSizePriorToPropAdds < insMethods.size())
|
||||
for (unsigned i = insMethodsSizePriorToPropAdds; i < insMethods.size(); i++)
|
||||
AddInstanceMethodToGlobalPool(insMethods[i]);
|
||||
if (clsMethodsSizePriorToPropAdds < clsMethods.size())
|
||||
for (unsigned i = clsMethodsSizePriorToPropAdds; i < clsMethods.size(); i++)
|
||||
AddFactoryMethodToGlobalPool(clsMethods[i]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1241,7 +1238,7 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
|
|||
|
||||
ObjCMethodDecl* ObjCMethod =
|
||||
ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
|
||||
ClassDecl,
|
||||
dyn_cast<DeclContext>(ClassDecl),
|
||||
MethodType == tok::minus, isVariadic,
|
||||
false,
|
||||
MethodDeclKind == tok::objc_optional ?
|
||||
|
|
|
@ -414,7 +414,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name,
|
|||
FunctionDecl *&Operator)
|
||||
{
|
||||
DeclContext::lookup_iterator Alloc, AllocEnd;
|
||||
llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name);
|
||||
llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name);
|
||||
if (Alloc == AllocEnd) {
|
||||
if (AllowMissing)
|
||||
return false;
|
||||
|
@ -517,7 +517,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
|
|||
// Check if this function is already declared.
|
||||
{
|
||||
DeclContext::lookup_iterator Alloc, AllocEnd;
|
||||
for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Context, Name);
|
||||
for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name);
|
||||
Alloc != AllocEnd; ++Alloc) {
|
||||
// FIXME: Do we need to check for default arguments here?
|
||||
FunctionDecl *Func = cast<FunctionDecl>(*Alloc);
|
||||
|
|
|
@ -1117,7 +1117,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
|
|||
= Context.DeclarationNames.getCXXConstructorName(
|
||||
Context.getCanonicalType(ToType));
|
||||
DeclContext::lookup_iterator Con, ConEnd;
|
||||
for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(Context, ConstructorName);
|
||||
for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(ConstructorName);
|
||||
Con != ConEnd; ++Con) {
|
||||
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
|
||||
if (Constructor->isConvertingConstructor())
|
||||
|
@ -2141,7 +2141,7 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
|
|||
// empty.
|
||||
if (const RecordType *T1Rec = T1->getAsRecordType()) {
|
||||
DeclContext::lookup_const_iterator Oper, OperEnd;
|
||||
for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName);
|
||||
for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName);
|
||||
Oper != OperEnd; ++Oper)
|
||||
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0],
|
||||
Args+1, NumArgs - 1, CandidateSet,
|
||||
|
@ -3392,7 +3392,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
|
|||
OverloadCandidateSet CandidateSet;
|
||||
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
|
||||
DeclContext::lookup_const_iterator Oper, OperEnd;
|
||||
for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName);
|
||||
for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
|
||||
Oper != OperEnd; ++Oper)
|
||||
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
|
||||
CandidateSet, /*SuppressUserConversions=*/false);
|
||||
|
@ -3577,7 +3577,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
|
|||
const RecordType *BaseRecord = Base->getType()->getAsRecordType();
|
||||
|
||||
DeclContext::lookup_const_iterator Oper, OperEnd;
|
||||
for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(Context, OpName);
|
||||
for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(OpName);
|
||||
Oper != OperEnd; ++Oper)
|
||||
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet,
|
||||
/*SuppressUserConversions=*/false);
|
||||
|
|
Загрузка…
Ссылка в новой задаче