diff options
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 16 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 50 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.h | 11 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 15 |
4 files changed, 92 insertions, 0 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d97b4e30a0..b815031939 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -301,6 +301,16 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { } } +void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { + // Treat these like attributes + while (Tok.is(tok::kw___kernel)) { + SourceLocation AttrNameLoc = ConsumeToken(); + attrs.add(AttrFactory.Create(PP.getIdentifierInfo("opencl_kernel_function"), + AttrNameLoc, 0, AttrNameLoc, 0, + SourceLocation(), 0, 0, false)); + } +} + void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) << attrs.Range; @@ -864,6 +874,7 @@ Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { /// [C99] 'inline' /// [C++] 'virtual' /// [C++] 'explicit' +/// [OpenCL] '__kernel' /// 'friend': [C++ dcl.friend] /// 'constexpr': [C++0x dcl.constexpr] @@ -1201,6 +1212,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, ParseBorlandTypeAttributes(DS.getAttributes()); continue; + // OpenCL single token adornments. + case tok::kw___kernel: + ParseOpenCLAttributes(DS.getAttributes()); + continue; + // storage-class-specifier case tok::kw_typedef: isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec, diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 41f32fb945..dfd0da079d 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -382,3 +382,53 @@ PragmaFPContractHandler::HandlePragma(Preprocessor &PP, Actions.ActOnPragmaFPContract(OOS); } + +void +PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &Tok) { + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << + "OPENCL"; + return; + } + IdentifierInfo *ename = Tok.getIdentifierInfo(); + SourceLocation NameLoc = Tok.getLocation(); + + PP.Lex(Tok); + if (Tok.isNot(tok::colon)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename; + return; + } + + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); + return; + } + IdentifierInfo *op = Tok.getIdentifierInfo(); + + unsigned state; + if (op->isStr("enable")) { + state = 1; + } else if (op->isStr("disable")) { + state = 0; + } else { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); + return; + } + + OpenCLOptions &f = Actions.getOpenCLOptions(); + if (ename->isStr("all")) { +#define OPENCLEXT(nm) f.nm = state; +#include "clang/Basic/OpenCLExtensions.def" + } +#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; } +#include "clang/Basic/OpenCLExtensions.def" + else { + PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename; + return; + } +} + diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h index 80894b28d8..bee6af3f4c 100644 --- a/lib/Parse/ParsePragma.h +++ b/lib/Parse/ParsePragma.h @@ -80,6 +80,17 @@ public: Token &FirstToken); }; +class PragmaOpenCLExtensionHandler : public PragmaHandler { + Sema &Actions; + Parser &parser; +public: + PragmaOpenCLExtensionHandler(Sema &S, Parser& p) : + PragmaHandler("EXTENSION"), Actions(S), parser(p) {} + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); +}; + + class PragmaFPContractHandler : public PragmaHandler { Sema &Actions; Parser &parser; diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 8273d5e2d1..a50763a0e3 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -53,6 +53,14 @@ Parser::Parser(Preprocessor &pp, Sema &actions) FPContractHandler.reset(new PragmaFPContractHandler(actions, *this)); PP.AddPragmaHandler("STDC", FPContractHandler.get()); + + if (getLang().OpenCL) { + OpenCLExtensionHandler.reset( + new PragmaOpenCLExtensionHandler(actions, *this)); + PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get()); + + PP.AddPragmaHandler("OPENCL", FPContractHandler.get()); + } PP.setCodeCompletionHandler(*this); } @@ -363,6 +371,13 @@ Parser::~Parser() { UnusedHandler.reset(); PP.RemovePragmaHandler(WeakHandler.get()); WeakHandler.reset(); + + if (getLang().OpenCL) { + PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get()); + OpenCLExtensionHandler.reset(); + PP.RemovePragmaHandler("OPENCL", FPContractHandler.get()); + } + PP.RemovePragmaHandler("STDC", FPContractHandler.get()); FPContractHandler.reset(); PP.clearCodeCompletionHandler(); |