Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -564,8 +564,6 @@ let Spellings = [Clang<"address_space">]; let Args = [IntArgument<"AddressSpace">]; let Documentation = [Undocumented]; - // Represented as a qualifier or DependentAddressSpaceType instead. - let ASTNode = 0; } def Alias : Attr { Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -1427,6 +1427,12 @@ return; } + // The printing of the address_space attribute is handled by the qualifier + // since it is still stored in the qualifier. Return early to prevent printing + // this twice. + if (T->getAttrKind() == attr::AddressSpace) + return; + OS << " __attribute__(("; switch (T->getAttrKind()) { #define TYPE_ATTR(NAME) @@ -1456,6 +1462,7 @@ case attr::Ptr64: case attr::SPtr: case attr::UPtr: + case attr::AddressSpace: llvm_unreachable("This attribute should have been handled already"); case attr::NSReturnsRetained: Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -5597,12 +5597,6 @@ } for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { - if (DependentAddressSpaceTypeLoc DASTL = - CurrTL.getAs()) { - fillDependentAddressSpaceTypeLoc(DASTL, D.getTypeObject(i).getAttrs()); - CurrTL = DASTL.getPointeeTypeLoc().getUnqualifiedLoc(); - } - // An AtomicTypeLoc might be produced by an atomic qualifier in this // declarator chunk. if (AtomicTypeLoc ATL = CurrTL.getAs()) { @@ -5615,6 +5609,12 @@ CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); } + while (DependentAddressSpaceTypeLoc TL = + CurrTL.getAs()) { + fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs()); + CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc(); + } + // FIXME: Ordering here? while (AdjustedTypeLoc TL = CurrTL.getAs()) CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); @@ -5767,7 +5767,10 @@ /// specified type. The attribute contains 1 argument, the id of the address /// space for the type. static void HandleAddressSpaceTypeAttribute(QualType &Type, - const ParsedAttr &Attr, Sema &S) { + const ParsedAttr &Attr, + TypeProcessingState &State) { + Sema &S = State.getSema(); + // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "A function type shall not be // qualified by an address-space qualifier." if (Type->isFunctionType()) { @@ -5809,10 +5812,15 @@ // the type. QualType T = S.BuildAddressSpaceAttr(Type, ASArgExpr, Attr.getLoc()); - if (!T.isNull()) - Type = T; - else + if (!T.isNull()) { + ASTContext &Ctx = S.Context; + auto *ASAttr = ::new (Ctx) AddressSpaceAttr( + Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(), + static_cast(T.getQualifiers().getAddressSpace())); + Type = State.getAttributedType(ASAttr, T, T); + } else { Attr.setInvalid(); + } } else { // The keyword-based type attributes imply which address space to use. switch (Attr.getKind()) { @@ -7282,7 +7290,7 @@ case ParsedAttr::AT_OpenCLConstantAddressSpace: case ParsedAttr::AT_OpenCLGenericAddressSpace: case ParsedAttr::AT_AddressSpace: - HandleAddressSpaceTypeAttribute(type, attr, state.getSema()); + HandleAddressSpaceTypeAttribute(type, attr, state); attr.setUsedAsTypeAttr(); break; OBJC_POINTER_TYPE_ATTRS_CASELIST: