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 15namespace clang { 16class 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. 26class 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 38protected: 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 51class APIntStorage : private APNumericStorage { 52public: 53 llvm::APInt getValue() const { return getIntValue(); } 54 void setValue(const ASTContext &C, const llvm::APInt &Val) { 55 setIntValue(C, Val); 56 } 57}; 58 59class APFloatStorage : private APNumericStorage { 60public: 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