r339638 - Revert r339623 "Model type attributes as regular Attrs."

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 20 14:48:31 PDT 2018


Thanks, fixed and re-committed as r340215.

On Mon, 13 Aug 2018 at 18:56, Reid Kleckner via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: rnk
> Date: Mon Aug 13 18:55:37 2018
> New Revision: 339638
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339638&view=rev
> Log:
> Revert r339623 "Model type attributes as regular Attrs."
>
> This breaks compiling atlwin.h in Chromium. I'm sure the code is invalid
> in some way, but we put a lot of work into accepting it, and I'm sure
> rejecting it was not an intended consequence of this refactoring. :)
>
> Modified:
>     cfe/trunk/include/clang/AST/ASTContext.h
>     cfe/trunk/include/clang/AST/Attr.h
>     cfe/trunk/include/clang/AST/Type.h
>     cfe/trunk/include/clang/AST/TypeLoc.h
>     cfe/trunk/include/clang/Basic/Attr.td
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/include/clang/Serialization/ASTReader.h
>     cfe/trunk/include/clang/Serialization/ASTWriter.h
>     cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
>     cfe/trunk/lib/ARCMigrate/Transforms.cpp
>     cfe/trunk/lib/AST/ASTContext.cpp
>     cfe/trunk/lib/AST/Type.cpp
>     cfe/trunk/lib/AST/TypeLoc.cpp
>     cfe/trunk/lib/AST/TypePrinter.cpp
>     cfe/trunk/lib/Sema/SemaDecl.cpp
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/lib/Sema/SemaInit.cpp
>     cfe/trunk/lib/Sema/SemaObjCProperty.cpp
>     cfe/trunk/lib/Sema/SemaType.cpp
>     cfe/trunk/lib/Sema/TreeTransform.h
>     cfe/trunk/lib/Serialization/ASTReader.cpp
>     cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>     cfe/trunk/lib/Serialization/ASTWriter.cpp
>     cfe/trunk/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
>     cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 13 18:55:37 2018
> @@ -31,7 +31,6 @@
>  #include "clang/AST/TemplateName.h"
>  #include "clang/AST/Type.h"
>  #include "clang/Basic/AddressSpaces.h"
> -#include "clang/Basic/AttrKinds.h"
>  #include "clang/Basic/IdentifierTable.h"
>  #include "clang/Basic/LLVM.h"
>  #include "clang/Basic/LangOptions.h"
> @@ -1423,7 +1422,7 @@ public:
>
>    QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST)
> const;
>
> -  QualType getAttributedType(attr::Kind attrKind,
> +  QualType getAttributedType(AttributedType::Kind attrKind,
>                               QualType modifiedType,
>                               QualType equivalentType);
>
>
> Modified: cfe/trunk/include/clang/AST/Attr.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Attr.h (original)
> +++ cfe/trunk/include/clang/AST/Attr.h Mon Aug 13 18:55:37 2018
> @@ -113,19 +113,6 @@ public:
>    void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
>  };
>
> -class TypeAttr : public Attr {
> -protected:
> -  TypeAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
> -           bool IsLateParsed)
> -      : Attr(AK, R, SpellingListIndex, IsLateParsed) {}
> -
> -public:
> -  static bool classof(const Attr *A) {
> -    return A->getKind() >= attr::FirstTypeAttr &&
> -           A->getKind() <= attr::LastTypeAttr;
> -  }
> -};
> -
>  class StmtAttr : public Attr {
>  protected:
>    StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
>
> Modified: cfe/trunk/include/clang/AST/Type.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Type.h (original)
> +++ cfe/trunk/include/clang/AST/Type.h Mon Aug 13 18:55:37 2018
> @@ -21,7 +21,6 @@
>  #include "clang/AST/NestedNameSpecifier.h"
>  #include "clang/AST/TemplateName.h"
>  #include "clang/Basic/AddressSpaces.h"
> -#include "clang/Basic/AttrKinds.h"
>  #include "clang/Basic/Diagnostic.h"
>  #include "clang/Basic/ExceptionSpecificationType.h"
>  #include "clang/Basic/LLVM.h"
> @@ -1871,16 +1870,7 @@ public:
>    bool isObjCQualifiedClassType() const;        // Class<foo>
>    bool isObjCObjectOrInterfaceType() const;
>    bool isObjCIdType() const;                    // id
> -
> -  /// Was this type written with the special inert-in-ARC
> __unsafe_unretained
> -  /// qualifier?
> -  ///
> -  /// This approximates the answer to the following question: if this
> -  /// translation unit were compiled in ARC, would this type be qualified
> -  /// with __unsafe_unretained?
> -  bool isObjCInertUnsafeUnretainedType() const {
> -    return hasAttr(attr::ObjCInertUnsafeUnretained);
> -  }
> +  bool isObjCInertUnsafeUnretainedType() const;
>
>    /// Whether the type is Objective-C 'id' or a __kindof type of an
>    /// object type, e.g., __kindof NSView * or __kindof id
> @@ -2094,10 +2084,6 @@ public:
>    /// qualifiers from the outermost type.
>    const ArrayType *castAsArrayTypeUnsafe() const;
>
> -  /// Determine whether this type had the specified attribute applied to
> it
> -  /// (looking through top-level type sugar).
> -  bool hasAttr(attr::Kind AK) const;
> -
>    /// Get the base element type of this type, potentially discarding type
>    /// qualifiers.  This should never be used when type qualifiers
>    /// are meaningful.
> @@ -4207,7 +4193,56 @@ public:
>  ///   - the canonical type is VectorType(16, int)
>  class AttributedType : public Type, public llvm::FoldingSetNode {
>  public:
> -  using Kind = attr::Kind;
> +  // It is really silly to have yet another attribute-kind enum, but
> +  // clang::attr::Kind doesn't currently cover the pure type attrs.
> +  enum Kind {
> +    // Expression operand.
> +    attr_address_space,
> +    attr_regparm,
> +    attr_vector_size,
> +    attr_neon_vector_type,
> +    attr_neon_polyvector_type,
> +
> +    FirstExprOperandKind = attr_address_space,
> +    LastExprOperandKind = attr_neon_polyvector_type,
> +
> +    // Enumerated operand (string or keyword).
> +    attr_objc_gc,
> +    attr_objc_ownership,
> +    attr_pcs,
> +    attr_pcs_vfp,
> +
> +    FirstEnumOperandKind = attr_objc_gc,
> +    LastEnumOperandKind = attr_pcs_vfp,
> +
> +    // No operand.
> +    attr_noreturn,
> +    attr_nocf_check,
> +    attr_cdecl,
> +    attr_fastcall,
> +    attr_stdcall,
> +    attr_thiscall,
> +    attr_regcall,
> +    attr_pascal,
> +    attr_swiftcall,
> +    attr_vectorcall,
> +    attr_inteloclbicc,
> +    attr_ms_abi,
> +    attr_sysv_abi,
> +    attr_preserve_most,
> +    attr_preserve_all,
> +    attr_ptr32,
> +    attr_ptr64,
> +    attr_sptr,
> +    attr_uptr,
> +    attr_nonnull,
> +    attr_ns_returns_retained,
> +    attr_nullable,
> +    attr_null_unspecified,
> +    attr_objc_kindof,
> +    attr_objc_inert_unsafe_unretained,
> +    attr_lifetimebound,
> +  };
>
>  private:
>    friend class ASTContext; // ASTContext creates these
> @@ -4215,7 +4250,7 @@ private:
>    QualType ModifiedType;
>    QualType EquivalentType;
>
> -  AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
> +  AttributedType(QualType canon, Kind attrKind, QualType modified,
>                   QualType equivalent)
>        : Type(Attributed, canon, equivalent->isDependentType(),
>               equivalent->isInstantiationDependentType(),
> @@ -4264,13 +4299,13 @@ public:
>    static Kind getNullabilityAttrKind(NullabilityKind kind) {
>      switch (kind) {
>      case NullabilityKind::NonNull:
> -      return attr::TypeNonNull;
> +      return attr_nonnull;
>
>      case NullabilityKind::Nullable:
> -      return attr::TypeNullable;
> +      return attr_nullable;
>
>      case NullabilityKind::Unspecified:
> -      return attr::TypeNullUnspecified;
> +      return attr_null_unspecified;
>      }
>      llvm_unreachable("Unknown nullability kind.");
>    }
>
> Modified: cfe/trunk/include/clang/AST/TypeLoc.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/TypeLoc.h (original)
> +++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Aug 13 18:55:37 2018
> @@ -15,7 +15,6 @@
>  #ifndef LLVM_CLANG_AST_TYPELOC_H
>  #define LLVM_CLANG_AST_TYPELOC_H
>
> -#include "clang/AST/Attr.h"
>  #include "clang/AST/Decl.h"
>  #include "clang/AST/NestedNameSpecifier.h"
>  #include "clang/AST/TemplateBase.h"
> @@ -850,7 +849,16 @@ class SubstTemplateTypeParmPackTypeLoc :
>  };
>
>  struct AttributedLocInfo {
> -  const Attr *TypeAttr;
> +  union {
> +    Expr *ExprOperand;
> +
> +    /// A raw SourceLocation.
> +    unsigned EnumOperandLoc;
> +  };
> +
> +  SourceRange OperandParens;
> +
> +  SourceLocation AttrLoc;
>  };
>
>  /// Type source information for an attributed type.
> @@ -859,10 +867,24 @@ class AttributedTypeLoc : public Concret
>                                                   AttributedType,
>                                                   AttributedLocInfo> {
>  public:
> -  attr::Kind getAttrKind() const {
> +  AttributedType::Kind getAttrKind() const {
>      return getTypePtr()->getAttrKind();
>    }
>
> +  bool hasAttrExprOperand() const {
> +    return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
> +            getAttrKind() <= AttributedType::LastExprOperandKind);
> +  }
> +
> +  bool hasAttrEnumOperand() const {
> +    return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
> +            getAttrKind() <= AttributedType::LastEnumOperandKind);
> +  }
> +
> +  bool hasAttrOperand() const {
> +    return hasAttrExprOperand() || hasAttrEnumOperand();
> +  }
> +
>    bool isQualifier() const {
>      return getTypePtr()->isQualifier();
>    }
> @@ -875,16 +897,51 @@ public:
>      return getInnerTypeLoc();
>    }
>
> -  /// The type attribute.
> -  const Attr *getAttr() const {
> -    return getLocalData()->TypeAttr;
> -  }
> -  void setAttr(const Attr *A) {
> -    getLocalData()->TypeAttr = A;
> -  }
> -
> -  template<typename T> const T *getAttrAs() {
> -    return dyn_cast_or_null<T>(getAttr());
> +  /// The location of the attribute name, i.e.
> +  ///    __attribute__((regparm(1000)))
> +  ///                   ^~~~~~~
> +  SourceLocation getAttrNameLoc() const {
> +    return getLocalData()->AttrLoc;
> +  }
> +  void setAttrNameLoc(SourceLocation loc) {
> +    getLocalData()->AttrLoc = loc;
> +  }
> +
> +  /// The attribute's expression operand, if it has one.
> +  ///    void *cur_thread __attribute__((address_space(21)))
> +  ///                                                  ^~
> +  Expr *getAttrExprOperand() const {
> +    assert(hasAttrExprOperand());
> +    return getLocalData()->ExprOperand;
> +  }
> +  void setAttrExprOperand(Expr *e) {
> +    assert(hasAttrExprOperand());
> +    getLocalData()->ExprOperand = e;
> +  }
> +
> +  /// The location of the attribute's enumerated operand, if it has one.
> +  ///    void * __attribute__((objc_gc(weak)))
> +  ///                                  ^~~~
> +  SourceLocation getAttrEnumOperandLoc() const {
> +    assert(hasAttrEnumOperand());
> +    return
> SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
> +  }
> +  void setAttrEnumOperandLoc(SourceLocation loc) {
> +    assert(hasAttrEnumOperand());
> +    getLocalData()->EnumOperandLoc = loc.getRawEncoding();
> +  }
> +
> +  /// The location of the parentheses around the operand, if there is
> +  /// an operand.
> +  ///    void * __attribute__((objc_gc(weak)))
> +  ///                                 ^    ^
> +  SourceRange getAttrOperandParensRange() const {
> +    assert(hasAttrOperand());
> +    return getLocalData()->OperandParens;
> +  }
> +  void setAttrOperandParensRange(SourceRange range) {
> +    assert(hasAttrOperand());
> +    getLocalData()->OperandParens = range;
>    }
>
>    SourceRange getLocalSourceRange() const {
> @@ -897,11 +954,21 @@ public:
>      //    ^~        ~~
>      // That enclosure doesn't necessarily belong to a single attribute
>      // anyway.
> -    return getAttr() ? getAttr()->getRange() : SourceRange();
> +    SourceRange range(getAttrNameLoc());
> +    if (hasAttrOperand())
> +      range.setEnd(getAttrOperandParensRange().getEnd());
> +    return range;
>    }
>
>    void initializeLocal(ASTContext &Context, SourceLocation loc) {
> -    setAttr(nullptr);
> +    setAttrNameLoc(loc);
> +    if (hasAttrExprOperand()) {
> +      setAttrOperandParensRange(SourceRange(loc));
> +      setAttrExprOperand(nullptr);
> +    } else if (hasAttrEnumOperand()) {
> +      setAttrOperandParensRange(SourceRange(loc));
> +      setAttrEnumOperandLoc(loc);
> +    }
>    }
>
>    QualType getInnerType() const {
>
> Modified: cfe/trunk/include/clang/Basic/Attr.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Attr.td (original)
> +++ cfe/trunk/include/clang/Basic/Attr.td Mon Aug 13 18:55:37 2018
> @@ -494,7 +494,10 @@ class Attr {
>  }
>
>  /// A type attribute is not processed on a declaration or a statement.
> -class TypeAttr : Attr;
> +class TypeAttr : Attr {
> +  // By default, type attributes do not get an AST node.
> +  let ASTNode = 0;
> +}
>
>  /// A stmt attribute is not processed on a declaration or a type.
>  class StmtAttr : Attr;
> @@ -564,8 +567,6 @@ def AddressSpace : TypeAttr {
>    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 {
> @@ -1223,7 +1224,7 @@ def LayoutVersion : InheritableAttr, Tar
>    let Documentation = [LayoutVersionDocs];
>  }
>
> -def LifetimeBound : DeclOrTypeAttr {
> +def LifetimeBound : InheritableAttr {
>    let Spellings = [Clang<"lifetimebound", 0>];
>    let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter],
> ErrorDiag>;
>    let Documentation = [LifetimeBoundDocs];
> @@ -1326,16 +1327,12 @@ def NeonPolyVectorType : TypeAttr {
>    let Spellings = [Clang<"neon_polyvector_type">];
>    let Args = [IntArgument<"NumElements">];
>    let Documentation = [Undocumented];
> -  // Represented as VectorType instead.
> -  let ASTNode = 0;
>  }
>
>  def NeonVectorType : TypeAttr {
>    let Spellings = [Clang<"neon_vector_type">];
>    let Args = [IntArgument<"NumElements">];
>    let Documentation = [Undocumented];
> -  // Represented as VectorType instead.
> -  let ASTNode = 0;
>  }
>
>  def ReturnsTwice : InheritableAttr {
> @@ -1510,14 +1507,6 @@ def TypeNullUnspecified : TypeAttr {
>    let Documentation = [TypeNullUnspecifiedDocs];
>  }
>
> -// This is a marker used to indicate that an __unsafe_unretained
> qualifier was
> -// ignored because ARC is not enabled. The usual representation for this
> -// qualifier is as an ObjCOwnership attribute with Kind == "none".
> -def ObjCInertUnsafeUnretained : TypeAttr {
> -  let Spellings = [Keyword<"__unsafe_unretained">];
> -  let Documentation = [Undocumented];
> -}
> -
>  def ObjCKindOf : TypeAttr {
>    let Spellings = [Keyword<"__kindof">];
>    let Documentation = [Undocumented];
> @@ -1605,7 +1594,7 @@ def ObjCBridgeRelated : InheritableAttr
>    let Documentation = [Undocumented];
>  }
>
> -def NSReturnsRetained : DeclOrTypeAttr {
> +def NSReturnsRetained : InheritableAttr {
>    let Spellings = [Clang<"ns_returns_retained">];
>  //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
>    let Documentation = [Undocumented];
> @@ -1790,8 +1779,6 @@ def Regparm : TypeAttr {
>    let Spellings = [GCC<"regparm">];
>    let Args = [UnsignedArgument<"NumParams">];
>    let Documentation = [RegparmDocs];
> -  // Represented as part of the enclosing function type.
> -  let ASTNode = 0;
>  }
>
>  def ReqdWorkGroupSize : InheritableAttr {
> @@ -2080,9 +2067,10 @@ def ObjCGC : TypeAttr {
>    let Documentation = [Undocumented];
>  }
>
> -def ObjCOwnership : DeclOrTypeAttr {
> +def ObjCOwnership : InheritableAttr {
>    let Spellings = [Clang<"objc_ownership">];
>    let Args = [IdentifierArgument<"Kind">];
> +  let ASTNode = 0;
>    let Documentation = [Undocumented];
>  }
>
> @@ -2120,8 +2108,6 @@ def VectorSize : TypeAttr {
>    let Spellings = [GCC<"vector_size">];
>    let Args = [ExprArgument<"NumBytes">];
>    let Documentation = [Undocumented];
> -  // Represented as VectorType instead.
> -  let ASTNode = 0;
>  }
>
>  def VecTypeHint : InheritableAttr {
> @@ -2216,7 +2202,7 @@ def AnyX86NoCallerSavedRegisters : Inher
>    let Documentation = [AnyX86NoCallerSavedRegistersDocs];
>  }
>
> -def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{
> +def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr<TargetAnyX86>{
>    let Spellings = [GCC<"nocf_check">];
>    let Subjects = SubjectList<[FunctionLike]>;
>    let Documentation = [AnyX86NoCfCheckDocs];
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Aug 13 18:55:37 2018
> @@ -1435,6 +1435,8 @@ public:
>
>    TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
>    TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType
> FromTy);
> +  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType
> T,
> +                                               TypeSourceInfo
> *ReturnTypeInfo);
>
>    /// Package the given type and TSI into a ParsedType.
>    ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
> @@ -3376,6 +3378,30 @@ public:
>    /// Valid types should not have multiple attributes with different CCs.
>    const AttributedType *getCallingConvAttributedType(QualType T) const;
>
> +  /// Check whether a nullability type specifier can be added to the given
> +  /// type.
> +  ///
> +  /// \param type The type to which the nullability specifier will be
> +  /// added. On success, this type will be updated appropriately.
> +  ///
> +  /// \param nullability The nullability specifier to add.
> +  ///
> +  /// \param nullabilityLoc The location of the nullability specifier.
> +  ///
> +  /// \param isContextSensitive Whether this nullability specifier was
> +  /// written as a context-sensitive keyword (in an Objective-C
> +  /// method) or an Objective-C property attribute, rather than as an
> +  /// underscored type specifier.
> +  ///
> +  /// \param allowArrayTypes Whether to accept nullability specifiers on
> an
> +  /// array type (e.g., because it will decay to a pointer).
> +  ///
> +  /// \returns true if nullability cannot be applied, false otherwise.
> +  bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind
> nullability,
> +                                     SourceLocation nullabilityLoc,
> +                                     bool isContextSensitive,
> +                                     bool allowArrayTypes);
> +
>    /// Stmt attributes - this routine is the top level dispatcher.
>    StmtResult ProcessStmtAttributes(Stmt *Stmt,
>                                     const ParsedAttributesView &Attrs,
> @@ -8045,6 +8071,10 @@ public:
>                                 SourceLocation ProtocolRAngleLoc,
>                                 bool FailOnError = false);
>
> +  /// Check the application of the Objective-C '__kindof' qualifier to
> +  /// the given type.
> +  bool checkObjCKindOfType(QualType &type, SourceLocation loc);
> +
>    /// Ensure attributes are consistent with type.
>    /// \param [in, out] Attributes The attributes to check; they will
>    /// be modified to be consistent with \p PropertyTy.
>
> Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Aug 13 18:55:37
> 2018
> @@ -2245,9 +2245,6 @@ public:
>    CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record,
>                                   unsigned &Idx);
>
> -  /// Reads one attribute from the current stream position.
> -  Attr *ReadAttr(ModuleFile &M, const RecordData &Record, unsigned &Idx);
> -
>    /// Reads attributes from the current stream position.
>    void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs);
>
> @@ -2633,11 +2630,6 @@ public:
>      return ASTReader::ReadVersionTuple(Record, Idx);
>    }
>
> -  /// Reads one attribute from the current stream position, advancing Idx.
> -  Attr *readAttr() {
> -    return Reader->ReadAttr(*F, Record, Idx);
> -  }
> -
>    /// Reads attributes from the current stream position, advancing Idx.
>    void readAttributes(AttrVec &Attrs) {
>      return Reader->ReadAttributes(*this, Attrs);
>
> Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon Aug 13 18:55:37
> 2018
> @@ -955,9 +955,6 @@ public:
>      return Writer->AddVersionTuple(Version, *Record);
>    }
>
> -  // Emit an attribute.
> -  void AddAttr(const Attr *A);
> -
>    /// Emit a list of attributes.
>    void AddAttributes(ArrayRef<const Attr*> Attrs);
>  };
>
> Modified: cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp (original)
> +++ cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp Mon Aug 13 18:55:37 2018
> @@ -81,11 +81,10 @@ public:
>    }
>
>    bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) {
> -    auto *OwnershipAttr = TL.getAttrAs<ObjCOwnershipAttr>();
> -    if (!OwnershipAttr)
> +    if (TL.getAttrKind() != AttributedType::attr_objc_ownership)
>        return false;
>
> -    SourceLocation Loc = OwnershipAttr->getLocation();
> +    SourceLocation Loc = TL.getAttrNameLoc();
>      unsigned RawLoc = Loc.getRawEncoding();
>      if (MigrateCtx.AttrSet.count(RawLoc))
>        return true;
> @@ -94,7 +93,13 @@ public:
>      SourceManager &SM = Ctx.getSourceManager();
>      if (Loc.isMacroID())
>        Loc = SM.getImmediateExpansionRange(Loc).getBegin();
> -    StringRef Spell = OwnershipAttr->getKind()->getName();
> +    SmallString<32> Buf;
> +    bool Invalid = false;
> +    StringRef Spell = Lexer::getSpelling(
> +
> SM.getSpellingLoc(TL.getAttrEnumOperandLoc()),
> +                                  Buf, SM, Ctx.getLangOpts(), &Invalid);
> +    if (Invalid)
> +      return false;
>      MigrationContext::GCAttrOccurrence::AttrKind Kind;
>      if (Spell == "strong")
>        Kind = MigrationContext::GCAttrOccurrence::Strong;
> @@ -279,7 +284,7 @@ static void checkAllAtProps(MigrationCon
>    }
>
>    for (unsigned i = 0, e = ATLs.size(); i != e; ++i) {
> -    SourceLocation Loc = ATLs[i].first.getAttr()->getLocation();
> +    SourceLocation Loc = ATLs[i].first.getAttrNameLoc();
>      if (Loc.isMacroID())
>        Loc = MigrateCtx.Pass.Ctx.getSourceManager()
>                  .getImmediateExpansionRange(Loc)
>
> Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
> +++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Mon Aug 13 18:55:37 2018
> @@ -359,7 +359,7 @@ MigrationContext::~MigrationContext() {
>  bool MigrationContext::isGCOwnedNonObjC(QualType T) {
>    while (!T.isNull()) {
>      if (const AttributedType *AttrT = T->getAs<AttributedType>()) {
> -      if (AttrT->getAttrKind() == attr::ObjCOwnership)
> +      if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership)
>          return !AttrT->getModifiedType()->isObjCRetainableType();
>      }
>
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 13 18:55:37 2018
> @@ -3876,7 +3876,7 @@ QualType ASTContext::getEnumType(const E
>    return QualType(newType, 0);
>  }
>
> -QualType ASTContext::getAttributedType(attr::Kind attrKind,
> +QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
>                                         QualType modifiedType,
>                                         QualType equivalentType) {
>    llvm::FoldingSetNodeID id;
>
> Modified: cfe/trunk/lib/AST/Type.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/Type.cpp (original)
> +++ cfe/trunk/lib/AST/Type.cpp Mon Aug 13 18:55:37 2018
> @@ -592,6 +592,28 @@ bool Type::isObjCClassOrClassKindOfType(
>    return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType();
>  }
>
> +/// Was this type written with the special inert-in-MRC
> __unsafe_unretained
> +/// qualifier?
> +///
> +/// This approximates the answer to the following question: if this
> +/// translation unit were compiled in ARC, would this type be qualified
> +/// with __unsafe_unretained?
> +bool Type::isObjCInertUnsafeUnretainedType() const {
> +  const Type *cur = this;
> +  while (true) {
> +    if (const auto attributed = dyn_cast<AttributedType>(cur)) {
> +      if (attributed->getAttrKind() ==
> +            AttributedType::attr_objc_inert_unsafe_unretained)
> +        return true;
> +    }
> +
> +    // Single-step desugar until we run out of sugar.
> +    QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType();
> +    if (next.getTypePtr() == cur) return false;
> +    cur = next.getTypePtr();
> +  }
> +}
> +
>  ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D,
>                                       QualType can,
>                                       ArrayRef<ObjCProtocolDecl *>
> protocols)
> @@ -1619,16 +1641,6 @@ TagDecl *Type::getAsTagDecl() const {
>    return nullptr;
>  }
>
> -bool Type::hasAttr(attr::Kind AK) const {
> -  const Type *Cur = this;
> -  while (const auto *AT = Cur->getAs<AttributedType>()) {
> -    if (AT->getAttrKind() == AK)
> -      return true;
> -    Cur = AT->getEquivalentType().getTypePtr();
> -  }
> -  return false;
> -}
> -
>  namespace {
>
>    class GetContainedDeducedTypeVisitor :
> @@ -3155,58 +3167,105 @@ bool RecordType::hasConstFields() const
>  }
>
>  bool AttributedType::isQualifier() const {
> -  // FIXME: Generate this with TableGen.
>    switch (getAttrKind()) {
>    // These are type qualifiers in the traditional C sense: they annotate
>    // something about a specific value/variable of a type.  (They aren't
>    // always part of the canonical type, though.)
> -  case attr::ObjCGC:
> -  case attr::ObjCOwnership:
> -  case attr::ObjCInertUnsafeUnretained:
> -  case attr::TypeNonNull:
> -  case attr::TypeNullable:
> -  case attr::TypeNullUnspecified:
> -  case attr::LifetimeBound:
> -    return true;
> -
> -  // All other type attributes aren't qualifiers; they rewrite the
> modified
> -  // type to be a semantically different type.
> -  default:
> +  case AttributedType::attr_address_space:
> +  case AttributedType::attr_objc_gc:
> +  case AttributedType::attr_objc_ownership:
> +  case AttributedType::attr_objc_inert_unsafe_unretained:
> +  case AttributedType::attr_nonnull:
> +  case AttributedType::attr_nullable:
> +  case AttributedType::attr_null_unspecified:
> +  case AttributedType::attr_lifetimebound:
> +    return true;
> +
> +  // These aren't qualifiers; they rewrite the modified type to be a
> +  // semantically different type.
> +  case AttributedType::attr_regparm:
> +  case AttributedType::attr_vector_size:
> +  case AttributedType::attr_neon_vector_type:
> +  case AttributedType::attr_neon_polyvector_type:
> +  case AttributedType::attr_pcs:
> +  case AttributedType::attr_pcs_vfp:
> +  case AttributedType::attr_noreturn:
> +  case AttributedType::attr_cdecl:
> +  case AttributedType::attr_fastcall:
> +  case AttributedType::attr_stdcall:
> +  case AttributedType::attr_thiscall:
> +  case AttributedType::attr_regcall:
> +  case AttributedType::attr_pascal:
> +  case AttributedType::attr_swiftcall:
> +  case AttributedType::attr_vectorcall:
> +  case AttributedType::attr_inteloclbicc:
> +  case AttributedType::attr_preserve_most:
> +  case AttributedType::attr_preserve_all:
> +  case AttributedType::attr_ms_abi:
> +  case AttributedType::attr_sysv_abi:
> +  case AttributedType::attr_ptr32:
> +  case AttributedType::attr_ptr64:
> +  case AttributedType::attr_sptr:
> +  case AttributedType::attr_uptr:
> +  case AttributedType::attr_objc_kindof:
> +  case AttributedType::attr_ns_returns_retained:
> +  case AttributedType::attr_nocf_check:
>      return false;
>    }
> +  llvm_unreachable("bad attributed type kind");
>  }
>
>  bool AttributedType::isMSTypeSpec() const {
> -  // FIXME: Generate this with TableGen?
>    switch (getAttrKind()) {
> -  default: return false;
> -  case attr::Ptr32:
> -  case attr::Ptr64:
> -  case attr::SPtr:
> -  case attr::UPtr:
> +  default:  return false;
> +  case attr_ptr32:
> +  case attr_ptr64:
> +  case attr_sptr:
> +  case attr_uptr:
>      return true;
>    }
>    llvm_unreachable("invalid attr kind");
>  }
>
>  bool AttributedType::isCallingConv() const {
> -  // FIXME: Generate this with TableGen.
>    switch (getAttrKind()) {
> -  default: return false;
> -  case attr::Pcs:
> -  case attr::CDecl:
> -  case attr::FastCall:
> -  case attr::StdCall:
> -  case attr::ThisCall:
> -  case attr::RegCall:
> -  case attr::SwiftCall:
> -  case attr::VectorCall:
> -  case attr::Pascal:
> -  case attr::MSABI:
> -  case attr::SysVABI:
> -  case attr::IntelOclBicc:
> -  case attr::PreserveMost:
> -  case attr::PreserveAll:
> +  case attr_ptr32:
> +  case attr_ptr64:
> +  case attr_sptr:
> +  case attr_uptr:
> +  case attr_address_space:
> +  case attr_regparm:
> +  case attr_vector_size:
> +  case attr_neon_vector_type:
> +  case attr_neon_polyvector_type:
> +  case attr_objc_gc:
> +  case attr_objc_ownership:
> +  case attr_objc_inert_unsafe_unretained:
> +  case attr_noreturn:
> +  case attr_nonnull:
> +  case attr_ns_returns_retained:
> +  case attr_nullable:
> +  case attr_null_unspecified:
> +  case attr_objc_kindof:
> +  case attr_nocf_check:
> +  case attr_lifetimebound:
> +    return false;
> +
> +  case attr_pcs:
> +  case attr_pcs_vfp:
> +  case attr_cdecl:
> +  case attr_fastcall:
> +  case attr_stdcall:
> +  case attr_thiscall:
> +  case attr_regcall:
> +  case attr_swiftcall:
> +  case attr_vectorcall:
> +  case attr_pascal:
> +  case attr_ms_abi:
> +  case attr_sysv_abi:
> +  case attr_inteloclbicc:
> +  case attr_preserve_most:
> +  case attr_preserve_all:
>      return true;
>    }
>    llvm_unreachable("invalid attr kind");
> @@ -3649,18 +3708,23 @@ LinkageInfo Type::getLinkageAndVisibilit
>    return LinkageComputer{}.getTypeLinkageAndVisibility(this);
>  }
>
> -Optional<NullabilityKind>
> -Type::getNullability(const ASTContext &Context) const {
> -  QualType Type(this, 0);
> -  while (const auto *AT = Type->getAs<AttributedType>()) {
> +Optional<NullabilityKind> Type::getNullability(const ASTContext &context)
> const {
> +  QualType type(this, 0);
> +  do {
>      // Check whether this is an attributed type with nullability
>      // information.
> -    if (auto Nullability = AT->getImmediateNullability())
> -      return Nullability;
> +    if (auto attributed = dyn_cast<AttributedType>(type.getTypePtr())) {
> +      if (auto nullability = attributed->getImmediateNullability())
> +        return nullability;
> +    }
>
> -    Type = AT->getEquivalentType();
> -  }
> -  return None;
> +    // Desugar the type. If desugaring does nothing, we're done.
> +    QualType desugared = type.getSingleStepDesugaredType(context);
> +    if (desugared.getTypePtr() == type.getTypePtr())
> +      return None;
> +
> +    type = desugared;
> +  } while (true);
>  }
>
>  bool Type::canHaveNullability(bool ResultIfUnknown) const {
> @@ -3773,13 +3837,12 @@ bool Type::canHaveNullability(bool Resul
>    llvm_unreachable("bad type kind!");
>  }
>
> -llvm::Optional<NullabilityKind>
> -AttributedType::getImmediateNullability() const {
> -  if (getAttrKind() == attr::TypeNonNull)
> +llvm::Optional<NullabilityKind> AttributedType::getImmediateNullability()
> const {
> +  if (getAttrKind() == AttributedType::attr_nonnull)
>      return NullabilityKind::NonNull;
> -  if (getAttrKind() == attr::TypeNullable)
> +  if (getAttrKind() == AttributedType::attr_nullable)
>      return NullabilityKind::Nullable;
> -  if (getAttrKind() == attr::TypeNullUnspecified)
> +  if (getAttrKind() == AttributedType::attr_null_unspecified)
>      return NullabilityKind::Unspecified;
>    return None;
>  }
>
> Modified: cfe/trunk/lib/AST/TypeLoc.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/TypeLoc.cpp (original)
> +++ cfe/trunk/lib/AST/TypeLoc.cpp Mon Aug 13 18:55:37 2018
> @@ -404,11 +404,11 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLo
>  }
>
>  SourceLocation TypeLoc::findNullabilityLoc() const {
> -  if (auto ATL = getAs<AttributedTypeLoc>()) {
> -    const Attr *A = ATL.getAttr();
> -    if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||
> -              isa<TypeNullUnspecifiedAttr>(A)))
> -      return A->getLocation();
> +  if (auto attributedLoc = getAs<AttributedTypeLoc>()) {
> +    if (attributedLoc.getAttrKind() == AttributedType::attr_nullable ||
> +        attributedLoc.getAttrKind() == AttributedType::attr_nonnull ||
> +        attributedLoc.getAttrKind() ==
> AttributedType::attr_null_unspecified)
> +      return attributedLoc.getAttrNameLoc();
>    }
>
>    return {};
>
> Modified: cfe/trunk/lib/AST/TypePrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/TypePrinter.cpp (original)
> +++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Aug 13 18:55:37 2018
> @@ -1354,14 +1354,12 @@ void TypePrinter::printPackExpansionAfte
>
>  void TypePrinter::printAttributedBefore(const AttributedType *T,
>                                          raw_ostream &OS) {
> -  // FIXME: Generate this with TableGen.
> -
>    // Prefer the macro forms of the GC and ownership qualifiers.
> -  if (T->getAttrKind() == attr::ObjCGC ||
> -      T->getAttrKind() == attr::ObjCOwnership)
> +  if (T->getAttrKind() == AttributedType::attr_objc_gc ||
> +      T->getAttrKind() == AttributedType::attr_objc_ownership)
>      return printBefore(T->getEquivalentType(), OS);
>
> -  if (T->getAttrKind() == attr::ObjCKindOf)
> +  if (T->getAttrKind() == AttributedType::attr_objc_kindof)
>      OS << "__kindof ";
>
>    printBefore(T->getModifiedType(), OS);
> @@ -1369,21 +1367,23 @@ void TypePrinter::printAttributedBefore(
>    if (T->isMSTypeSpec()) {
>      switch (T->getAttrKind()) {
>      default: return;
> -    case attr::Ptr32: OS << " __ptr32"; break;
> -    case attr::Ptr64: OS << " __ptr64"; break;
> -    case attr::SPtr: OS << " __sptr"; break;
> -    case attr::UPtr: OS << " __uptr"; break;
> +    case AttributedType::attr_ptr32: OS << " __ptr32"; break;
> +    case AttributedType::attr_ptr64: OS << " __ptr64"; break;
> +    case AttributedType::attr_sptr: OS << " __sptr"; break;
> +    case AttributedType::attr_uptr: OS << " __uptr"; break;
>      }
>      spaceBeforePlaceHolder(OS);
>    }
>
>    // Print nullability type specifiers.
> -  if (T->getImmediateNullability()) {
> -    if (T->getAttrKind() == attr::TypeNonNull)
> +  if (T->getAttrKind() == AttributedType::attr_nonnull ||
> +      T->getAttrKind() == AttributedType::attr_nullable ||
> +      T->getAttrKind() == AttributedType::attr_null_unspecified) {
> +    if (T->getAttrKind() == AttributedType::attr_nonnull)
>        OS << " _Nonnull";
> -    else if (T->getAttrKind() == attr::TypeNullable)
> +    else if (T->getAttrKind() == AttributedType::attr_nullable)
>        OS << " _Nullable";
> -    else if (T->getAttrKind() == attr::TypeNullUnspecified)
> +    else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
>        OS << " _Null_unspecified";
>      else
>        llvm_unreachable("unhandled nullability");
> @@ -1393,11 +1393,9 @@ void TypePrinter::printAttributedBefore(
>
>  void TypePrinter::printAttributedAfter(const AttributedType *T,
>                                         raw_ostream &OS) {
> -  // FIXME: Generate this with TableGen.
> -
>    // Prefer the macro forms of the GC and ownership qualifiers.
> -  if (T->getAttrKind() == attr::ObjCGC ||
> -      T->getAttrKind() == attr::ObjCOwnership)
> +  if (T->getAttrKind() == AttributedType::attr_objc_gc ||
> +      T->getAttrKind() == AttributedType::attr_objc_ownership)
>      return printAfter(T->getEquivalentType(), OS);
>
>    // If this is a calling convention attribute, don't print the implicit
> CC from
> @@ -1408,74 +1406,107 @@ void TypePrinter::printAttributedAfter(c
>
>    // Some attributes are printed as qualifiers before the type, so we have
>    // nothing left to do.
> -  if (T->getAttrKind() == attr::ObjCKindOf ||
> -      T->isMSTypeSpec() || T->getImmediateNullability())
> +  if (T->getAttrKind() == AttributedType::attr_objc_kindof ||
> +      T->isMSTypeSpec() ||
> +      T->getAttrKind() == AttributedType::attr_nonnull ||
> +      T->getAttrKind() == AttributedType::attr_nullable ||
> +      T->getAttrKind() == AttributedType::attr_null_unspecified)
>      return;
>
>    // Don't print the inert __unsafe_unretained attribute at all.
> -  if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
> +  if (T->getAttrKind() ==
> AttributedType::attr_objc_inert_unsafe_unretained)
>      return;
>
>    // Don't print ns_returns_retained unless it had an effect.
> -  if (T->getAttrKind() == attr::NSReturnsRetained &&
> +  if (T->getAttrKind() == AttributedType::attr_ns_returns_retained &&
>        !T->getEquivalentType()->castAs<FunctionType>()
>                               ->getExtInfo().getProducesResult())
>      return;
>
> -  if (T->getAttrKind() == attr::LifetimeBound) {
> +  if (T->getAttrKind() == AttributedType::attr_lifetimebound) {
>      OS << " [[clang::lifetimebound]]";
>      return;
>    }
>
>    OS << " __attribute__((";
>    switch (T->getAttrKind()) {
> -#define TYPE_ATTR(NAME)
> -#define DECL_OR_TYPE_ATTR(NAME)
> -#define ATTR(NAME) case attr::NAME:
> -#include "clang/Basic/AttrList.inc"
> -    llvm_unreachable("non-type attribute attached to type");
> -
> -  case attr::OpenCLPrivateAddressSpace:
> -  case attr::OpenCLGlobalAddressSpace:
> -  case attr::OpenCLLocalAddressSpace:
> -  case attr::OpenCLConstantAddressSpace:
> -  case attr::OpenCLGenericAddressSpace:
> -    // FIXME: Update printAttributedBefore to print these once we generate
> -    // AttributedType nodes for them.
> -    break;
> -
> -  case attr::LifetimeBound:
> -  case attr::TypeNonNull:
> -  case attr::TypeNullable:
> -  case attr::TypeNullUnspecified:
> -  case attr::ObjCGC:
> -  case attr::ObjCInertUnsafeUnretained:
> -  case attr::ObjCKindOf:
> -  case attr::ObjCOwnership:
> -  case attr::Ptr32:
> -  case attr::Ptr64:
> -  case attr::SPtr:
> -  case attr::UPtr:
> +  case AttributedType::attr_lifetimebound:
> +  case AttributedType::attr_nonnull:
> +  case AttributedType::attr_nullable:
> +  case AttributedType::attr_null_unspecified:
> +  case AttributedType::attr_objc_gc:
> +  case AttributedType::attr_objc_inert_unsafe_unretained:
> +  case AttributedType::attr_objc_kindof:
> +  case AttributedType::attr_objc_ownership:
> +  case AttributedType::attr_ptr32:
> +  case AttributedType::attr_ptr64:
> +  case AttributedType::attr_sptr:
> +  case AttributedType::attr_uptr:
>      llvm_unreachable("This attribute should have been handled already");
>
> -  case attr::NSReturnsRetained:
> +  case AttributedType::attr_address_space:
> +    OS << "address_space(";
> +    // FIXME: printing the raw LangAS value is wrong. This should probably
> +    // use the same code as Qualifiers::print()
> +    OS << (unsigned)T->getEquivalentType().getAddressSpace();
> +    OS << ')';
> +    break;
> +
> +  case AttributedType::attr_vector_size:
> +    OS << "__vector_size__(";
> +    if (const auto *vector = T->getEquivalentType()->getAs<VectorType>())
> {
> +      OS << vector->getNumElements();
> +      OS << " * sizeof(";
> +      print(vector->getElementType(), OS, StringRef());
> +      OS << ')';
> +    }
> +    OS << ')';
> +    break;
> +
> +  case AttributedType::attr_neon_vector_type:
> +  case AttributedType::attr_neon_polyvector_type: {
> +    if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
> +      OS << "neon_vector_type(";
> +    else
> +      OS << "neon_polyvector_type(";
> +    const auto *vector = T->getEquivalentType()->getAs<VectorType>();
> +    OS << vector->getNumElements();
> +    OS << ')';
> +    break;
> +  }
> +
> +  case AttributedType::attr_regparm: {
> +    // FIXME: When Sema learns to form this AttributedType, avoid
> printing the
> +    // attribute again in printFunctionProtoAfter.
> +    OS << "regparm(";
> +    QualType t = T->getEquivalentType();
> +    while (!t->isFunctionType())
> +      t = t->getPointeeType();
> +    OS << t->getAs<FunctionType>()->getRegParmType();
> +    OS << ')';
> +    break;
> +  }
> +
> +  case AttributedType::attr_ns_returns_retained:
>      OS << "ns_returns_retained";
>      break;
>
>    // FIXME: When Sema learns to form this AttributedType, avoid printing
> the
>    // attribute again in printFunctionProtoAfter.
> -  case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
> -  case attr::CDecl: OS << "cdecl"; break;
> -  case attr::FastCall: OS << "fastcall"; break;
> -  case attr::StdCall: OS << "stdcall"; break;
> -  case attr::ThisCall: OS << "thiscall"; break;
> -  case attr::SwiftCall: OS << "swiftcall"; break;
> -  case attr::VectorCall: OS << "vectorcall"; break;
> -  case attr::Pascal: OS << "pascal"; break;
> -  case attr::MSABI: OS << "ms_abi"; break;
> -  case attr::SysVABI: OS << "sysv_abi"; break;
> -  case attr::RegCall: OS << "regcall"; break;
> -  case attr::Pcs: {
> +  case AttributedType::attr_noreturn: OS << "noreturn"; break;
> +  case AttributedType::attr_nocf_check: OS << "nocf_check"; break;
> +  case AttributedType::attr_cdecl: OS << "cdecl"; break;
> +  case AttributedType::attr_fastcall: OS << "fastcall"; break;
> +  case AttributedType::attr_stdcall: OS << "stdcall"; break;
> +  case AttributedType::attr_thiscall: OS << "thiscall"; break;
> +  case AttributedType::attr_swiftcall: OS << "swiftcall"; break;
> +  case AttributedType::attr_vectorcall: OS << "vectorcall"; break;
> +  case AttributedType::attr_pascal: OS << "pascal"; break;
> +  case AttributedType::attr_ms_abi: OS << "ms_abi"; break;
> +  case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break;
> +  case AttributedType::attr_regcall: OS << "regcall"; break;
> +  case AttributedType::attr_pcs:
> +  case AttributedType::attr_pcs_vfp: {
>      OS << "pcs(";
>     QualType t = T->getEquivalentType();
>     while (!t->isFunctionType())
> @@ -1486,12 +1517,12 @@ void TypePrinter::printAttributedAfter(c
>     break;
>    }
>
> -  case attr::IntelOclBicc: OS << "inteloclbicc"; break;
> -  case attr::PreserveMost:
> +  case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;
> +  case AttributedType::attr_preserve_most:
>      OS << "preserve_most";
>      break;
>
> -  case attr::PreserveAll:
> +  case AttributedType::attr_preserve_all:
>      OS << "preserve_all";
>      break;
>    }
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 13 18:55:37 2018
> @@ -5999,14 +5999,14 @@ static void checkAttributesAfterMerging(
>        // The [[lifetimebound]] attribute can be applied to the implicit
> object
>        // parameter of a non-static member function (other than a ctor or
> dtor)
>        // by applying it to the function type.
> -      if (const auto *A = ATL.getAttrAs<LifetimeBoundAttr>()) {
> +      if (ATL.getAttrKind() == AttributedType::attr_lifetimebound) {
>          const auto *MD = dyn_cast<CXXMethodDecl>(FD);
>          if (!MD || MD->isStatic()) {
> -          S.Diag(A->getLocation(),
> diag::err_lifetimebound_no_object_param)
> -              << !MD << A->getRange();
> +          S.Diag(ATL.getAttrNameLoc(),
> diag::err_lifetimebound_no_object_param)
> +              << !MD << ATL.getLocalSourceRange();
>          } else if (isa<CXXConstructorDecl>(MD) ||
> isa<CXXDestructorDecl>(MD)) {
> -          S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor)
> -              << isa<CXXDestructorDecl>(MD) << A->getRange();
> +          S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_ctor_dtor)
> +              << isa<CXXDestructorDecl>(MD) << ATL.getLocalSourceRange();
>          }
>        }
>      }
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 13 18:55:37 2018
> @@ -14658,15 +14658,15 @@ static bool captureInBlock(BlockScopeInf
>    // Warn about implicitly autoreleasing indirect parameters captured by
> blocks.
>    if (const auto *PT = CaptureType->getAs<PointerType>()) {
>      // This function finds out whether there is an AttributedType of kind
> -    // attr::ObjCOwnership in Ty. The existence of AttributedType of kind
> -    // attr::ObjCOwnership implies __autoreleasing was explicitly
> specified
> +    // attr_objc_ownership in Ty. The existence of AttributedType of kind
> +    // attr_objc_ownership implies __autoreleasing was explicitly
> specified
>      // rather than being added implicitly by the compiler.
>      auto IsObjCOwnershipAttributedType = [](QualType Ty) {
>        while (const auto *AttrTy = Ty->getAs<AttributedType>()) {
> -        if (AttrTy->getAttrKind() == attr::ObjCOwnership)
> +        if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership)
>            return true;
>
> -        // Peel off AttributedTypes that are not of kind ObjCOwnership.
> +        // Peel off AttributedTypes that are not of kind objc_ownership.
>          Ty = AttrTy->getModifiedType();
>        }
>
>
> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Aug 13 18:55:37 2018
> @@ -6360,7 +6360,7 @@ static bool implicitObjectParamIsLifetim
>    for (TypeLoc TL = TSI->getTypeLoc();
>         (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
>         TL = ATL.getModifiedLoc()) {
> -    if (ATL.getAttrAs<LifetimeBoundAttr>())
> +    if (ATL.getAttrKind() == AttributedType::attr_lifetimebound)
>        return true;
>    }
>    return false;
>
> Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Mon Aug 13 18:55:37 2018
> @@ -2384,7 +2384,7 @@ void Sema::ProcessPropertyDecl(ObjCPrope
>        QualType modifiedTy = resultTy;
>        if (auto nullability =
> AttributedType::stripOuterNullability(modifiedTy)) {
>          if (*nullability == NullabilityKind::Unspecified)
> -          resultTy = Context.getAttributedType(attr::TypeNonNull,
> +          resultTy =
> Context.getAttributedType(AttributedType::attr_nonnull,
>                                                 modifiedTy, modifiedTy);
>        }
>      }
> @@ -2458,7 +2458,7 @@ void Sema::ProcessPropertyDecl(ObjCPrope
>          QualType modifiedTy = paramTy;
>          if (auto nullability =
> AttributedType::stripOuterNullability(modifiedTy)){
>            if (*nullability == NullabilityKind::Unspecified)
> -            paramTy = Context.getAttributedType(attr::TypeNullable,
> +            paramTy =
> Context.getAttributedType(AttributedType::attr_nullable,
>                                                  modifiedTy, modifiedTy);
>          }
>        }
>
> Modified: cfe/trunk/lib/Sema/SemaType.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=339638&r1=339637&r2=339638&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Aug 13 18:55:37 2018
> @@ -172,16 +172,6 @@ namespace {
>      /// processing is complete.
>      SmallVector<ParsedAttr *, 2> ignoredTypeAttrs;
>
> -    /// Attributes corresponding to AttributedTypeLocs that we have not
> yet
> -    /// populated.
> -    // FIXME: The two-phase mechanism by which we construct Types and fill
> -    // their TypeLocs makes it hard to correctly assign these. We keep the
> -    // attributes in creation order as an attempt to make them line up
> -    // properly.
> -    using TypeAttrPair = std::pair<const AttributedType*, const Attr*>;
> -    SmallVector<TypeAttrPair, 8> AttrsForTypes;
> -    bool AttrsForTypesSorted = true;
> -
>    public:
>      TypeProcessingState(Sema &sema, Declarator &declarator)
>        : sema(sema), declarator(declarator),
> @@ -240,43 +230,6 @@ namespace {
>          diagnoseBadTypeAttribute(getSema(), *Attr, type);
>      }
>
> -    /// Get an attributed type for the given attribute, and remember the
> Attr
> -    /// object so that we can attach it to the AttributedTypeLoc.
> -    QualType getAttributedType(Attr *A, QualType ModifiedType,
> -                               QualType EquivType) {
> -      QualType T =
> -          sema.Context.getAttributedType(A->getKind(), ModifiedType,
> EquivType);
> -      AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
> -      AttrsForTypesSorted = false;
> -      return T;
> -    }
> -
> -    /// Extract and remove the Attr* for a given attributed type.
> -    const Attr *takeAttrForAttributedType(const AttributedType *AT) {
> -      if (!AttrsForTypesSorted) {
> -        std::stable_sort(AttrsForTypes.begin(), AttrsForTypes.end(),
> -                         [](const TypeAttrPair &A, const TypeAttrPair &B)
> {
> -                           return A.first < B.first;
> -                         });
> -        AttrsForTypesSorted = true;
> -      }
> -
> -      // FIXME: This is quadratic if we have lots of reuses of the same
> -      // attributed type.
> -      for (auto It = std::partition_point(
> -               AttrsForTypes.begin(), AttrsForTypes.end(),
> -               [=](const TypeAttrPair &A) { return A.first < AT; });
> -           It != AttrsForTypes.end() && It->first == AT; ++It) {
> -        if (It->second) {
> -          const Attr *Result = It->second;
> -          It->second = nullptr;
> -          return Result;
> -        }
> -      }
> -
> -      llvm_unreachable("no Attr* for AttributedType*");
> -    }
> -
>      ~TypeProcessingState() {
>        if (trivial) return;
>
> @@ -3879,32 +3832,6 @@ static bool hasOuterPointerLikeChunk(con
>    return false;
>  }
>
> -template<typename AttrT>
> -static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &Attr) {
> -  Attr.setUsedAsTypeAttr();
> -  return ::new (Ctx)
> -      AttrT(Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex());
> -}
> -
> -static Attr *createNullabilityAttr(ASTContext &Ctx, ParsedAttr &Attr,
> -                                   NullabilityKind NK) {
> -  switch (NK) {
> -  case NullabilityKind::NonNull:
> -    return createSimpleAttr<TypeNonNullAttr>(Ctx, Attr);
> -
> -  case NullabilityKind::Nullable:
> -    return createSimpleAttr<TypeNullableAttr>(Ctx, Attr);
> -
> -  case NullabilityKind::Unspecified:
> -    return createSimpleAttr<TypeNullUnspecifiedAttr>(Ctx, Attr);
> -  }
> -  llvm_unreachable("unknown NullabilityKind");
> -}
> -
> -static TypeSourceInfo *
> -GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
> -                               QualType T, TypeSourceInfo
> *ReturnTypeInfo);
> -
>  static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState
> &state,
>                                                  QualType declSpecType,
>                                                  TypeSourceInfo *TInfo) {
> @@ -4257,8 +4184,9 @@ static TypeSourceInfo *GetFullTypeForDec
>                  pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),
>                  D.getDeclSpec().getEndLoc(),
>                  D.getMutableDeclSpec().getAttributes())) {
> -          T = state.getAttributedType(
> -              createNullabilityAttr(Context, *attr, *inferNullability),
> T, T);
> +          T = Context.getAttributedType(
> +
> AttributedType::getNullabilityAttrKind(*inferNullability),T,T);
> +          attr->setUsedAsTypeAttr();
>          }
>        }
>      }
> @@ -5097,7 +5025,7 @@ static TypeSourceInfo *GetFullTypeForDec
>    if (D.isInvalidType())
>      return Context.getTrivialTypeSourceInfo(T);
>
> -  return GetTypeSourceInfoForDeclarator(state, T, TInfo);
> +  return S.GetTypeSourceInfoForDeclarator(D, T, TInfo);
>  }
>
>  /// GetTypeForDeclarator - Convert the type for the specified
> @@ -5233,25 +5161,131 @@ TypeSourceInfo *Sema::GetTypeForDeclarat
>    return GetFullTypeForDeclarator(state, declSpecTy, ReturnTypeInfo);
>  }
>
> +/// Map an AttributedType::Kind to an ParsedAttr::Kind.
> +static ParsedAttr::Kind getAttrListKind(AttributedType::Kind kind) {
> +  switch (kind) {
> +  case AttributedType::attr_address_space:
> +    return ParsedAttr::AT_AddressSpace;
> +  case AttributedType::attr_regparm:
> +    return ParsedAttr::AT_Regparm;
> +  case AttributedType::attr_vector_size:
> +    return ParsedAttr::AT_VectorSize;
> +  case AttributedType::attr_neon_vector_type:
> +    return ParsedAttr::AT_NeonVectorType;
> +  case AttributedType::attr_neon_polyvector_type:
> +    return ParsedAttr::AT_NeonPolyVectorType;
> +  case AttributedType::attr_objc_gc:
> +    return ParsedAttr::AT_ObjCGC;
> +  case AttributedType::attr_objc_ownership:
> +  case AttributedType::attr_objc_inert_unsafe_unretained:
> +    return ParsedAttr::AT_ObjCOwnership;
> +  case AttributedType::attr_noreturn:
> +    return ParsedAttr::AT_NoReturn;
> +  case AttributedType::attr_nocf_check:
> +    return ParsedAttr::AT_AnyX86NoCfCheck;
> +  case AttributedType::attr_cdecl:
> +    return ParsedAttr::AT_CDecl;
> +  case AttributedType::attr_fastcall:
> +    return ParsedAttr::AT_FastCall;
> +  case AttributedType::attr_stdcall:
> +    return ParsedAttr::AT_StdCall;
> +  case AttributedType::attr_thiscall:
> +    return ParsedAttr::AT_ThisCall;
> +  case AttributedType::attr_regcall:
> +    return ParsedAttr::AT_RegCall;
> +  case AttributedType::attr_pascal:
> +    return ParsedAttr::AT_Pascal;
> +  case AttributedType::attr_swiftcall:
> +    return ParsedAttr::AT_SwiftCall;
> +  case AttributedType::attr_vectorcall:
> +    return ParsedAttr::AT_VectorCall;
> +  case AttributedType::attr_pcs:
> +  case AttributedType::attr_pcs_vfp:
> +    return ParsedAttr::AT_Pcs;
> +  case AttributedType::attr_inteloclbicc:
> +    return ParsedAttr::AT_IntelOclBicc;
> +  case AttributedType::attr_ms_abi:
> +    return ParsedAttr::AT_MSABI;
> +  case AttributedType::attr_sysv_abi:
> +    return ParsedAttr::AT_SysVABI;
> +  case AttributedType::attr_preserve_most:
> +    return ParsedAttr::AT_PreserveMost;
> +  case AttributedType::attr_preserve_all:
> +    return ParsedAttr::AT_PreserveAll;
> +  case AttributedType::attr_ptr32:
> +    return ParsedAttr::AT_Ptr32;
> +  case AttributedType::attr_ptr64:
> +    return ParsedAttr::AT_Ptr64;
> +  case AttributedType::attr_sptr:
> +    return ParsedAttr::AT_SPtr;
> +  case AttributedType::attr_uptr:
> +    return ParsedAttr::AT_UPtr;
> +  case AttributedType::attr_nonnull:
> +    return ParsedAttr::AT_TypeNonNull;
> +  case AttributedType::attr_nullable:
> +    return ParsedAttr::AT_TypeNullable;
> +  case AttributedType::attr_null_unspecified:
> +    return ParsedAttr::AT_TypeNullUnspecified;
> +  case AttributedType::attr_objc_kindof:
> +    return ParsedAttr::AT_ObjCKindOf;
> +  case AttributedType::attr_ns_returns_retained:
> +    return ParsedAttr::AT_NSReturnsRetained;
> +  case AttributedType::attr_lifetimebound:
> +    return ParsedAttr::AT_LifetimeBound;
> +  }
> +  llvm_unreachable("unexpected attribute kind!");
> +}
> +
> +static void setAttributedTypeLoc(AttributedTypeLoc TL, const ParsedAttr
> &attr) {
> +  TL.setAttrNameLoc(attr.getLoc());
> +  if (TL.hasAttrExprOperand()) {
> +    assert(attr.isArgExpr(0) && "mismatched attribute operand kind");
> +    TL.setAttrExprOperand(attr.getArgAsExpr(0));
> +  } else if (TL.hasAttrEnumOperand()) {
> +    assert((attr.isArgIdent(0) || attr.isArgExpr(0)) &&
> +           "unexpected attribute operand kind");
> +    if (attr.isArgIdent(0))
> +      TL.setAttrEnumOperandLoc(attr.getArgAsIdent(0)->Loc);
> +    else
> +      TL.setAttrEnumOperandLoc(attr.getArgAsExpr(0)->getExprLoc());
> +  }
> +
> +  // FIXME: preserve this information to here.
> +  if (TL.hasAttrOperand())
> +    TL.setAttrOperandParensRange(SourceRange());
> +}
> +
>  static void fillAttributedTypeLoc(AttributedTypeLoc TL,
> -                                  TypeProcessingState &State) {
> -  TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
> +                                  const ParsedAttributesView &Attrs,
> +                                  const ParsedAttributesView &DeclAttrs) {
> +  // DeclAttrs and Attrs cannot be both empty.
> +  assert((!Attrs.empty() || !DeclAttrs.empty()) &&
> +         "no type attributes in the expected location!");
> +
> +  ParsedAttr::Kind parsedKind = getAttrListKind(TL.getAttrKind());
> +  // Try to search for an attribute of matching kind in Attrs list.
> +  for (const ParsedAttr &AL : Attrs)
> +    if (AL.getKind() == parsedKind)
> +      return setAttributedTypeLoc(TL, AL);
> +
> +  for (const ParsedAttr &AL : DeclAttrs)
> +    if (AL.isCXX11Attribute() || AL.getKind() == parsedKind)
> +      return setAttributedTypeLoc(TL, AL);
> +  llvm_unreachable("no matching type attribute in expected location!");
>  }
>
>  namespace {
>    class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
>      ASTContext &Context;
> -    TypeProcessingState &State;
>      const DeclSpec &DS;
>
>    public:
> -    TypeSpecLocFiller(ASTContext &Context, TypeProcessingState &State,
> -                      const DeclSpec &DS)
> -        : Context(Context), State(State), DS(DS) {}
> +    TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS)
> +      : Context(Context), DS(DS) {}
>
>      void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
> +      fillAttributedTypeLoc(TL, DS.getAttributes(),
> ParsedAttributesView{});
>        Visit(TL.getModifiedLoc());
> -      fillAttributedTypeLoc(TL, State);
>      }
>      void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
>        Visit(TL.getUnqualifiedLoc());
> @@ -5408,13 +5442,11 @@ namespace {
>
>    class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
>      ASTContext &Context;
> -    TypeProcessingState &State;
>      const DeclaratorChunk &Chunk;
>
>    public:
> -    DeclaratorLocFiller(ASTContext &Context, TypeProcessingState &State,
> -                        const DeclaratorChunk &Chunk)
> -        : Context(Context), State(State), Chunk(Chunk) {}
> +    DeclaratorLocFiller(ASTContext &Context, const DeclaratorChunk &Chunk)
> +      : Context(Context), Chunk(Chunk) {}
>
>      void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
>        llvm_unreachable("qualified type locs not expected here!");
> @@ -5424,7 +5456,7 @@ namespace {
>      }
>
>      void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
> -      fillAttributedTypeLoc(TL, State);
> +      fillAttributedTypeLoc(TL, Chunk.getAttrs(), ParsedAttributesView{});
>      }
>      void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
>        // nothing
> @@ -5581,13 +5613,10 @@ fillDependentAddressSpaceTypeLoc(Depende
>  /// up in the normal place in the declaration specifiers (such as a C++
>  /// conversion function), this pointer will refer to a type source
> information
>  /// for that return type.
> -static TypeSourceInfo *
> -GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
> -                               QualType T, TypeSourceInfo
> *ReturnTypeInfo) {
> -  Sema &S = State.getSema();
> -  Declarator &D = State.getDeclarator();
> -
> -  TypeSourceInfo *TInfo = S.Context.CreateTypeSourceInfo(T);
> +TypeSourceInfo *
> +Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
> +                                     TypeSourceInfo *ReturnTypeInfo) {
> +  TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T);
>    UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();
>
>    // Handle parameter packs whose type is a pack expansion.
> @@ -5597,6 +5626,7 @@ GetTypeSourceInfoForDeclarator(TypeProce
>    }
>
>    for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
> +
>      if (DependentAddressSpaceTypeLoc DASTL =
>          CurrTL.getAs<DependentAddressSpaceTypeLoc>()) {
>        fillDependentAddressSpaceTypeLoc(DASTL,
> D.getTypeObject(i).getAttrs());
> @@ -5611,7 +5641,8 @@ GetTypeSourceInfoForDeclarator(TypeProce
>      }
>
>      while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
> -      fillAttributedTypeLoc(TL, State);
> +      fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(),
> +                            D.getAttributes());
>        CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
>      }
>
> @@ -5619,7 +5650,7 @@ GetTypeSourceInfoForDeclarator(TypeProce
>      while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())
>        CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
>
> -    DeclaratorLocFiller(S.Context, State,
> D.getTypeObject(i)).Visit(CurrTL);
> +    DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL);
>      CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
>    }
>
> @@ -5630,7 +5661,7 @@ GetTypeSourceInfoForDeclarator(TypeProce
>      assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
>      memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(),
> TL.getFullDataSize());
>    } else {
> -    TypeSpecLocFiller(S.Context, State, D.getDeclSpec()).Visit(CurrTL);
> +    TypeSpecLocFiller(Context, D.getDeclSpec()).Visit(CurrTL);
>    }
>
>    return TInfo;
> @@ -5859,7 +5890,7 @@ static bool hasDirectOwnershipQualifier(
>    while (true) {
>      // __strong id
>      if (const AttributedType *attr = dyn_cast<AttributedType>(type)) {
> -      if (attr->getAttrKind() == attr::ObjCOwnership)
> +      if (attr->getAttrKind() == AttributedType::attr_objc_ownership)
>          return true;
>
>        type = attr->getModifiedType();
> @@ -6003,9 +6034,9 @@ static bool handleObjCOwnershipTypeAttr(
>    // the coexistence problems with __unsafe_unretained.
>    if (!S.getLangOpts().ObjCAutoRefCount &&
>        lifetime == Qualifiers::OCL_ExplicitNone) {
> -    type = state.getAttributedType(
> -        createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr),
> -        type, type);
> +    type = S.Context.getAttributedType(
> +
>  AttributedType::attr_objc_inert_unsafe_unretained,
> +                                       type, type);
>      return true;
>    }
>
> @@ -6015,12 +6046,9 @@ static bool handleObjCOwnershipTypeAttr(
>
>    // If we have a valid source location for the attribute, use an
>    // AttributedType instead.
> -  if (AttrLoc.isValid()) {
> -    type = state.getAttributedType(::new (S.Context) ObjCOwnershipAttr(
> -                                       attr.getRange(), S.Context, II,
> -
>  attr.getAttributeSpellingListIndex()),
> -                                   origType, type);
> -  }
> +  if (AttrLoc.isValid())
> +    type =
> S.Context.getAttributedType(AttributedType::attr_objc_ownership,
> +                                       origType, type);
>
>    auto diagnoseOrDelay = [](Sema &S, SourceLocation loc,
>                              unsigned diagnostic, QualType type) {
> @@ -6120,10 +6148,8 @@ static bool handleObjCGCTypeAttr(TypePro
>
>    // Make an attributed type to preserve the source information.
>    if (attr.getLoc().isValid())
> -    type = state.getAttributedType(
> -        ::new (S.Context) ObjCGCAttr(attr.getRange(), S.Context, II,
> -
>  attr.getAttributeSpellingListIndex()),
> -        origType, type);
> +    type = S.Context.getAttributedType(AttributedType::attr_objc_gc,
> +                                       origType, type);
>
>    return true;
>  }
> @@ -6266,50 +6292,37 @@ namespace {
>  } // end anonymous namespace
>
>  static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
> -                                             ParsedAttr &PAttr, QualType
> &Type) {
> +                                             ParsedAttr &Attr, QualType
> &Type) {
>    Sema &S = State.getSema();
>
> -  Attr *A;
> -  switch (PAttr.getKind()) {
> -  default: llvm_unreachable("Unknown attribute kind");
> -  case ParsedAttr::AT_Ptr32:
> -    A = createSimpleAttr<Ptr32Attr>(S.Context, PAttr);
> -    break;
> -  case ParsedAttr::AT_Ptr64:
> -    A = createSimpleAttr<Ptr64Attr>(S.Context, PAttr);
> -    break;
> -  case ParsedAttr::AT_SPtr:
> -    A = createSimpleAttr<SPtrAttr>(S.Context, PAttr);
> -    break;
> -  case ParsedAttr::AT_UPtr:
> -    A = createSimpleAttr<UPtrAttr>(S.Context, PAttr);
> -    break;
> -  }
> -
> -  attr::Kind NewAttrKind = A->getKind();
> +  ParsedAttr::Kind Kind = Attr.getKind();
>    QualType Desugared = Type;
>    const AttributedType *AT = dyn_cast<AttributedType>(Type);
>    while (AT) {
> -    attr::Kind CurAttrKind = AT->getAttrKind();
> +    AttributedType::Kind CurAttrKind = AT->getAttrKind();
>
>      // You cannot specify duplicate type attributes, so if the attribute
> has
>      // already been applied, flag it.
> -    if (NewAttrKind == CurAttrKind) {
> -      S.Diag(PAttr.getLoc(), diag::warn_duplicate_attribute_exact)
> -        << PAttr.getName();
> +    if (getAttrListKind(CurAttrKind) == Kind) {
> +      S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute_exact)
> +        << Attr.getName();
>        return true;
>      }
>
>      // You cannot have both __sptr and __uptr on the same type, nor can
> you
>      // have __ptr32 and __ptr64.
> -
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180820/bacf8d77/attachment-0001.html>


More information about the cfe-commits mailing list