aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-19 07:56:44 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-19 07:56:44 +0000
commit73061d054128e486e70e0f2874b23d6eca067e5b (patch)
tree7ec16026021ec7aa8e0eceaa76d3d6206a8978ed
parent9aa472c45d2bd81b7b52c225e8acc560d716db97 (diff)
Pretty-print anonymous types using their kind and presumed location.
Fixes PR6643. Patch by Mike M! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98946 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td8
-rw-r--r--lib/AST/TypePrinter.cpp31
-rw-r--r--test/CXX/class/class.union/p1.cpp14
-rw-r--r--test/Sema/invalid-init-diag.c2
-rw-r--r--test/SemaCXX/condition.cpp2
5 files changed, 38 insertions, 19 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 8322f8f4b6..5a95c0f852 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 09a61736d2..0c4896decf 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -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.
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
index f53783eb5f..e974d825d6 100644
--- a/test/CXX/class/class.union/p1.cpp
+++ b/test/CXX/class/class.union/p1.cpp
@@ -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;
diff --git a/test/Sema/invalid-init-diag.c b/test/Sema/invalid-init-diag.c
index a215fa7c25..dec7d6c18f 100644
--- a/test/Sema/invalid-init-diag.c
+++ b/test/Sema/invalid-init-diag.c
@@ -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}}
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
index b3e862dc1b..daa86f62fc 100644
--- a/test/SemaCXX/condition.cpp
+++ b/test/SemaCXX/condition.cpp
@@ -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}}