From bc76297674a56c4dd182443d4ce817c4561fef50 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 26 Jul 2008 01:53:50 +0000 Subject: [PATCH] make DeclSpec manage its own protocol qualifier list memory instead of having clients allocate the memory and it delete it. llvm-svn: 54087 --- clang/include/clang/Parse/DeclSpec.h | 26 ++++++++++++++++++-------- clang/lib/Parse/ParseDecl.cpp | 14 ++++++-------- clang/lib/Sema/SemaType.cpp | 22 +++++++++------------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index efe726d8bcf2..d45f6011ecb2 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -126,7 +126,8 @@ private: // List of protocol qualifiers for objective-c classes. Used for // protocol-qualified interfaces "NString" and protocol-qualified id // "id". - llvm::SmallVector *ProtocolQualifiers; + Action::DeclTy * const *ProtocolQualifiers; + unsigned NumProtocolQualifiers; // SourceLocation info. These are null if the item wasn't specified or if // the setting was synthesized. @@ -143,6 +144,9 @@ private: bool BadSpecifier(TSC T, const char *&PrevSpec); bool BadSpecifier(TSW T, const char *&PrevSpec); bool BadSpecifier(SCS T, const char *&PrevSpec); + + DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT + void operator=(const DeclSpec&); // DO NOT IMPLEMENT public: DeclSpec() @@ -156,11 +160,12 @@ public: FS_inline_specified(false), TypeRep(0), AttrList(0), - ProtocolQualifiers(0) { + ProtocolQualifiers(0), + NumProtocolQualifiers(0) { } ~DeclSpec() { delete AttrList; - delete ProtocolQualifiers; + delete [] ProtocolQualifiers; } // storage-class-specifier SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } @@ -276,15 +281,20 @@ public: return AL; } - llvm::SmallVector *getProtocolQualifiers() const { + typedef Action::DeclTy *const * const ProtocolQualifierListTy; + ProtocolQualifierListTy getProtocolQualifiers() const { return ProtocolQualifiers; } - void setProtocolQualifiers(llvm::SmallVector *protos) { - ProtocolQualifiers = protos; - } unsigned getNumProtocolQualifiers() const { - return ProtocolQualifiers ? ProtocolQualifiers->size() : 0; + return NumProtocolQualifiers; } + void setProtocolQualifiers(Action::DeclTy* const *Protos, unsigned NumProtos){ + if (NumProtos == 0) return; + ProtocolQualifiers = new Action::DeclTy*[NumProtos]; + memcpy((void*)ProtocolQualifiers, Protos,sizeof(Action::DeclTy*)*NumProtos); + NumProtocolQualifiers = NumProtos; + } + /// Finish - This does final analysis of the declspec, issuing diagnostics for /// things like "_Imaginary" (lacking an FP type). After calling this method, /// DeclSpec is guaranteed self-consistent, even if an error occurred. diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 98c2d897d5d3..5ed1a61769e0 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -435,12 +435,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc); // FIXME: New'ing this here seems wrong, why not have the action do it? - llvm::SmallVector *ProtocolDecl = - new llvm::SmallVector; - DS.setProtocolQualifiers(ProtocolDecl); + llvm::SmallVector ProtocolDecl; Actions.FindProtocolDeclaration(Loc, &ProtocolRefs[0], ProtocolRefs.size(), - *ProtocolDecl); + ProtocolDecl); + DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size()); DS.SetRangeEnd(EndProtoLoc); @@ -576,12 +575,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { SourceLocation EndProtoLoc; llvm::SmallVector ProtocolRefs; ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc); - llvm::SmallVector *ProtocolDecl = - new llvm::SmallVector; - DS.setProtocolQualifiers(ProtocolDecl); + llvm::SmallVector ProtocolDecl; Actions.FindProtocolDeclaration(Loc, &ProtocolRefs[0], ProtocolRefs.size(), - *ProtocolDecl); + ProtocolDecl); + DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size()); DS.SetRangeEnd(EndProtoLoc); Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 85a457bd562f..7acb4587a0ba 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -44,9 +44,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { break; case DeclSpec::TST_unspecified: // "" is an objc qualified ID with a missing id. - if (llvm::SmallVector *PQ=DS.getProtocolQualifiers()) { - Action::DeclTy **PPDecl = &(*PQ)[0]; - Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)(PPDecl), + if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) { + Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers()); break; } @@ -122,28 +121,25 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 && DS.getTypeSpecSign() == 0 && "Can't handle qualifiers on typedef names yet!"); + DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers(); // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so // we have this "hack" for now... if (ObjCInterfaceDecl *ObjCIntDecl = dyn_cast(D)) { - if (DS.getProtocolQualifiers() == 0) { + if (PQ == 0) { Result = Context.getObjCInterfaceType(ObjCIntDecl); break; } - Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0]; Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl, - reinterpret_cast(PPDecl), + (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers()); break; } else if (TypedefDecl *typeDecl = dyn_cast(D)) { - if (Context.getObjCIdType() == Context.getTypedefType(typeDecl) - && DS.getProtocolQualifiers()) { - // id - Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0]; - Result = Context.getObjCQualifiedIdType( - reinterpret_cast(PPDecl), - DS.getNumProtocolQualifiers()); + if (Context.getObjCIdType() == Context.getTypedefType(typeDecl) && PQ) { + // id + Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ, + DS.getNumProtocolQualifiers()); break; } }