From 64c34f1c6f613eef02a7b488f8edadbe7a8650a8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 16 Nov 2008 07:46:48 +0000 Subject: [PATCH] add dump and print methods, add operator<< for APValue. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59411 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/APValue.h | 8 +++ lib/AST/APValue.cpp | 97 +++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 lib/AST/APValue.cpp diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index eac97a613e..48a9bf1a6e 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -92,6 +92,9 @@ public: bool isComplexFloat() const { return Kind == ComplexFloat; } bool isLValue() const { return Kind == LValue; } + void print(llvm::raw_ostream &OS) const; + void dump() const; + APSInt &getInt() { assert(isInt() && "Invalid accessor"); return *(APSInt*)(void*)Data; @@ -204,6 +207,11 @@ private: } }; +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) { + V.print(OS); + return OS; } + +} // end namespace clang. #endif diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp new file mode 100644 index 0000000000..38a89aa99e --- /dev/null +++ b/lib/AST/APValue.cpp @@ -0,0 +1,97 @@ +//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===// +// +// 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 APValue class. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/APValue.h" +#include "llvm/Support/raw_ostream.h" +using namespace clang; + + +const APValue &APValue::operator=(const APValue &RHS) { + if (Kind != RHS.Kind) { + MakeUninit(); + if (RHS.isInt()) + MakeInt(); + else if (RHS.isFloat()) + MakeFloat(); + else if (RHS.isComplexInt()) + MakeComplexInt(); + else if (RHS.isComplexFloat()) + MakeComplexFloat(); + else if (RHS.isLValue()) + MakeLValue(); + } + if (isInt()) + setInt(RHS.getInt()); + else if (isFloat()) + setFloat(RHS.getFloat()); + else if (isComplexInt()) + setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); + else if (isComplexFloat()) + setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); + else if (isLValue()) + setLValue(RHS.getLValueBase(), RHS.getLValueOffset()); + return *this; +} + +void APValue::MakeUninit() { + if (Kind == Int) + ((APSInt*)(void*)Data)->~APSInt(); + else if (Kind == Float) + ((APFloat*)(void*)Data)->~APFloat(); + else if (Kind == ComplexInt) + ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt(); + else if (Kind == ComplexFloat) + ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat(); + else if (Kind == LValue) { + ((LV*)(void*)Data)->~LV(); + } +} + +void APValue::dump() const { + print(llvm::errs()); + llvm::errs() << '\n'; + llvm::errs().flush(); +} + +static double GetApproxValue(const llvm::APFloat &F) { + llvm::APFloat V = F; + bool ignored; + V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven, + &ignored); + return V.convertToDouble(); +} + +void APValue::print(llvm::raw_ostream &OS) const { + switch (getKind()) { + default: assert(0 && "Unknown APValue kind!"); + case Uninitialized: + OS << "Uninitialized"; + return; + case Int: + OS << "Int: " << getInt(); + return; + case Float: + OS << "Float: " << GetApproxValue(getFloat()); + return; + case ComplexInt: + OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); + return; + case ComplexFloat: + OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) + << ", " << GetApproxValue(getComplexFloatImag()); + case LValue: + OS << "LValue: "; + return; + } +} + -- 2.40.0