aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp73
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;
}