Use llvm::getOrdinalSuffix to print ordinal numbers in diagnostics.

Just a refactoring of common infrastructure. No intended functionality change.

llvm-svn: 164443
This commit is contained in:
Jordan Rose 2012-09-22 01:24:42 +00:00
parent 1d64a49855
commit c102b35b44
4 changed files with 15 additions and 57 deletions

View File

@ -432,10 +432,6 @@ public:
/// 'getMessageForX()' methods to construct a specific message.
virtual std::string getMessage(const ExplodedNode *N);
/// Prints the ordinal form of the given integer,
/// only valid for ValNo : ValNo > 0.
void printOrdinal(unsigned ValNo, llvm::raw_svector_ostream &Out);
/// Produces the message of the following form:
/// 'Msg via Nth parameter'
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex);

View File

@ -15,6 +15,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include <cctype>
@ -515,23 +516,7 @@ static void HandleOrdinalModifier(unsigned ValNo,
// We could use text forms for the first N ordinals, but the numeric
// forms are actually nicer in diagnostics because they stand out.
Out << ValNo;
// It is critically important that we do this perfectly for
// user-written sequences with over 100 elements.
switch (ValNo % 100) {
case 11:
case 12:
case 13:
Out << "th"; return;
default:
switch (ValNo % 10) {
case 1: Out << "st"; return;
case 2: Out << "nd"; return;
case 3: Out << "rd"; return;
default: Out << "th"; return;
}
}
Out << ValNo << llvm::getOrdinalSuffix(ValNo);
}

View File

@ -26,6 +26,7 @@
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include <climits>
using namespace clang;
@ -317,13 +318,14 @@ private:
: StackHintGeneratorForSymbol(S, M) {}
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) {
// Printed parameters start at 1, not 0.
++ArgIndex;
SmallString<200> buf;
llvm::raw_svector_ostream os(buf);
os << "Reallocation of ";
// Printed parameters start at 1, not 0.
printOrdinal(++ArgIndex, os);
os << " parameter failed";
os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
<< " parameter failed";
return os.str();
}

View File

@ -21,6 +21,7 @@
#include "clang/AST/ParentMap.h"
#include "clang/AST/StmtCXX.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
using namespace clang;
using namespace ento;
@ -947,42 +948,16 @@ std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){
return getMessageForSymbolNotFound();
}
/// TODO: This is copied from clang diagnostics. Maybe we could just move it to
/// some common place. (Same as HandleOrdinalModifier.)
void StackHintGeneratorForSymbol::printOrdinal(unsigned ValNo,
llvm::raw_svector_ostream &Out) {
assert(ValNo != 0 && "ValNo must be strictly positive!");
// We could use text forms for the first N ordinals, but the numeric
// forms are actually nicer in diagnostics because they stand out.
Out << ValNo;
// It is critically important that we do this perfectly for
// user-written sequences with over 100 elements.
switch (ValNo % 100) {
case 11:
case 12:
case 13:
Out << "th"; return;
default:
switch (ValNo % 10) {
case 1: Out << "st"; return;
case 2: Out << "nd"; return;
case 3: Out << "rd"; return;
default: Out << "th"; return;
}
}
}
std::string StackHintGeneratorForSymbol::getMessageForArg(const Expr *ArgE,
unsigned ArgIndex) {
unsigned ArgIndex) {
// Printed parameters start at 1, not 0.
++ArgIndex;
SmallString<200> buf;
llvm::raw_svector_ostream os(buf);
os << Msg << " via ";
// Printed parameters start at 1, not 0.
printOrdinal(++ArgIndex, os);
os << " parameter";
os << Msg << " via " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
<< " parameter";
return os.str();
}