Pretty-print anonymous types using their kind and presumed location.

Fixes PR6643.  Patch by Mike M!

llvm-svn: 98946
This commit is contained in:
John McCall 2010-03-19 07:56:44 +00:00
parent a0296f7987
commit ef01f71a5a
5 changed files with 38 additions and 19 deletions

View File

@ -1889,16 +1889,16 @@ def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
def warn_mixed_sign_comparison : Warning<
"comparison of integers of different signs: %0 and %1">,
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
InGroup<SignCompare>, DefaultIgnore;
def warn_mixed_sign_conditional : Warning<
"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<
"comparison of unsigned expression %0 is always %1">,
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
InGroup<SignCompare>, DefaultIgnore;
def warn_runsigned_always_true_comparison : Warning<
"comparison of %0 unsigned expression is always %1">,
InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
InGroup<SignCompare>, DefaultIgnore;
def err_invalid_this_use : Error<
"invalid use of 'this' outside of a nonstatic member function">;

View File

@ -18,6 +18,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@ -412,10 +413,12 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
return;
std::string Buffer;
bool HasKindDecoration = false;
// We don't print tags unless this is an elaborated type.
// In C, we just assume every RecordType is an elaborated type.
if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
HasKindDecoration = true;
Buffer += D->getKindName();
Buffer += ' ';
}
@ -425,15 +428,31 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
// this will always be empty.
AppendScope(D->getDeclContext(), Buffer);
const char *ID;
if (const IdentifierInfo *II = D->getIdentifier())
ID = II->getNameStart();
Buffer += II->getNameStart();
else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
assert(Typedef->getIdentifier() && "Typedef without identifier?");
ID = Typedef->getIdentifier()->getNameStart();
} else
ID = "<anonymous>";
Buffer += ID;
Buffer += Typedef->getIdentifier()->getNameStart();
} else {
// Make an unambiguous representation for anonymous types, e.g.
// <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
// arguments.

View File

@ -46,25 +46,25 @@ union U1 {
union U2 {
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}}
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}}
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}}
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}}
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}}
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}}
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}}
struct {
Okay okay;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
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}}

View File

@ -17,7 +17,7 @@ void test() {
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 {} 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}} \
// expected-warning{{enumeration value 'E' not handled in switch}}