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"
|
2008-10-06 10:40:35 +04:00
|
|
|
#include "clang/AST/APValue.h"
|
2007-07-16 03:32:58 +04:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2008-10-06 10:40:35 +04:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2008-10-22 03:43:52 +04:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2009-02-04 22:02:06 +03:00
|
|
|
#include "clang/AST/DeclTemplate.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();
|
2008-10-10 03:02:32 +04:00
|
|
|
bool ignored;
|
|
|
|
V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
|
|
|
|
&ignored);
|
2008-06-08 02:13:43 +04:00
|
|
|
return V.convertToDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-06 22:55:15 +03:00
|
|
|
StringLiteral::StringLiteral(ASTContext& C, const char *strData,
|
|
|
|
unsigned byteLength, bool Wide, QualType t,
|
|
|
|
SourceLocation firstLoc,
|
2007-07-11 21:01:13 +04:00
|
|
|
SourceLocation lastLoc) :
|
|
|
|
Expr(StringLiteralClass, t) {
|
|
|
|
// OPTIMIZE: could allocate this appended to the StringLiteral.
|
2009-02-06 22:55:15 +03:00
|
|
|
char *AStrData = new (C, 1) char[byteLength];
|
2007-07-11 21:01:13 +04:00
|
|
|
memcpy(AStrData, strData, byteLength);
|
|
|
|
StrData = AStrData;
|
|
|
|
ByteLength = byteLength;
|
|
|
|
IsWide = Wide;
|
|
|
|
firstTokLoc = firstLoc;
|
|
|
|
lastTokLoc = lastLoc;
|
|
|
|
}
|
|
|
|
|
2009-02-06 22:55:15 +03:00
|
|
|
void StringLiteral::Destroy(ASTContext &C) {
|
2009-02-07 04:47:29 +03:00
|
|
|
C.Deallocate(const_cast<char*>(StrData));
|
2009-02-09 20:10:09 +03:00
|
|
|
this->~StringLiteral();
|
|
|
|
C.Deallocate(this);
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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 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.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-02-09 23:51:47 +03:00
|
|
|
CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args,
|
2009-02-07 04:47:29 +03:00
|
|
|
unsigned numargs, QualType t, SourceLocation rparenloc)
|
2008-12-06 02:32:09 +03:00
|
|
|
: Expr(SC, t,
|
|
|
|
fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs),
|
2009-02-17 01:33:34 +03:00
|
|
|
fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)),
|
2008-12-06 02:32:09 +03:00
|
|
|
NumArgs(numargs) {
|
2009-02-09 23:51:47 +03:00
|
|
|
|
|
|
|
SubExprs = new (C) Stmt*[numargs+1];
|
2008-11-14 19:09:21 +03:00
|
|
|
SubExprs[FN] = fn;
|
|
|
|
for (unsigned i = 0; i != numargs; ++i)
|
|
|
|
SubExprs[i+ARGS_START] = args[i];
|
2009-02-09 23:51:47 +03:00
|
|
|
|
2008-11-14 19:09:21 +03:00
|
|
|
RParenLoc = rparenloc;
|
|
|
|
}
|
2008-01-17 20:46:27 +03:00
|
|
|
|
2009-02-09 23:51:47 +03:00
|
|
|
CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
|
|
|
|
QualType t, SourceLocation rparenloc)
|
2008-12-06 02:32:09 +03:00
|
|
|
: Expr(CallExprClass, t,
|
|
|
|
fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs),
|
2009-02-17 01:33:34 +03:00
|
|
|
fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)),
|
2008-12-06 02:32:09 +03:00
|
|
|
NumArgs(numargs) {
|
2009-02-09 23:51:47 +03:00
|
|
|
|
|
|
|
SubExprs = new (C) 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];
|
2009-02-09 23:51:47 +03:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
RParenLoc = rparenloc;
|
|
|
|
}
|
|
|
|
|
2009-02-09 23:51:47 +03:00
|
|
|
void CallExpr::Destroy(ASTContext& C) {
|
|
|
|
DestroyChildren(C);
|
|
|
|
if (SubExprs) C.Deallocate(SubExprs);
|
|
|
|
this->~CallExpr();
|
|
|
|
C.Deallocate(this);
|
|
|
|
}
|
|
|
|
|
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.
|
2009-02-07 04:47:29 +03:00
|
|
|
void CallExpr::setNumArgs(ASTContext& C, unsigned NumArgs) {
|
2007-12-28 08:25:02 +03:00
|
|
|
// 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)
|
2009-02-07 04:47:29 +03:00
|
|
|
getArg(i)->Destroy(C);
|
2007-12-28 08:25:02 +03:00
|
|
|
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;
|
|
|
|
|
2009-02-07 04:47:29 +03:00
|
|
|
delete [] SubExprs;
|
2007-12-28 08:25:02 +03:00
|
|
|
SubExprs = NewSubExprs;
|
|
|
|
this->NumArgs = NumArgs;
|
|
|
|
}
|
|
|
|
|
2008-10-06 09:00:53 +04:00
|
|
|
/// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
|
|
|
|
/// not, return 0.
|
2009-02-14 21:57:46 +03:00
|
|
|
unsigned CallExpr::isBuiltinCall(ASTContext &Context) const {
|
2008-01-31 04:07:12 +03:00
|
|
|
// 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)()).
|
2008-10-06 09:00:53 +04:00
|
|
|
return 0;
|
|
|
|
|
2008-01-31 04:07:12 +03:00
|
|
|
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
|
|
|
|
if (!DRE)
|
2008-10-06 09:00:53 +04:00
|
|
|
return 0;
|
|
|
|
|
2008-01-31 05:13:57 +03:00
|
|
|
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
|
|
|
|
if (!FDecl)
|
2008-10-06 09:00:53 +04:00
|
|
|
return 0;
|
|
|
|
|
2008-11-21 18:30:19 +03:00
|
|
|
if (!FDecl->getIdentifier())
|
|
|
|
return 0;
|
|
|
|
|
2009-02-14 21:57:46 +03:00
|
|
|
return FDecl->getBuiltinID(Context);
|
2008-10-06 09:00:53 +04:00
|
|
|
}
|
2008-01-31 05:13:57 +03:00
|
|
|
|
2008-10-06 09:00:53 +04:00
|
|
|
|
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,
|
2008-10-27 02:43:26 +03:00
|
|
|
Expr **initExprs, unsigned numInits,
|
2009-01-29 00:54:33 +03:00
|
|
|
SourceLocation rbraceloc)
|
2008-05-01 06:04:18 +04:00
|
|
|
: Expr(InitListExprClass, QualType()),
|
2009-01-29 19:53:55 +03:00
|
|
|
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
|
2009-01-29 22:42:23 +03:00
|
|
|
UnionFieldInit(0), HadArrayRangeDesignator(false) {
|
2008-10-27 02:43:26 +03:00
|
|
|
|
|
|
|
InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
|
2007-08-31 08:56:16 +04:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
|
2009-01-29 00:54:33 +03:00
|
|
|
void InitListExpr::resizeInits(ASTContext &Context, unsigned NumInits) {
|
2009-02-17 01:33:34 +03:00
|
|
|
for (unsigned Idx = NumInits, LastIdx = InitExprs.size();
|
2009-02-17 01:42:44 +03:00
|
|
|
Idx < LastIdx; ++Idx)
|
2009-01-29 00:54:33 +03:00
|
|
|
delete InitExprs[Idx];
|
|
|
|
InitExprs.resize(NumInits, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *InitListExpr::updateInit(unsigned Init, Expr *expr) {
|
|
|
|
if (Init >= InitExprs.size()) {
|
|
|
|
InitExprs.insert(InitExprs.end(), Init - InitExprs.size() + 1, 0);
|
|
|
|
InitExprs.back() = expr;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
|
|
|
|
InitExprs[Init] = expr;
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2008-09-04 19:31:07 +04:00
|
|
|
/// getFunctionType - Return the underlying function type for this block.
|
2008-09-03 22:15:37 +04:00
|
|
|
///
|
|
|
|
const FunctionType *BlockExpr::getFunctionType() const {
|
|
|
|
return getType()->getAsBlockPointerType()->
|
|
|
|
getPointeeType()->getAsFunctionType();
|
|
|
|
}
|
|
|
|
|
2008-10-08 21:01:13 +04:00
|
|
|
SourceLocation BlockExpr::getCaretLocation() const {
|
|
|
|
return TheBlock->getCaretLocation();
|
|
|
|
}
|
|
|
|
const Stmt *BlockExpr::getBody() const { return TheBlock->getBody(); }
|
|
|
|
Stmt *BlockExpr::getBody() { return TheBlock->getBody(); }
|
|
|
|
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Generic Expression Routines
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-02-14 10:37:35 +03:00
|
|
|
/// isUnusedResultAWarning - Return true if this immediate expression should
|
|
|
|
/// be warned about if the result is unused. If so, fill in Loc and Ranges
|
|
|
|
/// with location to warn on and the source range[s] to report with the
|
|
|
|
/// warning.
|
|
|
|
bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
|
|
|
|
SourceRange &R2) const {
|
2007-07-11 21:01:13 +04:00
|
|
|
switch (getStmtClass()) {
|
|
|
|
default:
|
2009-02-14 10:37:35 +03:00
|
|
|
Loc = getExprLoc();
|
|
|
|
R1 = getSourceRange();
|
|
|
|
return true;
|
2007-07-11 21:01:13 +04:00
|
|
|
case ParenExprClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->
|
|
|
|
isUnusedResultAWarning(Loc, R1, R2);
|
2007-07-11 21:01:13 +04:00
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator *UO = cast<UnaryOperator>(this);
|
|
|
|
|
|
|
|
switch (UO->getOpcode()) {
|
2009-02-14 10:37:35 +03:00
|
|
|
default: break;
|
2007-07-11 21:01:13 +04:00
|
|
|
case UnaryOperator::PostInc:
|
|
|
|
case UnaryOperator::PostDec:
|
|
|
|
case UnaryOperator::PreInc:
|
2009-02-14 10:37:35 +03:00
|
|
|
case UnaryOperator::PreDec: // ++/--
|
|
|
|
return false; // Not a warning.
|
2007-07-11 21:01:13 +04:00
|
|
|
case UnaryOperator::Deref:
|
|
|
|
// Dereferencing a volatile pointer is a side-effect.
|
2009-02-14 10:37:35 +03:00
|
|
|
if (getType().isVolatileQualified())
|
|
|
|
return false;
|
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
case UnaryOperator::Real:
|
|
|
|
case UnaryOperator::Imag:
|
|
|
|
// accessing a piece of a volatile complex is a side-effect.
|
2009-02-14 10:37:35 +03:00
|
|
|
if (UO->getSubExpr()->getType().isVolatileQualified())
|
|
|
|
return false;
|
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
case UnaryOperator::Extension:
|
2009-02-14 10:37:35 +03:00
|
|
|
return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
2009-02-14 10:37:35 +03:00
|
|
|
Loc = UO->getOperatorLoc();
|
|
|
|
R1 = UO->getSubExpr()->getSourceRange();
|
|
|
|
return true;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
2007-12-01 09:07:34 +03:00
|
|
|
case BinaryOperatorClass: {
|
2009-02-14 10:37:35 +03:00
|
|
|
const BinaryOperator *BO = cast<BinaryOperator>(this);
|
|
|
|
// Consider comma to have side effects if the LHS or RHS does.
|
|
|
|
if (BO->getOpcode() == BinaryOperator::Comma)
|
|
|
|
return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2) ||
|
|
|
|
BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2);
|
2007-12-01 09:07:34 +03:00
|
|
|
|
2009-02-14 10:37:35 +03:00
|
|
|
if (BO->isAssignmentOp())
|
|
|
|
return false;
|
|
|
|
Loc = BO->getOperatorLoc();
|
|
|
|
R1 = BO->getLHS()->getSourceRange();
|
|
|
|
R2 = BO->getRHS()->getSourceRange();
|
|
|
|
return true;
|
2007-12-01 09:07:34 +03:00
|
|
|
}
|
2007-08-25 06:00:02 +04:00
|
|
|
case CompoundAssignOperatorClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
return false;
|
2007-07-11 21:01:13 +04:00
|
|
|
|
2007-12-01 22:58:28 +03:00
|
|
|
case ConditionalOperatorClass: {
|
2009-02-14 10:37:35 +03:00
|
|
|
// The condition must be evaluated, but if either the LHS or RHS is a
|
|
|
|
// warning, warn about them.
|
2007-12-01 22:58:28 +03:00
|
|
|
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
2009-02-14 10:37:35 +03:00
|
|
|
if (Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2))
|
|
|
|
return true;
|
|
|
|
return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2);
|
2007-12-01 22:58:28 +03:00
|
|
|
}
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
case MemberExprClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
// If the base pointer or element is to a volatile pointer/field, accessing
|
|
|
|
// it is a side effect.
|
|
|
|
if (getType().isVolatileQualified())
|
|
|
|
return false;
|
|
|
|
Loc = cast<MemberExpr>(this)->getMemberLoc();
|
|
|
|
R1 = SourceRange(Loc, Loc);
|
|
|
|
R2 = cast<MemberExpr>(this)->getBase()->getSourceRange();
|
|
|
|
return true;
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
case ArraySubscriptExprClass:
|
|
|
|
// If the base pointer or element is to a volatile pointer/field, accessing
|
2009-02-14 10:37:35 +03:00
|
|
|
// it is a side effect.
|
|
|
|
if (getType().isVolatileQualified())
|
|
|
|
return false;
|
|
|
|
Loc = cast<ArraySubscriptExpr>(this)->getRBracketLoc();
|
|
|
|
R1 = cast<ArraySubscriptExpr>(this)->getLHS()->getSourceRange();
|
|
|
|
R2 = cast<ArraySubscriptExpr>(this)->getRHS()->getSourceRange();
|
|
|
|
return true;
|
2008-05-27 19:24:04 +04:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
case CallExprClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
case CXXOperatorCallExprClass: {
|
|
|
|
// If this is a direct call, get the callee.
|
|
|
|
const CallExpr *CE = cast<CallExpr>(this);
|
|
|
|
const Expr *CalleeExpr = CE->getCallee()->IgnoreParenCasts();
|
|
|
|
if (const DeclRefExpr *CalleeDRE = dyn_cast<DeclRefExpr>(CalleeExpr)) {
|
|
|
|
// If the callee has attribute pure, const, or warn_unused_result, warn
|
|
|
|
// about it. void foo() { strlen("bar"); } should warn.
|
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeDRE->getDecl()))
|
|
|
|
if (FD->getAttr<WarnUnusedResultAttr>() ||
|
|
|
|
FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
|
|
|
|
Loc = CE->getCallee()->getLocStart();
|
|
|
|
R1 = CE->getCallee()->getSourceRange();
|
|
|
|
|
|
|
|
if (unsigned NumArgs = CE->getNumArgs())
|
|
|
|
R2 = SourceRange(CE->getArg(0)->getLocStart(),
|
|
|
|
CE->getArg(NumArgs-1)->getLocEnd());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2007-09-27 02:06:30 +04:00
|
|
|
case ObjCMessageExprClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
return false;
|
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()))
|
2009-02-14 10:37:35 +03:00
|
|
|
return E->isUnusedResultAWarning(Loc, R1, R2);
|
|
|
|
|
|
|
|
Loc = cast<StmtExpr>(this)->getLParenLoc();
|
|
|
|
R1 = getSourceRange();
|
|
|
|
return true;
|
2008-07-26 23:51:01 +04:00
|
|
|
}
|
2008-10-28 18:36:24 +03:00
|
|
|
case CStyleCastExprClass:
|
2009-02-14 10:37:35 +03: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()->isUnusedResultAWarning(Loc,
|
|
|
|
R1, R2);
|
|
|
|
Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
|
|
|
|
R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
|
|
|
|
return true;
|
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())
|
2009-02-14 10:37:35 +03:00
|
|
|
return cast<CastExpr>(this)->getSubExpr()->isUnusedResultAWarning(Loc,
|
|
|
|
R1, R2);
|
|
|
|
Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
|
|
|
|
R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
|
|
|
|
return true;
|
|
|
|
|
2008-05-20 01:24:43 +04:00
|
|
|
case ImplicitCastExprClass:
|
|
|
|
// Check the operand, since implicit casts are inserted by Sema
|
2009-02-14 10:37:35 +03:00
|
|
|
return cast<ImplicitCastExpr>(this)
|
|
|
|
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
|
2008-05-20 01:24:43 +04:00
|
|
|
|
2008-04-08 08:40:51 +04:00
|
|
|
case CXXDefaultArgExprClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
return cast<CXXDefaultArgExpr>(this)
|
|
|
|
->getExpr()->isUnusedResultAWarning(Loc, R1, R2);
|
2008-11-21 22:14:01 +03:00
|
|
|
|
|
|
|
case CXXNewExprClass:
|
|
|
|
// FIXME: In theory, there might be new expressions that don't have side
|
|
|
|
// effects (e.g. a placement new with an uninitialized POD).
|
|
|
|
case CXXDeleteExprClass:
|
2009-02-14 10:37:35 +03:00
|
|
|
return false;
|
2008-11-21 22:14:01 +03:00
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
|
2008-10-22 19:04:37 +04:00
|
|
|
/// DeclCanBeLvalue - Determine whether the given declaration can be
|
|
|
|
/// an lvalue. This is a helper routine for isLvalue.
|
|
|
|
static bool DeclCanBeLvalue(const NamedDecl *Decl, ASTContext &Ctx) {
|
2008-12-05 21:15:24 +03:00
|
|
|
// C++ [temp.param]p6:
|
|
|
|
// A non-type non-reference template-parameter is not an lvalue.
|
|
|
|
if (const NonTypeTemplateParmDecl *NTTParm
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(Decl))
|
|
|
|
return NTTParm->getType()->isReferenceType();
|
|
|
|
|
2008-12-11 19:49:14 +03:00
|
|
|
return isa<VarDecl>(Decl) || isa<FieldDecl>(Decl) ||
|
2008-10-22 19:04:37 +04:00
|
|
|
// C++ 3.10p2: An lvalue refers to an object or function.
|
|
|
|
(Ctx.getLangOptions().CPlusPlus &&
|
|
|
|
(isa<FunctionDecl>(Decl) || isa<OverloadedFunctionDecl>(Decl)));
|
|
|
|
}
|
|
|
|
|
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 {
|
2008-10-22 03:43:52 +04:00
|
|
|
// first, check the type (C99 6.3.2.1). Expressions with function
|
|
|
|
// type in C are not lvalues, but they can be lvalues in C++.
|
|
|
|
if (!Ctx.getLangOptions().CPlusPlus && TR->isFunctionType())
|
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;
|
|
|
|
|
2008-10-22 03:43:52 +04:00
|
|
|
/// FIXME: Expressions can't have reference type, so the following
|
|
|
|
/// isn't needed.
|
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;
|
2009-01-06 08:10:23 +03:00
|
|
|
case DeclRefExprClass:
|
|
|
|
case QualifiedDeclRefExprClass: { // C99 6.5.1p2
|
2008-10-22 19:04:37 +04:00
|
|
|
const NamedDecl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
|
|
|
|
if (DeclCanBeLvalue(RefdDecl, Ctx))
|
2007-07-11 21:01:13 +04:00
|
|
|
return LV_Valid;
|
|
|
|
break;
|
2008-06-17 22:05:57 +04:00
|
|
|
}
|
2008-09-06 02:11:13 +04:00
|
|
|
case BlockDeclRefExprClass: {
|
|
|
|
const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
|
2008-09-26 18:41:28 +04:00
|
|
|
if (isa<VarDecl>(BDR->getDecl()))
|
2008-09-06 02:11:13 +04:00
|
|
|
return LV_Valid;
|
|
|
|
break;
|
|
|
|
}
|
2008-12-21 02:49:58 +03:00
|
|
|
case MemberExprClass: {
|
2007-07-11 21:01:13 +04:00
|
|
|
const MemberExpr *m = cast<MemberExpr>(this);
|
2008-12-21 02:49:58 +03:00
|
|
|
if (Ctx.getLangOptions().CPlusPlus) { // C++ [expr.ref]p4:
|
|
|
|
NamedDecl *Member = m->getMemberDecl();
|
|
|
|
// C++ [expr.ref]p4:
|
|
|
|
// If E2 is declared to have type "reference to T", then E1.E2
|
|
|
|
// is an lvalue.
|
|
|
|
if (ValueDecl *Value = dyn_cast<ValueDecl>(Member))
|
|
|
|
if (Value->getType()->isReferenceType())
|
|
|
|
return LV_Valid;
|
|
|
|
|
|
|
|
// -- If E2 is a static data member [...] then E1.E2 is an lvalue.
|
|
|
|
if (isa<CXXClassVarDecl>(Member))
|
|
|
|
return LV_Valid;
|
|
|
|
|
|
|
|
// -- If E2 is a non-static data member [...]. If E1 is an
|
|
|
|
// lvalue, then E1.E2 is an lvalue.
|
|
|
|
if (isa<FieldDecl>(Member))
|
|
|
|
return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
|
|
|
|
|
|
|
|
// -- If it refers to a static member function [...], then
|
|
|
|
// E1.E2 is an lvalue.
|
|
|
|
// -- Otherwise, if E1.E2 refers to a non-static member
|
|
|
|
// function [...], then E1.E2 is not an lvalue.
|
|
|
|
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member))
|
|
|
|
return Method->isStatic()? LV_Valid : LV_MemberFunction;
|
|
|
|
|
|
|
|
// -- If E2 is a member enumerator [...], the expression E1.E2
|
|
|
|
// is not an lvalue.
|
|
|
|
if (isa<EnumConstantDecl>(Member))
|
|
|
|
return LV_InvalidExpression;
|
|
|
|
|
|
|
|
// Not an lvalue.
|
|
|
|
return LV_InvalidExpression;
|
|
|
|
}
|
|
|
|
|
|
|
|
// C99 6.5.2.3p4
|
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.
|
2008-11-19 18:42:04 +03:00
|
|
|
|
|
|
|
if (Ctx.getLangOptions().CPlusPlus && // C++ [expr.pre.incr]p1
|
|
|
|
(cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::PreInc ||
|
|
|
|
cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::PreDec))
|
|
|
|
return LV_Valid;
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59148 91177308-0d34-0410-b5e6-96231b3b80d8
2008-11-12 20:17:38 +03:00
|
|
|
case ImplicitCastExprClass:
|
|
|
|
return cast<ImplicitCastExpr>(this)->isLvalueCast()? LV_Valid
|
|
|
|
: LV_InvalidExpression;
|
2007-07-11 21:01:13 +04:00
|
|
|
case ParenExprClass: // C99 6.5.1p5
|
2008-07-27 01:30:36 +04:00
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->isLvalue(Ctx);
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59148 91177308-0d34-0410-b5e6-96231b3b80d8
2008-11-12 20:17:38 +03:00
|
|
|
case BinaryOperatorClass:
|
|
|
|
case CompoundAssignOperatorClass: {
|
|
|
|
const BinaryOperator *BinOp = cast<BinaryOperator>(this);
|
2008-11-19 20:17:41 +03:00
|
|
|
|
|
|
|
if (Ctx.getLangOptions().CPlusPlus && // C++ [expr.comma]p1
|
|
|
|
BinOp->getOpcode() == BinaryOperator::Comma)
|
|
|
|
return BinOp->getRHS()->isLvalue(Ctx);
|
|
|
|
|
2009-02-07 03:15:38 +03:00
|
|
|
// C++ [expr.mptr.oper]p6
|
|
|
|
if ((BinOp->getOpcode() == BinaryOperator::PtrMemD ||
|
|
|
|
BinOp->getOpcode() == BinaryOperator::PtrMemI) &&
|
|
|
|
!BinOp->getType()->isFunctionType())
|
|
|
|
return BinOp->getLHS()->isLvalue(Ctx);
|
|
|
|
|
2008-11-13 23:12:29 +03:00
|
|
|
if (!BinOp->isAssignmentOp())
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59148 91177308-0d34-0410-b5e6-96231b3b80d8
2008-11-12 20:17:38 +03:00
|
|
|
return LV_InvalidExpression;
|
|
|
|
|
2008-11-13 23:12:29 +03:00
|
|
|
if (Ctx.getLangOptions().CPlusPlus)
|
|
|
|
// C++ [expr.ass]p1:
|
|
|
|
// The result of an assignment operation [...] is an lvalue.
|
|
|
|
return LV_Valid;
|
|
|
|
|
|
|
|
|
|
|
|
// C99 6.5.16:
|
|
|
|
// An assignment expression [...] is not an lvalue.
|
|
|
|
return LV_InvalidExpression;
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59148 91177308-0d34-0410-b5e6-96231b3b80d8
2008-11-12 20:17:38 +03:00
|
|
|
}
|
2009-01-18 06:20:47 +03:00
|
|
|
// FIXME: OverloadExprClass
|
2008-11-14 19:09:21 +03:00
|
|
|
case CallExprClass:
|
2008-12-22 08:46:06 +03:00
|
|
|
case CXXOperatorCallExprClass:
|
|
|
|
case CXXMemberCallExprClass: {
|
2008-10-28 03:22:11 +03:00
|
|
|
// C++ [expr.call]p10:
|
|
|
|
// A function call is an lvalue if and only if the result type
|
|
|
|
// is a reference.
|
2008-10-29 03:13:59 +03:00
|
|
|
QualType CalleeType = cast<CallExpr>(this)->getCallee()->getType();
|
2008-10-28 03:22:11 +03:00
|
|
|
if (const PointerType *FnTypePtr = CalleeType->getAsPointerType())
|
2008-12-22 08:46:06 +03:00
|
|
|
CalleeType = FnTypePtr->getPointeeType();
|
|
|
|
if (const FunctionType *FnType = CalleeType->getAsFunctionType())
|
|
|
|
if (FnType->getResultType()->isReferenceType())
|
|
|
|
return LV_Valid;
|
2008-10-28 03:22:11 +03:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2007-12-05 07:00:10 +03:00
|
|
|
case CompoundLiteralExprClass: // C99 6.5.2.5p5
|
|
|
|
return LV_Valid;
|
2008-12-12 08:35:08 +03:00
|
|
|
case ChooseExprClass:
|
|
|
|
// __builtin_choose_expr is an lvalue if the selected operand is.
|
|
|
|
if (cast<ChooseExpr>(this)->isConditionTrue(Ctx))
|
|
|
|
return cast<ChooseExpr>(this)->getLHS()->isLvalue(Ctx);
|
|
|
|
else
|
|
|
|
return cast<ChooseExpr>(this)->getRHS()->isLvalue(Ctx);
|
|
|
|
|
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-11-22 21:39:36 +03:00
|
|
|
case ObjCKVCRefExprClass: // FIXME: check if read-only property.
|
2008-12-12 08:35:08 +03:00
|
|
|
return LV_Valid;
|
2008-08-10 05:53:14 +04:00
|
|
|
case PredefinedExprClass:
|
2008-11-04 17:32:21 +03:00
|
|
|
return LV_Valid;
|
2008-10-28 03:22:11 +03:00
|
|
|
case VAArgExprClass:
|
2009-02-12 12:21:08 +03:00
|
|
|
return LV_NotObjectType;
|
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);
|
2008-09-11 08:22:26 +04:00
|
|
|
case CXXConditionDeclExprClass:
|
|
|
|
return LV_Valid;
|
2008-10-28 18:36:24 +03:00
|
|
|
case CStyleCastExprClass:
|
2008-10-28 03:22:11 +03:00
|
|
|
case CXXFunctionalCastExprClass:
|
|
|
|
case CXXStaticCastExprClass:
|
|
|
|
case CXXDynamicCastExprClass:
|
|
|
|
case CXXReinterpretCastExprClass:
|
|
|
|
case CXXConstCastExprClass:
|
|
|
|
// The result of an explicit cast is an lvalue if the type we are
|
|
|
|
// casting to is a reference type. See C++ [expr.cast]p1,
|
|
|
|
// C++ [expr.static.cast]p2, C++ [expr.dynamic.cast]p2,
|
|
|
|
// C++ [expr.reinterpret.cast]p1, C++ [expr.const.cast]p1.
|
|
|
|
if (cast<ExplicitCastExpr>(this)->getTypeAsWritten()->isReferenceType())
|
|
|
|
return LV_Valid;
|
|
|
|
break;
|
2008-11-11 14:37:55 +03:00
|
|
|
case CXXTypeidExprClass:
|
|
|
|
// C++ 5.2.8p1: The result of a typeid expression is an lvalue of ...
|
|
|
|
return LV_Valid;
|
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) {
|
2008-10-22 04:03:08 +04:00
|
|
|
case LV_Valid:
|
|
|
|
// C++ 3.10p11: Functions cannot be modified, but pointers to
|
|
|
|
// functions can be modifiable.
|
|
|
|
if (Ctx.getLangOptions().CPlusPlus && TR->isFunctionType())
|
|
|
|
return MLV_NotObjectType;
|
|
|
|
break;
|
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
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;
|
2008-11-17 22:51:54 +03:00
|
|
|
case LV_InvalidExpression:
|
|
|
|
// If the top level is a C-style cast, and the subexpression is a valid
|
|
|
|
// lvalue, then this is probably a use of the old-school "cast as lvalue"
|
|
|
|
// GCC extension. We don't support it, but we want to produce good
|
|
|
|
// diagnostics when it happens so that the user knows why.
|
|
|
|
if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(this))
|
|
|
|
if (CE->getSubExpr()->isLvalue(Ctx) == LV_Valid)
|
|
|
|
return MLV_LValueCast;
|
|
|
|
return MLV_InvalidExpression;
|
2008-12-21 02:49:58 +03:00
|
|
|
case LV_MemberFunction: return MLV_MemberFunction;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
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;
|
|
|
|
}
|
2008-09-26 18:41:28 +04:00
|
|
|
// The following is illegal:
|
|
|
|
// void takeclosure(void (^C)(void));
|
|
|
|
// void func() { int x = 1; takeclosure(^{ x = 7 }); }
|
|
|
|
//
|
|
|
|
if (getStmtClass() == BlockDeclRefExprClass) {
|
|
|
|
const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
|
|
|
|
if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
|
|
|
|
return MLV_NotBlockQualified;
|
|
|
|
}
|
2009-01-12 22:55:42 +03:00
|
|
|
|
2008-11-22 23:25:50 +03:00
|
|
|
// Assigning to an 'implicit' property?
|
2008-11-25 20:56:43 +03:00
|
|
|
else if (getStmtClass() == ObjCKVCRefExprClass) {
|
2008-11-22 23:25:50 +03:00
|
|
|
const ObjCKVCRefExpr* KVCExpr = cast<ObjCKVCRefExpr>(this);
|
|
|
|
if (KVCExpr->getSetterMethod() == 0)
|
|
|
|
return MLV_NoSetterProperty;
|
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
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();
|
2009-01-06 08:10:23 +03:00
|
|
|
case DeclRefExprClass:
|
|
|
|
case QualifiedDeclRefExprClass: {
|
2007-11-13 21:05:45 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-06 02:32:09 +03:00
|
|
|
/// hasAnyTypeDependentArguments - Determines if any of the expressions
|
|
|
|
/// in Exprs is type-dependent.
|
|
|
|
bool Expr::hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs) {
|
|
|
|
for (unsigned I = 0; I < NumExprs; ++I)
|
|
|
|
if (Exprs[I]->isTypeDependent())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// hasAnyValueDependentArguments - Determines if any of the expressions
|
|
|
|
/// in Exprs is value-dependent.
|
|
|
|
bool Expr::hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs) {
|
|
|
|
for (unsigned I = 0; I < NumExprs; ++I)
|
|
|
|
if (Exprs[I]->isValueDependent())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-01-25 05:32:41 +03:00
|
|
|
bool Expr::isConstantInitializer(ASTContext &Ctx) const {
|
2009-01-25 06:12:18 +03:00
|
|
|
// This function is attempting whether an expression is an initializer
|
|
|
|
// which can be evaluated at compile-time. isEvaluatable handles most
|
|
|
|
// of the cases, but it can't deal with some initializer-specific
|
|
|
|
// expressions, and it can't deal with aggregates; we deal with those here,
|
|
|
|
// and fall back to isEvaluatable for the other cases.
|
|
|
|
|
2008-11-24 08:23:59 +03:00
|
|
|
switch (getStmtClass()) {
|
2009-01-25 06:12:18 +03:00
|
|
|
default: break;
|
2008-11-24 08:23:59 +03:00
|
|
|
case StringLiteralClass:
|
|
|
|
return true;
|
2009-01-18 06:20:47 +03:00
|
|
|
case CompoundLiteralExprClass: {
|
|
|
|
const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
|
2009-01-25 05:32:41 +03:00
|
|
|
return Exp->isConstantInitializer(Ctx);
|
2009-01-18 06:20:47 +03:00
|
|
|
}
|
2008-11-24 08:23:59 +03:00
|
|
|
case InitListExprClass: {
|
|
|
|
const InitListExpr *Exp = cast<InitListExpr>(this);
|
|
|
|
unsigned numInits = Exp->getNumInits();
|
|
|
|
for (unsigned i = 0; i < numInits; i++) {
|
2009-01-25 05:32:41 +03:00
|
|
|
if (!Exp->getInit(i)->isConstantInitializer(Ctx))
|
2008-11-24 08:23:59 +03:00
|
|
|
return false;
|
|
|
|
}
|
2009-01-25 06:12:18 +03:00
|
|
|
return true;
|
2008-11-24 08:23:59 +03:00
|
|
|
}
|
2009-01-29 20:44:32 +03:00
|
|
|
case ImplicitValueInitExprClass:
|
|
|
|
return true;
|
2009-01-25 06:12:18 +03:00
|
|
|
case ParenExprClass: {
|
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
|
|
|
|
}
|
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator* Exp = cast<UnaryOperator>(this);
|
|
|
|
if (Exp->getOpcode() == UnaryOperator::Extension)
|
|
|
|
return Exp->getSubExpr()->isConstantInitializer(Ctx);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CStyleCastExprClass:
|
|
|
|
// Handle casts with a destination that's a struct or union; this
|
|
|
|
// deals with both the gcc no-op struct cast extension and the
|
|
|
|
// cast-to-union extension.
|
|
|
|
if (getType()->isRecordType())
|
|
|
|
return cast<CastExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
|
|
|
|
break;
|
2009-01-25 06:27:40 +03:00
|
|
|
case DesignatedInitExprClass:
|
2009-01-25 16:34:47 +03:00
|
|
|
return cast<DesignatedInitExpr>(this)->
|
|
|
|
getInit()->isConstantInitializer(Ctx);
|
2008-11-24 08:23:59 +03:00
|
|
|
}
|
|
|
|
|
2009-01-25 06:12:18 +03:00
|
|
|
return isEvaluatable(Ctx);
|
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 {
|
2008-11-13 09:09:17 +03:00
|
|
|
// Pretest for integral type; some parts of the code crash for types that
|
|
|
|
// can't be sized.
|
|
|
|
if (!getType()->isIntegralType()) {
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
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();
|
2009-02-18 03:32:53 +03:00
|
|
|
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
2007-07-16 03:32:58 +04:00
|
|
|
case CharacterLiteralClass: {
|
|
|
|
const CharacterLiteral *CL = cast<CharacterLiteral>(this);
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(CL->getValue(), getType());
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
2007-07-16 03:32:58 +04:00
|
|
|
}
|
2008-08-24 01:12:35 +04:00
|
|
|
case CXXBoolLiteralExprClass: {
|
|
|
|
const CXXBoolLiteralExpr *BL = cast<CXXBoolLiteralExpr>(this);
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(BL->getValue(), getType());
|
2008-08-24 01:12:35 +04:00
|
|
|
break;
|
|
|
|
}
|
2008-08-23 23:35:47 +04:00
|
|
|
case CXXZeroInitValueExprClass:
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(0, getType());
|
2008-08-23 23:35:47 +04:00
|
|
|
break;
|
2007-08-02 08:09:23 +04:00
|
|
|
case TypesCompatibleExprClass: {
|
|
|
|
const TypesCompatibleExpr *TCE = cast<TypesCompatibleExpr>(this);
|
2008-10-24 12:07:57 +04:00
|
|
|
// Per gcc docs "this built-in function ignores top level
|
|
|
|
// qualifiers". We need to use the canonical version to properly
|
|
|
|
// be able to strip CRV qualifiers from the type.
|
|
|
|
QualType T0 = Ctx.getCanonicalType(TCE->getArgType1());
|
|
|
|
QualType T1 = Ctx.getCanonicalType(TCE->getArgType2());
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Ctx.typesAreCompatible(T0.getUnqualifiedType(),
|
|
|
|
T1.getUnqualifiedType()),
|
|
|
|
getType());
|
2007-08-02 04:13:27 +04:00
|
|
|
break;
|
2007-08-02 08:09:23 +04:00
|
|
|
}
|
2008-11-14 19:09:21 +03:00
|
|
|
case CallExprClass:
|
|
|
|
case CXXOperatorCallExprClass: {
|
2007-08-09 02:15:55 +04:00
|
|
|
const CallExpr *CE = cast<CallExpr>(this);
|
2008-10-06 10:40:35 +04:00
|
|
|
|
|
|
|
// If this is a call to a builtin function, constant fold it otherwise
|
|
|
|
// reject it.
|
2009-02-14 21:57:46 +03:00
|
|
|
if (CE->isBuiltinCall(Ctx)) {
|
2008-12-19 23:58:05 +03:00
|
|
|
EvalResult EvalResult;
|
|
|
|
if (CE->Evaluate(EvalResult, Ctx)) {
|
|
|
|
assert(!EvalResult.HasSideEffects &&
|
|
|
|
"Foldable builtin call should not have side effects!");
|
|
|
|
Result = EvalResult.Val.getInt();
|
2008-10-06 10:40:35 +04:00
|
|
|
break; // It is a constant, expand it.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-09 02:15:55 +04:00
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
case DeclRefExprClass:
|
2009-01-06 08:10:23 +03:00
|
|
|
case QualifiedDeclRefExprClass:
|
2007-07-11 21:01:13 +04:00
|
|
|
if (const EnumConstantDecl *D =
|
|
|
|
dyn_cast<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl())) {
|
|
|
|
Result = D->getInitVal();
|
|
|
|
break;
|
|
|
|
}
|
2009-02-07 16:06:23 +03:00
|
|
|
if (Ctx.getLangOptions().CPlusPlus &&
|
|
|
|
getType().getCVRQualifiers() == QualType::Const) {
|
|
|
|
// C++ 7.1.5.1p2
|
|
|
|
// A variable of non-volatile const-qualified integral or enumeration
|
|
|
|
// type initialized by an ICE can be used in ICEs.
|
|
|
|
if (const VarDecl *Dcl =
|
|
|
|
dyn_cast<VarDecl>(cast<DeclRefExpr>(this)->getDecl())) {
|
|
|
|
if (const Expr *Init = Dcl->getInit())
|
|
|
|
return Init->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
|
|
|
|
}
|
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator *Exp = cast<UnaryOperator>(this);
|
|
|
|
|
2008-11-11 20:56:53 +03:00
|
|
|
// Get the operand value. If this is offsetof, do not evalute the
|
2007-07-11 21:01:13 +04:00
|
|
|
// operand. This affects C99 6.6p3.
|
2008-11-11 20:56:53 +03:00
|
|
|
if (!Exp->isOffsetOfOp() && !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::LNot: {
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Result == 0, getType());
|
2007-07-11 21:01:13 +04:00
|
|
|
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:
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Exp->evaluateOffsetOf(Ctx), getType());
|
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2008-11-11 20:56:53 +03:00
|
|
|
case SizeOfAlignOfExprClass: {
|
|
|
|
const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(this);
|
2008-02-21 08:45:29 +03:00
|
|
|
|
2008-11-11 20:56:53 +03:00
|
|
|
QualType ArgTy = Exp->getTypeOfArgument();
|
2008-02-21 08:45:29 +03:00
|
|
|
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
2008-11-11 20:56:53 +03:00
|
|
|
if (ArgTy->isVoidType()) {
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(1, getType());
|
2008-02-21 08:45:29 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// alignof always evaluates to a constant, sizeof does if arg is not VLA.
|
2008-11-11 20:56:53 +03:00
|
|
|
if (Exp->isSizeOf() && !ArgTy->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-11-11 20:56:53 +03:00
|
|
|
if (ArgTy->isFunctionType()) {
|
2008-01-03 00:54:09 +03:00
|
|
|
// GCC extension: sizeof(function) = 1.
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Exp->isSizeOf() ? 1 : 4, getType());
|
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())
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Ctx.getTypeSize(ArgTy)/CharSize, getType());
|
2008-02-16 04:20:23 +03:00
|
|
|
else
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Ctx.getTypeAlign(ArgTy)/CharSize, getType());
|
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);
|
2008-09-23 03:53:24 +04:00
|
|
|
llvm::APSInt LHS, RHS;
|
|
|
|
|
|
|
|
// Initialize result to have correct signedness and width.
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(0, getType());
|
2008-11-13 05:13:11 +03:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// The LHS of a constant expr is always evaluated and needed.
|
2008-09-23 03:53:24 +04:00
|
|
|
if (!Exp->getLHS()->isIntegerConstantExpr(LHS, Ctx, Loc, isEvaluated))
|
2007-07-11 21:01:13 +04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// 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)
|
2008-09-23 03:53:24 +04:00
|
|
|
RHSEval = LHS != 0;
|
2007-07-11 21:01:13 +04:00
|
|
|
else {
|
|
|
|
assert(Exp->getOpcode() == BinaryOperator::LOr &&"Unexpected logical");
|
2008-09-23 03:53:24 +04:00
|
|
|
RHSEval = LHS == 0;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
|
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:
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS * RHS;
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case BinaryOperator::Div:
|
|
|
|
if (RHS == 0) {
|
|
|
|
if (!isEvaluated) break;
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS / RHS;
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case BinaryOperator::Rem:
|
|
|
|
if (RHS == 0) {
|
|
|
|
if (!isEvaluated) break;
|
|
|
|
if (Loc) *Loc = getLocStart();
|
|
|
|
return false;
|
|
|
|
}
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS % RHS;
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
2008-09-23 03:53:24 +04:00
|
|
|
case BinaryOperator::Add: Result = LHS + RHS; break;
|
|
|
|
case BinaryOperator::Sub: Result = LHS - RHS; break;
|
2007-07-11 21:01:13 +04:00
|
|
|
case BinaryOperator::Shl:
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS <<
|
|
|
|
static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1));
|
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
case BinaryOperator::Shr:
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS >>
|
|
|
|
static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1));
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
2008-09-23 03:53:24 +04:00
|
|
|
case BinaryOperator::LT: Result = LHS < RHS; break;
|
|
|
|
case BinaryOperator::GT: Result = LHS > RHS; break;
|
|
|
|
case BinaryOperator::LE: Result = LHS <= RHS; break;
|
|
|
|
case BinaryOperator::GE: Result = LHS >= RHS; break;
|
|
|
|
case BinaryOperator::EQ: Result = LHS == RHS; break;
|
|
|
|
case BinaryOperator::NE: Result = LHS != RHS; break;
|
|
|
|
case BinaryOperator::And: Result = LHS & RHS; break;
|
|
|
|
case BinaryOperator::Xor: Result = LHS ^ RHS; break;
|
|
|
|
case BinaryOperator::Or: Result = LHS | RHS; break;
|
2007-07-11 21:01:13 +04:00
|
|
|
case BinaryOperator::LAnd:
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS != 0 && RHS != 0;
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
case BinaryOperator::LOr:
|
2008-09-23 03:53:24 +04:00
|
|
|
Result = LHS != 0 || RHS != 0;
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
2008-11-13 05:13:11 +03:00
|
|
|
|
|
|
|
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;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
2009-02-18 03:32:53 +03:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
|
|
|
|
break;
|
|
|
|
}
|
2007-07-16 03:54:50 +04:00
|
|
|
case ImplicitCastExprClass:
|
2008-10-28 18:36:24 +03:00
|
|
|
case CStyleCastExprClass:
|
2008-08-22 19:38:55 +04:00
|
|
|
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.
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(Result != 0, getType());
|
|
|
|
} else if (SubExpr->getType()->isSignedIntegerType()) {
|
2007-07-16 03:54:50 +04:00
|
|
|
Result.sextOrTrunc(DestWidth);
|
2009-02-18 03:32:53 +03:00
|
|
|
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
|
|
|
|
} else { // If the input is unsigned, do a zero extend, noop,
|
|
|
|
// or truncate.
|
2007-07-16 03:54:50 +04:00
|
|
|
Result.zextOrTrunc(DestWidth);
|
2009-02-18 03:32:53 +03:00
|
|
|
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
|
|
|
|
}
|
2007-07-11 21:01:13 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allow floating constants that are the immediate operands of casts or that
|
|
|
|
// are parenthesized.
|
2009-02-18 03:32:53 +03:00
|
|
|
const Expr *Operand = SubExpr->IgnoreParens();
|
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()) {
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(!FL->getValue().isZero(), getType());
|
2008-01-09 21:59:34 +03:00
|
|
|
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.
|
2008-10-10 03:02:32 +04:00
|
|
|
uint64_t Space[4];
|
|
|
|
bool ignored;
|
2007-09-26 04:47:26 +04:00
|
|
|
(void)FL->getValue().convertToInteger(Space, DestWidth, DestSigned,
|
2008-10-10 03:02:32 +04:00
|
|
|
llvm::APFloat::rmTowardZero,
|
|
|
|
&ignored);
|
2007-09-22 23:04:13 +04:00
|
|
|
Result = llvm::APInt(DestWidth, 4, Space);
|
2009-02-18 03:32:53 +03:00
|
|
|
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
|
2007-09-22 23:04:13 +04:00
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
case ConditionalOperatorClass: {
|
|
|
|
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
|
|
|
|
2008-12-12 09:55:44 +03:00
|
|
|
const Expr *Cond = Exp->getCond();
|
|
|
|
|
|
|
|
if (!Cond->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);
|
|
|
|
|
2008-12-12 09:55:44 +03:00
|
|
|
// If the condition (ignoring parens) is a __builtin_constant_p call,
|
|
|
|
// then only the true side is actually considered in an integer constant
|
2008-12-12 21:00:51 +03:00
|
|
|
// expression, and it is fully evaluated. This is an important GNU
|
|
|
|
// extension. See GCC PR38377 for discussion.
|
2008-12-12 09:55:44 +03:00
|
|
|
if (const CallExpr *CallCE = dyn_cast<CallExpr>(Cond->IgnoreParenCasts()))
|
2009-02-14 21:57:46 +03:00
|
|
|
if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) {
|
2008-12-12 21:00:51 +03:00
|
|
|
EvalResult EVResult;
|
|
|
|
if (!Evaluate(EVResult, Ctx) || EVResult.HasSideEffects)
|
|
|
|
return false;
|
|
|
|
assert(EVResult.Val.isInt() && "FP conditional expr not expected");
|
|
|
|
Result = EVResult.Val.getInt();
|
|
|
|
if (Loc) *Loc = EVResult.DiagLoc;
|
|
|
|
return true;
|
|
|
|
}
|
2008-12-12 09:55:44 +03:00
|
|
|
|
2007-07-11 21:01:13 +04:00
|
|
|
// 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);
|
2009-01-05 23:52:13 +03:00
|
|
|
|
|
|
|
case UnaryTypeTraitExprClass:
|
2009-02-18 03:32:53 +03:00
|
|
|
Result = Ctx.MakeIntValue(cast<UnaryTypeTraitExpr>(this)->EvaluateTrait(),
|
|
|
|
getType());
|
|
|
|
break;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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*.
|
2008-12-01 05:13:57 +03:00
|
|
|
bool Expr::isNullPointerConstant(ASTContext &Ctx) const
|
|
|
|
{
|
2008-10-31 17:43:28 +03:00
|
|
|
// Strip off a cast to void*, if it exists. Except in C++.
|
2008-08-19 03:01:59 +04:00
|
|
|
if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
|
2008-11-04 14:45:54 +03:00
|
|
|
if (!Ctx.getLangOptions().CPlusPlus) {
|
2008-10-31 17:43:28 +03:00
|
|
|
// Check that it is a cast to void*.
|
|
|
|
if (const PointerType *PT = CE->getType()->getAsPointerType()) {
|
|
|
|
QualType Pointee = PT->getPointeeType();
|
|
|
|
if (Pointee.getCVRQualifiers() == 0 &&
|
|
|
|
Pointee->isVoidType() && // to void*
|
|
|
|
CE->getSubExpr()->getType()->isIntegerType()) // from int.
|
2008-12-01 09:28:23 +03:00
|
|
|
return CE->getSubExpr()->isNullPointerConstant(Ctx);
|
2008-10-31 17:43:28 +03:00
|
|
|
}
|
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.
|
2008-12-01 09:28:23 +03:00
|
|
|
return ICE->getSubExpr()->isNullPointerConstant(Ctx);
|
2008-01-14 19:10:57 +03:00
|
|
|
} else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
|
|
|
|
// Accept ((void*)0) as a null pointer constant, as many other
|
|
|
|
// implementations do.
|
2008-12-01 09:28:23 +03:00
|
|
|
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
|
2008-12-01 09:28:23 +03:00
|
|
|
return DefaultArg->getExpr()->isNullPointerConstant(Ctx);
|
2008-11-29 07:51:27 +03:00
|
|
|
} else if (isa<GNUNullExpr>(this)) {
|
|
|
|
// The GNU __null extension is always a null pointer constant.
|
|
|
|
return true;
|
2008-01-14 05:53:34 +03:00
|
|
|
}
|
2008-11-29 07:51:27 +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.
|
2008-12-01 09:28:23 +03:00
|
|
|
// FIXME: We should probably return false if we're compiling in strict mode
|
|
|
|
// and Diag is not null (this indicates that the value was foldable but not
|
|
|
|
// an ICE.
|
|
|
|
EvalResult Result;
|
2008-12-01 05:13:57 +03:00
|
|
|
return Evaluate(Result, Ctx) && !Result.HasSideEffects &&
|
2008-12-01 09:28:23 +03:00
|
|
|
Result.Val.isInt() && Result.Val.getInt() == 0;
|
2007-07-11 21:01:13 +04:00
|
|
|
}
|
2007-07-29 03:10:27 +04:00
|
|
|
|
2008-10-29 03:13:59 +03:00
|
|
|
/// isBitField - Return true if this expression is a bit-field.
|
|
|
|
bool Expr::isBitField() {
|
|
|
|
Expr *E = this->IgnoreParenCasts();
|
|
|
|
if (MemberExpr *MemRef = dyn_cast<MemberExpr>(E))
|
2008-12-21 02:49:58 +03:00
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(MemRef->getMemberDecl()))
|
|
|
|
return Field->isBitField();
|
2008-10-29 03:13:59 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-02-17 01:14:05 +03:00
|
|
|
/// isArrow - Return true if the base expression is a pointer to vector,
|
|
|
|
/// return false if the base expression is a vector.
|
|
|
|
bool ExtVectorElementExpr::isArrow() const {
|
|
|
|
return getBase()->getType()->isPointerType();
|
|
|
|
}
|
|
|
|
|
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();
|
2008-11-19 10:55:04 +03:00
|
|
|
unsigned length = Accessor.getLength();
|
2009-01-18 05:01:21 +03:00
|
|
|
|
|
|
|
// Halving swizzles do not contain duplicate elements.
|
|
|
|
if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
|
|
|
|
!strcmp(compStr, "even") || !strcmp(compStr, "odd"))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Advance past s-char prefix on hex swizzles.
|
|
|
|
if (*compStr == 's') {
|
|
|
|
compStr++;
|
|
|
|
length--;
|
|
|
|
}
|
2007-07-30 07:29:09 +04:00
|
|
|
|
2008-11-19 10:55:04 +03:00
|
|
|
for (unsigned i = 0; i != length-1; i++) {
|
2007-07-30 07:29:09 +04:00
|
|
|
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 {
|
2008-11-19 10:55:04 +03:00
|
|
|
const char *compStr = Accessor.getName();
|
2009-01-18 04:47:54 +03:00
|
|
|
if (*compStr == 's')
|
|
|
|
compStr++;
|
|
|
|
|
|
|
|
bool isHi = !strcmp(compStr, "hi");
|
|
|
|
bool isLo = !strcmp(compStr, "lo");
|
|
|
|
bool isEven = !strcmp(compStr, "even");
|
|
|
|
bool isOdd = !strcmp(compStr, "odd");
|
|
|
|
|
2008-05-09 10:41:27 +04:00
|
|
|
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-12-12 08:35:08 +03:00
|
|
|
static int64_t evaluateOffsetOf(ASTContext& C, const Expr *E) {
|
2008-01-29 18:56:48 +03:00
|
|
|
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-12-21 02:49:58 +03:00
|
|
|
if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
|
|
|
|
// FIXME: This is linear time. And the fact that we're indexing
|
|
|
|
// into the layout by position in the record means that we're
|
|
|
|
// either stuck numbering the fields in the AST or we have to keep
|
|
|
|
// the linear search (yuck and yuck).
|
|
|
|
unsigned i = 0;
|
|
|
|
for (RecordDecl::field_iterator Field = RD->field_begin(),
|
|
|
|
FieldEnd = RD->field_end();
|
|
|
|
Field != FieldEnd; (void)++Field, ++i) {
|
|
|
|
if (*Field == FD)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RL.getFieldOffset(i) + evaluateOffsetOf(C, ME->getBase());
|
2008-01-29 18:56:48 +03:00
|
|
|
}
|
|
|
|
} 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
|
|
|
}
|
|
|
|
|
2008-11-11 20:56:53 +03:00
|
|
|
void SizeOfAlignOfExpr::Destroy(ASTContext& C) {
|
|
|
|
// Override default behavior of traversing children. If this has a type
|
|
|
|
// operand and the type is a variable-length array, the child iteration
|
|
|
|
// will iterate over the size expression. However, this expression belongs
|
|
|
|
// to the type, not to this, so we don't want to delete it.
|
|
|
|
// We still want to delete this expression.
|
2009-02-07 04:47:29 +03:00
|
|
|
if (isArgumentType()) {
|
|
|
|
this->~SizeOfAlignOfExpr();
|
|
|
|
C.Deallocate(this);
|
|
|
|
}
|
2008-11-11 20:56:53 +03:00
|
|
|
else
|
|
|
|
Expr::Destroy(C);
|
2008-08-28 22:02:04 +04:00
|
|
|
}
|
|
|
|
|
2009-02-09 20:08:14 +03:00
|
|
|
void OverloadExpr::Destroy(ASTContext& C) {
|
|
|
|
DestroyChildren(C);
|
|
|
|
C.Deallocate(SubExprs);
|
|
|
|
this->~OverloadExpr();
|
|
|
|
C.Deallocate(this);
|
|
|
|
}
|
|
|
|
|
2009-01-22 03:58:24 +03:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DesignatedInitExpr
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() {
|
|
|
|
assert(Kind == FieldDesignator && "Only valid on a field designator");
|
|
|
|
if (Field.NameOrField & 0x01)
|
|
|
|
return reinterpret_cast<IdentifierInfo *>(Field.NameOrField&~0x01);
|
|
|
|
else
|
|
|
|
return getField()->getIdentifier();
|
|
|
|
}
|
|
|
|
|
|
|
|
DesignatedInitExpr *
|
|
|
|
DesignatedInitExpr::Create(ASTContext &C, Designator *Designators,
|
|
|
|
unsigned NumDesignators,
|
|
|
|
Expr **IndexExprs, unsigned NumIndexExprs,
|
|
|
|
SourceLocation ColonOrEqualLoc,
|
|
|
|
bool UsesColonSyntax, Expr *Init) {
|
2009-01-28 02:20:32 +03:00
|
|
|
void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
|
|
|
|
sizeof(Designator) * NumDesignators +
|
|
|
|
sizeof(Stmt *) * (NumIndexExprs + 1), 8);
|
2009-01-22 03:58:24 +03:00
|
|
|
DesignatedInitExpr *DIE
|
|
|
|
= new (Mem) DesignatedInitExpr(C.VoidTy, NumDesignators,
|
|
|
|
ColonOrEqualLoc, UsesColonSyntax,
|
|
|
|
NumIndexExprs + 1);
|
|
|
|
|
|
|
|
// Fill in the designators
|
|
|
|
unsigned ExpectedNumSubExprs = 0;
|
|
|
|
designators_iterator Desig = DIE->designators_begin();
|
|
|
|
for (unsigned Idx = 0; Idx < NumDesignators; ++Idx, ++Desig) {
|
|
|
|
new (static_cast<void*>(Desig)) Designator(Designators[Idx]);
|
|
|
|
if (Designators[Idx].isArrayDesignator())
|
|
|
|
++ExpectedNumSubExprs;
|
|
|
|
else if (Designators[Idx].isArrayRangeDesignator())
|
|
|
|
ExpectedNumSubExprs += 2;
|
|
|
|
}
|
|
|
|
assert(ExpectedNumSubExprs == NumIndexExprs && "Wrong number of indices!");
|
|
|
|
|
|
|
|
// Fill in the subexpressions, including the initializer expression.
|
|
|
|
child_iterator Child = DIE->child_begin();
|
|
|
|
*Child++ = Init;
|
|
|
|
for (unsigned Idx = 0; Idx < NumIndexExprs; ++Idx, ++Child)
|
|
|
|
*Child = IndexExprs[Idx];
|
|
|
|
|
|
|
|
return DIE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceRange DesignatedInitExpr::getSourceRange() const {
|
|
|
|
SourceLocation StartLoc;
|
2009-02-17 01:33:34 +03:00
|
|
|
Designator &First =
|
|
|
|
*const_cast<DesignatedInitExpr*>(this)->designators_begin();
|
2009-01-22 03:58:24 +03:00
|
|
|
if (First.isFieldDesignator()) {
|
|
|
|
if (UsesColonSyntax)
|
|
|
|
StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc);
|
|
|
|
else
|
|
|
|
StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc);
|
|
|
|
} else
|
2009-02-17 01:33:34 +03:00
|
|
|
StartLoc =
|
|
|
|
SourceLocation::getFromRawEncoding(First.ArrayOrRange.LBracketLoc);
|
2009-01-22 03:58:24 +03:00
|
|
|
return SourceRange(StartLoc, getInit()->getSourceRange().getEnd());
|
|
|
|
}
|
|
|
|
|
2009-02-17 01:33:34 +03:00
|
|
|
DesignatedInitExpr::designators_iterator
|
|
|
|
DesignatedInitExpr::designators_begin() {
|
2009-01-22 03:58:24 +03:00
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
return static_cast<Designator*>(static_cast<void*>(Ptr));
|
|
|
|
}
|
|
|
|
|
|
|
|
DesignatedInitExpr::designators_iterator DesignatedInitExpr::designators_end() {
|
|
|
|
return designators_begin() + NumDesignators;
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) {
|
|
|
|
assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Ptr += sizeof(Designator) * NumDesignators;
|
|
|
|
Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *DesignatedInitExpr::getArrayRangeStart(const Designator& D) {
|
|
|
|
assert(D.Kind == Designator::ArrayRangeDesignator &&
|
|
|
|
"Requires array range designator");
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Ptr += sizeof(Designator) * NumDesignators;
|
|
|
|
Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator& D) {
|
|
|
|
assert(D.Kind == Designator::ArrayRangeDesignator &&
|
|
|
|
"Requires array range designator");
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Ptr += sizeof(Designator) * NumDesignators;
|
|
|
|
Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2));
|
|
|
|
}
|
|
|
|
|
2008-10-27 21:40:21 +03:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ExprIterator.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
Expr* ExprIterator::operator[](size_t idx) { return cast<Expr>(I[idx]); }
|
|
|
|
Expr* ExprIterator::operator*() const { return cast<Expr>(*I); }
|
|
|
|
Expr* ExprIterator::operator->() const { return cast<Expr>(*I); }
|
|
|
|
const Expr* ConstExprIterator::operator[](size_t idx) const {
|
|
|
|
return cast<Expr>(I[idx]);
|
|
|
|
}
|
|
|
|
const Expr* ConstExprIterator::operator*() const { return cast<Expr>(*I); }
|
|
|
|
const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); }
|
|
|
|
|
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-11-22 21:39:36 +03:00
|
|
|
// ObjCKVCRefExpr
|
|
|
|
Stmt::child_iterator ObjCKVCRefExpr::child_begin() { return &Base; }
|
|
|
|
Stmt::child_iterator ObjCKVCRefExpr::child_end() { return &Base+1; }
|
|
|
|
|
2008-11-04 17:56:14 +03:00
|
|
|
// ObjCSuperExpr
|
|
|
|
Stmt::child_iterator ObjCSuperExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator ObjCSuperExpr::child_end() { return child_iterator(); }
|
|
|
|
|
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
|
2009-02-17 01:33:34 +03:00
|
|
|
Stmt::child_iterator CharacterLiteral::child_begin() { return child_iterator();}
|
2007-10-19 03:28:49 +04:00
|
|
|
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
|
|
|
|
2008-11-11 20:56:53 +03:00
|
|
|
// SizeOfAlignOfExpr
|
|
|
|
Stmt::child_iterator SizeOfAlignOfExpr::child_begin() {
|
|
|
|
// If this is of a type and the type is a VLA type (and not a typedef), the
|
|
|
|
// size expression of the VLA needs to be treated as an executable expression.
|
|
|
|
// Why isn't this weirdness documented better in StmtIterator?
|
|
|
|
if (isArgumentType()) {
|
|
|
|
if (VariableArrayType* T = dyn_cast<VariableArrayType>(
|
|
|
|
getArgumentType().getTypePtr()))
|
|
|
|
return child_iterator(T);
|
|
|
|
return child_iterator();
|
|
|
|
}
|
2008-12-04 02:17:54 +03:00
|
|
|
return child_iterator(&Argument.Ex);
|
2007-10-19 03:28:49 +04:00
|
|
|
}
|
2008-11-11 20:56:53 +03:00
|
|
|
Stmt::child_iterator SizeOfAlignOfExpr::child_end() {
|
|
|
|
if (isArgumentType())
|
|
|
|
return child_iterator();
|
2008-12-04 02:17:54 +03:00
|
|
|
return child_iterator(&Argument.Ex + 1);
|
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; }
|
2008-11-29 07:51:27 +03:00
|
|
|
|
|
|
|
// GNUNullExpr
|
|
|
|
Stmt::child_iterator GNUNullExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator GNUNullExpr::child_end() { return child_iterator(); }
|
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
|
|
|
}
|
|
|
|
|
2009-01-29 20:44:32 +03:00
|
|
|
// DesignatedInitExpr
|
2009-01-22 03:58:24 +03:00
|
|
|
Stmt::child_iterator DesignatedInitExpr::child_begin() {
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Ptr += sizeof(Designator) * NumDesignators;
|
|
|
|
return reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
}
|
|
|
|
Stmt::child_iterator DesignatedInitExpr::child_end() {
|
|
|
|
return child_iterator(&*child_begin() + NumSubExprs);
|
|
|
|
}
|
|
|
|
|
2009-01-29 20:44:32 +03:00
|
|
|
// ImplicitValueInitExpr
|
|
|
|
Stmt::child_iterator ImplicitValueInitExpr::child_begin() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
|
|
|
|
|
|
|
Stmt::child_iterator ImplicitValueInitExpr::child_end() {
|
|
|
|
return child_iterator();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2008-09-03 22:15:37 +04:00
|
|
|
// Blocks
|
2008-10-08 21:01:13 +04:00
|
|
|
Stmt::child_iterator BlockExpr::child_begin() { return child_iterator(); }
|
|
|
|
Stmt::child_iterator BlockExpr::child_end() { return child_iterator(); }
|
2008-09-03 22:15:37 +04:00
|
|
|
|
2008-09-27 03:24:14 +04:00
|
|
|
Stmt::child_iterator BlockDeclRefExpr::child_begin() { return child_iterator();}
|
|
|
|
Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator(); }
|