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_nestednamespec, // NestedNameSpecifier *
|
||||||
ak_declcontext // DeclContext *
|
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:
|
private:
|
||||||
unsigned char AllExtensionsSilenced; // Used by __extension__
|
unsigned char AllExtensionsSilenced; // Used by __extension__
|
||||||
|
@ -203,10 +207,17 @@ private:
|
||||||
/// ArgToStringFn - A function pointer that converts an opaque diagnostic
|
/// ArgToStringFn - A function pointer that converts an opaque diagnostic
|
||||||
/// argument to a strings. This takes the modifiers and argument that was
|
/// argument to a strings. This takes the modifiers and argument that was
|
||||||
/// present in the diagnostic.
|
/// 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.
|
/// This is a hack to avoid a layering violation between libbasic and libsema.
|
||||||
typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
|
typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
|
||||||
const char *Modifier, unsigned ModifierLen,
|
const char *Modifier, unsigned ModifierLen,
|
||||||
const char *Argument, unsigned ArgumentLen,
|
const char *Argument, unsigned ArgumentLen,
|
||||||
|
const ArgumentValue *PrevArgs,
|
||||||
|
unsigned NumPrevArgs,
|
||||||
llvm::SmallVectorImpl<char> &Output,
|
llvm::SmallVectorImpl<char> &Output,
|
||||||
void *Cookie);
|
void *Cookie);
|
||||||
void *ArgToStringCookie;
|
void *ArgToStringCookie;
|
||||||
|
@ -311,9 +322,10 @@ public:
|
||||||
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
|
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
|
||||||
const char *Modifier, unsigned ModLen,
|
const char *Modifier, unsigned ModLen,
|
||||||
const char *Argument, unsigned ArgLen,
|
const char *Argument, unsigned ArgLen,
|
||||||
|
const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
|
||||||
llvm::SmallVectorImpl<char> &Output) const {
|
llvm::SmallVectorImpl<char> &Output) const {
|
||||||
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, Output,
|
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
|
||||||
ArgToStringCookie);
|
PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
|
void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
|
||||||
|
|
|
@ -190,6 +190,8 @@ namespace clang {
|
||||||
static void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT,
|
static void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT,
|
||||||
const char *Modifier, unsigned ML,
|
const char *Modifier, unsigned ML,
|
||||||
const char *Argument, unsigned ArgLen,
|
const char *Argument, unsigned ArgLen,
|
||||||
|
const Diagnostic::ArgumentValue *PrevArgs,
|
||||||
|
unsigned NumPrevArgs,
|
||||||
llvm::SmallVectorImpl<char> &Output,
|
llvm::SmallVectorImpl<char> &Output,
|
||||||
void *Cookie) {
|
void *Cookie) {
|
||||||
const char *Str = "<can't format argument>";
|
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 *DiagStr = getDiags()->getDescription(getID());
|
||||||
const char *DiagEnd = DiagStr+strlen(DiagStr);
|
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) {
|
while (DiagStr != DiagEnd) {
|
||||||
if (DiagStr[0] != '%') {
|
if (DiagStr[0] != '%') {
|
||||||
// Append non-%0 substrings to Str if we have one.
|
// 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");
|
assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic");
|
||||||
unsigned ArgNo = *DiagStr++ - '0';
|
unsigned ArgNo = *DiagStr++ - '0';
|
||||||
|
|
||||||
switch (getArgKind(ArgNo)) {
|
Diagnostic::ArgumentKind Kind = getArgKind(ArgNo);
|
||||||
|
|
||||||
|
switch (Kind) {
|
||||||
// ---- STRINGS ----
|
// ---- STRINGS ----
|
||||||
case Diagnostic::ak_std_string: {
|
case Diagnostic::ak_std_string: {
|
||||||
const std::string &S = getArgStdStr(ArgNo);
|
const std::string &S = getArgStdStr(ArgNo);
|
||||||
|
@ -802,11 +812,23 @@ FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
|
||||||
case Diagnostic::ak_nameddecl:
|
case Diagnostic::ak_nameddecl:
|
||||||
case Diagnostic::ak_nestednamespec:
|
case Diagnostic::ak_nestednamespec:
|
||||||
case Diagnostic::ak_declcontext:
|
case Diagnostic::ak_declcontext:
|
||||||
getDiags()->ConvertArgToString(getArgKind(ArgNo), getRawArg(ArgNo),
|
getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
|
||||||
Modifier, ModifierLen,
|
Modifier, ModifierLen,
|
||||||
Argument, ArgumentLen, OutStr);
|
Argument, ArgumentLen,
|
||||||
|
FormattedArgs.data(), FormattedArgs.size(),
|
||||||
|
OutStr);
|
||||||
break;
|
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,
|
static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val,
|
||||||
const char *Modifier, unsigned ModLen,
|
const char *Modifier, unsigned ModLen,
|
||||||
const char *Argument, unsigned ArgLen,
|
const char *Argument, unsigned ArgLen,
|
||||||
|
const Diagnostic::ArgumentValue *PrevArgs,
|
||||||
|
unsigned NumPrevArgs,
|
||||||
llvm::SmallVectorImpl<char> &Output,
|
llvm::SmallVectorImpl<char> &Output,
|
||||||
void *Cookie) {
|
void *Cookie) {
|
||||||
ASTContext &Context = *static_cast<ASTContext*>(Cookie);
|
ASTContext &Context = *static_cast<ASTContext*>(Cookie);
|
||||||
|
|
Loading…
Reference in New Issue