summaryrefslogtreecommitdiffstats
path: root/include/clang/Sema/AttributeList.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Sema/AttributeList.h')
-rw-r--r--include/clang/Sema/AttributeList.h123
1 files changed, 97 insertions, 26 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 2e8b0c0..0f0d218 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -15,11 +15,11 @@
#ifndef LLVM_CLANG_SEMA_ATTRLIST_H
#define LLVM_CLANG_SEMA_ATTRLIST_H
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/SmallVector.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include <cassert>
namespace clang {
@@ -44,8 +44,9 @@ struct AvailabilityChange {
bool isValid() const { return !Version.empty(); }
};
-/// AttributeList - Represents GCC's __attribute__ declaration. There are
-/// 4 forms of this construct...they are:
+/// AttributeList - Represents a syntactic attribute.
+///
+/// For a GNU attribute, there are four forms of this construct:
///
/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
@@ -56,12 +57,14 @@ class AttributeList { // TODO: This should really be called ParsedAttribute
public:
/// The style used to specify an attribute.
enum Syntax {
+ /// __attribute__((...))
AS_GNU,
+ /// [[...]]
AS_CXX11,
+ /// __declspec(...)
AS_Declspec,
- // eg) __w64, __ptr32, etc. It is implied that an MSTypespec is also
- // a declspec.
- AS_MSTypespec
+ /// __ptr16, alignas(...), etc.
+ AS_Keyword
};
private:
IdentifierInfo *AttrName;
@@ -70,6 +73,7 @@ private:
SourceRange AttrRange;
SourceLocation ScopeLoc;
SourceLocation ParmLoc;
+ SourceLocation EllipsisLoc;
/// The number of expression arguments this attribute has.
/// The expressions themselves are stored after the object.
@@ -140,6 +144,14 @@ private:
return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1);
}
+ ParsedType &getTypeBuffer() {
+ return *reinterpret_cast<ParsedType *>(this + 1);
+ }
+
+ const ParsedType &getTypeBuffer() const {
+ return *reinterpret_cast<const ParsedType *>(this + 1);
+ }
+
AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
void operator delete(void *) LLVM_DELETED_FUNCTION;
@@ -152,11 +164,11 @@ private:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- Syntax syntaxUsed)
+ Syntax syntaxUsed, SourceLocation ellipsisLoc)
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
- NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false),
- UsedAsTypeAttr(false), IsAvailability(false),
+ EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed),
+ Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
@@ -173,7 +185,7 @@ private:
const Expr *messageExpr,
Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
- AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+ AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(),
NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false),
@@ -194,7 +206,7 @@ private:
bool mustBeNull, Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc),
- NumArgs(0), SyntaxUsed(syntaxUsed),
+ EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) {
TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -204,6 +216,20 @@ private:
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
+ /// Constructor for attributes with a single type argument.
+ AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ ParsedType typeArg, Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
+ AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+ EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
+ new (&getTypeBuffer()) ParsedType(typeArg);
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+ }
+
friend class AttributePool;
friend class AttributeFactory;
@@ -227,12 +253,16 @@ public:
IdentifierInfo *getParameterName() const { return ParmName; }
SourceLocation getParameterLoc() const { return ParmLoc; }
- /// Returns true if the attribute is a pure __declspec or a synthesized
- /// declspec representing a type specification (like __w64 or __ptr32).
- bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec ||
- SyntaxUsed == AS_MSTypespec; }
- bool isCXX0XAttribute() const { return SyntaxUsed == AS_CXX11; }
- bool isMSTypespecAttribute() const { return SyntaxUsed == AS_MSTypespec; }
+ bool isAlignasAttribute() const {
+ // FIXME: Use a better mechanism to determine this.
+ return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
+ }
+
+ bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
+ bool isCXX11Attribute() const {
+ return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
+ }
+ bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
bool isInvalid() const { return Invalid; }
void setInvalid(bool b = true) const { Invalid = b; }
@@ -240,6 +270,9 @@ public:
bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
+ bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+ SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
Kind getKind() const { return Kind(AttrKind); }
static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
Syntax SyntaxUsed);
@@ -340,6 +373,16 @@ public:
"Not a type_tag_for_datatype attribute");
return getTypeTagForDatatypeDataSlot().MustBeNull;
}
+
+ const ParsedType &getTypeArg() const {
+ assert(getKind() == AT_VecTypeHint && "Not a type attribute");
+ return getTypeBuffer();
+ }
+
+ /// \brief Get an index into the attribute spelling list
+ /// defined in Attr.td. This index is used by an attribute
+ /// to pretty print itself.
+ unsigned getAttributeSpellingListIndex() const;
};
/// A factory, from which one makes pools, from which one creates
@@ -448,13 +491,15 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- AttributeList::Syntax syntax) {
+ AttributeList::Syntax syntax,
+ SourceLocation ellipsisLoc = SourceLocation()) {
void *memory = allocate(sizeof(AttributeList)
+ numArgs * sizeof(Expr*));
return add(new (memory) AttributeList(attrName, attrRange,
scopeName, scopeLoc,
parmName, parmLoc,
- args, numArgs, syntax));
+ args, numArgs, syntax,
+ ellipsisLoc));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -491,6 +536,18 @@ public:
matchingCType, layoutCompatible,
mustBeNull, syntax));
}
+
+ AttributeList *createTypeAttribute(
+ IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+ void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
+ return add(new (memory) AttributeList(attrName, attrRange,
+ scopeName, scopeLoc,
+ parmName, parmLoc,
+ typeArg, syntaxUsed));
+ }
};
/// addAttributeLists - Add two AttributeLists together
@@ -511,18 +568,18 @@ inline AttributeList *addAttributeLists(AttributeList *Left,
return Left;
}
-/// CXX0XAttributeList - A wrapper around a C++0x attribute list.
+/// CXX11AttributeList - A wrapper around a C++11 attribute list.
/// Stores, in addition to the list proper, whether or not an actual list was
/// (as opposed to an empty list, which may be ill-formed in some places) and
/// the source range of the list.
-struct CXX0XAttributeList {
+struct CXX11AttributeList {
AttributeList *AttrList;
SourceRange Range;
bool HasAttr;
- CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
+ CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
: AttrList(attrList), Range(range), HasAttr (hasAttr) {
}
- CXX0XAttributeList ()
+ CXX11AttributeList ()
: AttrList(0), Range(), HasAttr(false) {
}
};
@@ -588,10 +645,11 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- AttributeList::Syntax syntax) {
+ AttributeList::Syntax syntax,
+ SourceLocation ellipsisLoc = SourceLocation()) {
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
- args, numArgs, syntax);
+ args, numArgs, syntax, ellipsisLoc);
add(attr);
return attr;
}
@@ -632,6 +690,19 @@ public:
return attr;
}
+ /// Add an attribute with a single type argument.
+ AttributeList *
+ addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+ AttributeList *attr =
+ pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
+ parmName, parmLoc, typeArg, syntaxUsed);
+ add(attr);
+ return attr;
+ }
+
AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
SourceLocation loc, int arg) {
AttributeList *attr =
OpenPOWER on IntegriCloud