]> granicus.if.org Git - clang/commitdiff
Implement OpenCL event_t as Clang builtin type, including event_t related OpenCL...
authorGuy Benyei <guy.benyei@intel.com>
Sun, 20 Jan 2013 12:31:11 +0000 (12:31 +0000)
committerGuy Benyei <guy.benyei@intel.com>
Sun, 20 Jan 2013 12:31:11 +0000 (12:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172973 91177308-0d34-0410-b5e6-96231b3b80d8

47 files changed:
include/clang/AST/ASTContext.h
include/clang/AST/BuiltinTypes.def
include/clang/AST/OperationKinds.h
include/clang/AST/Type.h
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/Specifiers.h
include/clang/Basic/TokenKinds.def
include/clang/Sema/DeclSpec.h
include/clang/Sema/Initialization.h
include/clang/Serialization/ASTBitCodes.h
lib/AST/ASTContext.cpp
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/AST/ItaniumMangle.cpp
lib/AST/MicrosoftMangle.cpp
lib/AST/NSAPI.cpp
lib/AST/Type.cpp
lib/AST/TypeLoc.cpp
lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGOpenCLRuntime.cpp
lib/CodeGen/CGRTTI.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/Edit/RewriteObjCFoundationAPI.cpp
lib/Parse/ParseDecl.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseTentative.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaTemplateVariadic.cpp
lib/Sema/SemaType.cpp
lib/Serialization/ASTCommon.cpp
lib/Serialization/ASTReader.cpp
lib/StaticAnalyzer/Core/ExprEngineC.cpp
test/CodeGenOpenCL/event_t.cl [new file with mode: 0644]
test/CodeGenOpenCL/opencl_types.cl
test/PCH/ocl_types.cl
test/PCH/ocl_types.h
test/SemaOpenCL/event_t.cl [new file with mode: 0644]
tools/libclang/CIndex.cpp
tools/libclang/CIndexUSRs.cpp

index fcea6fb2928ede9af16e0265386cdee48a2f69ae..05f818299b63f9c09146d463140abef2c8fd99ab 100644 (file)
@@ -721,6 +721,7 @@ public:
   CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
   CanQualType OCLImage2dTy, OCLImage2dArrayTy;
   CanQualType OCLImage3dTy;
+  CanQualType OCLEventTy;
 
   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
   mutable QualType AutoDeductTy;     // Deduction against 'auto'.
index cb7cfedb396a99db4deb7b6a43974b4ed34ec2ba..503d963eca621eee78174cf5ae8367b768c44d8b 100644 (file)
@@ -162,6 +162,9 @@ BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
 BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
 BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
 
+// OpenCL event_t.
+BUILTIN_TYPE(OCLEvent, OCLEventTy)
+
 // This represents the type of an expression whose type is
 // totally unknown, e.g. 'T::foo'.  It is permitted for this to
 // appear in situations where the structure of the type is
index 18169fd60c83debb7b934d5debaf2fa734c85364..5e41d955cfd7a2bc2fb46ca5dca1a8316ead8001 100644 (file)
@@ -292,7 +292,10 @@ enum CastKind {
 
   // Convert a builtin function to a function pointer; only allowed in the
   // callee of a call expression.
-  CK_BuiltinFnToFnPtr
+  CK_BuiltinFnToFnPtr,
+
+  // Convert a zero value for OpenCL event_t initialization.
+  CK_ZeroToOCLEvent
 };
 
 static const CastKind CK_Invalid = static_cast<CastKind>(-1);
index f1db761557052984101356a7934415361dec8811..cc6c1fd445d310e72558969df3eb974ddccfdbb8 100644 (file)
@@ -1584,6 +1584,8 @@ public:
 
   bool isImageType() const;                     // Any OpenCL image type
 
+  bool isEventT() const;                        // OpenCL event_t
+
   bool isOpenCLSpecificType() const;            // Any OpenCL specific type
 
   /// Determines if this type, which must satisfy
@@ -4916,6 +4918,10 @@ inline bool Type::isImage2dArrayT() const {
 inline bool Type::isImage3dT() const {
   return isSpecificBuiltinType(BuiltinType::OCLImage3d);
 }
+inline bool Type::isEventT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLEvent);
+}
+
 inline bool Type::isImageType() const {
   return isImage3dT() ||
          isImage2dT() || isImage2dArrayT() ||
@@ -4923,7 +4929,7 @@ inline bool Type::isImageType() const {
 }
 
 inline bool Type::isOpenCLSpecificType() const {
-  return isImageType();
+  return isImageType() || isEventT();
 }
 
 inline bool Type::isTemplateTypeParmType() const {
index c3f034a53a4fb35ed8816bce5f7e4b5e127cc0d6..3999fadc51704e7d54d88a5fd6d603e837fe043f 100644 (file)
@@ -6081,6 +6081,14 @@ def err_opencl_bitfields : Error<
   "bitfields are not supported in OpenCL">;
 def err_opencl_vla : Error<
   "variable length arrays are not supported in OpenCL">;
+def err_event_t_kernel_arg : Error<
+  "the event_t type cannot be used to declare a kernel function argument">;
+def err_event_t_global_var : Error<
+  "the event_t type cannot be used to declare a program scope variable">;
+def err_event_t_struct_field : Error<
+  "the event_t type cannot be used to declare a structure or union field">;
+def err_event_t_addr_space_qual : Error<
+  "the event_t type can only be used with __private address space qualifier">;
 
 } // end of sema category
 
index 321048f98585b256f2ece14610e574476d88c368..533cefeaae9e71c5587168165b8a035e6d7e3ce4 100644 (file)
@@ -68,6 +68,7 @@ namespace clang {
     TST_image2d_t,        // OpenCL image2d_t
     TST_image2d_array_t,  // OpenCL image2d_array_t
     TST_image3d_t,        // OpenCL image3d_t
+    TST_event_t,          // OpenCL event_t
     TST_error         // erroneous type
   };
   
index b4c0b2d97fe3b62f679107b1b9613047870cab6d..8008ca60a88bff5194e3b3199d3375b3aac2d56b 100644 (file)
@@ -455,6 +455,7 @@ KEYWORD(image1d_buffer_t            , KEYOPENCL)
 KEYWORD(image2d_t                   , KEYOPENCL)
 KEYWORD(image2d_array_t             , KEYOPENCL)
 KEYWORD(image3d_t                   , KEYOPENCL)
+KEYWORD(event_t                     , KEYOPENCL)
 
 // Borland Extensions.
 KEYWORD(__pascal                    , KEYALL)
index b232d34c40d24c6d9228c3761eaa5d8b38d545de..0d2c948399c29dddfe26280aadbfc849514bd34d 100644 (file)
@@ -282,6 +282,7 @@ public:
   static const TST TST_image2d_t = clang::TST_image2d_t;
   static const TST TST_image2d_array_t = clang::TST_image2d_array_t;
   static const TST TST_image3d_t = clang::TST_image3d_t;
+  static const TST TST_event_t = clang::TST_event_t;
   static const TST TST_error = clang::TST_error;
 
   // type-qualifiers
index 778b70b0ec12b5d577ad0a081d907cf43c4e78d3..002a12605d4437a34c88d71c2e17e7ec7e7f4355 100644 (file)
@@ -624,7 +624,9 @@ public:
     /// \brief Produce an Objective-C object pointer.
     SK_ProduceObjCObject,
     /// \brief Construct a std::initializer_list from an initializer list.
-    SK_StdInitializerList
+    SK_StdInitializerList,
+    /// \brief Passing zero to a function where OpenCL event_t is expected.
+    SK_OCLZeroEvent
   };
   
   /// \brief A single step in the initialization sequence.
@@ -953,6 +955,10 @@ public:
   /// initializer list.
   void AddStdInitializerListConstructionStep(QualType T);
 
+  /// \brief Add a step to initialize an OpenCL event_t from a NULL
+  /// constant.
+  void AddOCLZeroEventStep(QualType T);
+
   /// \brief Add steps to unwrap a initializer list for a reference around a
   /// single element and rewrap it at the end.
   void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
index a9386972630987557aa5df749243acd7ed6d1194..10453ec841f0911a1a49df6ee2aa6e079201efd4 100644 (file)
@@ -715,7 +715,8 @@ namespace clang {
       /// \brief OpenCL 2d image array type.
       PREDEF_TYPE_IMAGE2D_ARR_ID = 42,
       /// \brief OpenCL 3d image type.
-      PREDEF_TYPE_IMAGE3D_ID    = 43
+      PREDEF_TYPE_IMAGE3D_ID    = 43,
+      PREDEF_TYPE_EVENT_ID      = 44
     };
 
     /// \brief The number of predefined type IDs that are reserved for
index ace9dc0146a4153e1bf156fd340e59587ab9100b..b18fa679caa49ce6e428a4d4a648986498aea261 100644 (file)
@@ -893,6 +893,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
     InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d);
     InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray);
     InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d);
+
+    InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
   }
   
   // Builtin type for __objc_yes and __objc_no
@@ -1434,6 +1436,7 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
       Width = Target->getPointerWidth(0); 
       Align = Target->getPointerAlign(0);
       break;
+    case BuiltinType::OCLEvent:
     case BuiltinType::OCLImage1d:
     case BuiltinType::OCLImage1dArray:
     case BuiltinType::OCLImage1dBuffer:
@@ -4895,6 +4898,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
     case BuiltinType::OCLImage2d:
     case BuiltinType::OCLImage2dArray:
     case BuiltinType::OCLImage3d:
+    case BuiltinType::OCLEvent:
     case BuiltinType::Dependent:
 #define BUILTIN_TYPE(KIND, ID)
 #define PLACEHOLDER_TYPE(KIND, ID) \
index 718002f97d1e5a2e2011fdae61a899e73bdb560b..e3ff29d2d0faf85eae5b29b7b9ae072b7a603718 100644 (file)
@@ -1400,6 +1400,7 @@ void CastExpr::CheckCastConsistency() const {
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
+  case CK_ZeroToOCLEvent:
     assert(!getType()->isBooleanType() && "unheralded conversion to bool");
     goto CheckNoBasePath;
 
@@ -1531,6 +1532,8 @@ const char *CastExpr::getCastKindName() const {
     return "CopyAndAutoreleaseBlockObject";
   case CK_BuiltinFnToFnPtr:
     return "BuiltinFnToFnPtr";
+  case CK_ZeroToOCLEvent:
+    return "ZeroToOCLEvent";
   }
 
   llvm_unreachable("Unhandled cast kind!");
index 9965e1288b3bad7b006ed1904648e7b77c39a62f..64fd40b7a65027ed92db05cbd5648129914351a4 100644 (file)
@@ -5372,6 +5372,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
   case CK_IntegralComplexCast:
   case CK_IntegralComplexToFloatingComplex:
   case CK_BuiltinFnToFnPtr:
+  case CK_ZeroToOCLEvent:
     llvm_unreachable("invalid cast kind for integral value");
 
   case CK_BitCast:
@@ -5859,6 +5860,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
+  case CK_ZeroToOCLEvent:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:
index 65e630eb25642791606e4c215b6f5463a97aa4a0..926384decb0f39dcf333ba1864a0ee1bd3ec01b9 100644 (file)
@@ -1886,6 +1886,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
   case BuiltinType::OCLImage2d: Out << "11ocl_image2d"; break;
   case BuiltinType::OCLImage2dArray: Out << "16ocl_image2darray"; break;
   case BuiltinType::OCLImage3d: Out << "11ocl_image3d"; break;
+  case BuiltinType::OCLEvent: Out << "9ocl_event"; break;
   }
 }
 
index bd0125d63915344a4542bff86dffcfd7504eab44..0b77ac8c7852a37ee278080c5309561624199b93 100644 (file)
@@ -1060,6 +1060,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T,
   case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break;
   case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break;
   case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break;
+  case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break;
  
   case BuiltinType::NullPtr: Out << "$$T"; break;
 
index 35cc7d050bdf7a84fea4f2f4ccad6d97da7035e6..c8cf920d0c0c6d07d016c4dee195a29b38b0c78c 100644 (file)
@@ -351,6 +351,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
   case BuiltinType::OCLImage2d:
   case BuiltinType::OCLImage2dArray:
   case BuiltinType::OCLImage3d:
+  case BuiltinType::OCLEvent:
   case BuiltinType::BoundMember:
   case BuiltinType::Dependent:
   case BuiltinType::Overload:
index 45ec4edbc581ece2f0925bda0a819f6ea0844976..524d00560c435e9aa3e01306d34e82c93090ab3d 100644 (file)
@@ -1518,6 +1518,7 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
   case OCLImage2d:        return "image2d_t";
   case OCLImage2dArray:   return "image2d_array_t";
   case OCLImage3d:        return "image3d_t";
+  case OCLEvent:          return "event_t";
   }
   
   llvm_unreachable("Invalid builtin type.");
index a5baf703a4b02d6f036d3ea0de8819515e769337..3efa1485abbd4a7aa775d4be20b3e838f32bee5b 100644 (file)
@@ -268,6 +268,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
   case BuiltinType::OCLImage2d:
   case BuiltinType::OCLImage2dArray:
   case BuiltinType::OCLImage3d:
+  case BuiltinType::OCLEvent:
   case BuiltinType::BuiltinFn:
     return TST_unspecified;
   }
index 37df4b33ce4920c3c3c5d6fa5b649440360a2e1c..264d075e5c59e36d2a2ff8709792408b906b8014 100644 (file)
@@ -426,6 +426,9 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {
   case BuiltinType::OCLImage3d:
     return getOrCreateStructPtrType("opencl_image3d_t",
                                     OCLImage3dDITy);
+  case BuiltinType::OCLEvent:
+    return getOrCreateStructPtrType("opencl_event_t",
+                                    OCLEventDITy);
 
   case BuiltinType::UChar:
   case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
index 3ecf2edfb04f7256dae68f34f25ac6f6e56eaf1d..fbbee0b3d2bc65cbf2beb80f7a947a5ad9c4b3c0 100644 (file)
@@ -55,6 +55,7 @@ class CGDebugInfo {
   llvm::DIType OCLImage1dDITy, OCLImage1dArrayDITy, OCLImage1dBufferDITy;
   llvm::DIType OCLImage2dDITy, OCLImage2dArrayDITy;
   llvm::DIType OCLImage3dDITy;
+  llvm::DIType OCLEventDITy;
   
   /// TypeCache - Cache of previously constructed Types.
   llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
index cdbd6e7bb717d794f0e18945167928e6d3c98627..9bef08b4a59a2ba9a1f6da9890547bc444fd39c4 100644 (file)
@@ -2639,6 +2639,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
                                            ConvertType(ToType));
     return MakeAddrLValue(V, E->getType());
   }
+  case CK_ZeroToOCLEvent:
+    llvm_unreachable("NULL to OpenCL event lvalue cast is not valid");
   }
   
   llvm_unreachable("Unhandled lvalue cast kind?");
index b037113945aacb31d365b05d1eed2c0664976366..a35ef0c9318a894cf962e0b4566fbd7dd880f889 100644 (file)
@@ -648,6 +648,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
+  case CK_ZeroToOCLEvent:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }
index 127029795ca7af2e458065cbe69798e073293e31..0a53d4f1277f3493e8e6a206f16a3b26c5d6788d 100644 (file)
@@ -428,6 +428,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
+  case CK_ZeroToOCLEvent:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:
index 2c107cb716ae2deaa5471b3b627f8c2a73489036..80ab2ed28cedfaa93d66f7008c2efd138dca99e5 100644 (file)
@@ -747,6 +747,7 @@ public:
     case CK_FloatingToIntegral:
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
+    case CK_ZeroToOCLEvent:
       return 0;
     }
     llvm_unreachable("Invalid CastKind");
index 5715913b6a9c165c1affe45c3f65c119134e8090..ed927e2fb4afa92e12621998b1cffc7d374394eb 100644 (file)
@@ -1383,6 +1383,11 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
     return EmitComplexToScalarConversion(V, E->getType(), DestTy);
   }
 
+  case CK_ZeroToOCLEvent: {
+    assert(DestTy->isEventT() && "CK_ZeroToOCLEvent cast on non event type");
+    return llvm::Constant::getNullValue(ConvertType(DestTy));
+  }
+
   }
 
   llvm_unreachable("unknown scalar cast");
index bb239c6c3d2352ed989dfacc9145aded94c80fe5..215d09640a55d9a215321cb5228f84f02b88e418 100644 (file)
@@ -55,5 +55,8 @@ llvm::Type *CGOpenCLRuntime::convertOpenCLSpecificType(const Type *T) {
   case BuiltinType::OCLImage3d:
     return llvm::PointerType::get(llvm::StructType::create(
                            CGM.getLLVMContext(), "opencl.image3d_t"), 0);
+  case BuiltinType::OCLEvent:
+    return llvm::PointerType::get(llvm::StructType::create(
+                           CGM.getLLVMContext(), "opencl.event_t"), 0);
   }
 }
index 41b73e23cdaaf82e3034d1616f8c0da59e084b60..3d65892b2eb1083e975e4ecac9c5eafd2d5cbefd 100644 (file)
@@ -197,6 +197,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
     case BuiltinType::OCLImage2d:
     case BuiltinType::OCLImage2dArray:
     case BuiltinType::OCLImage3d:
+    case BuiltinType::OCLEvent:
       return true;
       
     case BuiltinType::Dependent:
index 2c5f2d80cf522c9a07a32d62c5f44a9103f26626..c186ebff29c9083f88e209972915870dc91879c0 100644 (file)
@@ -374,6 +374,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
     case BuiltinType::OCLImage2d:
     case BuiltinType::OCLImage2dArray:
     case BuiltinType::OCLImage3d:
+    case BuiltinType::OCLEvent:
       ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
       break;
     
index 312c86fe9bf9885f90558da2ab22eca9130eeb1c..215aacdad10833a9f42843b68de527877efec0e9 100644 (file)
@@ -1075,6 +1075,7 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
     case CK_NonAtomicToAtomic:
     case CK_CopyAndAutoreleaseBlockObject:
     case CK_BuiltinFnToFnPtr:
+    case CK_ZeroToOCLEvent:
       return false;
     }
   }
index f9c68c79b9c9c316b7a3dd1048b1b9c454aabc9f..cfe5d1b16ab447709c2ad0682b404a02da8921a7 100644 (file)
@@ -2783,6 +2783,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
                                      PrevSpec, DiagID);
       break;
+    case tok::kw_event_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc,
+                                     PrevSpec, DiagID);
+      break;
     case tok::kw___unknown_anytype:
       isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
                                      PrevSpec, DiagID);
@@ -3633,6 +3637,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
   case tok::kw_image2d_t:
   case tok::kw_image2d_array_t:
   case tok::kw_image3d_t:
+  case tok::kw_event_t:
 
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
@@ -3713,6 +3718,7 @@ bool Parser::isTypeSpecifierQualifier() {
   case tok::kw_image2d_t:
   case tok::kw_image2d_array_t:
   case tok::kw_image3d_t:
+  case tok::kw_event_t:
 
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
@@ -3865,6 +3871,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
   case tok::kw_image2d_t:
   case tok::kw_image2d_array_t:
   case tok::kw_image3d_t:
+  case tok::kw_event_t:
 
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
index d6d38c758aed075eabfbc2c09e7f4bf4ec58ecfb..9c788a1336425834af6a483b6b96fcd23ecffc6c 100644 (file)
@@ -1024,6 +1024,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
   case tok::kw_image2d_t:
   case tok::kw_image2d_array_t:
   case tok::kw_image3d_t: {
+  case tok::kw_event_t:
     if (!getLangOpts().CPlusPlus) {
       Diag(Tok, diag::err_expected_expression);
       return ExprError();
index 78d73bca4c47336ca1f3d44490c63282993ba561..1116daa4d1215a70a827cef36e7aa741f71c73dc 100644 (file)
@@ -843,6 +843,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
   case tok::kw_image2d_t:
   case tok::kw_image2d_array_t:
   case tok::kw_image3d_t:
+  case tok::kw_event_t:
   case tok::kw___unknown_anytype:
     return TPResult::False();
 
index 35b0736196ac761a293e3a33a40e8c24cf70b7ab..6d30b899528037e712473d735bab5aa7c8cd47ee 100644 (file)
@@ -286,6 +286,7 @@ bool Declarator::isDeclarationOfFunction() const {
     case TST_image2d_t:
     case TST_image2d_array_t:
     case TST_image3d_t:
+    case TST_event_t:
       return false;
 
     case TST_decltype:
@@ -427,6 +428,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
   case DeclSpec::TST_image2d_t:   return "image2d_t";
   case DeclSpec::TST_image2d_array_t: return "image2d_array_t";
   case DeclSpec::TST_image3d_t:   return "image3d_t";
+  case DeclSpec::TST_event_t:     return "event_t";
   case DeclSpec::TST_error:       return "(error)";
   }
   llvm_unreachable("Unknown typespec!");
index dbdbc3d6a2c317322e900f3b14bbb7eb24c12990..7936efa136d1d628a61e4e87db8bc7cb65898afc 100644 (file)
@@ -4401,6 +4401,22 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
       SC = SC_OpenCLWorkGroupLocal;
       SCAsWritten = SC_OpenCLWorkGroupLocal;
     }
+
+    // OpenCL 1.2 spec, p6.9 r:
+    // The event type cannot be used to declare a program scope variable.
+    // The event type cannot be used with the __local, __constant and __global
+    // address space qualifiers.
+    if (R->isEventT()) {
+      if (S->getParent() == 0) {
+        Diag(D.getLocStart(), diag::err_event_t_global_var);
+        D.setInvalidType();
+      }
+
+      if (R.getAddressSpace()) {
+        Diag(D.getLocStart(), diag::err_event_t_addr_space_qual);
+        D.setInvalidType();
+      }
+    }
   }
 
   bool isExplicitSpecialization = false;
@@ -6136,12 +6152,26 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     }
   }
 
-  // OpenCL v1.2 s6.8 static is invalid for kernel functions.
-  if ((getLangOpts().OpenCLVersion >= 120)
-      && NewFD->hasAttr<OpenCLKernelAttr>()
-      && (SC == SC_Static)) {
-    Diag(D.getIdentifierLoc(), diag::err_static_kernel);
-    D.setInvalidType();
+  if (NewFD->hasAttr<OpenCLKernelAttr>()) {
+
+    // OpenCL v1.2 s6.8 static is invalid for kernel functions.
+    if ((getLangOpts().OpenCLVersion >= 120)
+        && (SC == SC_Static)) {
+      Diag(D.getIdentifierLoc(), diag::err_static_kernel);
+      D.setInvalidType();
+    }
+
+    // OpenCL v1.2 s6.8 n:
+    // Arguments to kernel functions in a program cannot be declared to be of
+    // type event_t.
+    for (FunctionDecl::param_iterator PI = NewFD->param_begin(),
+         PE = NewFD->param_end(); PI != PE; ++PI) {
+      if ((*PI)->getType()->isEventT()) {
+        Diag((*PI)->getLocation(), diag::err_event_t_kernel_arg);
+        D.setInvalidType();
+      }
+    }
+    
   }
 
   MarkUnusedFileScopedDecl(NewFD);
@@ -9776,6 +9806,14 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
     }
   }
 
+  // OpenCL 1.2 spec, s6.9 r:
+  // The event type cannot be used to declare a structure or union field.
+  if (LangOpts.OpenCL && T->isEventT()) {
+    Diag(Loc, diag::err_event_t_struct_field);
+    D.setInvalidType();
+  }
+
+
   DiagnoseFunctionSpecifiers(D);
 
   if (D.getDeclSpec().isThreadSpecified())
index 26bb6efb8e05779b485c329dc76be7033d4aab0c..e6611108328a0faeca5f30a4dd30026121317d45 100644 (file)
@@ -2424,6 +2424,7 @@ void InitializationSequence::Step::Destroy() {
   case SK_PassByIndirectRestore:
   case SK_ProduceObjCObject:
   case SK_StdInitializerList:
+  case SK_OCLZeroEvent:
     break;
 
   case SK_ConversionSequence:
@@ -2652,6 +2653,13 @@ void InitializationSequence::AddStdInitializerListConstructionStep(QualType T) {
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddOCLZeroEventStep(QualType T) {
+  Step S;
+  S.Kind = SK_OCLZeroEvent;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::RewrapReferenceInitList(QualType T,
                                                      InitListExpr *Syntactic) {
   assert(Syntactic->getNumInits() == 1 &&
@@ -4009,6 +4017,27 @@ static bool tryObjCWritebackConversion(Sema &S,
   return true;
 }
 
+//
+// OpenCL 1.2 spec, s6.12.10
+//
+// The event argument can also be used to associate the
+// async_work_group_copy with a previous async copy allowing
+// an event to be shared by multiple async copies; otherwise
+// event should be zero.
+//
+static bool TryOCLZeroEventInitialization(Sema &S,
+                                          InitializationSequence &Sequence,
+                                          QualType DestType,
+                                          Expr *Initializer) {
+  if (!S.getLangOpts().OpenCL || !DestType->isEventT() ||
+      !Initializer->isIntegerConstantExpr(S.getASTContext()) ||
+      (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0))
+    return false;
+
+  Sequence.AddOCLZeroEventStep(DestType);
+  return true;
+}
+
 InitializationSequence::InitializationSequence(Sema &S,
                                                const InitializedEntity &Entity,
                                                const InitializationKind &Kind,
@@ -4152,6 +4181,10 @@ InitializationSequence::InitializationSequence(Sema &S,
       return;
     }
     
+
+    if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer))
+      return;
+
     // Handle initialization in C
     AddCAssignmentStep(DestType);
     MaybeProduceObjCObject(S, *this, Entity);
@@ -4940,7 +4973,8 @@ InitializationSequence::Perform(Sema &S,
   case SK_PassByIndirectCopyRestore:
   case SK_PassByIndirectRestore:
   case SK_ProduceObjCObject:
-  case SK_StdInitializerList: {
+  case SK_StdInitializerList:
+  case SK_OCLZeroEvent: {
     assert(Args.size() == 1);
     CurInit = Args[0];
     if (!CurInit.get()) return ExprError();
@@ -5453,6 +5487,15 @@ InitializationSequence::Perform(Sema &S,
       CurInit = S.Owned(Semantic);
       break;
     }
+    case SK_OCLZeroEvent: {
+      assert(Step->Type->isEventT() && 
+             "Event initialization on non event type.");
+
+      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+                                    CK_ZeroToOCLEvent,
+                                    CurInit.get()->getValueKind());
+      break;
+    }
     }
   }
 
@@ -6139,6 +6182,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
     case SK_StdInitializerList:
       OS << "std::initializer_list from initializer list";
       break;
+
+    case SK_OCLZeroEvent:
+      OS << "OpenCL event_t from zero";
+      break;
     }
   }
 }
index 6c7032089a02156d11ea1f0e0257f20d11ec35d6..bb20913dffa412d9084151596ee26ec279580119 100644 (file)
@@ -737,6 +737,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
   case TST_image2d_t:
   case TST_image2d_array_t:
   case TST_image3d_t:
+  case TST_event_t:
   case TST_error:
     break;
   }
index 35816a42f33e9388db09c9ff37ebb646d744c9f5..a3b0c45b9d8c0846bb3075160574af2046607594 100644 (file)
@@ -952,6 +952,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
     Result = Context.OCLImage3dTy;
     break;
 
+  case DeclSpec::TST_event_t:
+    Result = Context.OCLEventTy;
+    break;
+
   case DeclSpec::TST_error:
     Result = Context.IntTy;
     declarator.setInvalidType(true);
index bcd8e870834d19b9841cd7da0f6eb0bed9af2219..bf1e25a412083d29c86143b72675003fb92713a0 100644 (file)
@@ -66,6 +66,7 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
   case BuiltinType::OCLImage2d:       ID = PREDEF_TYPE_IMAGE2D_ID;      break;
   case BuiltinType::OCLImage2dArray:  ID = PREDEF_TYPE_IMAGE2D_ARR_ID;  break;
   case BuiltinType::OCLImage3d:       ID = PREDEF_TYPE_IMAGE3D_ID;      break;
+  case BuiltinType::OCLEvent:         ID = PREDEF_TYPE_EVENT_ID;        break;
   case BuiltinType::BuiltinFn:
                                 ID = PREDEF_TYPE_BUILTIN_FN; break;
 
index c378570ddb77a616228352411a40ff137e7f6592..00bae0aea3dceafc94e309dbdd3d60ae877b61f2 100644 (file)
@@ -4807,6 +4807,7 @@ QualType ASTReader::GetType(TypeID ID) {
     case PREDEF_TYPE_IMAGE2D_ID:    T = Context.OCLImage2dTy;       break;
     case PREDEF_TYPE_IMAGE2D_ARR_ID: T = Context.OCLImage2dArrayTy; break;
     case PREDEF_TYPE_IMAGE3D_ID:    T = Context.OCLImage3dTy;       break;
+    case PREDEF_TYPE_EVENT_ID:      T = Context.OCLEventTy;         break;
     case PREDEF_TYPE_AUTO_DEDUCT:   T = Context.getAutoDeductType(); break;
         
     case PREDEF_TYPE_AUTO_RREF_DEDUCT: 
index f1ef0f6601189913dac71bf6a56692877fa15cd5..ea2fc3c5b29a6cf6ae26daef239f2c51ba19bf60 100644 (file)
@@ -306,7 +306,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
       case CK_CPointerToObjCPointerCast:
       case CK_BlockPointerToObjCPointerCast:
       case CK_AnyPointerToBlockPointerCast:  
-      case CK_ObjCObjectLValueCast: {
+      case CK_ObjCObjectLValueCast: 
+      case CK_ZeroToOCLEvent: {
         // Delegate to SValBuilder to process.
         SVal V = state->getSVal(Ex, LCtx);
         V = svalBuilder.evalCast(V, T, ExTy);
diff --git a/test/CodeGenOpenCL/event_t.cl b/test/CodeGenOpenCL/event_t.cl
new file mode 100644 (file)
index 0000000..ddf12a9
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 | FileCheck %s
+
+void foo(event_t evt);
+
+void kernel ker() {
+  event_t e;
+// CHECK: alloca %opencl.event_t*,
+  foo(e);
+// CHECK: call void @foo(%opencl.event_t* %
+  foo(0);
+// CHECK: call void @foo(%opencl.event_t* null)
+}
index 35444ed9cbfef1bb5b8ad55a1c3b02e012c08e37..ab2ebe1ce71251d92e12eee5bbf6cfa6bb5a2940 100644 (file)
@@ -19,4 +19,6 @@ void fnc3(image3d_t img) {}
 // CHECK: @fnc3(%opencl.image3d_t*
 
 kernel void foo(image1d_t img) {
+       event_t evt;
+// CHECK: alloca %opencl.event_t*
 }
index 972853b50fd3a447dfec98b39eb5f0aa07af2e4c..29de5e3a0eba0b5e7cc3084d19ece39fe5fc6392 100644 (file)
@@ -16,3 +16,7 @@ void foo4(img2d_t img);
 void foo5(img2darr_t img);
 
 void foo6(img3d_t img);
+
+void foo8(evt_t evt) {
+  evt_t loc_evt;
+}
index bec065afff1fc921e1fac98373921d5eff4c32df..829ea03151d6b2822c9e386baaeab0e5865938a2 100644 (file)
@@ -17,3 +17,6 @@ typedef image2d_array_t img2darr_t;
 
 // image3d_t
 typedef image3d_t img3d_t;
+
+// event_t
+typedef event_t evt_t;
diff --git a/test/SemaOpenCL/event_t.cl b/test/SemaOpenCL/event_t.cl
new file mode 100644 (file)
index 0000000..57a0981
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}}
+
+struct evt_s {
+  event_t evt;  // expected-error {{the event_t type cannot be used to declare a structure or union field}}
+} evt_str;
+
+void foo(event_t evt); // expected-note {{passing argument to parameter 'evt' here}}
+
+void kernel ker(event_t argevt) { // expected-error {{the event_t type cannot be used to declare a kernel function argument}}
+  event_t e;
+  constant event_t const_evt; // expected-error {{the event_t type can only be used with __private address space qualifier}}
+  foo(e);
+  foo(0);
+  foo(5); // expected-error {{passing 'int' to parameter of incompatible type 'event_t'}}
+}
index f8c6f690962585d541c5b95d677d7c4445e33537..5ec0fba1a83e69b40506f88e496fb0f054965496 100644 (file)
@@ -1397,6 +1397,7 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
   case BuiltinType::OCLImage2d:
   case BuiltinType::OCLImage2dArray:
   case BuiltinType::OCLImage3d:
+  case BuiltinType::OCLEvent:
 #define BUILTIN_TYPE(Id, SingletonId)
 #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
 #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
index 1cfb6a48c522ea39e8420ad614e172b5458c8fee..5942b42ed03ec7d23d77671bbf714761b6da2abd 100644 (file)
@@ -593,6 +593,7 @@ void USRGenerator::VisitType(QualType T) {
         case BuiltinType::OCLImage2d:
         case BuiltinType::OCLImage2dArray:
         case BuiltinType::OCLImage3d:
+        case BuiltinType::OCLEvent:
           IgnoreResults = true;
           return;
         case BuiltinType::ObjCId: