forked from OSchip/llvm-project
Pretty-print anonymous types using their kind and presumed location.
Fixes PR6643. Patch by Mike M! llvm-svn: 98946
This commit is contained in:
parent
a0296f7987
commit
ef01f71a5a
|
@ -1889,16 +1889,16 @@ def err_stmtexpr_file_scope : Error<
|
||||||
"statement expression not allowed at file scope">;
|
"statement expression not allowed at file scope">;
|
||||||
def warn_mixed_sign_comparison : Warning<
|
def warn_mixed_sign_comparison : Warning<
|
||||||
"comparison of integers of different signs: %0 and %1">,
|
"comparison of integers of different signs: %0 and %1">,
|
||||||
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
|
InGroup<SignCompare>, DefaultIgnore;
|
||||||
def warn_mixed_sign_conditional : Warning<
|
def warn_mixed_sign_conditional : Warning<
|
||||||
"operands of ? are integers of different signs: %0 and %1">,
|
"operands of ? are integers of different signs: %0 and %1">,
|
||||||
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
|
InGroup<SignCompare>, DefaultIgnore;
|
||||||
def warn_lunsigned_always_true_comparison : Warning<
|
def warn_lunsigned_always_true_comparison : Warning<
|
||||||
"comparison of unsigned expression %0 is always %1">,
|
"comparison of unsigned expression %0 is always %1">,
|
||||||
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
|
InGroup<SignCompare>, DefaultIgnore;
|
||||||
def warn_runsigned_always_true_comparison : Warning<
|
def warn_runsigned_always_true_comparison : Warning<
|
||||||
"comparison of %0 unsigned expression is always %1">,
|
"comparison of %0 unsigned expression is always %1">,
|
||||||
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
|
InGroup<SignCompare>, DefaultIgnore;
|
||||||
|
|
||||||
def err_invalid_this_use : Error<
|
def err_invalid_this_use : Error<
|
||||||
"invalid use of 'this' outside of a nonstatic member function">;
|
"invalid use of 'this' outside of a nonstatic member function">;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
#include "clang/AST/PrettyPrinter.h"
|
#include "clang/AST/PrettyPrinter.h"
|
||||||
#include "clang/Basic/LangOptions.h"
|
#include "clang/Basic/LangOptions.h"
|
||||||
|
#include "clang/Basic/SourceManager.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
@ -412,10 +413,12 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string Buffer;
|
std::string Buffer;
|
||||||
|
bool HasKindDecoration = false;
|
||||||
|
|
||||||
// We don't print tags unless this is an elaborated type.
|
// We don't print tags unless this is an elaborated type.
|
||||||
// In C, we just assume every RecordType is an elaborated type.
|
// In C, we just assume every RecordType is an elaborated type.
|
||||||
if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
|
if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
|
||||||
|
HasKindDecoration = true;
|
||||||
Buffer += D->getKindName();
|
Buffer += D->getKindName();
|
||||||
Buffer += ' ';
|
Buffer += ' ';
|
||||||
}
|
}
|
||||||
|
@ -425,15 +428,31 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
|
||||||
// this will always be empty.
|
// this will always be empty.
|
||||||
AppendScope(D->getDeclContext(), Buffer);
|
AppendScope(D->getDeclContext(), Buffer);
|
||||||
|
|
||||||
const char *ID;
|
|
||||||
if (const IdentifierInfo *II = D->getIdentifier())
|
if (const IdentifierInfo *II = D->getIdentifier())
|
||||||
ID = II->getNameStart();
|
Buffer += II->getNameStart();
|
||||||
else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
|
else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
|
||||||
assert(Typedef->getIdentifier() && "Typedef without identifier?");
|
assert(Typedef->getIdentifier() && "Typedef without identifier?");
|
||||||
ID = Typedef->getIdentifier()->getNameStart();
|
Buffer += Typedef->getIdentifier()->getNameStart();
|
||||||
} else
|
} else {
|
||||||
ID = "<anonymous>";
|
// Make an unambiguous representation for anonymous types, e.g.
|
||||||
Buffer += ID;
|
// <anonymous enum at /usr/include/string.h:120:9>
|
||||||
|
llvm::raw_string_ostream OS(Buffer);
|
||||||
|
OS << "<anonymous";
|
||||||
|
|
||||||
|
// Suppress the redundant tag keyword if we just printed one.
|
||||||
|
// We don't have to worry about ElaboratedTypes here because you can't
|
||||||
|
// refer to an anonymous type with one.
|
||||||
|
if (!HasKindDecoration)
|
||||||
|
OS << " " << D->getKindName();
|
||||||
|
|
||||||
|
PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
|
||||||
|
D->getLocation());
|
||||||
|
OS << " at " << PLoc.getFilename()
|
||||||
|
<< ':' << PLoc.getLine()
|
||||||
|
<< ':' << PLoc.getColumn()
|
||||||
|
<< '>';
|
||||||
|
OS.flush();
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a class template specialization, print the template
|
// If this is a class template specialization, print the template
|
||||||
// arguments.
|
// arguments.
|
||||||
|
|
|
@ -46,25 +46,25 @@ union U1 {
|
||||||
|
|
||||||
union U2 {
|
union U2 {
|
||||||
struct {
|
struct {
|
||||||
Virtual v; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy constructor}}
|
Virtual v; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
|
} m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
|
||||||
struct {
|
struct {
|
||||||
VirtualBase vbase; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy constructor}}
|
VirtualBase vbase; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
|
} m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
|
||||||
struct {
|
struct {
|
||||||
Ctor ctor; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial constructor}}
|
Ctor ctor; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
|
} m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
|
||||||
struct {
|
struct {
|
||||||
Ctor2 ctor2; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial constructor}}
|
Ctor2 ctor2; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
|
} m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
|
||||||
struct {
|
struct {
|
||||||
CopyCtor copyctor; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy constructor}}
|
CopyCtor copyctor; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
|
} m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
|
||||||
struct {
|
struct {
|
||||||
CopyAssign copyassign; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy assignment operator}}
|
CopyAssign copyassign; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
|
} m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
|
||||||
struct {
|
struct {
|
||||||
Dtor dtor; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial destructor}}
|
Dtor dtor; // expected-note {{because type 'U2::<anonymous struct}}
|
||||||
} m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
|
} m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
|
||||||
struct {
|
struct {
|
||||||
Okay okay;
|
Okay okay;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// RUN: %clang_cc1 %s -verify -fsyntax-only
|
// RUN: %clang_cc1 %s -verify -fsyntax-only
|
||||||
|
|
||||||
int a;
|
int a;
|
||||||
struct {int x;} x = a; // expected-error {{incompatible type initializing 'int', expected 'struct <anonymous>'}}
|
struct {int x;} x = a; // expected-error {{incompatible type initializing 'int', expected 'struct <anonymous}}
|
||||||
|
|
|
@ -17,7 +17,7 @@ void test() {
|
||||||
switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}}
|
switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}}
|
||||||
|
|
||||||
while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
|
while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
|
||||||
while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
|
while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
|
||||||
switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \
|
switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \
|
||||||
// expected-warning{{enumeration value 'E' not handled in switch}}
|
// expected-warning{{enumeration value 'E' not handled in switch}}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue