diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 5634bf4d62bc..921aff100147 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1844,8 +1844,19 @@ public: BuiltinLoc(BLoc), RParenLoc(RPLoc) { } + /// \brief Create an empty __builtin_va_start expression. + explicit VAArgExpr(EmptyShell Empty) : Expr(VAArgExprClass, Empty) { } + const Expr *getSubExpr() const { return cast(Val); } Expr *getSubExpr() { return cast(Val); } + void setSubExpr(Expr *E) { Val = E; } + + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } + void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(BuiltinLoc, RParenLoc); } @@ -2306,19 +2317,28 @@ public: /// class ExtVectorElementExpr : public Expr { Stmt *Base; - IdentifierInfo &Accessor; + IdentifierInfo *Accessor; SourceLocation AccessorLoc; public: ExtVectorElementExpr(QualType ty, Expr *base, IdentifierInfo &accessor, SourceLocation loc) : Expr(ExtVectorElementExprClass, ty), - Base(base), Accessor(accessor), AccessorLoc(loc) {} + Base(base), Accessor(&accessor), AccessorLoc(loc) {} + /// \brief Build an empty vector element expression. + explicit ExtVectorElementExpr(EmptyShell Empty) + : Expr(ExtVectorElementExprClass, Empty) { } + const Expr *getBase() const { return cast(Base); } Expr *getBase() { return cast(Base); } - - IdentifierInfo &getAccessor() const { return Accessor; } - + void setBase(Expr *E) { Base = E; } + + IdentifierInfo &getAccessor() const { return *Accessor; } + void setAccessor(IdentifierInfo *II) { Accessor = II; } + + SourceLocation getAccessorLoc() const { return AccessorLoc; } + void setAccessorLoc(SourceLocation L) { AccessorLoc = L; } + /// getNumElements - Get the number of components being selected. unsigned getNumElements() const; diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index a944f09bcb1c..10169b3051ac 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -418,7 +418,15 @@ namespace clang { /// \brief An ImplicitCastExpr record. EXPR_IMPLICIT_CAST, /// \brief A CStyleCastExpr record. - EXPR_CSTYLE_CAST + EXPR_CSTYLE_CAST, + /// FIXME: CompoundLiteralExpr + /// \brief An ExtVectorElementExpr record. + EXPR_EXT_VECTOR_ELEMENT, + /// FIXME: InitListExpr + /// FIXME: DesignatedInitExpr + /// FIXME: ImplicitValueInitExpr + /// \brief A VAArgExpr record. + EXPR_VA_ARG }; /// @} } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 99e07c4b8ab1..91b6dc9d4c55 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1372,8 +1372,8 @@ unsigned ExtVectorElementExpr::getNumElements() const { /// containsDuplicateElements - Return true if any element access is repeated. bool ExtVectorElementExpr::containsDuplicateElements() const { - const char *compStr = Accessor.getName(); - unsigned length = Accessor.getLength(); + const char *compStr = Accessor->getName(); + unsigned length = Accessor->getLength(); // Halving swizzles do not contain duplicate elements. if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") || @@ -1398,7 +1398,7 @@ bool ExtVectorElementExpr::containsDuplicateElements() const { /// getEncodedElementAccess - We encode the fields as a llvm ConstantArray. void ExtVectorElementExpr::getEncodedElementAccess( llvm::SmallVectorImpl &Elts) const { - const char *compStr = Accessor.getName(); + const char *compStr = Accessor->getName(); if (*compStr == 's') compStr++; diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index f9290bac73fb..bd1ed1f3df15 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -257,6 +257,8 @@ namespace { unsigned VisitImplicitCastExpr(ImplicitCastExpr *E); unsigned VisitExplicitCastExpr(ExplicitCastExpr *E); unsigned VisitCStyleCastExpr(CStyleCastExpr *E); + unsigned VisitExtVectorElementExpr(ExtVectorElementExpr *E); + unsigned VisitVAArgExpr(VAArgExpr *E); }; } @@ -437,6 +439,23 @@ unsigned PCHStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) { return 1; } +unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { + VisitExpr(E); + E->setBase(ExprStack.back()); + E->setAccessor(Reader.GetIdentifierInfo(Record, Idx)); + E->setAccessorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 1; +} + +unsigned PCHStmtReader::VisitVAArgExpr(VAArgExpr *E) { + VisitExpr(E); + E->setSubExpr(ExprStack.back()); + E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 1; +} + + // FIXME: use the diagnostics machinery static bool Error(const char *Str) { std::fprintf(stderr, "%s\n", Str); @@ -1949,6 +1968,15 @@ Expr *PCHReader::ReadExpr() { case pch::EXPR_CSTYLE_CAST: E = new (Context) CStyleCastExpr(Empty); break; + + case pch::EXPR_EXT_VECTOR_ELEMENT: + E = new (Context) ExtVectorElementExpr(Empty); + break; + + case pch::EXPR_VA_ARG: + // FIXME: untested; we need function bodies first + E = new (Context) VAArgExpr(Empty); + break; } // We hit an EXPR_STOP, so we're done with this expression. diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 0321e4c40bae..612eb23b5292 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -464,6 +464,8 @@ namespace { void VisitImplicitCastExpr(ImplicitCastExpr *E); void VisitExplicitCastExpr(ExplicitCastExpr *E); void VisitCStyleCastExpr(CStyleCastExpr *E); + void VisitExtVectorElementExpr(ExtVectorElementExpr *E); + void VisitVAArgExpr(VAArgExpr *E); }; } @@ -637,6 +639,22 @@ void PCHStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) { Code = pch::EXPR_CSTYLE_CAST; } +void PCHStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { + VisitExpr(E); + Writer.WriteSubExpr(E->getBase()); + Writer.AddIdentifierRef(&E->getAccessor(), Record); + Writer.AddSourceLocation(E->getAccessorLoc(), Record); + Code = pch::EXPR_EXT_VECTOR_ELEMENT; +} + +void PCHStmtWriter::VisitVAArgExpr(VAArgExpr *E) { + VisitExpr(E); + Writer.WriteSubExpr(E->getSubExpr()); + Writer.AddSourceLocation(E->getBuiltinLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = pch::EXPR_VA_ARG; +} + //===----------------------------------------------------------------------===// // PCHWriter Implementation //===----------------------------------------------------------------------===// diff --git a/clang/test/PCH/exprs.c b/clang/test/PCH/exprs.c index 49f74dd91a91..6d5a9693014a 100644 --- a/clang/test/PCH/exprs.c +++ b/clang/test/PCH/exprs.c @@ -60,3 +60,6 @@ conditional_operator *double_ptr4 = &floating; // CStyleCastExpr void_ptr vp1 = &integer; + +// ExtVectorElementExpr +ext_vector_element *double_ptr5 = &floating; diff --git a/clang/test/PCH/exprs.h b/clang/test/PCH/exprs.h index 016c4c6beeed..9637b6ed62d1 100644 --- a/clang/test/PCH/exprs.h +++ b/clang/test/PCH/exprs.h @@ -56,3 +56,7 @@ typedef typeof(i? : d0) conditional_operator; // CStyleCastExpr typedef typeof((void *)0) void_ptr; +// ExtVectorElementExpr +typedef __attribute__(( ext_vector_type(2) )) double double2; +double2 vec2; +typedef typeof(vec2.x) ext_vector_element;