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">;
|
||||
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">;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue