Early support for declaring ivars in class extensions. wip.

llvm-svn: 96819
This commit is contained in:
Fariborz Jahanian 2010-02-22 23:04:20 +00:00
parent 017a505716
commit 4c172c63e5
4 changed files with 24 additions and 4 deletions

View File

@ -1490,6 +1490,8 @@ def err_forward_ref_enum : Error<
"ISO C++ forbids forward references to 'enum' types">;
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
def err_misplaced_ivar : Error<"ivar may be placed in a class extension "
"in non-fragile-abi2 mode only">;
def ext_enum_value_not_int : Extension<
"ISO C restricts enumerator values to range of 'int' (%0 is too "
"%select{small|large}1)">;

View File

@ -849,6 +849,7 @@ private:
DeclPtrTy ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
AttributeList *prefixAttrs = 0);
void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
tok::ObjCKeywordKind visibility,
SourceLocation atLoc);
bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &P,
llvm::SmallVectorImpl<SourceLocation> &PLocs,

View File

@ -188,7 +188,10 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
ProtocolRefs.size(),
ProtocolLocs.data(),
EndProtoLoc);
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
atLoc);
ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
return CategoryType;
}
@ -229,7 +232,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
EndProtoLoc, attrList);
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(ClsType, atLoc);
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
return ClsType;
@ -965,6 +968,7 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
/// struct-declaration
///
void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
tok::ObjCKeywordKind visibility,
SourceLocation atLoc) {
assert(Tok.is(tok::l_brace) && "expected {");
llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
@ -973,7 +977,6 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
tok::ObjCKeywordKind visibility = tok::objc_protected;
// While we still have something to read, read the instance variables.
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
// Each iteration of this loop reads one objc-instance-variable-decl.
@ -1228,7 +1231,8 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
superClassId, superClassLoc);
if (Tok.is(tok::l_brace)) // we have ivars
ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/,
tok::objc_protected, atLoc);
ObjCImpDecl = ImplClsType;
PendingObjCImpDecl.push_back(ObjCImpDecl);

View File

@ -5682,6 +5682,19 @@ void Sema::ActOnFields(Scope* S,
// Only it is in implementation's lexical context.
ClsFields[I]->setLexicalDeclContext(IMPDecl);
CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac);
} else if (ObjCCategoryDecl *CDecl =
dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension())
Diag(LBrac, diag::err_misplaced_ivar);
else {
// FIXME. Class extension does not have a LocEnd field.
// CDecl->setLocEnd(RBrac);
// Add ivar's to class extension's DeclContext.
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
ClsFields[i]->setLexicalDeclContext(CDecl);
CDecl->addDecl(ClsFields[i]);
}
}
}
}