diff options
-rw-r--r-- | clang/include/clang/AST/Decl.h | 1 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 33 | ||||
-rw-r--r-- | clang/test/SemaCXX/elaborated-type-specifier.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/enum.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/qualified-names-diag.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaTemplate/class-template-id-2.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaTemplate/qualified-names-diag.cpp | 2 |
7 files changed, 39 insertions, 13 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 1296c2fda9e..d4d22060c83 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -860,6 +860,7 @@ class TypeDecl : public NamedDecl { friend class TagDecl; friend class TemplateTypeParmDecl; friend class ClassTemplateSpecializationDecl; + friend class TagType; protected: TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 1fb1e999bd5..77d006e6449 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1526,8 +1526,35 @@ void TagType::getAsStringInternal(std::string &InnerString, InnerString = TemplateArgs + InnerString; } - if (Kind) - InnerString = std::string(Kind) + " " + ID + InnerString; - else + if (Kind) { + // Compute the full nested-name-specifier for this type. In C, + // this will always be empty. + std::string ContextStr; + for (DeclContext *DC = getDecl()->getDeclContext(); + !DC->isTranslationUnit(); DC = DC->getParent()) { + std::string MyPart; + if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { + if (NS->getIdentifier()) + MyPart = NS->getNameAsString(); + } else if (ClassTemplateSpecializationDecl *Spec + = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { + std::string TemplateArgs + = ClassTemplateSpecializationType::PrintTemplateArgumentList( + Spec->getTemplateArgs(), + Spec->getNumTemplateArgs()); + MyPart = Spec->getIdentifier()->getName() + TemplateArgs; + } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { + if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) + MyPart = Typedef->getIdentifier()->getName(); + else if (Tag->getIdentifier()) + MyPart = Tag->getIdentifier()->getName(); + } + + if (!MyPart.empty()) + ContextStr = MyPart + "::" + ContextStr; + } + + InnerString = std::string(Kind) + " " + ContextStr + ID + InnerString; + } else InnerString = ID + InnerString; } diff --git a/clang/test/SemaCXX/elaborated-type-specifier.cpp b/clang/test/SemaCXX/elaborated-type-specifier.cpp index b9ba5087896..fe4e210814c 100644 --- a/clang/test/SemaCXX/elaborated-type-specifier.cpp +++ b/clang/test/SemaCXX/elaborated-type-specifier.cpp @@ -27,7 +27,7 @@ namespace NS { void test_X_elab(NS::X x) { struct S4 *s4 = 0; - x.test_elab2(s4); // expected-error{{incompatible type passing 'struct S4 *', expected 'struct S4 *'}} + x.test_elab2(s4); // expected-error{{incompatible type passing 'struct S4 *', expected 'struct NS::S4 *'}} } namespace NS { diff --git a/clang/test/SemaCXX/enum.cpp b/clang/test/SemaCXX/enum.cpp index c7748c31ba0..156dfd62088 100644 --- a/clang/test/SemaCXX/enum.cpp +++ b/clang/test/SemaCXX/enum.cpp @@ -32,9 +32,7 @@ struct s1 { enum e1 { YES, NO }; static enum e1 badfunc(struct s1 *q) { - // FIXME: the message below should probably give context information - // in those types. - return q->bar(); // expected-error{{incompatible type returning 'enum e1', expected 'enum e1'}} + return q->bar(); // expected-error{{incompatible type returning 'enum s1::e1', expected 'enum e1'}} } enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} diff --git a/clang/test/SemaCXX/qualified-names-diag.cpp b/clang/test/SemaCXX/qualified-names-diag.cpp index c3bd47f9e5c..cb82f3189c7 100644 --- a/clang/test/SemaCXX/qualified-names-diag.cpp +++ b/clang/test/SemaCXX/qualified-names-diag.cpp @@ -16,17 +16,17 @@ namespace foo { namespace bar { typedef int y; - struct incomplete; // expected-note{{forward declaration of 'struct incomplete'}} + struct incomplete; // expected-note{{forward declaration of 'struct bar::incomplete'}} } void test() { foo::wibble::x a; ::bar::y b; - a + b; // expected-error{{invalid operands to binary expression ('foo::wibble::x' (aka 'struct x') and '::bar::y' (aka 'int'))}} + a + b; // expected-error{{invalid operands to binary expression ('foo::wibble::x' (aka 'struct foo::wibble::x') and '::bar::y' (aka 'int'))}} ::foo::wibble::bar::wonka::x::y c; - c + b; // expected-error{{invalid operands to binary expression ('::foo::wibble::bar::wonka::x::y' (aka 'struct y') and '::bar::y' (aka 'int'))}} + c + b; // expected-error{{invalid operands to binary expression ('::foo::wibble::bar::wonka::x::y' (aka 'struct foo::wibble::bar::wonka::x::y') and '::bar::y' (aka 'int'))}} - (void)sizeof(bar::incomplete); // expected-error{{invalid application of 'sizeof' to an incomplete type 'bar::incomplete' (aka 'struct incomplete')}} + (void)sizeof(bar::incomplete); // expected-error{{invalid application of 'sizeof' to an incomplete type 'bar::incomplete' (aka 'struct bar::incomplete')}} } int ::foo::wibble::bar::wonka::x::y::* ptrmem; diff --git a/clang/test/SemaTemplate/class-template-id-2.cpp b/clang/test/SemaTemplate/class-template-id-2.cpp index 5499c50a949..e77555f2f97 100644 --- a/clang/test/SemaTemplate/class-template-id-2.cpp +++ b/clang/test/SemaTemplate/class-template-id-2.cpp @@ -4,7 +4,7 @@ namespace N { template<> class A<int> { }; - template<> class A<float>; // expected-note{{forward declaration of 'class A<float>'}} + template<> class A<float>; // expected-note{{forward declaration of 'class N::A<float>'}} class B : public A<int> { }; } diff --git a/clang/test/SemaTemplate/qualified-names-diag.cpp b/clang/test/SemaTemplate/qualified-names-diag.cpp index 02bdf16b2ba..74e61bbb274 100644 --- a/clang/test/SemaTemplate/qualified-names-diag.cpp +++ b/clang/test/SemaTemplate/qualified-names-diag.cpp @@ -12,5 +12,5 @@ void test() { std::vector<INT> v1; vector<Real> v2; - v1 = v2; // expected-error{{incompatible type assigning 'vector<Real>' (aka 'class vector<float>'), expected 'std::vector<INT>' (aka 'class vector<int>')}} + v1 = v2; // expected-error{{incompatible type assigning 'vector<Real>' (aka 'class std::vector<float>'), expected 'std::vector<INT>' (aka 'class std::vector<int>')}} } |