APValue.cpp revision 4a77edb3f0fabc8e214a3d5636c4d0aff031645c
1//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the APValue class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/APValue.h" 15#include "llvm/Support/raw_ostream.h" 16using namespace clang; 17 18 19const APValue &APValue::operator=(const APValue &RHS) { 20 if (Kind != RHS.Kind) { 21 MakeUninit(); 22 if (RHS.isInt()) 23 MakeInt(); 24 else if (RHS.isFloat()) 25 MakeFloat(); 26 else if (RHS.isVector()) 27 MakeVector(); 28 else if (RHS.isComplexInt()) 29 MakeComplexInt(); 30 else if (RHS.isComplexFloat()) 31 MakeComplexFloat(); 32 else if (RHS.isLValue()) 33 MakeLValue(); 34 } 35 if (isInt()) 36 setInt(RHS.getInt()); 37 else if (isFloat()) 38 setFloat(RHS.getFloat()); 39 else if (isVector()) 40 setVector(((Vec*)(void*)RHS.Data)->Elts, RHS.getVectorLength()); 41 else if (isComplexInt()) 42 setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); 43 else if (isComplexFloat()) 44 setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); 45 else if (isLValue()) 46 setLValue(RHS.getLValueBase(), RHS.getLValueOffset()); 47 return *this; 48} 49 50void APValue::MakeUninit() { 51 if (Kind == Int) 52 ((APSInt*)(void*)Data)->~APSInt(); 53 else if (Kind == Float) 54 ((APFloat*)(void*)Data)->~APFloat(); 55 else if (Kind == Vector) 56 ((Vec*)(void*)Data)->~Vec(); 57 else if (Kind == ComplexInt) 58 ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt(); 59 else if (Kind == ComplexFloat) 60 ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat(); 61 else if (Kind == LValue) { 62 ((LV*)(void*)Data)->~LV(); 63 } 64 Kind = Uninitialized; 65} 66 67void APValue::dump() const { 68 print(llvm::errs()); 69 llvm::errs() << '\n'; 70} 71 72static double GetApproxValue(const llvm::APFloat &F) { 73 llvm::APFloat V = F; 74 bool ignored; 75 V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven, 76 &ignored); 77 return V.convertToDouble(); 78} 79 80void APValue::print(llvm::raw_ostream &OS) const { 81 switch (getKind()) { 82 default: assert(0 && "Unknown APValue kind!"); 83 case Uninitialized: 84 OS << "Uninitialized"; 85 return; 86 case Int: 87 OS << "Int: " << getInt(); 88 return; 89 case Float: 90 OS << "Float: " << GetApproxValue(getFloat()); 91 return; 92 case Vector: 93 OS << "Vector: " << getVectorElt(0); 94 for (unsigned i = 1; i != getVectorLength(); ++i) 95 OS << ", " << getVectorElt(i); 96 return; 97 case ComplexInt: 98 OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); 99 return; 100 case ComplexFloat: 101 OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) 102 << ", " << GetApproxValue(getComplexFloatImag()); 103 case LValue: 104 OS << "LValue: <todo>"; 105 return; 106 } 107} 108 109