1 //===--- APNumericStorage.h - Store APInt/APFloat in ASTContext -*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_AST_APNUMERICSTORAGE_H 10 #define LLVM_CLANG_AST_APNUMERICSTORAGE_H 11 12 #include "llvm/ADT/APFloat.h" 13 #include "llvm/ADT/APInt.h" 14 15 namespace clang { 16 class ASTContext; 17 18 /// Used by IntegerLiteral/FloatingLiteral/EnumConstantDecl to store the 19 /// numeric without leaking memory. 20 /// 21 /// For large floats/integers, APFloat/APInt will allocate memory from the heap 22 /// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator 23 /// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with 24 /// the APFloat/APInt values will never get freed. APNumericStorage uses 25 /// ASTContext's allocator for memory allocation. 26 class APNumericStorage { 27 union { 28 uint64_t VAL; ///< Used to store the <= 64 bits integer value. 29 uint64_t *pVal; ///< Used to store the >64 bits integer value. 30 }; 31 unsigned BitWidth; 32 33 bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } 34 35 APNumericStorage(const APNumericStorage &) = delete; 36 void operator=(const APNumericStorage &) = delete; 37 38 protected: 39 APNumericStorage() : VAL(0), BitWidth(0) {} 40 41 llvm::APInt getIntValue() const { 42 unsigned NumWords = llvm::APInt::getNumWords(BitWidth); 43 if (NumWords > 1) 44 return llvm::APInt(BitWidth, NumWords, pVal); 45 else 46 return llvm::APInt(BitWidth, VAL); 47 } 48 void setIntValue(const ASTContext &C, const llvm::APInt &Val); 49 }; 50 51 class APIntStorage : private APNumericStorage { 52 public: 53 llvm::APInt getValue() const { return getIntValue(); } 54 void setValue(const ASTContext &C, const llvm::APInt &Val) { 55 setIntValue(C, Val); 56 } 57 }; 58 59 class APFloatStorage : private APNumericStorage { 60 public: 61 llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { 62 return llvm::APFloat(Semantics, getIntValue()); 63 } 64 void setValue(const ASTContext &C, const llvm::APFloat &Val) { 65 setIntValue(C, Val.bitcastToAPInt()); 66 } 67 }; 68 69 } // end namespace clang 70 71 #endif // LLVM_CLANG_AST_APNUMERICSTORAGE_H 72