diff options
author | John McCall <rjmccall@apple.com> | 2011-03-04 04:00:19 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-03-04 04:00:19 +0000 |
commit | 14aa2175416f79ef17811282afbf425f87d54ebf (patch) | |
tree | acbbf7f9240a5d923fc6b0ce209671d2ad5dbf63 /lib/Sema/SemaType.cpp | |
parent | 0498247f87ea0d716e0c2931fea812280649e33d (diff) |
Make AttributedTypes for GC-qualified types and fix some miscellaneous
bugs with such types. Not sure this is quite how I want the desugaring
and a.k.a. logic to go, but it suffices.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126986 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index a2f1a6b65a..a9e6392247 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2126,6 +2126,60 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo); } +/// Map an AttributedType::Kind to an AttributeList::Kind. +static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) { + switch (kind) { + case AttributedType::attr_address_space: + return AttributeList::AT_address_space; + case AttributedType::attr_regparm: + return AttributeList::AT_regparm; + case AttributedType::attr_vector_size: + return AttributeList::AT_vector_size; + case AttributedType::attr_neon_vector_type: + return AttributeList::AT_neon_vector_type; + case AttributedType::attr_neon_polyvector_type: + return AttributeList::AT_neon_polyvector_type; + case AttributedType::attr_objc_gc: + return AttributeList::AT_objc_gc; + case AttributedType::attr_noreturn: + return AttributeList::AT_noreturn; + case AttributedType::attr_cdecl: + return AttributeList::AT_cdecl; + case AttributedType::attr_fastcall: + return AttributeList::AT_fastcall; + case AttributedType::attr_stdcall: + return AttributeList::AT_stdcall; + case AttributedType::attr_thiscall: + return AttributeList::AT_thiscall; + case AttributedType::attr_pascal: + return AttributeList::AT_pascal; + } + llvm_unreachable("unexpected attribute kind!"); + return AttributeList::Kind(); +} + +static void fillAttributedTypeLoc(AttributedTypeLoc TL, + const AttributeList *attrs) { + AttributedType::Kind kind = TL.getAttrKind(); + + assert(attrs && "no type attributes in the expected location!"); + AttributeList::Kind parsedKind = getAttrListKind(kind); + while (attrs->getKind() != parsedKind) { + attrs = attrs->getNext(); + assert(attrs && "no matching attribute in expected location!"); + } + + TL.setAttrNameLoc(attrs->getLoc()); + if (TL.hasAttrExprOperand()) + TL.setAttrExprOperand(attrs->getArg(0)); + else if (TL.hasAttrEnumOperand()) + TL.setAttrEnumOperandLoc(attrs->getParameterLoc()); + + // FIXME: preserve this information to here. + if (TL.hasAttrOperand()) + TL.setAttrOperandParensRange(SourceRange()); +} + namespace { class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> { ASTContext &Context; @@ -2135,6 +2189,10 @@ namespace { TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS) : Context(Context), DS(DS) {} + void VisitAttributedTypeLoc(AttributedTypeLoc TL) { + fillAttributedTypeLoc(TL, DS.getAttributes().getList()); + Visit(TL.getModifiedLoc()); + } void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { Visit(TL.getUnqualifiedLoc()); } @@ -2376,6 +2434,12 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, } for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { + while (isa<AttributedTypeLoc>(CurrTL)) { + AttributedTypeLoc TL = cast<AttributedTypeLoc>(CurrTL); + fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs()); + CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); + } + DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL); CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); } @@ -2545,7 +2609,14 @@ static bool handleObjCGCTypeAttr(TypeProcessingState &state, return true; } - type = S.Context.getObjCGCQualType(type, GCAttr); + QualType origType = type; + type = S.Context.getObjCGCQualType(origType, GCAttr); + + // Make an attributed type to preserve the source information. + if (attr.getLoc().isValid()) + type = S.Context.getAttributedType(AttributedType::attr_objc_gc, + origType, type); + return true; } |