error api for APInt / APFloat

I'm breaking this out from LLVM asserts thread. Here are all the
assertions in APInt I consider should be recoverable:

APInt::APInt:
bitwidth too small
Null pointer detected!

APInt::getBitsNeeded:
Invalid string length
string is only a minus!
Invalid radix

APInt::fromString:
Radix should be 2, 8, 10, or 16!
Invalid string length
string is only a minus
Insufficient bit width
Invalid digit in string for given radix

APInt::toString:
"Radix should be 2, 8, 10, or 16!

For the recoverable APFloat assertions:

assertArithmeticOK:
Compile-time arithmetic does not support these semantics

readExponent:
Exponent has no digits
Invalid character in exponent

totalExponent:
Invalid character in exponent

skipLeadingZeroesAndAnyDot:
String cannot be just a dot

interpretDecimal:
Multiple dots in float
Invalid character in digit string

trailingHexadecimalFraction:
Invalid trailing hexadecimal fraction!

I'd expect we'd want to keep the assertions that check to make sure
we're comparing APInts and APFloats of the right semantics.

I'm not sure if it makes sense trying to change this right before the
code freeze, especially since I can't find any other classes that have
similar semantics that we could copy. So, what should we do?

I'm breaking this out from LLVM asserts thread. Here are all the
assertions in APInt I consider should be recoverable:

APInt::APInt:
bitwidth too small
Null pointer detected!

Hi Eric,

As we discussed on IRC, I don't think there is any reason for the implementation of these methods to check these invariants. These are clear API invariants that the caller can check if needbe. Making the implementation check these will slow down clients which are known to be well formed. I didn't look at all of the things you listed, perhaps some other ones would make some more to be recoverable errors.

-Chris

By that logic, I think it's safe to say then to say that it's an
invariant of APInt and APFloat to pass in a well formed string, and
that it's the client's responsibility to make sure that the string
isn't invalid. Which then follows that the assertions checking the
validity of the string should stay.

I'm happy with that decision if you are.

You're right that anything can be declared to be a property the caller needs to enforce. This makes it a muddy issue that boils down to a judgement call based on how low-level the API is and how complex the invariant is.

Two examples:

Since APInt is a very low level class, bitwidth is something clients can be expected to have to know about.

Since detecting errors in floating point string literals basically requires parsing the whole string, so making clients enforce all the invariants would basically make a string literal parsing routine useless. Something like 'parsing a string' is also inherently an operation that can fail if the input is malformed, so returning an error code makes sense.

Does this rationale seem reasonable to you?

-Chris

Sure, that sounds good. I'll put together a patch for returning error
codes for the string parsing, but leave the rest as asserts.