[cfe-commits] r57158 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/AST/ExprConstant.cpp
Chris Lattner
sabre at nondot.org
Sun Oct 5 23:40:35 PDT 2008
Author: lattner
Date: Mon Oct 6 01:40:35 2008
New Revision: 57158
URL: http://llvm.org/viewvc/llvm-project?rev=57158&view=rev
Log:
Move folding of __builtin_classify_type out of the CallExpr
interface into the constant folding interface.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=57158&r1=57157&r2=57158&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Oct 6 01:40:35 2008
@@ -710,8 +710,6 @@
unsigned isBuiltinCall() const;
- bool isBuiltinClassifyType(llvm::APSInt &Result) const;
-
/// isBuiltinConstantExpr - Return true if this built-in call is constant.
bool isBuiltinConstantExpr(ASTContext &Ctx) const;
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=57158&r1=57157&r2=57158&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Oct 6 01:40:35 2008
@@ -12,8 +12,9 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/Expr.h"
-#include "clang/AST/DeclObjC.h"
+#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetInfo.h"
@@ -167,64 +168,6 @@
return Ctx.BuiltinInfo.isConstantExpr(BID);
}
-bool CallExpr::isBuiltinClassifyType(llvm::APSInt &Result) const {
- if (isBuiltinCall() != Builtin::BI__builtin_classify_type)
- return false;
-
- // The following enum mimics the values returned by GCC.
- enum gcc_type_class {
- no_type_class = -1,
- void_type_class, integer_type_class, char_type_class,
- enumeral_type_class, boolean_type_class,
- pointer_type_class, reference_type_class, offset_type_class,
- real_type_class, complex_type_class,
- function_type_class, method_type_class,
- record_type_class, union_type_class,
- array_type_class, string_type_class,
- lang_type_class
- };
- Result.setIsSigned(true);
-
- // If no argument was supplied, default to "no_type_class". This isn't
- // ideal, however it's what gcc does.
- Result = static_cast<uint64_t>(no_type_class);
- if (NumArgs == 0)
- return true;
-
- QualType argType = getArg(0)->getType();
- if (argType->isVoidType())
- Result = void_type_class;
- else if (argType->isEnumeralType())
- Result = enumeral_type_class;
- else if (argType->isBooleanType())
- Result = boolean_type_class;
- else if (argType->isCharType())
- Result = string_type_class; // gcc doesn't appear to use char_type_class
- else if (argType->isIntegerType())
- Result = integer_type_class;
- else if (argType->isPointerType())
- Result = pointer_type_class;
- else if (argType->isReferenceType())
- Result = reference_type_class;
- else if (argType->isRealType())
- Result = real_type_class;
- else if (argType->isComplexType())
- Result = complex_type_class;
- else if (argType->isFunctionType())
- Result = function_type_class;
- else if (argType->isStructureType())
- Result = record_type_class;
- else if (argType->isUnionType())
- Result = union_type_class;
- else if (argType->isArrayType())
- Result = array_type_class;
- else if (argType->isUnionType())
- Result = union_type_class;
- else // FIXME: offset_type_class, method_type_class, & lang_type_class?
- assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
- return true;
-}
-
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "<<=".
const char *BinaryOperator::getOpcodeStr(Opcode Op) {
@@ -755,8 +698,17 @@
case CallExprClass: {
const CallExpr *CE = cast<CallExpr>(this);
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- if (CE->isBuiltinClassifyType(Result))
- break;
+
+ // If this is a call to a builtin function, constant fold it otherwise
+ // reject it.
+ if (CE->isBuiltinCall()) {
+ APValue ResultAP;
+ if (CE->tryEvaluate(ResultAP, Ctx)) {
+ Result = ResultAP.getInt();
+ break; // It is a constant, expand it.
+ }
+ }
+
if (Loc) *Loc = getLocStart();
return false;
}
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=57158&r1=57157&r2=57158&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Oct 6 01:40:35 2008
@@ -245,6 +245,61 @@
return Error(E->getLocStart(), diag::err_expr_not_constant);
}
+/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
+/// as GCC.
+static int EvaluateBuiltinClassifyType(const CallExpr *E) {
+ // The following enum mimics the values returned by GCC.
+ enum gcc_type_class {
+ no_type_class = -1,
+ void_type_class, integer_type_class, char_type_class,
+ enumeral_type_class, boolean_type_class,
+ pointer_type_class, reference_type_class, offset_type_class,
+ real_type_class, complex_type_class,
+ function_type_class, method_type_class,
+ record_type_class, union_type_class,
+ array_type_class, string_type_class,
+ lang_type_class
+ };
+
+ // If no argument was supplied, default to "no_type_class". This isn't
+ // ideal, however it is what gcc does.
+ if (E->getNumArgs() == 0)
+ return no_type_class;
+
+ QualType ArgTy = E->getArg(0)->getType();
+ if (ArgTy->isVoidType())
+ return void_type_class;
+ else if (ArgTy->isEnumeralType())
+ return enumeral_type_class;
+ else if (ArgTy->isBooleanType())
+ return boolean_type_class;
+ else if (ArgTy->isCharType())
+ return string_type_class; // gcc doesn't appear to use char_type_class
+ else if (ArgTy->isIntegerType())
+ return integer_type_class;
+ else if (ArgTy->isPointerType())
+ return pointer_type_class;
+ else if (ArgTy->isReferenceType())
+ return reference_type_class;
+ else if (ArgTy->isRealType())
+ return real_type_class;
+ else if (ArgTy->isComplexType())
+ return complex_type_class;
+ else if (ArgTy->isFunctionType())
+ return function_type_class;
+ else if (ArgTy->isStructureType())
+ return record_type_class;
+ else if (ArgTy->isUnionType())
+ return union_type_class;
+ else if (ArgTy->isArrayType())
+ return array_type_class;
+ else if (ArgTy->isUnionType())
+ return union_type_class;
+ else // FIXME: offset_type_class, method_type_class, & lang_type_class?
+ assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
+ return -1;
+}
+
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
@@ -252,8 +307,8 @@
default:
return Error(E->getLocStart(), diag::err_expr_not_constant);
case Builtin::BI__builtin_classify_type:
- // __builtin_type_compatible_p is a constant. Return its value.
- E->isBuiltinClassifyType(Result);
+ Result.setIsSigned(true);
+ Result = EvaluateBuiltinClassifyType(E);
return true;
case Builtin::BI__builtin_constant_p: {
More information about the cfe-commits
mailing list