[cfe-commits] r41180 - in /cfe/trunk: AST/StmtDumper.cpp AST/StmtPrinter.cpp CodeGen/CGExpr.cpp Sema/SemaChecking.cpp include/clang/AST/Expr.h
Ted Kremenek
kremenek at apple.com
Mon Aug 20 09:18:39 PDT 2007
Author: kremenek
Date: Mon Aug 20 11:18:38 2007
New Revision: 41180
URL: http://llvm.org/viewvc/llvm-project?rev=41180&view=rev
Log:
Modified ArraySubscriptExpr to have accessors getLHS and getRHS in addition
to getBase and getIdx. getBase and getIdx now return a "normalized" view
of the expression (e.g., always "A[4]" instead of possibly "4[A]"). getLHS
and getRHS return the expressions with syntactic fidelity to the original
source code.
Also modified client code of ArraySubscriptExpr, including the AST dumper
and pretty printer, the return-stack value checker, and the LLVM code
generator.
Modified:
cfe/trunk/AST/StmtDumper.cpp
cfe/trunk/AST/StmtPrinter.cpp
cfe/trunk/CodeGen/CGExpr.cpp
cfe/trunk/Sema/SemaChecking.cpp
cfe/trunk/include/clang/AST/Expr.h
Modified: cfe/trunk/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtDumper.cpp?rev=41180&r1=41179&r2=41180&view=diff
==============================================================================
--- cfe/trunk/AST/StmtDumper.cpp (original)
+++ cfe/trunk/AST/StmtDumper.cpp Mon Aug 20 11:18:38 2007
@@ -374,9 +374,9 @@
void StmtDumper::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
DumpExpr(Node);
fprintf(F, "\n");
- DumpSubTree(Node->getBase());
+ DumpSubTree(Node->getLHS());
fprintf(F, "\n");
- DumpSubTree(Node->getIdx());
+ DumpSubTree(Node->getRHS());
fprintf(F, ")");
}
Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=41180&r1=41179&r2=41180&view=diff
==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Mon Aug 20 11:18:38 2007
@@ -417,9 +417,9 @@
OS << Node->getArgumentType().getAsString() << ")";
}
void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
- PrintExpr(Node->getBase());
+ PrintExpr(Node->getLHS());
OS << "[";
- PrintExpr(Node->getIdx());
+ PrintExpr(Node->getRHS());
OS << "]";
}
Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=41180&r1=41179&r2=41180&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Mon Aug 20 11:18:38 2007
@@ -495,35 +495,24 @@
}
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
- // The index must always be a pointer or integer, neither of which is an
- // aggregate. Emit it.
+ // The index must always be an integer, which is not an aggregate. Emit it.
llvm::Value *Idx = EmitExpr(E->getIdx()).getVal();
// If the base is a vector type, then we are forming a vector element lvalue
// with this subscript.
- if (E->getBase()->getType()->isVectorType()) {
+ if (E->getLHS()->getType()->isVectorType()) {
// Emit the vector as an lvalue to get its address.
- LValue Base = EmitLValue(E->getBase());
- assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
+ LValue LHS = EmitLValue(E->getLHS());
+ assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
// FIXME: This should properly sign/zero/extend or truncate Idx to i32.
- return LValue::MakeVectorElt(Base.getAddress(), Idx);
+ return LValue::MakeVectorElt(LHS.getAddress(), Idx);
}
- // At this point, the base must be a pointer or integer, neither of which are
- // aggregates. Emit it.
+ // The base must be a pointer, which is not an aggregate. Emit it.
llvm::Value *Base = EmitExpr(E->getBase()).getVal();
- // Usually the base is the pointer type, but sometimes it is the index.
- // Canonicalize to have the pointer as the base.
- QualType BaseTy = E->getBase()->getType();
+ // Extend or truncate the index type to 32 or 64-bits.
QualType IdxTy = E->getIdx()->getType();
- if (isa<llvm::PointerType>(Idx->getType())) {
- std::swap(Base, Idx);
- std::swap(BaseTy, IdxTy);
- }
-
- // The pointer is now the base. Extend or truncate the index type to 32 or
- // 64-bits.
bool IdxSigned = IdxTy->isSignedIntegerType();
unsigned IdxBitwidth = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
if (IdxBitwidth != LLVMPointerWidth)
Modified: cfe/trunk/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaChecking.cpp?rev=41180&r1=41179&r2=41180&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/Sema/SemaChecking.cpp Mon Aug 20 11:18:38 2007
@@ -16,6 +16,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Basic/SourceManager.h"
@@ -499,9 +500,24 @@
return NULL;
}
- // TODO: C++ casts.
- case Stmt::CXXCastExprClass:
- return NULL;
+ // C++ casts. For dynamic casts, static casts, and const casts, we
+ // are always converting from a pointer-to-pointer, so we just blow
+ // through the cast. In the case the dynamic cast doesn't fail
+ // (and return NULL), we take the conservative route and report cases
+ // where we return the address of a stack variable. For Reinterpre
+ case Stmt::CXXCastExprClass: {
+ CXXCastExpr *C = cast<CXXCastExpr>(E);
+
+ if (C->getOpcode() == CXXCastExpr::ReinterpretCast) {
+ Expr *S = C->getSubExpr();
+ if (S->getType()->isPointerType())
+ return EvalAddr(S);
+ else
+ return NULL;
+ }
+ else
+ return EvalAddr(C->getSubExpr());
+ }
// Everything else: we simply don't reason about them.
default:
@@ -554,18 +570,7 @@
// Array subscripts are potential references to data on the stack. We
// retrieve the DeclRefExpr* for the array variable if it indeed
// has local storage.
- ArraySubscriptExpr *A = cast<ArraySubscriptExpr>(E);
-
- // The array access could be written A[4] or 4[A] (both are equivalent).
- // In the second case, the "base" is the offset and the "Idx" is
- // the base. We test for this case by seeing if the Base expression
- // has a pointer type.
- Expr* Base = A->getBase();
-
- if (Base->getType()->isPointerType())
- return EvalAddr(Base);
- else
- return EvalAddr(A->getIdx());
+ return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase());
}
case Stmt::ConditionalOperatorClass: {
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=41180&r1=41179&r2=41180&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Aug 20 11:18:38 2007
@@ -367,26 +367,38 @@
/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
class ArraySubscriptExpr : public Expr {
- Expr *Base, *Idx;
+ Expr *LHS, *RHS;
SourceLocation RBracketLoc;
public:
- ArraySubscriptExpr(Expr *base, Expr *idx, QualType t,
+ ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
SourceLocation rbracketloc) :
Expr(ArraySubscriptExprClass, t),
- Base(base), Idx(idx), RBracketLoc(rbracketloc) {}
+ LHS(lhs), RHS(rhs), RBracketLoc(rbracketloc) {}
- // NOTE: An array access can be written A[4] or 4[A] (both are equivalent).
- // In the second case, getBase() actually returns the index and getIdx()
- // returns the offset. Only one of the subexpressions will have a pointer
- // type (the base), so the second case can be identified using the
- // expression getBase()->getType()->isPointerType().
- Expr *getBase() { return Base; }
- const Expr *getBase() const { return Base; }
- Expr *getIdx() { return Idx; }
- const Expr *getIdx() const { return Idx; }
+ /// An array access can be written A[4] or 4[A] (both are equivalent).
+ /// - getBase() and getIdx() always present the normalized view: A[4].
+ /// In this case getBase() returns "A" and getIdx() returns "4".
+ /// - getLHS() and getRHS() present the syntactic view. e.g. for
+ /// 4[A] getLHS() returns "4".
+
+ Expr *getBase() { return (LHS->getType()->isIntegerType()) ? RHS : LHS; }
+ const Expr *getBase() const {
+ return (LHS->getType()->isIntegerType()) ? RHS : LHS;
+ }
+
+ Expr *getIdx() { return (LHS->getType()->isIntegerType()) ? LHS : RHS; }
+ const Expr *getIdx() const {
+ return (LHS->getType()->isIntegerType()) ? LHS : RHS;
+ }
+
+ Expr *getLHS() { return LHS; }
+ const Expr *getLHS() const { return LHS; }
+
+ Expr *getRHS() { return RHS; }
+ const Expr *getRHS() const { return RHS; }
SourceRange getSourceRange() const {
- return SourceRange(Base->getLocStart(), RBracketLoc);
+ return SourceRange(LHS->getLocStart(), RBracketLoc);
}
virtual SourceLocation getExprLoc() const { return RBracketLoc; }
More information about the cfe-commits
mailing list