]> granicus.if.org Git - clang/commitdiff
Handling remaining rule for synthesize bitfields in
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 23 Aug 2010 22:46:52 +0000 (22:46 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 23 Aug 2010 22:46:52 +0000 (22:46 +0000)
class extensions (nonfragile-abi2).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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111857 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 611d2f42f26190eb3347b32295e49d7cf85fd212..542ac3b8dc306be86349857afaf061c95cf3d003 100644 (file)
@@ -722,6 +722,9 @@ public:
     return 0;
   }
 
+  virtual void ActOnLastBitfield(SourceLocation DeclStart, Decl *IntfDecl, 
+                         llvm::SmallVectorImpl<Decl *> &AllIvarDecls) {}
+
   virtual void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl,
                            Decl **Fields, unsigned NumFields,
                            SourceLocation LBrac, SourceLocation RBrac,
index 41abdb4bfaea88562814eb2f2915e524d6475cb2..6ec01572b918550ac674c7d091d9dca9aa444b61 100644 (file)
@@ -1022,7 +1022,8 @@ public:
   bool CheckNontrivialField(FieldDecl *FD);
   void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
   CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
-
+  virtual void ActOnLastBitfield(SourceLocation DeclStart, Decl *IntfDecl, 
+                         llvm::SmallVectorImpl<Decl *> &AllIvarDecls);
   virtual Decl *ActOnIvar(Scope *S, SourceLocation DeclStart,
                               Decl *IntfDecl,
                               Declarator &D, ExprTy *BitfieldWidth,
index aafe9996d4d0501c9b996c1d8993c9b568e63a5e..822d96b7c8152c46ae635232d9152097d1b5a57f 100644 (file)
@@ -1097,7 +1097,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
         return Field;
       }
     } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
-
+    
     // Parse all the comma separated declarators.
     DeclSpec DS;
     ParseStructDeclaration(DS, Callback);
@@ -1111,6 +1111,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
     }
   }
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+  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,
index f08092f92204bc9b0793208527182294eb17bb79..e9a2b3cd722509de3728ed430cc08fe6fb916f6e 100644 (file)
@@ -6399,6 +6399,48 @@ Decl *Sema::ActOnIvar(Scope *S,
   return NewID;
 }
 
+/// ActOnLastBitfield - This routine handles synthesized bitfields rules for 
+/// 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, Decl *EnclosingDecl,
+                             llvm::SmallVectorImpl<Decl *> &AllIvarDecls) {
+  if (!LangOpts.ObjCNonFragileABI2 || AllIvarDecls.empty())
+    return;
+  
+  Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];
+  ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl);
+  
+  if (!Ivar->isBitField())
+    return;
+  uint64_t BitFieldSize =
+    Ivar->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+  if (BitFieldSize == 0)
+    return;
+  ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl);
+  if (!ID) {
+    if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+      if (!CD->IsClassExtension())
+        return;
+    }
+    // No need to add this to end of @implementation.
+    else
+      return;
+  }
+  // All conditions are met. Add a new bitfield to the tail end of ivars.
+  llvm::APInt Zero(Context.getTypeSize(Context.CharTy), 0);
+  Expr * BW = 
+    new (Context) IntegerLiteral(Zero, Context.CharTy, DeclLoc);
+
+  Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl),
+                              DeclLoc, 0,
+                              Context.CharTy, 
+                              Context.CreateTypeSourceInfo(Context.CharTy),
+                              ObjCIvarDecl::Private, BW,
+                              true);
+  AllIvarDecls.push_back(Ivar);
+}
+
 void Sema::ActOnFields(Scope* S,
                        SourceLocation RecLoc, Decl *EnclosingDecl,
                        Decl **Fields, unsigned NumFields,