<div dir="rtl"><div dir="ltr">Hi Joey,</div><div dir="ltr"><br></div><div dir="ltr">In order for <span style="font-size:12.8px"> R</span><span class="gmail-il" style="background-color:rgb(255,255,255);font-size:12.8px">eadPipeType and WritePipeType</span><span style="font-size:12.8px"> to work with LLVM type system (isa, dyn_cast), you need to modify the existing TypeClass::Pipe kind into </span><span style="font-size:12.8px">TypeClass::ReadPipe and </span><span style="font-size:12.8px">TypeClass::WritePipe, have Pipe::classof recognize both kinds and have ReadPipe::classof and WritePipe::classof recognize their respective kinds.</span></div><div dir="ltr"><span style="font-size:12.8px"><br></span></div><div dir="ltr"><div dir="ltr"><span style="font-size:12.8px">See rule 4 in </span><span style="font-size:12.8px"><a href="http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html">http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html</a></span></div><div dir="ltr"><br></div></div><div dir="ltr"><span style="font-size:12.8px">Good example is how ConstantArrayType, IncompleteArrayType, VariableArrayType, DependentSizedArrayType inherit from ArrayType.</span></div><div dir="ltr"><span style="font-size:12.8px"><br></span></div><div dir="ltr">Yaron<br></div><div dir="ltr"><br></div><div dir="ltr"><span style="font-size:12.8px"><br></span></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div dir="ltr">2016-11-18 16:10 GMT+02:00 Joey Gouly via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span>:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: joey<br>
Date: Fri Nov 18 08:10:54 2016<br>
New Revision: 287343<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=287343&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=287343&view=rev</a><br>
Log:<br>
[OpenCL] Introduce ReadPipeType and WritePipeType.<br>
<br>
This allows Sema to diagnose passing a read_only pipe to a<br>
write_only pipe argument.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/<wbr>ASTContext.h<br>
    cfe/trunk/include/clang/AST/<wbr>Type.h<br>
    cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
    cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/AST/ASTContext.<wbr>cpp<br>
    cfe/trunk/lib/AST/TypePrinter.<wbr>cpp<br>
    cfe/trunk/lib/Sema/SemaType.<wbr>cpp<br>
    cfe/trunk/lib/Sema/<wbr>TreeTransform.h<br>
    cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
    cfe/trunk/test/Misc/<a href="http://ast-dump-pipe.cl" rel="noreferrer" target="_blank">ast-dump-<wbr>pipe.cl</a><br>
    cfe/trunk/test/SemaOpenCL/<a href="http://access-qualifier.cl" rel="noreferrer" target="_blank">acce<wbr>ss-qualifier.cl</a><br>
    cfe/trunk/test/SemaOpenCL/<a href="http://invalid-pipes-cl2.0.cl" rel="noreferrer" target="_blank">inva<wbr>lid-pipes-cl2.0.cl</a><br>
<br>
Modified: cfe/trunk/include/clang/AST/<wbr>ASTContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/ASTContext.h?rev=<wbr>287343&r1=287342&r2=287343&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/<wbr>ASTContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/<wbr>ASTContext.h Fri Nov 18 08:10:54 2016<br>
@@ -135,7 +135,8 @@ class ASTContext : public RefCountedBase<br>
   mutable llvm::FoldingSet<AutoType> AutoTypes;<br>
   mutable llvm::FoldingSet<AtomicType> AtomicTypes;<br>
   llvm::FoldingSet<<wbr>AttributedType> AttributedTypes;<br>
-  mutable llvm::FoldingSet<PipeType> PipeTypes;<br>
+  mutable llvm::FoldingSet<ReadPipeType> ReadPipeTypes;<br>
+  mutable llvm::FoldingSet<<wbr>WritePipeType> WritePipeTypes;<br>
<br>
   mutable llvm::FoldingSet<<wbr>QualifiedTemplateName> QualifiedTemplateNames;<br>
   mutable llvm::FoldingSet<<wbr>DependentTemplateName> DependentTemplateNames;<br>
@@ -1120,8 +1121,10 @@ public:<br>
   /// blocks.<br>
   QualType getBlockDescriptorType() const;<br>
<br>
-  /// \brief Return pipe type for the specified type.<br>
-  QualType getPipeType(QualType T) const;<br>
+  /// \brief Return a read_only pipe type for the specified type.<br>
+  QualType getReadPipeType(QualType T) const;<br>
+  /// \brief Return a write_only pipe type for the specified type.<br>
+  QualType getWritePipeType(QualType T) const;<br>
<br>
   /// Gets the struct used to keep track of the extended descriptor for<br>
   /// pointer to blocks.<br>
<br>
Modified: cfe/trunk/include/clang/AST/<wbr>Type.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/Type.h?rev=287343&<wbr>r1=287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/<wbr>Type.h (original)<br>
+++ cfe/trunk/include/clang/AST/<wbr>Type.h Fri Nov 18 08:10:54 2016<br>
@@ -5285,18 +5285,18 @@ class AtomicType : public Type, public l<br>
<br>
 /// PipeType - OpenCL20.<br>
 class PipeType : public Type, public llvm::FoldingSetNode {<br>
+protected:<br>
   QualType ElementType;<br>
+  bool isRead;<br>
<br>
-  PipeType(QualType elemType, QualType CanonicalPtr) :<br>
+  PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) :<br>
     Type(Pipe, CanonicalPtr, elemType->isDependentType(),<br>
          elemType-><wbr>isInstantiationDependentType()<wbr>,<br>
          elemType-><wbr>isVariablyModifiedType(),<br>
          elemType-><wbr>containsUnexpandedParameterPac<wbr>k()),<br>
-    ElementType(elemType) {}<br>
-  friend class ASTContext;  // ASTContext creates these.<br>
+    ElementType(elemType), isRead(isRead) {}<br>
<br>
 public:<br>
-<br>
   QualType getElementType() const { return ElementType; }<br>
<br>
   bool isSugared() const { return false; }<br>
@@ -5311,11 +5311,23 @@ public:<br>
     ID.AddPointer(T.<wbr>getAsOpaquePtr());<br>
   }<br>
<br>
-<br>
   static bool classof(const Type *T) {<br>
     return T->getTypeClass() == Pipe;<br>
   }<br>
<br>
+  bool isReadOnly() const { return isRead; }<br>
+};<br>
+<br>
+class ReadPipeType : public PipeType {<br>
+  ReadPipeType(QualType elemType, QualType CanonicalPtr) :<br>
+    PipeType(elemType, CanonicalPtr, true) {}<br>
+  friend class ASTContext;  // ASTContext creates these.<br>
+};<br>
+<br>
+class WritePipeType : public PipeType {<br>
+  WritePipeType(QualType elemType, QualType CanonicalPtr) :<br>
+    PipeType(elemType, CanonicalPtr, false) {}<br>
+  friend class ASTContext;  // ASTContext creates these.<br>
 };<br>
<br>
 /// A qualifier set is used to build a set of qualifiers.<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=287343&<wbr>r1=287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Fri Nov 18 08:10:54 2016<br>
@@ -1303,7 +1303,9 @@ public:<br>
                                  SourceLocation Loc, DeclarationName Entity);<br>
   QualType BuildParenType(QualType T);<br>
   QualType BuildAtomicType(QualType T, SourceLocation Loc);<br>
-  QualType BuildPipeType(QualType T,<br>
+  QualType BuildReadPipeType(QualType T,<br>
+                         SourceLocation Loc);<br>
+  QualType BuildWritePipeType(QualType T,<br>
                          SourceLocation Loc);<br>
<br>
   TypeSourceInfo *GetTypeForDeclarator(<wbr>Declarator &D, Scope *S);<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Serialization/<wbr>ASTBitCodes.h?rev=287343&r1=<wbr>287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h Fri Nov 18 08:10:54 2016<br>
@@ -905,10 +905,12 @@ namespace clang {<br>
       TYPE_DECAYED               = 41,<br>
       /// \brief An AdjustedType record.<br>
       TYPE_ADJUSTED              = 42,<br>
-      /// \brief A PipeType record.<br>
-      TYPE_PIPE                  = 43,<br>
+      /// \brief A ReadPipeType record.<br>
+      TYPE_READ_PIPE             = 43,<br>
       /// \brief An ObjCTypeParamType record.<br>
-      TYPE_OBJC_TYPE_PARAM       = 44<br>
+      TYPE_OBJC_TYPE_PARAM       = 44,<br>
+      /// \brief A WritePipeType record.<br>
+      TYPE_WRITE_PIPE            = 45,<br>
     };<br>
<br>
     /// \brief The type IDs for special types constructed by semantic<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ASTContext.cpp?rev=287343&r1=<wbr>287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/ASTContext.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.<wbr>cpp Fri Nov 18 08:10:54 2016<br>
@@ -3338,29 +3338,53 @@ QualType ASTContext::<wbr>getFunctionTypeInte<br>
   return QualType(FTP, 0);<br>
 }<br>
<br>
-/// Return pipe type for the specified type.<br>
-QualType ASTContext::getPipeType(<wbr>QualType T) const {<br>
+QualType ASTContext::getReadPipeType(<wbr>QualType T) const {<br>
   llvm::FoldingSetNodeID ID;<br>
-  PipeType::Profile(ID, T);<br>
+  ReadPipeType::Profile(ID, T);<br>
<br>
   void *InsertPos = 0;<br>
-  if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(<wbr>ID, InsertPos))<br>
+  if (ReadPipeType *PT = ReadPipeTypes.<wbr>FindNodeOrInsertPos(ID, InsertPos))<br>
     return QualType(PT, 0);<br>
<br>
   // If the pipe element type isn't canonical, this won't be a canonical type<br>
   // either, so fill in the canonical type field.<br>
   QualType Canonical;<br>
   if (!T.isCanonical()) {<br>
-    Canonical = getPipeType(getCanonicalType(<wbr>T));<br>
+    Canonical = getReadPipeType(<wbr>getCanonicalType(T));<br>
<br>
     // Get the new insert position for the node we care about.<br>
-    PipeType *NewIP = PipeTypes.FindNodeOrInsertPos(<wbr>ID, InsertPos);<br>
+    ReadPipeType *NewIP = ReadPipeTypes.<wbr>FindNodeOrInsertPos(ID, InsertPos);<br>
     assert(!NewIP && "Shouldn't be in the map!");<br>
     (void)NewIP;<br>
   }<br>
-  PipeType *New = new (*this, TypeAlignment) PipeType(T, Canonical);<br>
+  ReadPipeType *New = new (*this, TypeAlignment) ReadPipeType(T, Canonical);<br>
   Types.push_back(New);<br>
-  PipeTypes.InsertNode(New, InsertPos);<br>
+  ReadPipeTypes.InsertNode(New, InsertPos);<br>
+  return QualType(New, 0);<br>
+}<br>
+<br>
+QualType ASTContext::getWritePipeType(<wbr>QualType T) const {<br>
+  llvm::FoldingSetNodeID ID;<br>
+  WritePipeType::Profile(ID, T);<br>
+<br>
+  void *InsertPos = 0;<br>
+  if (WritePipeType *PT = WritePipeTypes.<wbr>FindNodeOrInsertPos(ID, InsertPos))<br>
+    return QualType(PT, 0);<br>
+<br>
+  // If the pipe element type isn't canonical, this won't be a canonical type<br>
+  // either, so fill in the canonical type field.<br>
+  QualType Canonical;<br>
+  if (!T.isCanonical()) {<br>
+    Canonical = getWritePipeType(<wbr>getCanonicalType(T));<br>
+<br>
+    // Get the new insert position for the node we care about.<br>
+    WritePipeType *NewIP = WritePipeTypes.<wbr>FindNodeOrInsertPos(ID, InsertPos);<br>
+    assert(!NewIP && "Shouldn't be in the map!");<br>
+    (void)NewIP;<br>
+  }<br>
+  WritePipeType *New = new (*this, TypeAlignment) WritePipeType(T, Canonical);<br>
+  Types.push_back(New);<br>
+  WritePipeTypes.InsertNode(New, InsertPos);<br>
   return QualType(New, 0);<br>
 }<br>
<br>
@@ -7720,7 +7744,7 @@ bool ASTContext::<wbr>typesAreCompatible(Qual<br>
                                     bool CompareUnqualified) {<br>
   if (getLangOpts().CPlusPlus)<br>
     return hasSameType(LHS, RHS);<br>
-<br>
+<br>
   return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull();<br>
 }<br>
<br>
@@ -8248,7 +8272,8 @@ QualType ASTContext::mergeTypes(<wbr>QualType<br>
       return LHS;<br>
     if (getCanonicalType(RHSValue) == getCanonicalType(ResultType))<br>
       return RHS;<br>
-    return getPipeType(ResultType);<br>
+    return isa<ReadPipeType>(LHS) ? getReadPipeType(ResultType)<br>
+                                  : getWritePipeType(ResultType);<br>
   }<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/TypePrinter.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>TypePrinter.cpp?rev=287343&r1=<wbr>287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/TypePrinter.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/AST/TypePrinter.<wbr>cpp Fri Nov 18 08:10:54 2016<br>
@@ -901,6 +901,10 @@ void TypePrinter::printAtomicAfter(<wbr>const<br>
 void TypePrinter::printPipeBefore(<wbr>const PipeType *T, raw_ostream &OS) {<br>
   IncludeStrongLifetimeRAII Strong(Policy);<br>
<br>
+  if (T->isReadOnly())<br>
+    OS << "read_only ";<br>
+  else<br>
+    OS << "write_only ";<br>
   OS << "pipe ";<br>
   print(T->getElementType(), OS, StringRef());<br>
   spaceBeforePlaceHolder(OS);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaType.cpp?rev=287343&r1=<wbr>287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaType.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.<wbr>cpp Fri Nov 18 08:10:54 2016<br>
@@ -2040,7 +2040,7 @@ QualType Sema::BuildReferenceType(<wbr>QualTy<br>
   return Context.<wbr>getRValueReferenceType(T);<br>
 }<br>
<br>
-/// \brief Build a Pipe type.<br>
+/// \brief Build a Read-only Pipe type.<br>
 ///<br>
 /// \param T The type to which we'll be building a Pipe.<br>
 ///<br>
@@ -2048,11 +2048,20 @@ QualType Sema::BuildReferenceType(<wbr>QualTy<br>
 ///<br>
 /// \returns A suitable pipe type, if there are no errors. Otherwise, returns a<br>
 /// NULL type.<br>
-QualType Sema::BuildPipeType(QualType T, SourceLocation Loc) {<br>
-  assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");<br>
+QualType Sema::BuildReadPipeType(<wbr>QualType T, SourceLocation Loc) {<br>
+  return Context.getReadPipeType(T);<br>
+}<br>
<br>
-  // Build the pipe type.<br>
-  return Context.getPipeType(T);<br>
+/// \brief Build a Write-only Pipe type.<br>
+///<br>
+/// \param T The type to which we'll be building a Pipe.<br>
+///<br>
+/// \param Loc We do not use it for now.<br>
+///<br>
+/// \returns A suitable pipe type, if there are no errors. Otherwise, returns a<br>
+/// NULL type.<br>
+QualType Sema::BuildWritePipeType(<wbr>QualType T, SourceLocation Loc) {<br>
+  return Context.getWritePipeType(T);<br>
 }<br>
<br>
 /// Check whether the specified array size makes the array type a VLA.  If so,<br>
@@ -4531,7 +4540,9 @@ static TypeSourceInfo *GetFullTypeForDec<br>
     }<br>
<br>
     case DeclaratorChunk::Pipe: {<br>
-      T = S.BuildPipeType(T, DeclType.Loc );<br>
+      T = S.BuildReadPipeType(T, DeclType.Loc);<br>
+      processTypeAttrs(state, T, TAL_DeclSpec,<br>
+                       D.getDeclSpec().getAttributes(<wbr>).getList());<br>
       break;<br>
     }<br>
     }<br>
@@ -6681,6 +6692,11 @@ static void HandleOpenCLAccessAttr(QualT<br>
<br>
     S.Diag(TypedefTy->getDecl()-><wbr>getLocStart(),<br>
        diag::note_opencl_typedef_<wbr>access_qualifier) << PrevAccessQual;<br>
+  } else if (CurType->isPipeType()) {<br>
+    if (Attr.getSemanticSpelling() == OpenCLAccessAttr::Keyword_<wbr>write_only) {<br>
+      QualType ElemType = CurType->getAs<PipeType>()-><wbr>getElementType();<br>
+      CurType = S.Context.getWritePipeType(<wbr>ElemType);<br>
+    }<br>
   }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>TreeTransform.h?rev=287343&r1=<wbr>287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>TreeTransform.h Fri Nov 18 08:10:54 2016<br>
@@ -1059,7 +1059,8 @@ public:<br>
   QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);<br>
<br>
   /// \brief Build a new pipe type given its value type.<br>
-  QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc);<br>
+  QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,<br>
+                           bool isReadPipe);<br>
<br>
   /// \brief Build a new template name given a nested name specifier, a flag<br>
   /// indicating whether the "template" keyword was provided, and the template<br>
@@ -5483,7 +5484,9 @@ QualType TreeTransform<Derived>::<wbr>Transfo<br>
<br>
   QualType Result = TL.getType();<br>
   if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {<br>
-    Result = getDerived().RebuildPipeType(<wbr>ValueType, TL.getKWLoc());<br>
+    const PipeType *PT = Result->getAs<PipeType>();<br>
+    bool isReadPipe = PT->isReadOnly();<br>
+    Result = getDerived().RebuildPipeType(<wbr>ValueType, TL.getKWLoc(), isReadPipe);<br>
     if (Result.isNull())<br>
       return QualType();<br>
   }<br>
@@ -11839,8 +11842,10 @@ QualType TreeTransform<Derived>::<wbr>Rebuild<br>
<br>
 template<typename Derived><br>
 QualType TreeTransform<Derived>::<wbr>RebuildPipeType(QualType ValueType,<br>
-                                                   SourceLocation KWLoc) {<br>
-  return SemaRef.BuildPipeType(<wbr>ValueType, KWLoc);<br>
+                                                 SourceLocation KWLoc,<br>
+                                                 bool isReadPipe) {<br>
+  return isReadPipe ? SemaRef.BuildReadPipeType(<wbr>ValueType, KWLoc)<br>
+                    : SemaRef.BuildWritePipeType(<wbr>ValueType, KWLoc);<br>
 }<br>
<br>
 template<typename Derived><br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTReader.cpp?<wbr>rev=287343&r1=287342&r2=<wbr>287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp Fri Nov 18 08:10:54 2016<br>
@@ -5793,7 +5793,7 @@ QualType ASTReader::readTypeRecord(<wbr>unsig<br>
     return Context.getAtomicType(<wbr>ValueType);<br>
   }<br>
<br>
-  case TYPE_PIPE: {<br>
+  case TYPE_READ_PIPE: {<br>
     if (Record.size() != 1) {<br>
       Error("Incorrect encoding of pipe type");<br>
       return QualType();<br>
@@ -5801,7 +5801,18 @@ QualType ASTReader::readTypeRecord(<wbr>unsig<br>
<br>
     // Reading the pipe element type.<br>
     QualType ElementType = readType(*Loc.F, Record, Idx);<br>
-    return Context.getPipeType(<wbr>ElementType);<br>
+    return Context.getReadPipeType(<wbr>ElementType);<br>
+  }<br>
+<br>
+  case TYPE_WRITE_PIPE: {<br>
+    if (Record.size() != 1) {<br>
+      Error("Incorrect encoding of pipe type");<br>
+      return QualType();<br>
+    }<br>
+<br>
+    // Reading the pipe element type.<br>
+    QualType ElementType = readType(*Loc.F, Record, Idx);<br>
+    return Context.getWritePipeType(<wbr>ElementType);<br>
   }<br>
   }<br>
   llvm_unreachable("Invalid TypeCode!");<br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTWriter.cpp?<wbr>rev=287343&r1=287342&r2=<wbr>287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp Fri Nov 18 08:10:54 2016<br>
@@ -516,7 +516,10 @@ ASTTypeWriter::<wbr>VisitAtomicType(const Ato<br>
 void<br>
 ASTTypeWriter::VisitPipeType(<wbr>const PipeType *T) {<br>
   Record.AddTypeRef(T-><wbr>getElementType());<br>
-  Code = TYPE_PIPE;<br>
+  if (T->isReadOnly())<br>
+    Code = TYPE_READ_PIPE;<br>
+  else<br>
+    Code = TYPE_WRITE_PIPE;<br>
 }<br>
<br>
 namespace {<br>
<br>
Modified: cfe/trunk/test/Misc/<a href="http://ast-dump-pipe.cl" rel="noreferrer" target="_blank">ast-dump-<wbr>pipe.cl</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-pipe.cl?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Misc/<wbr>ast-dump-pipe.cl?rev=287343&<wbr>r1=287342&r2=287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Misc/<a href="http://ast-dump-pipe.cl" rel="noreferrer" target="_blank">ast-dump-<wbr>pipe.cl</a> (original)<br>
+++ cfe/trunk/test/Misc/<a href="http://ast-dump-pipe.cl" rel="noreferrer" target="_blank">ast-dump-<wbr>pipe.cl</a> Fri Nov 18 08:10:54 2016<br>
@@ -1,4 +1,12 @@<br>
 // RUN: %clang_cc1 -triple spir64 -cl-std=CL2.0 -ast-dump -ast-dump-filter pipetype %s | FileCheck -strict-whitespace %s<br>
 typedef pipe int pipetype;<br>
-// CHECK:      PipeType {{.*}} 'pipe int'<br>
+// CHECK:      PipeType {{.*}} 'read_only pipe int'<br>
+// CHECK-NEXT:   BuiltinType {{.*}} 'int'<br>
+<br>
+typedef read_only pipe int pipetype2;<br>
+// CHECK:      PipeType {{.*}} 'read_only pipe int'<br>
+// CHECK-NEXT:   BuiltinType {{.*}} 'int'<br>
+<br>
+typedef write_only pipe int pipetype3;<br>
+// CHECK:      PipeType {{.*}} 'write_only pipe int'<br>
 // CHECK-NEXT:   BuiltinType {{.*}} 'int'<br>
<br>
Modified: cfe/trunk/test/SemaOpenCL/<a href="http://access-qualifier.cl" rel="noreferrer" target="_blank">acce<wbr>ss-qualifier.cl</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/access-qualifier.cl?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaOpenCL/access-qualifier.<wbr>cl?rev=287343&r1=287342&r2=<wbr>287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaOpenCL/<a href="http://access-qualifier.cl" rel="noreferrer" target="_blank">acce<wbr>ss-qualifier.cl</a> (original)<br>
+++ cfe/trunk/test/SemaOpenCL/<a href="http://access-qualifier.cl" rel="noreferrer" target="_blank">acce<wbr>ss-qualifier.cl</a> Fri Nov 18 08:10:54 2016<br>
@@ -63,7 +63,14 @@ kernel void k11(read_only write_only ima<br>
 kernel void k12(read_only read_only image1d_t i){} // expected-error{{multiple access qualifiers}}<br>
<br>
 #if __OPENCL_C_VERSION__ >= 200<br>
-kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'pipe int'}}<br>
+kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}}<br>
 #else<br>
 kernel void k13(__read_write image1d_t i){} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' prior to OpenCL version 2.0}}<br>
 #endif<br>
+<br>
+#if __OPENCL_C_VERSION__ >= 200<br>
+void myPipeWrite(write_only pipe int); // expected-note {{passing argument to parameter here}}<br>
+kernel void k14(read_only pipe int p) {<br>
+  myPipeWrite(p); // expected-error {{passing 'read_only pipe int' to parameter of incompatible type 'write_only pipe int'}}<br>
+}<br>
+#endif<br>
<br>
Modified: cfe/trunk/test/SemaOpenCL/<a href="http://invalid-pipes-cl2.0.cl" rel="noreferrer" target="_blank">inva<wbr>lid-pipes-cl2.0.cl</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-pipes-cl2.0.cl?rev=287343&r1=287342&r2=287343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaOpenCL/invalid-pipes-cl2.<wbr>0.cl?rev=287343&r1=287342&r2=<wbr>287343&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaOpenCL/<a href="http://invalid-pipes-cl2.0.cl" rel="noreferrer" target="_blank">inva<wbr>lid-pipes-cl2.0.cl</a> (original)<br>
+++ cfe/trunk/test/SemaOpenCL/<a href="http://invalid-pipes-cl2.0.cl" rel="noreferrer" target="_blank">inva<wbr>lid-pipes-cl2.0.cl</a> Fri Nov 18 08:10:54 2016<br>
@@ -7,16 +7,16 @@ void test2(pipe p) {// expected-error {{<br>
 void test3(int pipe p) {// expected-error {{cannot combine with previous 'int' declaration specifier}}<br>
 }<br>
 void test4() {<br>
-  pipe int p; // expected-error {{type 'pipe int' can only be used as a function parameter}}<br>
+  pipe int p; // expected-error {{type 'read_only pipe int' can only be used as a function parameter}}<br>
   //TODO: fix parsing of this pipe int (*p);<br>
 }<br>
<br>
 void test5(pipe int p) {<br>
-  p+p; // expected-error{{invalid operands to binary expression ('pipe int' and 'pipe int')}}<br>
-  p=p; // expected-error{{invalid operands to binary expression ('pipe int' and 'pipe int')}}<br>
-  &p; // expected-error{{invalid argument type 'pipe int' to unary expression}}<br>
-  *p; // expected-error{{invalid argument type 'pipe int' to unary expression}}<br>
+  p+p; // expected-error{{invalid operands to binary expression ('read_only pipe int' and 'read_only pipe int')}}<br>
+  p=p; // expected-error{{invalid operands to binary expression ('read_only pipe int' and 'read_only pipe int')}}<br>
+  &p; // expected-error{{invalid argument type 'read_only pipe int' to unary expression}}<br>
+  *p; // expected-error{{invalid argument type 'read_only pipe int' to unary expression}}<br>
 }<br>
<br>
 typedef pipe int pipe_int_t;<br>
-pipe_int_t test6() {} // expected-error{{declaring function return value of type 'pipe_int_t' (aka 'pipe int') is not allowed}}<br>
+pipe_int_t test6() {} // expected-error{{declaring function return value of type 'pipe_int_t' (aka 'read_only pipe int') is not allowed}}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>