xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h (revision 95eb4b873b6a8b527c5bd78d7191975dfca38998)
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