Submitted by:
Reviewed by:
- Added a getSourceRange() method to all subclasses of Expr.
- Changed all the constructors and instantiators.
- Only added SourceLocations's when necessary. For example, binary
expression *don't* carry the operator location...it isn't
necessary to implement getSourceRange(). On the other hand, unary
expressions *do* carry the operator location.
- Added trivial SourceRange value class to SourceLocation.

Note: need to talk to Chris about the FIXME for StringLiteral...
llvm-svn: 39452
This commit is contained in:
Steve Naroff 2007-05-17 01:16:00 +00:00
parent a78fe7e3ed
commit 509fe025aa
6 changed files with 141 additions and 61 deletions

View File

@ -22,7 +22,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
bool Wide, QualType t) :
bool Wide, QualType t, SourceLocation l) :
Expr(StringLiteralClass, t) {
// OPTIMIZE: could allocate this appended to the StringLiteral.
char *AStrData = new char[byteLength];
@ -30,6 +30,7 @@ StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
StrData = AStrData;
ByteLength = byteLength;
IsWide = Wide;
Loc = l;
}
StringLiteral::~StringLiteral() {
@ -73,11 +74,13 @@ const char *UnaryOperator::getOpcodeStr(Opcode Op) {
// Postfix Operators.
//===----------------------------------------------------------------------===//
CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t)
CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
SourceLocation l)
: Expr(CallExprClass, t), Fn(fn), NumArgs(numargs) {
Args = new Expr*[numargs];
for (unsigned i = 0; i != numargs; ++i)
Args[i] = args[i];
Loc = l;
}
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it

View File

@ -56,7 +56,7 @@ Sema::ParseStringLiteral(const LexerToken *StringToks, unsigned NumStringToks) {
// FIXME: use factory.
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
Literal.AnyWide, t);
Literal.AnyWide, t, SourceLocation()/*FIXME*/);
}
@ -83,7 +83,7 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
}
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
return new DeclRefExpr(VD, VD->getType());
return new DeclRefExpr(VD, VD->getType(), Loc);
if (isa<TypedefDecl>(D))
return Diag(Loc, diag::err_unexpected_typedef, II.getName());
@ -113,7 +113,8 @@ Sema::ExprResult Sema::ParseCharacterConstant(const LexerToken &Tok) {
Tok.getLocation(), PP);
if (Literal.hadError())
return ExprResult(true);
return new CharacterLiteral(Literal.getValue(), Context.IntTy);
return new CharacterLiteral(Literal.getValue(), Context.IntTy,
Tok.getLocation());
}
Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
@ -121,7 +122,8 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
// cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) {
const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation());
return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy));
return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy,
Tok.getLocation()));
}
SmallString<512> IntegerBuffer;
IntegerBuffer.resize(Tok.getLength());
@ -154,11 +156,11 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
}
uintmax_t val;
if (Literal.GetIntegerValue(val)) {
return new IntegerLiteral(val, t);
return new IntegerLiteral(val, t, Tok.getLocation());
}
} else if (Literal.isFloatingLiteral()) {
// FIXME: fill in the value and compute the real type...
return new FloatingLiteral(7.7, Context.FloatTy);
return new FloatingLiteral(7.7, Context.FloatTy, Tok.getLocation());
}
return ExprResult(true);
}
@ -192,8 +194,8 @@ QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType,
Action::ExprResult Sema::
ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc) {
SourceLocation LPLoc, TypeTy *Ty,
SourceLocation RPLoc) {
// If error parsing type, ignore.
if (Ty == 0) return true;
@ -204,7 +206,7 @@ ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
if (resultType.isNull())
return true;
return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, resultType);
return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, resultType, OpLoc, RPLoc);
}
@ -220,7 +222,7 @@ Action::ExprResult Sema::ParsePostfixUnaryOp(SourceLocation OpLoc,
QualType result = CheckIncrementDecrementOperand((Expr *)Input, OpLoc);
if (result.isNull())
return true;
return new UnaryOperator((Expr *)Input, Opc, result);
return new UnaryOperator((Expr *)Input, Opc, result, OpLoc);
}
Action::ExprResult Sema::
@ -266,7 +268,7 @@ ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
return Diag(LLoc, diag::err_typecheck_subscript_not_object,
baseType.getAsString());
}
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType);
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType, RLoc);
}
Action::ExprResult Sema::
@ -375,7 +377,8 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
if ((NumArgsInCall != NumArgsInProto) && !proto->isVariadic())
return true;
}
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType);
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType,
RParenLoc);
}
Action::ExprResult Sema::
@ -383,7 +386,7 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op) {
// If error parsing type, ignore.
assert((Ty != 0) && "ParseCastExpr(): missing type");
return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op);
return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op, LParenLoc);
}
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
@ -402,9 +405,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
// first, check the condition.
if (!cond->isScalarType()) { // C99 6.5.15p2
// FIXME: need to compute the location from the Cond expr node...
Diag(questionLoc, diag::err_typecheck_cond_expect_scalar,
cond.getAsString());
Diag(Cond->getSourceLocation(), diag::err_typecheck_cond_expect_scalar,
cond.getAsString());
return QualType();
}
// now check the two expressions.
@ -1115,5 +1117,5 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
}
if (resultType.isNull())
return true;
return new UnaryOperator((Expr *)Input, Opc, resultType);
return new UnaryOperator((Expr *)Input, Opc, resultType, OpLoc);
}

View File

@ -56,7 +56,7 @@ Sema::ParseStringLiteral(const LexerToken *StringToks, unsigned NumStringToks) {
// FIXME: use factory.
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
Literal.AnyWide, t);
Literal.AnyWide, t, SourceLocation()/*FIXME*/);
}
@ -83,7 +83,7 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
}
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
return new DeclRefExpr(VD, VD->getType());
return new DeclRefExpr(VD, VD->getType(), Loc);
if (isa<TypedefDecl>(D))
return Diag(Loc, diag::err_unexpected_typedef, II.getName());
@ -113,7 +113,8 @@ Sema::ExprResult Sema::ParseCharacterConstant(const LexerToken &Tok) {
Tok.getLocation(), PP);
if (Literal.hadError())
return ExprResult(true);
return new CharacterLiteral(Literal.getValue(), Context.IntTy);
return new CharacterLiteral(Literal.getValue(), Context.IntTy,
Tok.getLocation());
}
Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
@ -121,7 +122,8 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
// cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) {
const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation());
return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy));
return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy,
Tok.getLocation()));
}
SmallString<512> IntegerBuffer;
IntegerBuffer.resize(Tok.getLength());
@ -154,11 +156,11 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
}
uintmax_t val;
if (Literal.GetIntegerValue(val)) {
return new IntegerLiteral(val, t);
return new IntegerLiteral(val, t, Tok.getLocation());
}
} else if (Literal.isFloatingLiteral()) {
// FIXME: fill in the value and compute the real type...
return new FloatingLiteral(7.7, Context.FloatTy);
return new FloatingLiteral(7.7, Context.FloatTy, Tok.getLocation());
}
return ExprResult(true);
}
@ -192,8 +194,8 @@ QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType,
Action::ExprResult Sema::
ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc) {
SourceLocation LPLoc, TypeTy *Ty,
SourceLocation RPLoc) {
// If error parsing type, ignore.
if (Ty == 0) return true;
@ -204,7 +206,7 @@ ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
if (resultType.isNull())
return true;
return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, resultType);
return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, resultType, OpLoc, RPLoc);
}
@ -220,7 +222,7 @@ Action::ExprResult Sema::ParsePostfixUnaryOp(SourceLocation OpLoc,
QualType result = CheckIncrementDecrementOperand((Expr *)Input, OpLoc);
if (result.isNull())
return true;
return new UnaryOperator((Expr *)Input, Opc, result);
return new UnaryOperator((Expr *)Input, Opc, result, OpLoc);
}
Action::ExprResult Sema::
@ -266,7 +268,7 @@ ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
return Diag(LLoc, diag::err_typecheck_subscript_not_object,
baseType.getAsString());
}
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType);
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType, RLoc);
}
Action::ExprResult Sema::
@ -375,7 +377,8 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
if ((NumArgsInCall != NumArgsInProto) && !proto->isVariadic())
return true;
}
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType);
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType,
RParenLoc);
}
Action::ExprResult Sema::
@ -383,7 +386,7 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op) {
// If error parsing type, ignore.
assert((Ty != 0) && "ParseCastExpr(): missing type");
return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op);
return new CastExpr(QualType::getFromOpaquePtr(Ty), (Expr*)Op, LParenLoc);
}
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
@ -402,9 +405,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
// first, check the condition.
if (!cond->isScalarType()) { // C99 6.5.15p2
// FIXME: need to compute the location from the Cond expr node...
Diag(questionLoc, diag::err_typecheck_cond_expect_scalar,
cond.getAsString());
Diag(Cond->getSourceLocation(), diag::err_typecheck_cond_expect_scalar,
cond.getAsString());
return QualType();
}
// now check the two expressions.
@ -1115,5 +1117,5 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
}
if (resultType.isNull())
return true;
return new UnaryOperator((Expr *)Input, Opc, resultType);
return new UnaryOperator((Expr *)Input, Opc, resultType, OpLoc);
}

View File

@ -35,6 +35,12 @@ protected:
public:
QualType getType() const { return TR; }
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
virtual SourceRange getSourceRange() const = 0;
SourceLocation getSourceLocation() const { return getSourceRange().Begin(); }
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
/// incomplete type other than void. Nonarray expressions that can be lvalues:
/// - name, where name must be a variable
@ -77,11 +83,15 @@ private:
/// enum, etc.
class DeclRefExpr : public Expr {
Decl *D; // a ValueDecl or EnumConstantDecl
SourceLocation Loc;
public:
DeclRefExpr(Decl *d, QualType t) : Expr(DeclRefExprClass, t), D(d) {}
DeclRefExpr(Decl *d, QualType t, SourceLocation l) :
Expr(DeclRefExprClass, t), D(d), Loc(l) {}
Decl *getDecl() const { return D; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
@ -91,14 +101,17 @@ public:
class IntegerLiteral : public Expr {
intmax_t Value;
SourceLocation Loc;
public:
// type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
// or UnsignedLongLongTy
IntegerLiteral(intmax_t value, QualType type)
: Expr(IntegerLiteralClass, type), Value(value) {
IntegerLiteral(intmax_t value, QualType type, SourceLocation l)
: Expr(IntegerLiteralClass, type), Value(value), Loc(l) {
assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
}
intmax_t getValue() const { return Value; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@ -109,11 +122,15 @@ public:
class CharacterLiteral : public Expr {
unsigned Value;
SourceLocation Loc;
public:
// type should be IntTy
CharacterLiteral(unsigned value, QualType type)
: Expr(CharacterLiteralClass, type), Value(value) {
CharacterLiteral(unsigned value, QualType type, SourceLocation l)
: Expr(CharacterLiteralClass, type), Value(value), Loc(l) {
}
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CharacterLiteralClass;
@ -123,9 +140,13 @@ public:
class FloatingLiteral : public Expr {
float Value; // FIXME
SourceLocation Loc;
public:
FloatingLiteral(float value, QualType type) :
Expr(FloatingLiteralClass, type), Value(value) {}
FloatingLiteral(float value, QualType type, SourceLocation l)
: Expr(FloatingLiteralClass, type), Value(value), Loc(l) {}
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@ -138,14 +159,19 @@ class StringLiteral : public Expr {
const char *StrData;
unsigned ByteLength;
bool IsWide;
SourceLocation Loc;
public:
StringLiteral(const char *strData, unsigned byteLength, bool Wide, QualType t);
StringLiteral(const char *strData, unsigned byteLength, bool Wide,
QualType t, SourceLocation l);
virtual ~StringLiteral();
const char *getStrData() const { return StrData; }
unsigned getByteLength() const { return ByteLength; }
bool isWide() const { return IsWide; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass;
@ -163,6 +189,7 @@ public:
: Expr(ParenExprClass, QualType()), L(l), R(r), Val(val) {}
Expr *getSubExpr() const { return Val; }
SourceRange getSourceRange() const { return SourceRange(L, R); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@ -189,8 +216,8 @@ public:
Extension // __extension__ marker.
};
UnaryOperator(Expr *input, Opcode opc, QualType type)
: Expr(UnaryOperatorClass, type), Val(input), Opc(opc) {}
UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
: Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "sizeof" or "[pre]++"
@ -203,7 +230,13 @@ public:
Opcode getOpcode() const { return Opc; }
Expr *getSubExpr() const { return Val; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const {
if (isPostfix())
return SourceRange(getSubExpr()->getSourceRange().Begin(), Loc);
else
return SourceRange(Loc, getSubExpr()->getSourceRange().End());
}
bool isPostfix() const { return isPostfix(Opc); }
bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; }
@ -222,6 +255,7 @@ public:
private:
Expr *Val;
Opcode Opc;
SourceLocation Loc;
};
/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of
@ -229,13 +263,16 @@ private:
class SizeOfAlignOfTypeExpr : public Expr {
bool isSizeof; // true if sizeof, false if alignof.
QualType Ty;
SourceLocation OpLoc, RParenLoc;
public:
SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType) :
SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType,
SourceLocation op, SourceLocation rp) :
Expr(SizeOfAlignOfTypeExprClass, resultType),
isSizeof(issizeof), Ty(argType) {}
isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {}
bool isSizeOf() const { return isSizeof; }
QualType getArgumentType() const { return Ty; }
SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@ -251,14 +288,17 @@ public:
/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
class ArraySubscriptExpr : public Expr {
Expr *Base, *Idx;
SourceLocation Loc; // the location of the right bracket
public:
ArraySubscriptExpr(Expr *base, Expr *idx, QualType t) :
ArraySubscriptExpr(Expr *base, Expr *idx, QualType t, SourceLocation l) :
Expr(ArraySubscriptExprClass, t),
Base(base), Idx(idx) {}
Base(base), Idx(idx), Loc(l) {}
Expr *getBase() const { return Base; }
Expr *getIdx() { return Idx; }
SourceRange getSourceRange() const {
return SourceRange(Base->getSourceRange().Begin(), Loc);
}
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == ArraySubscriptExprClass;
@ -273,13 +313,18 @@ class CallExpr : public Expr {
Expr *Fn;
Expr **Args;
unsigned NumArgs;
SourceLocation Loc; // the location of the right paren
public:
CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t);
CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
SourceLocation l);
~CallExpr() {
delete [] Args;
}
Expr *getCallee() const { return Fn; }
SourceRange getSourceRange() const {
return SourceRange(Fn->getSourceRange().Begin(), Loc);
}
/// getNumArgs - Return the number of actual arguments to this call.
///
@ -316,7 +361,10 @@ public:
Expr *getBase() const { return Base; }
FieldDecl *getMemberDecl() const { return MemberDecl; }
bool isArrow() const { return IsArrow; }
virtual SourceRange getSourceRange() const {
return SourceRange(getBase()->getSourceRange().Begin(),
getMemberDecl()->getLocation());
}
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass;
@ -329,16 +377,19 @@ public:
class CastExpr : public Expr {
QualType Ty;
Expr *Op;
SourceLocation Loc; // the location of the left paren
public:
CastExpr(QualType ty, Expr *op) :
Expr(CastExprClass, ty), Ty(ty), Op(op) {}
CastExpr(QualType ty, Expr *op, SourceLocation l) :
Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {}
CastExpr(StmtClass SC, QualType ty, Expr *op) :
Expr(SC, QualType()), Ty(ty), Op(op) {}
Expr(SC, QualType()), Ty(ty), Op(op), Loc(SourceLocation()) {}
QualType getDestType() const { return Ty; }
Expr *getSubExpr() const { return Op; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const {
return SourceRange(Loc, getSubExpr()->getSourceRange().End());
}
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CastExprClass;
@ -390,6 +441,10 @@ public:
Opcode getOpcode() const { return Opc; }
Expr *getLHS() const { return LHS; }
Expr *getRHS() const { return RHS; }
virtual SourceRange getSourceRange() const {
return SourceRange(getLHS()->getSourceRange().Begin(),
getRHS()->getSourceRange().End());
}
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@ -413,7 +468,11 @@ public:
Expr *getCond() const { return Cond; }
Expr *getLHS() const { return LHS; }
Expr *getRHS() const { return RHS; }
virtual SourceRange getSourceRange() const {
return SourceRange(getCond()->getSourceRange().Begin(),
getRHS()->getSourceRange().End());
}
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == ConditionalOperatorClass;

View File

@ -50,6 +50,9 @@ namespace clang {
public:
CXXBoolLiteralExpr(bool val) :
Expr(CXXBoolLiteralExprClass, QualType()), Value(val) {}
virtual SourceRange getSourceRange() const { // FIXME
return SourceRange(SourceLocation(),SourceLocation()); }
virtual void visit(StmtVisitor &Visitor);
};

View File

@ -88,7 +88,18 @@ inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
return !(LHS == RHS);
}
/// SourceRange - a trival tuple used to represent a source range.
class SourceRange {
SourceLocation B;
SourceLocation E;
public:
SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
SourceLocation Begin() const { return B; }
SourceLocation End() const { return E; }
};
} // end namespace clang
} // end namespace llvm