tok::TokenKind Kind = Tok.getKind();
// Not a pointer or C++ reference.
- if (Kind != tok::star && !(Kind == tok::amp && getLang().CPlusPlus))
+ if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus))
return ParseDirectDeclarator(D);
// Otherwise, '*' -> pointer or '&' -> reference.
SourceLocation Loc = ConsumeToken(); // Eat the * or &.
if (Kind == tok::star) {
- // Is a pointer
+ // Is a pointer.
DeclSpec DS;
ParseTypeQualifierListOpt(DS);
ParseDeclaratorInternal(D);
// Remember that we parsed a pointer type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc));
+ D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
+ DS.TakeAttributes()));
} else {
// Is a reference
DeclSpec DS;
ParseDeclaratorInternal(D);
// Remember that we parsed a reference type. It doesn't have type-quals.
- D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc));
+ D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
+ DS.TakeAttributes()));
}
}
ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
ParmDecl.getIdentifierLoc(), ParamTy.Val, ParmDecl.getInvalidType(),
- ParmDecl.getDeclSpec().getAttributes()));
+ ParmDecl.getDeclSpec().TakeAttributes()));
- // Ownership of DeclSpec has been handed off to ParamInfo.
- DS.clearAttributes();
-
// If the next token is a comma, consume it and keep reading arguments.
if (Tok.isNot(tok::comma)) break;
FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC,
D.getDeclSpec().isInlineSpecified(),
LastDeclarator);
- // FIXME: Handle attributes.
- D.getDeclSpec().clearAttributes();
+ // FIXME: Handle attributes: should delete anything left.
+ D.getDeclSpec().SetAttributes(0);
// Merge the decl with the existing one if appropriate. Since C functions
// are in a flat namespace, make sure we consider decls in outer scopes.
Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl,
reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
- DS.NumProtocolQualifiers());
+ DS.getNumProtocolQualifiers());
break;
}
else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
Result = Context.getObjCQualifiedIdType(typeDecl->getUnderlyingType(),
reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
- DS.NumProtocolQualifiers());
+ DS.getNumProtocolQualifiers());
break;
}
}
// Walk the DeclTypeInfo, building the recursive type as we go. DeclTypeInfos
// are ordered from the identifier out, which is opposite of what we want :).
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
- const DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
+ DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
switch (DeclType.Kind) {
default: assert(0 && "Unknown decltype!");
case DeclaratorChunk::Pointer:
// Apply the pointer typequals to the pointer object.
T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals);
+
+ // See if there are any attributes on the pointer that apply to it.
+ if (AttributeList *AL = DeclType.Ptr.AttrList)
+ DeclType.Ptr.AttrList = ProcessTypeAttributes(T, AL);
+
break;
case DeclaratorChunk::Reference:
if (const ReferenceType *RT = T->getAsReferenceType()) {
}
T = Context.getReferenceType(T);
+
+ // See if there are any attributes on the pointer that apply to it.
+ if (AttributeList *AL = DeclType.Ref.AttrList)
+ DeclType.Ref.AttrList = ProcessTypeAttributes(T, AL);
break;
case DeclaratorChunk::Array: {
const DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
}
void SetAttributes(AttributeList *AL) { AttrList = AL; }
AttributeList *getAttributes() const { return AttrList; }
- void clearAttributes() { AttrList = 0; }
+
+ /// TakeAttributes - Return the current attribute list and remove them from
+ /// the DeclSpec so that it doesn't own them.
+ AttributeList *TakeAttributes() {
+ AttributeList *AL = AttrList;
+ AttrList = 0;
+ return AL;
+ }
llvm::SmallVector<Action::DeclTy *, 8> *getProtocolQualifiers() const {
return ProtocolQualifiers;
void setProtocolQualifiers(llvm::SmallVector<Action::DeclTy *, 8> *protos) {
ProtocolQualifiers = protos;
}
- unsigned NumProtocolQualifiers() const {
+ unsigned getNumProtocolQualifiers() const {
return ProtocolQualifiers ? ProtocolQualifiers->size() : 0;
}
/// Finish - This does final analysis of the declspec, issuing diagnostics for
struct PointerTypeInfo {
/// The type qualifiers: const/volatile/restrict.
unsigned TypeQuals : 3;
- void destroy() {}
+ AttributeList *AttrList;
+ void destroy() {
+ delete AttrList;
+ }
};
struct ReferenceTypeInfo {
/// The type qualifier: restrict. [GNU] C++ extension
bool HasRestrict;
- void destroy() {}
+ AttributeList *AttrList;
+ void destroy() {
+ delete AttrList;
+ }
};
struct ArrayTypeInfo {
/// getPointer - Return a DeclaratorChunk for a pointer.
///
- static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc) {
+ static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
+ AttributeList *AL) {
DeclaratorChunk I;
I.Kind = Pointer;
I.Loc = Loc;
I.Ptr.TypeQuals = TypeQuals;
+ I.Ptr.AttrList = AL;
return I;
}
/// getReference - Return a DeclaratorChunk for a reference.
///
- static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc) {
+ static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
+ AttributeList *AL) {
DeclaratorChunk I;
I.Kind = Reference;
I.Loc = Loc;
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
+ I.Ref.AttrList = AL;
return I;
}