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, StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
bool Wide, QualType t) : bool Wide, QualType t, SourceLocation l) :
Expr(StringLiteralClass, t) { Expr(StringLiteralClass, t) {
// OPTIMIZE: could allocate this appended to the StringLiteral. // OPTIMIZE: could allocate this appended to the StringLiteral.
char *AStrData = new char[byteLength]; char *AStrData = new char[byteLength];
@ -30,6 +30,7 @@ StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
StrData = AStrData; StrData = AStrData;
ByteLength = byteLength; ByteLength = byteLength;
IsWide = Wide; IsWide = Wide;
Loc = l;
} }
StringLiteral::~StringLiteral() { StringLiteral::~StringLiteral() {
@ -73,11 +74,13 @@ const char *UnaryOperator::getOpcodeStr(Opcode Op) {
// Postfix Operators. // 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) { : Expr(CallExprClass, t), Fn(fn), NumArgs(numargs) {
Args = new Expr*[numargs]; Args = new Expr*[numargs];
for (unsigned i = 0; i != numargs; ++i) for (unsigned i = 0; i != numargs; ++i)
Args[i] = args[i]; Args[i] = args[i];
Loc = l;
} }
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// 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. // FIXME: use factory.
// Pass &StringTokLocs[0], StringTokLocs.size() to factory! // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(), 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)) if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
return new DeclRefExpr(VD, VD->getType()); return new DeclRefExpr(VD, VD->getType(), Loc);
if (isa<TypedefDecl>(D)) if (isa<TypedefDecl>(D))
return Diag(Loc, diag::err_unexpected_typedef, II.getName()); return Diag(Loc, diag::err_unexpected_typedef, II.getName());
@ -113,7 +113,8 @@ Sema::ExprResult Sema::ParseCharacterConstant(const LexerToken &Tok) {
Tok.getLocation(), PP); Tok.getLocation(), PP);
if (Literal.hadError()) if (Literal.hadError())
return ExprResult(true); 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) { 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. // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) { if (Tok.getLength() == 1) {
const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation()); 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; SmallString<512> IntegerBuffer;
IntegerBuffer.resize(Tok.getLength()); IntegerBuffer.resize(Tok.getLength());
@ -154,11 +156,11 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
} }
uintmax_t val; uintmax_t val;
if (Literal.GetIntegerValue(val)) { if (Literal.GetIntegerValue(val)) {
return new IntegerLiteral(val, t); return new IntegerLiteral(val, t, Tok.getLocation());
} }
} else if (Literal.isFloatingLiteral()) { } else if (Literal.isFloatingLiteral()) {
// FIXME: fill in the value and compute the real type... // 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); return ExprResult(true);
} }
@ -192,8 +194,8 @@ QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType,
Action::ExprResult Sema:: Action::ExprResult Sema::
ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof, ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
SourceLocation LParenLoc, TypeTy *Ty, SourceLocation LPLoc, TypeTy *Ty,
SourceLocation RParenLoc) { SourceLocation RPLoc) {
// If error parsing type, ignore. // If error parsing type, ignore.
if (Ty == 0) return true; if (Ty == 0) return true;
@ -204,7 +206,7 @@ ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
if (resultType.isNull()) if (resultType.isNull())
return true; 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); QualType result = CheckIncrementDecrementOperand((Expr *)Input, OpLoc);
if (result.isNull()) if (result.isNull())
return true; return true;
return new UnaryOperator((Expr *)Input, Opc, result); return new UnaryOperator((Expr *)Input, Opc, result, OpLoc);
} }
Action::ExprResult Sema:: Action::ExprResult Sema::
@ -266,7 +268,7 @@ ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
return Diag(LLoc, diag::err_typecheck_subscript_not_object, return Diag(LLoc, diag::err_typecheck_subscript_not_object,
baseType.getAsString()); baseType.getAsString());
} }
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType); return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType, RLoc);
} }
Action::ExprResult Sema:: Action::ExprResult Sema::
@ -375,7 +377,8 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
if ((NumArgsInCall != NumArgsInProto) && !proto->isVariadic()) if ((NumArgsInCall != NumArgsInProto) && !proto->isVariadic())
return true; return true;
} }
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType); return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType,
RParenLoc);
} }
Action::ExprResult Sema:: Action::ExprResult Sema::
@ -383,7 +386,7 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op) { SourceLocation RParenLoc, ExprTy *Op) {
// If error parsing type, ignore. // If error parsing type, ignore.
assert((Ty != 0) && "ParseCastExpr(): missing type"); 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 inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
@ -402,9 +405,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
// first, check the condition. // first, check the condition.
if (!cond->isScalarType()) { // C99 6.5.15p2 if (!cond->isScalarType()) { // C99 6.5.15p2
// FIXME: need to compute the location from the Cond expr node... Diag(Cond->getSourceLocation(), diag::err_typecheck_cond_expect_scalar,
Diag(questionLoc, diag::err_typecheck_cond_expect_scalar, cond.getAsString());
cond.getAsString());
return QualType(); return QualType();
} }
// now check the two expressions. // now check the two expressions.
@ -1115,5 +1117,5 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
} }
if (resultType.isNull()) if (resultType.isNull())
return true; 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. // FIXME: use factory.
// Pass &StringTokLocs[0], StringTokLocs.size() to factory! // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(), 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)) if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
return new DeclRefExpr(VD, VD->getType()); return new DeclRefExpr(VD, VD->getType(), Loc);
if (isa<TypedefDecl>(D)) if (isa<TypedefDecl>(D))
return Diag(Loc, diag::err_unexpected_typedef, II.getName()); return Diag(Loc, diag::err_unexpected_typedef, II.getName());
@ -113,7 +113,8 @@ Sema::ExprResult Sema::ParseCharacterConstant(const LexerToken &Tok) {
Tok.getLocation(), PP); Tok.getLocation(), PP);
if (Literal.hadError()) if (Literal.hadError())
return ExprResult(true); 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) { 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. // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) { if (Tok.getLength() == 1) {
const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation()); 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; SmallString<512> IntegerBuffer;
IntegerBuffer.resize(Tok.getLength()); IntegerBuffer.resize(Tok.getLength());
@ -154,11 +156,11 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
} }
uintmax_t val; uintmax_t val;
if (Literal.GetIntegerValue(val)) { if (Literal.GetIntegerValue(val)) {
return new IntegerLiteral(val, t); return new IntegerLiteral(val, t, Tok.getLocation());
} }
} else if (Literal.isFloatingLiteral()) { } else if (Literal.isFloatingLiteral()) {
// FIXME: fill in the value and compute the real type... // 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); return ExprResult(true);
} }
@ -192,8 +194,8 @@ QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType,
Action::ExprResult Sema:: Action::ExprResult Sema::
ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof, ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
SourceLocation LParenLoc, TypeTy *Ty, SourceLocation LPLoc, TypeTy *Ty,
SourceLocation RParenLoc) { SourceLocation RPLoc) {
// If error parsing type, ignore. // If error parsing type, ignore.
if (Ty == 0) return true; if (Ty == 0) return true;
@ -204,7 +206,7 @@ ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
if (resultType.isNull()) if (resultType.isNull())
return true; 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); QualType result = CheckIncrementDecrementOperand((Expr *)Input, OpLoc);
if (result.isNull()) if (result.isNull())
return true; return true;
return new UnaryOperator((Expr *)Input, Opc, result); return new UnaryOperator((Expr *)Input, Opc, result, OpLoc);
} }
Action::ExprResult Sema:: Action::ExprResult Sema::
@ -266,7 +268,7 @@ ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
return Diag(LLoc, diag::err_typecheck_subscript_not_object, return Diag(LLoc, diag::err_typecheck_subscript_not_object,
baseType.getAsString()); baseType.getAsString());
} }
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType); return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType, RLoc);
} }
Action::ExprResult Sema:: Action::ExprResult Sema::
@ -375,7 +377,8 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
if ((NumArgsInCall != NumArgsInProto) && !proto->isVariadic()) if ((NumArgsInCall != NumArgsInProto) && !proto->isVariadic())
return true; return true;
} }
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType); return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgsInCall, resultType,
RParenLoc);
} }
Action::ExprResult Sema:: Action::ExprResult Sema::
@ -383,7 +386,7 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op) { SourceLocation RParenLoc, ExprTy *Op) {
// If error parsing type, ignore. // If error parsing type, ignore.
assert((Ty != 0) && "ParseCastExpr(): missing type"); 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 inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
@ -402,9 +405,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
// first, check the condition. // first, check the condition.
if (!cond->isScalarType()) { // C99 6.5.15p2 if (!cond->isScalarType()) { // C99 6.5.15p2
// FIXME: need to compute the location from the Cond expr node... Diag(Cond->getSourceLocation(), diag::err_typecheck_cond_expect_scalar,
Diag(questionLoc, diag::err_typecheck_cond_expect_scalar, cond.getAsString());
cond.getAsString());
return QualType(); return QualType();
} }
// now check the two expressions. // now check the two expressions.
@ -1115,5 +1117,5 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
} }
if (resultType.isNull()) if (resultType.isNull())
return true; 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: public:
QualType getType() const { return TR; } 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 /// 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: /// incomplete type other than void. Nonarray expressions that can be lvalues:
/// - name, where name must be a variable /// - name, where name must be a variable
@ -77,11 +83,15 @@ private:
/// enum, etc. /// enum, etc.
class DeclRefExpr : public Expr { class DeclRefExpr : public Expr {
Decl *D; // a ValueDecl or EnumConstantDecl Decl *D; // a ValueDecl or EnumConstantDecl
SourceLocation Loc;
public: 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; } Decl *getDecl() const { return D; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass; return T->getStmtClass() == DeclRefExprClass;
@ -91,14 +101,17 @@ public:
class IntegerLiteral : public Expr { class IntegerLiteral : public Expr {
intmax_t Value; intmax_t Value;
SourceLocation Loc;
public: public:
// type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
// or UnsignedLongLongTy // or UnsignedLongLongTy
IntegerLiteral(intmax_t value, QualType type) IntegerLiteral(intmax_t value, QualType type, SourceLocation l)
: Expr(IntegerLiteralClass, type), Value(value) { : Expr(IntegerLiteralClass, type), Value(value), Loc(l) {
assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
} }
intmax_t getValue() const { return Value; } intmax_t getValue() const { return Value; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
@ -109,11 +122,15 @@ public:
class CharacterLiteral : public Expr { class CharacterLiteral : public Expr {
unsigned Value; unsigned Value;
SourceLocation Loc;
public: public:
// type should be IntTy // type should be IntTy
CharacterLiteral(unsigned value, QualType type) CharacterLiteral(unsigned value, QualType type, SourceLocation l)
: Expr(CharacterLiteralClass, type), Value(value) { : 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); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == CharacterLiteralClass; return T->getStmtClass() == CharacterLiteralClass;
@ -123,9 +140,13 @@ public:
class FloatingLiteral : public Expr { class FloatingLiteral : public Expr {
float Value; // FIXME float Value; // FIXME
SourceLocation Loc;
public: public:
FloatingLiteral(float value, QualType type) : FloatingLiteral(float value, QualType type, SourceLocation l)
Expr(FloatingLiteralClass, type), Value(value) {} : 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); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
@ -138,14 +159,19 @@ class StringLiteral : public Expr {
const char *StrData; const char *StrData;
unsigned ByteLength; unsigned ByteLength;
bool IsWide; bool IsWide;
SourceLocation Loc;
public: 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(); virtual ~StringLiteral();
const char *getStrData() const { return StrData; } const char *getStrData() const { return StrData; }
unsigned getByteLength() const { return ByteLength; } unsigned getByteLength() const { return ByteLength; }
bool isWide() const { return IsWide; } bool isWide() const { return IsWide; }
SourceLocation getSourceLocation() const { return Loc; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc,Loc); }
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass; return T->getStmtClass() == StringLiteralClass;
@ -163,6 +189,7 @@ public:
: Expr(ParenExprClass, QualType()), L(l), R(r), Val(val) {} : Expr(ParenExprClass, QualType()), L(l), R(r), Val(val) {}
Expr *getSubExpr() const { return Val; } Expr *getSubExpr() const { return Val; }
SourceRange getSourceRange() const { return SourceRange(L, R); }
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
@ -189,8 +216,8 @@ public:
Extension // __extension__ marker. Extension // __extension__ marker.
}; };
UnaryOperator(Expr *input, Opcode opc, QualType type) UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
: Expr(UnaryOperatorClass, type), Val(input), Opc(opc) {} : Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "sizeof" or "[pre]++" /// corresponds to, e.g. "sizeof" or "[pre]++"
@ -203,7 +230,13 @@ public:
Opcode getOpcode() const { return Opc; } Opcode getOpcode() const { return Opc; }
Expr *getSubExpr() const { return Val; } 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 isPostfix() const { return isPostfix(Opc); }
bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; } bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; } bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; }
@ -222,6 +255,7 @@ public:
private: private:
Expr *Val; Expr *Val;
Opcode Opc; Opcode Opc;
SourceLocation Loc;
}; };
/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of /// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of
@ -229,13 +263,16 @@ private:
class SizeOfAlignOfTypeExpr : public Expr { class SizeOfAlignOfTypeExpr : public Expr {
bool isSizeof; // true if sizeof, false if alignof. bool isSizeof; // true if sizeof, false if alignof.
QualType Ty; QualType Ty;
SourceLocation OpLoc, RParenLoc;
public: public:
SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType) : SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType,
SourceLocation op, SourceLocation rp) :
Expr(SizeOfAlignOfTypeExprClass, resultType), Expr(SizeOfAlignOfTypeExprClass, resultType),
isSizeof(issizeof), Ty(argType) {} isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {}
bool isSizeOf() const { return isSizeof; } bool isSizeOf() const { return isSizeof; }
QualType getArgumentType() const { return Ty; } QualType getArgumentType() const { return Ty; }
SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); }
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
@ -251,14 +288,17 @@ public:
/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting. /// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
class ArraySubscriptExpr : public Expr { class ArraySubscriptExpr : public Expr {
Expr *Base, *Idx; Expr *Base, *Idx;
SourceLocation Loc; // the location of the right bracket
public: public:
ArraySubscriptExpr(Expr *base, Expr *idx, QualType t) : ArraySubscriptExpr(Expr *base, Expr *idx, QualType t, SourceLocation l) :
Expr(ArraySubscriptExprClass, t), Expr(ArraySubscriptExprClass, t),
Base(base), Idx(idx) {} Base(base), Idx(idx), Loc(l) {}
Expr *getBase() const { return Base; } Expr *getBase() const { return Base; }
Expr *getIdx() { return Idx; } Expr *getIdx() { return Idx; }
SourceRange getSourceRange() const {
return SourceRange(Base->getSourceRange().Begin(), Loc);
}
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == ArraySubscriptExprClass; return T->getStmtClass() == ArraySubscriptExprClass;
@ -273,13 +313,18 @@ class CallExpr : public Expr {
Expr *Fn; Expr *Fn;
Expr **Args; Expr **Args;
unsigned NumArgs; unsigned NumArgs;
SourceLocation Loc; // the location of the right paren
public: public:
CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t); CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
SourceLocation l);
~CallExpr() { ~CallExpr() {
delete [] Args; delete [] Args;
} }
Expr *getCallee() const { return Fn; } Expr *getCallee() const { return Fn; }
SourceRange getSourceRange() const {
return SourceRange(Fn->getSourceRange().Begin(), Loc);
}
/// getNumArgs - Return the number of actual arguments to this call. /// getNumArgs - Return the number of actual arguments to this call.
/// ///
@ -316,7 +361,10 @@ public:
Expr *getBase() const { return Base; } Expr *getBase() const { return Base; }
FieldDecl *getMemberDecl() const { return MemberDecl; } FieldDecl *getMemberDecl() const { return MemberDecl; }
bool isArrow() const { return IsArrow; } bool isArrow() const { return IsArrow; }
virtual SourceRange getSourceRange() const {
return SourceRange(getBase()->getSourceRange().Begin(),
getMemberDecl()->getLocation());
}
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass; return T->getStmtClass() == MemberExprClass;
@ -329,16 +377,19 @@ public:
class CastExpr : public Expr { class CastExpr : public Expr {
QualType Ty; QualType Ty;
Expr *Op; Expr *Op;
SourceLocation Loc; // the location of the left paren
public: public:
CastExpr(QualType ty, Expr *op) : CastExpr(QualType ty, Expr *op, SourceLocation l) :
Expr(CastExprClass, ty), Ty(ty), Op(op) {} Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {}
CastExpr(StmtClass SC, QualType ty, Expr *op) : 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; } QualType getDestType() const { return Ty; }
Expr *getSubExpr() const { return Op; } 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); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == CastExprClass; return T->getStmtClass() == CastExprClass;
@ -390,6 +441,10 @@ public:
Opcode getOpcode() const { return Opc; } Opcode getOpcode() const { return Opc; }
Expr *getLHS() const { return LHS; } Expr *getLHS() const { return LHS; }
Expr *getRHS() const { return RHS; } Expr *getRHS() const { return RHS; }
virtual SourceRange getSourceRange() const {
return SourceRange(getLHS()->getSourceRange().Begin(),
getRHS()->getSourceRange().End());
}
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
@ -413,7 +468,11 @@ public:
Expr *getCond() const { return Cond; } Expr *getCond() const { return Cond; }
Expr *getLHS() const { return LHS; } Expr *getLHS() const { return LHS; }
Expr *getRHS() const { return RHS; } Expr *getRHS() const { return RHS; }
virtual SourceRange getSourceRange() const {
return SourceRange(getCond()->getSourceRange().Begin(),
getRHS()->getSourceRange().End());
}
virtual void visit(StmtVisitor &Visitor); virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == ConditionalOperatorClass; return T->getStmtClass() == ConditionalOperatorClass;

View File

@ -50,6 +50,9 @@ namespace clang {
public: public:
CXXBoolLiteralExpr(bool val) : CXXBoolLiteralExpr(bool val) :
Expr(CXXBoolLiteralExprClass, QualType()), Value(val) {} Expr(CXXBoolLiteralExprClass, QualType()), Value(val) {}
virtual SourceRange getSourceRange() const { // FIXME
return SourceRange(SourceLocation(),SourceLocation()); }
virtual void visit(StmtVisitor &Visitor); 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) { inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
return !(LHS == 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 clang
} // end namespace llvm } // end namespace llvm