aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h2
-rw-r--r--include/clang/AST/Expr.h46
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td12
-rw-r--r--include/clang/Basic/StmtNodes.td2
-rw-r--r--include/clang/Basic/TokenKinds.def3
-rw-r--r--include/clang/Basic/TypeTraits.h7
-rw-r--r--include/clang/Parse/Parser.h4
-rw-r--r--include/clang/Sema/Sema.h24
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h6
-rw-r--r--lib/AST/ASTImporter.cpp13
-rw-r--r--lib/AST/Expr.cpp4
-rw-r--r--lib/AST/ExprClassification.cpp2
-rw-r--r--lib/AST/ExprConstant.cpp77
-rw-r--r--lib/AST/ItaniumMangle.cpp20
-rw-r--r--lib/AST/StmtDumper.cpp16
-rw-r--r--lib/AST/StmtPrinter.cpp14
-rw-r--r--lib/AST/StmtProfile.cpp4
-rw-r--r--lib/Analysis/CFG.cpp12
-rw-r--r--lib/Analysis/UninitializedValuesV2.cpp7
-rw-r--r--lib/CodeGen/CGExprScalar.cpp9
-rw-r--r--lib/Parse/ParseDecl.cpp6
-rw-r--r--lib/Parse/ParseDeclCXX.cpp4
-rw-r--r--lib/Parse/ParseExpr.cpp69
-rw-r--r--lib/Rewrite/RewriteObjC.cpp9
-rw-r--r--lib/Sema/SemaChecking.cpp2
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp103
-rw-r--r--lib/Sema/TreeTransform.h39
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp8
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp29
-rw-r--r--test/PCH/exprs.c2
-rw-r--r--test/PCH/exprs.h2
-rw-r--r--test/SemaOpenCL/vec_step.cl32
-rw-r--r--tools/libclang/CIndex.cpp5
-rw-r--r--tools/libclang/CXCursor.cpp2
40 files changed, 395 insertions, 228 deletions
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index 035f57c12e..3bc62eda2d 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -37,7 +37,7 @@ public:
// other sub-expressions).
void VisitDeclRefExpr(DeclRefExpr *E) { }
void VisitOffsetOfExpr(OffsetOfExpr *E) { }
- void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { }
+ void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
void VisitBlockExpr(BlockExpr *E) { }
void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 548568127a..4a68e43e06 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -21,6 +21,7 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ASTVector.h"
#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
@@ -1554,10 +1555,11 @@ public:
}
};
-/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of
-/// types and expressions.
-class SizeOfAlignOfExpr : public Expr {
- bool isSizeof : 1; // true if sizeof, false if alignof.
+/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
+/// expression operand. Used for sizeof/alignof (C99 6.5.3.4) and
+/// vec_step (OpenCL 1.1 6.11.12).
+class UnaryExprOrTypeTraitExpr : public Expr {
+ unsigned Kind : 2;
bool isType : 1; // true if operand is a type, false if an expression
union {
TypeSourceInfo *Ty;
@@ -1566,36 +1568,38 @@ class SizeOfAlignOfExpr : public Expr {
SourceLocation OpLoc, RParenLoc;
public:
- SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
- QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary,
+ UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
+ QualType resultType, SourceLocation op,
+ SourceLocation rp) :
+ Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
TInfo->getType()->isDependentType(),
TInfo->getType()->containsUnexpandedParameterPack()),
- isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
+ Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) {
Argument.Ty = TInfo;
}
- SizeOfAlignOfExpr(bool issizeof, Expr *E,
- QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary,
+ UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
+ QualType resultType, SourceLocation op,
+ SourceLocation rp) :
+ Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
E->isTypeDependent(),
E->containsUnexpandedParameterPack()),
- isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) {
+ Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) {
Argument.Ex = E;
}
/// \brief Construct an empty sizeof/alignof expression.
- explicit SizeOfAlignOfExpr(EmptyShell Empty)
- : Expr(SizeOfAlignOfExprClass, Empty) { }
+ explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
+ : Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
- bool isSizeOf() const { return isSizeof; }
- void setSizeof(bool S) { isSizeof = S; }
+ UnaryExprOrTypeTrait getKind() const {
+ return static_cast<UnaryExprOrTypeTrait>(Kind);
+ }
+ void setKind(UnaryExprOrTypeTrait K) { Kind = K; }
bool isArgumentType() const { return isType; }
QualType getArgumentType() const {
@@ -1610,7 +1614,7 @@ public:
return static_cast<Expr*>(Argument.Ex);
}
const Expr *getArgumentExpr() const {
- return const_cast<SizeOfAlignOfExpr*>(this)->getArgumentExpr();
+ return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
}
void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
@@ -1636,9 +1640,9 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfAlignOfExprClass;
+ return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
}
- static bool classof(const SizeOfAlignOfExpr *) { return true; }
+ static bool classof(const UnaryExprOrTypeTraitExpr *) { return true; }
// Iterators
child_range children();
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index e5f5a9c056..ba8f6b52af 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1787,7 +1787,7 @@ DEF_TRAVERSE_STMT(OffsetOfExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, {
+DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
// The child-iterator will pick up the arg if it's an expression,
// but not if it's a type.
if (S->isArgumentType())
@@ -1930,7 +1930,7 @@ DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
// Candidates:
//
// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1SizeOfAlignOfExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
// Every class that has getQualifier.
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 982ed25103..2331132507 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2343,14 +2343,18 @@ def err_func_def_incomplete_result : Error<
def ext_sizeof_function_type : Extension<
"invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
def err_sizeof_alignof_overloaded_function_type : Error<
- "invalid application of '%select{sizeof|__alignof}0' to an overloaded "
- "function">;
+ "invalid application of '%select{sizeof|__alignof|vec_step}0' to an "
+ "overloaded function">;
def ext_sizeof_void_type : Extension<
- "invalid application of '%0' to a void type">, InGroup<PointerArith>;
+ "invalid application of '%select{sizeof|__alignof|vec_step}0' to a void "
+ "type">, InGroup<PointerArith>;
def err_sizeof_alignof_incomplete_type : Error<
- "invalid application of '%select{sizeof|__alignof}0' to an incomplete type %1">;
+ "invalid application of '%select{sizeof|__alignof|vec_step}0' to an "
+ "incomplete type %1">;
def err_sizeof_alignof_bitfield : Error<
"invalid application of '%select{sizeof|__alignof}0' to bit-field">;
+def err_vecstep_non_scalar_vector_type : Error<
+ "'vec_step' requires built-in scalar or vector type, %0 invalid">;
def err_offsetof_incomplete_type : Error<
"offsetof of incomplete type %0">;
def err_offsetof_record_type : Error<
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index be0d8ff091..44f6f53939 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -54,7 +54,7 @@ def CharacterLiteral : DStmt<Expr>;
def ParenExpr : DStmt<Expr>;
def UnaryOperator : DStmt<Expr>;
def OffsetOfExpr : DStmt<Expr>;
-def SizeOfAlignOfExpr : DStmt<Expr>;
+def UnaryExprOrTypeTraitExpr : DStmt<Expr>;
def ArraySubscriptExpr : DStmt<Expr>;
def CallExpr : DStmt<Expr>;
def MemberExpr : DStmt<Expr>;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 96a817bdae..c7d9524b41 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -346,9 +346,10 @@ KEYWORD(__fastcall , KEYALL)
KEYWORD(__thiscall , KEYALL)
KEYWORD(__forceinline , KEYALL)
-// OpenCL-specific keywords (see OpenCL 1.1 [6.1.9])
+// OpenCL-specific keywords
KEYWORD(__kernel , KEYOPENCL)
ALIAS("kernel", __kernel , KEYOPENCL)
+KEYWORD(vec_step , KEYOPENCL)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 00c6e9ed50..16a57a5485 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -42,6 +42,13 @@ namespace clang {
BTT_TypeCompatible,
BTT_IsConvertibleTo
};
+
+ /// UnaryExprOrTypeTrait - Names for the "expression or type" traits.
+ enum UnaryExprOrTypeTrait {
+ UETT_SizeOf,
+ UETT_AlignOf,
+ UETT_VecStep
+ };
}
#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 5d667d9b8e..1afc3c94df 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1041,10 +1041,10 @@ private:
}
ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
- ExprResult ParseSizeofAlignofExpression();
+ ExprResult ParseUnaryExprOrTypeTraitExpression();
ExprResult ParseBuiltinPrimaryExpression();
- ExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+ ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
bool &isCastExpr,
ParsedType &CastTy,
SourceRange &CastRange);
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 5935864f38..17e9d3d696 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1990,19 +1990,25 @@ public:
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Op, Expr *Input);
- ExprResult CreateSizeOfAlignOfExpr(TypeSourceInfo *T,
- SourceLocation OpLoc,
- bool isSizeOf, SourceRange R);
- ExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
- bool isSizeOf, SourceRange R);
+ ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *T,
+ SourceLocation OpLoc,
+ UnaryExprOrTypeTrait ExprKind,
+ SourceRange R);
+ ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
+ UnaryExprOrTypeTrait ExprKind,
+ SourceRange R);
ExprResult
- ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
- void *TyOrEx, const SourceRange &ArgRange);
+ ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
+ UnaryExprOrTypeTrait ExprKind,
+ bool isType, void *TyOrEx,
+ const SourceRange &ArgRange);
ExprResult CheckPlaceholderExpr(Expr *E, SourceLocation Loc);
+ bool CheckVecStepExpr(Expr *E, SourceLocation OpLoc, SourceRange R);
- bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
- SourceRange R, bool isSizeof);
+ bool CheckUnaryExprOrTypeTraitOperand(QualType type, SourceLocation OpLoc,
+ SourceRange R,
+ UnaryExprOrTypeTrait ExprKind);
ExprResult ActOnSizeofParameterPackExpr(Scope *S,
SourceLocation OpLoc,
IdentifierInfo &Name,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index e5b76d29f6..7a562482c2 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -339,9 +339,9 @@ public:
void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred,
ExplodedNodeSet& Dst);
- /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
- void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
+ /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
+ void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr* Ex,
+ ExplodedNode* Pred, ExplodedNodeSet& Dst);
/// VisitUnaryOperator - Transfer function logic for unary operators.
void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred,
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 357819a684..b00c78827f 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -139,7 +139,7 @@ namespace {
Expr *VisitCharacterLiteral(CharacterLiteral *E);
Expr *VisitParenExpr(ParenExpr *E);
Expr *VisitUnaryOperator(UnaryOperator *E);
- Expr *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+ Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Expr *VisitBinaryOperator(BinaryOperator *E);
Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
@@ -3799,7 +3799,8 @@ Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
Importer.Import(E->getOperatorLoc()));
}
-Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
+ UnaryExprOrTypeTraitExpr *E) {
QualType ResultType = Importer.Import(E->getType());
if (E->isArgumentType()) {
@@ -3807,8 +3808,8 @@ Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
if (!TInfo)
return 0;
- return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
- TInfo, ResultType,
+ return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
+ TInfo, ResultType,
Importer.Import(E->getOperatorLoc()),
Importer.Import(E->getRParenLoc()));
}
@@ -3817,8 +3818,8 @@ Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
if (!SubExpr)
return 0;
- return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
- SubExpr, ResultType,
+ return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
+ SubExpr, ResultType,
Importer.Import(E->getOperatorLoc()),
Importer.Import(E->getRParenLoc()));
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 99ce611394..4793b114ef 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2854,8 +2854,8 @@ const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); }
// Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===//
-// SizeOfAlignOfExpr
-Stmt::child_range SizeOfAlignOfExpr::children() {
+// UnaryExprOrTypeTraitExpr
+Stmt::child_range UnaryExprOrTypeTraitExpr::children() {
// If this is of a type and the type is a VLA type (and not a typedef), the
// size expression of the VLA needs to be treated as an executable expression.
// Why isn't this weirdness documented better in StmtIterator?
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 890898a985..376792223a 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -128,7 +128,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
// Expressions that are prvalues.
case Expr::CXXBoolLiteralExprClass:
case Expr::CXXPseudoDestructorExprClass:
- case Expr::SizeOfAlignOfExprClass:
+ case Expr::UnaryExprOrTypeTraitExprClass:
case Expr::CXXNewExprClass:
case Expr::CXXThisExprClass:
case Expr::CXXNullPtrLiteralExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index f421671f7f..b6ab33258d 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -290,7 +290,8 @@ public:
bool VisitFloatingLiteral(FloatingLiteral *E) { return false; }
bool VisitStringLiteral(StringLiteral *E) { return false; }
bool VisitCharacterLiteral(CharacterLiteral *E) { return false; }
- bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return false; }
+ bool VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E)
+ { return false; }
bool VisitArraySubscriptExpr(ArraySubscriptExpr *E)
{ return Visit(E->getLHS()) || Visit(E->getRHS()); }
bool VisitChooseExpr(ChooseExpr *E)
@@ -1020,7 +1021,7 @@ public:
bool VisitBinaryConditionalOperator(const BinaryConditionalOperator *E);
bool VisitCastExpr(CastExpr* E);
- bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
+ bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
return Success(E->getValue(), E);
@@ -1601,36 +1602,59 @@ CharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
}
-/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
-/// expression's type.
-bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
- // Handle alignof separately.
- if (!E->isSizeOf()) {
+/// VisitUnaryExprOrTypeTraitExpr - Evaluate a sizeof, alignof or vec_step with
+/// a result as the expression's type.
+bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
+ const UnaryExprOrTypeTraitExpr *E) {
+ switch(E->getKind()) {
+ case UETT_AlignOf: {
if (E->isArgumentType())
return Success(GetAlignOfType(E->getArgumentType()), E);
else
return Success(GetAlignOfExpr(E->getArgumentExpr()), E);
}
- QualType SrcTy = E->getTypeOfArgument();
- // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
- // the result is the size of the referenced type."
- // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
- // result shall be the alignment of the referenced type."
- if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
- SrcTy = Ref->getPointeeType();
+ case UETT_VecStep: {
+ QualType Ty = E->getTypeOfArgument();
- // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
- // extension.
- if (SrcTy->isVoidType() || SrcTy->isFunctionType())
- return Success(1, E);
+ if (Ty->isVectorType()) {
+ unsigned n = Ty->getAs<VectorType>()->getNumElements();
- // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
- if (!SrcTy->isConstantSizeType())
- return false;
+ // The vec_step built-in functions that take a 3-component
+ // vector return 4. (OpenCL 1.1 spec 6.11.12)
+ if (n == 3)
+ n = 4;
+
+ return Success(n, E);
+ } else
+ return Success(1, E);
+ }
+
+ case UETT_SizeOf: {
+ QualType SrcTy = E->getTypeOfArgument();
+ // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
+ // the result is the size of the referenced type."
+ // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
+ // result shall be the alignment of the referenced type."
+ if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
+ SrcTy = Ref->getPointeeType();
- // Get information about the size.
- return Success(Info.Ctx.getTypeSizeInChars(SrcTy), E);
+ // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
+ // extension.
+ if (SrcTy->isVoidType() || SrcTy->isFunctionType())
+ return Success(1, E);
+
+ // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
+ if (!SrcTy->isConstantSizeType())
+ return false;
+
+ // Get information about the size.
+ return Success(Info.Ctx.getTypeSizeInChars(SrcTy), E);
+ }
+ }
+
+ llvm_unreachable("unknown expr/type trait");
+ return false;
}
bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *E) {
@@ -2884,9 +2908,10 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
// are ICEs, the value of the offsetof must be an integer constant.
return CheckEvalInICE(E, Ctx);
}
- case Expr::SizeOfAlignOfExprClass: {
- const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(E);
- if (Exp->isSizeOf() && Exp->getTypeOfArgument()->isVariableArrayType())
+ case Expr::UnaryExprOrTypeTraitExprClass: {
+ const UnaryExprOrTypeTraitExpr *Exp = cast<UnaryExprOrTypeTraitExpr>(E);
+ if ((Exp->getKind() == UETT_SizeOf) &&
+ Exp->getTypeOfArgument()->isVariableArrayType())
return ICEDiag(2, E->getLocStart());
return NoDiag();
}
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 45653e6e7d..bceed08137 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1888,10 +1888,22 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
break;
}
- case Expr::SizeOfAlignOfExprClass: {
- const SizeOfAlignOfExpr *SAE = cast<SizeOfAlignOfExpr>(E);
- if (SAE->isSizeOf()) Out << 's';
- else Out << 'a';
+ case Expr::UnaryExprOrTypeTraitExprClass: {
+ const UnaryExprOrTypeTraitExpr *SAE = cast<UnaryExprOrTypeTraitExpr>(E);
+ switch(SAE->getKind()) {
+ case UETT_SizeOf:
+ Out << 's';
+ break;
+ case UETT_AlignOf:
+ Out << 'a';
+ break;
+ case UETT_VecStep:
+ Diagnostic &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
+ "cannot yet mangle vec_step expression");
+ Diags.Report(DiagID);
+ return;
+ }
if (SAE->isArgumentType()) {
Out << 't';
mangleType(SAE->getArgumentType());
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 5c7dbb3ed9..21ed848967 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -141,7 +141,7 @@ namespace {
void VisitFloatingLiteral(FloatingLiteral *Node);
void VisitStringLiteral(StringLiteral *Str);
void VisitUnaryOperator(UnaryOperator *Node);
- void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
+ void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node);
void VisitMemberExpr(MemberExpr *Node);
void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
void VisitBinaryOperator(BinaryOperator *Node);
@@ -441,9 +441,19 @@ void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) {
OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
<< " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}
-void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+void StmtDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
DumpExpr(Node);
- OS << " " << (Node->isSizeOf() ? "sizeof" : "alignof") << " ";
+ switch(Node->getKind()) {
+ case UETT_SizeOf:
+ OS << " sizeof ";
+ break;
+ case UETT_AlignOf:
+ OS << " __alignof ";
+ break;
+ case UETT_VecStep:
+ OS << " vec_step ";
+ break;
+ }
if (Node->isArgumentType())
DumpType(Node->getArgumentType());
}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 1cdd220881..4f50044116 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -706,8 +706,18 @@ void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
OS << ")";
}
-void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
- OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
+void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
+ switch(Node->getKind()) {
+ case UETT_SizeOf:
+ OS << "sizeof";
+ break;
+ case UETT_AlignOf:
+ OS << "__alignof";
+ break;
+ case UETT_VecStep:
+ OS << "vec_step";
+ break;
+ }
if (Node->isArgumentType())
OS << "(" << Node->getArgumentType().getAsString(Policy) << ")";
else {
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index b54001167b..a506d055b3 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -290,9 +290,9 @@ void StmtProfiler::VisitOffsetOfExpr(OffsetOfExpr *S) {
VisitExpr(S);
}
-void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) {
+void StmtProfiler::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *S) {
VisitExpr(S);
- ID.AddBoolean(S->isSizeOf());
+ ID.AddInteger(S->getKind());
if (S->isArgumentType())
VisitType(S->getArgumentType());
}
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index fa054f66e2..ca7469f677 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -343,7 +343,8 @@ private:
CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
CFGBlock *VisitReturnStmt(ReturnStmt* R);
- CFGBlock *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E, AddStmtChoice asc);
+ CFGBlock *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
+ AddStmtChoice asc);
CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc);
CFGBlock *VisitSwitchStmt(SwitchStmt *S);
CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc);
@@ -951,8 +952,9 @@ tryAgain:
case Stmt::ReturnStmtClass:
return VisitReturnStmt(cast<ReturnStmt>(S));
- case Stmt::SizeOfAlignOfExprClass:
- return VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), asc);
+ case Stmt::UnaryExprOrTypeTraitExprClass:
+ return VisitUnaryExprO