|
@@ -7105,23 +7105,43 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr,
|
|
|
}
|
|
|
|
|
|
if (const TypedefType* TypedefTy = CurType->getAs<TypedefType>()) {
|
|
|
- QualType PointeeTy = TypedefTy->desugar();
|
|
|
- S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers);
|
|
|
+ QualType BaseTy = TypedefTy->desugar();
|
|
|
|
|
|
std::string PrevAccessQual;
|
|
|
- switch (cast<BuiltinType>(PointeeTy.getTypePtr())->getKind()) {
|
|
|
- #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
|
|
- case BuiltinType::Id: \
|
|
|
- PrevAccessQual = #Access; \
|
|
|
- break;
|
|
|
- #include "clang/Basic/OpenCLImageTypes.def"
|
|
|
- default:
|
|
|
- assert(0 && "Unable to find corresponding image type.");
|
|
|
+ if (BaseTy->isPipeType()) {
|
|
|
+ if (TypedefTy->getDecl()->hasAttr<OpenCLAccessAttr>()) {
|
|
|
+ OpenCLAccessAttr *Attr =
|
|
|
+ TypedefTy->getDecl()->getAttr<OpenCLAccessAttr>();
|
|
|
+ PrevAccessQual = Attr->getSpelling();
|
|
|
+ } else {
|
|
|
+ PrevAccessQual = "read_only";
|
|
|
+ }
|
|
|
+ } else if (const BuiltinType* ImgType = BaseTy->getAs<BuiltinType>()) {
|
|
|
+
|
|
|
+ switch (ImgType->getKind()) {
|
|
|
+ #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
|
|
+ case BuiltinType::Id: \
|
|
|
+ PrevAccessQual = #Access; \
|
|
|
+ break;
|
|
|
+ #include "clang/Basic/OpenCLImageTypes.def"
|
|
|
+ default:
|
|
|
+ llvm_unreachable("Unable to find corresponding image type.");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ llvm_unreachable("unexpected type");
|
|
|
+ }
|
|
|
+ StringRef AttrName = Attr.getName()->getName();
|
|
|
+ if (PrevAccessQual == AttrName.ltrim("_")) {
|
|
|
+ // Duplicated qualifiers
|
|
|
+ S.Diag(Attr.getLoc(), diag::warn_duplicate_declspec)
|
|
|
+ << AttrName << Attr.getRange();
|
|
|
+ } else {
|
|
|
+ // Contradicting qualifiers
|
|
|
+ S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers);
|
|
|
}
|
|
|
|
|
|
S.Diag(TypedefTy->getDecl()->getBeginLoc(),
|
|
|
- diag::note_opencl_typedef_access_qualifier)
|
|
|
- << PrevAccessQual;
|
|
|
+ diag::note_opencl_typedef_access_qualifier) << PrevAccessQual;
|
|
|
} else if (CurType->isPipeType()) {
|
|
|
if (Attr.getSemanticSpelling() == OpenCLAccessAttr::Keyword_write_only) {
|
|
|
QualType ElemType = CurType->getAs<PipeType>()->getElementType();
|