forked from OSchip/llvm-project
teach FormatDiagnostic to aggregate previously formatted arguments and
pass them down into the ArgToStringFn implementation. This allows redundancy across operands to a diagnostic to be eliminated. This isn't used yet, so no functionality change. llvm-svn: 84602
This commit is contained in:
parent
2f9876cf7c
commit
c243f299ce
|
@ -164,6 +164,10 @@ public:
|
|||
ak_nestednamespec, // NestedNameSpecifier *
|
||||
ak_declcontext // DeclContext *
|
||||
};
|
||||
|
||||
/// ArgumentValue - This typedef represents on argument value, which is a
|
||||
/// union discriminated by ArgumentKind, with a value.
|
||||
typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
|
||||
|
||||
private:
|
||||
unsigned char AllExtensionsSilenced; // Used by __extension__
|
||||
|
@ -203,10 +207,17 @@ private:
|
|||
/// ArgToStringFn - A function pointer that converts an opaque diagnostic
|
||||
/// argument to a strings. This takes the modifiers and argument that was
|
||||
/// present in the diagnostic.
|
||||
///
|
||||
/// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
|
||||
/// arguments formatted for this diagnostic. Implementations of this function
|
||||
/// can use this information to avoid redundancy across arguments.
|
||||
///
|
||||
/// This is a hack to avoid a layering violation between libbasic and libsema.
|
||||
typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
|
||||
const char *Modifier, unsigned ModifierLen,
|
||||
const char *Argument, unsigned ArgumentLen,
|
||||
const ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie);
|
||||
void *ArgToStringCookie;
|
||||
|
@ -311,9 +322,10 @@ public:
|
|||
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
|
||||
const char *Modifier, unsigned ModLen,
|
||||
const char *Argument, unsigned ArgLen,
|
||||
const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output) const {
|
||||
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, Output,
|
||||
ArgToStringCookie);
|
||||
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
|
||||
PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
|
||||
}
|
||||
|
||||
void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
|
||||
|
|
|
@ -190,6 +190,8 @@ namespace clang {
|
|||
static void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT,
|
||||
const char *Modifier, unsigned ML,
|
||||
const char *Argument, unsigned ArgLen,
|
||||
const Diagnostic::ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie) {
|
||||
const char *Str = "<can't format argument>";
|
||||
|
@ -685,6 +687,12 @@ FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
|
|||
const char *DiagStr = getDiags()->getDescription(getID());
|
||||
const char *DiagEnd = DiagStr+strlen(DiagStr);
|
||||
|
||||
/// FormattedArgs - Keep track of all of the arguments formatted by
|
||||
/// ConvertArgToString and pass them into subsequent calls to
|
||||
/// ConvertArgToString, allowing the implementation to avoid redundancies in
|
||||
/// obvious cases.
|
||||
llvm::SmallVector<Diagnostic::ArgumentValue, 8> FormattedArgs;
|
||||
|
||||
while (DiagStr != DiagEnd) {
|
||||
if (DiagStr[0] != '%') {
|
||||
// Append non-%0 substrings to Str if we have one.
|
||||
|
@ -732,7 +740,9 @@ FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
|
|||
assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic");
|
||||
unsigned ArgNo = *DiagStr++ - '0';
|
||||
|
||||
switch (getArgKind(ArgNo)) {
|
||||
Diagnostic::ArgumentKind Kind = getArgKind(ArgNo);
|
||||
|
||||
switch (Kind) {
|
||||
// ---- STRINGS ----
|
||||
case Diagnostic::ak_std_string: {
|
||||
const std::string &S = getArgStdStr(ArgNo);
|
||||
|
@ -802,11 +812,23 @@ FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
|
|||
case Diagnostic::ak_nameddecl:
|
||||
case Diagnostic::ak_nestednamespec:
|
||||
case Diagnostic::ak_declcontext:
|
||||
getDiags()->ConvertArgToString(getArgKind(ArgNo), getRawArg(ArgNo),
|
||||
getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
|
||||
Modifier, ModifierLen,
|
||||
Argument, ArgumentLen, OutStr);
|
||||
Argument, ArgumentLen,
|
||||
FormattedArgs.data(), FormattedArgs.size(),
|
||||
OutStr);
|
||||
break;
|
||||
}
|
||||
|
||||
// Remember this argument info for subsequent formatting operations. Turn
|
||||
// std::strings into a null terminated string to make it be the same case as
|
||||
// all the other ones.
|
||||
if (Kind != Diagnostic::ak_std_string)
|
||||
FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
|
||||
else
|
||||
FormattedArgs.push_back(std::make_pair(Diagnostic::ak_c_string,
|
||||
(intptr_t)getArgStdStr(ArgNo).c_str()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,8 @@ static std::string ConvertTypeToDiagnosticString(ASTContext &Context,
|
|||
static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val,
|
||||
const char *Modifier, unsigned ModLen,
|
||||
const char *Argument, unsigned ArgLen,
|
||||
const Diagnostic::ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie) {
|
||||
ASTContext &Context = *static_cast<ASTContext*>(Cookie);
|
||||
|
|
Loading…
Reference in New Issue