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