aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-08-19 18:02:47 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-08-19 18:02:47 +0000
commite6f07f538fd0eddd6c087fcc01d4e4ff19129c71 (patch)
treed48b4f4bd3d46b513a2ad7613d7146ece6e97952
parent3dbf2f5f00cfc8b25318c119c0d39f4a49d15ebe (diff)
Revers r138040. Need to look at a few buildbot failures.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138049 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclBase.h5
-rw-r--r--include/clang/Parse/Parser.h10
-rw-r--r--include/clang/Sema/Sema.h33
-rw-r--r--lib/Parse/ParseDecl.cpp1
-rw-r--r--lib/Parse/ParseObjc.cpp110
-rw-r--r--lib/Parse/Parser.cpp11
-rw-r--r--lib/Sema/SemaCodeComplete.cpp37
-rw-r--r--lib/Sema/SemaDecl.cpp34
-rw-r--r--lib/Sema/SemaDeclObjC.cpp24
-rw-r--r--lib/Sema/SemaObjCProperty.cpp27
-rw-r--r--test/Index/rdar-8288645-invalid-code.mm1
11 files changed, 128 insertions, 165 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index dfe43f4086..8355e36c75 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -893,11 +893,6 @@ public:
return DeclKind == Decl::Block;
}
- bool isObjCContainer() const {
- return (DeclKind >= (int)Decl::ObjCCategory &&
- DeclKind <= (int)Decl::ObjCProtocol);
- }
-
bool isFunctionOrMethod() const {
switch (DeclKind) {
case Decl::Block:
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 00917c64ae..fc5d11cb6a 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -186,8 +186,6 @@ public:
const Token &getCurToken() const { return Tok; }
Scope *getCurScope() const { return Actions.getCurScope(); }
-
- Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.
@@ -1056,7 +1054,8 @@ private:
SourceLocation &LAngleLoc,
SourceLocation &EndProtoLoc);
bool ParseObjCProtocolQualifiers(DeclSpec &DS);
- void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey);
+ void ParseObjCInterfaceDeclList(Decl *interfaceDecl,
+ tok::ObjCKeywordKind contextKey);
Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
ParsedAttributes &prefixAttrs);
@@ -1087,13 +1086,14 @@ private:
ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, ObjCTypeNameContext Context);
void ParseObjCMethodRequirement();
- Decl *ParseObjCMethodPrototype(
+ Decl *ParseObjCMethodPrototype(Decl *classOrCat,
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
bool MethodDefinition = true);
Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
+ Decl *classDecl,
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
bool MethodDefinition=true);
- void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
+ void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl);
Decl *ParseObjCMethodDefinition();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 4bb014b88a..520afbc5d2 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1154,9 +1154,9 @@ public:
bool CheckNontrivialField(FieldDecl *FD);
void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
- void ActOnLastBitfield(SourceLocation DeclStart,
+ void ActOnLastBitfield(SourceLocation DeclStart, Decl *IntfDecl,
SmallVectorImpl<Decl *> &AllIvarDecls);
- Decl *ActOnIvar(Scope *S, SourceLocation DeclStart,
+ Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, Decl *IntfDecl,
Declarator &D, Expr *BitfieldWidth,
tok::ObjCKeywordKind visibility);
@@ -1171,8 +1171,6 @@ public:
/// struct, or union).
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
- void ActOnObjCContainerStartDefinition(Decl *IDecl);
-
/// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
/// C++ record definition's base-specifiers clause and are starting its
/// member declarations.
@@ -1185,8 +1183,6 @@ public:
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl,
SourceLocation RBraceLoc);
- void ActOnObjCContainerFinishDefinition(Decl *IDecl);
-
/// ActOnTagDefinitionError - Invoked when there was an unrecoverable
/// error parsing the definition of a tag.
void ActOnTagDefinitionError(Scope *S, Decl *TagDecl);
@@ -1849,6 +1845,7 @@ public:
/// Called by ActOnProperty to handle @property declarations in
//// class extensions.
Decl *HandlePropertyInClassExtension(Scope *S,
+ ObjCCategoryDecl *CDecl,
SourceLocation AtLoc,
FieldDeclarator &FD,
Selector GetterSel,
@@ -5047,7 +5044,7 @@ public:
void MatchOneProtocolPropertiesInClass(Decl *CDecl,
ObjCProtocolDecl *PDecl);
- void ActOnAtEnd(Scope *S, SourceRange AtEnd,
+ void ActOnAtEnd(Scope *S, SourceRange AtEnd, Decl *classDecl,
Decl **allMethods = 0, unsigned allNum = 0,
Decl **allProperties = 0, unsigned pNum = 0,
DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
@@ -5055,6 +5052,7 @@ public:
Decl *ActOnProperty(Scope *S, SourceLocation AtLoc,
FieldDeclarator &FD, ObjCDeclSpec &ODS,
Selector GetterSel, Selector SetterSel,
+ Decl *ClassCategory,
bool *OverridingProperty,
tok::ObjCKeywordKind MethodImplKind,
DeclContext *lexicalDC = 0);
@@ -5062,7 +5060,7 @@ public:
Decl *ActOnPropertyImplDecl(Scope *S,
SourceLocation AtLoc,
SourceLocation PropertyLoc,
- bool ImplKind,
+ bool ImplKind,Decl *ClassImplDecl,
IdentifierInfo *PropertyId,
IdentifierInfo *PropertyIvar,
SourceLocation PropertyIvarLoc);
@@ -5093,7 +5091,7 @@ public:
SourceLocation BeginLoc, // location of the + or -.
SourceLocation EndLoc, // location of the ; or {.
tok::TokenKind MethodType,
- ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
+ Decl *ClassDecl, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
SourceLocation SelectorStartLoc, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
@@ -5839,13 +5837,14 @@ public:
CXXCtorInitializer** Initializers,
unsigned NumInitializers);
- void CodeCompleteObjCAtDirective(Scope *S);
+ void CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
+ bool InInterface);
void CodeCompleteObjCAtVisibility(Scope *S);
void CodeCompleteObjCAtStatement(Scope *S);
void CodeCompleteObjCAtExpression(Scope *S);
void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
- void CodeCompleteObjCPropertyGetter(Scope *S);
- void CodeCompleteObjCPropertySetter(Scope *S);
+ void CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl);
+ void CodeCompleteObjCPropertySetter(Scope *S, Decl *ClassDecl);
void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
bool IsParameter);
void CodeCompleteObjCMessageReceiver(Scope *S);
@@ -5882,12 +5881,14 @@ public:
void CodeCompleteObjCImplementationCategory(Scope *S,
IdentifierInfo *ClassName,
SourceLocation ClassNameLoc);
- void CodeCompleteObjCPropertyDefinition(Scope *S);
+ void CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl);
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
- IdentifierInfo *PropertyName);
+ IdentifierInfo *PropertyName,
+ Decl *ObjCImpDecl);
void CodeCompleteObjCMethodDecl(Scope *S,
bool IsInstanceMethod,
- ParsedType ReturnType);
+ ParsedType ReturnType,
+ Decl *IDecl);
void CodeCompleteObjCMethodDeclSelector(Scope *S,
bool IsInstanceMethod,
bool AtParameterName,
@@ -6004,8 +6005,6 @@ public:
/// itself and in routines directly invoked from the parser and *never* from
/// template substitution or instantiation.
Scope *getCurScope() const { return CurScope; }
-
- Decl *getObjCDeclContext() const;
};
/// \brief RAII object that enters a new expression evaluation context.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2316590afe..9023b34fa9 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2319,7 +2319,6 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
///
void Parser::
ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
-
if (Tok.is(tok::kw___extension__)) {
// __extension__ silences extension warnings in the subexpression.
ExtensionRAIIObject O(Diags); // Use RAII to do this.
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index e2f8d1f3e6..c8b2a09d5e 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -33,7 +33,7 @@ Decl *Parser::ParseObjCAtDirectives() {
SourceLocation AtLoc = ConsumeToken(); // the "@"
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCAtDirective(getCurScope());
+ Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, false);
ConsumeCodeCompletionToken();
}
@@ -195,13 +195,11 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
ProtocolRefs.size(),
ProtocolLocs.data(),
EndProtoLoc);
-
if (Tok.is(tok::l_brace))
- ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, atLoc);
-
- Actions.ActOnObjCContainerStartDefinition(CategoryType);
- ParseObjCInterfaceDeclList(tok::objc_not_keyword);
- Actions.ActOnObjCContainerFinishDefinition(CategoryType);
+ ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
+ atLoc);
+
+ ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
return CategoryType;
}
// Parse a class interface.
@@ -243,9 +241,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
- Actions.ActOnObjCContainerStartDefinition(ClsType);
- ParseObjCInterfaceDeclList(tok::objc_interface);
- Actions.ActOnObjCContainerFinishDefinition(ClsType);
+ ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
return ClsType;
}
@@ -253,16 +249,17 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
/// it's used, but instead it's been lifted to here to support VS2005.
struct Parser::ObjCPropertyCallback : FieldCallback {
Parser &P;
+ Decl *IDecl;
SmallVectorImpl<Decl *> &Props;
ObjCDeclSpec &OCDS;
SourceLocation AtLoc;
tok::ObjCKeywordKind MethodImplKind;
- ObjCPropertyCallback(Parser &P,
+ ObjCPropertyCallback(Parser &P, Decl *IDecl,
SmallVectorImpl<Decl *> &Props,
ObjCDeclSpec &OCDS, SourceLocation AtLoc,
tok::ObjCKeywordKind MethodImplKind) :
- P(P), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
+ P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
MethodImplKind(MethodImplKind) {
}
@@ -295,7 +292,7 @@ struct Parser::ObjCPropertyCallback : FieldCallback {
bool isOverridingProperty = false;
Decl *Property =
P.Actions.ActOnProperty(P.getCurScope(), AtLoc, FD, OCDS,
- GetterSel, SetterSel,
+ GetterSel, SetterSel, IDecl,
&isOverridingProperty,
MethodImplKind);
if (!isOverridingProperty)
@@ -317,7 +314,8 @@ struct Parser::ObjCPropertyCallback : FieldCallback {
/// @required
/// @optional
///
-void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
+void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
+ tok::ObjCKeywordKind contextKey) {
SmallVector<Decl *, 32> allMethods;
SmallVector<Decl *, 16> allProperties;
SmallVector<DeclGroupPtrTy, 8> allTUVariables;
@@ -329,7 +327,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
// If this is a method prototype, parse it.
if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
Decl *methodPrototype =
- ParseObjCMethodPrototype(MethodImplKind, false);
+ ParseObjCMethodPrototype(interfaceDecl, MethodImplKind, false);
allMethods.push_back(methodPrototype);
// Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
// method definitions.
@@ -341,6 +339,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
Diag(Tok, diag::err_expected_minus_or_plus);
ParseObjCMethodDecl(Tok.getLocation(),
tok::minus,
+ interfaceDecl,
MethodImplKind, false);
continue;
}
@@ -369,6 +368,9 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
// erroneous r_brace would cause an infinite loop if not handled here.
if (Tok.is(tok::r_brace))
break;
+
+ // FIXME: as the name implies, this rule allows function definitions.
+ // We could pass a flag or check for functions during semantic analysis.
ParsedAttributes attrs(AttrFactory);
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
continue;
@@ -377,7 +379,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
// Otherwise, we have an @ directive, eat the @.
SourceLocation AtLoc = ConsumeToken(); // the "@"
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCAtDirective(getCurScope());
+ Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true);
ConsumeCodeCompletionToken();
break;
}
@@ -431,9 +433,9 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
ObjCDeclSpec OCDS;
// Parse property attribute list, if any.
if (Tok.is(tok::l_paren))
- ParseObjCPropertyAttribute(OCDS);
+ ParseObjCPropertyAttribute(OCDS, interfaceDecl);
- ObjCPropertyCallback Callback(*this, allProperties,
+ ObjCPropertyCallback Callback(*this, interfaceDecl, allProperties,
OCDS, AtLoc, MethodImplKind);
// Parse all the comma separated declarators.
@@ -448,7 +450,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
// We break out of the big loop in two cases: when we see @end or when we see
// EOF. In the former case, eat the @end. In the later case, emit an error.
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCAtDirective(getCurScope());
+ Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true);
ConsumeCodeCompletionToken();
} else if (Tok.isObjCAtKeyword(tok::objc_end))
ConsumeToken(); // the "end" identifier
@@ -457,7 +459,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
// Insert collected methods declarations into the @interface object.
// This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
- Actions.ActOnAtEnd(getCurScope(), AtEnd,
+ Actions.ActOnAtEnd(getCurScope(), AtEnd, interfaceDecl,
allMethods.data(), allMethods.size(),
allProperties.data(), allProperties.size(),
allTUVariables.data(), allTUVariables.size());
@@ -483,7 +485,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
/// weak
/// unsafe_unretained
///
-void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
+void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) {
assert(Tok.getKind() == tok::l_paren);
SourceLocation LHSLoc = ConsumeParen(); // consume '('
@@ -534,9 +536,9 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
if (Tok.is(tok::code_completion)) {
if (IsSetter)
- Actions.CodeCompleteObjCPropertySetter(getCurScope());
+ Actions.CodeCompleteObjCPropertySetter(getCurScope(), ClassDecl);
else
- Actions.CodeCompleteObjCPropertyGetter(getCurScope());
+ Actions.CodeCompleteObjCPropertyGetter(getCurScope(), ClassDecl);
ConsumeCodeCompletionToken();
}
@@ -588,13 +590,14 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
/// objc-method-attributes: [OBJC2]
/// __attribute__((deprecated))
///
-Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
+Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl,
+ tok::ObjCKeywordKind MethodImplKind,
bool MethodDefinition) {
assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
tok::TokenKind methodType = Tok.getKind();
SourceLocation mLoc = ConsumeToken();
- Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
+ Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind,
MethodDefinition);
// Since this rule is used for both method declarations and definitions,
// the caller is (optionally) responsible for consuming the ';'.
@@ -832,13 +835,14 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
///
Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
tok::TokenKind mType,
+ Decl *IDecl,
tok::ObjCKeywordKind MethodImplKind,
bool MethodDefinition) {
ParsingDeclRAIIObject PD(*this);
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
- /*ReturnType=*/ ParsedType());
+ /*ReturnType=*/ ParsedType(), IDecl);
ConsumeCodeCompletionToken();
}
@@ -855,7 +859,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
- ReturnType);
+ ReturnType, IDecl);
ConsumeCodeCompletionToken();
}
@@ -881,7 +885,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
Decl *Result
= Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
- mType, DSRet, ReturnType,
+ mType, IDecl, DSRet, ReturnType,
selLoc, Sel, 0,
CParamInfo.data(), CParamInfo.size(),
methodAttrs.getList(), MethodImplKind,
@@ -997,18 +1001,23 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
if (getLang().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
- if (KeyIdents.size() == 0)
+ if (KeyIdents.size() == 0) {
+ // Leave prototype scope.
+ PrototypeScope.Exit();
return 0;
+ }
Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
&KeyIdents[0]);
Decl *Result
= Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
- mType, DSRet, ReturnType,
+ mType, IDecl, DSRet, ReturnType,
selLoc, Sel, &ArgInfos[0],
CParamInfo.data(), CParamInfo.size(),
methodAttrs.getList(),
MethodImplKind, isVariadic, MethodDefinition);
+ // Leave prototype scope.
+ PrototypeScope.Exit();
PD.complete(Result);
return Result;
@@ -1108,7 +1117,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
SourceLocation atLoc) {
assert(Tok.is(tok::l_brace) && "expected {");
SmallVector<Decl *, 32> AllIvarDecls;
-
+
ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
@@ -1166,13 +1175,11 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
}
Decl *invoke(FieldDeclarator &FD) {
- P.Actions.ActOnObjCContainerStartDefinition(IDecl);
// Install the declarator into the interface decl.
Decl *Field
= P.Actions.ActOnIvar(P.getCurScope(),
FD.D.getDeclSpec().getSourceRange().getBegin(),
- FD.D, FD.BitfieldSize, visibility);
- P.Actions.ActOnObjCContainerFinishDefinition(IDecl);
+ IDecl, FD.D, FD.BitfieldSize, visibility);
if (Field)
AllIvarDecls.push_back(Field);
return Field;
@@ -1192,7 +1199,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
}
}
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- Actions.ActOnLastBitfield(RBraceLoc, AllIvarDecls);
+ Actions.ActOnLastBitfield(RBraceLoc, interfaceDecl, AllIvarDecls);
// Call ActOnFields() even if we don't have any decls. This is useful
// for code rewriting tools that need to be aware of the empty list.
Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
@@ -1288,11 +1295,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
ProtocolRefs.size(),
ProtocolLocs.data(),
EndProtoLoc, attrs.getList());
-
-
- Actions.ActOnObjCContainerStartDefinition(ProtoType);
- ParseObjCInterfaceDeclList(tok::objc_protocol);
- Actions.ActOnObjCContainerFinishDefinition(ProtoType);
+ ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
return ProtoType;
}
@@ -1353,8 +1356,6 @@ Decl *Parser::ParseObjCAtImplementationDeclaration(
Decl *ImplCatType = Actions.ActOnStartCategoryImplementation(
atLoc, nameId, nameLoc, categoryId,
categoryLoc);
-
- Actions.ActOnObjCContainerStartDefinition(ImplCatType);
ObjCImpDecl = ImplCatType;
PendingObjCImpDecl.push_back(ObjCImpDecl);
return 0;
@@ -1377,11 +1378,11 @@ Decl *Parser::ParseObjCAtImplementationDeclaration(
superClassId, superClassLoc);
if (Tok.is(tok::l_brace)) // we have ivars
- ParseObjCClassInstanceVariables(ImplClsType, tok::objc_private, atLoc);
-
- Actions.ActOnObjCContainerStartDefinition(ImplClsType);
+ ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/,
+ tok::objc_private, atLoc);
ObjCImpDecl = ImplClsType;
PendingObjCImpDecl.push_back(ObjCImpDecl);
+
return 0;
}
@@ -1391,8 +1392,7 @@ Decl *Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
Decl *Result = ObjCImpDecl;
ConsumeToken(); // the "end" identifier
if (ObjCImpDecl) {
- Actions.ActOnAtEnd(getCurScope(), atEnd);
- Actions.ActOnObjCContainerFinishDefinition(ObjCImpDecl);
+ Actions.ActOnAtEnd(getCurScope(), atEnd, ObjCImpDecl);
ObjCImpDecl = 0;
PendingObjCImpDecl.pop_back();
}
@@ -1408,8 +1408,7 @@ Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() {
if (PendingObjCImpDecl.empty())
return Actions.ConvertDeclToDeclGroup(0);
Decl *ImpDecl = PendingObjCImpDecl.pop_back_val();
- Actions.ActOnAtEnd(getCurScope(), SourceRange());
- Actions.ActOnObjCContainerFinishDefinition(ImpDecl);
+ Actions.ActOnAtEnd(getCurScope(), SourceRange(), ImpDecl);
return Actions.ConvertDeclToDeclGroup(ImpDecl);
}
@@ -1456,7 +1455,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
while (true) {
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
+ Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
ConsumeCodeCompletionToken();
}
@@ -1475,7 +1474,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
ConsumeToken(); // consume '='
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
+ Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId,
+ ObjCImpDecl);
ConsumeCodeCompletionToken();
}
@@ -1486,7 +1486,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
propertyIvar = Tok.getIdentifierInfo();
propertyIvarLoc = ConsumeToken(); // consume ivar-name
}
- Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true,
+ Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl,
propertyId, propertyIvar, propertyIvarLoc);
if (Tok.isNot(tok::comma))
break;
@@ -1509,7 +1509,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
ConsumeToken(); // consume dynamic
while (true) {
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
+ Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
ConsumeCodeCompletionToken();
}
@@ -1521,7 +1521,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
SourceLocation propertyLoc = ConsumeToken(); // consume property name
- Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false,
+ Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl,
propertyId, 0, SourceLocation());
if (Tok.isNot(tok::comma))
@@ -1739,7 +1739,7 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
///
Decl *Parser::ParseObjCMethodDefinition() {
- Decl *MDecl = ParseObjCMethodPrototype();
+ Decl *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
"parsing Objective-C method");
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index d7e7d4b081..5bb4165fbb 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -811,16 +811,7 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
AccessSpecifier AS) {
ParsingDeclSpec DS(*this);
DS.takeAttributesFrom(attrs);
- Decl *DC = getObjCDeclContext();
- if (DC)
- // Must temporarily exit the objective-c container scope for
- // parsing c constructs and re-enter objc container scope
- // afterwards.
- Actions.ActOnObjCContainerFinishDefinition(DC);
- DeclGroupPtrTy resPtrTy = ParseDeclarationOrFunctionDefinition(DS, AS);
- if (DC)
- Actions.ActOnObjCContainerStartDefinition(DC);
- return resPtrTy;
+ return ParseDeclarationOrFunctionDefinition(DS, AS);
}
/// ParseFunctionDefinition - We parsed and verified that the specified
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index ef54fbcad8..858a001d43 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -4141,14 +4141,15 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Results.AddResult(Result(Builder.TakeString()));
}
-void Sema::CodeCompleteObjCAtDirective(Scope *S) {
+void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
+ bool InInterface) {
typedef CodeCompletionResult Result;
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext::CCC_Other);
Results.EnterNewScope();
- if (isa<ObjCImplDecl>(CurContext))
+ if (ObjCImpDecl)
AddObjCImplementationResults(getLangOptions(), Results, false);
- else if (CurContext->isObjCContainer())
+ else if (InInterface)
AddObjCInterfaceResults(getLangOptions(), Results, false);
else
AddObjCTopLevelResults(Results, false);
@@ -4520,14 +4521,14 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
}
-void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
+void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl) {
typedef CodeCompletionResult Result;
// Try to find the interface where getters might live.
- ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
+ ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
if (!Class) {
if (ObjCCategoryDecl *Category
- = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
+ = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Class = Category->getClassInterface();
if (!Class)
@@ -4548,15 +4549,15 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
Results.data(),Results.size());
}
-void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
+void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl) {
typedef CodeCompletionResult Result;
// Try to find the interface where setters might live.
ObjCInterfaceDecl *Class
- = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
+ = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
if (!Class) {
if (ObjCCategoryDecl *Category
- = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
+ = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Class = Category->getClassInterface();
if (!Class)
@@ -5550,14 +5551,14 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Results.data(),Results.size());
}
-void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
+void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
typedef CodeCompletionResult Result;
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext::CCC_Other);
// Figure out where this @synthesize lives.
ObjCContainerDecl *Container
- = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
+ = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
if (!Container ||
(!isa<ObjCImplementationDecl>(Container) &&
!isa<ObjCCategoryImplDecl>(Container)))
@@ -5590,14 +5591,15 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
}
void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
- IdentifierInfo *PropertyName) {
+ IdentifierInfo *PropertyName,
+ Decl *ObjCImpDecl) {
typedef CodeCompletionResult Result;
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext::CCC_Other);
// Figure out where this @synthesize lives.
ObjCContainerDecl *Container
- = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
+ = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
if (!Container ||
(!isa<ObjCImplementationDecl>(Container) &&
!isa<ObjCCategoryImplDecl>(Container)))
@@ -6410,15 +6412,12 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
void Sema::CodeCompleteObjCMethodDecl(Scope *S,
bool IsInstanceMethod,
- ParsedType ReturnTy) {
+ ParsedType ReturnTy,
+ Decl *IDecl) {
// Determine the return type of the method we're declaring, if
// provided.
QualType ReturnType = GetTypeFromParser(ReturnTy);
- Decl *IDecl = 0;
- if (CurContext->isObjCContainer()) {
- ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
- IDecl = cast<Decl>(OCD);
- }
+
// Determine where we should start searching for methods.
ObjCContainerDecl *SearchDecl = 0;
bool IsInImplementation = false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 26af6ef97d..b45b7ae5dc 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -737,6 +737,11 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) {
return DC;
}
+ // ObjCMethodDecls are parsed (for some reason) outside the context
+ // of the class.
+ if (isa<ObjCMethodDecl>(DC))
+ return DC->getLexicalParent()->getLexicalParent();
+
return DC->getLexicalParent();
}
@@ -7727,15 +7732,6 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
PushDeclContext(S, Tag);
}
-void Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) {
- assert(isa<ObjCContainerDecl>(IDecl) &&
- "ActOnObjCContainerStartDefinition - Not ObjCContainerDecl");
- DeclContext *OCD = cast<DeclContext>(IDecl);
- assert(getContainingDC(OCD) == CurContext &&
- "The next DeclContext should be lexically contained in the current one.");
- CurContext = OCD;
-}
-
void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
SourceLocation FinalLoc,
SourceLocation LBraceLoc) {
@@ -7787,11 +7783,6 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
Consumer.HandleTagDeclDefinition(Tag);
}
-void Sema::ActOnObjCContainerFinishDefinition(Decl *IDecl) {
- // Exit this scope of this interface definition.
- PopDeclContext();
-}
-
void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
AdjustDeclIfTemplate(TagD);
TagDecl *Tag = cast<TagDecl>(TagD);
@@ -8336,6 +8327,7 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) {
/// in order to create an IvarDecl object for it.
Decl *Sema::ActOnIvar(Scope *S,
SourceLocation DeclStart,
+ Decl *IntfDecl,
Declarator &D, ExprTy *BitfieldWidth,
tok::ObjCKeywordKind Visibility) {
@@ -8378,7 +8370,7 @@ Decl *Sema::ActOnIvar(Scope *S,
Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
: ObjCIvarDecl::None;
// Must set ivar's DeclContext to its enclosing interface.
- ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(CurContext);
+ ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(IntfDecl);
ObjCContainerDecl *EnclosingContext;
if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
@@ -8440,7 +8432,7 @@ Decl *Sema::ActOnIvar(Scope *S,
/// class and class extensions. For every class @interface and class
/// extension @interface, if the last ivar is a bitfield of any type,
/// then add an implicit `char :0` ivar to the end of that interface.
-void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
+void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl,
SmallVectorImpl<Decl *> &AllIvarDecls) {
if (!LangOpts.ObjCNonFragileABI2 || AllIvarDecls.empty())
return;
@@ -8454,9 +8446,9 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
Ivar->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
if (BitFieldSize == 0)
return;
- ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CurContext);
+ ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl);
if (!ID) {
- if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CurContext)) {
+ if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
if (!CD->IsClassExtension())
return;
}
@@ -8468,7 +8460,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
llvm::APInt Zero(Context.getTypeSize(Context.IntTy), 0);
Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc);
- Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext),
+ Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl),
DeclLoc, DeclLoc, 0,
Context.CharTy,
Context.getTrivialTypeSourceInfo(Context.CharTy,
@@ -9340,7 +9332,3 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
std::pair<IdentifierInfo*,WeakInfo>(AliasName, W));
}
}
-
-Decl *Sema::getObjCDeclContext() const {
- return (dyn_cast_or_null<ObjCContainerDecl>(CurContext));
-}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index d255a3686f..3c3c7cb232 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -2052,14 +2052,15 @@ void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
// Note: For class/category implemenations, allMethods/allProperties is
// always null.
void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
+ Decl *ClassDecl,
Decl **allMethods, unsigned allNum,
Decl **allProperties, unsigned pNum,
DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
-
- if (!CurContext->isObjCContainer())
+ // FIXME: If we don't have a ClassDecl, we have an error. We should consider
+ // always passing in a decl. If the decl has an error, isInvalidDecl()
+ // should be true.
+ if (!ClassDecl)
return;
- ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
- Decl *ClassDecl = cast<Decl>(OCD);
bool isInterfaceDeclKind =
isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
@@ -2426,7 +2427,7 @@ private:
Decl *Sema::ActOnMethodDeclaration(
Scope *S,
SourceLocation MethodLoc, SourceLocation EndLoc,
- tok::TokenKind MethodType,
+ tok::TokenKind MethodType, Decl *ClassDecl,
ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
SourceLocation SelectorStartLoc,
Selector Sel,
@@ -2437,12 +2438,10 @@ Decl *Sema::ActOnMethodDeclaration(
AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
bool isVariadic, bool MethodDefinition) {
// Make sure we can establish a context for the method.
- if (!CurContext->isObjCContainer()) {
+ if (!ClassDecl) {
Diag(MethodLoc, diag::error_missing_method_context);
return 0;
}
- ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
- Decl *ClassDecl = cast<Decl>(OCD);
QualType resultDeclType;
TypeSourceInfo *ResultTInfo = 0;
@@ -2465,7 +2464,7 @@ Decl *Sema::ActOnMethodDeclaration(
ObjCMethodDecl* ObjCMethod =
ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
ResultTInfo,
- CurContext,
+ cast<DeclContext>(ClassDecl),
MethodType == tok::minus, isVariadic,
/*isSynthesized=*/false,
/*isImplicitlyDeclared=*/false, /*isDefined=*/false,
@@ -2657,12 +2656,7 @@ Decl *Sema::ActOnMethodDeclaration(
bool Sema::CheckObjCDeclScope(Decl *D) {
if (isa<TranslationUnitDecl>(CurContext->getRedeclContext()))
return false;
- // Following is also an error. But it is caused my a missing @end
- // and diagnostic is issued elsewere.
- if (isa<ObjCContainerDecl>(CurContext->getRedeclContext())) {
- return false;
- }
-
+
Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
D->setInvalidDecl();
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index a98c2c7d9a..9602c2bd5b 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -74,6 +74,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
ObjCDeclSpec &ODS,
Selector GetterSel,
Selector SetterSel,
+ Decl *ClassCategory,
bool *isOverridingProperty,
tok::ObjCKeywordKind MethodImplKind,
DeclContext *lexicalDC) {
@@ -100,11 +101,12 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
!(Attributes & ObjCDeclSpec::DQ_PR_weak)));
// Proceed with constructing the ObjCPropertDecls.
- ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
+ ObjCContainerDecl *ClassDecl =
+ cast<ObjCContainerDecl>(ClassCategory);
if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
if (CDecl->IsClassExtension()) {
- Decl *Res = HandlePropertyInClassExtension(S, AtLoc,
+ Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
FD, GetterSel, SetterSel,
isAssign, isReadWrite,
Attributes,
@@ -135,7 +137,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
}
Decl *
-Sema::HandlePropertyInClassExtension(Scope *S,
+Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
SourceLocation AtLoc, FieldDeclarator &FD,
Selector GetterSel, Selector SetterSel,
const bool isAssign,
@@ -144,9 +146,9 @@ Sema::HandlePropertyInClassExtension(Scope *S,
bool *isOverridingProperty,
TypeSourceInfo *T,
tok::ObjCKeywordKind MethodImplKind) {
- ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(CurContext);
+
// Diagnose if this property is already in continuation class.
- DeclContext *DC = CurContext;
+ DeclContext *DC = cast<DeclContext>(CDecl);
IdentifierInfo *PropertyId = FD.D.getIdentifier();
ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
@@ -233,20 +235,14 @@ Sema::HandlePropertyInClassExtension(Scope *S,
ProtocolPropertyODS.
setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
PIkind);
- // Must re-establish the context from class extension to primary
- // class context.
- ActOnObjCContainerFinishDefinition(CDecl);
- ActOnObjCContainerStartDefinition(CCPrimary);
+
Decl *ProtocolPtrTy =
ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
PIDecl->getGetterName(),
PIDecl->getSetterName(),
- isOverridingProperty,
+ CCPrimary, isOverridingProperty,
MethodImplKind,
/* lexicalDC = */ CDecl);
- // restore class extension context.
- ActOnObjCContainerFinishDefinition(CCPrimary);
- ActOnObjCContainerStartDefinition(CDecl);
PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy);
}
PIDecl->makeitReadWriteAttribute();
@@ -511,11 +507,12 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
SourceLocation AtLoc,
SourceLocation PropertyLoc,
bool Synthesize,
+ Decl *ClassCatImpDecl,
IdentifierInfo *PropertyId,
IdentifierInfo *PropertyIvar,
SourceLocation PropertyIvarLoc) {
ObjCContainerDecl *ClassImpDecl =
- cast_or_null<ObjCContainerDecl>(CurContext);
+ cast_or_null<ObjCContainerDecl>(ClassCatImpDecl);
// Make sure we have a context for the property implementation declaration.
if (!ClassImpDecl) {
Diag(AtLoc, diag::error_missing_property_context);
@@ -1283,7 +1280,7 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
// Saying that they are located at the @implementation isn't really going
// to help users.
ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(),
- true,
+ true,IMPDecl,
Prop->getIdentifier(), Prop->getIdentifier(),
SourceLocation());
}
diff --git a/test/Index/rdar-8288645-invalid-code.mm b/test/Index/rdar-8288645-invalid-code.mm
index ec4564130a..74e2365edc 100644
--- a/test/Index/rdar-8288645-invalid-code.mm
+++ b/test/Index/rdar-8288645-invalid-code.mm
@@ -5,3 +5,4 @@
extern "C" { @implementation Foo - (id)initWithBar:(Baz<WozBar>)pepper {
// CHECK: warning: cannot find interface declaration for 'Foo'
+// CHECK: error: '@end' is missing in implementation context