diff options
author | John McCall <rjmccall@apple.com> | 2010-03-19 07:56:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-19 07:56:44 +0000 |
commit | 73061d054128e486e70e0f2874b23d6eca067e5b (patch) | |
tree | 7ec16026021ec7aa8e0eceaa76d3d6206a8978ed | |
parent | 9aa472c45d2bd81b7b52c225e8acc560d716db97 (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.td | 8 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 31 | ||||
-rw-r--r-- | test/CXX/class/class.union/p1.cpp | 14 | ||||
-rw-r--r-- | test/Sema/invalid-init-diag.c | 2 | ||||
-rw-r--r-- | test/SemaCXX/condition.cpp | 2 |
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}} |