summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2016-07-22 18:49:43 +0000
committerPirama Arumuga Nainar <pirama@google.com>2016-07-22 18:49:43 +0000
commit98eaa62e369d8e11e53c9143d70e327df2cbf19f (patch)
treea2ed0a3ec7e96e257007a47de866c65fa36332d9 /clang/lib
parentff3ea5f4f8b51d7cf2156c3aca0a6b176da7ba34 (diff)
downloadbcm5719-llvm-98eaa62e369d8e11e53c9143d70e327df2cbf19f.tar.gz
bcm5719-llvm-98eaa62e369d8e11e53c9143d70e327df2cbf19f.zip
Add .rgba syntax extension to ext_vector_type types
Summary: This patch enables .rgba accessors to ext_vector_type types and adds tests for syntax validation and code generation. 'a' and 'b' can appear either in the point access mode or the numeric access mode (for indices 10 and 11). To disambiguate between the two usages, the accessor type is explicitly passed to relevant methods. Reviewers: rsmith Subscribers: Anastasia, bader, srhines, cfe-commits Differential Revision: http://reviews.llvm.org/D20602 llvm-svn: 276455
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp7
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp30
2 files changed, 34 insertions, 3 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 8762dda7ec2..71bbfdc3369 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3395,8 +3395,11 @@ bool ExtVectorElementExpr::containsDuplicateElements() const {
void ExtVectorElementExpr::getEncodedElementAccess(
SmallVectorImpl<uint32_t> &Elts) const {
StringRef Comp = Accessor->getName();
- if (Comp[0] == 's' || Comp[0] == 'S')
+ bool isNumericAccessor = false;
+ if (Comp[0] == 's' || Comp[0] == 'S') {
Comp = Comp.substr(1);
+ isNumericAccessor = true;
+ }
bool isHi = Comp == "hi";
bool isLo = Comp == "lo";
@@ -3415,7 +3418,7 @@ void ExtVectorElementExpr::getEncodedElementAccess(
else if (isOdd)
Index = 2 * i + 1;
else
- Index = ExtVectorType::getAccessorIdx(Comp[i]);
+ Index = ExtVectorType::getAccessorIdx(Comp[i], isNumericAccessor);
Elts.push_back(Index);
}
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 283621889f8..0c625b24c57 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -269,6 +269,20 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
llvm_unreachable("unexpected instance member access kind");
}
+/// Determine whether input char is from rgba component set.
+static bool
+IsRGBA(char c) {
+ switch (c) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ return true;
+ default:
+ return false;
+ }
+}
+
/// Check an ext-vector component access expression.
///
/// VK should be set in advance to the value kind of the base
@@ -308,11 +322,25 @@ CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK,
HalvingSwizzle = true;
} else if (!HexSwizzle &&
(Idx = vecType->getPointAccessorIdx(*compStr)) != -1) {
+ bool HasRGBA = IsRGBA(*compStr);
do {
+ // Ensure that xyzw and rgba components don't intermingle.
+ if (HasRGBA != IsRGBA(*compStr))
+ break;
if (HasIndex[Idx]) HasRepeated = true;
HasIndex[Idx] = true;
compStr++;
} while (*compStr && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1);
+
+ // Emit a warning if an rgba selector is used earlier than OpenCL 2.2
+ if (HasRGBA || (*compStr && IsRGBA(*compStr))) {
+ if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion < 220) {
+ const char *DiagBegin = HasRGBA ? CompName->getNameStart() : compStr;
+ S.Diag(OpLoc, diag::ext_opencl_ext_vector_type_rgba_selector)
+ << StringRef(DiagBegin, 1)
+ << S.getLangOpts().OpenCLVersion << SourceRange(CompLoc);
+ }
+ }
} else {
if (HexSwizzle) compStr++;
while ((Idx = vecType->getNumericAccessorIdx(*compStr)) != -1) {
@@ -339,7 +367,7 @@ CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK,
compStr++;
while (*compStr) {
- if (!vecType->isAccessorWithinNumElements(*compStr++)) {
+ if (!vecType->isAccessorWithinNumElements(*compStr++, HexSwizzle)) {
S.Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
<< baseType << SourceRange(CompLoc);
return QualType();
OpenPOWER on IntegriCloud