Shuffle things around in preparation for integrating Eli's constant evaluator.

llvm-svn: 53074
This commit is contained in:
Anders Carlsson 2008-07-03 04:20:39 +00:00
parent ac1d1d1c34
commit 7a241baf2f
6 changed files with 86 additions and 38 deletions

View File

@ -10,6 +10,7 @@
035611E20DB40C8100D2EF2A /* RewriteObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 035611E10DB40C8100D2EF2A /* RewriteObjC.cpp */; };
03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F50AC50D416EAA00B9CF60 /* Targets.cpp */; };
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
1A32C17F0E1C87AD00A6B483 /* ExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A32C17E0E1C87AD00A6B483 /* ExprConstant.cpp */; };
1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */; };
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
@ -260,6 +261,7 @@
035611E10DB40C8100D2EF2A /* RewriteObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteObjC.cpp; path = Driver/RewriteObjC.cpp; sourceTree = "<group>"; };
03F50AC50D416EAA00B9CF60 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Targets.cpp; sourceTree = "<group>"; };
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
1A32C17E0E1C87AD00A6B483 /* ExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ExprConstant.cpp; path = lib/AST/ExprConstant.cpp; sourceTree = "<group>"; tabWidth = 2; };
1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprConstant.cpp; path = lib/CodeGen/CGExprConstant.cpp; sourceTree = "<group>"; };
1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PPCBuiltins.def; path = clang/AST/PPCBuiltins.def; sourceTree = "<group>"; };
1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetBuiltins.h; path = clang/AST/TargetBuiltins.h; sourceTree = "<group>"; };
@ -406,7 +408,7 @@
DE5932CE0AD60FF400BC794C /* clang.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = clang.h; path = Driver/clang.h; sourceTree = "<group>"; };
DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintParserCallbacks.cpp; path = Driver/PrintParserCallbacks.cpp; sourceTree = "<group>"; };
DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintPreprocessedOutput.cpp; path = Driver/PrintPreprocessedOutput.cpp; sourceTree = "<group>"; };
DE613EF30E0E148D00B05B79 /* APValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APValue.h; path = clang/AST/APValue.h; sourceTree = "<group>"; };
DE613EF30E0E148D00B05B79 /* APValue.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = APValue.h; path = clang/AST/APValue.h; sourceTree = "<group>"; tabWidth = 2; };
DE67E70A0C020EC500F66BC5 /* SemaType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaType.cpp; path = lib/Sema/SemaType.cpp; sourceTree = "<group>"; };
DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaStmt.cpp; path = lib/Sema/SemaStmt.cpp; sourceTree = "<group>"; };
DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprCXX.cpp; path = lib/Sema/SemaExprCXX.cpp; sourceTree = "<group>"; };
@ -826,6 +828,7 @@
DE38CF260D8C9E6C00A273B6 /* DeclObjC.cpp */,
3513185F0CD14468006B66F7 /* DeclSerialization.cpp */,
DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
1A32C17E0E1C87AD00A6B483 /* ExprConstant.cpp */,
35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */,
DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */,
@ -1121,6 +1124,7 @@
3534A01D0E129849002709B2 /* ParseCXXInlineMethods.cpp in Sources */,
DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */,
359DBBD40E1AC9CC00F43FA0 /* AnalysisConsumer.cpp in Sources */,
1A32C17F0E1C87AD00A6B483 /* ExprConstant.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -18,9 +18,10 @@
#include "llvm/ADT/APFloat.h"
namespace clang {
class Expr;
/// APValue - This class implements a discriminated union of [uninitialized]
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat].
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
class APValue {
typedef llvm::APSInt APSInt;
typedef llvm::APFloat APFloat;
@ -30,7 +31,8 @@ public:
SInt,
Float,
ComplexSInt,
ComplexFloat
ComplexFloat,
LValue
};
private:
ValueKind Kind;
@ -44,6 +46,11 @@ private:
ComplexAPFloat() : Real(0.0), Imag(0.0) {}
};
struct LValue {
Expr* Base;
uint64_t Offset;
};
enum {
MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))

View File

@ -29,7 +29,8 @@ namespace clang {
class Selector;
class Decl;
class ASTContext;
class APValue;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
/// is required.
@ -108,6 +109,8 @@ public:
/// isConstantExpr - Return true if this expression is a valid constant expr.
bool isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const;
bool tryEvaluate(APValue& Result, ASTContext &Ctx) const;
/// hasGlobalStorage - Return true if this expression has static storage
/// duration. This means that the address of this expression is a link-time
/// constant.

View File

@ -13,6 +13,7 @@
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/APValue.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"

View File

@ -0,0 +1,60 @@
//===--- Expr.cpp - Expression Constant Evaluator -------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Expr constant evaluator.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
using namespace clang;
static bool CalcFakeICEVal(const Expr* Expr,
llvm::APSInt& Result,
ASTContext& Context) {
// Calculate the value of an expression that has a calculatable
// value, but isn't an ICE. Currently, this only supports
// a very narrow set of extensions, but it can be expanded if needed.
if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
QualType CETy = CE->getType();
if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
CETy->isPointerType()) {
if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
Result.extOrTrunc(Context.getTypeSize(CETy));
// FIXME: This assumes pointers are signed.
Result.setIsSigned(CETy->isSignedIntegerType() ||
CETy->isPointerType());
return true;
}
}
}
if (Expr->getType()->isIntegralType())
return Expr->isIntegerConstantExpr(Result, Context);
return false;
}
bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const
{
llvm::APSInt sInt(1);
if (CalcFakeICEVal(this, sInt, Ctx)) {
Result = APValue(sInt);
return true;
}
return false;
}

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "Sema.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
@ -1799,48 +1800,20 @@ void Sema::ActOnDefs(Scope *S, SourceLocation DeclStart,
CollectIvars(Class, Decls);
}
static bool CalcFakeICEVal(const Expr* Expr,
llvm::APSInt& Result,
ASTContext& Context) {
// Calculate the value of an expression that has a calculatable
// value, but isn't an ICE. Currently, this only supports
// a very narrow set of extensions, but it can be expanded if needed.
if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
QualType CETy = CE->getType();
if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
CETy->isPointerType()) {
if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
Result.extOrTrunc(Context.getTypeSize(CETy));
// FIXME: This assumes pointers are signed.
Result.setIsSigned(CETy->isSignedIntegerType() ||
CETy->isPointerType());
return true;
}
}
}
if (Expr->getType()->isIntegralType())
return Expr->isIntegerConstantExpr(Result, Context);
return false;
}
QualType Sema::TryFixInvalidVariablyModifiedType(QualType T) {
// This method tries to turn a variable array into a constant
// array even when the size isn't an ICE. This is necessary
// for compatibility with code that depends on gcc's buggy
// constant expression folding, like struct {char x[(int)(char*)2];}
if (const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T)) {
llvm::APSInt Result(32);
APValue Result;
if (VLATy->getSizeExpr() &&
CalcFakeICEVal(VLATy->getSizeExpr(), Result, Context) &&
Result > llvm::APSInt(Result.getBitWidth(), Result.isUnsigned())) {
VLATy->getSizeExpr()->tryEvaluate(Result, Context) && Result.isSInt() &&
Result.getSInt() > llvm::APSInt(Result.getSInt().getBitWidth(),
Result.getSInt().isUnsigned())) {
return Context.getConstantArrayType(VLATy->getElementType(),
Result, ArrayType::Normal, 0);
Result.getSInt(),
ArrayType::Normal, 0);
}
}
return QualType();