diff --git a/clang/AST/Expr.cpp b/clang/AST/Expr.cpp index 542d4cab4c78..11aca820fdc4 100644 --- a/clang/AST/Expr.cpp +++ b/clang/AST/Expr.cpp @@ -571,3 +571,13 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const { llvm::APSInt Val(32); return isIntegerConstantExpr(Val, Ctx, 0, true) && Val == 0; } + +OCUVectorComponent::ComponentType OCUVectorComponent::getComponentType() const { + // derive the component type, no need to waste space. + const char *compStr = Accessor.getName(); + const OCUVectorType *VT = getType()->isOCUVectorType(); + if (VT->isPointAccessor(*compStr)) return Point; + if (VT->isColorAccessor(*compStr)) return Color; + if (VT->isTextureAccessor(*compStr)) return Texture; + assert(0 && "getComponentType(): Illegal accessor"); +} diff --git a/clang/AST/StmtPrinter.cpp b/clang/AST/StmtPrinter.cpp index 2c4b21eb854d..578f03f8ece2 100644 --- a/clang/AST/StmtPrinter.cpp +++ b/clang/AST/StmtPrinter.cpp @@ -439,6 +439,11 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { assert(Field && "MemberExpr should alway reference a field!"); OS << Field->getName(); } +void StmtPrinter::VisitOCUVectorComponent(OCUVectorComponent *Node) { + PrintExpr(Node->getBase()); + OS << "."; + OS << Node->getAccessor().getName(); +} void StmtPrinter::VisitCastExpr(CastExpr *Node) { OS << "(" << Node->getType().getAsString() << ")"; PrintExpr(Node->getSubExpr()); diff --git a/clang/AST/Type.cpp b/clang/AST/Type.cpp index 90cd7d009864..214dbea4881b 100644 --- a/clang/AST/Type.cpp +++ b/clang/AST/Type.cpp @@ -631,6 +631,13 @@ void VectorType::getAsStringInternal(std::string &S) const { ElementType.getAsStringInternal(S); } +void OCUVectorType::getAsStringInternal(std::string &S) const { + S += " __attribute__((ocu_vector_type("; + S += llvm::utostr_32(NumElements); + S += ")))"; + ElementType.getAsStringInternal(S); +} + void FunctionTypeNoProto::getAsStringInternal(std::string &S) const { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!S.empty()) diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 91d6d8de9b19..445b6b566887 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -423,8 +423,7 @@ ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, QualType ret = CheckOCUVectorComponent(BaseType, OpLoc, Member, MemberLoc); if (ret.isNull()) return true; - // FIXME: instantiate a OCUVectorComponentExpr node... - return true; + return new OCUVectorComponent(ret, BaseExpr, Member, MemberLoc); } else return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion, SourceRange(MemberLoc)); diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index cf5ee87c797a..fc63a7823f73 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -461,6 +461,38 @@ public: static bool classof(const MemberExpr *) { return true; } }; +/// OCUVectorComponent +/// +class OCUVectorComponent : public Expr { +public: + enum ComponentType { + Point, + Color, + Texture + }; +private: + Expr *Base; + IdentifierInfo &Accessor; + SourceLocation AccessorLoc; +public: + OCUVectorComponent(QualType ty, Expr *base, IdentifierInfo &accessor, + SourceLocation loc) : Expr(OCUVectorComponentClass, ty), + Base(base), Accessor(accessor), AccessorLoc(loc) {} + + Expr *getBase() const { return Base; } + IdentifierInfo & getAccessor() const { return Accessor; } + ComponentType getComponentType() const; + + virtual SourceRange getSourceRange() const { + return SourceRange(getBase()->getLocStart(), AccessorLoc); + } + virtual void visit(StmtVisitor &Visitor); + static bool classof(const Stmt *T) { + return T->getStmtClass() == OCUVectorComponentClass; + } + static bool classof(const OCUVectorComponent *) { return true; } +}; + /// CompoundLiteralExpr - [C99 6.5.2.5] /// class CompoundLiteralExpr : public Expr { diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index b99d225d2adc..4335b51469a5 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -62,15 +62,16 @@ STMT(45, BinaryOperator , Expr) STMT(46, ConditionalOperator , Expr) STMT(47, ImplicitCastExpr , Expr) STMT(48, CompoundLiteralExpr , Expr) +STMT(49, OCUVectorComponent , Expr) // GNU Extensions. -STMT(49, AddrLabel , Expr) -STMT(50, StmtExpr , Expr) +STMT(50, AddrLabel , Expr) +STMT(51, StmtExpr , Expr) // C++ Expressions. -STMT(51, CXXCastExpr , Expr) -STMT(52, CXXBoolLiteralExpr , Expr) -LAST_EXPR(52) +STMT(52, CXXCastExpr , Expr) +STMT(53, CXXBoolLiteralExpr , Expr) +LAST_EXPR(53) #undef STMT #undef FIRST_STMT diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 3988b99966a4..6853dbcf13df 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -526,6 +526,8 @@ public: isTextureAccessor(c); } } + virtual void getAsStringInternal(std::string &InnerString) const; + static bool classof(const Type *T) { return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector; }