From: Fariborz Jahanian Date: Thu, 10 Apr 2008 23:32:45 +0000 (+0000) Subject: Patch for: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d78cc443084134428c4c333fab25148900c3ca4;p=clang Patch for: 1) objc ivar processing is split out of ActOnField into its own ActOnIvar method. 2) the new objc ivar action takes visibility info directly, eliminating AllVisibilities in ParseObjCClassInstanceVariables. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49506 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index fb180c2d1a..3e915cb6d2 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -194,14 +194,21 @@ public: return 0; } - virtual DeclTy *ActOnField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart, + virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart, Declarator &D, ExprTy *BitfieldWidth) { return 0; } + + virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart, + Declarator &D, ExprTy *BitfieldWidth, + tok::ObjCKeywordKind visibility = tok::objc_not_keyword) { + return 0; + } + virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *TagDecl, DeclTy **Fields, unsigned NumFields, - SourceLocation LBrac, SourceLocation RBrac, - tok::ObjCKeywordKind *visibility = 0) {} + SourceLocation LBrac, SourceLocation RBrac) {} + virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl, DeclTy *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 804fffb9f1..e3d6b4f788 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -759,7 +759,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { FieldDeclarator &FD = FieldDeclarators[i]; // Install the declarator into the current TagDecl. - DeclTy *Field = Actions.ActOnField(CurScope, TagDecl, + DeclTy *Field = Actions.ActOnField(CurScope, DS.getSourceRange().getBegin(), FD.D, FD.BitfieldSize); FieldDecls.push_back(Field); diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 5a9b980b6d..eb3c5df6fb 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -397,9 +397,9 @@ Parser::DeclTy *Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl, for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { FieldDeclarator &FD = FieldDeclarators[i]; // Install the declarator into interfaceDecl. - DeclTy *Field = Actions.ActOnField(CurScope, interfaceDecl, + DeclTy *Field = Actions.ActOnIvar(CurScope, DS.getSourceRange().getBegin(), - FD.D, FD.BitfieldSize); + FD.D, FD.BitfieldSize); PropertyDecls.push_back(Field); } @@ -772,7 +772,6 @@ void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, SourceLocation atLoc) { assert(Tok.is(tok::l_brace) && "expected {"); llvm::SmallVector AllIvarDecls; - llvm::SmallVector AllVisibilities; llvm::SmallVector FieldDeclarators; SourceLocation LBraceLoc = ConsumeBrace(); // the "{" @@ -815,11 +814,10 @@ void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { FieldDeclarator &FD = FieldDeclarators[i]; // Install the declarator into interfaceDecl. - DeclTy *Field = Actions.ActOnField(CurScope, interfaceDecl, + DeclTy *Field = Actions.ActOnIvar(CurScope, DS.getSourceRange().getBegin(), - FD.D, FD.BitfieldSize); + FD.D, FD.BitfieldSize, visibility); AllIvarDecls.push_back(Field); - AllVisibilities.push_back(visibility); } if (Tok.is(tok::semi)) { @@ -838,7 +836,7 @@ void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, // for code rewriting tools that need to be aware of the empty list. Actions.ActOnFields(CurScope, atLoc, interfaceDecl, &AllIvarDecls[0], AllIvarDecls.size(), - LBraceLoc, RBraceLoc, &AllVisibilities[0]); + LBraceLoc, RBraceLoc); return; } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b2a88eb635..143257aeab 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -235,15 +235,18 @@ private: virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK, SourceLocation KWLoc, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr); - virtual DeclTy *ActOnField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart, + virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart, Declarator &D, ExprTy *BitfieldWidth); - + + virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart, + Declarator &D, ExprTy *BitfieldWidth, + tok::ObjCKeywordKind visibility = tok::objc_not_keyword); + // This is used for both record definitions and ObjC interface declarations. virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *TagDecl, DeclTy **Fields, unsigned NumFields, - SourceLocation LBrac, SourceLocation RBrac, - tok::ObjCKeywordKind *visibility = 0); + SourceLocation LBrac, SourceLocation RBrac); virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl, DeclTy *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 27825dbef6..157700f579 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1419,12 +1419,11 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, /// ActOnField - Each field of a struct/union/class is passed into this in order /// to create a FieldDecl object for it. -Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl, +Sema::DeclTy *Sema::ActOnField(Scope *S, SourceLocation DeclStart, Declarator &D, ExprTy *BitfieldWidth) { IdentifierInfo *II = D.getIdentifier(); Expr *BitWidth = (Expr*)BitfieldWidth; - Decl *TagDecl = static_cast(tagDecl); SourceLocation Loc = DeclStart; if (II) Loc = D.getIdentifierLoc(); @@ -1460,19 +1459,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl, // FIXME: Chain fielddecls together. FieldDecl *NewFD; - if (isa(TagDecl)) - NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth); - else if (isa(TagDecl) || - isa(TagDecl) || - isa(TagDecl) || - // FIXME: ivars are currently used to model properties, and - // properties can appear within a protocol. - // See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl. - isa(TagDecl)) - NewFD = ObjCIvarDecl::Create(Context, Loc, II, T); - else - assert(0 && "Sema::ActOnField(): Unknown TagDecl"); - + NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth); HandleDeclAttributes(NewFD, D.getDeclSpec().getAttributes(), D.getAttributes()); @@ -1494,11 +1481,66 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { } } +/// ActOnIvar - Each field of a struct/union/class is passed into this in order +/// to create an IvarDecl object for it. +Sema::DeclTy *Sema::ActOnIvar(Scope *S, + SourceLocation DeclStart, + Declarator &D, ExprTy *BitfieldWidth, + tok::ObjCKeywordKind visibility) { + IdentifierInfo *II = D.getIdentifier(); + Expr *BitWidth = (Expr*)BitfieldWidth; + SourceLocation Loc = DeclStart; + if (II) Loc = D.getIdentifierLoc(); + + // FIXME: Unnamed fields can be handled in various different ways, for + // example, unnamed unions inject all members into the struct namespace! + + + if (BitWidth) { + // TODO: Validate. + //printf("WARNING: BITFIELDS IGNORED!\n"); + + // 6.7.2.1p3 + // 6.7.2.1p4 + + } else { + // Not a bitfield. + + // validate II. + + } + + QualType T = GetTypeForDeclarator(D, S); + assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); + bool InvalidDecl = false; + + // C99 6.7.2.1p8: A member of a structure or union may have any type other + // than a variably modified type. + if (T->isVariablyModifiedType()) { + // FIXME: This diagnostic needs work + Diag(Loc, diag::err_typecheck_illegal_vla, Loc); + InvalidDecl = true; + } + + ObjCIvarDecl *NewID; + + NewID = ObjCIvarDecl::Create(Context, Loc, II, T); + + HandleDeclAttributes(NewID, D.getDeclSpec().getAttributes(), + D.getAttributes()); + + if (D.getInvalidType() || InvalidDecl) + NewID->setInvalidDecl(); + // If we have visibility info, make sure the AST is set accordingly. + if (visibility != tok::objc_not_keyword) + NewID ->setAccessControl(TranslateIvarVisibility(visibility)); + return NewID; +} + void Sema::ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *RecDecl, DeclTy **Fields, unsigned NumFields, - SourceLocation LBrac, SourceLocation RBrac, - tok::ObjCKeywordKind *visibility) { + SourceLocation LBrac, SourceLocation RBrac) { Decl *EnclosingDecl = static_cast(RecDecl); assert(EnclosingDecl && "missing record or interface decl"); RecordDecl *Record = dyn_cast(EnclosingDecl); @@ -1529,11 +1571,6 @@ void Sema::ActOnFields(Scope* S, // Get the type for the field. Type *FDTy = FD->getType().getTypePtr(); - - // If we have visibility info, make sure the AST is set accordingly. - if (visibility) - cast(FD)->setAccessControl( - TranslateIvarVisibility(visibility[i])); // C99 6.7.2.1p2 - A field may not be a function type. if (FDTy->isFunctionType()) {