10b57cec5SDimitry Andric //===-- llvm/ADT/APSInt.cpp - Arbitrary Precision Signed Int ---*- C++ -*--===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the APSInt class, which is a simple class that
100b57cec5SDimitry Andric // represents an arbitrary sized integer that knows its signedness.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
150b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
175ffd83dbSDimitry Andric #include <cassert>
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric 
APSInt(StringRef Str)210b57cec5SDimitry Andric APSInt::APSInt(StringRef Str) {
220b57cec5SDimitry Andric   assert(!Str.empty() && "Invalid string length");
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric   // (Over-)estimate the required number of bits.
250b57cec5SDimitry Andric   unsigned NumBits = ((Str.size() * 64) / 19) + 2;
260b57cec5SDimitry Andric   APInt Tmp(NumBits, Str, /*radix=*/10);
270b57cec5SDimitry Andric   if (Str[0] == '-') {
28*fe013be4SDimitry Andric     unsigned MinBits = Tmp.getSignificantBits();
295ffd83dbSDimitry Andric     if (MinBits < NumBits)
305ffd83dbSDimitry Andric       Tmp = Tmp.trunc(std::max<unsigned>(1, MinBits));
310b57cec5SDimitry Andric     *this = APSInt(Tmp, /*isUnsigned=*/false);
320b57cec5SDimitry Andric     return;
330b57cec5SDimitry Andric   }
340b57cec5SDimitry Andric   unsigned ActiveBits = Tmp.getActiveBits();
355ffd83dbSDimitry Andric   if (ActiveBits < NumBits)
365ffd83dbSDimitry Andric     Tmp = Tmp.trunc(std::max<unsigned>(1, ActiveBits));
370b57cec5SDimitry Andric   *this = APSInt(Tmp, /*isUnsigned=*/true);
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric 
Profile(FoldingSetNodeID & ID) const400b57cec5SDimitry Andric void APSInt::Profile(FoldingSetNodeID& ID) const {
410b57cec5SDimitry Andric   ID.AddInteger((unsigned) (IsUnsigned ? 1 : 0));
420b57cec5SDimitry Andric   APInt::Profile(ID);
430b57cec5SDimitry Andric }
44