[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.
llvm-svn: 288332
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index ed08558..22be71a 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3338,54 +3338,37 @@
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::getReadPipeType(QualType T) const {
+ return getPipeType(T, true);
+}
+
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));
-
- // 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);
+ return getPipeType(T, false);
}
#ifndef NDEBUG
@@ -8260,22 +8243,9 @@
}
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();
}
}