summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp45
-rw-r--r--clang/lib/AST/TypePrinter.cpp4
-rw-r--r--clang/lib/Sema/SemaType.cpp28
-rw-r--r--clang/lib/Sema/TreeTransform.h13
-rw-r--r--clang/lib/Serialization/ASTReader.cpp15
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp5
6 files changed, 87 insertions, 23 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c48ab9a44a4..622898dde27 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3338,29 +3338,53 @@ QualType ASTContext::getFunctionTypeInternal(
return QualType(FTP, 0);
}
-/// Return pipe type for the specified type.
-QualType ASTContext::getPipeType(QualType T) const {
+QualType ASTContext::getReadPipeType(QualType T) const {
llvm::FoldingSetNodeID ID;
- PipeType::Profile(ID, T);
+ ReadPipeType::Profile(ID, T);
void *InsertPos = 0;
- if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos))
+ if (ReadPipeType *PT = ReadPipeTypes.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 = getPipeType(getCanonicalType(T));
+ Canonical = getReadPipeType(getCanonicalType(T));
// Get the new insert position for the node we care about.
- PipeType *NewIP = PipeTypes.FindNodeOrInsertPos(ID, InsertPos);
+ ReadPipeType *NewIP = ReadPipeTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!");
(void)NewIP;
}
- PipeType *New = new (*this, TypeAlignment) PipeType(T, Canonical);
+ ReadPipeType *New = new (*this, TypeAlignment) ReadPipeType(T, Canonical);
Types.push_back(New);
- PipeTypes.InsertNode(New, InsertPos);
+ ReadPipeTypes.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));
+
+ // 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);
}
@@ -7720,7 +7744,7 @@ bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS,
bool CompareUnqualified) {
if (getLangOpts().CPlusPlus)
return hasSameType(LHS, RHS);
-
+
return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull();
}
@@ -8248,7 +8272,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return LHS;
if (getCanonicalType(RHSValue) == getCanonicalType(ResultType))
return RHS;
- return getPipeType(ResultType);
+ return isa<ReadPipeType>(LHS) ? getReadPipeType(ResultType)
+ : getWritePipeType(ResultType);
}
}
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 3372d334f66..cccc9087632 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -901,6 +901,10 @@ void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { }
void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
+ if (T->isReadOnly())
+ OS << "read_only ";
+ else
+ OS << "write_only ";
OS << "pipe ";
print(T->getElementType(), OS, StringRef());
spaceBeforePlaceHolder(OS);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 8dada8ca949..181a3818abe 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2040,7 +2040,7 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
return Context.getRValueReferenceType(T);
}
-/// \brief Build a Pipe type.
+/// \brief Build a Read-only Pipe type.
///
/// \param T The type to which we'll be building a Pipe.
///
@@ -2048,11 +2048,20 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
///
/// \returns A suitable pipe type, if there are no errors. Otherwise, returns a
/// NULL type.
-QualType Sema::BuildPipeType(QualType T, SourceLocation Loc) {
- assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");
+QualType Sema::BuildReadPipeType(QualType T, SourceLocation Loc) {
+ return Context.getReadPipeType(T);
+}
- // Build the pipe type.
- return Context.getPipeType(T);
+/// \brief Build a Write-only Pipe type.
+///
+/// \param T The type to which we'll be building a Pipe.
+///
+/// \param Loc We do not use it for now.
+///
+/// \returns A suitable pipe type, if there are no errors. Otherwise, returns a
+/// NULL type.
+QualType Sema::BuildWritePipeType(QualType T, SourceLocation Loc) {
+ return Context.getWritePipeType(T);
}
/// Check whether the specified array size makes the array type a VLA. If so,
@@ -4531,7 +4540,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
}
case DeclaratorChunk::Pipe: {
- T = S.BuildPipeType(T, DeclType.Loc );
+ T = S.BuildReadPipeType(T, DeclType.Loc);
+ processTypeAttrs(state, T, TAL_DeclSpec,
+ D.getDeclSpec().getAttributes().getList());
break;
}
}
@@ -6681,6 +6692,11 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr,
S.Diag(TypedefTy->getDecl()->getLocStart(),
diag::note_opencl_typedef_access_qualifier) << PrevAccessQual;
+ } else if (CurType->isPipeType()) {
+ if (Attr.getSemanticSpelling() == OpenCLAccessAttr::Keyword_write_only) {
+ QualType ElemType = CurType->getAs<PipeType>()->getElementType();
+ CurType = S.Context.getWritePipeType(ElemType);
+ }
}
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 26d7222445b..a52234663d7 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1059,7 +1059,8 @@ public:
QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
/// \brief Build a new pipe type given its value type.
- QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc);
+ QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
+ bool isReadPipe);
/// \brief Build a new template name given a nested name specifier, a flag
/// indicating whether the "template" keyword was provided, and the template
@@ -5483,7 +5484,9 @@ QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
- Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc());
+ const PipeType *PT = Result->getAs<PipeType>();
+ bool isReadPipe = PT->isReadOnly();
+ Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
if (Result.isNull())
return QualType();
}
@@ -11839,8 +11842,10 @@ QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
template<typename Derived>
QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
- SourceLocation KWLoc) {
- return SemaRef.BuildPipeType(ValueType, KWLoc);
+ SourceLocation KWLoc,
+ bool isReadPipe) {
+ return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
+ : SemaRef.BuildWritePipeType(ValueType, KWLoc);
}
template<typename Derived>
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 35065d0fc1e..f97571b7e80 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5793,7 +5793,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getAtomicType(ValueType);
}
- case TYPE_PIPE: {
+ case TYPE_READ_PIPE: {
if (Record.size() != 1) {
Error("Incorrect encoding of pipe type");
return QualType();
@@ -5801,7 +5801,18 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
// Reading the pipe element type.
QualType ElementType = readType(*Loc.F, Record, Idx);
- return Context.getPipeType(ElementType);
+ return Context.getReadPipeType(ElementType);
+ }
+
+ 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!");
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index e34347d2064..f60a24cecb2 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -516,7 +516,10 @@ ASTTypeWriter::VisitAtomicType(const AtomicType *T) {
void
ASTTypeWriter::VisitPipeType(const PipeType *T) {
Record.AddTypeRef(T->getElementType());
- Code = TYPE_PIPE;
+ if (T->isReadOnly())
+ Code = TYPE_READ_PIPE;
+ else
+ Code = TYPE_WRITE_PIPE;
}
namespace {
OpenPOWER on IntegriCloud