From: Chris Lattner Date: Thu, 21 Feb 2008 01:32:26 +0000 (+0000) Subject: Collect and build and process type attributes on pointers. For X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7654914fc5c6e2683d9e7358a64b3b53f368a8fc;p=clang Collect and build and process type attributes on pointers. For example, we can now correctly build the type for things like: _AS1 float * _AS2 *B; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47420 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/ParseDecl.cpp b/Parse/ParseDecl.cpp index 3b6e04d84f..d8aba9d730 100644 --- a/Parse/ParseDecl.cpp +++ b/Parse/ParseDecl.cpp @@ -1064,14 +1064,14 @@ void Parser::ParseDeclaratorInternal(Declarator &D) { 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); @@ -1080,7 +1080,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D) { 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; @@ -1108,7 +1109,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D) { 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())); } } @@ -1385,11 +1387,8 @@ void Parser::ParseParenDeclarator(Declarator &D) { 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; diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 9db0e0145e..e0a42a282d 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -732,8 +732,8 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { 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. diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index 45bae6d2f0..4b06e6adad 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -100,7 +100,7 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0]; Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl, reinterpret_cast(PPDecl), - DS.NumProtocolQualifiers()); + DS.getNumProtocolQualifiers()); break; } else if (TypedefDecl *typeDecl = dyn_cast(D)) { @@ -110,7 +110,7 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0]; Result = Context.getObjCQualifiedIdType(typeDecl->getUnderlyingType(), reinterpret_cast(PPDecl), - DS.NumProtocolQualifiers()); + DS.getNumProtocolQualifiers()); break; } } @@ -164,7 +164,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // 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: @@ -178,6 +178,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // 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()) { @@ -190,6 +195,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { } 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; diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 2eb2364ad9..b15279379e 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -260,7 +260,14 @@ public: } 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 *getProtocolQualifiers() const { return ProtocolQualifiers; @@ -268,7 +275,7 @@ public: void setProtocolQualifiers(llvm::SmallVector *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 @@ -362,13 +369,19 @@ struct DeclaratorChunk { 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 { @@ -441,21 +454,25 @@ struct DeclaratorChunk { /// 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; }