summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp7
-rw-r--r--clang/lib/Parse/ParseDecl.cpp3
-rw-r--r--clang/lib/Sema/SemaChecking.cpp10
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp38
-rw-r--r--clang/lib/Sema/SemaType.cpp16
5 files changed, 58 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 3d0b17b9246..8e327c2bc4e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -561,15 +561,14 @@ static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn,
argTypeQuals.push_back(llvm::MDString::get(Context, typeQuals));
// Get image and pipe access qualifier:
- // FIXME: now image and pipe share the same access qualifier maybe we can
- // refine it to OpenCL access qualifier and also handle write_read
if (ty->isImageType()|| ty->isPipeType()) {
- const OpenCLImageAccessAttr *A = parm->getAttr<OpenCLImageAccessAttr>();
+ const OpenCLAccessAttr *A = parm->getAttr<OpenCLAccessAttr>();
if (A && A->isWriteOnly())
accessQuals.push_back(llvm::MDString::get(Context, "write_only"));
+ else if (A && A->isReadWrite())
+ accessQuals.push_back(llvm::MDString::get(Context, "read_write"));
else
accessQuals.push_back(llvm::MDString::get(Context, "read_only"));
- // FIXME: what about read_write?
} else
accessQuals.push_back(llvm::MDString::get(Context, "none"));
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 14b11285ea4..ab6f3ccc2db 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4989,7 +4989,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
tok::TokenKind Kind = Tok.getKind();
if (D.getDeclSpec().isTypeSpecPipe() && !isPipeDeclerator(D)) {
- DeclSpec &DS = D.getMutableDeclSpec();
+ DeclSpec DS(AttrFactory);
+ ParseTypeQualifierListOpt(DS);
D.AddTypeInfo(
DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()),
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a1f975a826f..134248dbe22 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -265,11 +265,9 @@ static StringRef getFunctionName(CallExpr *Call) {
}
/// Returns OpenCL access qual.
-// TODO: Refine OpenCLImageAccessAttr to OpenCLAccessAttr since pipe can use
-// it too
-static OpenCLImageAccessAttr *getOpenCLArgAccess(const Decl *D) {
- if (D->hasAttr<OpenCLImageAccessAttr>())
- return D->getAttr<OpenCLImageAccessAttr>();
+static OpenCLAccessAttr *getOpenCLArgAccess(const Decl *D) {
+ if (D->hasAttr<OpenCLAccessAttr>())
+ return D->getAttr<OpenCLAccessAttr>();
return nullptr;
}
@@ -282,7 +280,7 @@ static bool checkOpenCLPipeArg(Sema &S, CallExpr *Call) {
<< getFunctionName(Call) << Arg0->getSourceRange();
return true;
}
- OpenCLImageAccessAttr *AccessQual =
+ OpenCLAccessAttr *AccessQual =
getOpenCLArgAccess(cast<DeclRefExpr>(Arg0)->getDecl());
// Validates the access qualifier is compatible with the call.
// OpenCL v2.0 s6.13.16 - The access qualifiers for pipe should only be
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 3f6af3d765b..b031e38c757 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5043,6 +5043,40 @@ static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
return false;
}
+static void handleOpenCLAccessAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (D->isInvalidDecl())
+ return;
+
+ // Check if there is only one access qualifier.
+ if (D->hasAttr<OpenCLAccessAttr>()) {
+ S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers)
+ << D->getSourceRange();
+ D->setInvalidDecl(true);
+ return;
+ }
+
+ // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that an
+ // image object can be read and written.
+ // OpenCL v2.0 s6.13.6 - A kernel cannot read from and write to the same pipe
+ // object. Using the read_write (or __read_write) qualifier with the pipe
+ // qualifier is a compilation error.
+ if (const ParmVarDecl *PDecl = dyn_cast<ParmVarDecl>(D)) {
+ const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
+ if (Attr.getName()->getName().find("read_write") != StringRef::npos) {
+ if (S.getLangOpts().OpenCLVersion < 200 || DeclTy->isPipeType()) {
+ S.Diag(Attr.getLoc(), diag::err_opencl_invalid_read_write)
+ << Attr.getName() << PDecl->getType() << DeclTy->isImageType();
+ D->setInvalidDecl(true);
+ return;
+ }
+ }
+ }
+
+ D->addAttr(::new (S.Context) OpenCLAccessAttr(
+ Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
+}
+
//===----------------------------------------------------------------------===//
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
@@ -5440,8 +5474,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_OpenCLKernel:
handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr);
break;
- case AttributeList::AT_OpenCLImageAccess:
- handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr);
+ case AttributeList::AT_OpenCLAccess:
+ handleOpenCLAccessAttr(S, D, Attr);
break;
case AttributeList::AT_InternalLinkage:
handleInternalLinkageAttr(S, D, Attr);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index fb37743a710..dbc325c149b 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6237,6 +6237,17 @@ static void HandleNeonVectorTypeAttr(QualType& CurType,
CurType = S.Context.getVectorType(CurType, numElts, VecKind);
}
+/// Handle OpenCL Access Qualifier Attribute.
+static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr,
+ Sema &S) {
+ // OpenCL v2.0 s6.6 - Access qualifier can used only for image and pipe type.
+ if (!(CurType->isImageType() || CurType->isPipeType())) {
+ S.Diag(Attr.getLoc(), diag::err_opencl_invalid_access_qualifier);
+ Attr.setInvalid();
+ return;
+ }
+}
+
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
TypeAttrLocation TAL, AttributeList *attrs) {
// Scan through and apply attributes to this type where it makes sense. Some
@@ -6332,9 +6343,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
VectorType::NeonPolyVector);
attr.setUsedAsTypeAttr();
break;
- case AttributeList::AT_OpenCLImageAccess:
- // FIXME: there should be some type checking happening here, I would
- // imagine, but the original handler's checking was entirely superfluous.
+ case AttributeList::AT_OpenCLAccess:
+ HandleOpenCLAccessAttr(type, attr, state.getSema());
attr.setUsedAsTypeAttr();
break;
OpenPOWER on IntegriCloud