Author: joey Date: Thu Dec 1 05:30:49 2016 New Revision: 288332 URL: http://llvm.org/viewvc/llvm-project?rev=288332&view=rev Log: [OpenCL] Refactor read_only/write_only pipes.
This adds the access qualifier to the Pipe Type, rather than using a class hierarchy. It also fixes mergeTypes for Pipes, by disallowing merges. Only identical pipe types can be merged. The test case in invalid-pipes-cl2.0.cl is added to check that. Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/include/clang/AST/Type.h cfe/trunk/include/clang/Serialization/ASTBitCodes.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/test/SemaOpenCL/invalid-pipes-cl2.0.cl Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Thu Dec 1 05:30:49 2016 @@ -135,8 +135,7 @@ class ASTContext : public RefCountedBase mutable llvm::FoldingSet<AutoType> AutoTypes; mutable llvm::FoldingSet<AtomicType> AtomicTypes; llvm::FoldingSet<AttributedType> AttributedTypes; - mutable llvm::FoldingSet<ReadPipeType> ReadPipeTypes; - mutable llvm::FoldingSet<WritePipeType> WritePipeTypes; + mutable llvm::FoldingSet<PipeType> PipeTypes; mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; @@ -1012,6 +1011,8 @@ private: QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const; + QualType getPipeType(QualType T, bool ReadOnly) const; + public: /// \brief Return the uniqued reference to the type for an address space /// qualified type with the specified type and address space. Modified: cfe/trunk/include/clang/AST/Type.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Type.h (original) +++ cfe/trunk/include/clang/AST/Type.h Thu Dec 1 05:30:49 2016 @@ -5285,7 +5285,6 @@ class AtomicType : public Type, public l /// PipeType - OpenCL20. class PipeType : public Type, public llvm::FoldingSetNode { -protected: QualType ElementType; bool isRead; @@ -5295,6 +5294,7 @@ protected: elemType->isVariablyModifiedType(), elemType->containsUnexpandedParameterPack()), ElementType(elemType), isRead(isRead) {} + friend class ASTContext; // ASTContext creates these. public: QualType getElementType() const { return ElementType; } @@ -5304,11 +5304,12 @@ public: QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getElementType()); + Profile(ID, getElementType(), isReadOnly()); } - static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { + static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) { ID.AddPointer(T.getAsOpaquePtr()); + ID.AddBoolean(isRead); } static bool classof(const Type *T) { @@ -5318,18 +5319,6 @@ public: bool isReadOnly() const { return isRead; } }; -class ReadPipeType : public PipeType { - ReadPipeType(QualType elemType, QualType CanonicalPtr) : - PipeType(elemType, CanonicalPtr, true) {} - friend class ASTContext; // ASTContext creates these. -}; - -class WritePipeType : public PipeType { - WritePipeType(QualType elemType, QualType CanonicalPtr) : - PipeType(elemType, CanonicalPtr, false) {} - friend class ASTContext; // ASTContext creates these. -}; - /// A qualifier set is used to build a set of qualifiers. class QualifierCollector : public Qualifiers { public: Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Dec 1 05:30:49 2016 @@ -905,12 +905,10 @@ namespace clang { TYPE_DECAYED = 41, /// \brief An AdjustedType record. TYPE_ADJUSTED = 42, - /// \brief A ReadPipeType record. - TYPE_READ_PIPE = 43, + /// \brief A PipeType record. + TYPE_PIPE = 43, /// \brief An ObjCTypeParamType record. - TYPE_OBJC_TYPE_PARAM = 44, - /// \brief A WritePipeType record. - TYPE_WRITE_PIPE = 45, + TYPE_OBJC_TYPE_PARAM = 44 }; /// \brief The type IDs for special types constructed by semantic Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Dec 1 05:30:49 2016 @@ -3338,54 +3338,37 @@ QualType ASTContext::getFunctionTypeInte return QualType(FTP, 0); } -QualType ASTContext::getReadPipeType(QualType T) const { +QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const { llvm::FoldingSetNodeID ID; - ReadPipeType::Profile(ID, T); + PipeType::Profile(ID, T, ReadOnly); void *InsertPos = 0; - if (ReadPipeType *PT = ReadPipeTypes.FindNodeOrInsertPos(ID, InsertPos)) + if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(PT, 0); // If the pipe element type isn't canonical, this won't be a canonical type // either, so fill in the canonical type field. QualType Canonical; if (!T.isCanonical()) { - Canonical = getReadPipeType(getCanonicalType(T)); + Canonical = getPipeType(getCanonicalType(T), ReadOnly); // Get the new insert position for the node we care about. - ReadPipeType *NewIP = ReadPipeTypes.FindNodeOrInsertPos(ID, InsertPos); + PipeType *NewIP = PipeTypes.FindNodeOrInsertPos(ID, InsertPos); assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } - ReadPipeType *New = new (*this, TypeAlignment) ReadPipeType(T, Canonical); + PipeType *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly); Types.push_back(New); - ReadPipeTypes.InsertNode(New, InsertPos); + PipeTypes.InsertNode(New, InsertPos); return QualType(New, 0); } -QualType ASTContext::getWritePipeType(QualType T) const { - llvm::FoldingSetNodeID ID; - WritePipeType::Profile(ID, T); - - void *InsertPos = 0; - if (WritePipeType *PT = WritePipeTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(PT, 0); - - // If the pipe element type isn't canonical, this won't be a canonical type - // either, so fill in the canonical type field. - QualType Canonical; - if (!T.isCanonical()) { - Canonical = getWritePipeType(getCanonicalType(T)); +QualType ASTContext::getReadPipeType(QualType T) const { + return getPipeType(T, true); +} - // Get the new insert position for the node we care about. - WritePipeType *NewIP = WritePipeTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(!NewIP && "Shouldn't be in the map!"); - (void)NewIP; - } - WritePipeType *New = new (*this, TypeAlignment) WritePipeType(T, Canonical); - Types.push_back(New); - WritePipeTypes.InsertNode(New, InsertPos); - return QualType(New, 0); +QualType ASTContext::getWritePipeType(QualType T) const { + return getPipeType(T, false); } #ifndef NDEBUG @@ -8260,22 +8243,9 @@ QualType ASTContext::mergeTypes(QualType } case Type::Pipe: { - // Merge two pointer types, while trying to preserve typedef info - QualType LHSValue = LHS->getAs<PipeType>()->getElementType(); - QualType RHSValue = RHS->getAs<PipeType>()->getElementType(); - if (Unqualified) { - LHSValue = LHSValue.getUnqualifiedType(); - RHSValue = RHSValue.getUnqualifiedType(); - } - QualType ResultType = mergeTypes(LHSValue, RHSValue, false, - Unqualified); - if (ResultType.isNull()) return QualType(); - if (getCanonicalType(LHSValue) == getCanonicalType(ResultType)) - return LHS; - if (getCanonicalType(RHSValue) == getCanonicalType(ResultType)) - return RHS; - return isa<ReadPipeType>(LHS) ? getReadPipeType(ResultType) - : getWritePipeType(ResultType); + assert(LHS != RHS && + "Equivalent pipe types should have already been handled!"); + return QualType(); } } Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Dec 1 05:30:49 2016 @@ -5793,27 +5793,18 @@ QualType ASTReader::readTypeRecord(unsig return Context.getAtomicType(ValueType); } - case TYPE_READ_PIPE: { - if (Record.size() != 1) { + case TYPE_PIPE: { + if (Record.size() != 2) { Error("Incorrect encoding of pipe type"); return QualType(); } // Reading the pipe element type. QualType ElementType = readType(*Loc.F, Record, Idx); - return Context.getReadPipeType(ElementType); + unsigned ReadOnly = Record[1]; + return Context.getPipeType(ElementType, ReadOnly); } - case TYPE_WRITE_PIPE: { - if (Record.size() != 1) { - Error("Incorrect encoding of pipe type"); - return QualType(); - } - - // Reading the pipe element type. - QualType ElementType = readType(*Loc.F, Record, Idx); - return Context.getWritePipeType(ElementType); - } } llvm_unreachable("Invalid TypeCode!"); } Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Dec 1 05:30:49 2016 @@ -516,10 +516,8 @@ ASTTypeWriter::VisitAtomicType(const Ato void ASTTypeWriter::VisitPipeType(const PipeType *T) { Record.AddTypeRef(T->getElementType()); - if (T->isReadOnly()) - Code = TYPE_READ_PIPE; - else - Code = TYPE_WRITE_PIPE; + Record.push_back(T->isReadOnly()); + Code = TYPE_PIPE; } namespace { Modified: cfe/trunk/test/SemaOpenCL/invalid-pipes-cl2.0.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-pipes-cl2.0.cl?rev=288332&r1=288331&r2=288332&view=diff ============================================================================== --- cfe/trunk/test/SemaOpenCL/invalid-pipes-cl2.0.cl (original) +++ cfe/trunk/test/SemaOpenCL/invalid-pipes-cl2.0.cl Thu Dec 1 05:30:49 2016 @@ -28,3 +28,12 @@ bool test_id_comprision(void) { reserve_id_t id1, id2; return (id1 == id2); // expected-error {{invalid operands to binary expression ('reserve_id_t' and 'reserve_id_t')}} } + +// Tests ASTContext::mergeTypes rejects this. +int f(pipe int x, int y); // expected-note {{previous declaration is here}} +int f(x, y) // expected-error {{conflicting types for 'f}} +pipe short x; +int y; +{ + return y; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits