2007-07-11 21:01:13 +04:00
|
|
|
//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 22:59:25 +03:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-07-11 21:01:13 +04:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the Expr class and subclasses.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-08-11 09:35:13 +04:00
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
2007-07-16 03:32:58 +04:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2008-08-11 08:54:23 +04:00
|
|
|
#include "clang/AST/RecordLayout.h"
|
2007-07-11 21:01:13 +04:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2007-11-27 21:22:04 +03:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2007-07-11 21:01:13 +04:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Primary Expressions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-06-08 02:13:43 +04:00
|
|
|
/// getValueAsApproximateDouble - This returns the value as an inaccurate
|
|
|
|
/// double. Note that this may cause loss of precision, but is useful for
|
|
|
|
/// debugging dumps, etc.
|
|
|
|
double FloatingLiteral::getValueAsApproximateDouble() const {
|
|
|
|
llvm::APFloat V = getValue();
|
|
|
|
V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven);
|
|
|
|
return V.convertToDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
|
|
|
|
bool Wide, QualType t, SourceLocation firstLoc,
|
|
|
|
SourceLocation lastLoc) :
|
|
|
|
Expr(StringLiteralClass, t) {
|
|
|
|
// OPTIMIZE: could allocate this appended to the StringLiteral.
|
|
|
|
char *AStrData = new char[byteLength];
|
|
|
|
memcpy(AStrData, strData, byteLength);
|
|
|
|
StrData = AStrData;
|
|
|
|
ByteLength = byteLength;
|
|
|
|
IsWide = Wide;
|
|
|
|
firstTokLoc = firstLoc;
|
|
|
|
lastTokLoc = lastLoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
StringLiteral::~StringLiteral() {
|
|
|
|
delete[] StrData;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnaryOperator::isPostfix(Opcode Op) {
|
|
|
|
switch (Op) {
|
|
|
|
case PostInc:
|
|
|
|
case PostDec:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-24 02:18:43 +04:00
|
|
|
bool UnaryOperator::isPrefix(Opcode Op) {
|
|
|
|
switch (Op) {
|
|
|
|
case PreInc:
|
|
|
|
case PreDec:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
|
|
|
/// corresponds to, e.g. "sizeof" or "[pre]++".
|
|
|
|
const char *UnaryOperator::getOpcodeStr(Opcode Op) {
|
|
|
|
switch (Op) {
|
|
|
|
default: assert(0 && "Unknown unary operator");
|
|
|
|
case PostInc: return "++";
|
|
|
|
case PostDec: return "--";
|
|
|
|
case PreInc: return "++";
|
|
|
|
case PreDec: return "--";
|
|
|
|
case AddrOf: return "&";
|
|
|
|
case Deref: return "*";
|
|
|
|
case Plus: return "+";
|
|
|
|
case Minus: return "-";
|
|
|
|
case Not: return "~";
|
|
|
|
case LNot: return "!";
|
|
|
|
case Real: return "__real";
|
|
|
|
case Imag: return "__imag";
|
|
|
|
case SizeOf: return "sizeof";
|
|
|
|
case AlignOf: return "alignof";
|
|
|
|
case Extension: return "__extension__";
|
2007-08-30 21:45:32 +04:00
|
|
|
case OffsetOf: return "__builtin_offsetof";
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Postfix Operators.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-01-17 20:46:27 +03:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
|
|
|
|
SourceLocation rparenloc)
|
2007-08-24 22:13:47 +04:00
|
|
|
: Expr(CallExprClass, t), NumArgs(numargs) {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
SubExprs = new Stmt*[numargs+1];
|
2007-08-24 22:13:47 +04:00
|
|
|
SubExprs[FN] = fn;
|
2007-07-11 21:01:13 +04:00
|
|
|
for (unsigned i = 0; i != numargs; ++i)
|
2007-08-24 22:13:47 +04:00
|
|
|
SubExprs[i+ARGS_START] = args[i];
|
2007-07-11 21:01:13 +04:00
|
|
|
RParenLoc = rparenloc;
|
|
|
|
}
|
|
|
|
|
2007-12-28 08:25:02 +03:00
|
|
|
/// setNumArgs - This changes the number of arguments present in this call.
|
|
|
|
/// Any orphaned expressions are deleted by this, and any new operands are set
|
|
|
|
/// to null.
|
|
|
|
void CallExpr::setNumArgs(unsigned NumArgs) {
|
|
|
|
// No change, just return.
|
|
|
|
if (NumArgs == getNumArgs()) return;
|
|
|
|
|
|
|
|
// If shrinking # arguments, just delete the extras and forgot them.
|
|
|
|
if (NumArgs < getNumArgs()) {
|
|
|
|
for (unsigned i = NumArgs, e = getNumArgs(); i != e; ++i)
|
|
|
|
delete getArg(i);
|
|
|
|
this->NumArgs = NumArgs;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, we are growing the # arguments. New an bigger argument array.
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt **NewSubExprs = new Stmt*[NumArgs+1];
|
2007-12-28 08:25:02 +03:00
|
|
|
// Copy over args.
|
|
|
|
for (unsigned i = 0; i != getNumArgs()+ARGS_START; ++i)
|
|
|
|
NewSubExprs[i] = SubExprs[i];
|
|
|
|
// Null out new args.
|
|
|
|
for (unsigned i = getNumArgs()+ARGS_START; i != NumArgs+ARGS_START; ++i)
|
|
|
|
NewSubExprs[i] = 0;
|
|
|
|
|
|
|
|
delete[] SubExprs;
|
|
|
|
SubExprs = NewSubExprs;
|
|
|
|
this->NumArgs = NumArgs;
|
|
|
|
}
|
|
|
|
|
2008-01-31 04:07:12 +03:00
|
|
|
bool CallExpr::isBuiltinConstantExpr() const {
|
|
|
|
// All simple function calls (e.g. func()) are implicitly cast to pointer to
|
|
|
|
// function. As a result, we try and obtain the DeclRefExpr from the
|
|
|
|
// ImplicitCastExpr.
|
|
|
|
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());
|
|
|
|
if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
|
|
|
|
if (!DRE)
|
|
|
|
return false;
|
|
|
|
|
2008-01-31 05:13:57 +03:00
|
|
|
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
|
|
|
|
if (!FDecl)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
unsigned builtinID = FDecl->getIdentifier()->getBuiltinID();
|
|
|
|
if (!builtinID)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// We have a builtin that is a constant expression
|
2008-05-16 17:28:37 +04:00
|
|
|
return builtinID == Builtin::BI__builtin___CFStringMakeConstantString ||
|
|
|
|
builtinID == Builtin::BI__builtin_classify_type;
|
2008-01-31 04:07:12 +03:00
|
|
|
}
|
2007-12-28 08:25:02 +03:00
|
|
|
|
2007-08-09 02:15:55 +04:00
|
|
|
bool CallExpr::isBuiltinClassifyType(llvm::APSInt &Result) const {
|
|
|
|
// The following enum mimics gcc's internal "typeclass.h" file.
|
|
|
|
enum gcc_type_class {
|
|
|
|
no_type_class = -1,
|
|
|
|
void_type_class, integer_type_class, char_type_class,
|
|
|
|
enumeral_type_class, boolean_type_class,
|
|
|
|
pointer_type_class, reference_type_class, offset_type_class,
|
|
|
|
real_type_class, complex_type_class,
|
|
|
|
function_type_class, method_type_class,
|
|
|
|
record_type_class, union_type_class,
|
|
|
|
array_type_class, string_type_class,
|
|
|
|
lang_type_class
|
|
|
|
};
|
|
|
|
Result.setIsSigned(true);
|
|
|
|
|
|
|
|
// All simple function calls (e.g. func()) are implicitly cast to pointer to
|
|
|
|
// function. As a result, we try and obtain the DeclRefExpr from the
|
|
|
|
// ImplicitCastExpr.
|
|
|
|
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());
|
|
|
|
if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).
|
|
|
|
return false;
|
|
|
|
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
|
|
|
|
if (!DRE)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// We have a DeclRefExpr.
|
|
|
|
if (strcmp(DRE->getDecl()->getName(), "__builtin_classify_type") == 0) {
|
|
|
|
// If no argument was supplied, default to "no_type_class". This isn't
|
|
|
|
// ideal, however it's what gcc does.
|
|
|
|
Result = static_cast<uint64_t>(no_type_class);
|
|
|
|
if (NumArgs >= 1) {
|
|
|
|
QualType argType = getArg(0)->getType();
|
|
|
|
|
|
|
|
if (argType->isVoidType())
|
|
|
|
Result = void_type_class;
|
|
|
|
else if (argType->isEnumeralType())
|
|
|
|
Result = enumeral_type_class;
|
|
|
|
else if (argType->isBooleanType())
|
|
|
|
Result = boolean_type_class;
|
|
|
|
else if (argType->isCharType())
|
|
|
|
Result = string_type_class; // gcc doesn't appear to use char_type_class
|
|
|
|
else if (argType->isIntegerType())
|
|
|
|
Result = integer_type_class;
|
|
|
|
else if (argType->isPointerType())
|
|
|
|
Result = pointer_type_class;
|
|
|
|
else if (argType->isReferenceType())
|
|
|
|
Result = reference_type_class;
|
|
|
|
else if (argType->isRealType())
|
|
|
|
Result = real_type_class;
|
|
|
|
else if (argType->isComplexType())
|
|
|
|
Result = complex_type_class;
|
|
|
|
else if (argType->isFunctionType())
|
|
|
|
Result = function_type_class;
|
|
|
|
else if (argType->isStructureType())
|
|
|
|
Result = record_type_class;
|
|
|
|
else if (argType->isUnionType())
|
|
|
|
Result = union_type_class;
|
|
|
|
else if (argType->isArrayType())
|
|
|
|
Result = array_type_class;
|
|
|
|
else if (argType->isUnionType())
|
|
|
|
Result = union_type_class;
|
|
|
|
else // FIXME: offset_type_class, method_type_class, & lang_type_class?
|
2007-11-08 20:56:40 +03:00
|
|
|
assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
|
2007-08-09 02:15:55 +04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
|
|
|
/// corresponds to, e.g. "<<=".
|
|
|
|
const char *BinaryOperator::getOpcodeStr(Opcode Op) {
|
|
|
|
switch (Op) {
|
|
|
|
default: assert(0 && "Unknown binary operator");
|
|
|
|
case Mul: return "*";
|
|
|
|
case Div: return "/";
|
|
|
|
case Rem: return "%";
|
|
|
|
case Add: return "+";
|
|
|
|
case Sub: return "-";
|
|
|
|
case Shl: return "<<";
|
|
|
|
case Shr: return ">>";
|
|
|
|
case LT: return "<";
|
|
|
|
case GT: return ">";
|
|
|
|
case LE: return "<=";
|
|
|
|
case GE: return ">=";
|
|
|
|
case EQ: return "==";
|
|
|
|
case NE: return "!=";
|
|
|
|
case And: return "&";
|
|
|
|
case Xor: return "^";
|
|
|
|
case Or: return "|";
|
|
|
|
case LAnd: return "&&";
|
|
|
|
case LOr: return "||";
|
|
|
|
case Assign: return "=";
|
|
|
|
case MulAssign: return "*=";
|
|
|
|
case DivAssign: return "/=";
|
|
|
|
case RemAssign: return "%=";
|
|
|
|
case AddAssign: return "+=";
|
|
|
|
case SubAssign: return "-=";
|
|
|
|
case ShlAssign: return "<<=";
|
|
|
|
case ShrAssign: return ">>=";
|
|
|
|
case AndAssign: return "&=";
|
|
|
|
case XorAssign: return "^=";
|
|
|
|
case OrAssign: return "|=";
|
|
|
|
case Comma: return ",";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-31 08:56:16 +04:00
|
|
|
InitListExpr::InitListExpr(SourceLocation lbraceloc,
|
|
|
|
Expr **initexprs, unsigned numinits,
|
|
|
|
SourceLocation rbraceloc)
|
2008-05-01 06:04:18 +04:00
|
|
|
: Expr(InitListExprClass, QualType()),
|
|
|
|
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc)
|
2007-08-31 08:56:16 +04:00
|
|
|
{
|
|
|
|
for (unsigned i = 0; i != numinits; i++)
|
2008-05-01 06:04:18 +04:00
|
|
|
InitExprs.push_back(initexprs[i]);
|
2007-08-31 08:56:16 +04:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Generic Expression Routines
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// hasLocalSideEffect - Return true if this immediate expression has side
|
|
|
|
/// effects, not counting any sub-expressions.
|
|
|
|
bool Expr::hasLocalSideEffect() const {
|
|
|
|
switch (getStmtClass()) {
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
case ParenExprClass:
|
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->hasLocalSideEffect();
|
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator *UO = cast<UnaryOperator>(this);
|
|
|
|
|
|
|
|
switch (UO->getOpcode()) {
|
|
|
|
default: return false;
|
|
|
|
case UnaryOperator::PostInc:
|
|
|
|
case UnaryOperator::PostDec:
|
|
|
|
case UnaryOperator::PreInc:
|
|
|
|
case UnaryOperator::PreDec:
|
|
|
|
return true; // ++/--
|
|
|
|
|
|
|
|
case UnaryOperator::Deref:
|
|
|
|
// Dereferencing a volatile pointer is a side-effect.
|
|
|
|
return getType().isVolatileQualified();
|
|
|
|
case UnaryOperator::Real:
|
|
|
|
case UnaryOperator::Imag:
|
|
|
|
// accessing a piece of a volatile complex is a side-effect.
|
|
|
|
return UO->getSubExpr()->getType().isVolatileQualified();
|
|
|
|
|
|
|
|
case UnaryOperator::Extension:
|
|
|
|
return UO->getSubExpr()->hasLocalSideEffect();
|
|
|
|
}
|
|
|
|
}
|
2007-12-01 09:07:34 +03:00
|
|
|
case BinaryOperatorClass: {
|
|
|
|
const BinaryOperator *BinOp = cast<BinaryOperator>(this);
|
|
|
|
// Consider comma to have side effects if the LHS and RHS both do.
|
|
|
|
if (BinOp->getOpcode() == BinaryOperator::Comma)
|
|
|
|
return BinOp->getLHS()->hasLocalSideEffect() &&
|
|
|
|
BinOp->getRHS()->hasLocalSideEffect();
|
|
|
|
|
|
|
|
return BinOp->isAssignmentOp();
|
|
|
|
}
|
2007-08-25 06:00:02 +04:00
|
|
|
case CompoundAssignOperatorClass:
|
2007-08-25 05:55:00 +04:00
|
|
|
return true;
|
2007-07-11 21:01:13 +04:00
|
|
|
|
2007-12-01 22:58:28 +03:00
|
|
|
case ConditionalOperatorClass: {
|
|
|
|
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
|
|
|
return Exp->getCond()->hasLocalSideEffect()
|
|
|
|
|| (Exp->getLHS() && Exp->getLHS()->hasLocalSideEffect())
|
|
|
|
|| (Exp->getRHS() && Exp->getRHS()->hasLocalSideEffect());
|
|
|
|
}
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
case MemberExprClass:
|
|
|
|
case ArraySubscriptExprClass:
|
|
|
|
// If the base pointer or element is to a volatile pointer/field, accessing
|
|
|
|
// if is a side effect.
|
|
|
|
return getType().isVolatileQualified();
|
2008-05-27 19:24:04 +04:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
case CallExprClass:
|
|
|
|
// TODO: check attributes for pure/const. "void foo() { strlen("bar"); }"
|
|
|
|
// should warn.
|
|
|
|
return true;
|
2007-09-27 02:06:30 +04:00
|
|
|
case ObjCMessageExprClass:
|
|
|
|
return true;
|
2008-07-26 23:51:01 +04:00
|
|
|
case StmtExprClass: {
|
|
|
|
// Statement exprs don't logically have side effects themselves, but are
|
|
|
|
// sometimes used in macros in ways that give them a type that is unused.
|
|
|
|
// For example ({ blah; foo(); }) will end up with a type if foo has a type.
|
|
|
|
// however, if the result of the stmt expr is dead, we don't want to emit a
|
|
|
|
// warning.
|
|
|
|
const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
|
|
|
|
if (!CS->body_empty())
|
|
|
|
if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
|
|
|
|
return E->hasLocalSideEffect();
|
|
|
|
return false;
|
|
|
|
}
|
2008-08-19 03:01:59 +04:00
|
|
|
case ExplicitCastExprClass:
|
2008-08-22 19:38:55 +04:00
|
|
|
case CXXFunctionalCastExprClass:
|
2007-07-11 21:01:13 +04:00
|
|
|
// If this is a cast to void, check the operand. Otherwise, the result of
|
|
|
|
// the cast is unused.
|
|
|
|
if (getType()->isVoidType())
|
|
|
|
return cast<CastExpr>(this)->getSubExpr()->hasLocalSideEffect();
|
|
|
|
return false;
|
2008-04-08 08:40:51 +04:00
|
|
|
|
2008-05-20 01:24:43 +04:00
|
|
|
case ImplicitCastExprClass:
|
|
|
|
// Check the operand, since implicit casts are inserted by Sema
|
|
|
|
return cast<ImplicitCastExpr>(this)->getSubExpr()->hasLocalSideEffect();
|
|
|
|
|
2008-04-08 08:40:51 +04:00
|
|
|
case CXXDefaultArgExprClass:
|
|
|
|
return cast<CXXDefaultArgExpr>(this)->getExpr()->hasLocalSideEffect();
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or an
|
|
|
|
/// incomplete type other than void. Nonarray expressions that can be lvalues:
|
|
|
|
/// - name, where name must be a variable
|
|
|
|
/// - e[i]
|
|
|
|
/// - (e), where e must be an lvalue
|
|
|
|
/// - e.name, where e must be an lvalue
|
|
|
|
/// - e->name
|
|
|
|
/// - *e, the type of e cannot be a function type
|
|
|
|
/// - string-constant
|
2007-10-31 01:53:42 +03:00
|
|
|
/// - (__real__ e) and (__imag__ e) where e is an lvalue [GNU extension]
|
2007-07-17 07:52:31 +04:00
|
|
|
/// - reference type [C++ [expr]]
|
2007-07-11 21:01:13 +04:00
|
|
|
///
|
2008-07-27 01:30:36 +04:00
|
|
|
Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
|
2007-07-11 21:01:13 +04:00
|
|
|
// first, check the type (C99 6.3.2.1)
|
2007-07-21 09:33:26 +04:00
|
|
|
if (TR->isFunctionType()) // from isObjectType()
|
2007-07-11 21:01:13 +04:00
|
|
|
return LV_NotObjectType;
|
|
|
|
|
2008-02-10 04:39:04 +03:00
|
|
|
// Allow qualified void which is an incomplete type other than void (yuck).
|
2008-07-27 01:30:36 +04:00
|
|
|
if (TR->isVoidType() && !Ctx.getCanonicalType(TR).getCVRQualifiers())
|
2008-02-10 04:39:04 +03:00
|
|
|
return LV_IncompleteVoidType;
|
|
|
|
|
2007-07-21 09:33:26 +04:00
|
|
|
if (TR->isReferenceType()) // C++ [expr]
|
2007-07-17 07:52:31 +04:00
|
|
|
return LV_Valid;
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// the type looks fine, now check the expression
|
|
|
|
switch (getStmtClass()) {
|
|
|
|
case StringLiteralClass: // C99 6.5.1p4
|
2007-12-01 01:47:59 +03:00
|
|
|
return LV_Valid;
|
2007-07-11 21:01:13 +04:00
|
|
|
case ArraySubscriptExprClass: // C99 6.5.3p4 (e1[e2] == (*((e1)+(e2))))
|
|
|
|
// For vectors, make sure base is an lvalue (i.e. not a function call).
|
|
|
|
if (cast<ArraySubscriptExpr>(this)->getBase()->getType()->isVectorType())
|
2008-07-27 01:30:36 +04:00
|
|
|
return cast<ArraySubscriptExpr>(this)->getBase()->isLvalue(Ctx);
|
2007-07-11 21:01:13 +04:00
|
|
|
return LV_Valid;
|
2008-06-17 22:05:57 +04:00
|
|
|
case DeclRefExprClass: { // C99 6.5.1p2
|
|
|
|
const Decl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
|
|
|
|
if (isa<VarDecl>(RefdDecl) || isa<ImplicitParamDecl>(RefdDecl))
|
2007-07-11 21:01:13 +04:00
|
|
|
return LV_Valid;
|
|
|
|
break;
|
2008-06-17 22:05:57 +04:00
|
|
|
}
|
2007-07-12 19:26:50 +04:00
|
|
|
case MemberExprClass: { // C99 6.5.2.3p4
|
2007-07-11 21:01:13 +04:00
|
|
|
const MemberExpr *m = cast<MemberExpr>(this);
|
2008-07-27 01:30:36 +04:00
|
|
|
return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
|
2007-07-12 19:26:50 +04:00
|
|
|
}
|
2007-10-31 01:53:42 +03:00
|
|
|
case UnaryOperatorClass:
|
2007-07-11 21:01:13 +04:00
|
|
|
if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Deref)
|
2007-10-31 01:53:42 +03:00
|
|
|
return LV_Valid; // C99 6.5.3p4
|
|
|
|
|
|
|
|
if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Real ||
|
2008-07-25 22:07:19 +04:00
|
|
|
cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Imag ||
|
|
|
|
cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Extension)
|
2008-07-27 01:30:36 +04:00
|
|
|
return cast<UnaryOperator>(this)->getSubExpr()->isLvalue(Ctx); // GNU.
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case ParenExprClass: // C99 6.5.1p5
|
2008-07-27 01:30:36 +04:00
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->isLvalue(Ctx);
|
2007-12-05 07:00:10 +03:00
|
|
|
case CompoundLiteralExprClass: // C99 6.5.2.5p5
|
|
|
|
return LV_Valid;
|
2008-04-19 03:10:10 +04:00
|
|
|
case ExtVectorElementExprClass:
|
|
|
|
if (cast<ExtVectorElementExpr>(this)->containsDuplicateElements())
|
2007-07-30 07:29:09 +04:00
|
|
|
return LV_DuplicateVectorComponents;
|
|
|
|
return LV_Valid;
|
2007-11-12 17:34:27 +03:00
|
|
|
case ObjCIvarRefExprClass: // ObjC instance variables are lvalues.
|
|
|
|
return LV_Valid;
|
2008-05-31 03:23:16 +04:00
|
|
|
case ObjCPropertyRefExprClass: // FIXME: check if read-only property.
|
|
|
|
return LV_Valid;
|
2008-08-10 05:53:14 +04:00
|
|
|
case PredefinedExprClass:
|
|
|
|
return (cast<PredefinedExpr>(this)->getIdentType()
|
|
|
|
== PredefinedExpr::CXXThis
|
2008-07-26 03:30:42 +04:00
|
|
|
? LV_InvalidExpression : LV_Valid);
|
2008-04-08 08:40:51 +04:00
|
|
|
case CXXDefaultArgExprClass:
|
2008-07-27 01:30:36 +04:00
|
|
|
return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
|
2007-07-11 21:01:13 +04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return LV_InvalidExpression;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
|
|
|
|
/// does not have an incomplete type, does not have a const-qualified type, and
|
|
|
|
/// if it is a structure or union, does not have any member (including,
|
|
|
|
/// recursively, any member or element of all contained aggregates or unions)
|
|
|
|
/// with a const-qualified type.
|
2008-07-27 01:30:36 +04:00
|
|
|
Expr::isModifiableLvalueResult Expr::isModifiableLvalue(ASTContext &Ctx) const {
|
|
|
|
isLvalueResult lvalResult = isLvalue(Ctx);
|
2007-07-11 21:01:13 +04:00
|
|
|
|
|
|
|
switch (lvalResult) {
|
|
|
|
case LV_Valid: break;
|
|
|
|
case LV_NotObjectType: return MLV_NotObjectType;
|
|
|
|
case LV_IncompleteVoidType: return MLV_IncompleteVoidType;
|
2007-07-30 07:29:09 +04:00
|
|
|
case LV_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
|
2007-07-11 21:01:13 +04:00
|
|
|
case LV_InvalidExpression: return MLV_InvalidExpression;
|
|
|
|
}
|
2008-08-04 11:31:14 +04:00
|
|
|
|
|
|
|
QualType CT = Ctx.getCanonicalType(getType());
|
|
|
|
|
|
|
|
if (CT.isConstQualified())
|
2007-07-11 21:01:13 +04:00
|
|
|
return MLV_ConstQualified;
|
2008-08-04 11:31:14 +04:00
|
|
|
if (CT->isArrayType())
|
2007-07-11 21:01:13 +04:00
|
|
|
return MLV_ArrayType;
|
2008-08-04 11:31:14 +04:00
|
|
|
if (CT->isIncompleteType())
|
2007-07-11 21:01:13 +04:00
|
|
|
return MLV_IncompleteType;
|
|
|
|
|
2008-08-04 11:31:14 +04:00
|
|
|
if (const RecordType *r = CT->getAsRecordType()) {
|
2007-07-11 21:01:13 +04:00
|
|
|
if (r->hasConstFields())
|
|
|
|
return MLV_ConstQualified;
|
|
|
|
}
|
|
|
|
return MLV_Valid;
|
|
|
|
}
|
|
|
|
|
2008-02-27 21:39:48 +03:00
|
|
|
/// hasGlobalStorage - Return true if this expression has static storage
|
2007-11-28 00:35:27 +03:00
|
|
|
/// duration. This means that the address of this expression is a link-time
|
|
|
|
/// constant.
|
2008-02-27 21:39:48 +03:00
|
|
|
bool Expr::hasGlobalStorage() const {
|
2007-11-13 21:05:45 +03:00
|
|
|
switch (getStmtClass()) {
|
|
|
|
default:
|
|
|
|
return false;
|
2007-11-28 00:35:27 +03:00
|
|
|
case ParenExprClass:
|
2008-02-27 21:39:48 +03:00
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->hasGlobalStorage();
|
2007-11-28 00:35:27 +03:00
|
|
|
case ImplicitCastExprClass:
|
2008-02-27 21:39:48 +03:00
|
|
|
return cast<ImplicitCastExpr>(this)->getSubExpr()->hasGlobalStorage();
|
2008-01-14 21:19:28 +03:00
|
|
|
case CompoundLiteralExprClass:
|
|
|
|
return cast<CompoundLiteralExpr>(this)->isFileScope();
|
2007-11-13 21:05:45 +03:00
|
|
|
case DeclRefExprClass: {
|
|
|
|
const Decl *D = cast<DeclRefExpr>(this)->getDecl();
|
|
|
|
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
|
2008-02-27 21:39:48 +03:00
|
|
|
return VD->hasGlobalStorage();
|
2008-04-04 13:45:30 +04:00
|
|
|
if (isa<FunctionDecl>(D))
|
|
|
|
return true;
|
2007-11-13 21:05:45 +03:00
|
|
|
return false;
|
|
|
|
}
|
2007-11-28 07:30:09 +03:00
|
|
|
case MemberExprClass: {
|
2007-11-13 21:05:45 +03:00
|
|
|
const MemberExpr *M = cast<MemberExpr>(this);
|
2008-02-27 21:39:48 +03:00
|
|
|
return !M->isArrow() && M->getBase()->hasGlobalStorage();
|
2007-11-28 07:30:09 +03:00
|
|
|
}
|
2007-11-28 00:35:27 +03:00
|
|
|
case ArraySubscriptExprClass:
|
2008-02-27 21:39:48 +03:00
|
|
|
return cast<ArraySubscriptExpr>(this)->getBase()->hasGlobalStorage();
|
2008-08-10 05:53:14 +04:00
|
|
|
case PredefinedExprClass:
|
2008-01-12 11:14:25 +03:00
|
|
|
return true;
|
2008-04-08 08:40:51 +04:00
|
|
|
case CXXDefaultArgExprClass:
|
|
|
|
return cast<CXXDefaultArgExpr>(this)->getExpr()->hasGlobalStorage();
|
2007-11-13 21:05:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-17 19:57:34 +03:00
|
|
|
Expr* Expr::IgnoreParens() {
|
|
|
|
Expr* E = this;
|
|
|
|
while (ParenExpr* P = dyn_cast<ParenExpr>(E))
|
|
|
|
E = P->getSubExpr();
|
|
|
|
|
|
|
|
return E;
|
|
|
|
}
|
|
|
|
|
2008-02-13 04:02:39 +03:00
|
|
|
/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
|
|
|
|
/// or CastExprs or ImplicitCastExprs, returning their operand.
|
|
|
|
Expr *Expr::IgnoreParenCasts() {
|
|
|
|
Expr *E = this;
|
|
|
|
while (true) {
|
|
|
|
if (ParenExpr *P = dyn_cast<ParenExpr>(E))
|
|
|
|
E = P->getSubExpr();
|
|
|
|
else if (CastExpr *P = dyn_cast<CastExpr>(E))
|
|
|
|
E = P->getSubExpr();
|
|
|
|
else
|
|
|
|
return E;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-03 00:30:18 +04:00
|
|
|
bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
|
|
|
|
switch (getStmtClass()) {
|
|
|
|
default:
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
case ParenExprClass:
|
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->isConstantExpr(Ctx, Loc);
|
|
|
|
case StringLiteralClass:
|
2007-11-09 18:00:03 +03:00
|
|
|
case ObjCStringLiteralClass:
|
2007-09-03 00:30:18 +04:00
|
|
|
case FloatingLiteralClass:
|
|
|
|
case IntegerLiteralClass:
|
|
|
|
case CharacterLiteralClass:
|
|
|
|
case ImaginaryLiteralClass:
|
2007-10-17 04:52:43 +04:00
|
|
|
case TypesCompatibleExprClass:
|
|
|
|
case CXXBoolLiteralExprClass:
|
2008-08-23 22:49:32 +04:00
|
|
|
case AddrLabelExprClass:
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
case CallExprClass: {
|
|
|
|
const CallExpr *CE = cast<CallExpr>(this);
|
2008-01-31 04:07:12 +03:00
|
|
|
if (CE->isBuiltinConstantExpr())
|
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2007-11-01 05:45:17 +03:00
|
|
|
case DeclRefExprClass: {
|
|
|
|
const Decl *D = cast<DeclRefExpr>(this)->getDecl();
|
|
|
|
// Accept address of function.
|
|
|
|
if (isa<EnumConstantDecl>(D) || isa<FunctionDecl>(D))
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
if (Loc) *Loc = getLocStart();
|
2007-11-13 21:05:45 +03:00
|
|
|
if (isa<VarDecl>(D))
|
|
|
|
return TR->isArrayType();
|
2007-09-03 00:30:18 +04:00
|
|
|
return false;
|
2007-11-01 05:45:17 +03:00
|
|
|
}
|
2008-01-09 03:05:37 +03:00
|
|
|
case CompoundLiteralExprClass:
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
// Allow "(int []){2,4}", since the array will be converted to a pointer.
|
2008-01-25 08:34:48 +03:00
|
|
|
// Allow "(vector type){2,4}" since the elements are all constant.
|
|
|
|
return TR->isArrayType() || TR->isVectorType();
|
2007-09-03 00:30:18 +04:00
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator *Exp = cast<UnaryOperator>(this);
|
|
|
|
|
2007-11-13 21:05:45 +03:00
|
|
|
// C99 6.6p9
|
2007-12-12 02:11:17 +03:00
|
|
|
if (Exp->getOpcode() == UnaryOperator::AddrOf) {
|
2008-02-27 21:39:48 +03:00
|
|
|
if (!Exp->getSubExpr()->hasGlobalStorage()) {
|
2007-12-12 02:11:17 +03:00
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2007-11-13 21:05:45 +03:00
|
|
|
|
2007-09-03 00:30:18 +04:00
|
|
|
// Get the operand value. If this is sizeof/alignof, do not evalute the
|
|
|
|
// operand. This affects C99 6.6p3.
|
2008-01-11 01:15:12 +03:00
|
|
|
if (!Exp->isSizeOfAlignOfOp() &&
|
|
|
|
Exp->getOpcode() != UnaryOperator::OffsetOf &&
|
2007-09-03 00:30:18 +04:00
|
|
|
!Exp->getSubExpr()->isConstantExpr(Ctx, Loc))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (Exp->getOpcode()) {
|
|
|
|
// Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
|
|
|
|
// See C99 6.6p3.
|
|
|
|
default:
|
|
|
|
if (Loc) *Loc = Exp->getOperatorLoc();
|
|
|
|
return false;
|
|
|
|
case UnaryOperator::Extension:
|
|
|
|
return true; // FIXME: this is wrong.
|
|
|
|
case UnaryOperator::SizeOf:
|
|
|
|
case UnaryOperator::AlignOf:
|
2008-01-11 01:15:12 +03:00
|
|
|
case UnaryOperator::OffsetOf:
|
2007-09-03 00:30:18 +04:00
|
|
|
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
2008-02-15 15:20:59 +03:00
|
|
|
if (!Exp->getSubExpr()->getType()->isConstantSizeType()) {
|
2007-12-18 10:15:40 +03:00
|
|
|
if (Loc) *Loc = Exp->getOperatorLoc();
|
2007-09-03 00:30:18 +04:00
|
|
|
return false;
|
2007-12-18 10:15:40 +03:00
|
|
|
}
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
case UnaryOperator::LNot:
|
|
|
|
case UnaryOperator::Plus:
|
|
|
|
case UnaryOperator::Minus:
|
|
|
|
case UnaryOperator::Not:
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
case SizeOfAlignOfTypeExprClass: {
|
|
|
|
const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
|
|
|
|
// alignof always evaluates to a constant.
|
2008-02-21 08:45:29 +03:00
|
|
|
if (Exp->isSizeOf() && !Exp->getArgumentType()->isVoidType() &&
|
|
|
|
!Exp->getArgumentType()->isConstantSizeType()) {
|
2007-12-18 10:15:40 +03:00
|
|
|
if (Loc) *Loc = Exp->getOperatorLoc();
|
2007-09-03 00:30:18 +04:00
|
|
|
return false;
|
2007-12-18 10:15:40 +03:00
|
|
|
}
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
}
|
|
|
|
case BinaryOperatorClass: {
|
|
|
|
const BinaryOperator *Exp = cast<BinaryOperator>(this);
|
|
|
|
|
|
|
|
// The LHS of a constant expr is always evaluated and needed.
|
|
|
|
if (!Exp->getLHS()->isConstantExpr(Ctx, Loc))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!Exp->getRHS()->isConstantExpr(Ctx, Loc))
|
|
|
|
return false;
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
}
|
|
|
|
case ImplicitCastExprClass:
|
2008-08-22 19:38:55 +04:00
|
|
|
case ExplicitCastExprClass:
|
|
|
|
case CXXFunctionalCastExprClass: {
|
2008-08-19 03:01:59 +04:00
|
|
|
const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
|
|
|
|
SourceLocation CastLoc = getLocStart();
|
2007-09-03 00:30:18 +04:00
|
|
|
if (!SubExpr->isConstantExpr(Ctx, Loc)) {
|
|
|
|
if (Loc) *Loc = SubExpr->getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
}
|
|
|
|
case ConditionalOperatorClass: {
|
|
|
|
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
2007-10-18 04:20:32 +04:00
|
|
|
if (!Exp->getCond()->isConstantExpr(Ctx, Loc) ||
|
2007-11-30 22:04:31 +03:00
|
|
|
// Handle the GNU extension for missing LHS.
|
|
|
|
!(Exp->getLHS() && Exp->getLHS()->isConstantExpr(Ctx, Loc)) ||
|
2007-10-18 04:20:32 +04:00
|
|
|
!Exp->getRHS()->isConstantExpr(Ctx, Loc))
|
2007-09-03 00:30:18 +04:00
|
|
|
return false;
|
2007-10-18 04:20:32 +04:00
|
|
|
return true;
|
2007-09-03 00:30:18 +04:00
|
|
|
}
|
2008-01-11 01:15:12 +03:00
|
|
|
case InitListExprClass: {
|
|
|
|
const InitListExpr *Exp = cast<InitListExpr>(this);
|
|
|
|
unsigned numInits = Exp->getNumInits();
|
|
|
|
for (unsigned i = 0; i < numInits; i++) {
|
|
|
|
if (!Exp->getInit(i)->isConstantExpr(Ctx, Loc)) {
|
|
|
|
if (Loc) *Loc = Exp->getInit(i)->getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2008-04-08 08:40:51 +04:00
|
|
|
case CXXDefaultArgExprClass:
|
|
|
|
return cast<CXXDefaultArgExpr>(this)->getExpr()->isConstantExpr(Ctx, Loc);
|
2007-09-03 00:30:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
/// isIntegerConstantExpr - this recursive routine will test if an expression is
|
|
|
|
/// an integer constant expression. Note: With the introduction of VLA's in
|
|
|
|
/// C99 the result of the sizeof operator is no longer always a constant
|
|
|
|
/// expression. The generalization of the wording to include any subexpression
|
|
|
|
/// that is not evaluated (C99 6.6p3) means that nonconstant subexpressions
|
|
|
|
/// can appear as operands to other operators (e.g. &&, ||, ?:). For instance,
|
2008-07-09 01:13:06 +04:00
|
|
|
/// "0 || f()" can be treated as a constant expression. In C90 this expression,
|
2007-07-11 21:01:13 +04:00
|
|
|
/// occurring in a context requiring a constant, would have been a constraint
|
|
|
|
/// violation. FIXME: This routine currently implements C90 semantics.
|
|
|
|
/// To properly implement C99 semantics this routine will need to evaluate
|
|
|
|
/// expressions involving operators previously mentioned.
|
|
|
|
|
|
|
|
/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero,
|
|
|
|
/// comma, etc
|
|
|
|
///
|
|
|
|
/// FIXME: This should ext-warn on overflow during evaluation! ISO C does not
|
2007-09-26 04:47:26 +04:00
|
|
|
/// permit this. This includes things like (int)1e1000
|
2007-07-18 09:21:20 +04:00
|
|
|
///
|
|
|
|
/// FIXME: Handle offsetof. Two things to do: Handle GCC's __builtin_offsetof
|
|
|
|
/// to support gcc 4.0+ and handle the idiom GCC recognizes with a null pointer
|
|
|
|
/// cast+dereference.
|
2007-07-16 03:26:56 +04:00
|
|
|
bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
|
|
|
|
SourceLocation *Loc, bool isEvaluated) const {
|
2007-07-11 21:01:13 +04:00
|
|
|
switch (getStmtClass()) {
|
|
|
|
default:
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
case ParenExprClass:
|
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->
|
2007-07-16 03:26:56 +04:00
|
|
|
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
|
2007-07-11 21:01:13 +04:00
|
|
|
case IntegerLiteralClass:
|
|
|
|
Result = cast<IntegerLiteral>(this)->getValue();
|
|
|
|
break;
|
2007-07-16 03:32:58 +04:00
|
|
|
case CharacterLiteralClass: {
|
|
|
|
const CharacterLiteral *CL = cast<CharacterLiteral>(this);
|
2008-03-05 21:54:05 +03:00
|
|
|
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
|
2007-07-16 03:32:58 +04:00
|
|
|
Result = CL->getValue();
|
2007-07-17 01:04:56 +04:00
|
|
|
Result.setIsUnsigned(!getType()->isSignedIntegerType());
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
2007-07-16 03:32:58 +04:00
|
|
|
}
|
2007-08-02 08:09:23 +04:00
|
|
|
case TypesCompatibleExprClass: {
|
|
|
|
const TypesCompatibleExpr *TCE = cast<TypesCompatibleExpr>(this);
|
2008-03-05 21:54:05 +03:00
|
|
|
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
|
2007-10-16 00:41:53 +04:00
|
|
|
Result = Ctx.typesAreCompatible(TCE->getArgType1(), TCE->getArgType2());
|
2007-08-02 04:13:27 +04:00
|
|
|
break;
|
2007-08-02 08:09:23 +04:00
|
|
|
}
|
2007-08-09 02:15:55 +04:00
|
|
|
case CallExprClass: {
|
|
|
|
const CallExpr *CE = cast<CallExpr>(this);
|
2008-03-05 21:54:05 +03:00
|
|
|
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
|
2007-08-09 02:15:55 +04:00
|
|
|
if (CE->isBuiltinClassifyType(Result))
|
|
|
|
break;
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
case DeclRefExprClass:
|
|
|
|
if (const EnumConstantDecl *D =
|
|
|
|
dyn_cast<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl())) {
|
|
|
|
Result = D->getInitVal();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator *Exp = cast<UnaryOperator>(this);
|
|
|
|
|
|
|
|
// Get the operand value. If this is sizeof/alignof, do not evalute the
|
|
|
|
// operand. This affects C99 6.6p3.
|
2008-01-29 18:56:48 +03:00
|
|
|
if (!Exp->isSizeOfAlignOfOp() && !Exp->isOffsetOfOp() &&
|
2007-08-24 01:42:50 +04:00
|
|
|
!Exp->getSubExpr()->isIntegerConstantExpr(Result, Ctx, Loc,isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (Exp->getOpcode()) {
|
|
|
|
// Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
|
|
|
|
// See C99 6.6p3.
|
|
|
|
default:
|
|
|
|
if (Loc) *Loc = Exp->getOperatorLoc();
|
|
|
|
return false;
|
|
|
|
case UnaryOperator::Extension:
|
2007-07-18 22:38:36 +04:00
|
|
|
return true; // FIXME: this is wrong.
|
2007-07-11 21:01:13 +04:00
|
|
|
case UnaryOperator::SizeOf:
|
|
|
|
case UnaryOperator::AlignOf:
|
2008-02-21 08:45:29 +03:00
|
|
|
// Return the result in the right width.
|
2008-03-05 21:54:05 +03:00
|
|
|
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
|
2008-02-21 08:45:29 +03:00
|
|
|
|
|
|
|
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
|
|
|
if (Exp->getSubExpr()->getType()->isVoidType()) {
|
|
|
|
Result = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
2008-02-15 15:20:59 +03:00
|
|
|
if (!Exp->getSubExpr()->getType()->isConstantSizeType()) {
|
2007-12-18 10:15:40 +03:00
|
|
|
if (Loc) *Loc = Exp->getOperatorLoc();
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
2007-12-18 10:15:40 +03:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
|
2007-07-18 22:38:36 +04:00
|
|
|
// Get information about the size or align.
|
2008-01-03 00:54:09 +03:00
|
|
|
if (Exp->getSubExpr()->getType()->isFunctionType()) {
|
|
|
|
// GCC extension: sizeof(function) = 1.
|
|
|
|
Result = Exp->getOpcode() == UnaryOperator::AlignOf ? 4 : 1;
|
2007-11-27 21:22:04 +03:00
|
|
|
} else {
|
2008-03-05 21:54:05 +03:00
|
|
|
unsigned CharSize = Ctx.Target.getCharWidth();
|
2008-02-18 10:10:45 +03:00
|
|
|
if (Exp->getOpcode() == UnaryOperator::AlignOf)
|
2008-03-05 21:54:05 +03:00
|
|
|
Result = Ctx.getTypeAlign(Exp->getSubExpr()->getType()) / CharSize;
|
2008-02-18 10:10:45 +03:00
|
|
|
else
|
2008-03-05 21:54:05 +03:00
|
|
|
Result = Ctx.getTypeSize(Exp->getSubExpr()->getType()) / CharSize;
|
2007-11-27 21:22:04 +03:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case UnaryOperator::LNot: {
|
2008-01-25 22:16:19 +03:00
|
|
|
bool Val = Result == 0;
|
2008-03-05 21:54:05 +03:00
|
|
|
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
|
2007-07-11 21:01:13 +04:00
|
|
|
Result = Val;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case UnaryOperator::Plus:
|
|
|
|
break;
|
|
|
|
case UnaryOperator::Minus:
|
|
|
|
Result = -Result;
|
|
|
|
break;
|
|
|
|
case UnaryOperator::Not:
|
|
|
|
Result = ~Result;
|
|
|
|
break;
|
2008-01-29 18:56:48 +03:00
|
|
|
case UnaryOperator::OffsetOf:
|
|
|
|
Result = Exp->evaluateOffsetOf(Ctx);
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SizeOfAlignOfTypeExprClass: {
|
|
|
|
const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
|
2008-02-21 08:45:29 +03:00
|
|
|
|
|
|
|
// Return the result in the right width.
|
2008-03-05 21:54:05 +03:00
|
|
|
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
|
2008-02-21 08:45:29 +03:00
|
|
|
|
|
|
|
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
|
|
|
if (Exp->getArgumentType()->isVoidType()) {
|
|
|
|
Result = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// alignof always evaluates to a constant, sizeof does if arg is not VLA.
|
2008-02-15 15:20:59 +03:00
|
|
|
if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
|
2007-12-18 10:15:40 +03:00
|
|
|
if (Loc) *Loc = Exp->getOperatorLoc();
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
2007-12-18 10:15:40 +03:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
|
2007-07-18 22:38:36 +04:00
|
|
|
// Get information about the size or align.
|
2008-01-03 00:54:09 +03:00
|
|
|
if (Exp->getArgumentType()->isFunctionType()) {
|
|
|
|
// GCC extension: sizeof(function) = 1.
|
|
|
|
Result = Exp->isSizeOf() ? 1 : 4;
|
2008-02-16 04:20:23 +03:00
|
|
|
} else {
|
2008-03-05 21:54:05 +03:00
|
|
|
unsigned CharSize = Ctx.Target.getCharWidth();
|
2008-02-16 04:20:23 +03:00
|
|
|
if (Exp->isSizeOf())
|
2008-03-05 21:54:05 +03:00
|
|
|
Result = Ctx.getTypeSize(Exp->getArgumentType()) / CharSize;
|
2008-02-16 04:20:23 +03:00
|
|
|
else
|
2008-03-05 21:54:05 +03:00
|
|
|
Result = Ctx.getTypeAlign(Exp->getArgumentType()) / CharSize;
|
2007-12-17 20:38:43 +03:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BinaryOperatorClass: {
|
|
|
|
const BinaryOperator *Exp = cast<BinaryOperator>(this);
|
|
|
|
|
|
|
|
// The LHS of a constant expr is always evaluated and needed.
|
2007-07-16 03:26:56 +04:00
|
|
|
if (!Exp->getLHS()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
llvm::APSInt RHS(Result);
|
|
|
|
|
|
|
|
// The short-circuiting &&/|| operators don't necessarily evaluate their
|
|
|
|
// RHS. Make sure to pass isEvaluated down correctly.
|
|
|
|
if (Exp->isLogicalOp()) {
|
|
|
|
bool RHSEval;
|
|
|
|
if (Exp->getOpcode() == BinaryOperator::LAnd)
|
|
|
|
RHSEval = Result != 0;
|
|
|
|
else {
|
|
|
|
assert(Exp->getOpcode() == BinaryOperator::LOr &&"Unexpected logical");
|
|
|
|
RHSEval = Result == 0;
|
|
|
|
}
|
|
|
|
|
2007-07-16 03:26:56 +04:00
|
|
|
if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc,
|
2007-07-11 21:01:13 +04:00
|
|
|
isEvaluated & RHSEval))
|
|
|
|
return false;
|
|
|
|
} else {
|
2007-07-16 03:26:56 +04:00
|
|
|
if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc, isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Exp->getOpcode()) {
|
|
|
|
default:
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
case BinaryOperator::Mul:
|
|
|
|
Result *= RHS;
|
|
|
|
break;
|
|
|
|
case BinaryOperator::Div:
|
|
|
|
if (RHS == 0) {
|
|
|
|
if (!isEvaluated) break;
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Result /= RHS;
|
|
|
|
break;
|
|
|
|
case BinaryOperator::Rem:
|
|
|
|
if (RHS == 0) {
|
|
|
|
if (!isEvaluated) break;
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Result %= RHS;
|
|
|
|
break;
|
|
|
|
case BinaryOperator::Add: Result += RHS; break;
|
|
|
|
case BinaryOperator::Sub: Result -= RHS; break;
|
|
|
|
case BinaryOperator::Shl:
|
2007-09-04 06:45:27 +04:00
|
|
|
Result <<=
|
|
|
|
static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case BinaryOperator::Shr:
|
2007-09-04 06:45:27 +04:00
|
|
|
Result >>=
|
|
|
|
static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case BinaryOperator::LT: Result = Result < RHS; break;
|
|
|
|
case BinaryOperator::GT: Result = Result > RHS; break;
|
|
|
|
case BinaryOperator::LE: Result = Result <= RHS; break;
|
|
|
|
case BinaryOperator::GE: Result = Result >= RHS; break;
|
|
|
|
case BinaryOperator::EQ: Result = Result == RHS; break;
|
|
|
|
case BinaryOperator::NE: Result = Result != RHS; break;
|
|
|
|
case BinaryOperator::And: Result &= RHS; break;
|
|
|
|
case BinaryOperator::Xor: Result ^= RHS; break;
|
|
|
|
case BinaryOperator::Or: Result |= RHS; break;
|
|
|
|
case BinaryOperator::LAnd:
|
|
|
|
Result = Result != 0 && RHS != 0;
|
|
|
|
break;
|
|
|
|
case BinaryOperator::LOr:
|
|
|
|
Result = Result != 0 || RHS != 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BinaryOperator::Comma:
|
|
|
|
// C99 6.6p3: "shall not contain assignment, ..., or comma operators,
|
|
|
|
// *except* when they are contained within a subexpression that is not
|
|
|
|
// evaluated". Note that Assignment can never happen due to constraints
|
|
|
|
// on the LHS subexpr, so we don't need to check it here.
|
|
|
|
if (isEvaluated) {
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The result of the constant expr is the RHS.
|
|
|
|
Result = RHS;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
|
|
|
|
break;
|
|
|
|
}
|
2007-07-16 03:54:50 +04:00
|
|
|
case ImplicitCastExprClass:
|
2008-08-22 19:38:55 +04:00
|
|
|
case ExplicitCastExprClass:
|
|
|
|
case CXXFunctionalCastExprClass: {
|
2008-08-19 03:01:59 +04:00
|
|
|
const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
|
|
|
|
SourceLocation CastLoc = getLocStart();
|
2007-07-16 03:54:50 +04:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// C99 6.6p6: shall only convert arithmetic types to integer types.
|
2007-07-16 03:54:50 +04:00
|
|
|
if (!SubExpr->getType()->isArithmeticType() ||
|
|
|
|
!getType()->isIntegerType()) {
|
|
|
|
if (Loc) *Loc = SubExpr->getLocStart();
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
}
|
2007-09-22 23:04:13 +04:00
|
|
|
|
2008-03-05 21:54:05 +03:00
|
|
|
uint32_t DestWidth = static_cast<uint32_t>(Ctx.getTypeSize(getType()));
|
2007-09-22 23:04:13 +04:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// Handle simple integer->integer casts.
|
2007-07-16 03:54:50 +04:00
|
|
|
if (SubExpr->getType()->isIntegerType()) {
|
|
|
|
if (!SubExpr->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
2007-07-16 03:54:50 +04:00
|
|
|
|
|
|
|
// Figure out if this is a truncate, extend or noop cast.
|
|
|
|
// If the input is signed, do a sign extend, noop, or truncate.
|
2008-01-09 21:59:34 +03:00
|
|
|
if (getType()->isBooleanType()) {
|
|
|
|
// Conversion to bool compares against zero.
|
|
|
|
Result = Result != 0;
|
|
|
|
Result.zextOrTrunc(DestWidth);
|
|
|
|
} else if (SubExpr->getType()->isSignedIntegerType())
|
2007-07-16 03:54:50 +04:00
|
|
|
Result.sextOrTrunc(DestWidth);
|
|
|
|
else // If the input is unsigned, do a zero extend, noop, or truncate.
|
|
|
|
Result.zextOrTrunc(DestWidth);
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allow floating constants that are the immediate operands of casts or that
|
|
|
|
// are parenthesized.
|
2007-07-16 03:54:50 +04:00
|
|
|
const Expr *Operand = SubExpr;
|
2007-07-11 21:01:13 +04:00
|
|
|
while (const ParenExpr *PE = dyn_cast<ParenExpr>(Operand))
|
|
|
|
Operand = PE->getSubExpr();
|
2007-09-22 23:04:13 +04:00
|
|
|
|
|
|
|
// If this isn't a floating literal, we can't handle it.
|
|
|
|
const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Operand);
|
|
|
|
if (!FL) {
|
|
|
|
if (Loc) *Loc = Operand->getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2008-01-09 21:59:34 +03:00
|
|
|
|
|
|
|
// If the destination is boolean, compare against zero.
|
|
|
|
if (getType()->isBooleanType()) {
|
|
|
|
Result = !FL->getValue().isZero();
|
|
|
|
Result.zextOrTrunc(DestWidth);
|
|
|
|
break;
|
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
|
2007-09-22 23:04:13 +04:00
|
|
|
// Determine whether we are converting to unsigned or signed.
|
|
|
|
bool DestSigned = getType()->isSignedIntegerType();
|
2007-09-26 04:47:26 +04:00
|
|
|
|
|
|
|
// TODO: Warn on overflow, but probably not here: isIntegerConstantExpr can
|
|
|
|
// be called multiple times per AST.
|
2007-09-22 23:04:13 +04:00
|
|
|
uint64_t Space[4];
|
2007-09-26 04:47:26 +04:00
|
|
|
(void)FL->getValue().convertToInteger(Space, DestWidth, DestSigned,
|
|
|
|
llvm::APFloat::rmTowardZero);
|
2007-09-22 23:04:13 +04:00
|
|
|
Result = llvm::APInt(DestWidth, 4, Space);
|
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
case ConditionalOperatorClass: {
|
|
|
|
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
|
|
|
|
2007-07-16 03:26:56 +04:00
|
|
|
if (!Exp->getCond()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
const Expr *TrueExp = Exp->getLHS();
|
|
|
|
const Expr *FalseExp = Exp->getRHS();
|
|
|
|
if (Result == 0) std::swap(TrueExp, FalseExp);
|
|
|
|
|
|
|
|
// Evaluate the false one first, discard the result.
|
2007-11-30 22:04:31 +03:00
|
|
|
if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
// Evalute the true one, capture the result.
|
2007-11-30 22:04:31 +03:00
|
|
|
if (TrueExp &&
|
|
|
|
!TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2008-04-08 08:40:51 +04:00
|
|
|
case CXXDefaultArgExprClass:
|
|
|
|
return cast<CXXDefaultArgExpr>(this)
|
|
|
|
->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Cases that are valid constant exprs fall through to here.
|
|
|
|
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an
|
|
|
|
/// integer constant expression with the value zero, or if this is one that is
|
|
|
|
/// cast to void*.
|
2007-07-16 03:26:56 +04:00
|
|
|
bool Expr::isNullPointerConstant(ASTContext &Ctx) const {
|
2008-01-14 19:10:57 +03:00
|
|
|
// Strip off a cast to void*, if it exists.
|
2008-08-19 03:01:59 +04:00
|
|
|
if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
|
2008-01-14 19:10:57 +03:00
|
|
|
// Check that it is a cast to void*.
|
2008-02-13 20:29:58 +03:00
|
|
|
if (const PointerType *PT = CE->getType()->getAsPointerType()) {
|
2007-07-11 21:01:13 +04:00
|
|
|
QualType Pointee = PT->getPointeeType();
|
2008-02-20 23:55:12 +03:00
|
|
|
if (Pointee.getCVRQualifiers() == 0 &&
|
|
|
|
Pointee->isVoidType() && // to void*
|
2008-01-14 19:10:57 +03:00
|
|
|
CE->getSubExpr()->getType()->isIntegerType()) // from int.
|
|
|
|
return CE->getSubExpr()->isNullPointerConstant(Ctx);
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
2008-01-14 19:10:57 +03:00
|
|
|
} else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(this)) {
|
|
|
|
// Ignore the ImplicitCastExpr type entirely.
|
|
|
|
return ICE->getSubExpr()->isNullPointerConstant(Ctx);
|
|
|
|
} else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
|
|
|
|
// Accept ((void*)0) as a null pointer constant, as many other
|
|
|
|
// implementations do.
|
|
|
|
return PE->getSubExpr()->isNullPointerConstant(Ctx);
|
2008-04-10 06:22:51 +04:00
|
|
|
} else if (const CXXDefaultArgExpr *DefaultArg
|
|
|
|
= dyn_cast<CXXDefaultArgExpr>(this)) {
|
2008-04-08 08:40:51 +04:00
|
|
|
// See through default argument expressions
|
|
|
|
return DefaultArg->getExpr()->isNullPointerConstant(Ctx);
|
2008-01-14 05:53:34 +03:00
|
|
|
}
|
2008-01-14 19:10:57 +03:00
|
|
|
|
|
|
|
// This expression must be an integer type.
|
|
|
|
if (!getType()->isIntegerType())
|
|
|
|
return false;
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// If we have an integer constant expression, we need to *evaluate* it and
|
|
|
|
// test for the value 0.
|
|
|
|
llvm::APSInt Val(32);
|
2008-01-14 19:10:57 +03:00
|
|
|
return isIntegerConstantExpr(Val, Ctx, 0, true) && Val == 0;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
2007-07-29 03:10:27 +04:00
|
|
|
|
2008-04-19 03:10:10 +04:00
|
|
|
unsigned ExtVectorElementExpr::getNumElements() const {
|
2008-05-09 10:41:27 +04:00
|
|
|
if (const VectorType *VT = getType()->getAsVectorType())
|
|
|
|
return VT->getNumElements();
|
|
|
|
return 1;
|
2007-08-03 20:00:20 +04:00
|
|
|
}
|
|
|
|
|
2008-05-09 10:41:27 +04:00
|
|
|
/// containsDuplicateElements - Return true if any element access is repeated.
|
2008-04-19 03:10:10 +04:00
|
|
|
bool ExtVectorElementExpr::containsDuplicateElements() const {
|
2007-07-30 07:29:09 +04:00
|
|
|
const char *compStr = Accessor.getName();
|
|
|
|
unsigned length = strlen(compStr);
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < length-1; i++) {
|
|
|
|
const char *s = compStr+i;
|
|
|
|
for (const char c = *s++; *s; s++)
|
|
|
|
if (c == *s)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2007-08-03 03:36:59 +04:00
|
|
|
|
2008-05-09 10:41:27 +04:00
|
|
|
/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
|
2008-05-14 01:03:02 +04:00
|
|
|
void ExtVectorElementExpr::getEncodedElementAccess(
|
|
|
|
llvm::SmallVectorImpl<unsigned> &Elts) const {
|
2007-08-03 03:36:59 +04:00
|
|
|
const char *compStr = Accessor.getName();
|
2008-05-09 10:41:27 +04:00
|
|
|
|
|
|
|
bool isHi = !strcmp(compStr, "hi");
|
|
|
|
bool isLo = !strcmp(compStr, "lo");
|
|
|
|
bool isEven = !strcmp(compStr, "e");
|
|
|
|
bool isOdd = !strcmp(compStr, "o");
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
|
|
|
|
uint64_t Index;
|
|
|
|
|
|
|
|
if (isHi)
|
|
|
|
Index = e + i;
|
|
|
|
else if (isLo)
|
|
|
|
Index = i;
|
|
|
|
else if (isEven)
|
|
|
|
Index = 2 * i;
|
|
|
|
else if (isOdd)
|
|
|
|
Index = 2 * i + 1;
|
|
|
|
else
|
|
|
|
Index = ExtVectorType::getAccessorIdx(compStr[i]);
|
2007-08-03 03:36:59 +04:00
|
|
|
|
2008-05-14 01:03:02 +04:00
|
|
|
Elts.push_back(Index);
|
2007-08-03 03:36:59 +04:00
|
|
|
}
|
2008-05-09 10:41:27 +04:00
|
|
|
}
|
|
|
|
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42395 91177308-0d34-0410-b5e6-96231b3b80d8
2007-09-27 18:38:14 +04:00
|
|
|
// constructor for instance messages.
|
2007-09-29 02:22:11 +04:00
|
|
|
ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo,
|
2008-01-07 22:49:32 +03:00
|
|
|
QualType retType, ObjCMethodDecl *mproto,
|
2007-11-03 19:37:59 +03:00
|
|
|
SourceLocation LBrac, SourceLocation RBrac,
|
2007-11-15 16:05:42 +03:00
|
|
|
Expr **ArgExprs, unsigned nargs)
|
2007-11-03 19:37:59 +03:00
|
|
|
: Expr(ObjCMessageExprClass, retType), SelName(selInfo),
|
2008-05-01 21:26:20 +04:00
|
|
|
MethodProto(mproto) {
|
2007-11-15 16:05:42 +03:00
|
|
|
NumArgs = nargs;
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
SubExprs = new Stmt*[NumArgs+1];
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42395 91177308-0d34-0410-b5e6-96231b3b80d8
2007-09-27 18:38:14 +04:00
|
|
|
SubExprs[RECEIVER] = receiver;
|
2007-11-15 16:05:42 +03:00
|
|
|
if (NumArgs) {
|
|
|
|
for (unsigned i = 0; i != NumArgs; ++i)
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42395 91177308-0d34-0410-b5e6-96231b3b80d8
2007-09-27 18:38:14 +04:00
|
|
|
SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
|
|
|
|
}
|
2007-09-19 03:55:05 +04:00
|
|
|
LBracloc = LBrac;
|
|
|
|
RBracloc = RBrac;
|
|
|
|
}
|
|
|
|
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42395 91177308-0d34-0410-b5e6-96231b3b80d8
2007-09-27 18:38:14 +04:00
|
|
|
// constructor for class messages.
|
|
|
|
// FIXME: clsName should be typed to ObjCInterfaceType
|
2007-09-29 02:22:11 +04:00
|
|
|
ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
|
2008-01-07 22:49:32 +03:00
|
|
|
QualType retType, ObjCMethodDecl *mproto,
|
2007-11-03 19:37:59 +03:00
|
|
|
SourceLocation LBrac, SourceLocation RBrac,
|
2007-11-15 16:05:42 +03:00
|
|
|
Expr **ArgExprs, unsigned nargs)
|
2007-11-03 19:37:59 +03:00
|
|
|
: Expr(ObjCMessageExprClass, retType), SelName(selInfo),
|
2008-05-01 21:26:20 +04:00
|
|
|
MethodProto(mproto) {
|
2007-11-15 16:05:42 +03:00
|
|
|
NumArgs = nargs;
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
SubExprs = new Stmt*[NumArgs+1];
|
2008-06-24 19:50:53 +04:00
|
|
|
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
|
2007-11-15 16:05:42 +03:00
|
|
|
if (NumArgs) {
|
|
|
|
for (unsigned i = 0; i != NumArgs; ++i)
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42395 91177308-0d34-0410-b5e6-96231b3b80d8
2007-09-27 18:38:14 +04:00
|
|
|
SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
|
|
|
|
}
|
2007-09-19 03:55:05 +04:00
|
|
|
LBracloc = LBrac;
|
|
|
|
RBracloc = RBrac;
|
|
|
|
}
|
|
|
|
|
2008-06-24 19:50:53 +04:00
|
|
|
// constructor for class messages.
|
|
|
|
ObjCMessageExpr::ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
|
|
|
|
QualType retType, ObjCMethodDecl *mproto,
|
|
|
|
SourceLocation LBrac, SourceLocation RBrac,
|
|
|
|
Expr **ArgExprs, unsigned nargs)
|
|
|
|
: Expr(ObjCMessageExprClass, retType), SelName(selInfo),
|
|
|
|
MethodProto(mproto) {
|
|
|
|
NumArgs = nargs;
|
|
|
|
SubExprs = new Stmt*[NumArgs+1];
|
|
|
|
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
|
|
|
|
if (NumArgs) {
|
|
|
|
for (unsigned i = 0; i != NumArgs; ++i)
|
|
|
|
SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
|
|
|
|
}
|
|
|
|
LBracloc = LBrac;
|
|
|
|
RBracloc = RBrac;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
|
|
|
|
uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
|
|
|
|
switch (x & Flags) {
|
|
|
|
default:
|
|
|
|
assert(false && "Invalid ObjCMessageExpr.");
|
|
|
|
case IsInstMeth:
|
|
|
|
return ClassInfo(0, 0);
|
|
|
|
case IsClsMethDeclUnknown:
|
|
|
|
return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
|
|
|
|
case IsClsMethDeclKnown: {
|
|
|
|
ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
|
|
|
|
return ClassInfo(D, D->getIdentifier());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-25 04:29:32 +04:00
|
|
|
bool ChooseExpr::isConditionTrue(ASTContext &C) const {
|
2008-08-14 03:47:13 +04:00
|
|
|
return getCond()->getIntegerConstantExprValue(C) != 0;
|
2007-10-25 04:29:32 +04:00
|
|
|
}
|
|
|
|
|
2008-01-29 18:56:48 +03:00
|
|
|
static int64_t evaluateOffsetOf(ASTContext& C, const Expr *E)
|
|
|
|
{
|
|
|
|
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
|
|
|
|
QualType Ty = ME->getBase()->getType();
|
|
|
|
|
|
|
|
RecordDecl *RD = Ty->getAsRecordType()->getDecl();
|
2008-03-05 21:54:05 +03:00
|
|
|
const ASTRecordLayout &RL = C.getASTRecordLayout(RD);
|
2008-01-29 18:56:48 +03:00
|
|
|
FieldDecl *FD = ME->getMemberDecl();
|
|
|
|
|
|
|
|
// FIXME: This is linear time.
|
|
|
|
unsigned i = 0, e = 0;
|
|
|
|
for (i = 0, e = RD->getNumMembers(); i != e; i++) {
|
|
|
|
if (RD->getMember(i) == FD)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RL.getFieldOffset(i) + evaluateOffsetOf(C, ME->getBase());
|
|
|
|
} else if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
|
|
|
|
const Expr *Base = ASE->getBase();
|
|
|
|
|
2008-03-05 21:54:05 +03:00
|
|
|
int64_t size = C.getTypeSize(ASE->getType());
|
2008-08-14 03:47:13 +04:00
|
|
|
size *= ASE->getIdx()->getIntegerConstantExprValue(C).getSExtValue();
|
2008-01-29 18:56:48 +03:00
|
|
|
|
|
|
|
return size + evaluateOffsetOf(C, Base);
|
|
|
|
} else if (isa<CompoundLiteralExpr>(E))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
assert(0 && "Unknown offsetof subexpression!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t UnaryOperator::evaluateOffsetOf(ASTContext& C) const
|
|
|
|
{
|
|
|
|
assert(Opc == OffsetOf && "Unary operator not offsetof!");
|
|
|
|
|
2008-03-05 21:54:05 +03:00
|
|
|
unsigned CharSize = C.Target.getCharWidth();
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return ::evaluateOffsetOf(C, cast<Expr>(Val)) / CharSize;
|
2008-01-29 18:56:48 +03:00
|
|
|
}
|
|
|
|
|
2007-08-24 22:13:47 +04:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Child Iterators for iterating over subexpressions/substatements
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// DeclRefExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator DeclRefExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator DeclRefExpr::child_end() { return child_iterator(); }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
2007-11-12 17:29:37 +03:00
|
|
|
// ObjCIvarRefExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator ObjCIvarRefExpr::child_begin() { return &Base; }
|
|
|
|
Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; }
|
2007-11-12 17:29:37 +03:00
|
|
|
|
2008-06-03 03:03:37 +04:00
|
|
|
// ObjCPropertyRefExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { return &Base; }
|
|
|
|
Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; }
|
2008-05-30 04:40:33 +04:00
|
|
|
|
2008-08-10 05:53:14 +04:00
|
|
|
// PredefinedExpr
|
|
|
|
Stmt::child_iterator PredefinedExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator PredefinedExpr::child_end() { return child_iterator(); }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// IntegerLiteral
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator IntegerLiteral::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator IntegerLiteral::child_end() { return child_iterator(); }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// CharacterLiteral
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator CharacterLiteral::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator CharacterLiteral::child_end() { return child_iterator(); }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// FloatingLiteral
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator FloatingLiteral::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator FloatingLiteral::child_end() { return child_iterator(); }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
2007-08-26 07:42:43 +04:00
|
|
|
// ImaginaryLiteral
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator ImaginaryLiteral::child_begin() { return &Val; }
|
|
|
|
Stmt::child_iterator ImaginaryLiteral::child_end() { return &Val+1; }
|
2007-08-26 07:42:43 +04:00
|
|
|
|
2007-08-24 22:13:47 +04:00
|
|
|
// StringLiteral
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator StringLiteral::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator StringLiteral::child_end() { return child_iterator(); }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// ParenExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator ParenExpr::child_begin() { return &Val; }
|
|
|
|
Stmt::child_iterator ParenExpr::child_end() { return &Val+1; }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// UnaryOperator
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator UnaryOperator::child_begin() { return &Val; }
|
|
|
|
Stmt::child_iterator UnaryOperator::child_end() { return &Val+1; }
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// SizeOfAlignOfTypeExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator SizeOfAlignOfTypeExpr::child_begin() {
|
2007-12-15 01:52:23 +03:00
|
|
|
// If the type is a VLA type (and not a typedef), the size expression of the
|
|
|
|
// VLA needs to be treated as an executable expression.
|
|
|
|
if (VariableArrayType* T = dyn_cast<VariableArrayType>(Ty.getTypePtr()))
|
|
|
|
return child_iterator(T);
|
|
|
|
else
|
|
|
|
return child_iterator();
|
2007-10-19 03:28:49 +04:00
|
|
|
}
|
|
|
|
Stmt::child_iterator SizeOfAlignOfTypeExpr::child_end() {
|
2007-12-15 01:52:23 +03:00
|
|
|
return child_iterator();
|
2007-10-19 03:28:49 +04:00
|
|
|
}
|
2007-08-24 22:13:47 +04:00
|
|
|
|
|
|
|
// ArraySubscriptExpr
|
2007-08-25 00:06:47 +04:00
|
|
|
Stmt::child_iterator ArraySubscriptExpr::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0];
|
2007-08-24 22:13:47 +04:00
|
|
|
}
|
2007-08-25 00:06:47 +04:00
|
|
|
Stmt::child_iterator ArraySubscriptExpr::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0]+END_EXPR;
|
2007-08-24 22:13:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// CallExpr
|
2007-08-25 00:06:47 +04:00
|
|
|
Stmt::child_iterator CallExpr::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0];
|
2007-08-24 22:13:47 +04:00
|
|
|
}
|
2007-08-25 00:06:47 +04:00
|
|
|
Stmt::child_iterator CallExpr::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0]+NumArgs+ARGS_START;
|
2007-08-24 22:13:47 +04:00
|
|
|
}
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// MemberExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator MemberExpr::child_begin() { return &Base; }
|
|
|
|
Stmt::child_iterator MemberExpr::child_end() { return &Base+1; }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
2008-04-19 03:10:10 +04:00
|
|
|
// ExtVectorElementExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator ExtVectorElementExpr::child_begin() { return &Base; }
|
|
|
|
Stmt::child_iterator ExtVectorElementExpr::child_end() { return &Base+1; }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// CompoundLiteralExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator CompoundLiteralExpr::child_begin() { return &Init; }
|
|
|
|
Stmt::child_iterator CompoundLiteralExpr::child_end() { return &Init+1; }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// CastExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator CastExpr::child_begin() { return &Op; }
|
|
|
|
Stmt::child_iterator CastExpr::child_end() { return &Op+1; }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// BinaryOperator
|
|
|
|
Stmt::child_iterator BinaryOperator::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0];
|
2007-08-25 00:06:47 +04:00
|
|
|
}
|
|
|
|
Stmt::child_iterator BinaryOperator::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0]+END_EXPR;
|
2007-08-25 00:06:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ConditionalOperator
|
|
|
|
Stmt::child_iterator ConditionalOperator::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0];
|
2007-08-25 00:06:47 +04:00
|
|
|
}
|
|
|
|
Stmt::child_iterator ConditionalOperator::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0]+END_EXPR;
|
2007-08-25 00:06:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddrLabelExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator AddrLabelExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator AddrLabelExpr::child_end() { return child_iterator(); }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// StmtExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator StmtExpr::child_begin() { return &SubStmt; }
|
|
|
|
Stmt::child_iterator StmtExpr::child_end() { return &SubStmt+1; }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// TypesCompatibleExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator TypesCompatibleExpr::child_begin() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
|
|
|
|
|
|
|
Stmt::child_iterator TypesCompatibleExpr::child_end() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// ChooseExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator ChooseExpr::child_begin() { return &SubExprs[0]; }
|
|
|
|
Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
2008-01-17 20:46:27 +03:00
|
|
|
// OverloadExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator OverloadExpr::child_begin() { return &SubExprs[0]; }
|
|
|
|
Stmt::child_iterator OverloadExpr::child_end() { return &SubExprs[0]+NumExprs; }
|
2008-01-17 20:46:27 +03:00
|
|
|
|
2008-05-14 23:38:39 +04:00
|
|
|
// ShuffleVectorExpr
|
|
|
|
Stmt::child_iterator ShuffleVectorExpr::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0];
|
2008-05-14 23:38:39 +04:00
|
|
|
}
|
|
|
|
Stmt::child_iterator ShuffleVectorExpr::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0]+NumExprs;
|
2008-05-14 23:38:39 +04:00
|
|
|
}
|
|
|
|
|
2007-10-16 00:28:48 +04:00
|
|
|
// VAArgExpr
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
Stmt::child_iterator VAArgExpr::child_begin() { return &Val; }
|
|
|
|
Stmt::child_iterator VAArgExpr::child_end() { return &Val+1; }
|
2007-10-16 00:28:48 +04:00
|
|
|
|
2007-08-31 08:56:16 +04:00
|
|
|
// InitListExpr
|
|
|
|
Stmt::child_iterator InitListExpr::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return InitExprs.size() ? &InitExprs[0] : 0;
|
2007-08-31 08:56:16 +04:00
|
|
|
}
|
|
|
|
Stmt::child_iterator InitListExpr::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
|
2007-08-31 08:56:16 +04:00
|
|
|
}
|
|
|
|
|
2007-08-25 00:06:47 +04:00
|
|
|
// ObjCStringLiteral
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator ObjCStringLiteral::child_begin() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
|
|
|
Stmt::child_iterator ObjCStringLiteral::child_end() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
2007-08-25 00:06:47 +04:00
|
|
|
|
|
|
|
// ObjCEncodeExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator ObjCEncodeExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator ObjCEncodeExpr::child_end() { return child_iterator(); }
|
2007-08-25 00:06:47 +04:00
|
|
|
|
2007-10-17 00:40:23 +04:00
|
|
|
// ObjCSelectorExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator ObjCSelectorExpr::child_begin() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
|
|
|
Stmt::child_iterator ObjCSelectorExpr::child_end() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
2007-10-17 00:40:23 +04:00
|
|
|
|
2007-10-17 20:58:11 +04:00
|
|
|
// ObjCProtocolExpr
|
2007-10-19 03:28:49 +04:00
|
|
|
Stmt::child_iterator ObjCProtocolExpr::child_begin() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
|
|
|
Stmt::child_iterator ObjCProtocolExpr::child_end() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
2007-10-17 20:58:11 +04:00
|
|
|
|
2007-09-19 03:55:05 +04:00
|
|
|
// ObjCMessageExpr
|
2008-05-01 21:26:20 +04:00
|
|
|
Stmt::child_iterator ObjCMessageExpr::child_begin() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return getReceiver() ? &SubExprs[0] : &SubExprs[0] + ARGS_START;
|
2007-09-19 03:55:05 +04:00
|
|
|
}
|
|
|
|
Stmt::child_iterator ObjCMessageExpr::child_end() {
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52378 91177308-0d34-0410-b5e6-96231b3b80d8
2008-06-17 06:43:46 +04:00
|
|
|
return &SubExprs[0]+ARGS_START+getNumArgs();
|
2007-09-19 03:55:05 +04:00
|
|
|
}
|
|
|
|
|