diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 38 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 16 |
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; |