diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-08-20 03:26:33 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-08-20 03:26:33 +0000 |
commit | 01e6779faca1e3a3164c697d6e2dfee0881a6981 (patch) | |
tree | 5062f900fd1c9929be52505fdb29b78c8ea53254 | |
parent | 618234a7481ed8da28dcdee0f997beb6e8252204 (diff) |
Added ObjCAtDefsFieldDecl to represent FieldDecls created by @defs.
This fixes an ownership issue where FieldDecls could be owned both by an ObjCInterfaceDecl and a RecordDecl.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55037 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/DeclBase.h | 3 | ||||
-rw-r--r-- | include/clang/AST/DeclObjC.h | 20 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 7 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 18 |
5 files changed, 55 insertions, 6 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 213515010c..d274fd381d 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -45,6 +45,7 @@ public: Field, CXXField, ObjCIvar, + ObjCAtDefsField, ObjCCategory, ObjCCategoryImpl, ObjCImplementation, @@ -84,7 +85,7 @@ public: // For each non-leaf class, we now define a mapping to the first/last member // of the class, to allow efficient classof. NamedFirst = Field , NamedLast = ParmVar, - FieldFirst = Field , FieldLast = ObjCIvar, + FieldFirst = Field , FieldLast = ObjCAtDefsField, ScopedFirst = Namespace , ScopedLast = ParmVar, TypeFirst = Typedef , TypeLast = CXXClass, TagFirst = Enum , TagLast = CXXClass, diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 413426c6a7..f4efbc052b 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -508,6 +508,26 @@ private: unsigned DeclAccess : 3; }; + +/// ObjCAtDefsFieldDecl - Represents a field declaration created by an +/// @defs(...). +class ObjCAtDefsFieldDecl : public FieldDecl { +private: + ObjCAtDefsFieldDecl(SourceLocation L, IdentifierInfo *Id, + QualType T, Expr *BW) + : FieldDecl(ObjCAtDefsField, L, Id, T, BW) {} + +public: + static ObjCAtDefsFieldDecl *Create(ASTContext &C, SourceLocation L, + IdentifierInfo *Id, QualType T, + Expr *BW); + + virtual void Destroy(ASTContext& C); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; } + static bool classof(const ObjCAtDefsFieldDecl *D) { return true; } +}; /// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols /// declare a pure abstract type (i.e no instance variables are permitted). diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index f48b7346e2..db179fec3e 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -41,6 +41,7 @@ static unsigned nProtocolDecls = 0; static unsigned nForwardProtocolDecls = 0; static unsigned nCategoryDecls = 0; static unsigned nIvarDecls = 0; +static unsigned nAtDefsFieldDecls = 0; static unsigned nObjCImplementationDecls = 0; static unsigned nObjCCategoryImpl = 0; static unsigned nObjCCompatibleAlias = 0; @@ -91,7 +92,7 @@ void Decl::PrintStats() { int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXFieldDecls+nCXXSUC+ nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+ nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+ - nNamespaces)); + nAtDefsFieldDecls+nNamespaces)); fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n", nNamespaces, (int)sizeof(NamespaceDecl), int(nNamespaces*sizeof(NamespaceDecl))); @@ -106,6 +107,9 @@ void Decl::PrintStats() { fprintf(stderr, " %d field decls, %d each (%d bytes)\n", nFieldDecls, (int)sizeof(FieldDecl), int(nFieldDecls*sizeof(FieldDecl))); + fprintf(stderr, " %d @defs generated field decls, %d each (%d bytes)\n", + nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl), + int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl))); fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n", nSUC, (int)sizeof(RecordDecl), int(nSUC*sizeof(RecordDecl))); @@ -209,6 +213,7 @@ void Decl::addDeclKind(Kind k) { case ObjCForwardProtocol: nForwardProtocolDecls++; break; case ObjCCategory: nCategoryDecls++; break; case ObjCIvar: nIvarDecls++; break; + case ObjCAtDefsField: nAtDefsFieldDecls++; break; case ObjCImplementation: nObjCImplementationDecls++; break; case ObjCCategoryImpl: nObjCCategoryImpl++; break; case ObjCCompatibleAlias: nObjCCompatibleAlias++; break; diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index a793ac608d..bd8b874735 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -94,6 +94,19 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L, return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW); } + +ObjCAtDefsFieldDecl +*ObjCAtDefsFieldDecl::Create(ASTContext &C, SourceLocation L, + IdentifierInfo *Id, QualType T, Expr *BW) { + void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>(); + return new (Mem) ObjCAtDefsFieldDecl(L, Id, T, BW); +} + +void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { + this->~ObjCAtDefsFieldDecl(); + C.getAllocator().Deallocate((void *)this); +} + ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id) { diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 5a1ad50cd2..b3e278c565 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1794,11 +1794,21 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, /// Collect the instance variables declared in an Objective-C object. Used in /// the creation of structures from objects using the @defs directive. -static void CollectIvars(ObjCInterfaceDecl *Class, +static void CollectIvars(ObjCInterfaceDecl *Class, ASTContext& Ctx, llvm::SmallVectorImpl<Sema::DeclTy*> &ivars) { if (Class->getSuperClass()) - CollectIvars(Class->getSuperClass(), ivars); - ivars.append(Class->ivar_begin(), Class->ivar_end()); + CollectIvars(Class->getSuperClass(), Ctx, ivars); + + // For each ivar, create a fresh ObjCAtDefsFieldDecl. + for (ObjCInterfaceDecl::ivar_iterator I=Class->ivar_begin(), E=Class->ivar_end(); + I!=E; ++I) { + + ObjCIvarDecl* ID = *I; + ivars.push_back(ObjCAtDefsFieldDecl::Create(Ctx, ID->getLocation(), + ID->getIdentifier(), + ID->getType(), + ID->getBitWidth())); + } } /// Called whenever @defs(ClassName) is encountered in the source. Inserts the @@ -1813,7 +1823,7 @@ void Sema::ActOnDefs(Scope *S, SourceLocation DeclStart, return; } // Collect the instance variables - CollectIvars(Class, Decls); + CollectIvars(Class, Context, Decls); } QualType Sema::TryFixInvalidVariablyModifiedType(QualType T) { |