From 9cd30fb0f554fd22ea98a59dd1abadd35804f754 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 11 Dec 2014 14:44:46 -0500 Subject: Output: Fix references to cv-qualified types encountered indirectly Teach AddDumpNode to optionally report back the actual QualType that it selects after possibly unwrapping some layers of indirection in the Clang AST. Use this in GetTypeIdRef so that we check this actual QualType's cv qualifiers instead of the original QualType. Otherwise we may generate a dangling reference to the id number that is replaced by a CvQualifiedType id. Fix the expected output of existing test cases that exhibit this problem and add a new test case designed to cover the behavior explicitly. --- src/Output.cxx | 35 +++++++++++++++------- test/CMakeLists.txt | 1 + ...cxml.any.Class-implicit-member-bad-base.xml.txt | 10 +++---- ...any.Class-template-member-Typedef-const.xml.txt | 23 ++++++++++++++ test/input/Class-template-member-Typedef-const.cxx | 6 ++++ 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 test/expect/gccxml.any.Class-template-member-Typedef-const.xml.txt create mode 100644 test/input/Class-template-member-Typedef-const.cxx diff --git a/src/Output.cxx b/src/Output.cxx index 3b7065d..973415b 100644 --- a/src/Output.cxx +++ b/src/Output.cxx @@ -159,7 +159,8 @@ class ASTVisitor: public ASTVisitorBase unsigned int AddDumpNode(clang::Decl const* d, bool complete); /** Allocate a dump node for a Clang type. */ - unsigned int AddDumpNode(DumpType dt, bool complete); + unsigned int AddDumpNode(DumpType dt, bool complete, + clang::QualType* pt = 0); /** Helper common to AddDumpNode implementation for every kind. */ template unsigned int AddDumpNodeImpl(K k, bool complete); @@ -461,7 +462,8 @@ unsigned int ASTVisitor::AddDumpNode(clang::Decl const* d, bool complete) { } //---------------------------------------------------------------------------- -unsigned int ASTVisitor::AddDumpNode(DumpType dt, bool complete) { +unsigned int ASTVisitor::AddDumpNode(DumpType dt, bool complete, + clang::QualType* pt) { clang::QualType t = dt.Type; clang::Type const* c = dt.Class; @@ -470,34 +472,39 @@ unsigned int ASTVisitor::AddDumpNode(DumpType dt, bool complete) { switch (t->getTypeClass()) { case clang::Type::Adjusted: return this->AddDumpNode(DumpType( - t->getAs()->getAdjustedType(), c), complete); + t->getAs()->getAdjustedType(), c), + complete, pt); case clang::Type::Attributed: return this->AddDumpNode(DumpType( - t->getAs()->getEquivalentType(), c), complete); + t->getAs()->getEquivalentType(), c), + complete, pt); case clang::Type::Decayed: return this->AddDumpNode(DumpType( - t->getAs()->getDecayedType(), c), complete); + t->getAs()->getDecayedType(), c), + complete, pt); case clang::Type::Elaborated: return this->AddDumpNode(DumpType( - t->getAs()->getNamedType(), c), complete); + t->getAs()->getNamedType(), c), + complete, pt); case clang::Type::Enum: return this->AddDumpNode(t->getAs()->getDecl(), complete); case clang::Type::Paren: return this->AddDumpNode(DumpType( - t->getAs()->getInnerType(), c), complete); + t->getAs()->getInnerType(), c), + complete, pt); case clang::Type::Record: return this->AddDumpNode(t->getAs()->getDecl(), complete); case clang::Type::SubstTemplateTypeParm: return this->AddDumpNode(DumpType( t->getAs()->getReplacementType(), c), - complete); + complete, pt); case clang::Type::TemplateSpecialization: { clang::TemplateSpecializationType const* tst = t->getAs(); if(tst->isSugared()) { - return this->AddDumpNode(DumpType(tst->desugar(), c), complete); + return this->AddDumpNode(DumpType(tst->desugar(), c), complete, pt); } } break; case clang::Type::Typedef: { @@ -514,7 +521,7 @@ unsigned int ASTVisitor::AddDumpNode(DumpType dt, bool complete) { // format does not include uninstantiated templates we // must use the desugared type so that we do not end up // referencing a class template as context. - return this->AddDumpNode(tdt->desugar(), complete); + return this->AddDumpNode(tdt->desugar(), complete, pt); } } } @@ -525,6 +532,12 @@ unsigned int ASTVisitor::AddDumpNode(DumpType dt, bool complete) { break; } } + + // Report to caller the type we actually will dump. + if (pt) { + *pt = t; + } + return this->AddDumpNodeImpl(dt, complete); } @@ -838,7 +851,7 @@ unsigned int ASTVisitor::GetTypeIdRef(clang::QualType t, bool complete, bool& qc, bool& qv, bool& qr) { // Add the type node. - unsigned int id = this->AddDumpNode(t, complete); + unsigned int id = this->AddDumpNode(t, complete, &t); // Check for qualifiers. qc = t.isLocalConstQualified(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5978260..fd666b6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -159,6 +159,7 @@ castxml_test_gccxml(Class-template-Method-Argument-default) castxml_test_gccxml(Class-template-bases) castxml_test_gccxml(Class-template-friends) castxml_test_gccxml(Class-template-member-Typedef) +castxml_test_gccxml(Class-template-member-Typedef-const) castxml_test_gccxml(Class-template-member-template) castxml_test_gccxml(CvQualifiedType) castxml_test_gccxml(Enumeration) diff --git a/test/expect/gccxml.any.Class-implicit-member-bad-base.xml.txt b/test/expect/gccxml.any.Class-implicit-member-bad-base.xml.txt index 3f73cac..35aec14 100644 --- a/test/expect/gccxml.any.Class-implicit-member-bad-base.xml.txt +++ b/test/expect/gccxml.any.Class-implicit-member-bad-base.xml.txt @@ -10,15 +10,15 @@ - + - + - - - + + + diff --git a/test/expect/gccxml.any.Class-template-member-Typedef-const.xml.txt b/test/expect/gccxml.any.Class-template-member-Typedef-const.xml.txt new file mode 100644 index 0000000..cc8c598 --- /dev/null +++ b/test/expect/gccxml.any.Class-template-member-Typedef-const.xml.txt @@ -0,0 +1,23 @@ +^<\?xml version="1.0"\?> +]*> + + + + + + + + + + + + + + + + + + + + +$ diff --git a/test/input/Class-template-member-Typedef-const.cxx b/test/input/Class-template-member-Typedef-const.cxx new file mode 100644 index 0000000..f2a21b7 --- /dev/null +++ b/test/input/Class-template-member-Typedef-const.cxx @@ -0,0 +1,6 @@ +template class start { + typedef T IntConst; +public: + T method(IntConst); +}; +template class start; -- cgit v0.12