r340215 - Model type attributes as regular Attrs.
Mikael Holmén via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 21 00:23:51 PDT 2018
On 08/21/2018 08:11 AM, Mikael Holmén wrote:
> Hi,
>
> I get a warning with this:
>
> [1/16] Building CXX object
> tools/clang/lib/Sema/CMakeFiles/clangSema.dir/SemaType.cpp.o
> ../tools/clang/lib/Sema/SemaType.cpp: In function 'bool
> handleFunctionTypeAttr({anonymous}::TypeProcessingState&,
> clang::ParsedAttr&, clang::QualType&)':
> ../tools/clang/lib/Sema/SemaType.cpp:6788:31: warning: unused variable
> 'AT' [-Wunused-variable]
> if (const AttributedType *AT =
> S.getCallingConvAttributedType(type)) {
> ^
I fixed in r340251.
/Mikael
> /Mikael
>
> On 08/20/2018 11:47 PM, Richard Smith via cfe-commits wrote:
>> Author: rsmith
>> Date: Mon Aug 20 14:47:29 2018
>> New Revision: 340215
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=340215&view=rev
>> Log:
>> Model type attributes as regular Attrs.
>>
>> Specifically, AttributedType now tracks a regular attr::Kind rather than
>> having its own parallel Kind enumeration, and AttributedTypeLoc now
>> holds an Attr* instead of holding an ad-hoc collection of Attr fields.
>>
>> Differential Revision: https://reviews.llvm.org/D50526
>>
>> This reinstates r339623, reverted in r339638, with a fix to not fail
>> template instantiation if we instantiate a QualType with no associated
>> type source information and we encounter an AttributedType.
>>
>> 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/test/SemaCXX/calling-conv-compat.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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
>> +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 20 14:47:29 2018
>> @@ -31,6 +31,7 @@
>> #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"
>> @@ -1422,7 +1423,7 @@ public:
>> QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType
>> TST) const;
>> - QualType getAttributedType(AttributedType::Kind attrKind,
>> + QualType getAttributedType(attr::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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/Attr.h (original)
>> +++ cfe/trunk/include/clang/AST/Attr.h Mon Aug 20 14:47:29 2018
>> @@ -113,6 +113,19 @@ 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/Type.h (original)
>> +++ cfe/trunk/include/clang/AST/Type.h Mon Aug 20 14:47:29 2018
>> @@ -21,6 +21,7 @@
>> #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"
>> @@ -1970,7 +1971,16 @@ public:
>> bool isObjCQualifiedClassType() const; // Class<foo>
>> bool isObjCObjectOrInterfaceType() const;
>> bool isObjCIdType() const; // id
>> - bool isObjCInertUnsafeUnretainedType() const;
>> +
>> + /// 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);
>> + }
>> /// Whether the type is Objective-C 'id' or a __kindof type of an
>> /// object type, e.g., __kindof NSView * or __kindof id
>> @@ -2184,6 +2194,10 @@ 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.
>> @@ -4293,56 +4307,7 @@ public:
>> /// - the canonical type is VectorType(16, int)
>> class AttributedType : public Type, public llvm::FoldingSetNode {
>> public:
>> - // 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,
>> - };
>> + using Kind = attr::Kind;
>> private:
>> friend class ASTContext; // ASTContext creates these
>> @@ -4350,7 +4315,7 @@ private:
>> QualType ModifiedType;
>> QualType EquivalentType;
>> - AttributedType(QualType canon, Kind attrKind, QualType modified,
>> + AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
>> QualType equivalent)
>> : Type(Attributed, canon, equivalent->isDependentType(),
>> equivalent->isInstantiationDependentType(),
>> @@ -4399,13 +4364,13 @@ public:
>> static Kind getNullabilityAttrKind(NullabilityKind kind) {
>> switch (kind) {
>> case NullabilityKind::NonNull:
>> - return attr_nonnull;
>> + return attr::TypeNonNull;
>> case NullabilityKind::Nullable:
>> - return attr_nullable;
>> + return attr::TypeNullable;
>> case NullabilityKind::Unspecified:
>> - return attr_null_unspecified;
>> + return attr::TypeNullUnspecified;
>> }
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/TypeLoc.h (original)
>> +++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Aug 20 14:47:29 2018
>> @@ -15,6 +15,7 @@
>> #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"
>> @@ -849,16 +850,7 @@ class SubstTemplateTypeParmPackTypeLoc :
>> };
>> struct AttributedLocInfo {
>> - union {
>> - Expr *ExprOperand;
>> -
>> - /// A raw SourceLocation.
>> - unsigned EnumOperandLoc;
>> - };
>> -
>> - SourceRange OperandParens;
>> -
>> - SourceLocation AttrLoc;
>> + const Attr *TypeAttr;
>> };
>> /// Type source information for an attributed type.
>> @@ -867,24 +859,10 @@ class AttributedTypeLoc : public Concret
>> AttributedType,
>> AttributedLocInfo> {
>> public:
>> - AttributedType::Kind getAttrKind() const {
>> + attr::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();
>> }
>> @@ -897,51 +875,16 @@ public:
>> return getInnerTypeLoc();
>> }
>> - /// 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;
>> + /// 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());
>> }
>> SourceRange getLocalSourceRange() const {
>> @@ -954,21 +897,11 @@ public:
>> // ^~ ~~
>> // That enclosure doesn't necessarily belong to a single attribute
>> // anyway.
>> - SourceRange range(getAttrNameLoc());
>> - if (hasAttrOperand())
>> - range.setEnd(getAttrOperandParensRange().getEnd());
>> - return range;
>> + return getAttr() ? getAttr()->getRange() : SourceRange();
>> }
>> void initializeLocal(ASTContext &Context, SourceLocation loc) {
>> - setAttrNameLoc(loc);
>> - if (hasAttrExprOperand()) {
>> - setAttrOperandParensRange(SourceRange(loc));
>> - setAttrExprOperand(nullptr);
>> - } else if (hasAttrEnumOperand()) {
>> - setAttrOperandParensRange(SourceRange(loc));
>> - setAttrEnumOperandLoc(loc);
>> - }
>> + setAttr(nullptr);
>> }
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>> +++ cfe/trunk/include/clang/Basic/Attr.td Mon Aug 20 14:47:29 2018
>> @@ -494,10 +494,7 @@ class Attr {
>> }
>> /// A type attribute is not processed on a declaration or a statement.
>> -class TypeAttr : Attr {
>> - // By default, type attributes do not get an AST node.
>> - let ASTNode = 0;
>> -}
>> +class TypeAttr : Attr;
>> /// A stmt attribute is not processed on a declaration or a type.
>> class StmtAttr : Attr;
>> @@ -567,6 +564,8 @@ 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 {
>> @@ -1224,7 +1223,7 @@ def LayoutVersion : InheritableAttr, Tar
>> let Documentation = [LayoutVersionDocs];
>> }
>> -def LifetimeBound : InheritableAttr {
>> +def LifetimeBound : DeclOrTypeAttr {
>> let Spellings = [Clang<"lifetimebound", 0>];
>> let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter],
>> ErrorDiag>;
>> let Documentation = [LifetimeBoundDocs];
>> @@ -1327,12 +1326,16 @@ 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 {
>> @@ -1507,6 +1510,14 @@ 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];
>> @@ -1594,7 +1605,7 @@ def ObjCBridgeRelated : InheritableAttr
>> let Documentation = [Undocumented];
>> }
>> -def NSReturnsRetained : InheritableAttr {
>> +def NSReturnsRetained : DeclOrTypeAttr {
>> let Spellings = [Clang<"ns_returns_retained">];
>> // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
>> let Documentation = [Undocumented];
>> @@ -1779,6 +1790,8 @@ 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 {
>> @@ -2067,10 +2080,9 @@ def ObjCGC : TypeAttr {
>> let Documentation = [Undocumented];
>> }
>> -def ObjCOwnership : InheritableAttr {
>> +def ObjCOwnership : DeclOrTypeAttr {
>> let Spellings = [Clang<"objc_ownership">];
>> let Args = [IdentifierArgument<"Kind">];
>> - let ASTNode = 0;
>> let Documentation = [Undocumented];
>> }
>> @@ -2108,6 +2120,8 @@ 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 {
>> @@ -2202,7 +2216,7 @@ def AnyX86NoCallerSavedRegisters : Inher
>> let Documentation = [AnyX86NoCallerSavedRegistersDocs];
>> }
>> -def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr<TargetAnyX86>{
>> +def AnyX86NoCfCheck : DeclOrTypeAttr, 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Aug 20 14:47:29 2018
>> @@ -1435,8 +1435,6 @@ 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);
>> @@ -3378,30 +3376,6 @@ 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,
>> @@ -8071,10 +8045,6 @@ 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Aug 20
>> 14:47:29 2018
>> @@ -2245,6 +2245,9 @@ 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);
>> @@ -2630,6 +2633,11 @@ 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon Aug 20
>> 14:47:29 2018
>> @@ -955,6 +955,9 @@ 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp (original)
>> +++ cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp Mon Aug 20 14:47:29 2018
>> @@ -81,10 +81,11 @@ public:
>> }
>> bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) {
>> - if (TL.getAttrKind() != AttributedType::attr_objc_ownership)
>> + auto *OwnershipAttr = TL.getAttrAs<ObjCOwnershipAttr>();
>> + if (!OwnershipAttr)
>> return false;
>> - SourceLocation Loc = TL.getAttrNameLoc();
>> + SourceLocation Loc = OwnershipAttr->getLocation();
>> unsigned RawLoc = Loc.getRawEncoding();
>> if (MigrateCtx.AttrSet.count(RawLoc))
>> return true;
>> @@ -93,13 +94,7 @@ public:
>> SourceManager &SM = Ctx.getSourceManager();
>> if (Loc.isMacroID())
>> Loc = SM.getImmediateExpansionRange(Loc).getBegin();
>> - SmallString<32> Buf;
>> - bool Invalid = false;
>> - StringRef Spell = Lexer::getSpelling(
>> -
>> SM.getSpellingLoc(TL.getAttrEnumOperandLoc()),
>> - Buf, SM, Ctx.getLangOpts(), &Invalid);
>> - if (Invalid)
>> - return false;
>> + StringRef Spell = OwnershipAttr->getKind()->getName();
>> MigrationContext::GCAttrOccurrence::AttrKind Kind;
>> if (Spell == "strong")
>> Kind = MigrationContext::GCAttrOccurrence::Strong;
>> @@ -284,7 +279,7 @@ static void checkAllAtProps(MigrationCon
>> }
>> for (unsigned i = 0, e = ATLs.size(); i != e; ++i) {
>> - SourceLocation Loc = ATLs[i].first.getAttrNameLoc();
>> + SourceLocation Loc = ATLs[i].first.getAttr()->getLocation();
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
>> +++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Mon Aug 20 14:47:29 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() == AttributedType::attr_objc_ownership)
>> + if (AttrT->getAttrKind() == attr::ObjCOwnership)
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 20 14:47:29 2018
>> @@ -3876,7 +3876,7 @@ QualType ASTContext::getEnumType(const E
>> return QualType(newType, 0);
>> }
>> -QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
>> +QualType ASTContext::getAttributedType(attr::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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/Type.cpp (original)
>> +++ cfe/trunk/lib/AST/Type.cpp Mon Aug 20 14:47:29 2018
>> @@ -592,28 +592,6 @@ 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)
>> @@ -1641,6 +1619,16 @@ 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 :
>> @@ -3168,105 +3156,58 @@ 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 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:
>> + 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:
>> 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()) {
>> - 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:
>> + 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:
>> return true;
>> }
>> llvm_unreachable("invalid attr kind");
>> @@ -3712,23 +3653,18 @@ LinkageInfo Type::getLinkageAndVisibilit
>> return LinkageComputer{}.getTypeLinkageAndVisibility(this);
>> }
>> -Optional<NullabilityKind> Type::getNullability(const ASTContext
>> &context) const {
>> - QualType type(this, 0);
>> - do {
>> +Optional<NullabilityKind>
>> +Type::getNullability(const ASTContext &Context) const {
>> + QualType Type(this, 0);
>> + while (const auto *AT = Type->getAs<AttributedType>()) {
>> // Check whether this is an attributed type with nullability
>> // information.
>> - if (auto attributed = dyn_cast<AttributedType>(type.getTypePtr())) {
>> - if (auto nullability = attributed->getImmediateNullability())
>> - return nullability;
>> - }
>> -
>> - // Desugar the type. If desugaring does nothing, we're done.
>> - QualType desugared = type.getSingleStepDesugaredType(context);
>> - if (desugared.getTypePtr() == type.getTypePtr())
>> - return None;
>> + if (auto Nullability = AT->getImmediateNullability())
>> + return Nullability;
>> - type = desugared;
>> - } while (true);
>> + Type = AT->getEquivalentType();
>> + }
>> + return None;
>> }
>> bool Type::canHaveNullability(bool ResultIfUnknown) const {
>> @@ -3841,12 +3777,13 @@ bool Type::canHaveNullability(bool Resul
>> llvm_unreachable("bad type kind!");
>> }
>> -llvm::Optional<NullabilityKind>
>> AttributedType::getImmediateNullability() const {
>> - if (getAttrKind() == AttributedType::attr_nonnull)
>> +llvm::Optional<NullabilityKind>
>> +AttributedType::getImmediateNullability() const {
>> + if (getAttrKind() == attr::TypeNonNull)
>> return NullabilityKind::NonNull;
>> - if (getAttrKind() == AttributedType::attr_nullable)
>> + if (getAttrKind() == attr::TypeNullable)
>> return NullabilityKind::Nullable;
>> - if (getAttrKind() == AttributedType::attr_null_unspecified)
>> + if (getAttrKind() == attr::TypeNullUnspecified)
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/TypeLoc.cpp (original)
>> +++ cfe/trunk/lib/AST/TypeLoc.cpp Mon Aug 20 14:47:29 2018
>> @@ -404,11 +404,11 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLo
>> }
>> SourceLocation TypeLoc::findNullabilityLoc() const {
>> - 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();
>> + if (auto ATL = getAs<AttributedTypeLoc>()) {
>> + const Attr *A = ATL.getAttr();
>> + if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||
>> + isa<TypeNullUnspecifiedAttr>(A)))
>> + return A->getLocation();
>> }
>> return {};
>>
>> Modified: cfe/trunk/lib/AST/TypePrinter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/TypePrinter.cpp (original)
>> +++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Aug 20 14:47:29 2018
>> @@ -1354,12 +1354,14 @@ 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() == AttributedType::attr_objc_gc ||
>> - T->getAttrKind() == AttributedType::attr_objc_ownership)
>> + if (T->getAttrKind() == attr::ObjCGC ||
>> + T->getAttrKind() == attr::ObjCOwnership)
>> return printBefore(T->getEquivalentType(), OS);
>> - if (T->getAttrKind() == AttributedType::attr_objc_kindof)
>> + if (T->getAttrKind() == attr::ObjCKindOf)
>> OS << "__kindof ";
>> printBefore(T->getModifiedType(), OS);
>> @@ -1367,23 +1369,21 @@ void TypePrinter::printAttributedBefore(
>> if (T->isMSTypeSpec()) {
>> switch (T->getAttrKind()) {
>> default: return;
>> - 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;
>> + case attr::Ptr32: OS << " __ptr32"; break;
>> + case attr::Ptr64: OS << " __ptr64"; break;
>> + case attr::SPtr: OS << " __sptr"; break;
>> + case attr::UPtr: OS << " __uptr"; break;
>> }
>> spaceBeforePlaceHolder(OS);
>> }
>> // Print nullability type specifiers.
>> - if (T->getAttrKind() == AttributedType::attr_nonnull ||
>> - T->getAttrKind() == AttributedType::attr_nullable ||
>> - T->getAttrKind() == AttributedType::attr_null_unspecified) {
>> - if (T->getAttrKind() == AttributedType::attr_nonnull)
>> + if (T->getImmediateNullability()) {
>> + if (T->getAttrKind() == attr::TypeNonNull)
>> OS << " _Nonnull";
>> - else if (T->getAttrKind() == AttributedType::attr_nullable)
>> + else if (T->getAttrKind() == attr::TypeNullable)
>> OS << " _Nullable";
>> - else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
>> + else if (T->getAttrKind() == attr::TypeNullUnspecified)
>> OS << " _Null_unspecified";
>> else
>> llvm_unreachable("unhandled nullability");
>> @@ -1393,9 +1393,11 @@ 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() == AttributedType::attr_objc_gc ||
>> - T->getAttrKind() == AttributedType::attr_objc_ownership)
>> + if (T->getAttrKind() == attr::ObjCGC ||
>> + T->getAttrKind() == attr::ObjCOwnership)
>> return printAfter(T->getEquivalentType(), OS);
>> // If this is a calling convention attribute, don't print the
>> implicit CC from
>> @@ -1406,107 +1408,74 @@ void TypePrinter::printAttributedAfter(c
>> // Some attributes are printed as qualifiers before the type, so
>> we have
>> // nothing left to do.
>> - 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)
>> + if (T->getAttrKind() == attr::ObjCKindOf ||
>> + T->isMSTypeSpec() || T->getImmediateNullability())
>> return;
>> // Don't print the inert __unsafe_unretained attribute at all.
>> - if (T->getAttrKind() ==
>> AttributedType::attr_objc_inert_unsafe_unretained)
>> + if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
>> return;
>> // Don't print ns_returns_retained unless it had an effect.
>> - if (T->getAttrKind() == AttributedType::attr_ns_returns_retained &&
>> + if (T->getAttrKind() == attr::NSReturnsRetained &&
>> !T->getEquivalentType()->castAs<FunctionType>()
>> ->getExtInfo().getProducesResult())
>> return;
>> - if (T->getAttrKind() == AttributedType::attr_lifetimebound) {
>> + if (T->getAttrKind() == attr::LifetimeBound) {
>> OS << " [[clang::lifetimebound]]";
>> return;
>> }
>> OS << " __attribute__((";
>> switch (T->getAttrKind()) {
>> - 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:
>> +#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:
>> llvm_unreachable("This attribute should have been handled
>> already");
>> - 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:
>> + case attr::NSReturnsRetained:
>> OS << "ns_returns_retained";
>> break;
>> // FIXME: When Sema learns to form this AttributedType, avoid
>> printing the
>> // attribute again in printFunctionProtoAfter.
>> - 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: {
>> + 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: {
>> OS << "pcs(";
>> QualType t = T->getEquivalentType();
>> while (!t->isFunctionType())
>> @@ -1517,12 +1486,12 @@ void TypePrinter::printAttributedAfter(c
>> break;
>> }
>> - case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;
>> - case AttributedType::attr_preserve_most:
>> + case attr::IntelOclBicc: OS << "inteloclbicc"; break;
>> + case attr::PreserveMost:
>> OS << "preserve_most";
>> break;
>> - case AttributedType::attr_preserve_all:
>> + case attr::PreserveAll:
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 20 14:47:29 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 (ATL.getAttrKind() == AttributedType::attr_lifetimebound) {
>> + if (const auto *A = ATL.getAttrAs<LifetimeBoundAttr>()) {
>> const auto *MD = dyn_cast<CXXMethodDecl>(FD);
>> if (!MD || MD->isStatic()) {
>> - S.Diag(ATL.getAttrNameLoc(),
>> diag::err_lifetimebound_no_object_param)
>> - << !MD << ATL.getLocalSourceRange();
>> + S.Diag(A->getLocation(),
>> diag::err_lifetimebound_no_object_param)
>> + << !MD << A->getRange();
>> } else if (isa<CXXConstructorDecl>(MD) ||
>> isa<CXXDestructorDecl>(MD)) {
>> - S.Diag(ATL.getAttrNameLoc(),
>> diag::err_lifetimebound_ctor_dtor)
>> - << isa<CXXDestructorDecl>(MD) <<
>> ATL.getLocalSourceRange();
>> + S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor)
>> + << isa<CXXDestructorDecl>(MD) << A->getRange();
>> }
>> }
>> }
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 20 14:47:29 2018
>> @@ -14648,15 +14648,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_objc_ownership in Ty. The existence of AttributedType of
>> kind
>> - // attr_objc_ownership implies __autoreleasing was explicitly
>> specified
>> + // attr::ObjCOwnership in Ty. The existence of AttributedType of
>> kind
>> + // attr::ObjCOwnership 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() ==
>> AttributedType::attr_objc_ownership)
>> + if (AttrTy->getAttrKind() == attr::ObjCOwnership)
>> return true;
>> - // Peel off AttributedTypes that are not of kind objc_ownership.
>> + // Peel off AttributedTypes that are not of kind ObjCOwnership.
>> Ty = AttrTy->getModifiedType();
>> }
>>
>> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Aug 20 14:47:29 2018
>> @@ -6360,7 +6360,7 @@ static bool implicitObjectParamIsLifetim
>> for (TypeLoc TL = TSI->getTypeLoc();
>> (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
>> TL = ATL.getModifiedLoc()) {
>> - if (ATL.getAttrKind() == AttributedType::attr_lifetimebound)
>> + if (ATL.getAttrAs<LifetimeBoundAttr>())
>> 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=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Mon Aug 20 14:47:29 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(AttributedType::attr_nonnull,
>> + resultTy = Context.getAttributedType(attr::TypeNonNull,
>> 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(AttributedType::attr_nullable,
>> + paramTy = Context.getAttributedType(attr::TypeNullable,
>> modifiedTy,
>> modifiedTy);
>> }
>> }
>>
>> Modified: cfe/trunk/lib/Sema/SemaType.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Aug 20 14:47:29 2018
>> @@ -172,6 +172,16 @@ 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),
>> @@ -230,6 +240,43 @@ 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;
>> @@ -3832,6 +3879,32 @@ 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) {
>> @@ -4184,9 +4257,8 @@ static TypeSourceInfo *GetFullTypeForDec
>> pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),
>> D.getDeclSpec().getEndLoc(),
>> D.getMutableDeclSpec().getAttributes())) {
>> - T = Context.getAttributedType(
>> -
>> AttributedType::getNullabilityAttrKind(*inferNullability),T,T);
>> - attr->setUsedAsTypeAttr();
>> + T = state.getAttributedType(
>> + createNullabilityAttr(Context, *attr,
>> *inferNullability), T, T);
>> }
>> }
>> }
>> @@ -5025,7 +5097,7 @@ static TypeSourceInfo *GetFullTypeForDec
>> if (D.isInvalidType())
>> return Context.getTrivialTypeSourceInfo(T);
>> - return S.GetTypeSourceInfoForDeclarator(D, T, TInfo);
>> + return GetTypeSourceInfoForDeclarator(state, T, TInfo);
>> }
>> /// GetTypeForDeclarator - Convert the type for the specified
>> @@ -5161,131 +5233,25 @@ 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,
>> - 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!");
>> + TypeProcessingState &State) {
>> + TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
>> }
>> namespace {
>> class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
>> ASTContext &Context;
>> + TypeProcessingState &State;
>> const DeclSpec &DS;
>> public:
>> - TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS)
>> - : Context(Context), DS(DS) {}
>> + TypeSpecLocFiller(ASTContext &Context, TypeProcessingState &State,
>> + const DeclSpec &DS)
>> + : Context(Context), State(State), DS(DS) {}
>> void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
>> - fillAttributedTypeLoc(TL, DS.getAttributes(),
>> ParsedAttributesView{});
>> Visit(TL.getModifiedLoc());
>> + fillAttributedTypeLoc(TL, State);
>> }
>> void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
>> Visit(TL.getUnqualifiedLoc());
>> @@ -5442,11 +5408,13 @@ namespace {
>> class DeclaratorLocFiller : public
>> TypeLocVisitor<DeclaratorLocFiller> {
>> ASTContext &Context;
>> + TypeProcessingState &State;
>> const DeclaratorChunk &Chunk;
>> public:
>> - DeclaratorLocFiller(ASTContext &Context, const DeclaratorChunk
>> &Chunk)
>> - : Context(Context), Chunk(Chunk) {}
>> + DeclaratorLocFiller(ASTContext &Context, TypeProcessingState &State,
>> + const DeclaratorChunk &Chunk)
>> + : Context(Context), State(State), Chunk(Chunk) {}
>> void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
>> llvm_unreachable("qualified type locs not expected here!");
>> @@ -5456,7 +5424,7 @@ namespace {
>> }
>> void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
>> - fillAttributedTypeLoc(TL, Chunk.getAttrs(),
>> ParsedAttributesView{});
>> + fillAttributedTypeLoc(TL, State);
>> }
>> void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
>> // nothing
>> @@ -5613,10 +5581,13 @@ 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.
>> -TypeSourceInfo *
>> -Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
>> - TypeSourceInfo *ReturnTypeInfo) {
>> - TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T);
>> +static TypeSourceInfo *
>> +GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
>> + QualType T, TypeSourceInfo
>> *ReturnTypeInfo) {
>> + Sema &S = State.getSema();
>> + Declarator &D = State.getDeclarator();
>> +
>> + TypeSourceInfo *TInfo = S.Context.CreateTypeSourceInfo(T);
>> UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();
>> // Handle parameter packs whose type is a pack expansion.
>> @@ -5626,7 +5597,6 @@ Sema::GetTypeSourceInfoForDeclarator(Dec
>> }
>> for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
>> -
>> if (DependentAddressSpaceTypeLoc DASTL =
>> CurrTL.getAs<DependentAddressSpaceTypeLoc>()) {
>> fillDependentAddressSpaceTypeLoc(DASTL,
>> D.getTypeObject(i).getAttrs());
>> @@ -5641,8 +5611,7 @@ Sema::GetTypeSourceInfoForDeclarator(Dec
>> }
>> while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
>> - fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(),
>> - D.getAttributes());
>> + fillAttributedTypeLoc(TL, State);
>> CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
>> }
>> @@ -5650,7 +5619,7 @@ Sema::GetTypeSourceInfoForDeclarator(Dec
>> while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())
>> CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
>> - DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL);
>> + DeclaratorLocFiller(S.Context, State,
>> D.getTypeObject(i)).Visit(CurrTL);
>> CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
>> }
>> @@ -5661,7 +5630,7 @@ Sema::GetTypeSourceInfoForDeclarator(Dec
>> assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
>> memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(),
>> TL.getFullDataSize());
>> } else {
>> - TypeSpecLocFiller(Context, D.getDeclSpec()).Visit(CurrTL);
>> + TypeSpecLocFiller(S.Context, State, D.getDeclSpec()).Visit(CurrTL);
>> }
>> return TInfo;
>> @@ -5890,7 +5859,7 @@ static bool hasDirectOwnershipQualifier(
>> while (true) {
>> // __strong id
>> if (const AttributedType *attr = dyn_cast<AttributedType>(type)) {
>> - if (attr->getAttrKind() == AttributedType::attr_objc_ownership)
>> + if (attr->getAttrKind() == attr::ObjCOwnership)
>> return true;
>> type = attr->getModifiedType();
>> @@ -6034,9 +6003,9 @@ static bool handleObjCOwnershipTypeAttr(
>> // the coexistence problems with __unsafe_unretained.
>> if (!S.getLangOpts().ObjCAutoRefCount &&
>> lifetime == Qualifiers::OCL_ExplicitNone) {
>> - type = S.Context.getAttributedType(
>> -
>> AttributedType::attr_objc_inert_unsafe_unretained,
>> - type, type);
>> + type = state.getAttributedType(
>> + createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context,
>> attr),
>> + type, type);
>> return true;
>> }
>> @@ -6046,9 +6015,12 @@ static bool handleObjCOwnershipTypeAttr(
>> // If we have a valid source location for the attribute, use an
>> // AttributedType instead.
>> - if (AttrLoc.isValid())
>> - type =
>> S.Context.getAttributedType(AttributedType::attr_objc_ownership,
>> - origType, type);
>> + if (AttrLoc.isValid()) {
>> + type = state.getAttributedType(::new (S.Context) ObjCOwnershipAttr(
>> + attr.getRange(), S.Context, II,
>> +
>> attr.getAttributeSpellingListIndex()),
>> + origType, type);
>> + }
>> auto diagnoseOrDelay = [](Sema &S, SourceLocation loc,
>> unsigned diagnostic, QualType type) {
>> @@ -6148,8 +6120,10 @@ static bool handleObjCGCTypeAttr(TypePro
>> // Make an attributed type to preserve the source information.
>> if (attr.getLoc().isValid())
>> - type = S.Context.getAttributedType(AttributedType::attr_objc_gc,
>> - origType, type);
>> + type = state.getAttributedType(
>> + ::new (S.Context) ObjCGCAttr(attr.getRange(), S.Context, II,
>> +
>> attr.getAttributeSpellingListIndex()),
>> + origType, type);
>> return true;
>> }
>> @@ -6292,37 +6266,50 @@ namespace {
>> } // end anonymous namespace
>> static bool handleMSPointerTypeQualifierAttr(TypeProcessingState
>> &State,
>> - ParsedAttr &Attr,
>> QualType &Type) {
>> + ParsedAttr &PAttr,
>> QualType &Type) {
>> Sema &S = State.getSema();
>> - ParsedAttr::Kind Kind = Attr.getKind();
>> + 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();
>> QualType Desugared = Type;
>> const AttributedType *AT = dyn_cast<AttributedType>(Type);
>> while (AT) {
>> - AttributedType::Kind CurAttrKind = AT->getAttrKind();
>> + attr::Kind CurAttrKind = AT->getAttrKind();
>> // You cannot specify duplicate type attributes, so if the
>> attribute has
>> // already been applied, flag it.
>> - if (getAttrListKind(CurAttrKind) == Kind) {
>> - S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute_exact)
>> - << Attr.getName();
>> + if (NewAttrKind == CurAttrKind) {
>> + S.Diag(PAttr.getLoc(), diag::warn_duplicate_attribute_exact)
>> + << PAttr.getName();
>> return true;
>> }
>> // You cannot have both __sptr and __uptr on the same type, nor
>> can you
>> // have __ptr32 and __ptr64.
>> - if ((CurAttrKind == AttributedType::attr_ptr32 &&
>> - Kind == ParsedAttr::AT_Ptr64) ||
>> - (CurAttrKind == AttributedType::attr_ptr64 &&
>> - Kind == ParsedAttr::AT_Ptr32)) {
>> - S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
>> + if ((CurAttrKind == attr::Ptr32 && NewAttrKind == attr::Ptr64) ||
>> + (CurAttrKind == attr::Ptr64 && NewAttrKind == attr::Ptr32)) {
>> + S.Diag(PAttr.getLoc(), diag::err_attributes_are_not_compatible)
>> << "'__ptr32'" << "'__ptr64'";
>> return true;
>> - } else if ((CurAttrKind == AttributedType::attr_sptr &&
>> - Kind == ParsedAttr::AT_UPtr) ||
>> - (CurAttrKind == AttributedType::attr_uptr &&
>> - Kind == ParsedAttr::AT_SPtr)) {
>> - S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
>> + } else if ((CurAttrKind == attr::SPtr && NewAttrKind ==
>> attr::UPtr) ||
>> + (CurAttrKind == attr::UPtr && NewAttrKind ==
>> attr::SPtr)) {
>> + S.Diag(PAttr.getLoc(), diag::err_attributes_are_not_compatible)
>> << "'__sptr'" << "'__uptr'";
>> return true;
>> }
>> @@ -6333,41 +6320,64 @@ static bool handleMSPointerTypeQualifier
>> // Pointer type qualifiers can only operate on pointer types, but not
>> // pointer-to-member types.
>> + //
>> + // FIXME: Should we really be disallowing this attribute if there
>> is any
>> + // type sugar between it and the pointer (other than attributes)?
>> Eg, this
>> + // disallows the attribute on a parenthesized pointer.
>> + // And if so, should we really allow *any* type attribute?
>> if (!isa<PointerType>(Desugared)) {
>> if (Type->isMemberPointerType())
>> - S.Diag(Attr.getLoc(), diag::err_attribute_no_member_pointers)
>> << Attr;
>> + S.Diag(PAttr.getLoc(), diag::err_attribute_no_member_pointers)
>> << PAttr;
>> else
>> - S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only) <<
>> Attr << 0;
>> + S.Diag(PAttr.getLoc(), diag::err_attribute_pointers_only) <<
>> PAttr << 0;
>> return true;
>> }
>> - AttributedType::Kind TAK;
>> - switch (Kind) {
>> - default: llvm_unreachable("Unknown attribute kind");
>> - case ParsedAttr::AT_Ptr32:
>> - TAK = AttributedType::attr_ptr32;
>> - break;
>> - case ParsedAttr::AT_Ptr64:
>> - TAK = AttributedType::attr_ptr64;
>> - break;
>> - case ParsedAttr::AT_SPtr:
>> - TAK = AttributedType::attr_sptr;
>> - break;
>> - case ParsedAttr::AT_UPtr:
>> - TAK = AttributedType::attr_uptr;
>> - break;
>> - }
>> -
>> - Type = S.Context.getAttributedType(TAK, Type, Type);
>> + Type = State.getAttributedType(A, Type, Type);
>> return false;
>> }
>> -bool Sema::checkNullabilityTypeSpecifier(QualType &type,
>> - NullabilityKind nullability,
>> - SourceLocation nullabilityLoc,
>> - bool isContextSensitive,
>> - bool allowOnArrayType) {
>> - recordNullabilitySeen(*this, nullabilityLoc);
>> +/// Map a nullability attribute kind to a nullability kind.
>> +static NullabilityKind mapNullabilityAttrKind(ParsedAttr::Kind kind) {
>> + switch (kind) {
>> + case ParsedAttr::AT_TypeNonNull:
>> + return NullabilityKind::NonNull;
>> +
>> + case ParsedAttr::AT_TypeNullable:
>> + return NullabilityKind::Nullable;
>> +
>> + case ParsedAttr::AT_TypeNullUnspecified:
>> + return NullabilityKind::Unspecified;
>> +
>> + default:
>> + llvm_unreachable("not a nullability attribute kind");
>> + }
>> +}
>> +
>> +/// Applies a nullability type specifier to the given type, if possible.
>> +///
>> +/// \param state The type processing state.
>> +///
>> +/// \param type The type to which the nullability specifier will be
>> +/// added. On success, this type will be updated appropriately.
>> +///
>> +/// \param attr The attribute as written on the type.
>> +///
>> +/// \param allowArrayTypes Whether to accept nullability specifiers
>> on an
>> +/// array type (e.g., because it will decay to a pointer).
>> +///
>> +/// \returns true if a problem has been diagnosed, false on success.
>> +static bool checkNullabilityTypeSpecifier(TypeProcessingState &state,
>> + QualType &type,
>> + ParsedAttr &attr,
>> + bool allowOnArrayType) {
>> + Sema &S = state.getSema();
>> +
>> + NullabilityKind nullability = mapNullabilityAttrKind(attr.getKind());
>> + SourceLocation nullabilityLoc = attr.getLoc();
>> + bool isContextSensitive = attr.isContextSensitiveKeywordAttribute();
>> +
>> + recordNullabilitySeen(S, nullabilityLoc);
>> // Check for existing nullability attributes on the type.
>> QualType desugared = type;
>> @@ -6376,7 +6386,7 @@ bool Sema::checkNullabilityTypeSpecifier
>> if (auto existingNullability =
>> attributed->getImmediateNullability()) {
>> // Duplicated nullability.
>> if (nullability == *existingNullability) {
>> - Diag(nullabilityLoc, diag::warn_nullability_duplicate)
>> + S.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
>> << DiagNullabilityKind(nullability, isContextSensitive)
>> << FixItHint::CreateRemoval(nullabilityLoc);
>> @@ -6384,7 +6394,7 @@ bool Sema::checkNullabilityTypeSpecifier
>> }
>> // Conflicting nullability.
>> - Diag(nullabilityLoc, diag::err_nullability_conflicting)
>> + S.Diag(nullabilityLoc, diag::err_nullability_conflicting)
>> << DiagNullabilityKind(nullability, isContextSensitive)
>> << DiagNullabilityKind(*existingNullability, false);
>> return true;
>> @@ -6397,9 +6407,9 @@ bool Sema::checkNullabilityTypeSpecifier
>> // This (unlike the code above) looks through typedefs that might
>> // have nullability specifiers on them, which means we cannot
>> // provide a useful Fix-It.
>> - if (auto existingNullability = desugared->getNullability(Context)) {
>> + if (auto existingNullability = desugared->getNullability(S.Context)) {
>> if (nullability != *existingNullability) {
>> - Diag(nullabilityLoc, diag::err_nullability_conflicting)
>> + S.Diag(nullabilityLoc, diag::err_nullability_conflicting)
>> << DiagNullabilityKind(nullability, isContextSensitive)
>> << DiagNullabilityKind(*existingNullability, false);
>> @@ -6410,7 +6420,7 @@ bool Sema::checkNullabilityTypeSpecifier
>> if (auto typedefNullability
>> =
>> AttributedType::stripOuterNullability(underlyingType)) {
>> if (*typedefNullability == *existingNullability) {
>> - Diag(typedefDecl->getLocation(),
>> diag::note_nullability_here)
>> + S.Diag(typedefDecl->getLocation(),
>> diag::note_nullability_here)
>> << DiagNullabilityKind(*existingNullability, false);
>> }
>> }
>> @@ -6423,7 +6433,7 @@ bool Sema::checkNullabilityTypeSpecifier
>> // If this definitely isn't a pointer type, reject the specifier.
>> if (!desugared->canHaveNullability() &&
>> !(allowOnArrayType && desugared->isArrayType())) {
>> - Diag(nullabilityLoc, diag::err_nullability_nonpointer)
>> + S.Diag(nullabilityLoc, diag::err_nullability_nonpointer)
>> << DiagNullabilityKind(nullability, isContextSensitive) << type;
>> return true;
>> }
>> @@ -6441,10 +6451,10 @@ bool Sema::checkNullabilityTypeSpecifier
>> if (pointeeType->isAnyPointerType() ||
>> pointeeType->isObjCObjectPointerType() ||
>> pointeeType->isMemberPointerType()) {
>> - Diag(nullabilityLoc, diag::err_nullability_cs_multilevel)
>> + S.Diag(nullabilityLoc, diag::err_nullability_cs_multilevel)
>> << DiagNullabilityKind(nullability, true)
>> << type;
>> - Diag(nullabilityLoc, diag::note_nullability_type_specifier)
>> + S.Diag(nullabilityLoc, diag::note_nullability_type_specifier)
>> << DiagNullabilityKind(nullability, false)
>> << type
>> << FixItHint::CreateReplacement(nullabilityLoc,
>> @@ -6454,16 +6464,21 @@ bool Sema::checkNullabilityTypeSpecifier
>> }
>> // Form the attributed type.
>> - type = Context.getAttributedType(
>> - AttributedType::getNullabilityAttrKind(nullability), type,
>> type);
>> + type = state.getAttributedType(
>> + createNullabilityAttr(S.Context, attr, nullability), type, type);
>> return false;
>> }
>> -bool Sema::checkObjCKindOfType(QualType &type, SourceLocation loc) {
>> +/// Check the application of the Objective-C '__kindof' qualifier to
>> +/// the given type.
>> +static bool checkObjCKindOfType(TypeProcessingState &state, QualType
>> &type,
>> + ParsedAttr &attr) {
>> + Sema &S = state.getSema();
>> +
>> if (isa<ObjCTypeParamType>(type)) {
>> // Build the attributed type to record where __kindof occurred.
>> - type = Context.getAttributedType(AttributedType::attr_objc_kindof,
>> - type, type);
>> + type = state.getAttributedType(
>> + createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, type);
>> return false;
>> }
>> @@ -6475,7 +6490,7 @@ bool Sema::checkObjCKindOfType(QualType
>> // If not, we can't apply __kindof.
>> if (!objType) {
>> // FIXME: Handle dependent types that aren't yet object types.
>> - Diag(loc, diag::err_objc_kindof_nonobject)
>> + S.Diag(attr.getLoc(), diag::err_objc_kindof_nonobject)
>> << type;
>> return true;
>> }
>> @@ -6483,45 +6498,31 @@ bool Sema::checkObjCKindOfType(QualType
>> // Rebuild the "equivalent" type, which pushes __kindof down into
>> // the object type.
>> // There is no need to apply kindof on an unqualified id type.
>> - QualType equivType = Context.getObjCObjectType(
>> + QualType equivType = S.Context.getObjCObjectType(
>> objType->getBaseType(), objType->getTypeArgsAsWritten(),
>> objType->getProtocols(),
>> /*isKindOf=*/objType->isObjCUnqualifiedId() ? false : true);
>> // If we started with an object pointer type, rebuild it.
>> if (ptrType) {
>> - equivType = Context.getObjCObjectPointerType(equivType);
>> - if (auto nullability = type->getNullability(Context)) {
>> - auto attrKind =
>> AttributedType::getNullabilityAttrKind(*nullability);
>> - equivType = Context.getAttributedType(attrKind, equivType,
>> equivType);
>> + equivType = S.Context.getObjCObjectPointerType(equivType);
>> + if (auto nullability = type->getNullability(S.Context)) {
>> + // We create a nullability attribute from the __kindof attribute.
>> + // Make sure that will make sense.
>> + assert(attr.getAttributeSpellingListIndex() == 0 &&
>> + "multiple spellings for __kindof?");
>> + Attr *A = createNullabilityAttr(S.Context, attr, *nullability);
>> + A->setImplicit(true);
>> + equivType = state.getAttributedType(A, equivType, equivType);
>> }
>> }
>> // Build the attributed type to record where __kindof occurred.
>> - type = Context.getAttributedType(AttributedType::attr_objc_kindof,
>> - type,
>> - equivType);
>> -
>> + type = state.getAttributedType(
>> + createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type,
>> equivType);
>> return false;
>> }
>> -/// Map a nullability attribute kind to a nullability kind.
>> -static NullabilityKind mapNullabilityAttrKind(ParsedAttr::Kind kind) {
>> - switch (kind) {
>> - case ParsedAttr::AT_TypeNonNull:
>> - return NullabilityKind::NonNull;
>> -
>> - case ParsedAttr::AT_TypeNullable:
>> - return NullabilityKind::Nullable;
>> -
>> - case ParsedAttr::AT_TypeNullUnspecified:
>> - return NullabilityKind::Unspecified;
>> -
>> - default:
>> - llvm_unreachable("not a nullability attribute kind");
>> - }
>> -}
>> -
>> /// Distribute a nullability type attribute that cannot be applied to
>> /// the type specifier to a pointer, block pointer, or member pointer
>> /// declarator, complaining if necessary.
>> @@ -6609,27 +6610,27 @@ static bool distributeNullabilityTypeAtt
>> return false;
>> }
>> -static AttributedType::Kind getCCTypeAttrKind(ParsedAttr &Attr) {
>> +static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
>> assert(!Attr.isInvalid());
>> switch (Attr.getKind()) {
>> default:
>> llvm_unreachable("not a calling convention attribute");
>> case ParsedAttr::AT_CDecl:
>> - return AttributedType::attr_cdecl;
>> + return createSimpleAttr<CDeclAttr>(Ctx, Attr);
>> case ParsedAttr::AT_FastCall:
>> - return AttributedType::attr_fastcall;
>> + return createSimpleAttr<FastCallAttr>(Ctx, Attr);
>> case ParsedAttr::AT_StdCall:
>> - return AttributedType::attr_stdcall;
>> + return createSimpleAttr<StdCallAttr>(Ctx, Attr);
>> case ParsedAttr::AT_ThisCall:
>> - return AttributedType::attr_thiscall;
>> + return createSimpleAttr<ThisCallAttr>(Ctx, Attr);
>> case ParsedAttr::AT_RegCall:
>> - return AttributedType::attr_regcall;
>> + return createSimpleAttr<RegCallAttr>(Ctx, Attr);
>> case ParsedAttr::AT_Pascal:
>> - return AttributedType::attr_pascal;
>> + return createSimpleAttr<PascalAttr>(Ctx, Attr);
>> case ParsedAttr::AT_SwiftCall:
>> - return AttributedType::attr_swiftcall;
>> + return createSimpleAttr<SwiftCallAttr>(Ctx, Attr);
>> case ParsedAttr::AT_VectorCall:
>> - return AttributedType::attr_vectorcall;
>> + return createSimpleAttr<VectorCallAttr>(Ctx, Attr);
>> case ParsedAttr::AT_Pcs: {
>> // The attribute may have had a fixit applied where we treated an
>> // identifier as a string literal. The contents of the string
>> are valid,
>> @@ -6639,20 +6640,22 @@ static AttributedType::Kind getCCTypeAtt
>> Str = cast<StringLiteral>(Attr.getArgAsExpr(0))->getString();
>> else
>> Str = Attr.getArgAsIdent(0)->Ident->getName();
>> - return llvm::StringSwitch<AttributedType::Kind>(Str)
>> - .Case("aapcs", AttributedType::attr_pcs)
>> - .Case("aapcs-vfp", AttributedType::attr_pcs_vfp);
>> + PcsAttr::PCSType Type;
>> + if (!PcsAttr::ConvertStrToPCSType(Str, Type))
>> + llvm_unreachable("already validated the attribute");
>> + return ::new (Ctx) PcsAttr(Attr.getRange(), Ctx, Type,
>> + Attr.getAttributeSpellingListIndex());
>> }
>> case ParsedAttr::AT_IntelOclBicc:
>> - return AttributedType::attr_inteloclbicc;
>> + return createSimpleAttr<IntelOclBiccAttr>(Ctx, Attr);
>> case ParsedAttr::AT_MSABI:
>> - return AttributedType::attr_ms_abi;
>> + return createSimpleAttr<MSABIAttr>(Ctx, Attr);
>> case ParsedAttr::AT_SysVABI:
>> - return AttributedType::attr_sysv_abi;
>> + return createSimpleAttr<SysVABIAttr>(Ctx, Attr);
>> case ParsedAttr::AT_PreserveMost:
>> - return AttributedType::attr_preserve_most;
>> + return createSimpleAttr<PreserveMostAttr>(Ctx, Attr);
>> case ParsedAttr::AT_PreserveAll:
>> - return AttributedType::attr_preserve_all;
>> + return createSimpleAttr<PreserveAllAttr>(Ctx, Attr);
>> }
>> llvm_unreachable("unexpected attribute kind!");
>> }
>> @@ -6700,8 +6703,9 @@ static bool handleFunctionTypeAttr(TypeP
>> = unwrapped.get()->getExtInfo().withProducesResult(true);
>> type = unwrapped.wrap(S,
>> S.Context.adjustFunctionType(unwrapped.get(), EI));
>> }
>> - type =
>> S.Context.getAttributedType(AttributedType::attr_ns_returns_retained,
>> - origType, type);
>> + type = state.getAttributedType(
>> + createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr),
>> + origType, type);
>> return true;
>> }
>> @@ -6776,13 +6780,12 @@ static bool handleFunctionTypeAttr(TypeP
>> const FunctionType *fn = unwrapped.get();
>> CallingConv CCOld = fn->getCallConv();
>> - AttributedType::Kind CCAttrKind = getCCTypeAttrKind(attr);
>> + Attr *CCAttr = getCCTypeAttr(S.Context, attr);
>> if (CCOld != CC) {
>> // Error out on when there's already an attribute on the type
>> // and the CCs don't match.
>> - const AttributedType *AT = S.getCallingConvAttributedType(type);
>> - if (AT && AT->getAttrKind() != CCAttrKind) {
>> + if (const AttributedType *AT =
>> S.getCallingConvAttributedType(type)) {
>> S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
>> << FunctionType::getNameForCallConv(CC)
>> << FunctionType::getNameForCallConv(CCOld);
>> @@ -6836,7 +6839,7 @@ static bool handleFunctionTypeAttr(TypeP
>> Equivalent =
>> unwrapped.wrap(S,
>> S.Context.adjustFunctionType(unwrapped.get(), EI));
>> }
>> - type = S.Context.getAttributedType(CCAttrKind, type, Equivalent);
>> + type = state.getAttributedType(CCAttr, type, Equivalent);
>> return true;
>> }
>> @@ -7192,14 +7195,15 @@ static void deduceOpenCLImplicitAddrSpac
>> T = State.getSema().Context.getAddrSpaceQualType(T, ImpAddr);
>> }
>> -static void HandleLifetimeBoundAttr(QualType &CurType,
>> - const ParsedAttr &Attr,
>> - Sema &S, Declarator &D) {
>> - if (D.isDeclarationOfFunction()) {
>> - CurType =
>> S.Context.getAttributedType(AttributedType::attr_lifetimebound,
>> - CurType, CurType);
>> +static void HandleLifetimeBoundAttr(TypeProcessingState &State,
>> + QualType &CurType,
>> + ParsedAttr &Attr) {
>> + if (State.getDeclarator().isDeclarationOfFunction()) {
>> + CurType = State.getAttributedType(
>> + createSimpleAttr<LifetimeBoundAttr>(State.getSema().Context,
>> Attr),
>> + CurType, CurType);
>> } else {
>> - Attr.diagnoseAppertainsTo(S, nullptr);
>> + Attr.diagnoseAppertainsTo(State.getSema(), nullptr);
>> }
>> }
>> @@ -7309,11 +7313,8 @@ static void processTypeAttrs(TypeProcess
>> attr.setUsedAsTypeAttr();
>> break;
>> case ParsedAttr::AT_LifetimeBound:
>> - if (TAL == TAL_DeclChunk) {
>> - HandleLifetimeBoundAttr(type, attr, state.getSema(),
>> - state.getDeclarator());
>> - attr.setUsedAsTypeAttr();
>> - }
>> + if (TAL == TAL_DeclChunk)
>> + HandleLifetimeBoundAttr(state, type, attr);
>> break;
>> MS_TYPE_ATTRS_CASELIST:
>> @@ -7337,11 +7338,10 @@ static void processTypeAttrs(TypeProcess
>> bool allowOnArrayType =
>> state.getDeclarator().isPrototypeContext() &&
>> !hasOuterPointerLikeChunk(state.getDeclarator(), endIndex);
>> - if (state.getSema().checkNullabilityTypeSpecifier(
>> + if (checkNullabilityTypeSpecifier(
>> + state,
>> type,
>> - mapNullabilityAttrKind(attr.getKind()),
>> - attr.getLoc(),
>> - attr.isContextSensitiveKeywordAttribute(),
>> + attr,
>> allowOnArrayType)) {
>> attr.setInvalid();
>> }
>> @@ -7368,9 +7368,8 @@ static void processTypeAttrs(TypeProcess
>> }
>> // Apply it regardless.
>> - if (state.getSema().checkObjCKindOfType(type, attr.getLoc()))
>> + if (checkObjCKindOfType(state, type, attr))
>> attr.setInvalid();
>> - attr.setUsedAsTypeAttr();
>> break;
>> FUNCTION_TYPE_ATTRS_CASELIST:
>>
>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>> +++ cfe/trunk/lib/Sema/TreeTransform.h Mon Aug 20 14:47:29 2018
>> @@ -6058,6 +6058,12 @@ QualType TreeTransform<Derived>::Transfo
>> if (modifiedType.isNull())
>> return QualType();
>> + // oldAttr can be null if we started with a QualType rather than a
>> TypeLoc.
>> + const Attr *oldAttr = TL.getAttr();
>> + const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr)
>> : nullptr;
>> + if (oldAttr && !newAttr)
>> + return QualType();
>> +
>> QualType result = TL.getType();
>> // FIXME: dependent operand expressions?
>> @@ -6074,26 +6080,20 @@ QualType TreeTransform<Derived>::Transfo
>> // type sugar, and therefore cannot be diagnosed in any other way.
>> if (auto nullability = oldType->getImmediateNullability()) {
>> if (!modifiedType->canHaveNullability()) {
>> - SemaRef.Diag(TL.getAttrNameLoc(),
>> diag::err_nullability_nonpointer)
>> - << DiagNullabilityKind(*nullability, false) << modifiedType;
>> + SemaRef.Diag(TL.getAttr()->getLocation(),
>> + diag::err_nullability_nonpointer)
>> + << DiagNullabilityKind(*nullability, false) << modifiedType;
>> return QualType();
>> }
>> }
>> - result = SemaRef.Context.getAttributedType(oldType->getAttrKind(),
>> + result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
>> modifiedType,
>> equivalentType);
>> }
>> AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
>> - newTL.setAttrNameLoc(TL.getAttrNameLoc());
>> - if (TL.hasAttrOperand())
>> - newTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
>> - if (TL.hasAttrExprOperand())
>> - newTL.setAttrExprOperand(TL.getAttrExprOperand());
>> - else if (TL.hasAttrEnumOperand())
>> - newTL.setAttrEnumOperandLoc(TL.getAttrEnumOperandLoc());
>> -
>> + newTL.setAttr(newAttr);
>> return result;
>> }
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Aug 20 14:47:29 2018
>> @@ -6455,6 +6455,10 @@ class TypeLocReader : public TypeLocVisi
>> return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx);
>> }
>> + Attr *ReadAttr() {
>> + return Reader->ReadAttr(*F, Record, Idx);
>> + }
>> +
>> public:
>> TypeLocReader(ModuleFile &F, ASTReader &Reader,
>> const ASTReader::RecordData &Record, unsigned &Idx)
>> @@ -6646,20 +6650,7 @@ void TypeLocReader::VisitEnumTypeLoc(Enu
>> }
>> void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
>> - TL.setAttrNameLoc(ReadSourceLocation());
>> - if (TL.hasAttrOperand()) {
>> - SourceRange range;
>> - range.setBegin(ReadSourceLocation());
>> - range.setEnd(ReadSourceLocation());
>> - TL.setAttrOperandParensRange(range);
>> - }
>> - if (TL.hasAttrExprOperand()) {
>> - if (Record[Idx++])
>> - TL.setAttrExprOperand(Reader->ReadExpr(*F));
>> - else
>> - TL.setAttrExprOperand(nullptr);
>> - } else if (TL.hasAttrEnumOperand())
>> - TL.setAttrEnumOperandLoc(ReadSourceLocation());
>> + TL.setAttr(ReadAttr());
>> }
>> void
>> TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Aug 20 14:47:29
>> 2018
>> @@ -2648,19 +2648,72 @@ void ASTDeclReader::VisitOMPCapturedExpr
>> // Attribute Reading
>>
>> //===----------------------------------------------------------------------===//
>>
>> -/// Reads attributes from the current stream position.
>> -void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec
>> &Attrs) {
>> - for (unsigned i = 0, e = Record.readInt(); i != e; ++i) {
>> - Attr *New = nullptr;
>> - auto Kind = (attr::Kind)Record.readInt();
>> - SourceRange Range = Record.readSourceRange();
>> - ASTContext &Context = getContext();
>> +namespace {
>> +class AttrReader {
>> + ModuleFile *F;
>> + ASTReader *Reader;
>> + const ASTReader::RecordData &Record;
>> + unsigned &Idx;
>> -#include "clang/Serialization/AttrPCHRead.inc"
>> +public:
>> + AttrReader(ModuleFile &F, ASTReader &Reader,
>> + const ASTReader::RecordData &Record, unsigned &Idx)
>> + : F(&F), Reader(&Reader), Record(Record), Idx(Idx) {}
>> +
>> + const uint64_t &readInt() { return Record[Idx++]; }
>> +
>> + SourceRange readSourceRange() {
>> + return Reader->ReadSourceRange(*F, Record, Idx);
>> + }
>> +
>> + Expr *readExpr() { return Reader->ReadExpr(*F); }
>> +
>> + std::string readString() {
>> + return Reader->ReadString(Record, Idx);
>> + }
>> +
>> + TypeSourceInfo *getTypeSourceInfo() {
>> + return Reader->GetTypeSourceInfo(*F, Record, Idx);
>> + }
>> +
>> + IdentifierInfo *getIdentifierInfo() {
>> + return Reader->GetIdentifierInfo(*F, Record, Idx);
>> + }
>> - assert(New && "Unable to decode attribute?");
>> - Attrs.push_back(New);
>> + VersionTuple readVersionTuple() {
>> + return ASTReader::ReadVersionTuple(Record, Idx);
>> }
>> +
>> + template <typename T> T *GetLocalDeclAs(uint32_t LocalID) {
>> + return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
>> + }
>> +};
>> +}
>> +
>> +Attr *ASTReader::ReadAttr(ModuleFile &M, const RecordData &Rec,
>> + unsigned &Idx) {
>> + AttrReader Record(M, *this, Rec, Idx);
>> + auto V = Record.readInt();
>> + if (!V)
>> + return nullptr;
>> +
>> + Attr *New = nullptr;
>> + // Kind is stored as a 1-based integer because 0 is used to
>> indicate a null
>> + // Attr pointer.
>> + auto Kind = static_cast<attr::Kind>(V - 1);
>> + SourceRange Range = Record.readSourceRange();
>> + ASTContext &Context = getContext();
>> +
>> +#include "clang/Serialization/AttrPCHRead.inc"
>> +
>> + assert(New && "Unable to decode attribute?");
>> + return New;
>> +}
>> +
>> +/// Reads attributes from the current stream position.
>> +void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec
>> &Attrs) {
>> + for (unsigned I = 0, E = Record.readInt(); I != E; ++I)
>> + Attrs.push_back(Record.readAttr());
>> }
>>
>> //===----------------------------------------------------------------------===//
>>
>>
>> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Aug 20 14:47:29 2018
>> @@ -770,19 +770,7 @@ void TypeLocWriter::VisitEnumTypeLoc(Enu
>> }
>> void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
>> - Record.AddSourceLocation(TL.getAttrNameLoc());
>> - if (TL.hasAttrOperand()) {
>> - SourceRange range = TL.getAttrOperandParensRange();
>> - Record.AddSourceLocation(range.getBegin());
>> - Record.AddSourceLocation(range.getEnd());
>> - }
>> - if (TL.hasAttrExprOperand()) {
>> - Expr *operand = TL.getAttrExprOperand();
>> - Record.push_back(operand ? 1 : 0);
>> - if (operand) Record.AddStmt(operand);
>> - } else if (TL.hasAttrEnumOperand()) {
>> - Record.AddSourceLocation(TL.getAttrEnumOperandLoc());
>> - }
>> + Record.AddAttr(TL.getAttr());
>> }
>> void
>> TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
>> @@ -4481,16 +4469,21 @@ void ASTWriter::WriteModuleFileExtension
>> // General Serialization Routines
>>
>> //===----------------------------------------------------------------------===//
>>
>> -/// Emit the list of attributes to the specified record.
>> -void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
>> +void ASTRecordWriter::AddAttr(const Attr *A) {
>> auto &Record = *this;
>> - Record.push_back(Attrs.size());
>> - for (const auto *A : Attrs) {
>> - Record.push_back(A->getKind()); // FIXME: stable encoding, target
>> attrs
>> - Record.AddSourceRange(A->getRange());
>> + if (!A)
>> + return Record.push_back(0);
>> + Record.push_back(A->getKind() + 1); // FIXME: stable encoding,
>> target attrs
>> + Record.AddSourceRange(A->getRange());
>> #include "clang/Serialization/AttrPCHWrite.inc"
>> - }
>> +}
>> +
>> +/// Emit the list of attributes to the specified record.
>> +void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
>> + push_back(Attrs.size());
>> + for (const auto *A : Attrs)
>> + AddAttr(A);
>> }
>> void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) {
>>
>> Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerHelpers.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/StaticAnalyzer/Core/CheckerHelpers.cpp (original)
>> +++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerHelpers.cpp Mon Aug 20
>> 14:47:29 2018
>> @@ -103,9 +103,9 @@ Nullability getNullabilityAnnotation(Qua
>> const auto *AttrType = Type->getAs<AttributedType>();
>> if (!AttrType)
>> return Nullability::Unspecified;
>> - if (AttrType->getAttrKind() == AttributedType::attr_nullable)
>> + if (AttrType->getAttrKind() == attr::TypeNullable)
>> return Nullability::Nullable;
>> - else if (AttrType->getAttrKind() == AttributedType::attr_nonnull)
>> + else if (AttrType->getAttrKind() == attr::TypeNonNull)
>> return Nullability::Nonnull;
>> return Nullability::Unspecified;
>> }
>>
>> Modified: cfe/trunk/test/SemaCXX/calling-conv-compat.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/calling-conv-compat.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/test/SemaCXX/calling-conv-compat.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/calling-conv-compat.cpp Mon Aug 20 14:47:29
>> 2018
>> @@ -1,4 +1,8 @@
>> // RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -verify
>> -triple i686-pc-win32 %s
>> +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -verify
>> -triple x86_64-pc-win32 %s
>> +
>> +// FIXME: Extend this portion of the test to cover the 64-bit case.
>> +#if !_M_X64
>> // Pointers to free functions
>> void free_func_default();
>> @@ -244,11 +248,16 @@ void call_member_inheritance() {
>> }
>> } // end namespace NonVariadic
>> +#endif // !_M_X64
>> +
>> namespace Variadic {
>> struct A {
>> void member_default(int, ...);
>> void __cdecl member_cdecl(int, ...);
>> - void __thiscall member_thiscall(int, ...); // expected-error
>> {{variadic function cannot use thiscall calling convention}}
>> + void __thiscall member_thiscall(int, ...);
>> +#if !_M_X64
>> + // expected-error at -2 {{variadic function cannot use thiscall
>> calling convention}}
>> +#endif
>> };
>> struct B : public A {
>> @@ -319,7 +328,10 @@ mptr_t __stdcall return_mptr_std(short)
>> }
>> void (A::*(*return_fptr_std_mptr(char))(short))(int) {
>> - return return_mptr_std; // expected-error {{cannot initialize
>> return object of type 'void (MultiChunkDecls::A::*(*)(short))(int)
>> __attribute__((thiscall))' with an lvalue of type
>> 'MultiChunkDecls::mptr_t (short) __attribute__((stdcall))'}}
>> + return return_mptr_std;
>> +#if !_M_X64
>> + // expected-error at -2 {{cannot initialize return object of type
>> 'void (MultiChunkDecls::A::*(*)(short))(int)
>> __attribute__((thiscall))' with an lvalue of type
>> 'MultiChunkDecls::mptr_t (short) __attribute__((stdcall))'}}
>> +#endif
>> }
>> void call_return() {
>> @@ -387,15 +399,32 @@ Y<decltype(&A::method_thiscall)>::p tmpl
>> // Test that lambdas that capture nothing convert to cdecl function
>> pointers.
>> namespace Lambdas {
>> -
>> void pass_fptr_cdecl (void (__cdecl *fp)());
>> -void pass_fptr_stdcall (void (__stdcall *fp)()); // expected-note
>> {{candidate function not viable}}
>> -void pass_fptr_fastcall(void (__fastcall *fp)()); // expected-note
>> {{candidate function not viable}}
>> +void pass_fptr_stdcall (void (__stdcall *fp)());
>> +void pass_fptr_fastcall(void (__fastcall *fp)());
>> void conversion_to_fptr() {
>> pass_fptr_cdecl ([]() { } );
>> - pass_fptr_stdcall ([]() { } ); // expected-error {{no matching
>> function for call}}
>> - pass_fptr_fastcall([]() { } ); // expected-error {{no matching
>> function for call}}
>> +
>> + pass_fptr_stdcall ([]() { } );
>> +#if !_M_X64
>> + // expected-error at -2 {{no matching function for call}}
>> + // expected-note at -9 {{candidate function not viable}}
>> +#endif
>> +
>> + pass_fptr_fastcall([]() { } );
>> +#if !_M_X64
>> + // expected-error at -2 {{no matching function for call}}
>> + // expected-note at -14 {{candidate function not viable}}
>> +#endif
>> +}
>> }
>> +namespace D50526 {
>> + template<typename T, T (__stdcall f)()> void g();
>> + void h() { g<void, h>(); }
>> +#if !_M_X64
>> + // expected-error at -2 {{no matching function for call to}}
>> + // expected-note at -4 {{invalid explicitly-specified argument}}
>> +#endif
>> }
>>
>> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=340215&r1=340214&r2=340215&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
>> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Aug 20 14:47:29
>> 2018
>> @@ -2470,8 +2470,10 @@ namespace {
>> static const AttrClassDescriptor AttrClassDescriptors[] = {
>> { "ATTR", "Attr" },
>> + { "TYPE_ATTR", "TypeAttr" },
>> { "STMT_ATTR", "StmtAttr" },
>> { "INHERITABLE_ATTR", "InheritableAttr" },
>> + { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" },
>> { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
>> { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
>> };
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
More information about the cfe-commits
mailing list