forked from OSchip/llvm-project
Shuffle things around in preparation for integrating Eli's constant evaluator.
llvm-svn: 53074
This commit is contained in:
parent
ac1d1d1c34
commit
7a241baf2f
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -29,6 +29,7 @@ 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
|
||||
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue