atch for implementation of objective-c's -Wselector

warning flag in clang. Little more to do
for a PCH issue. Radar 6507158.

llvm-svn: 109129
This commit is contained in:
Fariborz Jahanian 2010-07-22 18:24:20 +00:00
parent a11b4bfcbe
commit 6e7e8cc19d
16 changed files with 104 additions and 40 deletions

View File

@ -129,6 +129,9 @@ private:
// Synthesized declaration method for a property setter/getter // Synthesized declaration method for a property setter/getter
bool IsSynthesized : 1; bool IsSynthesized : 1;
// Method has a definition.
bool IsDefined : 1;
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
/// @required/@optional /// @required/@optional
unsigned DeclImplementation : 2; unsigned DeclImplementation : 2;
@ -171,12 +174,14 @@ private:
bool isInstance = true, bool isInstance = true,
bool isVariadic = false, bool isVariadic = false,
bool isSynthesized = false, bool isSynthesized = false,
bool isDefined = false,
ImplementationControl impControl = None, ImplementationControl impControl = None,
unsigned numSelectorArgs = 0) unsigned numSelectorArgs = 0)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod), DeclContext(ObjCMethod),
IsInstance(isInstance), IsVariadic(isVariadic), IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized), IsSynthesized(isSynthesized),
IsDefined(isDefined),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
NumSelectorArgs(numSelectorArgs), MethodDeclType(T), NumSelectorArgs(numSelectorArgs), MethodDeclType(T),
ResultTInfo(ResultTInfo), ResultTInfo(ResultTInfo),
@ -203,6 +208,7 @@ public:
bool isInstance = true, bool isInstance = true,
bool isVariadic = false, bool isVariadic = false,
bool isSynthesized = false, bool isSynthesized = false,
bool isDefined = false,
ImplementationControl impControl = None, ImplementationControl impControl = None,
unsigned numSelectorArgs = 0); unsigned numSelectorArgs = 0);
@ -297,6 +303,9 @@ public:
bool isSynthesized() const { return IsSynthesized; } bool isSynthesized() const { return IsSynthesized; }
void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
bool isDefined() const { return IsDefined; }
void setDefined(bool isDefined) { IsDefined = isDefined; }
// Related to protocols declared in @protocol // Related to protocols declared in @protocol
void setDeclImplementation(ImplementationControl ic) { void setDeclImplementation(ImplementationControl ic) {
DeclImplementation = ic; DeclImplementation = ic;

View File

@ -134,6 +134,7 @@ def UnusedVariable : DiagGroup<"unused-variable">;
def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
def Reorder : DiagGroup<"reorder">; def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">; def UndeclaredSelector : DiagGroup<"undeclared-selector">;
def Selector : DiagGroup<"selector">;
def Protocol : DiagGroup<"protocol">; def Protocol : DiagGroup<"protocol">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def : DiagGroup<"variadic-macros">; def : DiagGroup<"variadic-macros">;

View File

@ -400,6 +400,8 @@ def warn_objc_property_attr_mutually_exclusive : Warning<
InGroup<ReadOnlySetterAttrs>, DefaultIgnore; InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
def warn_undeclared_selector : Warning< def warn_undeclared_selector : Warning<
"undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore; "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
def warn_unimplemented_selector: Warning<
"unimplemented selector %0">, InGroup<Selector>, DefaultIgnore;
def warn_unimplemented_protocol_method : Warning< def warn_unimplemented_protocol_method : Warning<
"method in protocol not implemented">, InGroup<Protocol>; "method in protocol not implemented">, InGroup<Protocol>;

View File

@ -202,6 +202,8 @@ public:
return DeclGroupPtrTy(); return DeclGroupPtrTy();
} }
virtual void DiagnoseUseOfUnimplementedSelectors() {}
/// getTypeName - Return non-null if the specified identifier is a type name /// getTypeName - Return non-null if the specified identifier is a type name
/// in the current scope. /// in the current scope.
/// ///

View File

@ -201,7 +201,7 @@ public:
/// the EOF was encountered. /// the EOF was encountered.
bool ParseTopLevelDecl(DeclGroupPtrTy &Result); bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
DeclGroupPtrTy RetrievePendingObjCImpDecl(); DeclGroupPtrTy FinishPendingObjCActions();
private: private:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -2299,6 +2299,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
D->isInstanceMethod(), D->isInstanceMethod(),
D->isVariadic(), D->isVariadic(),
D->isSynthesized(), D->isSynthesized(),
D->isDefined(),
D->getImplementationControl()); D->getImplementationControl());
// FIXME: When we decide to merge method definitions, we'll need to // FIXME: When we decide to merge method definitions, we'll need to

View File

@ -339,12 +339,14 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
bool isInstance, bool isInstance,
bool isVariadic, bool isVariadic,
bool isSynthesized, bool isSynthesized,
bool isDefined,
ImplementationControl impControl, ImplementationControl impControl,
unsigned numSelectorArgs) { unsigned numSelectorArgs) {
return new (C) ObjCMethodDecl(beginLoc, endLoc, return new (C) ObjCMethodDecl(beginLoc, endLoc,
SelInfo, T, ResultTInfo, contextDecl, SelInfo, T, ResultTInfo, contextDecl,
isInstance, isInstance,
isVariadic, isSynthesized, impControl, isVariadic, isSynthesized, isDefined,
impControl,
numSelectorArgs); numSelectorArgs);
} }

View File

@ -1930,7 +1930,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
D->getLocation(), D->getLocation(),
D->getLocation(), cxxSelector, D->getLocation(), cxxSelector,
getContext().VoidTy, 0, getContext().VoidTy, 0,
DC, true, false, true, DC, true, false, true, false,
ObjCMethodDecl::Required); ObjCMethodDecl::Required);
D->addInstanceMethod(DTORMethod); D->addInstanceMethod(DTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false);
@ -1942,7 +1942,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
D->getLocation(), D->getLocation(),
D->getLocation(), cxxSelector, D->getLocation(), cxxSelector,
getContext().getObjCIdType(), 0, getContext().getObjCIdType(), 0,
DC, true, false, true, DC, true, false, true, false,
ObjCMethodDecl::Required); ObjCMethodDecl::Required);
D->addInstanceMethod(CTORMethod); D->addInstanceMethod(CTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true);

View File

@ -324,6 +324,7 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
MD->setInstanceMethod(Record[Idx++]); MD->setInstanceMethod(Record[Idx++]);
MD->setVariadic(Record[Idx++]); MD->setVariadic(Record[Idx++]);
MD->setSynthesized(Record[Idx++]); MD->setSynthesized(Record[Idx++]);
MD->setDefined(Record[Idx++]);
MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]); MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]); MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
MD->setNumSelectorArgs(unsigned(Record[Idx++])); MD->setNumSelectorArgs(unsigned(Record[Idx++]));

View File

@ -312,6 +312,7 @@ void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Record.push_back(D->isInstanceMethod()); Record.push_back(D->isInstanceMethod());
Record.push_back(D->isVariadic()); Record.push_back(D->isVariadic());
Record.push_back(D->isSynthesized()); Record.push_back(D->isSynthesized());
Record.push_back(D->isDefined());
// FIXME: stable encoding for @required/@optional // FIXME: stable encoding for @required/@optional
Record.push_back(D->getImplementationControl()); Record.push_back(D->getImplementationControl());
// FIXME: stable encoding for in/out/inout/bycopy/byref/oneway // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway

View File

@ -1314,7 +1314,8 @@ Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
return Result; return Result;
} }
Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() { Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() {
Actions.DiagnoseUseOfUnimplementedSelectors();
if (PendingObjCImpDecl.empty()) if (PendingObjCImpDecl.empty())
return Actions.ConvertDeclToDeclGroup(DeclPtrTy()); return Actions.ConvertDeclToDeclGroup(DeclPtrTy());
DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val(); DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val();

View File

@ -92,7 +92,7 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>()); Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
}; };
// Check for any pending objective-c implementation decl. // Check for any pending objective-c implementation decl.
while ((ADecl = P.RetrievePendingObjCImpDecl())) while ((ADecl = P.FinishPendingObjCActions()))
Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>()); Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
// Process any TopLevelDecls generated by #pragma weak. // Process any TopLevelDecls generated by #pragma weak.

View File

@ -606,6 +606,11 @@ public:
MethodPool InstanceMethodPool; MethodPool InstanceMethodPool;
MethodPool FactoryMethodPool; MethodPool FactoryMethodPool;
/// Method selectors used in a @selector expression. Used for implementation
/// of -Wselector.
llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors;
MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance); MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance);
/// Private Helper predicate to check for 'self'. /// Private Helper predicate to check for 'self'.
@ -798,6 +803,8 @@ public:
DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr); DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
void DiagnoseUseOfUnimplementedSelectors();
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec *SS, Scope *S, CXXScopeSpec *SS,
bool isClassName = false, bool isClassName = false,
@ -1656,7 +1663,7 @@ public:
/// unit are added to a global pool. This allows us to efficiently associate /// unit are added to a global pool. This allows us to efficiently associate
/// a selector with a method declaraation for purposes of typechecking /// a selector with a method declaraation for purposes of typechecking
/// messages sent to "id" (where the class of the object is unknown). /// messages sent to "id" (where the class of the object is unknown).
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method); void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false);
/// LookupInstanceMethodInGlobalPool - Returns the method and warns if /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
/// there are multiple signatures. /// there are multiple signatures.
@ -1665,10 +1672,15 @@ public:
/// LookupFactoryMethodInGlobalPool - Returns the method and warns if /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
/// there are multiple signatures. /// there are multiple signatures.
ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R); ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R,
bool warn=true);
/// LookupImplementedMethodInGlobalPool - Returns the method which has an
/// implementation.
ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);
/// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method); void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false);
/// CollectIvarsToConstructOrDestruct - Collect those ivars which require /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
/// initialization. /// initialization.

View File

@ -32,9 +32,9 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
// Allow the rest of sema to find private method decl implementations. // Allow the rest of sema to find private method decl implementations.
if (MDecl->isInstanceMethod()) if (MDecl->isInstanceMethod())
AddInstanceMethodToGlobalPool(MDecl); AddInstanceMethodToGlobalPool(MDecl, true);
else else
AddFactoryMethodToGlobalPool(MDecl); AddFactoryMethodToGlobalPool(MDecl, true);
// Allow all of Sema to see that we are entering a method definition. // Allow all of Sema to see that we are entering a method definition.
PushDeclContext(FnBodyScope, MDecl); PushDeclContext(FnBodyScope, MDecl);
@ -1130,7 +1130,7 @@ Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,
return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first; return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;
} }
void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) { void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl) {
llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
= InstanceMethodPool.find(Method->getSelector()); = InstanceMethodPool.find(Method->getSelector());
if (Pos == InstanceMethodPool.end()) { if (Pos == InstanceMethodPool.end()) {
@ -1140,7 +1140,7 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(), Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
ObjCMethodList())).first; ObjCMethodList())).first;
} }
Method->setDefined(impl);
ObjCMethodList &Entry = Pos->second; ObjCMethodList &Entry = Pos->second;
if (Entry.Method == 0) { if (Entry.Method == 0) {
// Haven't seen a method with this selector name yet - add it. // Haven't seen a method with this selector name yet - add it.
@ -1152,8 +1152,10 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
// We've seen a method with this name, see if we have already seen this type // We've seen a method with this name, see if we have already seen this type
// signature. // signature.
for (ObjCMethodList *List = &Entry; List; List = List->Next) for (ObjCMethodList *List = &Entry; List; List = List->Next)
if (MatchTwoMethodDeclarations(Method, List->Method)) if (MatchTwoMethodDeclarations(Method, List->Method)) {
List->Method->setDefined(impl);
return; return;
}
// We have a new signature for an existing method - add it. // We have a new signature for an existing method - add it.
// This is extremely rare. Only 1% of Cocoa selectors are "overloaded". // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
@ -1194,7 +1196,7 @@ ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
return MethList.Method; return MethList.Method;
} }
void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) { void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl) {
llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
= FactoryMethodPool.find(Method->getSelector()); = FactoryMethodPool.find(Method->getSelector());
if (Pos == FactoryMethodPool.end()) { if (Pos == FactoryMethodPool.end()) {
@ -1204,32 +1206,31 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(), Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),
ObjCMethodList())).first; ObjCMethodList())).first;
} }
Method->setDefined(impl);
ObjCMethodList &FirstMethod = Pos->second; ObjCMethodList &Entry = Pos->second;
if (!FirstMethod.Method) { if (!Entry.Method) {
// Haven't seen a method with this selector name yet - add it. // Haven't seen a method with this selector name yet - add it.
FirstMethod.Method = Method; Entry.Method = Method;
FirstMethod.Next = 0; Entry.Next = 0;
} else { return;
// We've seen a method with this name, now check the type signature(s). }
bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method); // We've seen a method with this name, see if we have already seen this type
// signature.
for (ObjCMethodList *List = &Entry; List; List = List->Next)
if (MatchTwoMethodDeclarations(Method, List->Method)) {
List->Method->setDefined(impl);
return;
}
for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
Next = Next->Next)
match = MatchTwoMethodDeclarations(Method, Next->Method);
if (!match) {
// We have a new signature for an existing method - add it. // We have a new signature for an existing method - add it.
// This is extremely rare. Only 1% of Cocoa selectors are "overloaded". // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
ObjCMethodList *OMI = new (Mem) ObjCMethodList(Method, FirstMethod.Next); Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);
FirstMethod.Next = OMI;
}
}
} }
ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel, ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
SourceRange R) { SourceRange R,
bool warn) {
llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
= FactoryMethodPool.find(Sel); = FactoryMethodPool.find(Sel);
if (Pos == FactoryMethodPool.end()) { if (Pos == FactoryMethodPool.end()) {
@ -1246,7 +1247,7 @@ ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
// This checks if the methods differ by size & alignment. // This checks if the methods differ by size & alignment.
if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true)) if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
issueWarning = true; issueWarning = warn;
} }
if (issueWarning && (MethList.Method && MethList.Next)) { if (issueWarning && (MethList.Method && MethList.Next)) {
Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R; Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
@ -1259,6 +1260,18 @@ ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
return MethList.Method; return MethList.Method;
} }
ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
SourceRange SR;
ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
SR, false);
if (Method && Method->isDefined())
return Method;
Method = LookupFactoryMethodInGlobalPool(Sel, SR, false);
if (Method && Method->isDefined())
return Method;
return 0;
}
/// CompareMethodParamsInBaseAndSuper - This routine compares methods with /// CompareMethodParamsInBaseAndSuper - This routine compares methods with
/// identical selector names in current and its super classes and issues /// identical selector names in current and its super classes and issues
/// a warning if any of their argument types are incompatible. /// a warning if any of their argument types are incompatible.
@ -1540,7 +1553,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
ResultTInfo, ResultTInfo,
cast<DeclContext>(ClassDecl), cast<DeclContext>(ClassDecl),
MethodType == tok::minus, isVariadic, MethodType == tok::minus, isVariadic,
false, false, false,
MethodDeclKind == tok::objc_optional ? MethodDeclKind == tok::objc_optional ?
ObjCMethodDecl::Optional : ObjCMethodDecl::Optional :
ObjCMethodDecl::Required); ObjCMethodDecl::Required);
@ -1849,3 +1862,15 @@ void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
} }
} }
void Sema::DiagnoseUseOfUnimplementedSelectors() {
if (ReferencedSelectors.empty())
return;
for (llvm::DenseMap<Selector, SourceLocation>::iterator S =
ReferencedSelectors.begin(),
E = ReferencedSelectors.end(); S != E; ++S) {
Selector Sel = (*S).first;
if (!LookupImplementedMethodInGlobalPool(Sel))
Diag((*S).second, diag::warn_unimplemented_selector) << Sel;
}
return;
}

View File

@ -163,6 +163,11 @@ Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
if (!Method) if (!Method)
Diag(SelLoc, diag::warn_undeclared_selector) << Sel; Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
llvm::DenseMap<Selector, SourceLocation>::iterator Pos
= ReferencedSelectors.find(Sel);
if (Pos == ReferencedSelectors.end())
ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
QualType Ty = Context.getObjCSelType(); QualType Ty = Context.getObjCSelType();
return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc); return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
} }

View File

@ -1085,6 +1085,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(), GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
property->getLocation(), property->getGetterName(), property->getLocation(), property->getGetterName(),
property->getType(), 0, CD, true, false, true, property->getType(), 0, CD, true, false, true,
false,
(property->getPropertyImplementation() == (property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ? ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional : ObjCMethodDecl::Optional :
@ -1112,6 +1113,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
property->getLocation(), property->getLocation(),
property->getSetterName(), property->getSetterName(),
Context.VoidTy, 0, CD, true, false, true, Context.VoidTy, 0, CD, true, false, true,
false,
(property->getPropertyImplementation() == (property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ? ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional : ObjCMethodDecl::Optional :