[cfe-commits] r40568 - in /cfe/trunk: Sema/Sema.h Sema/SemaExpr.cpp Sema/SemaStmt.cpp include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def test/Parser/ocu_vector_components.c
Steve Naroff
snaroff at apple.com
Fri Jul 27 15:15:19 PDT 2007
Author: snaroff
Date: Fri Jul 27 17:15:19 2007
New Revision: 40568
URL: http://llvm.org/viewvc/llvm-project?rev=40568&view=rev
Log:
Implement syntax/semantic analysis for OCU Vector Components.
Next step, AST support...
Added:
cfe/trunk/test/Parser/ocu_vector_components.c
Modified:
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/Sema/SemaStmt.cpp
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=40568&r1=40567&r2=40568&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Fri Jul 27 17:15:19 2007
@@ -38,6 +38,7 @@
class ArrayType;
class LabelStmt;
class SwitchStmt;
+ class OCUVectorType;
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
@@ -369,7 +370,11 @@
QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
QualType CheckSizeOfAlignOfOperand(QualType type, SourceLocation loc,
bool isSizeof);
-
+
+ /// type checking primary expressions.
+ QualType CheckOCUVectorComponent(QualType baseType, SourceLocation OpLoc,
+ IdentifierInfo &Comp, SourceLocation CmpLoc);
+
/// C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have
/// a constant expression of type int with a value greater than zero. If the
/// array has an incomplete type or a valid constant size, return false,
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=40568&r1=40567&r2=40568&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Fri Jul 27 17:15:19 2007
@@ -339,6 +339,57 @@
return new ArraySubscriptExpr(LHSExp, RHSExp, ResultType, RLoc);
}
+QualType Sema::
+CheckOCUVectorComponent(QualType baseType, SourceLocation OpLoc,
+ IdentifierInfo &CompName, SourceLocation CompLoc) {
+ const OCUVectorType *vecType = baseType->isOCUVectorType();
+
+ // The vector accessor can't exceed the number of elements.
+ const char *compStr = CompName.getName();
+ if (strlen(compStr) > vecType->getNumElements()) {
+ Diag(OpLoc, diag::err_ocuvector_component_exceeds_length,
+ baseType.getAsString(), SourceRange(CompLoc));
+ return QualType();
+ }
+ // The component names must come from the same set.
+ if (vecType->isPointAccessor(*compStr))
+ do { compStr++; } while (*compStr && vecType->isPointAccessor(*compStr));
+ else if (vecType->isColorAccessor(*compStr))
+ do { compStr++; } while (*compStr && vecType->isColorAccessor(*compStr));
+ else if (vecType->isTextureAccessor(*compStr))
+ do { compStr++; } while (*compStr && vecType->isTextureAccessor(*compStr));
+
+ if (*compStr) {
+ // We didn't get to the end of the string. This means the component names
+ // didn't come from the same set *or* we encountered an illegal name.
+ Diag(OpLoc, diag::err_ocuvector_component_name_illegal,
+ std::string(compStr,compStr+1), SourceRange(CompLoc));
+ return QualType();
+ }
+ // Each component accessor can't exceed the vector type.
+ compStr = CompName.getName();
+ while (*compStr) {
+ if (vecType->isAccessorWithinNumElements(*compStr))
+ compStr++;
+ else
+ break;
+ }
+ if (*compStr) {
+ // We didn't get to the end of the string. This means a component accessor
+ // exceeds the number of elements in the vector.
+ Diag(OpLoc, diag::err_ocuvector_component_exceeds_length,
+ baseType.getAsString(), SourceRange(CompLoc));
+ return QualType();
+ }
+ // The component accessor looks fine - now we need to compute the actual type.
+ // The vector type is implied by the component accessor. For example,
+ // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
+ unsigned CompSize = strlen(CompName.getName());
+ if (CompSize == 1)
+ return vecType->getElementType();
+ return Context.getOCUVectorType(vecType->getElementType(), CompSize);
+}
+
Action::ExprResult Sema::
ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
@@ -356,22 +407,27 @@
return Diag(OpLoc, diag::err_typecheck_member_reference_arrow,
SourceRange(MemberLoc));
}
- // Get the member decl from the struct/union definition.
- FieldDecl *MemberDecl;
+ // The base type is either a record or an OCUVectorType.
if (const RecordType *RTy = BaseType->isRecordType()) {
RecordDecl *RDecl = RTy->getDecl();
if (RTy->isIncompleteType())
return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RDecl->getName(),
BaseExpr->getSourceRange());
// The record definition is complete, now make sure the member is valid.
- if (!(MemberDecl = RDecl->getMember(&Member)))
+ FieldDecl *MemberDecl = RDecl->getMember(&Member);
+ if (!MemberDecl)
return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName(),
SourceRange(MemberLoc));
+ return new MemberExpr(BaseExpr, OpKind==tok::arrow, MemberDecl, MemberLoc);
+ } else if (BaseType->isOCUVectorType() && OpKind == tok::period) {
+ QualType ret = CheckOCUVectorComponent(BaseType, OpLoc, Member, MemberLoc);
+ if (ret.isNull())
+ return true;
+ // FIXME: instantiate a OCUVectorComponentExpr node...
+ return true;
} else
return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion,
SourceRange(MemberLoc));
-
- return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl, MemberLoc);
}
/// ParseCallExpr - Handle a call to Fn with the specified array of arguments.
Modified: cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaStmt.cpp?rev=40568&r1=40567&r2=40568&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/Sema/SemaStmt.cpp Fri Jul 27 17:15:19 2007
@@ -23,6 +23,7 @@
Sema::StmtResult Sema::ParseExprStmt(ExprTy *expr) {
Expr *E = static_cast<Expr*>(expr);
+ assert(E && "ParseExprStmt(): missing expression");
// Exprs are statements, so there is no need to do a conversion here. However,
// diagnose some potentially bad code.
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=40568&r1=40567&r2=40568&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Jul 27 17:15:19 2007
@@ -504,6 +504,28 @@
VectorType(OCUVector, vecType, nElements, canonType) {}
friend class ASTContext; // ASTContext creates these.
public:
+ bool isPointAccessor(const char c) const {
+ return c == 'x' || c == 'y' || c == 'z' || c == 'w';
+ }
+ bool isColorAccessor(const char c) const {
+ return c == 'r' || c == 'g' || c == 'b' || c == 'a';
+ }
+ bool isTextureAccessor(const char c) const {
+ return c == 's' || c == 't' || c == 'p' || c == 'q';
+ };
+ bool isAccessorWithinNumElements(const char c) const {
+ switch (NumElements) {
+ default: assert(0 && "Illegal number of elements");
+ case 2: return c == 'x' || c == 'y' ||
+ c == 'r' || c == 'g' ||
+ c == 's' || c == 't';
+ case 3: return c == 'x' || c == 'y' || c == 'z' ||
+ c == 'r' || c == 'g' || c == 'b' ||
+ c == 's' || c == 't' || c == 'p';
+ case 4: return isPointAccessor(c) || isColorAccessor(c) ||
+ isTextureAccessor(c);
+ }
+ }
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector;
}
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=40568&r1=40567&r2=40568&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Jul 27 17:15:19 2007
@@ -445,6 +445,10 @@
"can't convert between vector values of different size ('%0' and '%1')")
DIAG(err_typecheck_ocu_vector_not_typedef, ERROR,
"ocu_vector_type only applies to types, not variables")
+DIAG(err_ocuvector_component_exceeds_length, ERROR,
+ "vector component access exceeds type '%0'")
+DIAG(err_ocuvector_component_name_illegal, ERROR,
+ "illegal vector component name '%0'")
// Function Parameter Semantic Analysis.
DIAG(err_param_with_void_type, ERROR,
Added: cfe/trunk/test/Parser/ocu_vector_components.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/ocu_vector_components.c?rev=40568&view=auto
==============================================================================
--- cfe/trunk/test/Parser/ocu_vector_components.c (added)
+++ cfe/trunk/test/Parser/ocu_vector_components.c Fri Jul 27 17:15:19 2007
@@ -0,0 +1,20 @@
+// RUN: clang -parse-ast-check %s
+
+typedef __attribute__(( ocu_vector_type(2) )) float float2;
+typedef __attribute__(( ocu_vector_type(3) )) float float3;
+typedef __attribute__(( ocu_vector_type(4) )) float float4;
+
+static void test() {
+ float2 vec2;
+ float3 vec3;
+ float4 vec4;
+ float f;
+
+ vec2.z; // // expected-error {{vector component access exceeds type 'float2'}}
+ vec2.rgba; // // expected-error {{vector component access exceeds type 'float2'}}
+ vec4.rgba;
+ vec4.rgbc; // // expected-error {{illegal vector component name 'c'}}
+ vec3 = vec4.rgb; // legal, shorten
+ f = vec2.x; // legal, shorten
+ vec4 = (float4){ 1,2,3,4 };
+}
More information about the cfe-commits
mailing list