]> granicus.if.org Git - clang/commitdiff
Patch for:
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 10 Apr 2008 23:32:45 +0000 (23:32 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 10 Apr 2008 23:32:45 +0000 (23:32 +0000)
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

include/clang/Parse/Action.h
lib/Parse/ParseDecl.cpp
lib/Parse/ParseObjc.cpp
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp

index fb180c2d1a84e8faed94feb080c85a16237799b0..3e915cb6d2419a5edf7734c4574e0f460bed20c8 100644 (file)
@@ -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,
index 804fffb9f13b6050a676da967f31c549abaadd0b..e3d6b4f788b037e216958760ee5d86fefaec192e 100644 (file)
@@ -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);
index 5a9b980b6dd436d34c9fc3e10c5a6de89bf37019..eb3c5df6fbe0fd2a940ec100f60748d00d58ee40 100644 (file)
@@ -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<DeclTy*, 32> AllIvarDecls;
-  llvm::SmallVector<tok::ObjCKeywordKind, 32> AllVisibilities;
   llvm::SmallVector<FieldDeclarator, 8> 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;
 }
 
index b2a88eb635f6bf7b14674c43612e0fbbeecdb421..143257aeab85d30e7d4fb0760a60c02960ad5114 100644 (file)
@@ -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,
index 27825dbef651ab048b3f7dd7a7d183990b197cd0..157700f5794ae1f880de73b5fa00c927d0398d6f 100644 (file)
@@ -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<Decl *>(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<RecordDecl>(TagDecl))
-    NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
-  else if (isa<ObjCInterfaceDecl>(TagDecl) ||
-           isa<ObjCImplementationDecl>(TagDecl) ||
-           isa<ObjCCategoryDecl>(TagDecl) ||
-           // FIXME: ivars are currently used to model properties, and
-           // properties can appear within a protocol.
-           // See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl.
-           isa<ObjCProtocolDecl>(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<Decl*>(RecDecl);
   assert(EnclosingDecl && "missing record or interface decl");
   RecordDecl *Record = dyn_cast<RecordDecl>(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<ObjCIvarDecl>(FD)->setAccessControl(
-                                TranslateIvarVisibility(visibility[i]));
       
     // C99 6.7.2.1p2 - A field may not be a function type.
     if (FDTy->isFunctionType()) {