]> granicus.if.org Git - clang/commitdiff
[OpenCL] Allow addr space spelling without __ prefix in C++.
authorAnastasia Stulova <anastasia.stulova@arm.com>
Mon, 25 Mar 2019 11:54:02 +0000 (11:54 +0000)
committerAnastasia Stulova <anastasia.stulova@arm.com>
Mon, 25 Mar 2019 11:54:02 +0000 (11:54 +0000)
For backwards compatibility we allow alternative spelling of address
spaces - 'private', 'local', 'global', 'constant', 'generic'.

In order to accept 'private' correctly, parsing has been changed to
understand different use cases - access specifier vs address space.

Fixes PR40707 and PR41011!

Differential Revision: https://reviews.llvm.org/D59603

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356888 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/TokenKinds.def
lib/Parse/ParseDecl.cpp
lib/Parse/ParseDeclCXX.cpp
lib/Parse/ParseTentative.cpp
test/Parser/opencl-cxx-keywords.cl

index ee0a78204669f68f27dfbcb96c44beca8604581b..0aeda6f42e5ef835733b9b42ed5b03173f366dbe 100644 (file)
@@ -539,11 +539,11 @@ KEYWORD(__local                     , KEYOPENCLC | KEYOPENCLCXX)
 KEYWORD(__constant                  , KEYOPENCLC | KEYOPENCLCXX)
 KEYWORD(__private                   , KEYOPENCLC | KEYOPENCLCXX)
 KEYWORD(__generic                   , KEYOPENCLC | KEYOPENCLCXX)
-ALIAS("global", __global            , KEYOPENCLC)
-ALIAS("local", __local              , KEYOPENCLC)
-ALIAS("constant", __constant        , KEYOPENCLC)
+ALIAS("global", __global            , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("local", __local              , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("constant", __constant        , KEYOPENCLC | KEYOPENCLCXX)
 ALIAS("private", __private          , KEYOPENCLC)
-ALIAS("generic", __generic          , KEYOPENCLC)
+ALIAS("generic", __generic          , KEYOPENCLC | KEYOPENCLCXX)
 // OpenCL function qualifiers
 KEYWORD(__kernel                    , KEYOPENCLC | KEYOPENCLCXX)
 ALIAS("kernel", __kernel            , KEYOPENCLC | KEYOPENCLCXX)
index c56c3c54b6486a0fabab1329a76587d972713583..556fce21887713cd913c1a6852be22935613efa7 100644 (file)
@@ -3824,6 +3824,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
         break;
       };
       LLVM_FALLTHROUGH;
+    case tok::kw_private:
     case tok::kw___private:
     case tok::kw___global:
     case tok::kw___local:
@@ -4790,6 +4791,7 @@ bool Parser::isTypeSpecifierQualifier() {
 
   case tok::kw___kindof:
 
+  case tok::kw_private:
   case tok::kw___private:
   case tok::kw___local:
   case tok::kw___global:
@@ -4980,6 +4982,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
 
   case tok::kw___kindof:
 
+  case tok::kw_private:
   case tok::kw___private:
   case tok::kw___local:
   case tok::kw___global:
@@ -5192,6 +5195,7 @@ void Parser::ParseTypeQualifierListOpt(
       break;
 
     // OpenCL qualifiers:
+    case tok::kw_private:
     case tok::kw___private:
     case tok::kw___global:
     case tok::kw___local:
index 895aa02c79decf1f238dca03ad2b405c9623647a..fe9fa1059a6392a502c18ee58a38ef1277d49505 100644 (file)
@@ -3047,9 +3047,14 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
     DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
     return nullptr;
 
+  case tok::kw_private:
+    // FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode
+    // yet.
+    if (getLangOpts().OpenCL && !NextToken().is(tok::colon))
+      return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
+    LLVM_FALLTHROUGH;
   case tok::kw_public:
-  case tok::kw_protected:
-  case tok::kw_private: {
+  case tok::kw_protected: {
     AccessSpecifier NewAS = getAccessSpecifierIfPresent();
     assert(NewAS != AS_none);
     // Current token is a C++ access specifier.
index 11f1aeb76ff0abdaff0bfb0f64e6d9e17b5891f1..81079cda949c62fbe19581353da8044122fbf7f9 100644 (file)
@@ -1411,6 +1411,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
   case tok::kw_const:
   case tok::kw_volatile:
     // OpenCL address space qualifiers
+  case tok::kw_private:
   case tok::kw___private:
   case tok::kw___local:
   case tok::kw___global:
index 791da9361d3194698cc7aab3ced4456960f2f1e6..beae6f4b0895dcae6ffbf3d192bf7e345693163b 100644 (file)
@@ -19,32 +19,34 @@ kernel void test_exceptions() {
 // Test that only __-prefixed address space qualifiers are accepted.
 struct test_address_space_qualifiers {
   global int *g;
-  // expected-error@-1 {{unknown type name 'global'}}
-  // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
   __global int *uug;
-  int global; // should be fine in OpenCL C++
+  int global; // expected-warning{{declaration does not declare anything}}
 
   local int *l;
-  // expected-error@-1 {{unknown type name 'local'}}
-  // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
   __local int *uul;
-  int local; // should be fine in OpenCL C++
+  int local; // expected-warning{{declaration does not declare anything}}
 
   private int *p;
-  // expected-error@-1 {{expected ':'}}
   __private int *uup;
-  int private; // 'private' is a keyword in C++14 and thus in OpenCL C++
-  // expected-error@-1 {{expected member name or ';' after declaration specifiers}}
+  int private; // expected-warning{{declaration does not declare anything}}
 
   constant int *c;
-  // expected-error@-1 {{unknown type name 'constant'}}
-  // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
   __constant int *uuc;
-  int constant; // should be fine in OpenCL C++
+  int constant; // expected-warning{{declaration does not declare anything}}
 
   generic int *ge;
-  // expected-error@-1 {{unknown type name 'generic'}}
-  // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
   __generic int *uuge;
-  int generic; // should be fine in OpenCL C++
+  int generic; // expected-warning{{declaration does not declare anything}}
 };
+
+// Test that 'private' can be parsed as an access qualifier and an address space too.
+class A{
+  private:
+  private int i; //expected-error{{field may not be qualified with an address space}}
+};
+
+private ::A i; //expected-error{{program scope variable must reside in global or constant address space}}
+
+void foo(private int i);
+
+private int bar(); //expected-error{{return value cannot be qualified with address space}}