void TypePrinter::printAttributed(const AttributedType *T,
std::string &S) {
+ // Prefer the macro forms of the GC qualifiers.
+ if (T->getAttrKind() == AttributedType::attr_objc_gc)
+ return print(T->getEquivalentType(), S);
+
print(T->getModifiedType(), S);
// TODO: not all attributes are GCC-style attributes.
- S += "__attribute__((";
+ S += " __attribute__((";
switch (T->getAttrKind()) {
case AttributedType::attr_address_space:
S += "address_space(";
void Qualifiers::getAsStringInternal(std::string &S,
const PrintingPolicy&) const {
AppendTypeQualList(S, getCVRQualifiers());
- if (unsigned AddressSpace = getAddressSpace()) {
+ if (unsigned addrspace = getAddressSpace()) {
if (!S.empty()) S += ' ';
S += "__attribute__((address_space(";
- S += llvm::utostr_32(AddressSpace);
+ S += llvm::utostr_32(addrspace);
S += ")))";
}
- if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
+ if (Qualifiers::GC gc = getObjCGCAttr()) {
if (!S.empty()) S += ' ';
- S += "__attribute__((objc_gc(";
- if (GCAttrType == Qualifiers::Weak)
- S += "weak";
+ if (gc == Qualifiers::Weak)
+ S += "__weak";
else
- S += "strong";
- S += ")))";
+ S += "__strong";
}
}
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;
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());
}
}
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();
}
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;
}