diff options
-rw-r--r-- | include/clang/AST/Attr.h | 22 | ||||
-rw-r--r-- | include/clang/Parse/AttributeList.h | 1 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/AttributeList.cpp | 3 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 27 |
7 files changed, 92 insertions, 2 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index a5b7ad4ca3..7d3009b011 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -72,6 +72,7 @@ public: Packed, Pure, Regparm, + ReqdWorkGroupSize, // OpenCL-specific Section, Sentinel, StdCall, @@ -501,6 +502,27 @@ public: static bool classof(const RegparmAttr *A) { return true; } }; +class ReqdWorkGroupSizeAttr : public Attr { + unsigned X, Y, Z; +public: + ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z) + : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {} + + unsigned getXDim() const { return X; } + unsigned getYDim() const { return Y; } + unsigned getZDim() const { return Z; } + + virtual Attr *clone(ASTContext &C) const { + return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() == ReqdWorkGroupSize; + } + static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; } +}; + // Checker-specific attributes. DEF_SIMPLE_ATTR(CFReturnsRetained); DEF_SIMPLE_ATTR(NSReturnsRetained); diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 26cebf0915..50ca88acbc 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -97,6 +97,7 @@ public: AT_warn_unused_result, AT_weak, AT_weak_import, + AT_reqd_wg_size, IgnoredAttribute, UnknownAttribute }; diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 3dd84c7b08..3f6ae354dc 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -489,6 +489,14 @@ Attr *PCHReader::ReadAttributes() { New = ::new (*Context) NonNullAttr(ArgNums.data(), Size); break; } + + case Attr::ReqdWorkGroupSize: { + unsigned X = Record[Idx++]; + unsigned Y = Record[Idx++]; + unsigned Z = Record[Idx++]; + New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z); + break; + } SIMPLE_ATTR(ObjCException); SIMPLE_ATTR(ObjCNSObject); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index e7bacabb3a..808df70df3 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1622,6 +1622,12 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) { case Attr::Regparm: Record.push_back(cast<RegparmAttr>(Attr)->getNumParams()); break; + + case Attr::ReqdWorkGroupSize: + Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim()); + Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim()); + Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim()); + break; case Attr::Section: AddString(cast<SectionAttr>(Attr)->getName(), Record); diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 3fb6f950ef..5ee668a317 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -118,6 +118,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { case 13: if (!memcmp(Str, "address_space", 13)) return AT_address_space; if (!memcmp(Str, "always_inline", 13)) return AT_always_inline; + if (!memcmp(Str, "vec_type_hint", 13)) return IgnoredAttribute; break; case 14: if (!memcmp(Str, "objc_exception", 14)) return AT_objc_exception; @@ -136,6 +137,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { if (!memcmp(Str, "ns_returns_retained", 19)) return AT_ns_returns_retained; if (!memcmp(Str, "cf_returns_retained", 19)) return AT_cf_returns_retained; break; + case 20: + if (!memcmp(Str, "reqd_work_group_size", 20)) return AT_reqd_wg_size; case 22: if (!memcmp(Str, "no_instrument_function", 22)) return AT_no_instrument_function; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9a8e34211d..c11383c3ec 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -149,13 +149,35 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) { } } } else { // not an identifier + switch (Tok.getKind()) { + case tok::r_paren: // parse a possibly empty comma separated list of expressions - if (Tok.is(tok::r_paren)) { // __attribute__(( nonnull() )) ConsumeParen(); // ignore the right paren loc for now CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, SourceLocation(), 0, 0, CurrAttr); - } else { + break; + case tok::kw_char: + case tok::kw_wchar_t: + case tok::kw_bool: + case tok::kw_short: + case tok::kw_int: + case tok::kw_long: + case tok::kw_signed: + case tok::kw_unsigned: + case tok::kw_float: + case tok::kw_double: + case tok::kw_void: + case tok::kw_typeof: + // If it's a builtin type name, eat it and expect a rparen + // __attribute__(( vec_type_hint(char) )) + ConsumeToken(); + CurrAttr = new AttributeList(AttrName, AttrNameLoc, + 0, SourceLocation(), 0, 0, CurrAttr); + if (Tok.is(tok::r_paren)) + ConsumeParen(); + break; + default: // __attribute__(( aligned(16) )) ExprVector ArgExprs(Actions); bool ArgExprsOk = true; @@ -181,6 +203,7 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) { SourceLocation(), ArgExprs.take(), ArgExprs.size(), CurrAttr); } + break; } } } else { diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index d57630e6af..f7dd9303cb 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -915,6 +915,30 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { D->addAttr(S.Context, ::new (S.Context) DLLExportAttr()); } +static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, + Sema &S) { + // Attribute has 3 arguments. + if (Attr.getNumArgs() != 3) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; + return; + } + + unsigned WGSize[3]; + for (unsigned i = 0; i < 3; ++i) { + Expr *E = static_cast<Expr *>(Attr.getArg(i)); + llvm::APSInt ArgNum(32); + if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) + << "reqd_work_group_size" << E->getSourceRange(); + return; + } + WGSize[i] = (unsigned) ArgNum.getZExtValue(); + } + D->addAttr(S.Context, + ::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], + WGSize[2])); +} + static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { // Attribute has no arguments. if (Attr.getNumArgs() != 1) { @@ -1736,6 +1760,9 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Att case AttributeList::AT_cf_returns_retained: HandleNSReturnsRetainedAttr(D, Attr, S); break; + case AttributeList::AT_reqd_wg_size: + HandleReqdWorkGroupSize(D, Attr, S); break; + case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; |