make DeclSpec manage its own protocol qualifier list memory instead of having

clients allocate the memory and it delete it.

llvm-svn: 54087
This commit is contained in:
Chris Lattner 2008-07-26 01:53:50 +00:00
parent 16fac4f2ad
commit bc76297674
3 changed files with 33 additions and 29 deletions

View File

@ -126,7 +126,8 @@ private:
// List of protocol qualifiers for objective-c classes. Used for
// protocol-qualified interfaces "NString<foo>" and protocol-qualified id
// "id<foo>".
llvm::SmallVector<Action::DeclTy *, 8> *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<Action::DeclTy *, 8> *getProtocolQualifiers() const {
typedef Action::DeclTy *const * const ProtocolQualifierListTy;
ProtocolQualifierListTy getProtocolQualifiers() const {
return ProtocolQualifiers;
}
void setProtocolQualifiers(llvm::SmallVector<Action::DeclTy *, 8> *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.

View File

@ -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<DeclTy *, 8> *ProtocolDecl =
new llvm::SmallVector<DeclTy *, 8>;
DS.setProtocolQualifiers(ProtocolDecl);
llvm::SmallVector<DeclTy *, 8> 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<IdentifierLocPair, 8> ProtocolRefs;
ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc);
llvm::SmallVector<DeclTy *, 8> *ProtocolDecl =
new llvm::SmallVector<DeclTy *, 8>;
DS.setProtocolQualifiers(ProtocolDecl);
llvm::SmallVector<DeclTy *, 8> 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,

View File

@ -44,9 +44,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
break;
case DeclSpec::TST_unspecified:
// "<proto1,proto2>" is an objc qualified ID with a missing id.
if (llvm::SmallVector<Action::DeclTy *, 8> *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<ObjCInterfaceDecl>(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<ObjCProtocolDecl**>(PPDecl),
(ObjCProtocolDecl**)PQ,
DS.getNumProtocolQualifiers());
break;
} else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
if (Context.getObjCIdType() == Context.getTypedefType(typeDecl)
&& DS.getProtocolQualifiers()) {
// id<protocol-list>
Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
Result = Context.getObjCQualifiedIdType(
reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
DS.getNumProtocolQualifiers());
if (Context.getObjCIdType() == Context.getTypedefType(typeDecl) && PQ) {
// id<protocol-list>
Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
DS.getNumProtocolQualifiers());
break;
}
}