[NFC] Rename clang::AttributeList to clang::ParsedAttr

Since The type no longer contains the 'next' item anymore, it isn't a list,
so rename it to ParsedAttr to be more accurate.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337005 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Erich Keane 2018-07-13 15:07:47 +00:00
parent ff0bfffe18
commit 74701fe1cf
26 changed files with 1070 additions and 1140 deletions

View File

@ -1664,15 +1664,15 @@ and then the semantic handling of the attribute.
Parsing of the attribute is determined by the various syntactic forms attributes Parsing of the attribute is determined by the various syntactic forms attributes
can take, such as GNU, C++11, and Microsoft style attributes, as well as other can take, such as GNU, C++11, and Microsoft style attributes, as well as other
information provided by the table definition of the attribute. Ultimately, the information provided by the table definition of the attribute. Ultimately, the
parsed representation of an attribute object is an ``AttributeList`` object. parsed representation of an attribute object is an ``ParsedAttr`` object.
These parsed attributes chain together as a list of parsed attributes attached These parsed attributes chain together as a list of parsed attributes attached
to a declarator or declaration specifier. The parsing of attributes is handled to a declarator or declaration specifier. The parsing of attributes is handled
automatically by Clang, except for attributes spelled as keywords. When automatically by Clang, except for attributes spelled as keywords. When
implementing a keyword attribute, the parsing of the keyword and creation of the implementing a keyword attribute, the parsing of the keyword and creation of the
``AttributeList`` object must be done manually. ``ParsedAttr`` object must be done manually.
Eventually, ``Sema::ProcessDeclAttributeList()`` is called with a ``Decl`` and Eventually, ``Sema::ProcessDeclAttributeList()`` is called with a ``Decl`` and
an ``AttributeList``, at which point the parsed attribute can be transformed an ``ParsedAttr``, at which point the parsed attribute can be transformed
into a semantic attribute. The process by which a parsed attribute is converted into a semantic attribute. The process by which a parsed attribute is converted
into a semantic attribute depends on the attribute definition and semantic into a semantic attribute depends on the attribute definition and semantic
requirements of the attribute. The end result, however, is that the semantic requirements of the attribute. The end result, however, is that the semantic
@ -1751,8 +1751,8 @@ subjects in the list, but a custom diagnostic parameter can also be specified in
the ``SubjectList``. The diagnostics generated for subject list violations are the ``SubjectList``. The diagnostics generated for subject list violations are
either ``diag::warn_attribute_wrong_decl_type`` or either ``diag::warn_attribute_wrong_decl_type`` or
``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found ``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found
in `include/clang/Sema/AttributeList.h in `include/clang/Sema/ParsedAttr.h
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup>`_ <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?view=markup>`_
If a previously unused Decl node is added to the ``SubjectList``, the logic used If a previously unused Decl node is added to the ``SubjectList``, the logic used
to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp
<http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_ <http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
@ -1887,7 +1887,7 @@ requirements. To support this feature, an attribute inheriting from
should be the same value between all arguments sharing a spelling, and should be the same value between all arguments sharing a spelling, and
corresponds to the parsed attribute's ``Kind`` enumerator. This allows corresponds to the parsed attribute's ``Kind`` enumerator. This allows
attributes to share a parsed attribute kind, but have distinct semantic attributes to share a parsed attribute kind, but have distinct semantic
attribute classes. For instance, ``AttributeList::AT_Interrupt`` is the shared attribute classes. For instance, ``ParsedAttr`` is the shared
parsed attribute kind, but ARMInterruptAttr and MSP430InterruptAttr are the parsed attribute kind, but ARMInterruptAttr and MSP430InterruptAttr are the
semantic attributes generated. semantic attributes generated.

View File

@ -509,7 +509,7 @@ class TargetSpecificAttr<TargetSpec target> {
// "exists" for a given target. So two target-specific attributes can share // "exists" for a given target. So two target-specific attributes can share
// the same name when they exist in different targets. To support this, a // the same name when they exist in different targets. To support this, a
// Kind can be explicitly specified for a target-specific attribute. This // Kind can be explicitly specified for a target-specific attribute. This
// corresponds to the AttributeList::AT_* enum that is generated and it // corresponds to the ParsedAttr::AT_* enum that is generated and it
// should contain a shared value between the attributes. // should contain a shared value between the attributes.
// //
// Target-specific attributes which use this feature should ensure that the // Target-specific attributes which use this feature should ensure that the

View File

@ -238,7 +238,7 @@ class Parser : public CodeCompletionHandler {
unsigned getDepth() const { return Depth; } unsigned getDepth() const { return Depth; }
}; };
/// Factory object for creating AttributeList objects. /// Factory object for creating ParsedAttr objects.
AttributeFactory AttrFactory; AttributeFactory AttrFactory;
/// Gathers and cleans up TemplateIdAnnotations when parsing of a /// Gathers and cleans up TemplateIdAnnotations when parsing of a
@ -2361,7 +2361,7 @@ private:
ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc, ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc, IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax); ParsedAttr::Syntax Syntax);
void MaybeParseGNUAttributes(Declarator &D, void MaybeParseGNUAttributes(Declarator &D,
LateParsedAttrList *LateAttrs = nullptr) { LateParsedAttrList *LateAttrs = nullptr) {
@ -2384,19 +2384,16 @@ private:
Declarator *D = nullptr); Declarator *D = nullptr);
void ParseGNUAttributeArgs(IdentifierInfo *AttrName, void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, ParsedAttributes &Attrs, SourceLocation *EndLoc,
SourceLocation *EndLoc, IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
IdentifierInfo *ScopeName, ParsedAttr::Syntax Syntax, Declarator *D);
SourceLocation ScopeLoc,
AttributeList::Syntax Syntax,
Declarator *D);
IdentifierLoc *ParseIdentifierLoc(); IdentifierLoc *ParseIdentifierLoc();
unsigned unsigned
ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc, ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc, IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax); ParsedAttr::Syntax Syntax);
void MaybeParseCXX11Attributes(Declarator &D) { void MaybeParseCXX11Attributes(Declarator &D) {
if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
@ -2482,7 +2479,7 @@ private:
SourceLocation *endLoc, SourceLocation *endLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax); ParsedAttr::Syntax Syntax);
Optional<AvailabilitySpec> ParseAvailabilitySpec(); Optional<AvailabilitySpec> ParseAvailabilitySpec();
ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc); ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
@ -2493,7 +2490,7 @@ private:
SourceLocation *EndLoc, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax); ParsedAttr::Syntax Syntax);
void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated, void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
SourceLocation ObjCBridgeRelatedLoc, SourceLocation ObjCBridgeRelatedLoc,
@ -2501,7 +2498,7 @@ private:
SourceLocation *endLoc, SourceLocation *endLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax); ParsedAttr::Syntax Syntax);
void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc, SourceLocation AttrNameLoc,
@ -2509,15 +2506,13 @@ private:
SourceLocation *EndLoc, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax); ParsedAttr::Syntax Syntax);
void ParseAttributeWithTypeArg(IdentifierInfo &AttrName, void
SourceLocation AttrNameLoc, ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
ParsedAttributes &Attrs, SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
SourceLocation *EndLoc, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax);
SourceLocation ScopeLoc,
AttributeList::Syntax Syntax);
void ParseTypeofSpecifier(DeclSpec &DS); void ParseTypeofSpecifier(DeclSpec &DS);
SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);

View File

@ -29,8 +29,8 @@
#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h" #include "clang/Basic/Specifiers.h"
#include "clang/Lex/Token.h" #include "clang/Lex/Token.h"
#include "clang/Sema/AttributeList.h"
#include "clang/Sema/Ownership.h" #include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
@ -2406,7 +2406,7 @@ public:
/// Return a source range list of C++11 attributes associated /// Return a source range list of C++11 attributes associated
/// with the declarator. /// with the declarator.
void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) {
for (const AttributeList &AL : Attrs) for (const ParsedAttr &AL : Attrs)
if (AL.isCXX11Attribute()) if (AL.isCXX11Attribute())
Ranges.push_back(AL.getRange()); Ranges.push_back(AL.getRange());
} }

View File

@ -12,8 +12,8 @@
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceLocation.h"
#include "clang/Sema/AttributeList.h"
#include "clang/Sema/Ownership.h" #include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
namespace clang { namespace clang {

View File

@ -1,4 +1,4 @@
//===- AttributeList.h - Parsed attribute sets ------------------*- C++ -*-===// //======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -7,7 +7,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines the AttributeList class, which is used to collect // This file defines the ParsedAttr class, which is used to collect
// parsed attributes. // parsed attributes.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -60,7 +60,7 @@ enum AvailabilitySlot {
IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
}; };
/// Describes the trailing object for Availability attribute in AttributeList. /// Describes the trailing object for Availability attribute in ParsedAttr.
struct AvailabilityData { struct AvailabilityData {
AvailabilityChange Changes[NumAvailabilitySlots]; AvailabilityChange Changes[NumAvailabilitySlots];
SourceLocation StrictLoc; SourceLocation StrictLoc;
@ -89,11 +89,11 @@ struct IdentifierLoc {
}; };
/// A union of the various pointer types that can be passed to an /// A union of the various pointer types that can be passed to an
/// AttributeList as an argument. /// ParsedAttr as an argument.
using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>; using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>; using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
/// AttributeList - Represents a syntactic attribute. /// ParsedAttr - Represents a syntactic attribute.
/// ///
/// For a GNU attribute, there are four forms of this construct: /// For a GNU attribute, there are four forms of this construct:
/// ///
@ -102,7 +102,7 @@ using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
/// ///
class AttributeList { // TODO: This should really be called ParsedAttribute class ParsedAttr { // TODO: This should really be called ParsedAttribute
public: public:
/// The style used to specify an attribute. /// The style used to specify an attribute.
enum Syntax { enum Syntax {
@ -215,10 +215,10 @@ private:
friend class AttributePool; friend class AttributePool;
/// Constructor for attributes with expression arguments. /// Constructor for attributes with expression arguments.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
ArgsUnion *args, unsigned numArgs, ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
Syntax syntaxUsed, SourceLocation ellipsisLoc) SourceLocation ellipsisLoc)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
@ -229,15 +229,13 @@ private:
} }
/// Constructor for availability attributes. /// Constructor for availability attributes.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Parm, const AvailabilityChange &introduced, IdentifierLoc *Parm, const AvailabilityChange &introduced,
const AvailabilityChange &deprecated, const AvailabilityChange &deprecated,
const AvailabilityChange &obsoleted, const AvailabilityChange &obsoleted, SourceLocation unavailable,
SourceLocation unavailable, const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
const Expr *messageExpr, const Expr *replacementExpr)
Syntax syntaxUsed, SourceLocation strict,
const Expr *replacementExpr)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(true), UsedAsTypeAttr(false), IsAvailability(true),
@ -252,12 +250,10 @@ private:
} }
/// Constructor for objc_bridge_related attributes. /// Constructor for objc_bridge_related attributes.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Parm1, IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
IdentifierLoc *Parm2, Syntax syntaxUsed)
IdentifierLoc *Parm3,
Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false), ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false), UsedAsTypeAttr(false), IsAvailability(false),
@ -271,10 +267,10 @@ private:
} }
/// Constructor for type_tag_for_datatype attribute. /// Constructor for type_tag_for_datatype attribute.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *ArgKind, ParsedType matchingCType, IdentifierLoc *ArgKind, ParsedType matchingCType,
bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false), UsedAsTypeAttr(false), IsAvailability(false),
@ -290,9 +286,9 @@ private:
} }
/// Constructor for attributes with a single type argument. /// Constructor for attributes with a single type argument.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
ParsedType typeArg, Syntax syntaxUsed) ParsedType typeArg, Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false), UsedAsTypeAttr(false), IsAvailability(false),
@ -303,13 +299,13 @@ private:
} }
/// Constructor for microsoft __declspec(property) attribute. /// Constructor for microsoft __declspec(property) attribute.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *getterId, IdentifierInfo *setterId, IdentifierInfo *getterId, IdentifierInfo *setterId,
Syntax syntaxUsed) Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
HasProcessingCache(false) { HasProcessingCache(false) {
new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
@ -350,9 +346,9 @@ private:
size_t allocated_size() const; size_t allocated_size() const;
public: public:
AttributeList(const AttributeList &) = delete; ParsedAttr(const ParsedAttr &) = delete;
AttributeList &operator=(const AttributeList &) = delete; ParsedAttr &operator=(const ParsedAttr &) = delete;
~AttributeList() = delete; ~ParsedAttr() = delete;
void operator delete(void *) = delete; void operator delete(void *) = delete;
@ -559,18 +555,17 @@ public:
/// The required allocation size of an availability attribute, /// The required allocation size of an availability attribute,
/// which we want to ensure is a multiple of sizeof(void*). /// which we want to ensure is a multiple of sizeof(void*).
AvailabilityAllocSize = AvailabilityAllocSize =
sizeof(AttributeList) sizeof(ParsedAttr) +
+ ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1) ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
/ sizeof(void*) * sizeof(void*)), sizeof(void *) * sizeof(void *)),
TypeTagForDatatypeAllocSize = TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
sizeof(AttributeList) (sizeof(ParsedAttr::TypeTagForDatatypeData) +
+ (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
sizeof(ArgsUnion) - 1) sizeof(void *) * sizeof(void *),
/ sizeof(void*) * sizeof(void*),
PropertyAllocSize = PropertyAllocSize =
sizeof(AttributeList) sizeof(ParsedAttr) +
+ (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1) (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
/ sizeof(void*) * sizeof(void*) sizeof(void *) * sizeof(void *)
}; };
private: private:
@ -581,15 +576,14 @@ private:
/// attribute that needs more than that; on x86-64 you'd need 10 /// attribute that needs more than that; on x86-64 you'd need 10
/// expression arguments, and on i386 you'd need 19. /// expression arguments, and on i386 you'd need 19.
InlineFreeListsCapacity = InlineFreeListsCapacity =
1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*) 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
}; };
llvm::BumpPtrAllocator Alloc; llvm::BumpPtrAllocator Alloc;
/// Free lists. The index is determined by the following formula: /// Free lists. The index is determined by the following formula:
/// (size - sizeof(AttributeList)) / sizeof(void*) /// (size - sizeof(ParsedAttr)) / sizeof(void*)
SmallVector<SmallVector<AttributeList *, 8>, InlineFreeListsCapacity> SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
FreeLists;
// The following are the private interface used by AttributePool. // The following are the private interface used by AttributePool.
friend class AttributePool; friend class AttributePool;
@ -597,7 +591,7 @@ private:
/// Allocate an attribute of the given size. /// Allocate an attribute of the given size.
void *allocate(size_t size); void *allocate(size_t size);
void deallocate(AttributeList *AL); void deallocate(ParsedAttr *AL);
/// Reclaim all the attributes in the given pool chain, which is /// Reclaim all the attributes in the given pool chain, which is
/// non-empty. Note that the current implementation is safe /// non-empty. Note that the current implementation is safe
@ -614,18 +608,18 @@ public:
class AttributePool { class AttributePool {
friend class AttributeFactory; friend class AttributeFactory;
AttributeFactory &Factory; AttributeFactory &Factory;
llvm::TinyPtrVector<AttributeList *> Attrs; llvm::TinyPtrVector<ParsedAttr *> Attrs;
void *allocate(size_t size) { void *allocate(size_t size) {
return Factory.allocate(size); return Factory.allocate(size);
} }
AttributeList *add(AttributeList *attr) { ParsedAttr *add(ParsedAttr *attr) {
Attrs.push_back(attr); Attrs.push_back(attr);
return attr; return attr;
} }
void remove(AttributeList *attr) { void remove(ParsedAttr *attr) {
assert(llvm::is_contained(Attrs, attr) && assert(llvm::is_contained(Attrs, attr) &&
"Can't take attribute from a pool that doesn't own it!"); "Can't take attribute from a pool that doesn't own it!");
Attrs.erase(llvm::find(Attrs, attr)); Attrs.erase(llvm::find(Attrs, attr));
@ -657,97 +651,93 @@ public:
pool.Attrs.clear(); pool.Attrs.clear();
} }
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
ArgsUnion *args, unsigned numArgs, ArgsUnion *args, unsigned numArgs,
AttributeList::Syntax syntax, ParsedAttr::Syntax syntax,
SourceLocation ellipsisLoc = SourceLocation()) { SourceLocation ellipsisLoc = SourceLocation()) {
void *memory = void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
allocate(sizeof(AttributeList) + numArgs * sizeof(ArgsUnion)); return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
return add(new (memory) args, numArgs, syntax, ellipsisLoc));
AttributeList(attrName, attrRange, scopeName, scopeLoc, args,
numArgs, syntax, ellipsisLoc));
} }
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param, IdentifierLoc *Param, const AvailabilityChange &introduced,
const AvailabilityChange &introduced, const AvailabilityChange &deprecated,
const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted,
const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr,
SourceLocation unavailable, const Expr *MessageExpr, ParsedAttr::Syntax syntax, SourceLocation strict,
AttributeList::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr) {
const Expr *ReplacementExpr) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize); void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
return add(new (memory) AttributeList( return add(new (memory) ParsedAttr(
attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr)); obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
} }
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param1, IdentifierLoc *Param2,
IdentifierLoc *Param3, AttributeList::Syntax syntax) { IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion); size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
void *memory = allocate(size); void *memory = allocate(size);
return add(new (memory) return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
AttributeList(attrName, attrRange, scopeName, scopeLoc, Param1, Param2, Param3, syntax));
Param1, Param2, Param3, syntax));
} }
AttributeList * ParsedAttr *
createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *argumentKind, IdentifierLoc *argumentKind,
ParsedType matchingCType, bool layoutCompatible, ParsedType matchingCType, bool layoutCompatible,
bool mustBeNull, AttributeList::Syntax syntax) { bool mustBeNull, ParsedAttr::Syntax syntax) {
void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
return add(new (memory) AttributeList( return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType, argumentKind, matchingCType,
layoutCompatible, mustBeNull, syntax)); layoutCompatible, mustBeNull, syntax));
} }
AttributeList * ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName,
ParsedType typeArg, AttributeList::Syntax syntaxUsed) { SourceLocation scopeLoc, ParsedType typeArg,
void *memory = allocate(sizeof(AttributeList) + sizeof(void *)); ParsedAttr::Syntax syntaxUsed) {
return add(new (memory) AttributeList(attrName, attrRange, scopeName, void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
scopeLoc, typeArg, syntaxUsed)); return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
typeArg, syntaxUsed));
} }
AttributeList * ParsedAttr *
createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *getterId, IdentifierInfo *setterId, IdentifierInfo *getterId, IdentifierInfo *setterId,
AttributeList::Syntax syntaxUsed) { ParsedAttr::Syntax syntaxUsed) {
void *memory = allocate(AttributeFactory::PropertyAllocSize); void *memory = allocate(AttributeFactory::PropertyAllocSize);
return add(new (memory) return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
AttributeList(attrName, attrRange, scopeName, scopeLoc, getterId, setterId, syntaxUsed));
getterId, setterId, syntaxUsed));
} }
}; };
class ParsedAttributesView { class ParsedAttributesView {
using VecTy = llvm::TinyPtrVector<AttributeList *>; using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
using SizeType = decltype(std::declval<VecTy>().size()); using SizeType = decltype(std::declval<VecTy>().size());
public: public:
bool empty() const { return AttrList.empty(); } bool empty() const { return AttrList.empty(); }
SizeType size() const { return AttrList.size(); } SizeType size() const { return AttrList.size(); }
AttributeList &operator[](SizeType pos) { return *AttrList[pos]; } ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
const AttributeList &operator[](SizeType pos) const { return *AttrList[pos]; } const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
void addAtStart(AttributeList *newAttr) { void addAtStart(ParsedAttr *newAttr) {
assert(newAttr); assert(newAttr);
AttrList.insert(AttrList.begin(), newAttr); AttrList.insert(AttrList.begin(), newAttr);
} }
void addAtEnd(AttributeList *newAttr) { void addAtEnd(ParsedAttr *newAttr) {
assert(newAttr); assert(newAttr);
AttrList.push_back(newAttr); AttrList.push_back(newAttr);
} }
void remove(AttributeList *ToBeRemoved) { void remove(ParsedAttr *ToBeRemoved) {
assert(is_contained(AttrList, ToBeRemoved) && assert(is_contained(AttrList, ToBeRemoved) &&
"Cannot remove attribute that isn't in the list"); "Cannot remove attribute that isn't in the list");
AttrList.erase(llvm::find(AttrList, ToBeRemoved)); AttrList.erase(llvm::find(AttrList, ToBeRemoved));
@ -757,7 +747,7 @@ public:
struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator, struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
std::random_access_iterator_tag, std::random_access_iterator_tag,
AttributeList> { ParsedAttr> {
iterator() : iterator_adaptor_base(nullptr) {} iterator() : iterator_adaptor_base(nullptr) {}
iterator(VecTy::iterator I) : iterator_adaptor_base(I) {} iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
reference operator*() { return **I; } reference operator*() { return **I; }
@ -766,7 +756,7 @@ public:
struct const_iterator struct const_iterator
: llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator, : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
std::random_access_iterator_tag, std::random_access_iterator_tag,
AttributeList> { ParsedAttr> {
const_iterator() : iterator_adaptor_base(nullptr) {} const_iterator() : iterator_adaptor_base(nullptr) {}
const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {} const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
@ -795,9 +785,9 @@ public:
iterator end() { return iterator(AttrList.end()); } iterator end() { return iterator(AttrList.end()); }
const_iterator end() const { return const_iterator(AttrList.end()); } const_iterator end() const { return const_iterator(AttrList.end()); }
bool hasAttribute(AttributeList::Kind K) const { bool hasAttribute(ParsedAttr::Kind K) const {
return llvm::any_of( return llvm::any_of(
AttrList, [K](const AttributeList *AL) { return AL->getKind() == K; }); AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; });
} }
private: private:
@ -829,86 +819,76 @@ public:
} }
/// Add attribute with expression arguments. /// Add attribute with expression arguments.
AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
ArgsUnion *args, unsigned numArgs, ArgsUnion *args, unsigned numArgs,
AttributeList::Syntax syntax, ParsedAttr::Syntax syntax,
SourceLocation ellipsisLoc = SourceLocation()) { SourceLocation ellipsisLoc = SourceLocation()) {
AttributeList *attr = ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs, args, numArgs, syntax, ellipsisLoc);
syntax, ellipsisLoc);
addAtStart(attr); addAtStart(attr);
return attr; return attr;
} }
/// Add availability attribute. /// Add availability attribute.
AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param, IdentifierLoc *Param, const AvailabilityChange &introduced,
const AvailabilityChange &introduced, const AvailabilityChange &deprecated,
const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted,
const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr,
SourceLocation unavailable, ParsedAttr::Syntax syntax, SourceLocation strict,
const Expr *MessageExpr, const Expr *ReplacementExpr) {
AttributeList::Syntax syntax, ParsedAttr *attr = pool.create(
SourceLocation strict, const Expr *ReplacementExpr) { attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
AttributeList *attr = obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
deprecated, obsoleted, unavailable, MessageExpr, syntax,
strict, ReplacementExpr);
addAtStart(attr); addAtStart(attr);
return attr; return attr;
} }
/// Add objc_bridge_related attribute. /// Add objc_bridge_related attribute.
AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param1, IdentifierLoc *Param1, IdentifierLoc *Param2,
IdentifierLoc *Param2, IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
IdentifierLoc *Param3, ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
AttributeList::Syntax syntax) { Param1, Param2, Param3, syntax);
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc,
Param1, Param2, Param3, syntax);
addAtStart(attr); addAtStart(attr);
return attr; return attr;
} }
/// Add type_tag_for_datatype attribute. /// Add type_tag_for_datatype attribute.
AttributeList *addNewTypeTagForDatatype( ParsedAttr *
IdentifierInfo *attrName, SourceRange attrRange, addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *argumentKind, ParsedType matchingCType, IdentifierLoc *argumentKind,
bool layoutCompatible, bool mustBeNull, ParsedType matchingCType, bool layoutCompatible,
AttributeList::Syntax syntax) { bool mustBeNull, ParsedAttr::Syntax syntax) {
AttributeList *attr = ParsedAttr *attr = pool.createTypeTagForDatatype(
pool.createTypeTagForDatatype(attrName, attrRange, attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
scopeName, scopeLoc, layoutCompatible, mustBeNull, syntax);
argumentKind, matchingCType,
layoutCompatible, mustBeNull, syntax);
addAtStart(attr); addAtStart(attr);
return attr; return attr;
} }
/// Add an attribute with a single type argument. /// Add an attribute with a single type argument.
AttributeList * ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg,
ParsedType typeArg, AttributeList::Syntax syntaxUsed) { ParsedAttr::Syntax syntaxUsed) {
AttributeList *attr = ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc, scopeLoc, typeArg, syntaxUsed);
typeArg, syntaxUsed);
addAtStart(attr); addAtStart(attr);
return attr; return attr;
} }
/// Add microsoft __delspec(property) attribute. /// Add microsoft __delspec(property) attribute.
AttributeList * ParsedAttr *
addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *getterId, IdentifierInfo *setterId, IdentifierInfo *getterId, IdentifierInfo *setterId,
AttributeList::Syntax syntaxUsed) { ParsedAttr::Syntax syntaxUsed) {
AttributeList *attr = ParsedAttr *attr =
pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
getterId, setterId, syntaxUsed); getterId, setterId, syntaxUsed);
addAtStart(attr); addAtStart(attr);

View File

@ -76,7 +76,7 @@ namespace clang {
class ASTReader; class ASTReader;
class ASTWriter; class ASTWriter;
class ArrayType; class ArrayType;
class AttributeList; class ParsedAttr;
class BindingDecl; class BindingDecl;
class BlockDecl; class BlockDecl;
class CapturedDecl; class CapturedDecl;
@ -494,7 +494,7 @@ public:
/// \#pragma clang attribute. /// \#pragma clang attribute.
struct PragmaAttributeEntry { struct PragmaAttributeEntry {
SourceLocation Loc; SourceLocation Loc;
AttributeList *Attribute; ParsedAttr *Attribute;
SmallVector<attr::SubjectMatchRule, 4> MatchRules; SmallVector<attr::SubjectMatchRule, 4> MatchRules;
bool IsUsed; bool IsUsed;
}; };
@ -2224,7 +2224,7 @@ public:
Expr *BitfieldWidth, Expr *BitfieldWidth,
InClassInitStyle InitStyle, InClassInitStyle InitStyle,
AccessSpecifier AS, AccessSpecifier AS,
const AttributeList &MSPropertyAttr); const ParsedAttr &MSPropertyAttr);
FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo, TypeSourceInfo *TInfo,
@ -3321,11 +3321,10 @@ public:
// Helper for delayed processing of attributes. // Helper for delayed processing of attributes.
void ProcessDeclAttributeDelayed(Decl *D, void ProcessDeclAttributeDelayed(Decl *D,
const ParsedAttributesView &AttrList); const ParsedAttributesView &AttrList);
void ProcessDeclAttributeList(Scope *S, Decl *D, void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL,
const ParsedAttributesView &AL, bool IncludeCXX11Attributes = true);
bool IncludeCXX11Attributes = true);
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
const ParsedAttributesView &AttrList); const ParsedAttributesView &AttrList);
void checkUnusedDeclAttributes(Declarator &D); void checkUnusedDeclAttributes(Declarator &D);
@ -3335,13 +3334,13 @@ public:
/// type as valid. /// type as valid.
bool isValidPointerAttrType(QualType T, bool RefOkay = false); bool isValidPointerAttrType(QualType T, bool RefOkay = false);
bool CheckRegparmAttr(const AttributeList &attr, unsigned &value); bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value);
bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC,
const FunctionDecl *FD = nullptr); const FunctionDecl *FD = nullptr);
bool CheckAttrTarget(const AttributeList &CurrAttr); bool CheckAttrTarget(const ParsedAttr &CurrAttr);
bool CheckAttrNoArgs(const AttributeList &CurrAttr); bool CheckAttrNoArgs(const ParsedAttr &CurrAttr);
bool checkStringLiteralArgumentAttr(const AttributeList &Attr, bool checkStringLiteralArgumentAttr(const ParsedAttr &Attr, unsigned ArgNum,
unsigned ArgNum, StringRef &Str, StringRef &Str,
SourceLocation *ArgLocation = nullptr); SourceLocation *ArgLocation = nullptr);
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); bool checkSectionName(SourceLocation LiteralLoc, StringRef Str);
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
@ -8446,8 +8445,7 @@ public:
void AddCFAuditedAttribute(Decl *D); void AddCFAuditedAttribute(Decl *D);
/// Called on well-formed '\#pragma clang attribute push'. /// Called on well-formed '\#pragma clang attribute push'.
void ActOnPragmaAttributePush(AttributeList &Attribute, void ActOnPragmaAttributePush(ParsedAttr &Attribute, SourceLocation PragmaLoc,
SourceLocation PragmaLoc,
attr::ParsedSubjectMatchRuleSet Rules); attr::ParsedSubjectMatchRuleSet Rules);
/// Called on well-formed '\#pragma clang attribute pop'. /// Called on well-formed '\#pragma clang attribute pop'.

View File

@ -162,14 +162,14 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
if (Tok.isNot(tok::l_paren)) { if (Tok.isNot(tok::l_paren)) {
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_GNU); ParsedAttr::AS_GNU);
continue; continue;
} }
// Handle "parameterized" attributes // Handle "parameterized" attributes
if (!LateAttrs || !isAttributeLateParsed(*AttrName)) { if (!LateAttrs || !isAttributeLateParsed(*AttrName)) {
ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, nullptr, ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, nullptr,
SourceLocation(), AttributeList::AS_GNU, D); SourceLocation(), ParsedAttr::AS_GNU, D);
continue; continue;
} }
@ -249,7 +249,7 @@ void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
SourceLocation *EndLoc, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax) { ParsedAttr::Syntax Syntax) {
BalancedDelimiterTracker Parens(*this, tok::l_paren); BalancedDelimiterTracker Parens(*this, tok::l_paren);
Parens.consumeOpen(); Parens.consumeOpen();
@ -275,7 +275,7 @@ void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
unsigned Parser::ParseAttributeArgsCommon( unsigned Parser::ParseAttributeArgsCommon(
IdentifierInfo *AttrName, SourceLocation AttrNameLoc, IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, AttributeList::Syntax Syntax) { SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) {
// Ignore the left paren location for now. // Ignore the left paren location for now.
ConsumeParen(); ConsumeParen();
@ -283,13 +283,13 @@ unsigned Parser::ParseAttributeArgsCommon(
if (Tok.is(tok::identifier)) { if (Tok.is(tok::identifier)) {
// If this attribute wants an 'identifier' argument, make it so. // If this attribute wants an 'identifier' argument, make it so.
bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName); bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
AttributeList::Kind AttrKind = ParsedAttr::Kind AttrKind =
AttributeList::getKind(AttrName, ScopeName, Syntax); ParsedAttr::getKind(AttrName, ScopeName, Syntax);
// If we don't know how to parse this attribute, but this is the only // If we don't know how to parse this attribute, but this is the only
// token in this argument, assume it's meant to be an identifier. // token in this argument, assume it's meant to be an identifier.
if (AttrKind == AttributeList::UnknownAttribute || if (AttrKind == ParsedAttr::UnknownAttribute ||
AttrKind == AttributeList::IgnoredAttribute) { AttrKind == ParsedAttr::IgnoredAttribute) {
const Token &Next = NextToken(); const Token &Next = NextToken();
IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma); IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
} }
@ -343,27 +343,27 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation *EndLoc, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax, ParsedAttr::Syntax Syntax,
Declarator *D) { Declarator *D) {
assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
AttributeList::Kind AttrKind = ParsedAttr::Kind AttrKind =
AttributeList::getKind(AttrName, ScopeName, Syntax); ParsedAttr::getKind(AttrName, ScopeName, Syntax);
if (AttrKind == AttributeList::AT_Availability) { if (AttrKind == ParsedAttr::AT_Availability) {
ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
ScopeLoc, Syntax); ScopeLoc, Syntax);
return; return;
} else if (AttrKind == AttributeList::AT_ExternalSourceSymbol) { } else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
return; return;
} else if (AttrKind == AttributeList::AT_ObjCBridgeRelated) { } else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
return; return;
} else if (AttrKind == AttributeList::AT_TypeTagForDatatype) { } else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
return; return;
@ -395,29 +395,29 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
unsigned Parser::ParseClangAttributeArgs( unsigned Parser::ParseClangAttributeArgs(
IdentifierInfo *AttrName, SourceLocation AttrNameLoc, IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, AttributeList::Syntax Syntax) { SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) {
assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
AttributeList::Kind AttrKind = ParsedAttr::Kind AttrKind =
AttributeList::getKind(AttrName, ScopeName, Syntax); ParsedAttr::getKind(AttrName, ScopeName, Syntax);
switch (AttrKind) { switch (AttrKind) {
default: default:
return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
case AttributeList::AT_ExternalSourceSymbol: case ParsedAttr::AT_ExternalSourceSymbol:
ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
break; break;
case AttributeList::AT_Availability: case ParsedAttr::AT_Availability:
ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
ScopeLoc, Syntax); ScopeLoc, Syntax);
break; break;
case AttributeList::AT_ObjCBridgeRelated: case ParsedAttr::AT_ObjCBridgeRelated:
ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
break; break;
case AttributeList::AT_TypeTagForDatatype: case ParsedAttr::AT_TypeTagForDatatype:
ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax); ScopeName, ScopeLoc, Syntax);
break; break;
@ -549,14 +549,14 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
if (!HasInvalidAccessor) if (!HasInvalidAccessor)
Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, nullptr, SourceLocation(), Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, nullptr, SourceLocation(),
AccessorNames[AK_Get], AccessorNames[AK_Put], AccessorNames[AK_Get], AccessorNames[AK_Put],
AttributeList::AS_Declspec); ParsedAttr::AS_Declspec);
T.skipToEnd(); T.skipToEnd();
return !HasInvalidAccessor; return !HasInvalidAccessor;
} }
unsigned NumArgs = unsigned NumArgs =
ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr, ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
SourceLocation(), AttributeList::AS_Declspec); SourceLocation(), ParsedAttr::AS_Declspec);
// If this attribute's args were parsed, and it was expected to have // If this attribute's args were parsed, and it was expected to have
// arguments but none were provided, emit a diagnostic. // arguments but none were provided, emit a diagnostic.
@ -631,7 +631,7 @@ void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
if (!AttrHandled) if (!AttrHandled)
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Declspec); ParsedAttr::AS_Declspec);
} }
T.consumeClose(); T.consumeClose();
if (End) if (End)
@ -657,7 +657,7 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo(); IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken(); SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Keyword); ParsedAttr::AS_Keyword);
break; break;
} }
default: default:
@ -708,7 +708,7 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo(); IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken(); SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Keyword); ParsedAttr::AS_Keyword);
} }
} }
@ -718,7 +718,7 @@ void Parser::ParseOpenCLKernelAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo(); IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken(); SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Keyword); ParsedAttr::AS_Keyword);
} }
} }
@ -726,7 +726,7 @@ void Parser::ParseOpenCLQualifiers(ParsedAttributes &Attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo(); IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = Tok.getLocation(); SourceLocation AttrNameLoc = Tok.getLocation();
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Keyword); ParsedAttr::AS_Keyword);
} }
void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) { void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
@ -742,7 +742,7 @@ void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
Diag(AttrNameLoc, diag::ext_nullability) Diag(AttrNameLoc, diag::ext_nullability)
<< AttrName; << AttrName;
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Keyword); ParsedAttr::AS_Keyword);
break; break;
} }
default: default:
@ -905,7 +905,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
SourceLocation *endLoc, SourceLocation *endLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax) { ParsedAttr::Syntax Syntax) {
enum { Introduced, Deprecated, Obsoleted, Unknown }; enum { Introduced, Deprecated, Obsoleted, Unknown };
AvailabilityChange Changes[Unknown]; AvailabilityChange Changes[Unknown];
ExprResult MessageExpr, ReplacementExpr; ExprResult MessageExpr, ReplacementExpr;
@ -1122,7 +1122,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
void Parser::ParseExternalSourceSymbolAttribute( void Parser::ParseExternalSourceSymbolAttribute(
IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc, IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, AttributeList::Syntax Syntax) { SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) {
// Opening '('. // Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren); BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.expectAndConsume()) if (T.expectAndConsume())
@ -1236,7 +1236,7 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
SourceLocation *endLoc, SourceLocation *endLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax) { ParsedAttr::Syntax Syntax) {
// Opening '('. // Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren); BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen()) { if (T.consumeOpen()) {
@ -1415,7 +1415,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
Actions.ActOnReenterFunctionContext(Actions.CurScope, D); Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
nullptr, SourceLocation(), AttributeList::AS_GNU, nullptr, SourceLocation(), ParsedAttr::AS_GNU,
nullptr); nullptr);
if (HasFunScope) { if (HasFunScope) {
@ -1429,7 +1429,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
// If there are multiple decls, then the decl cannot be within the // If there are multiple decls, then the decl cannot be within the
// function scope. // function scope.
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
nullptr, SourceLocation(), AttributeList::AS_GNU, nullptr, SourceLocation(), ParsedAttr::AS_GNU,
nullptr); nullptr);
} }
} else { } else {
@ -1459,7 +1459,7 @@ void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation *EndLoc, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, IdentifierInfo *ScopeName,
SourceLocation ScopeLoc, SourceLocation ScopeLoc,
AttributeList::Syntax Syntax) { ParsedAttr::Syntax Syntax) {
assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
BalancedDelimiterTracker T(*this, tok::l_paren); BalancedDelimiterTracker T(*this, tok::l_paren);
@ -1581,10 +1581,10 @@ void Parser::DiagnoseProhibitedAttributes(
void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
unsigned DiagID) { unsigned DiagID) {
for (const AttributeList &AL : Attrs) { for (const ParsedAttr &AL : Attrs) {
if (!AL.isCXX11Attribute() && !AL.isC2xAttribute()) if (!AL.isCXX11Attribute() && !AL.isC2xAttribute())
continue; continue;
if (AL.getKind() == AttributeList::UnknownAttribute) if (AL.getKind() == ParsedAttr::UnknownAttribute)
Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName(); Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName();
else { else {
Diag(AL.getLoc(), DiagID) << AL.getName(); Diag(AL.getLoc(), DiagID) << AL.getName();
@ -1606,16 +1606,16 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
if (TUK == Sema::TUK_Reference) if (TUK == Sema::TUK_Reference)
return; return;
llvm::SmallVector<AttributeList *, 1> ToBeMoved; llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
for (AttributeList &AL : DS.getAttributes()) { for (ParsedAttr &AL : DS.getAttributes()) {
if ((AL.getKind() == AttributeList::AT_Aligned && if ((AL.getKind() == ParsedAttr::AT_Aligned &&
AL.isDeclspecAttribute()) || AL.isDeclspecAttribute()) ||
AL.isMicrosoftAttribute()) AL.isMicrosoftAttribute())
ToBeMoved.push_back(&AL); ToBeMoved.push_back(&AL);
} }
for (AttributeList *AL : ToBeMoved) { for (ParsedAttr *AL : ToBeMoved) {
DS.getAttributes().remove(AL); DS.getAttributes().remove(AL);
Attrs.addAtEnd(AL); Attrs.addAtEnd(AL);
} }
@ -2731,7 +2731,7 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
ArgsVector ArgExprs; ArgsVector ArgExprs;
ArgExprs.push_back(ArgExpr.get()); ArgExprs.push_back(ArgExpr.get());
Attrs.addNew(KWName, KWLoc, nullptr, KWLoc, ArgExprs.data(), 1, Attrs.addNew(KWName, KWLoc, nullptr, KWLoc, ArgExprs.data(), 1,
AttributeList::AS_Keyword, EllipsisLoc); ParsedAttr::AS_Keyword, EllipsisLoc);
} }
/// Determine whether we're looking at something that might be a declarator /// Determine whether we're looking at something that might be a declarator
@ -3321,7 +3321,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
IdentifierInfo *AttrName = Tok.getIdentifierInfo(); IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = Tok.getLocation(); SourceLocation AttrNameLoc = Tok.getLocation();
DS.getAttributes().addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, DS.getAttributes().addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc,
nullptr, 0, AttributeList::AS_Keyword); nullptr, 0, ParsedAttr::AS_Keyword);
break; break;
} }
@ -3364,7 +3364,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// Objective-C 'kindof' types. // Objective-C 'kindof' types.
case tok::kw___kindof: case tok::kw___kindof:
DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc, DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc,
nullptr, 0, AttributeList::AS_Keyword); nullptr, 0, ParsedAttr::AS_Keyword);
(void)ConsumeToken(); (void)ConsumeToken();
continue; continue;
@ -5195,7 +5195,7 @@ void Parser::ParseTypeQualifierListOpt(
// Objective-C 'kindof' types. // Objective-C 'kindof' types.
case tok::kw___kindof: case tok::kw___kindof:
DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc, DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc,
nullptr, 0, AttributeList::AS_Keyword); nullptr, 0, ParsedAttr::AS_Keyword);
(void)ConsumeToken(); (void)ConsumeToken();
continue; continue;

View File

@ -1206,7 +1206,7 @@ void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo(); IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken(); SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_Keyword); ParsedAttr::AS_Keyword);
} }
} }
@ -2284,7 +2284,7 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
if (!VS.isUnset()) { if (!VS.isUnset()) {
// If we saw any GNU-style attributes that are known to GCC followed by a // If we saw any GNU-style attributes that are known to GCC followed by a
// virt-specifier, issue a GCC-compat warning. // virt-specifier, issue a GCC-compat warning.
for (const AttributeList &AL : DeclaratorInfo.getAttributes()) for (const ParsedAttr &AL : DeclaratorInfo.getAttributes())
if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
Diag(AL.getLoc(), diag::warn_gcc_attribute_location); Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
@ -3803,16 +3803,15 @@ IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
IdentifierInfo *ScopeName) { IdentifierInfo *ScopeName) {
switch (AttributeList::getKind(AttrName, ScopeName, switch (ParsedAttr::getKind(AttrName, ScopeName, ParsedAttr::AS_CXX11)) {
AttributeList::AS_CXX11)) { case ParsedAttr::AT_CarriesDependency:
case AttributeList::AT_CarriesDependency: case ParsedAttr::AT_Deprecated:
case AttributeList::AT_Deprecated: case ParsedAttr::AT_FallThrough:
case AttributeList::AT_FallThrough: case ParsedAttr::AT_CXX11NoReturn:
case AttributeList::AT_CXX11NoReturn:
return true; return true;
case AttributeList::AT_WarnUnusedResult: case ParsedAttr::AT_WarnUnusedResult:
return !ScopeName && AttrName->getName().equals("nodiscard"); return !ScopeName && AttrName->getName().equals("nodiscard");
case AttributeList::AT_Unused: case ParsedAttr::AT_Unused:
return !ScopeName && AttrName->getName().equals("maybe_unused"); return !ScopeName && AttrName->getName().equals("maybe_unused");
default: default:
return false; return false;
@ -3842,8 +3841,8 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
SourceLocation LParenLoc = Tok.getLocation(); SourceLocation LParenLoc = Tok.getLocation();
const LangOptions &LO = getLangOpts(); const LangOptions &LO = getLangOpts();
AttributeList::Syntax Syntax = ParsedAttr::Syntax Syntax =
LO.CPlusPlus ? AttributeList::AS_CXX11 : AttributeList::AS_C2x; LO.CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x;
// If the attribute isn't known, we will not attempt to parse any // If the attribute isn't known, we will not attempt to parse any
// arguments. // arguments.
@ -3876,7 +3875,7 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
if (!Attrs.empty() && if (!Attrs.empty() &&
IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
AttributeList &Attr = *Attrs.begin(); ParsedAttr &Attr = *Attrs.begin();
// If the attribute is a standard or built-in attribute and we are // If the attribute is a standard or built-in attribute and we are
// parsing an argument list, we need to determine whether this attribute // parsing an argument list, we need to determine whether this attribute
// was allowed to have an argument list (such as [[deprecated]]), and how // was allowed to have an argument list (such as [[deprecated]]), and how
@ -4012,8 +4011,7 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
AttrName, AttrName,
SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc),
ScopeName, ScopeLoc, nullptr, 0, ScopeName, ScopeLoc, nullptr, 0,
getLangOpts().CPlusPlus ? AttributeList::AS_CXX11 getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x);
: AttributeList::AS_C2x);
if (TryConsumeToken(tok::ellipsis)) if (TryConsumeToken(tok::ellipsis))
Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
@ -4165,7 +4163,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
if (!T.consumeClose()) { if (!T.consumeClose()) {
Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr, Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
SourceLocation(), ArgExprs.data(), ArgExprs.size(), SourceLocation(), ArgExprs.data(), ArgExprs.size(),
AttributeList::AS_Microsoft); ParsedAttr::AS_Microsoft);
} }
} }

View File

@ -1109,10 +1109,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// after '(...)'. nvcc doesn't accept this. // after '(...)'. nvcc doesn't accept this.
auto WarnIfHasCUDATargetAttr = [&] { auto WarnIfHasCUDATargetAttr = [&] {
if (getLangOpts().CUDA) if (getLangOpts().CUDA)
for (const AttributeList &A : Attr) for (const ParsedAttr &A : Attr)
if (A.getKind() == AttributeList::AT_CUDADevice || if (A.getKind() == ParsedAttr::AT_CUDADevice ||
A.getKind() == AttributeList::AT_CUDAHost || A.getKind() == ParsedAttr::AT_CUDAHost ||
A.getKind() == AttributeList::AT_CUDAGlobal) A.getKind() == ParsedAttr::AT_CUDAGlobal)
Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)
<< A.getName()->getName(); << A.getName()->getName();
}; };

View File

@ -376,10 +376,10 @@ static void addContextSensitiveTypeNullability(Parser &P,
SourceLocation nullabilityLoc, SourceLocation nullabilityLoc,
bool &addedToDeclSpec) { bool &addedToDeclSpec) {
// Create the attribute. // Create the attribute.
auto getNullabilityAttr = [&](AttributePool &Pool) -> AttributeList * { auto getNullabilityAttr = [&](AttributePool &Pool) -> ParsedAttr * {
return Pool.create(P.getNullabilityKeyword(nullability), return Pool.create(P.getNullabilityKeyword(nullability),
SourceRange(nullabilityLoc), nullptr, SourceLocation(), SourceRange(nullabilityLoc), nullptr, SourceLocation(),
nullptr, 0, AttributeList::AS_ContextSensitiveKeyword); nullptr, 0, ParsedAttr::AS_ContextSensitiveKeyword);
}; };
if (D.getNumTypeObjects() > 0) { if (D.getNumTypeObjects() > 0) {

View File

@ -1271,7 +1271,7 @@ getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
/// suggests the possible attribute subject rules in a fix-it together with /// suggests the possible attribute subject rules in a fix-it together with
/// any other missing tokens. /// any other missing tokens.
DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic( DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
unsigned DiagID, AttributeList &Attribute, unsigned DiagID, ParsedAttr &Attribute,
MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) { MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
SourceLocation Loc = PRef.getEndOfPreviousToken(); SourceLocation Loc = PRef.getEndOfPreviousToken();
if (Loc.isInvalid()) if (Loc.isInvalid())
@ -1371,12 +1371,11 @@ void Parser::HandlePragmaAttribute() {
if (Tok.isNot(tok::l_paren)) if (Tok.isNot(tok::l_paren))
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
AttributeList::AS_GNU); ParsedAttr::AS_GNU);
else else
ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr, ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
/*ScopeName=*/nullptr, /*ScopeName=*/nullptr,
/*ScopeLoc=*/SourceLocation(), /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
AttributeList::AS_GNU,
/*Declarator=*/nullptr); /*Declarator=*/nullptr);
if (ExpectAndConsume(tok::r_paren)) if (ExpectAndConsume(tok::r_paren))
@ -1390,9 +1389,9 @@ void Parser::HandlePragmaAttribute() {
if (Tok.getIdentifierInfo()) { if (Tok.getIdentifierInfo()) {
// If we suspect that this is an attribute suggest the use of // If we suspect that this is an attribute suggest the use of
// '__attribute__'. // '__attribute__'.
if (AttributeList::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr, if (ParsedAttr::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
AttributeList::AS_GNU) != ParsedAttr::AS_GNU) !=
AttributeList::UnknownAttribute) { ParsedAttr::UnknownAttribute) {
SourceLocation InsertStartLoc = Tok.getLocation(); SourceLocation InsertStartLoc = Tok.getLocation();
ConsumeToken(); ConsumeToken();
if (Tok.is(tok::l_paren)) { if (Tok.is(tok::l_paren)) {
@ -1423,7 +1422,7 @@ void Parser::HandlePragmaAttribute() {
return; return;
} }
AttributeList &Attribute = *Attrs.begin(); ParsedAttr &Attribute = *Attrs.begin();
if (!Attribute.isSupportedByPragmaAttribute()) { if (!Attribute.isSupportedByPragmaAttribute()) {
Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute) Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
<< Attribute.getName(); << Attribute.getName();

View File

@ -1942,7 +1942,7 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
ArgsUnion(Hint.ValueExpr)}; ArgsUnion(Hint.ValueExpr)};
TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr, TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
Hint.PragmaNameLoc->Loc, ArgHints, 4, Hint.PragmaNameLoc->Loc, ArgHints, 4,
AttributeList::AS_Pragma); ParsedAttr::AS_Pragma);
} }
// Get the next statement. // Get the next statement.
@ -2267,7 +2267,7 @@ bool Parser::ParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs) {
if (Attrs.empty()) if (Attrs.empty())
return true; return true;
if (Attrs.begin()->getKind() != AttributeList::AT_OpenCLUnrollHint) if (Attrs.begin()->getKind() != ParsedAttr::AT_OpenCLUnrollHint)
return true; return true;
if (!(Tok.is(tok::kw_for) || Tok.is(tok::kw_while) || Tok.is(tok::kw_do))) { if (!(Tok.is(tok::kw_for) || Tok.is(tok::kw_while) || Tok.is(tok::kw_do))) {

View File

@ -1089,7 +1089,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Check to make sure that any normal attributes are allowed to be on // Check to make sure that any normal attributes are allowed to be on
// a definition. Late parsed attributes are checked at the end. // a definition. Late parsed attributes are checked at the end.
if (Tok.isNot(tok::equal)) { if (Tok.isNot(tok::equal)) {
for (const AttributeList &AL : D.getAttributes()) for (const ParsedAttr &AL : D.getAttributes())
if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) Diag(AL.getLoc(), diag::warn_attribute_on_function_definition)
<< AL.getName(); << AL.getName();

View File

@ -9,13 +9,13 @@ endif()
add_clang_library(clangSema add_clang_library(clangSema
AnalysisBasedWarnings.cpp AnalysisBasedWarnings.cpp
AttributeList.cpp
CodeCompleteConsumer.cpp CodeCompleteConsumer.cpp
DeclSpec.cpp DeclSpec.cpp
DelayedDiagnostic.cpp DelayedDiagnostic.cpp
IdentifierResolver.cpp IdentifierResolver.cpp
JumpDiagnostics.cpp JumpDiagnostics.cpp
MultiplexExternalSemaSource.cpp MultiplexExternalSemaSource.cpp
ParsedAttr.cpp
Scope.cpp Scope.cpp
ScopeInfo.cpp ScopeInfo.cpp
Sema.cpp Sema.cpp

View File

@ -994,7 +994,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
writtenBS.Width = getTypeSpecWidth(); writtenBS.Width = getTypeSpecWidth();
writtenBS.Type = getTypeSpecType(); writtenBS.Type = getTypeSpecType();
// Search the list of attributes for the presence of a mode attribute. // Search the list of attributes for the presence of a mode attribute.
writtenBS.ModeAttr = getAttributes().hasAttribute(AttributeList::AT_Mode); writtenBS.ModeAttr = getAttributes().hasAttribute(ParsedAttr::AT_Mode);
} }
/// Finish - This does final analysis of the declspec, rejecting things like /// Finish - This does final analysis of the declspec, rejecting things like

View File

@ -1,4 +1,4 @@
//===- AttributeList.cpp --------------------------------------------------===// //======- ParsedAttr.cpp --------------------------------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -7,11 +7,11 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines the AttributeList class implementation // This file defines the ParsedAttr class implementation
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "clang/Sema/AttributeList.h" #include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/Basic/AttrSubjectMatchRules.h" #include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/IdentifierTable.h"
@ -34,15 +34,15 @@ IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc,
return Result; return Result;
} }
size_t AttributeList::allocated_size() const { size_t ParsedAttr::allocated_size() const {
if (IsAvailability) return AttributeFactory::AvailabilityAllocSize; if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
else if (IsTypeTagForDatatype) else if (IsTypeTagForDatatype)
return AttributeFactory::TypeTagForDatatypeAllocSize; return AttributeFactory::TypeTagForDatatypeAllocSize;
else if (IsProperty) else if (IsProperty)
return AttributeFactory::PropertyAllocSize; return AttributeFactory::PropertyAllocSize;
else if (HasParsedType) else if (HasParsedType)
return sizeof(AttributeList) + sizeof(void *); return sizeof(ParsedAttr) + sizeof(void *);
return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion)); return (sizeof(ParsedAttr) + NumArgs * sizeof(ArgsUnion));
} }
AttributeFactory::AttributeFactory() { AttributeFactory::AttributeFactory() {
@ -52,16 +52,16 @@ AttributeFactory::AttributeFactory() {
AttributeFactory::~AttributeFactory() = default; AttributeFactory::~AttributeFactory() = default;
static size_t getFreeListIndexForSize(size_t size) { static size_t getFreeListIndexForSize(size_t size) {
assert(size >= sizeof(AttributeList)); assert(size >= sizeof(ParsedAttr));
assert((size % sizeof(void*)) == 0); assert((size % sizeof(void*)) == 0);
return ((size - sizeof(AttributeList)) / sizeof(void*)); return ((size - sizeof(ParsedAttr)) / sizeof(void *));
} }
void *AttributeFactory::allocate(size_t size) { void *AttributeFactory::allocate(size_t size) {
// Check for a previously reclaimed attribute. // Check for a previously reclaimed attribute.
size_t index = getFreeListIndexForSize(size); size_t index = getFreeListIndexForSize(size);
if (index < FreeLists.size() && !FreeLists[index].empty()) { if (index < FreeLists.size() && !FreeLists[index].empty()) {
AttributeList *attr = FreeLists[index].back(); ParsedAttr *attr = FreeLists[index].back();
FreeLists[index].pop_back(); FreeLists[index].pop_back();
return attr; return attr;
} }
@ -70,7 +70,7 @@ void *AttributeFactory::allocate(size_t size) {
return Alloc.Allocate(size, alignof(AttributeFactory)); return Alloc.Allocate(size, alignof(AttributeFactory));
} }
void AttributeFactory::deallocate(AttributeList *Attr) { void AttributeFactory::deallocate(ParsedAttr *Attr) {
size_t size = Attr->allocated_size(); size_t size = Attr->allocated_size();
size_t freeListIndex = getFreeListIndexForSize(size); size_t freeListIndex = getFreeListIndexForSize(size);
@ -88,7 +88,7 @@ void AttributeFactory::deallocate(AttributeList *Attr) {
} }
void AttributeFactory::reclaimPool(AttributePool &cur) { void AttributeFactory::reclaimPool(AttributePool &cur) {
for (AttributeList *AL : cur.Attrs) for (ParsedAttr *AL : cur.Attrs)
deallocate(AL); deallocate(AL);
} }
@ -100,12 +100,13 @@ void AttributePool::takePool(AttributePool &pool) {
#include "clang/Sema/AttrParsedAttrKinds.inc" #include "clang/Sema/AttrParsedAttrKinds.inc"
static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
AttributeList::Syntax SyntaxUsed) { ParsedAttr::Syntax SyntaxUsed) {
// Normalize the attribute name, __foo__ becomes foo. This is only allowable // Normalize the attribute name, __foo__ becomes foo. This is only allowable
// for GNU attributes. // for GNU attributes.
bool IsGNU = SyntaxUsed == AttributeList::AS_GNU || bool IsGNU = SyntaxUsed == ParsedAttr::AS_GNU ||
((SyntaxUsed == AttributeList::AS_CXX11 || ((SyntaxUsed == ParsedAttr::AS_CXX11 ||
SyntaxUsed == AttributeList::AS_C2x) && ScopeName == "gnu"); SyntaxUsed == ParsedAttr::AS_C2x) &&
ScopeName == "gnu");
if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") && if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
AttrName.endswith("__")) AttrName.endswith("__"))
AttrName = AttrName.slice(2, AttrName.size() - 2); AttrName = AttrName.slice(2, AttrName.size() - 2);
@ -113,9 +114,9 @@ static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
return AttrName; return AttrName;
} }
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name, ParsedAttr::Kind ParsedAttr::getKind(const IdentifierInfo *Name,
const IdentifierInfo *ScopeName, const IdentifierInfo *ScopeName,
Syntax SyntaxUsed) { Syntax SyntaxUsed) {
StringRef AttrName = Name->getName(); StringRef AttrName = Name->getName();
SmallString<64> FullName; SmallString<64> FullName;
@ -133,12 +134,12 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
return ::getAttrKind(FullName, SyntaxUsed); return ::getAttrKind(FullName, SyntaxUsed);
} }
unsigned AttributeList::getAttributeSpellingListIndex() const { unsigned ParsedAttr::getAttributeSpellingListIndex() const {
// Both variables will be used in tablegen generated // Both variables will be used in tablegen generated
// attribute spell list index matching code. // attribute spell list index matching code.
StringRef Scope = ScopeName ? ScopeName->getName() : ""; StringRef Scope = ScopeName ? ScopeName->getName() : "";
StringRef Name = normalizeAttrName(AttrName->getName(), Scope, StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
(AttributeList::Syntax)SyntaxUsed); (ParsedAttr::Syntax)SyntaxUsed);
#include "clang/Sema/AttrSpellingListIndex.inc" #include "clang/Sema/AttrSpellingListIndex.inc"
@ -154,11 +155,10 @@ struct ParsedAttrInfo {
unsigned IsKnownToGCC : 1; unsigned IsKnownToGCC : 1;
unsigned IsSupportedByPragmaAttribute : 1; unsigned IsSupportedByPragmaAttribute : 1;
bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr, bool (*DiagAppertainsToDecl)(Sema &S, const ParsedAttr &Attr, const Decl *);
const Decl *); bool (*DiagLangOpts)(Sema &S, const ParsedAttr &Attr);
bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
bool (*ExistsInTarget)(const TargetInfo &Target); bool (*ExistsInTarget)(const TargetInfo &Target);
unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr); unsigned (*SpellingIndexToSemanticSpelling)(const ParsedAttr &Attr);
void (*GetPragmaAttributeMatchRules)( void (*GetPragmaAttributeMatchRules)(
llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules, llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
const LangOptions &LangOpts); const LangOptions &LangOpts);
@ -170,71 +170,63 @@ namespace {
} // namespace } // namespace
static const ParsedAttrInfo &getInfo(const AttributeList &A) { static const ParsedAttrInfo &getInfo(const ParsedAttr &A) {
return AttrInfoMap[A.getKind()]; return AttrInfoMap[A.getKind()];
} }
unsigned AttributeList::getMinArgs() const { unsigned ParsedAttr::getMinArgs() const { return getInfo(*this).NumArgs; }
return getInfo(*this).NumArgs;
}
unsigned AttributeList::getMaxArgs() const { unsigned ParsedAttr::getMaxArgs() const {
return getMinArgs() + getInfo(*this).OptArgs; return getMinArgs() + getInfo(*this).OptArgs;
} }
bool AttributeList::hasCustomParsing() const { bool ParsedAttr::hasCustomParsing() const {
return getInfo(*this).HasCustomParsing; return getInfo(*this).HasCustomParsing;
} }
bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const { bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
return getInfo(*this).DiagAppertainsToDecl(S, *this, D); return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
} }
bool AttributeList::appliesToDecl(const Decl *D, bool ParsedAttr::appliesToDecl(const Decl *D,
attr::SubjectMatchRule MatchRule) const { attr::SubjectMatchRule MatchRule) const {
return checkAttributeMatchRuleAppliesTo(D, MatchRule); return checkAttributeMatchRuleAppliesTo(D, MatchRule);
} }
void AttributeList::getMatchRules( void ParsedAttr::getMatchRules(
const LangOptions &LangOpts, const LangOptions &LangOpts,
SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules) SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
const { const {
return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts); return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
} }
bool AttributeList::diagnoseLangOpts(Sema &S) const { bool ParsedAttr::diagnoseLangOpts(Sema &S) const {
return getInfo(*this).DiagLangOpts(S, *this); return getInfo(*this).DiagLangOpts(S, *this);
} }
bool AttributeList::isTargetSpecificAttr() const { bool ParsedAttr::isTargetSpecificAttr() const {
return getInfo(*this).IsTargetSpecific; return getInfo(*this).IsTargetSpecific;
} }
bool AttributeList::isTypeAttr() const { bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; }
return getInfo(*this).IsType;
}
bool AttributeList::isStmtAttr() const { bool ParsedAttr::isStmtAttr() const { return getInfo(*this).IsStmt; }
return getInfo(*this).IsStmt;
}
bool AttributeList::existsInTarget(const TargetInfo &Target) const { bool ParsedAttr::existsInTarget(const TargetInfo &Target) const {
return getInfo(*this).ExistsInTarget(Target); return getInfo(*this).ExistsInTarget(Target);
} }
bool AttributeList::isKnownToGCC() const { bool ParsedAttr::isKnownToGCC() const { return getInfo(*this).IsKnownToGCC; }
return getInfo(*this).IsKnownToGCC;
}
bool AttributeList::isSupportedByPragmaAttribute() const { bool ParsedAttr::isSupportedByPragmaAttribute() const {
return getInfo(*this).IsSupportedByPragmaAttribute; return getInfo(*this).IsSupportedByPragmaAttribute;
} }
unsigned AttributeList::getSemanticSpelling() const { unsigned ParsedAttr::getSemanticSpelling() const {
return getInfo(*this).SpellingIndexToSemanticSpelling(*this); return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
} }
bool AttributeList::hasVariadicArg() const { bool ParsedAttr::hasVariadicArg() const {
// If the attribute has the maximum number of optional arguments, we will // If the attribute has the maximum number of optional arguments, we will
// claim that as being variadic. If we someday get an attribute that // claim that as being variadic. If we someday get an attribute that
// legitimately bumps up against that maximum, we can use another bit to track // legitimately bumps up against that maximum, we can use another bit to track

View File

@ -520,7 +520,7 @@ attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
} // end anonymous namespace } // end anonymous namespace
void Sema::ActOnPragmaAttributePush(AttributeList &Attribute, void Sema::ActOnPragmaAttributePush(ParsedAttr &Attribute,
SourceLocation PragmaLoc, SourceLocation PragmaLoc,
attr::ParsedSubjectMatchRuleSet Rules) { attr::ParsedSubjectMatchRuleSet Rules) {
SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules; SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
@ -645,7 +645,7 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
if (PragmaAttributeStack.empty()) if (PragmaAttributeStack.empty())
return; return;
for (auto &Entry : PragmaAttributeStack) { for (auto &Entry : PragmaAttributeStack) {
AttributeList *Attribute = Entry.Attribute; ParsedAttr *Attribute = Entry.Attribute;
assert(Attribute && "Expected an attribute"); assert(Attribute && "Expected an attribute");
// Ensure that the attribute can be applied to the given declaration. // Ensure that the attribute can be applied to the given declaration.

View File

@ -61,18 +61,18 @@ Sema::IdentifyCUDATarget(const ParsedAttributesView &Attrs) {
bool HasDeviceAttr = false; bool HasDeviceAttr = false;
bool HasGlobalAttr = false; bool HasGlobalAttr = false;
bool HasInvalidTargetAttr = false; bool HasInvalidTargetAttr = false;
for (const AttributeList &AL : Attrs) { for (const ParsedAttr &AL : Attrs) {
switch (AL.getKind()) { switch (AL.getKind()) {
case AttributeList::AT_CUDAGlobal: case ParsedAttr::AT_CUDAGlobal:
HasGlobalAttr = true; HasGlobalAttr = true;
break; break;
case AttributeList::AT_CUDAHost: case ParsedAttr::AT_CUDAHost:
HasHostAttr = true; HasHostAttr = true;
break; break;
case AttributeList::AT_CUDADevice: case ParsedAttr::AT_CUDADevice:
HasDeviceAttr = true; HasDeviceAttr = true;
break; break;
case AttributeList::AT_CUDAInvalidTarget: case ParsedAttr::AT_CUDAInvalidTarget:
HasInvalidTargetAttr = true; HasInvalidTargetAttr = true;
break; break;
default: default:

View File

@ -4447,7 +4447,7 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS,
TypeSpecType == DeclSpec::TST_interface || TypeSpecType == DeclSpec::TST_interface ||
TypeSpecType == DeclSpec::TST_union || TypeSpecType == DeclSpec::TST_union ||
TypeSpecType == DeclSpec::TST_enum) { TypeSpecType == DeclSpec::TST_enum) {
for (const AttributeList &AL : DS.getAttributes()) for (const ParsedAttr &AL : DS.getAttributes())
Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored) Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored)
<< AL.getName() << GetDiagnosticTypeSpecifierID(TypeSpecType); << AL.getName() << GetDiagnosticTypeSpecifierID(TypeSpecType);
} }
@ -6204,7 +6204,7 @@ static bool shouldConsiderLinkage(const FunctionDecl *FD) {
} }
static bool hasParsedAttr(Scope *S, const Declarator &PD, static bool hasParsedAttr(Scope *S, const Declarator &PD,
AttributeList::Kind Kind) { ParsedAttr::Kind Kind) {
// Check decl attributes on the DeclSpec. // Check decl attributes on the DeclSpec.
if (PD.getDeclSpec().getAttributes().hasAttribute(Kind)) if (PD.getDeclSpec().getAttributes().hasAttribute(Kind))
return true; return true;
@ -6372,8 +6372,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
// dllimport globals without explicit storage class are treated as extern. We // dllimport globals without explicit storage class are treated as extern. We
// have to change the storage class this early to get the right DeclContext. // have to change the storage class this early to get the right DeclContext.
if (SC == SC_None && !DC->isRecord() && if (SC == SC_None && !DC->isRecord() &&
hasParsedAttr(S, D, AttributeList::AT_DLLImport) && hasParsedAttr(S, D, ParsedAttr::AT_DLLImport) &&
!hasParsedAttr(S, D, AttributeList::AT_DLLExport)) !hasParsedAttr(S, D, ParsedAttr::AT_DLLExport))
SC = SC_Extern; SC = SC_Extern;
DeclContext *OriginalDC = DC; DeclContext *OriginalDC = DC;

File diff suppressed because it is too large Load Diff

View File

@ -2300,10 +2300,10 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
// We do not support any C++11 attributes on base-specifiers yet. // We do not support any C++11 attributes on base-specifiers yet.
// Diagnose any attributes we see. // Diagnose any attributes we see.
for (const AttributeList &AL : Attributes) { for (const ParsedAttr &AL : Attributes) {
if (AL.isInvalid() || AL.getKind() == AttributeList::IgnoredAttribute) if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
continue; continue;
Diag(AL.getLoc(), AL.getKind() == AttributeList::UnknownAttribute Diag(AL.getLoc(), AL.getKind() == ParsedAttr::UnknownAttribute
? diag::warn_unknown_attribute_ignored ? diag::warn_unknown_attribute_ignored
: diag::err_base_specifier_attribute) : diag::err_base_specifier_attribute)
<< AL.getName(); << AL.getName();
@ -2816,10 +2816,9 @@ static bool InitializationHasSideEffects(const FieldDecl &FD) {
return false; return false;
} }
static const AttributeList * static const ParsedAttr *getMSPropertyAttr(const ParsedAttributesView &list) {
getMSPropertyAttr(const ParsedAttributesView &list) {
ParsedAttributesView::const_iterator Itr = ParsedAttributesView::const_iterator Itr =
llvm::find_if(list, [](const AttributeList &AL) { llvm::find_if(list, [](const ParsedAttr &AL) {
return AL.isDeclspecPropertyAttribute(); return AL.isDeclspecPropertyAttribute();
}); });
if (Itr != list.end()) if (Itr != list.end())
@ -2902,7 +2901,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
assert(!DS.isFriendSpecified()); assert(!DS.isFriendSpecified());
bool isFunc = D.isDeclarationOfFunction(); bool isFunc = D.isDeclarationOfFunction();
const AttributeList *MSPropertyAttr = const ParsedAttr *MSPropertyAttr =
getMSPropertyAttr(D.getDeclSpec().getAttributes()); getMSPropertyAttr(D.getDeclSpec().getAttributes());
if (cast<CXXRecordDecl>(CurContext)->isInterface()) { if (cast<CXXRecordDecl>(CurContext)->isInterface()) {
@ -7815,8 +7814,8 @@ void Sema::ActOnFinishCXXMemberSpecification(
AdjustDeclIfTemplate(TagDecl); AdjustDeclIfTemplate(TagDecl);
for (const AttributeList &AL : AttrList) { for (const ParsedAttr &AL : AttrList) {
if (AL.getKind() != AttributeList::AT_Visibility) if (AL.getKind() != ParsedAttr::AT_Visibility)
continue; continue;
AL.setInvalid(); AL.setInvalid();
Diag(AL.getLoc(), diag::warn_attribute_after_definition_ignored) Diag(AL.getLoc(), diag::warn_attribute_after_definition_ignored)
@ -15388,7 +15387,7 @@ MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
Expr *BitWidth, Expr *BitWidth,
InClassInitStyle InitStyle, InClassInitStyle InitStyle,
AccessSpecifier AS, AccessSpecifier AS,
const AttributeList &MSPropertyAttr) { const ParsedAttr &MSPropertyAttr) {
IdentifierInfo *II = D.getIdentifier(); IdentifierInfo *II = D.getIdentifier();
if (!II) { if (!II) {
Diag(DeclStart, diag::err_anonymous_property); Diag(DeclStart, diag::err_anonymous_property);
@ -15451,7 +15450,7 @@ MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
PrevDecl = nullptr; PrevDecl = nullptr;
SourceLocation TSSL = D.getLocStart(); SourceLocation TSSL = D.getLocStart();
const AttributeList::PropertyData &Data = MSPropertyAttr.getPropertyData(); const ParsedAttr::PropertyData &Data = MSPropertyAttr.getPropertyData();
MSPropertyDecl *NewPD = MSPropertyDecl::Create( MSPropertyDecl *NewPD = MSPropertyDecl::Create(
Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId); Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId);
ProcessDeclAttributes(TUScope, NewPD, D); ProcessDeclAttributes(TUScope, NewPD, D);

View File

@ -23,7 +23,7 @@
using namespace clang; using namespace clang;
using namespace sema; using namespace sema;
static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const AttributeList &A, static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange Range) { SourceRange Range) {
FallThroughAttr Attr(A.getRange(), S.Context, FallThroughAttr Attr(A.getRange(), S.Context,
A.getAttributeSpellingListIndex()); A.getAttributeSpellingListIndex());
@ -53,7 +53,7 @@ static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const AttributeList &A,
return ::new (S.Context) auto(Attr); return ::new (S.Context) auto(Attr);
} }
static Attr *handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A, static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange Range) { SourceRange Range) {
if (A.getNumArgs() < 1) { if (A.getNumArgs() < 1) {
S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments) S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments)
@ -78,7 +78,7 @@ static Attr *handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A,
DiagnosticIdentifiers.size(), A.getAttributeSpellingListIndex()); DiagnosticIdentifiers.size(), A.getAttributeSpellingListIndex());
} }
static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange) { SourceRange) {
IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0); IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0);
IdentifierLoc *OptionLoc = A.getArgAsIdent(1); IdentifierLoc *OptionLoc = A.getArgAsIdent(1);
@ -246,7 +246,7 @@ CheckForIncompatibleAttributes(Sema &S,
} }
} }
static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange Range) { SourceRange Range) {
// Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's
// useful for OpenCL 1.x too and doesn't require HW support. // useful for OpenCL 1.x too and doesn't require HW support.
@ -288,21 +288,21 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A,
return OpenCLUnrollHintAttr::CreateImplicit(S.Context, UnrollFactor); return OpenCLUnrollHintAttr::CreateImplicit(S.Context, UnrollFactor);
} }
static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A, static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange Range) { SourceRange Range) {
switch (A.getKind()) { switch (A.getKind()) {
case AttributeList::UnknownAttribute: case ParsedAttr::UnknownAttribute:
S.Diag(A.getLoc(), A.isDeclspecAttribute() ? S.Diag(A.getLoc(), A.isDeclspecAttribute() ?
diag::warn_unhandled_ms_attribute_ignored : diag::warn_unhandled_ms_attribute_ignored :
diag::warn_unknown_attribute_ignored) << A.getName(); diag::warn_unknown_attribute_ignored) << A.getName();
return nullptr; return nullptr;
case AttributeList::AT_FallThrough: case ParsedAttr::AT_FallThrough:
return handleFallThroughAttr(S, St, A, Range); return handleFallThroughAttr(S, St, A, Range);
case AttributeList::AT_LoopHint: case ParsedAttr::AT_LoopHint:
return handleLoopHintAttr(S, St, A, Range); return handleLoopHintAttr(S, St, A, Range);
case AttributeList::AT_OpenCLUnrollHint: case ParsedAttr::AT_OpenCLUnrollHint:
return handleOpenCLUnrollHint(S, St, A, Range); return handleOpenCLUnrollHint(S, St, A, Range);
case AttributeList::AT_Suppress: case ParsedAttr::AT_Suppress:
return handleSuppressAttr(S, St, A, Range); return handleSuppressAttr(S, St, A, Range);
default: default:
// if we're here, then we parsed a known attribute, but didn't recognize // if we're here, then we parsed a known attribute, but didn't recognize
@ -317,7 +317,7 @@ StmtResult Sema::ProcessStmtAttributes(Stmt *S,
const ParsedAttributesView &AttrList, const ParsedAttributesView &AttrList,
SourceRange Range) { SourceRange Range) {
SmallVector<const Attr*, 8> Attrs; SmallVector<const Attr*, 8> Attrs;
for (const AttributeList &AL : AttrList) { for (const ParsedAttr &AL : AttrList) {
if (Attr *a = ProcessStmtAttribute(*this, S, AL, Range)) if (Attr *a = ProcessStmtAttribute(*this, S, AL, Range))
Attrs.push_back(a); Attrs.push_back(a);
} }

View File

@ -8599,8 +8599,8 @@ DeclResult Sema::ActOnExplicitInstantiation(
if (TSK == TSK_ExplicitInstantiationDeclaration) { if (TSK == TSK_ExplicitInstantiationDeclaration) {
// Check for dllexport class template instantiation declarations. // Check for dllexport class template instantiation declarations.
for (const AttributeList &AL : Attr) { for (const ParsedAttr &AL : Attr) {
if (AL.getKind() == AttributeList::AT_DLLExport) { if (AL.getKind() == ParsedAttr::AT_DLLExport) {
Diag(ExternLoc, Diag(ExternLoc,
diag::warn_attribute_dllexport_explicit_instantiation_decl); diag::warn_attribute_dllexport_explicit_instantiation_decl);
Diag(AL.getLoc(), diag::note_attribute); Diag(AL.getLoc(), diag::note_attribute);
@ -8623,10 +8623,10 @@ DeclResult Sema::ActOnExplicitInstantiation(
// Check for dllimport class template instantiation definitions. // Check for dllimport class template instantiation definitions.
bool DLLImport = bool DLLImport =
ClassTemplate->getTemplatedDecl()->getAttr<DLLImportAttr>(); ClassTemplate->getTemplatedDecl()->getAttr<DLLImportAttr>();
for (const AttributeList &AL : Attr) { for (const ParsedAttr &AL : Attr) {
if (AL.getKind() == AttributeList::AT_DLLImport) if (AL.getKind() == ParsedAttr::AT_DLLImport)
DLLImport = true; DLLImport = true;
if (AL.getKind() == AttributeList::AT_DLLExport) { if (AL.getKind() == ParsedAttr::AT_DLLExport) {
// dllexport trumps dllimport here. // dllexport trumps dllimport here.
DLLImport = false; DLLImport = false;
break; break;

View File

@ -64,13 +64,17 @@ static bool isOmittedBlockReturnType(const Declarator &D) {
/// diagnoseBadTypeAttribute - Diagnoses a type attribute which /// diagnoseBadTypeAttribute - Diagnoses a type attribute which
/// doesn't apply to the given type. /// doesn't apply to the given type.
static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr, static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
QualType type) { QualType type) {
TypeDiagSelector WhichType; TypeDiagSelector WhichType;
bool useExpansionLoc = true; bool useExpansionLoc = true;
switch (attr.getKind()) { switch (attr.getKind()) {
case AttributeList::AT_ObjCGC: WhichType = TDS_Pointer; break; case ParsedAttr::AT_ObjCGC:
case AttributeList::AT_ObjCOwnership: WhichType = TDS_ObjCObjOrBlock; break; WhichType = TDS_Pointer;
break;
case ParsedAttr::AT_ObjCOwnership:
WhichType = TDS_ObjCObjOrBlock;
break;
default: default:
// Assume everything else was a function attribute. // Assume everything else was a function attribute.
WhichType = TDS_Function; WhichType = TDS_Function;
@ -98,48 +102,48 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
// objc_gc applies to Objective-C pointers or, otherwise, to the // objc_gc applies to Objective-C pointers or, otherwise, to the
// smallest available pointer type (i.e. 'void*' in 'void**'). // smallest available pointer type (i.e. 'void*' in 'void**').
#define OBJC_POINTER_TYPE_ATTRS_CASELIST \ #define OBJC_POINTER_TYPE_ATTRS_CASELIST \
case AttributeList::AT_ObjCGC: \ case ParsedAttr::AT_ObjCGC: \
case AttributeList::AT_ObjCOwnership case ParsedAttr::AT_ObjCOwnership
// Calling convention attributes. // Calling convention attributes.
#define CALLING_CONV_ATTRS_CASELIST \ #define CALLING_CONV_ATTRS_CASELIST \
case AttributeList::AT_CDecl: \ case ParsedAttr::AT_CDecl: \
case AttributeList::AT_FastCall: \ case ParsedAttr::AT_FastCall: \
case AttributeList::AT_StdCall: \ case ParsedAttr::AT_StdCall: \
case AttributeList::AT_ThisCall: \ case ParsedAttr::AT_ThisCall: \
case AttributeList::AT_RegCall: \ case ParsedAttr::AT_RegCall: \
case AttributeList::AT_Pascal: \ case ParsedAttr::AT_Pascal: \
case AttributeList::AT_SwiftCall: \ case ParsedAttr::AT_SwiftCall: \
case AttributeList::AT_VectorCall: \ case ParsedAttr::AT_VectorCall: \
case AttributeList::AT_MSABI: \ case ParsedAttr::AT_MSABI: \
case AttributeList::AT_SysVABI: \ case ParsedAttr::AT_SysVABI: \
case AttributeList::AT_Pcs: \ case ParsedAttr::AT_Pcs: \
case AttributeList::AT_IntelOclBicc: \ case ParsedAttr::AT_IntelOclBicc: \
case AttributeList::AT_PreserveMost: \ case ParsedAttr::AT_PreserveMost: \
case AttributeList::AT_PreserveAll case ParsedAttr::AT_PreserveAll
// Function type attributes. // Function type attributes.
#define FUNCTION_TYPE_ATTRS_CASELIST \ #define FUNCTION_TYPE_ATTRS_CASELIST \
case AttributeList::AT_NSReturnsRetained: \ case ParsedAttr::AT_NSReturnsRetained: \
case AttributeList::AT_NoReturn: \ case ParsedAttr::AT_NoReturn: \
case AttributeList::AT_Regparm: \ case ParsedAttr::AT_Regparm: \
case AttributeList::AT_AnyX86NoCallerSavedRegisters: \ case ParsedAttr::AT_AnyX86NoCallerSavedRegisters: \
case AttributeList::AT_AnyX86NoCfCheck: \ case ParsedAttr::AT_AnyX86NoCfCheck: \
CALLING_CONV_ATTRS_CASELIST CALLING_CONV_ATTRS_CASELIST
// Microsoft-specific type qualifiers. // Microsoft-specific type qualifiers.
#define MS_TYPE_ATTRS_CASELIST \ #define MS_TYPE_ATTRS_CASELIST \
case AttributeList::AT_Ptr32: \ case ParsedAttr::AT_Ptr32: \
case AttributeList::AT_Ptr64: \ case ParsedAttr::AT_Ptr64: \
case AttributeList::AT_SPtr: \ case ParsedAttr::AT_SPtr: \
case AttributeList::AT_UPtr case ParsedAttr::AT_UPtr
// Nullability qualifiers. // Nullability qualifiers.
#define NULLABILITY_TYPE_ATTRS_CASELIST \ #define NULLABILITY_TYPE_ATTRS_CASELIST \
case AttributeList::AT_TypeNonNull: \ case ParsedAttr::AT_TypeNonNull: \
case AttributeList::AT_TypeNullable: \ case ParsedAttr::AT_TypeNullable: \
case AttributeList::AT_TypeNullUnspecified case ParsedAttr::AT_TypeNullUnspecified
namespace { namespace {
/// An object which stores processing state for the entire /// An object which stores processing state for the entire
@ -162,11 +166,11 @@ namespace {
bool hasSavedAttrs; bool hasSavedAttrs;
/// The original set of attributes on the DeclSpec. /// The original set of attributes on the DeclSpec.
SmallVector<AttributeList*, 2> savedAttrs; SmallVector<ParsedAttr *, 2> savedAttrs;
/// A list of attributes to diagnose the uselessness of when the /// A list of attributes to diagnose the uselessness of when the
/// processing is complete. /// processing is complete.
SmallVector<AttributeList*, 2> ignoredTypeAttrs; SmallVector<ParsedAttr *, 2> ignoredTypeAttrs;
public: public:
TypeProcessingState(Sema &sema, Declarator &declarator) TypeProcessingState(Sema &sema, Declarator &declarator)
@ -207,7 +211,7 @@ namespace {
if (hasSavedAttrs) return; if (hasSavedAttrs) return;
DeclSpec &spec = getMutableDeclSpec(); DeclSpec &spec = getMutableDeclSpec();
for (AttributeList &AL : spec.getAttributes()) for (ParsedAttr &AL : spec.getAttributes())
savedAttrs.push_back(&AL); savedAttrs.push_back(&AL);
trivial &= savedAttrs.empty(); trivial &= savedAttrs.empty();
hasSavedAttrs = true; hasSavedAttrs = true;
@ -215,7 +219,7 @@ namespace {
/// Record that we had nowhere to put the given type attribute. /// Record that we had nowhere to put the given type attribute.
/// We will diagnose such attributes later. /// We will diagnose such attributes later.
void addIgnoredTypeAttr(AttributeList &attr) { void addIgnoredTypeAttr(ParsedAttr &attr) {
ignoredTypeAttrs.push_back(&attr); ignoredTypeAttrs.push_back(&attr);
} }
@ -241,13 +245,13 @@ namespace {
assert(hasSavedAttrs); assert(hasSavedAttrs);
getMutableDeclSpec().getAttributes().clearListOnly(); getMutableDeclSpec().getAttributes().clearListOnly();
for (AttributeList *AL : savedAttrs) for (ParsedAttr *AL : savedAttrs)
getMutableDeclSpec().getAttributes().addAtStart(AL); getMutableDeclSpec().getAttributes().addAtStart(AL);
} }
}; };
} // end anonymous namespace } // end anonymous namespace
static void moveAttrFromListToList(AttributeList &attr, static void moveAttrFromListToList(ParsedAttr &attr,
ParsedAttributesView &fromList, ParsedAttributesView &fromList,
ParsedAttributesView &toList) { ParsedAttributesView &toList) {
fromList.remove(&attr); fromList.remove(&attr);
@ -267,25 +271,23 @@ enum TypeAttrLocation {
static void processTypeAttrs(TypeProcessingState &state, QualType &type, static void processTypeAttrs(TypeProcessingState &state, QualType &type,
TypeAttrLocation TAL, ParsedAttributesView &attrs); TypeAttrLocation TAL, ParsedAttributesView &attrs);
static bool handleFunctionTypeAttr(TypeProcessingState &state, static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
AttributeList &attr,
QualType &type); QualType &type);
static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &state, static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &state,
AttributeList &attr, ParsedAttr &attr, QualType &type);
QualType &type);
static bool handleObjCGCTypeAttr(TypeProcessingState &state, static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
AttributeList &attr, QualType &type); QualType &type);
static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
AttributeList &attr, QualType &type); ParsedAttr &attr, QualType &type);
static bool handleObjCPointerTypeAttr(TypeProcessingState &state, static bool handleObjCPointerTypeAttr(TypeProcessingState &state,
AttributeList &attr, QualType &type) { ParsedAttr &attr, QualType &type) {
if (attr.getKind() == AttributeList::AT_ObjCGC) if (attr.getKind() == ParsedAttr::AT_ObjCGC)
return handleObjCGCTypeAttr(state, attr, type); return handleObjCGCTypeAttr(state, attr, type);
assert(attr.getKind() == AttributeList::AT_ObjCOwnership); assert(attr.getKind() == ParsedAttr::AT_ObjCOwnership);
return handleObjCOwnershipTypeAttr(state, attr, type); return handleObjCOwnershipTypeAttr(state, attr, type);
} }
@ -367,8 +369,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator,
/// didn't apply in whatever position it was written in, try to move /// didn't apply in whatever position it was written in, try to move
/// it to a more appropriate position. /// it to a more appropriate position.
static void distributeObjCPointerTypeAttr(TypeProcessingState &state, static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
AttributeList &attr, ParsedAttr &attr, QualType type) {
QualType type) {
Declarator &declarator = state.getDeclarator(); Declarator &declarator = state.getDeclarator();
// Move it to the outermost normal or block pointer declarator. // Move it to the outermost normal or block pointer declarator.
@ -381,7 +382,7 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
// of a block. // of a block.
DeclaratorChunk *destChunk = nullptr; DeclaratorChunk *destChunk = nullptr;
if (state.isProcessingDeclSpec() && if (state.isProcessingDeclSpec() &&
attr.getKind() == AttributeList::AT_ObjCOwnership) attr.getKind() == ParsedAttr::AT_ObjCOwnership)
destChunk = maybeMovePastReturnType(declarator, i - 1, destChunk = maybeMovePastReturnType(declarator, i - 1,
/*onlyBlockPointers=*/true); /*onlyBlockPointers=*/true);
if (!destChunk) destChunk = &chunk; if (!destChunk) destChunk = &chunk;
@ -398,7 +399,7 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
// We may be starting at the return type of a block. // We may be starting at the return type of a block.
case DeclaratorChunk::Function: case DeclaratorChunk::Function:
if (state.isProcessingDeclSpec() && if (state.isProcessingDeclSpec() &&
attr.getKind() == AttributeList::AT_ObjCOwnership) { attr.getKind() == ParsedAttr::AT_ObjCOwnership) {
if (DeclaratorChunk *dest = maybeMovePastReturnType( if (DeclaratorChunk *dest = maybeMovePastReturnType(
declarator, i, declarator, i,
/*onlyBlockPointers=*/true)) { /*onlyBlockPointers=*/true)) {
@ -423,10 +424,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
/// Distribute an objc_gc type attribute that was written on the /// Distribute an objc_gc type attribute that was written on the
/// declarator. /// declarator.
static void static void distributeObjCPointerTypeAttrFromDeclarator(
distributeObjCPointerTypeAttrFromDeclarator(TypeProcessingState &state, TypeProcessingState &state, ParsedAttr &attr, QualType &declSpecType) {
AttributeList &attr,
QualType &declSpecType) {
Declarator &declarator = state.getDeclarator(); Declarator &declarator = state.getDeclarator();
// objc_gc goes on the innermost pointer to something that's not a // objc_gc goes on the innermost pointer to something that's not a
@ -487,8 +486,7 @@ distributeObjCPointerTypeAttrFromDeclarator(TypeProcessingState &state,
/// that it didn't apply in whatever position it was written in, try /// that it didn't apply in whatever position it was written in, try
/// to move it to a more appropriate position. /// to move it to a more appropriate position.
static void distributeFunctionTypeAttr(TypeProcessingState &state, static void distributeFunctionTypeAttr(TypeProcessingState &state,
AttributeList &attr, ParsedAttr &attr, QualType type) {
QualType type) {
Declarator &declarator = state.getDeclarator(); Declarator &declarator = state.getDeclarator();
// Try to push the attribute from the return type of a function to // Try to push the attribute from the return type of a function to
@ -519,7 +517,7 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state,
/// function chunk or type. Returns true if the attribute was /// function chunk or type. Returns true if the attribute was
/// distributed, false if no location was found. /// distributed, false if no location was found.
static bool distributeFunctionTypeAttrToInnermost( static bool distributeFunctionTypeAttrToInnermost(
TypeProcessingState &state, AttributeList &attr, TypeProcessingState &state, ParsedAttr &attr,
ParsedAttributesView &attrList, QualType &declSpecType) { ParsedAttributesView &attrList, QualType &declSpecType) {
Declarator &declarator = state.getDeclarator(); Declarator &declarator = state.getDeclarator();
@ -537,10 +535,9 @@ static bool distributeFunctionTypeAttrToInnermost(
/// A function type attribute was written in the decl spec. Try to /// A function type attribute was written in the decl spec. Try to
/// apply it somewhere. /// apply it somewhere.
static void static void distributeFunctionTypeAttrFromDeclSpec(TypeProcessingState &state,
distributeFunctionTypeAttrFromDeclSpec(TypeProcessingState &state, ParsedAttr &attr,
AttributeList &attr, QualType &declSpecType) {
QualType &declSpecType) {
state.saveDeclSpecAttrs(); state.saveDeclSpecAttrs();
// C++11 attributes before the decl specifiers actually appertain to // C++11 attributes before the decl specifiers actually appertain to
@ -564,10 +561,9 @@ distributeFunctionTypeAttrFromDeclSpec(TypeProcessingState &state,
/// A function type attribute was written on the declarator. Try to /// A function type attribute was written on the declarator. Try to
/// apply it somewhere. /// apply it somewhere.
static void static void distributeFunctionTypeAttrFromDeclarator(TypeProcessingState &state,
distributeFunctionTypeAttrFromDeclarator(TypeProcessingState &state, ParsedAttr &attr,
AttributeList &attr, QualType &declSpecType) {
QualType &declSpecType) {
Declarator &declarator = state.getDeclarator(); Declarator &declarator = state.getDeclarator();
// Try to distribute to the innermost. // Try to distribute to the innermost.
@ -599,7 +595,7 @@ static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
// list, so iterating over the existing list isn't possible. Instead, make a // list, so iterating over the existing list isn't possible. Instead, make a
// non-owning copy and iterate over that. // non-owning copy and iterate over that.
ParsedAttributesView AttrsCopy{state.getDeclarator().getAttributes()}; ParsedAttributesView AttrsCopy{state.getDeclarator().getAttributes()};
for (AttributeList &attr : AttrsCopy) { for (ParsedAttr &attr : AttrsCopy) {
// Do not distribute C++11 attributes. They have strict rules for what // Do not distribute C++11 attributes. They have strict rules for what
// they appertain to. // they appertain to.
if (attr.isCXX11Attribute()) if (attr.isCXX11Attribute())
@ -622,7 +618,7 @@ static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
// Nullability specifiers cannot go after the declarator-id. // Nullability specifiers cannot go after the declarator-id.
// Objective-C __kindof does not get distributed. // Objective-C __kindof does not get distributed.
case AttributeList::AT_ObjCKindOf: case ParsedAttr::AT_ObjCKindOf:
continue; continue;
default: default:
@ -728,8 +724,8 @@ static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator,
return false; return false;
// Warn if we see type attributes for omitted return type on a block literal. // Warn if we see type attributes for omitted return type on a block literal.
SmallVector<AttributeList *, 2> ToBeRemoved; SmallVector<ParsedAttr *, 2> ToBeRemoved;
for (AttributeList &AL : declarator.getMutableDeclSpec().getAttributes()) { for (ParsedAttr &AL : declarator.getMutableDeclSpec().getAttributes()) {
if (AL.isInvalid() || !AL.isTypeAttr()) if (AL.isInvalid() || !AL.isTypeAttr())
continue; continue;
S.Diag(AL.getLoc(), S.Diag(AL.getLoc(),
@ -738,7 +734,7 @@ static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator,
ToBeRemoved.push_back(&AL); ToBeRemoved.push_back(&AL);
} }
// Remove bad attributes from the list. // Remove bad attributes from the list.
for (AttributeList *AL : ToBeRemoved) for (ParsedAttr *AL : ToBeRemoved)
declarator.getMutableDeclSpec().getAttributes().remove(AL); declarator.getMutableDeclSpec().getAttributes().remove(AL);
// Warn if we see type qualifiers for omitted return type on a block literal. // Warn if we see type qualifiers for omitted return type on a block literal.
@ -1169,8 +1165,8 @@ TypeResult Sema::actOnObjCTypeArgsAndProtocolQualifiers(
static OpenCLAccessAttr::Spelling static OpenCLAccessAttr::Spelling
getImageAccess(const ParsedAttributesView &Attrs) { getImageAccess(const ParsedAttributesView &Attrs) {
for (const AttributeList &AL : Attrs) for (const ParsedAttr &AL : Attrs)
if (AL.getKind() == AttributeList::AT_OpenCLAccess) if (AL.getKind() == ParsedAttr::AT_OpenCLAccess)
return static_cast<OpenCLAccessAttr::Spelling>(AL.getSemanticSpelling()); return static_cast<OpenCLAccessAttr::Spelling>(AL.getSemanticSpelling());
return OpenCLAccessAttr::Keyword_read_only; return OpenCLAccessAttr::Keyword_read_only;
} }
@ -2599,8 +2595,8 @@ static void inferARCWriteback(TypeProcessingState &state,
if (chunk.Kind != DeclaratorChunk::Pointer && if (chunk.Kind != DeclaratorChunk::Pointer &&
chunk.Kind != DeclaratorChunk::BlockPointer) chunk.Kind != DeclaratorChunk::BlockPointer)
return; return;
for (const AttributeList &AL : chunk.getAttrs()) for (const ParsedAttr &AL : chunk.getAttrs())
if (AL.getKind() == AttributeList::AT_ObjCOwnership) if (AL.getKind() == ParsedAttr::AT_ObjCOwnership)
return; return;
transferARCOwnershipToDeclaratorChunk(state, Qualifiers::OCL_Autoreleasing, transferARCOwnershipToDeclaratorChunk(state, Qualifiers::OCL_Autoreleasing,
@ -3272,7 +3268,7 @@ static CallingConv getCCForDeclaratorChunk(
assert(D.getTypeObject(ChunkIndex).Kind == DeclaratorChunk::Function); assert(D.getTypeObject(ChunkIndex).Kind == DeclaratorChunk::Function);
// Check for an explicit CC attribute. // Check for an explicit CC attribute.
for (const AttributeList &AL : AttrList) { for (const ParsedAttr &AL : AttrList) {
switch (AL.getKind()) { switch (AL.getKind()) {
CALLING_CONV_ATTRS_CASELIST : { CALLING_CONV_ATTRS_CASELIST : {
// Ignore attributes that don't validate or can't apply to the // Ignore attributes that don't validate or can't apply to the
@ -3335,8 +3331,8 @@ static CallingConv getCCForDeclaratorChunk(
// convention attribute. This is the simplest place to infer // convention attribute. This is the simplest place to infer
// calling convention for OpenCL kernels. // calling convention for OpenCL kernels.
if (S.getLangOpts().OpenCL) { if (S.getLangOpts().OpenCL) {
for (const AttributeList &AL : D.getDeclSpec().getAttributes()) { for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
if (AL.getKind() == AttributeList::AT_OpenCLKernel) { if (AL.getKind() == ParsedAttr::AT_OpenCLKernel) {
CC = CC_OpenCLKernel; CC = CC_OpenCLKernel;
break; break;
} }
@ -3388,10 +3384,10 @@ IdentifierInfo *Sema::getNSErrorIdent() {
/// Check whether there is a nullability attribute of any kind in the given /// Check whether there is a nullability attribute of any kind in the given
/// attribute list. /// attribute list.
static bool hasNullabilityAttr(const ParsedAttributesView &attrs) { static bool hasNullabilityAttr(const ParsedAttributesView &attrs) {
for (const AttributeList &AL : attrs) { for (const ParsedAttr &AL : attrs) {
if (AL.getKind() == AttributeList::AT_TypeNonNull || if (AL.getKind() == ParsedAttr::AT_TypeNonNull ||
AL.getKind() == AttributeList::AT_TypeNullable || AL.getKind() == ParsedAttr::AT_TypeNullable ||
AL.getKind() == AttributeList::AT_TypeNullUnspecified) AL.getKind() == ParsedAttr::AT_TypeNullUnspecified)
return true; return true;
} }
@ -3995,9 +3991,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// infer the inner pointer as _Nullable. // infer the inner pointer as _Nullable.
auto hasCFReturnsAttr = auto hasCFReturnsAttr =
[](const ParsedAttributesView &AttrList) -> bool { [](const ParsedAttributesView &AttrList) -> bool {
return AttrList.hasAttribute(AttributeList::AT_CFReturnsRetained) || return AttrList.hasAttribute(ParsedAttr::AT_CFReturnsRetained) ||
AttrList.hasAttribute( AttrList.hasAttribute(ParsedAttr::AT_CFReturnsNotRetained);
AttributeList::AT_CFReturnsNotRetained);
}; };
if (const auto *InnermostChunk = D.getInnermostNonParenChunk()) { if (const auto *InnermostChunk = D.getInnermostNonParenChunk()) {
if (hasCFReturnsAttr(D.getAttributes()) || if (hasCFReturnsAttr(D.getAttributes()) ||
@ -4061,7 +4056,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
auto inferPointerNullability = auto inferPointerNullability =
[&](SimplePointerKind pointerKind, SourceLocation pointerLoc, [&](SimplePointerKind pointerKind, SourceLocation pointerLoc,
SourceLocation pointerEndLoc, SourceLocation pointerEndLoc,
ParsedAttributesView &attrs) -> AttributeList * { ParsedAttributesView &attrs) -> ParsedAttr * {
// We've seen a pointer. // We've seen a pointer.
if (NumPointersRemaining > 0) if (NumPointersRemaining > 0)
--NumPointersRemaining; --NumPointersRemaining;
@ -4072,16 +4067,14 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// If we're supposed to infer nullability, do so now. // If we're supposed to infer nullability, do so now.
if (inferNullability && !inferNullabilityInnerOnlyComplete) { if (inferNullability && !inferNullabilityInnerOnlyComplete) {
AttributeList::Syntax syntax ParsedAttr::Syntax syntax = inferNullabilityCS
= inferNullabilityCS ? AttributeList::AS_ContextSensitiveKeyword ? ParsedAttr::AS_ContextSensitiveKeyword
: AttributeList::AS_Keyword; : ParsedAttr::AS_Keyword;
AttributeList *nullabilityAttr = state.getDeclarator().getAttributePool() ParsedAttr *nullabilityAttr =
.create( state.getDeclarator().getAttributePool().create(
S.getNullabilityKeyword( S.getNullabilityKeyword(*inferNullability),
*inferNullability), SourceRange(pointerLoc), nullptr, SourceLocation(), nullptr, 0,
SourceRange(pointerLoc), syntax);
nullptr, SourceLocation(),
nullptr, 0, syntax);
attrs.addAtStart(nullabilityAttr); attrs.addAtStart(nullabilityAttr);
@ -4474,16 +4467,16 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
SourceLocation AttrLoc; SourceLocation AttrLoc;
if (chunkIndex + 1 < D.getNumTypeObjects()) { if (chunkIndex + 1 < D.getNumTypeObjects()) {
DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1); DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1);
for (const AttributeList &AL : ReturnTypeChunk.getAttrs()) { for (const ParsedAttr &AL : ReturnTypeChunk.getAttrs()) {
if (AL.getKind() == AttributeList::AT_ObjCOwnership) { if (AL.getKind() == ParsedAttr::AT_ObjCOwnership) {
AttrLoc = AL.getLoc(); AttrLoc = AL.getLoc();
break; break;
} }
} }
} }
if (AttrLoc.isInvalid()) { if (AttrLoc.isInvalid()) {
for (const AttributeList &AL : D.getDeclSpec().getAttributes()) { for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
if (AL.getKind() == AttributeList::AT_ObjCOwnership) { if (AL.getKind() == ParsedAttr::AT_ObjCOwnership) {
AttrLoc = AL.getLoc(); AttrLoc = AL.getLoc();
break; break;
} }
@ -4536,7 +4529,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// function is marked with the "overloadable" attribute. Scan // function is marked with the "overloadable" attribute. Scan
// for this attribute now. // for this attribute now.
if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus) if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus)
if (!D.getAttributes().hasAttribute(AttributeList::AT_Overloadable)) if (!D.getAttributes().hasAttribute(ParsedAttr::AT_Overloadable))
S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_param); S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_param);
if (FTI.NumParams && FTI.Params[0].Param == nullptr) { if (FTI.NumParams && FTI.Params[0].Param == nullptr) {
@ -5024,7 +5017,7 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
// Look for an explicit lifetime attribute. // Look for an explicit lifetime attribute.
DeclaratorChunk &chunk = D.getTypeObject(chunkIndex); DeclaratorChunk &chunk = D.getTypeObject(chunkIndex);
if (chunk.getAttrs().hasAttribute(AttributeList::AT_ObjCOwnership)) if (chunk.getAttrs().hasAttribute(ParsedAttr::AT_ObjCOwnership))
return; return;
const char *attrStr = nullptr; const char *attrStr = nullptr;
@ -5044,10 +5037,10 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
// If there wasn't one, add one (with an invalid source location // If there wasn't one, add one (with an invalid source location
// so that we don't make an AttributedType for it). // so that we don't make an AttributedType for it).
AttributeList *attr = D.getAttributePool() ParsedAttr *attr = D.getAttributePool().create(
.create(&S.Context.Idents.get("objc_ownership"), SourceLocation(), &S.Context.Idents.get("objc_ownership"), SourceLocation(),
/*scope*/ nullptr, SourceLocation(), /*scope*/ nullptr, SourceLocation(),
/*args*/ &Args, 1, AttributeList::AS_GNU); /*args*/ &Args, 1, ParsedAttr::AS_GNU);
chunk.getAttrs().addAtStart(attr); chunk.getAttrs().addAtStart(attr);
// TODO: mark whether we did this inference? // TODO: mark whether we did this inference?
} }
@ -5119,81 +5112,80 @@ TypeSourceInfo *Sema::GetTypeForDeclaratorCast(Declarator &D, QualType FromTy) {
return GetFullTypeForDeclarator(state, declSpecTy, ReturnTypeInfo); return GetFullTypeForDeclarator(state, declSpecTy, ReturnTypeInfo);
} }
/// Map an AttributedType::Kind to an AttributeList::Kind. /// Map an AttributedType::Kind to an ParsedAttr::Kind.
static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) { static ParsedAttr::Kind getAttrListKind(AttributedType::Kind kind) {
switch (kind) { switch (kind) {
case AttributedType::attr_address_space: case AttributedType::attr_address_space:
return AttributeList::AT_AddressSpace; return ParsedAttr::AT_AddressSpace;
case AttributedType::attr_regparm: case AttributedType::attr_regparm:
return AttributeList::AT_Regparm; return ParsedAttr::AT_Regparm;
case AttributedType::attr_vector_size: case AttributedType::attr_vector_size:
return AttributeList::AT_VectorSize; return ParsedAttr::AT_VectorSize;
case AttributedType::attr_neon_vector_type: case AttributedType::attr_neon_vector_type:
return AttributeList::AT_NeonVectorType; return ParsedAttr::AT_NeonVectorType;
case AttributedType::attr_neon_polyvector_type: case AttributedType::attr_neon_polyvector_type:
return AttributeList::AT_NeonPolyVectorType; return ParsedAttr::AT_NeonPolyVectorType;
case AttributedType::attr_objc_gc: case AttributedType::attr_objc_gc:
return AttributeList::AT_ObjCGC; return ParsedAttr::AT_ObjCGC;
case AttributedType::attr_objc_ownership: case AttributedType::attr_objc_ownership:
case AttributedType::attr_objc_inert_unsafe_unretained: case AttributedType::attr_objc_inert_unsafe_unretained:
return AttributeList::AT_ObjCOwnership; return ParsedAttr::AT_ObjCOwnership;
case AttributedType::attr_noreturn: case AttributedType::attr_noreturn:
return AttributeList::AT_NoReturn; return ParsedAttr::AT_NoReturn;
case AttributedType::attr_nocf_check: case AttributedType::attr_nocf_check:
return AttributeList::AT_AnyX86NoCfCheck; return ParsedAttr::AT_AnyX86NoCfCheck;
case AttributedType::attr_cdecl: case AttributedType::attr_cdecl:
return AttributeList::AT_CDecl; return ParsedAttr::AT_CDecl;
case AttributedType::attr_fastcall: case AttributedType::attr_fastcall:
return AttributeList::AT_FastCall; return ParsedAttr::AT_FastCall;
case AttributedType::attr_stdcall: case AttributedType::attr_stdcall:
return AttributeList::AT_StdCall; return ParsedAttr::AT_StdCall;
case AttributedType::attr_thiscall: case AttributedType::attr_thiscall:
return AttributeList::AT_ThisCall; return ParsedAttr::AT_ThisCall;
case AttributedType::attr_regcall: case AttributedType::attr_regcall:
return AttributeList::AT_RegCall; return ParsedAttr::AT_RegCall;
case AttributedType::attr_pascal: case AttributedType::attr_pascal:
return AttributeList::AT_Pascal; return ParsedAttr::AT_Pascal;
case AttributedType::attr_swiftcall: case AttributedType::attr_swiftcall:
return AttributeList::AT_SwiftCall; return ParsedAttr::AT_SwiftCall;
case AttributedType::attr_vectorcall: case AttributedType::attr_vectorcall:
return AttributeList::AT_VectorCall; return ParsedAttr::AT_VectorCall;
case AttributedType::attr_pcs: case AttributedType::attr_pcs:
case AttributedType::attr_pcs_vfp: case AttributedType::attr_pcs_vfp:
return AttributeList::AT_Pcs; return ParsedAttr::AT_Pcs;
case AttributedType::attr_inteloclbicc: case AttributedType::attr_inteloclbicc:
return AttributeList::AT_IntelOclBicc; return ParsedAttr::AT_IntelOclBicc;
case AttributedType::attr_ms_abi: case AttributedType::attr_ms_abi:
return AttributeList::AT_MSABI; return ParsedAttr::AT_MSABI;
case AttributedType::attr_sysv_abi: case AttributedType::attr_sysv_abi:
return AttributeList::AT_SysVABI; return ParsedAttr::AT_SysVABI;
case AttributedType::attr_preserve_most: case AttributedType::attr_preserve_most:
return AttributeList::AT_PreserveMost; return ParsedAttr::AT_PreserveMost;
case AttributedType::attr_preserve_all: case AttributedType::attr_preserve_all:
return AttributeList::AT_PreserveAll; return ParsedAttr::AT_PreserveAll;
case AttributedType::attr_ptr32: case AttributedType::attr_ptr32:
return AttributeList::AT_Ptr32; return ParsedAttr::AT_Ptr32;
case AttributedType::attr_ptr64: case AttributedType::attr_ptr64:
return AttributeList::AT_Ptr64; return ParsedAttr::AT_Ptr64;
case AttributedType::attr_sptr: case AttributedType::attr_sptr:
return AttributeList::AT_SPtr; return ParsedAttr::AT_SPtr;
case AttributedType::attr_uptr: case AttributedType::attr_uptr:
return AttributeList::AT_UPtr; return ParsedAttr::AT_UPtr;
case AttributedType::attr_nonnull: case AttributedType::attr_nonnull:
return AttributeList::AT_TypeNonNull; return ParsedAttr::AT_TypeNonNull;
case AttributedType::attr_nullable: case AttributedType::attr_nullable:
return AttributeList::AT_TypeNullable; return ParsedAttr::AT_TypeNullable;
case AttributedType::attr_null_unspecified: case AttributedType::attr_null_unspecified:
return AttributeList::AT_TypeNullUnspecified; return ParsedAttr::AT_TypeNullUnspecified;
case AttributedType::attr_objc_kindof: case AttributedType::attr_objc_kindof:
return AttributeList::AT_ObjCKindOf; return ParsedAttr::AT_ObjCKindOf;
case AttributedType::attr_ns_returns_retained: case AttributedType::attr_ns_returns_retained:
return AttributeList::AT_NSReturnsRetained; return ParsedAttr::AT_NSReturnsRetained;
} }
llvm_unreachable("unexpected attribute kind!"); llvm_unreachable("unexpected attribute kind!");
} }
static void setAttributedTypeLoc(AttributedTypeLoc TL, static void setAttributedTypeLoc(AttributedTypeLoc TL, const ParsedAttr &attr) {
const AttributeList &attr) {
TL.setAttrNameLoc(attr.getLoc()); TL.setAttrNameLoc(attr.getLoc());
if (TL.hasAttrExprOperand()) { if (TL.hasAttrExprOperand()) {
assert(attr.isArgExpr(0) && "mismatched attribute operand kind"); assert(attr.isArgExpr(0) && "mismatched attribute operand kind");
@ -5219,13 +5211,13 @@ static void fillAttributedTypeLoc(AttributedTypeLoc TL,
assert((!Attrs.empty() || !DeclAttrs.empty()) && assert((!Attrs.empty() || !DeclAttrs.empty()) &&
"no type attributes in the expected location!"); "no type attributes in the expected location!");
AttributeList::Kind parsedKind = getAttrListKind(TL.getAttrKind()); ParsedAttr::Kind parsedKind = getAttrListKind(TL.getAttrKind());
// Try to search for an attribute of matching kind in Attrs list. // Try to search for an attribute of matching kind in Attrs list.
for (const AttributeList &AL : Attrs) for (const ParsedAttr &AL : Attrs)
if (AL.getKind() == parsedKind) if (AL.getKind() == parsedKind)
return setAttributedTypeLoc(TL, AL); return setAttributedTypeLoc(TL, AL);
for (const AttributeList &AL : DeclAttrs) for (const ParsedAttr &AL : DeclAttrs)
if (AL.isCXX11Attribute() || AL.getKind() == parsedKind) if (AL.isCXX11Attribute() || AL.getKind() == parsedKind)
return setAttributedTypeLoc(TL, AL); return setAttributedTypeLoc(TL, AL);
llvm_unreachable("no matching type attribute in expected location!"); llvm_unreachable("no matching type attribute in expected location!");
@ -5549,8 +5541,8 @@ static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) {
static void static void
fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL, fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
const ParsedAttributesView &Attrs) { const ParsedAttributesView &Attrs) {
for (const AttributeList &AL : Attrs) { for (const ParsedAttr &AL : Attrs) {
if (AL.getKind() == AttributeList::AT_AddressSpace) { if (AL.getKind() == ParsedAttr::AT_AddressSpace) {
DASTL.setAttrNameLoc(AL.getLoc()); DASTL.setAttrNameLoc(AL.getLoc());
DASTL.setAttrExprOperand(AL.getArgAsExpr(0)); DASTL.setAttrExprOperand(AL.getArgAsExpr(0));
DASTL.setAttrOperandParensRange(SourceRange()); DASTL.setAttrOperandParensRange(SourceRange());
@ -5755,7 +5747,7 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
/// specified type. The attribute contains 1 argument, the id of the address /// specified type. The attribute contains 1 argument, the id of the address
/// space for the type. /// space for the type.
static void HandleAddressSpaceTypeAttribute(QualType &Type, static void HandleAddressSpaceTypeAttribute(QualType &Type,
const AttributeList &Attr, Sema &S){ const ParsedAttr &Attr, Sema &S) {
// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "A function type shall not be // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "A function type shall not be
// qualified by an address-space qualifier." // qualified by an address-space qualifier."
if (Type->isFunctionType()) { if (Type->isFunctionType()) {
@ -5765,7 +5757,7 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
} }
LangAS ASIdx; LangAS ASIdx;
if (Attr.getKind() == AttributeList::AT_AddressSpace) { if (Attr.getKind() == ParsedAttr::AT_AddressSpace) {
// Check the attribute arguments. // Check the attribute arguments.
if (Attr.getNumArgs() != 1) { if (Attr.getNumArgs() != 1) {
@ -5804,15 +5796,15 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
} else { } else {
// The keyword-based type attributes imply which address space to use. // The keyword-based type attributes imply which address space to use.
switch (Attr.getKind()) { switch (Attr.getKind()) {
case AttributeList::AT_OpenCLGlobalAddressSpace: case ParsedAttr::AT_OpenCLGlobalAddressSpace:
ASIdx = LangAS::opencl_global; break; ASIdx = LangAS::opencl_global; break;
case AttributeList::AT_OpenCLLocalAddressSpace: case ParsedAttr::AT_OpenCLLocalAddressSpace:
ASIdx = LangAS::opencl_local; break; ASIdx = LangAS::opencl_local; break;
case AttributeList::AT_OpenCLConstantAddressSpace: case ParsedAttr::AT_OpenCLConstantAddressSpace:
ASIdx = LangAS::opencl_constant; break; ASIdx = LangAS::opencl_constant; break;
case AttributeList::AT_OpenCLGenericAddressSpace: case ParsedAttr::AT_OpenCLGenericAddressSpace:
ASIdx = LangAS::opencl_generic; break; ASIdx = LangAS::opencl_generic; break;
case AttributeList::AT_OpenCLPrivateAddressSpace: case ParsedAttr::AT_OpenCLPrivateAddressSpace:
ASIdx = LangAS::opencl_private; break; ASIdx = LangAS::opencl_private; break;
default: default:
llvm_unreachable("Invalid address space"); llvm_unreachable("Invalid address space");
@ -5872,8 +5864,7 @@ static bool hasDirectOwnershipQualifier(QualType type) {
/// ///
/// Returns 'true' if the attribute was handled. /// Returns 'true' if the attribute was handled.
static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
AttributeList &attr, ParsedAttr &attr, QualType &type) {
QualType &type) {
bool NonObjCPointer = false; bool NonObjCPointer = false;
if (!type->isDependentType() && !type->isUndeducedType()) { if (!type->isDependentType() && !type->isUndeducedType()) {
@ -6058,8 +6049,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
/// attribute on the specified type. Returns true to indicate that /// attribute on the specified type. Returns true to indicate that
/// the attribute was handled, false to indicate that the type does /// the attribute was handled, false to indicate that the type does
/// not permit the attribute. /// not permit the attribute.
static bool handleObjCGCTypeAttr(TypeProcessingState &state, static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
AttributeList &attr,
QualType &type) { QualType &type) {
Sema &S = state.getSema(); Sema &S = state.getSema();
@ -6251,11 +6241,10 @@ namespace {
} // end anonymous namespace } // end anonymous namespace
static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State, static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
AttributeList &Attr, ParsedAttr &Attr, QualType &Type) {
QualType &Type) {
Sema &S = State.getSema(); Sema &S = State.getSema();
AttributeList::Kind Kind = Attr.getKind(); ParsedAttr::Kind Kind = Attr.getKind();
QualType Desugared = Type; QualType Desugared = Type;
const AttributedType *AT = dyn_cast<AttributedType>(Type); const AttributedType *AT = dyn_cast<AttributedType>(Type);
while (AT) { while (AT) {
@ -6272,16 +6261,16 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
// You cannot have both __sptr and __uptr on the same type, nor can you // You cannot have both __sptr and __uptr on the same type, nor can you
// have __ptr32 and __ptr64. // have __ptr32 and __ptr64.
if ((CurAttrKind == AttributedType::attr_ptr32 && if ((CurAttrKind == AttributedType::attr_ptr32 &&
Kind == AttributeList::AT_Ptr64) || Kind == ParsedAttr::AT_Ptr64) ||
(CurAttrKind == AttributedType::attr_ptr64 && (CurAttrKind == AttributedType::attr_ptr64 &&
Kind == AttributeList::AT_Ptr32)) { Kind == ParsedAttr::AT_Ptr32)) {
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< "'__ptr32'" << "'__ptr64'"; << "'__ptr32'" << "'__ptr64'";
return true; return true;
} else if ((CurAttrKind == AttributedType::attr_sptr && } else if ((CurAttrKind == AttributedType::attr_sptr &&
Kind == AttributeList::AT_UPtr) || Kind == ParsedAttr::AT_UPtr) ||
(CurAttrKind == AttributedType::attr_uptr && (CurAttrKind == AttributedType::attr_uptr &&
Kind == AttributeList::AT_SPtr)) { Kind == ParsedAttr::AT_SPtr)) {
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< "'__sptr'" << "'__uptr'"; << "'__sptr'" << "'__uptr'";
return true; return true;
@ -6306,10 +6295,18 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
AttributedType::Kind TAK; AttributedType::Kind TAK;
switch (Kind) { switch (Kind) {
default: llvm_unreachable("Unknown attribute kind"); default: llvm_unreachable("Unknown attribute kind");
case AttributeList::AT_Ptr32: TAK = AttributedType::attr_ptr32; break; case ParsedAttr::AT_Ptr32:
case AttributeList::AT_Ptr64: TAK = AttributedType::attr_ptr64; break; TAK = AttributedType::attr_ptr32;
case AttributeList::AT_SPtr: TAK = AttributedType::attr_sptr; break; break;
case AttributeList::AT_UPtr: TAK = AttributedType::attr_uptr; 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 = S.Context.getAttributedType(TAK, Type, Type);
@ -6460,15 +6457,15 @@ bool Sema::checkObjCKindOfType(QualType &type, SourceLocation loc) {
} }
/// Map a nullability attribute kind to a nullability kind. /// Map a nullability attribute kind to a nullability kind.
static NullabilityKind mapNullabilityAttrKind(AttributeList::Kind kind) { static NullabilityKind mapNullabilityAttrKind(ParsedAttr::Kind kind) {
switch (kind) { switch (kind) {
case AttributeList::AT_TypeNonNull: case ParsedAttr::AT_TypeNonNull:
return NullabilityKind::NonNull; return NullabilityKind::NonNull;
case AttributeList::AT_TypeNullable: case ParsedAttr::AT_TypeNullable:
return NullabilityKind::Nullable; return NullabilityKind::Nullable;
case AttributeList::AT_TypeNullUnspecified: case ParsedAttr::AT_TypeNullUnspecified:
return NullabilityKind::Unspecified; return NullabilityKind::Unspecified;
default: default:
@ -6483,8 +6480,7 @@ static NullabilityKind mapNullabilityAttrKind(AttributeList::Kind kind) {
/// \returns true if the nullability annotation was distributed, false /// \returns true if the nullability annotation was distributed, false
/// otherwise. /// otherwise.
static bool distributeNullabilityTypeAttr(TypeProcessingState &state, static bool distributeNullabilityTypeAttr(TypeProcessingState &state,
QualType type, QualType type, ParsedAttr &attr) {
AttributeList &attr) {
Declarator &declarator = state.getDeclarator(); Declarator &declarator = state.getDeclarator();
/// Attempt to move the attribute to the specified chunk. /// Attempt to move the attribute to the specified chunk.
@ -6564,28 +6560,28 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state,
return false; return false;
} }
static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) { static AttributedType::Kind getCCTypeAttrKind(ParsedAttr &Attr) {
assert(!Attr.isInvalid()); assert(!Attr.isInvalid());
switch (Attr.getKind()) { switch (Attr.getKind()) {
default: default:
llvm_unreachable("not a calling convention attribute"); llvm_unreachable("not a calling convention attribute");
case AttributeList::AT_CDecl: case ParsedAttr::AT_CDecl:
return AttributedType::attr_cdecl; return AttributedType::attr_cdecl;
case AttributeList::AT_FastCall: case ParsedAttr::AT_FastCall:
return AttributedType::attr_fastcall; return AttributedType::attr_fastcall;
case AttributeList::AT_StdCall: case ParsedAttr::AT_StdCall:
return AttributedType::attr_stdcall; return AttributedType::attr_stdcall;
case AttributeList::AT_ThisCall: case ParsedAttr::AT_ThisCall:
return AttributedType::attr_thiscall; return AttributedType::attr_thiscall;
case AttributeList::AT_RegCall: case ParsedAttr::AT_RegCall:
return AttributedType::attr_regcall; return AttributedType::attr_regcall;
case AttributeList::AT_Pascal: case ParsedAttr::AT_Pascal:
return AttributedType::attr_pascal; return AttributedType::attr_pascal;
case AttributeList::AT_SwiftCall: case ParsedAttr::AT_SwiftCall:
return AttributedType::attr_swiftcall; return AttributedType::attr_swiftcall;
case AttributeList::AT_VectorCall: case ParsedAttr::AT_VectorCall:
return AttributedType::attr_vectorcall; return AttributedType::attr_vectorcall;
case AttributeList::AT_Pcs: { case ParsedAttr::AT_Pcs: {
// The attribute may have had a fixit applied where we treated an // The attribute may have had a fixit applied where we treated an
// identifier as a string literal. The contents of the string are valid, // identifier as a string literal. The contents of the string are valid,
// but the form may not be. // but the form may not be.
@ -6598,15 +6594,15 @@ static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) {
.Case("aapcs", AttributedType::attr_pcs) .Case("aapcs", AttributedType::attr_pcs)
.Case("aapcs-vfp", AttributedType::attr_pcs_vfp); .Case("aapcs-vfp", AttributedType::attr_pcs_vfp);
} }
case AttributeList::AT_IntelOclBicc: case ParsedAttr::AT_IntelOclBicc:
return AttributedType::attr_inteloclbicc; return AttributedType::attr_inteloclbicc;
case AttributeList::AT_MSABI: case ParsedAttr::AT_MSABI:
return AttributedType::attr_ms_abi; return AttributedType::attr_ms_abi;
case AttributeList::AT_SysVABI: case ParsedAttr::AT_SysVABI:
return AttributedType::attr_sysv_abi; return AttributedType::attr_sysv_abi;
case AttributeList::AT_PreserveMost: case ParsedAttr::AT_PreserveMost:
return AttributedType::attr_preserve_most; return AttributedType::attr_preserve_most;
case AttributeList::AT_PreserveAll: case ParsedAttr::AT_PreserveAll:
return AttributedType::attr_preserve_all; return AttributedType::attr_preserve_all;
} }
llvm_unreachable("unexpected attribute kind!"); llvm_unreachable("unexpected attribute kind!");
@ -6614,14 +6610,13 @@ static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) {
/// Process an individual function attribute. Returns true to /// Process an individual function attribute. Returns true to
/// indicate that the attribute was handled, false if it wasn't. /// indicate that the attribute was handled, false if it wasn't.
static bool handleFunctionTypeAttr(TypeProcessingState &state, static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
AttributeList &attr,
QualType &type) { QualType &type) {
Sema &S = state.getSema(); Sema &S = state.getSema();
FunctionTypeUnwrapper unwrapped(S, type); FunctionTypeUnwrapper unwrapped(S, type);
if (attr.getKind() == AttributeList::AT_NoReturn) { if (attr.getKind() == ParsedAttr::AT_NoReturn) {
if (S.CheckAttrNoArgs(attr)) if (S.CheckAttrNoArgs(attr))
return true; return true;
@ -6637,7 +6632,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
// ns_returns_retained is not always a type attribute, but if we got // ns_returns_retained is not always a type attribute, but if we got
// here, we're treating it as one right now. // here, we're treating it as one right now.
if (attr.getKind() == AttributeList::AT_NSReturnsRetained) { if (attr.getKind() == ParsedAttr::AT_NSReturnsRetained) {
if (attr.getNumArgs()) return true; if (attr.getNumArgs()) return true;
// Delay if this is not a function type. // Delay if this is not a function type.
@ -6661,7 +6656,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
return true; return true;
} }
if (attr.getKind() == AttributeList::AT_AnyX86NoCallerSavedRegisters) { if (attr.getKind() == ParsedAttr::AT_AnyX86NoCallerSavedRegisters) {
if (S.CheckAttrTarget(attr) || S.CheckAttrNoArgs(attr)) if (S.CheckAttrTarget(attr) || S.CheckAttrNoArgs(attr))
return true; return true;
@ -6675,7 +6670,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
return true; return true;
} }
if (attr.getKind() == AttributeList::AT_AnyX86NoCfCheck) { if (attr.getKind() == ParsedAttr::AT_AnyX86NoCfCheck) {
if (!S.getLangOpts().CFProtectionBranch) { if (!S.getLangOpts().CFProtectionBranch) {
S.Diag(attr.getLoc(), diag::warn_nocf_check_attribute_ignored); S.Diag(attr.getLoc(), diag::warn_nocf_check_attribute_ignored);
attr.setInvalid(); attr.setInvalid();
@ -6696,7 +6691,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
return true; return true;
} }
if (attr.getKind() == AttributeList::AT_Regparm) { if (attr.getKind() == ParsedAttr::AT_Regparm) {
unsigned value; unsigned value;
if (S.CheckRegparmAttr(attr, value)) if (S.CheckRegparmAttr(attr, value))
return true; return true;
@ -6853,7 +6848,7 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor,
/// The raw attribute should contain precisely 1 argument, the vector size for /// The raw attribute should contain precisely 1 argument, the vector size for
/// the variable, measured in bytes. If curType and rawAttr are well formed, /// the variable, measured in bytes. If curType and rawAttr are well formed,
/// this routine will return a new vector type. /// this routine will return a new vector type.
static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, static void HandleVectorSizeAttr(QualType &CurType, const ParsedAttr &Attr,
Sema &S) { Sema &S) {
// Check the attribute arguments. // Check the attribute arguments.
if (Attr.getNumArgs() != 1) { if (Attr.getNumArgs() != 1) {
@ -6912,8 +6907,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
/// Process the OpenCL-like ext_vector_type attribute when it occurs on /// Process the OpenCL-like ext_vector_type attribute when it occurs on
/// a type. /// a type.
static void HandleExtVectorTypeAttr(QualType &CurType, static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
const AttributeList &Attr,
Sema &S) { Sema &S) {
// check the attribute arguments. // check the attribute arguments.
if (Attr.getNumArgs() != 1) { if (Attr.getNumArgs() != 1) {
@ -7002,9 +6996,8 @@ static bool isPermittedNeonBaseType(QualType &Ty,
/// the argument to these Neon attributes is the number of vector elements, /// the argument to these Neon attributes is the number of vector elements,
/// not the vector size in bytes. The vector width and element type must /// not the vector size in bytes. The vector width and element type must
/// match one of the standard Neon vector types. /// match one of the standard Neon vector types.
static void HandleNeonVectorTypeAttr(QualType& CurType, static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
const AttributeList &Attr, Sema &S, Sema &S, VectorType::VectorKind VecKind) {
VectorType::VectorKind VecKind) {
// Target must have NEON // Target must have NEON
if (!S.Context.getTargetInfo().hasFeature("neon")) { if (!S.Context.getTargetInfo().hasFeature("neon")) {
S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr.getName(); S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr.getName();
@ -7050,7 +7043,7 @@ static void HandleNeonVectorTypeAttr(QualType& CurType,
} }
/// Handle OpenCL Access Qualifier Attribute. /// Handle OpenCL Access Qualifier Attribute.
static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr, static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr,
Sema &S) { Sema &S) {
// OpenCL v2.0 s6.6 - Access qualifier can be used only for image and pipe type. // OpenCL v2.0 s6.6 - Access qualifier can be used only for image and pipe type.
if (!(CurType->isImageType() || CurType->isPipeType())) { if (!(CurType->isImageType() || CurType->isPipeType())) {
@ -7183,7 +7176,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
// sure we visit every element once. Copy the attributes list, and iterate // sure we visit every element once. Copy the attributes list, and iterate
// over that. // over that.
ParsedAttributesView AttrsCopy{attrs}; ParsedAttributesView AttrsCopy{attrs};
for (AttributeList &attr : AttrsCopy) { for (ParsedAttr &attr : AttrsCopy) {
// Skip attributes that were marked to be invalid. // Skip attributes that were marked to be invalid.
if (attr.isInvalid()) if (attr.isInvalid())
@ -7224,27 +7217,27 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
} }
break; break;
case AttributeList::UnknownAttribute: case ParsedAttr::UnknownAttribute:
if (attr.isCXX11Attribute() && TAL == TAL_DeclChunk) if (attr.isCXX11Attribute() && TAL == TAL_DeclChunk)
state.getSema().Diag(attr.getLoc(), state.getSema().Diag(attr.getLoc(),
diag::warn_unknown_attribute_ignored) diag::warn_unknown_attribute_ignored)
<< attr.getName(); << attr.getName();
break; break;
case AttributeList::IgnoredAttribute: case ParsedAttr::IgnoredAttribute:
break; break;
case AttributeList::AT_MayAlias: case ParsedAttr::AT_MayAlias:
// FIXME: This attribute needs to actually be handled, but if we ignore // FIXME: This attribute needs to actually be handled, but if we ignore
// it it breaks large amounts of Linux software. // it it breaks large amounts of Linux software.
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
case AttributeList::AT_OpenCLPrivateAddressSpace: case ParsedAttr::AT_OpenCLPrivateAddressSpace:
case AttributeList::AT_OpenCLGlobalAddressSpace: case ParsedAttr::AT_OpenCLGlobalAddressSpace:
case AttributeList::AT_OpenCLLocalAddressSpace: case ParsedAttr::AT_OpenCLLocalAddressSpace:
case AttributeList::AT_OpenCLConstantAddressSpace: case ParsedAttr::AT_OpenCLConstantAddressSpace:
case AttributeList::AT_OpenCLGenericAddressSpace: case ParsedAttr::AT_OpenCLGenericAddressSpace:
case AttributeList::AT_AddressSpace: case ParsedAttr::AT_AddressSpace:
HandleAddressSpaceTypeAttribute(type, attr, state.getSema()); HandleAddressSpaceTypeAttribute(type, attr, state.getSema());
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
@ -7253,25 +7246,25 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
distributeObjCPointerTypeAttr(state, attr, type); distributeObjCPointerTypeAttr(state, attr, type);
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
case AttributeList::AT_VectorSize: case ParsedAttr::AT_VectorSize:
HandleVectorSizeAttr(type, attr, state.getSema()); HandleVectorSizeAttr(type, attr, state.getSema());
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
case AttributeList::AT_ExtVectorType: case ParsedAttr::AT_ExtVectorType:
HandleExtVectorTypeAttr(type, attr, state.getSema()); HandleExtVectorTypeAttr(type, attr, state.getSema());
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
case AttributeList::AT_NeonVectorType: case ParsedAttr::AT_NeonVectorType:
HandleNeonVectorTypeAttr(type, attr, state.getSema(), HandleNeonVectorTypeAttr(type, attr, state.getSema(),
VectorType::NeonVector); VectorType::NeonVector);
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
case AttributeList::AT_NeonPolyVectorType: case ParsedAttr::AT_NeonPolyVectorType:
HandleNeonVectorTypeAttr(type, attr, state.getSema(), HandleNeonVectorTypeAttr(type, attr, state.getSema(),
VectorType::NeonPolyVector); VectorType::NeonPolyVector);
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
case AttributeList::AT_OpenCLAccess: case ParsedAttr::AT_OpenCLAccess:
HandleOpenCLAccessAttr(type, attr, state.getSema()); HandleOpenCLAccessAttr(type, attr, state.getSema());
attr.setUsedAsTypeAttr(); attr.setUsedAsTypeAttr();
break; break;
@ -7310,7 +7303,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
} }
break; break;
case AttributeList::AT_ObjCKindOf: case ParsedAttr::AT_ObjCKindOf:
// '__kindof' must be part of the decl-specifiers. // '__kindof' must be part of the decl-specifiers.
switch (TAL) { switch (TAL) {
case TAL_DeclSpec: case TAL_DeclSpec:

View File

@ -3132,7 +3132,7 @@ static void emitArgInfo(const Record &R, raw_ostream &OS) {
} }
static void GenerateDefaultAppertainsTo(raw_ostream &OS) { static void GenerateDefaultAppertainsTo(raw_ostream &OS) {
OS << "static bool defaultAppertainsTo(Sema &, const AttributeList &,"; OS << "static bool defaultAppertainsTo(Sema &, const ParsedAttr &,";
OS << "const Decl *) {\n"; OS << "const Decl *) {\n";
OS << " return true;\n"; OS << " return true;\n";
OS << "}\n\n"; OS << "}\n\n";
@ -3270,7 +3270,7 @@ static std::string GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
// name of that check to the caller. // name of that check to the caller.
std::string FnName = "check" + Attr.getName().str() + "AppertainsTo"; std::string FnName = "check" + Attr.getName().str() + "AppertainsTo";
std::stringstream SS; std::stringstream SS;
SS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr, "; SS << "static bool " << FnName << "(Sema &S, const ParsedAttr &Attr, ";
SS << "const Decl *D) {\n"; SS << "const Decl *D) {\n";
SS << " if ("; SS << " if (";
for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) { for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
@ -3342,7 +3342,7 @@ emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
static void GenerateDefaultLangOptRequirements(raw_ostream &OS) { static void GenerateDefaultLangOptRequirements(raw_ostream &OS) {
OS << "static bool defaultDiagnoseLangOpts(Sema &, "; OS << "static bool defaultDiagnoseLangOpts(Sema &, ";
OS << "const AttributeList &) {\n"; OS << "const ParsedAttr &) {\n";
OS << " return true;\n"; OS << " return true;\n";
OS << "}\n\n"; OS << "}\n\n";
} }
@ -3381,7 +3381,7 @@ static std::string GenerateLangOptRequirements(const Record &R,
if (I != CustomLangOptsSet.end()) if (I != CustomLangOptsSet.end())
return *I; return *I;
OS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr) {\n"; OS << "static bool " << FnName << "(Sema &S, const ParsedAttr &Attr) {\n";
OS << " if (" << Test << ")\n"; OS << " if (" << Test << ")\n";
OS << " return true;\n\n"; OS << " return true;\n\n";
OS << " S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) "; OS << " S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) ";
@ -3414,7 +3414,7 @@ static std::string GenerateTargetRequirements(const Record &Attr,
// If there are other attributes which share the same parsed attribute kind, // If there are other attributes which share the same parsed attribute kind,
// such as target-specific attributes with a shared spelling, collapse the // such as target-specific attributes with a shared spelling, collapse the
// duplicate architectures. This is required because a shared target-specific // duplicate architectures. This is required because a shared target-specific
// attribute has only one AttributeList::Kind enumeration value, but it // attribute has only one ParsedAttr::Kind enumeration value, but it
// applies to multiple target architectures. In order for the attribute to be // applies to multiple target architectures. In order for the attribute to be
// considered valid, all of its architectures need to be included. // considered valid, all of its architectures need to be included.
if (!Attr.isValueUnset("ParseKind")) { if (!Attr.isValueUnset("ParseKind")) {
@ -3451,7 +3451,7 @@ static std::string GenerateTargetRequirements(const Record &Attr,
static void GenerateDefaultSpellingIndexToSemanticSpelling(raw_ostream &OS) { static void GenerateDefaultSpellingIndexToSemanticSpelling(raw_ostream &OS) {
OS << "static unsigned defaultSpellingIndexToSemanticSpelling(" OS << "static unsigned defaultSpellingIndexToSemanticSpelling("
<< "const AttributeList &Attr) {\n"; << "const ParsedAttr &Attr) {\n";
OS << " return UINT_MAX;\n"; OS << " return UINT_MAX;\n";
OS << "}\n\n"; OS << "}\n\n";
} }
@ -3474,7 +3474,7 @@ static std::string GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap); std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
std::string Name = Attr.getName().str() + "AttrSpellingMap"; std::string Name = Attr.getName().str() + "AttrSpellingMap";
OS << "static unsigned " << Name << "(const AttributeList &Attr) {\n"; OS << "static unsigned " << Name << "(const ParsedAttr &Attr) {\n";
OS << Enum; OS << Enum;
OS << " unsigned Idx = Attr.getAttributeSpellingListIndex();\n"; OS << " unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS); WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
@ -3524,7 +3524,7 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
// the spellings are identical, and custom parsing rules match, etc. // the spellings are identical, and custom parsing rules match, etc.
// We need to generate struct instances based off ParsedAttrInfo from // We need to generate struct instances based off ParsedAttrInfo from
// AttributeList.cpp. // ParsedAttr.cpp.
SS << " { "; SS << " { ";
emitArgInfo(*I->second, SS); emitArgInfo(*I->second, SS);
SS << ", " << I->second->getValueAsBit("HasCustomParsing"); SS << ", " << I->second->getValueAsBit("HasCustomParsing");
@ -3549,7 +3549,8 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
SS << " // AT_" << I->first << "\n"; SS << " // AT_" << I->first << "\n";
} }
OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n"; OS << "static const ParsedAttrInfo AttrInfoMap[ParsedAttr::UnknownAttribute "
"+ 1] = {\n";
OS << SS.str(); OS << SS.str();
OS << "};\n\n"; OS << "};\n\n";
@ -3577,7 +3578,7 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
// specific attribute, or MSP430-specific attribute. Additionally, an // specific attribute, or MSP430-specific attribute. Additionally, an
// attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport"> // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport">
// for the same semantic attribute. Ultimately, we need to map each of // for the same semantic attribute. Ultimately, we need to map each of
// these to a single AttributeList::Kind value, but the StringMatcher // these to a single ParsedAttr::Kind value, but the StringMatcher
// class cannot handle duplicate match strings. So we generate a list of // class cannot handle duplicate match strings. So we generate a list of
// string to match based on the syntax, and emit multiple string matchers // string to match based on the syntax, and emit multiple string matchers
// depending on the syntax used. // depending on the syntax used.
@ -3624,34 +3625,34 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
Spelling += RawSpelling; Spelling += RawSpelling;
if (SemaHandler) if (SemaHandler)
Matches->push_back(StringMatcher::StringPair(Spelling, Matches->push_back(StringMatcher::StringPair(
"return AttributeList::AT_" + AttrName + ";")); Spelling, "return ParsedAttr::AT_" + AttrName + ";"));
else else
Matches->push_back(StringMatcher::StringPair(Spelling, Matches->push_back(StringMatcher::StringPair(
"return AttributeList::IgnoredAttribute;")); Spelling, "return ParsedAttr::IgnoredAttribute;"));
} }
} }
} }
OS << "static AttributeList::Kind getAttrKind(StringRef Name, "; OS << "static ParsedAttr::Kind getAttrKind(StringRef Name, ";
OS << "AttributeList::Syntax Syntax) {\n"; OS << "ParsedAttr::Syntax Syntax) {\n";
OS << " if (AttributeList::AS_GNU == Syntax) {\n"; OS << " if (ParsedAttr::AS_GNU == Syntax) {\n";
StringMatcher("Name", GNU, OS).Emit(); StringMatcher("Name", GNU, OS).Emit();
OS << " } else if (AttributeList::AS_Declspec == Syntax) {\n"; OS << " } else if (ParsedAttr::AS_Declspec == Syntax) {\n";
StringMatcher("Name", Declspec, OS).Emit(); StringMatcher("Name", Declspec, OS).Emit();
OS << " } else if (AttributeList::AS_Microsoft == Syntax) {\n"; OS << " } else if (ParsedAttr::AS_Microsoft == Syntax) {\n";
StringMatcher("Name", Microsoft, OS).Emit(); StringMatcher("Name", Microsoft, OS).Emit();
OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n"; OS << " } else if (ParsedAttr::AS_CXX11 == Syntax) {\n";
StringMatcher("Name", CXX11, OS).Emit(); StringMatcher("Name", CXX11, OS).Emit();
OS << " } else if (AttributeList::AS_C2x == Syntax) {\n"; OS << " } else if (ParsedAttr::AS_C2x == Syntax) {\n";
StringMatcher("Name", C2x, OS).Emit(); StringMatcher("Name", C2x, OS).Emit();
OS << " } else if (AttributeList::AS_Keyword == Syntax || "; OS << " } else if (ParsedAttr::AS_Keyword == Syntax || ";
OS << "AttributeList::AS_ContextSensitiveKeyword == Syntax) {\n"; OS << "ParsedAttr::AS_ContextSensitiveKeyword == Syntax) {\n";
StringMatcher("Name", Keywords, OS).Emit(); StringMatcher("Name", Keywords, OS).Emit();
OS << " } else if (AttributeList::AS_Pragma == Syntax) {\n"; OS << " } else if (ParsedAttr::AS_Pragma == Syntax) {\n";
StringMatcher("Name", Pragma, OS).Emit(); StringMatcher("Name", Pragma, OS).Emit();
OS << " }\n"; OS << " }\n";
OS << " return AttributeList::UnknownAttribute;\n" OS << " return ParsedAttr::UnknownAttribute;\n"
<< "}\n"; << "}\n";
} }