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" 16 using namespace clang; 17 18 19 const 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.isComplexInt()) 27 MakeComplexInt(); 28 else if (RHS.isComplexFloat()) 29 MakeComplexFloat(); 30 else if (RHS.isLValue()) 31 MakeLValue(); 32 } 33 if (isInt()) 34 setInt(RHS.getInt()); 35 else if (isFloat()) 36 setFloat(RHS.getFloat()); 37 else if (isComplexInt()) 38 setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); 39 else if (isComplexFloat()) 40 setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); 41 else if (isLValue()) 42 setLValue(RHS.getLValueBase(), RHS.getLValueOffset()); 43 return *this; 44 } 45 46 void APValue::MakeUninit() { 47 if (Kind == Int) 48 ((APSInt*)(void*)Data)->~APSInt(); 49 else if (Kind == Float) 50 ((APFloat*)(void*)Data)->~APFloat(); 51 else if (Kind == ComplexInt) 52 ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt(); 53 else if (Kind == ComplexFloat) 54 ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat(); 55 else if (Kind == LValue) { 56 ((LV*)(void*)Data)->~LV(); 57 } 58 } 59 60 void APValue::dump() const { 61 print(llvm::errs()); 62 llvm::errs() << '\n'; 63 llvm::errs().flush(); 64 } 65 66 static double GetApproxValue(const llvm::APFloat &F) { 67 llvm::APFloat V = F; 68 bool ignored; 69 V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven, 70 &ignored); 71 return V.convertToDouble(); 72 } 73 74 void APValue::print(llvm::raw_ostream &OS) const { 75 switch (getKind()) { 76 default: assert(0 && "Unknown APValue kind!"); 77 case Uninitialized: 78 OS << "Uninitialized"; 79 return; 80 case Int: 81 OS << "Int: " << getInt(); 82 return; 83 case Float: 84 OS << "Float: " << GetApproxValue(getFloat()); 85 return; 86 case ComplexInt: 87 OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); 88 return; 89 case ComplexFloat: 90 OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) 91 << ", " << GetApproxValue(getComplexFloatImag()); 92 case LValue: 93 OS << "LValue: <todo>"; 94 return; 95 } 96 } 97 98