diff options
-rw-r--r-- | src/Output.cxx | 11 | ||||
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/expect/gccxml.any.Class-base-offset.xml.txt | 11 | ||||
-rw-r--r-- | test/expect/gccxml.any.Class-base-typedef.xml.txt | 2 | ||||
-rw-r--r-- | test/expect/gccxml.any.Class-implicit-member-access-mutable.xml.txt | 2 | ||||
-rw-r--r-- | test/expect/gccxml.any.Class-implicit-member-access.xml.txt | 2 | ||||
-rw-r--r-- | test/expect/gccxml.any.Class-implicit-member-bad-base.xml.txt | 2 | ||||
-rw-r--r-- | test/expect/gccxml.any.Method-overrides.xml.txt | 2 | ||||
-rw-r--r-- | test/expect/gccxml.any.using-declaration-class.xml.txt | 2 | ||||
-rw-r--r-- | test/expect/gccxml.c++11.Class-bases.xml.txt | 4 | ||||
-rw-r--r-- | test/expect/gccxml.c++11.Class-template-bases.xml.txt | 4 | ||||
-rw-r--r-- | test/expect/gccxml.c++14.Class-bases.xml.txt | 4 | ||||
-rw-r--r-- | test/expect/gccxml.c++14.Class-template-bases.xml.txt | 4 | ||||
-rw-r--r-- | test/expect/gccxml.c++98.Class-bases.xml.txt | 4 | ||||
-rw-r--r-- | test/expect/gccxml.c++98.Class-template-bases.xml.txt | 4 | ||||
-rw-r--r-- | test/input/Class-base-offset.cxx | 4 | ||||
-rw-r--r-- | test/run.cmake | 3 |
17 files changed, 47 insertions, 19 deletions
diff --git a/src/Output.cxx b/src/Output.cxx index 5051b61..43af2e1 100644 --- a/src/Output.cxx +++ b/src/Output.cxx @@ -26,6 +26,7 @@ #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Mangle.h" +#include "clang/AST/RecordLayout.h" #include "clang/Basic/Specifiers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" @@ -1545,12 +1546,20 @@ void ASTVisitor::OutputRecordDecl(clang::RecordDecl const* d, this->PrintAttributesAttribute(d); if(doBases) { this->OS << ">\n"; + clang::ASTRecordLayout const& layout = this->CTX.getASTRecordLayout(dx); for(clang::CXXRecordDecl::base_class_const_iterator i = dx->bases_begin(), e = dx->bases_end(); i != e; ++i) { + clang::QualType bt = i->getType().getCanonicalType(); + clang::CXXRecordDecl const* bd = clang::dyn_cast<clang::CXXRecordDecl>( + bt->getAs<clang::RecordType>()->getDecl()); this->OS << " <Base"; - this->PrintTypeAttribute(i->getType().getCanonicalType(), true); + this->PrintTypeAttribute(bt, true); this->PrintAccessAttribute(i->getAccessSpecifier()); this->OS << " virtual=\"" << (i->isVirtual()? 1 : 0) << "\""; + if (bd && !i->isVirtual()) { + this->OS << " offset=\"" << + layout.getBaseClassOffset(bd).getQuantity() << "\""; + } this->OS << "/>\n"; } this->OS << " </" << tag << ">\n"; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8efb924..b13fbb1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -212,6 +212,7 @@ castxml_test_gccxml(ArrayType-incomplete) castxml_test_gccxml(Class) castxml_test_gccxml(Class-abstract) castxml_test_gccxml(Class-annotate) +castxml_test_gccxml(Class-base-offset) castxml_test_gccxml(Class-base-typedef) castxml_test_gccxml(Class-bases) castxml_test_gccxml(Class-forward) diff --git a/test/expect/gccxml.any.Class-base-offset.xml.txt b/test/expect/gccxml.any.Class-base-offset.xml.txt new file mode 100644 index 0000000..14f49b6 --- /dev/null +++ b/test/expect/gccxml.any.Class-base-offset.xml.txt @@ -0,0 +1,11 @@ +^<\?xml version="1.0"\?> +<GCC_XML[^>]*> + <Class id="_1" name="start" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 _8 _9" size="[0-9]+" align="[0-9]+"> + <Base type="_7" access="public" virtual="0" offset="0"/> + <Base type="_8" access="public" virtual="0" offset="1"/> + <Base type="_9" access="public" virtual="0" offset="2"/> + </Class> +.* + <Namespace id="_2" name="::"/> + <File id="f1" name=".*/test/input/Class-base-offset.cxx"/> +</GCC_XML>$ diff --git a/test/expect/gccxml.any.Class-base-typedef.xml.txt b/test/expect/gccxml.any.Class-base-typedef.xml.txt index 101af60..f82be8a 100644 --- a/test/expect/gccxml.any.Class-base-typedef.xml.txt +++ b/test/expect/gccxml.any.Class-base-typedef.xml.txt @@ -1,7 +1,7 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:3" file="f1" line="3" members="_3 _4 _5 _6" bases="_7" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="0"/> </Class> <Constructor id="_3" name="start" context="_1" access="public" location="f1:3" file="f1" line="3" inline="1" artificial="1"( throw="")?/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:3" file="f1" line="3" inline="1" artificial="1"( throw="")?> diff --git a/test/expect/gccxml.any.Class-implicit-member-access-mutable.xml.txt b/test/expect/gccxml.any.Class-implicit-member-access-mutable.xml.txt index 833adbd..56dece8 100644 --- a/test/expect/gccxml.any.Class-implicit-member-access-mutable.xml.txt +++ b/test/expect/gccxml.any.Class-implicit-member-access-mutable.xml.txt @@ -1,7 +1,7 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:10" file="f1" line="10" members="_3 _4" bases="_5" size="[0-9]+" align="[0-9]+"> - <Base type="_5" access="public" virtual="0"/> + <Base type="_5" access="public" virtual="0" offset="0"/> </Class> <Destructor id="_3" name="start" context="_1" access="public" location="f1:10" file="f1" line="10" inline="1" artificial="1"( throw="")?/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:10" file="f1" line="10" inline="1" artificial="1"( throw="")?/> diff --git a/test/expect/gccxml.any.Class-implicit-member-access.xml.txt b/test/expect/gccxml.any.Class-implicit-member-access.xml.txt index 7ccf23a..9cf2a14 100644 --- a/test/expect/gccxml.any.Class-implicit-member-access.xml.txt +++ b/test/expect/gccxml.any.Class-implicit-member-access.xml.txt @@ -1,7 +1,7 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:9" file="f1" line="9" members="_3 _4" bases="_5" size="[0-9]+" align="[0-9]+"> - <Base type="_5" access="public" virtual="0"/> + <Base type="_5" access="public" virtual="0" offset="0"/> </Class> <Destructor id="_3" name="start" context="_1" access="public" location="f1:9" file="f1" line="9" inline="1" artificial="1"( throw="")?/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:9" file="f1" line="9" inline="1" artificial="1"( throw="")?/> 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 16ba2dc..6c98ab9 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 @@ -1,7 +1,7 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:9" file="f1" line="9" members="_3 _4 _5" bases="_6" size="[0-9]+" align="[0-9]+"> - <Base type="_6" access="public" virtual="0"/> + <Base type="_6" access="public" virtual="0" offset="0"/> </Class> <Constructor id="_3" name="start" context="_1" access="public" location="f1:9" file="f1" line="9" inline="1" artificial="1"( throw="")?/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:9" file="f1" line="9" inline="1" artificial="1"( throw="")?> diff --git a/test/expect/gccxml.any.Method-overrides.xml.txt b/test/expect/gccxml.any.Method-overrides.xml.txt index 5bce53e..dc95285 100644 --- a/test/expect/gccxml.any.Method-overrides.xml.txt +++ b/test/expect/gccxml.any.Method-overrides.xml.txt @@ -1,7 +1,7 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6 _7" bases="_8" size="[0-9]+" align="[0-9]+"> - <Base type="_8" access="public" virtual="0"/> + <Base type="_8" access="public" virtual="0" offset="0"/> </Class> <Method id="_3" name="method" returns="_9" context="_1" access="private" location="f1:5" file="f1" line="5" virtual="1" overrides="_10" mangled="[^"]+"> <Argument type="_9" location="f1:5" file="f1" line="5"/> diff --git a/test/expect/gccxml.any.using-declaration-class.xml.txt b/test/expect/gccxml.any.using-declaration-class.xml.txt index 4ab41e3..857d19f 100644 --- a/test/expect/gccxml.any.using-declaration-class.xml.txt +++ b/test/expect/gccxml.any.using-declaration-class.xml.txt @@ -1,7 +1,7 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:5" file="f1" line="5" members="_3 _4 _5 _6 _7 _8" bases="_9" size="[0-9]+" align="[0-9]+"> - <Base type="_9" access="public" virtual="0"/> + <Base type="_9" access="public" virtual="0" offset="0"/> </Class> <Method id="_3" name="f" returns="_10" context="_9" access="protected" location="f1:3" file="f1" line="3" mangled="[^"]+"> <Argument type="_10" location="f1:3" file="f1" line="3"/> diff --git a/test/expect/gccxml.c++11.Class-bases.xml.txt b/test/expect/gccxml.c++11.Class-bases.xml.txt index c9535df..48b51e1 100644 --- a/test/expect/gccxml.c++11.Class-bases.xml.txt +++ b/test/expect/gccxml.c++11.Class-bases.xml.txt @@ -1,8 +1,8 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 private:_8 protected:_9" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> - <Base type="_8" access="private" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="[0-9]+"/> + <Base type="_8" access="private" virtual="0" offset="[0-9]+"/> <Base type="_9" access="protected" virtual="1"/> </Class> <OperatorMethod id="_3" name="=" returns="_10" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1" mangled="[^"]+"> diff --git a/test/expect/gccxml.c++11.Class-template-bases.xml.txt b/test/expect/gccxml.c++11.Class-template-bases.xml.txt index 33f0acc..6f9b62a 100644 --- a/test/expect/gccxml.c++11.Class-template-bases.xml.txt +++ b/test/expect/gccxml.c++11.Class-template-bases.xml.txt @@ -1,8 +1,8 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start<int>" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 _8" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> - <Base type="_8" access="public" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="[0-9]+"/> + <Base type="_8" access="public" virtual="0" offset="[0-9]+"/> </Class> <Constructor id="_3" name="start" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1"/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1"> diff --git a/test/expect/gccxml.c++14.Class-bases.xml.txt b/test/expect/gccxml.c++14.Class-bases.xml.txt index c9535df..48b51e1 100644 --- a/test/expect/gccxml.c++14.Class-bases.xml.txt +++ b/test/expect/gccxml.c++14.Class-bases.xml.txt @@ -1,8 +1,8 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 private:_8 protected:_9" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> - <Base type="_8" access="private" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="[0-9]+"/> + <Base type="_8" access="private" virtual="0" offset="[0-9]+"/> <Base type="_9" access="protected" virtual="1"/> </Class> <OperatorMethod id="_3" name="=" returns="_10" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1" mangled="[^"]+"> diff --git a/test/expect/gccxml.c++14.Class-template-bases.xml.txt b/test/expect/gccxml.c++14.Class-template-bases.xml.txt index 33f0acc..6f9b62a 100644 --- a/test/expect/gccxml.c++14.Class-template-bases.xml.txt +++ b/test/expect/gccxml.c++14.Class-template-bases.xml.txt @@ -1,8 +1,8 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start<int>" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 _8" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> - <Base type="_8" access="public" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="[0-9]+"/> + <Base type="_8" access="public" virtual="0" offset="[0-9]+"/> </Class> <Constructor id="_3" name="start" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1"/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1"> diff --git a/test/expect/gccxml.c++98.Class-bases.xml.txt b/test/expect/gccxml.c++98.Class-bases.xml.txt index d7ffa95..6e58110 100644 --- a/test/expect/gccxml.c++98.Class-bases.xml.txt +++ b/test/expect/gccxml.c++98.Class-bases.xml.txt @@ -1,8 +1,8 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 private:_8 protected:_9" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> - <Base type="_8" access="private" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="[0-9]+"/> + <Base type="_8" access="private" virtual="0" offset="[0-9]+"/> <Base type="_9" access="protected" virtual="1"/> </Class> <OperatorMethod id="_3" name="=" returns="_10" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1" throw="" mangled="[^"]+"> diff --git a/test/expect/gccxml.c++98.Class-template-bases.xml.txt b/test/expect/gccxml.c++98.Class-template-bases.xml.txt index 2c8728f..44c30e1 100644 --- a/test/expect/gccxml.c++98.Class-template-bases.xml.txt +++ b/test/expect/gccxml.c++98.Class-template-bases.xml.txt @@ -1,8 +1,8 @@ ^<\?xml version="1.0"\?> <GCC_XML[^>]*> <Class id="_1" name="start<int>" context="_2" location="f1:4" file="f1" line="4" members="_3 _4 _5 _6" bases="_7 _8" size="[0-9]+" align="[0-9]+"> - <Base type="_7" access="public" virtual="0"/> - <Base type="_8" access="public" virtual="0"/> + <Base type="_7" access="public" virtual="0" offset="[0-9]+"/> + <Base type="_8" access="public" virtual="0" offset="[0-9]+"/> </Class> <Constructor id="_3" name="start" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1"( throw="")?/> <Constructor id="_4" name="start" context="_1" access="public" location="f1:4" file="f1" line="4" inline="1" artificial="1" throw=""> diff --git a/test/input/Class-base-offset.cxx b/test/input/Class-base-offset.cxx new file mode 100644 index 0000000..279584c --- /dev/null +++ b/test/input/Class-base-offset.cxx @@ -0,0 +1,4 @@ +class base_1 { char b1; }; +class base_2 { char b2; }; +class base_3 { char b3; }; +class start: public base_1, public base_2, public base_3 {}; diff --git a/test/run.cmake b/test/run.cmake index e254b33..e7b2c29 100644 --- a/test/run.cmake +++ b/test/run.cmake @@ -96,6 +96,9 @@ if(msg) string(REGEX REPLACE "artificial=\"1\"( throw=\"\")?" "artificial=\"1\"( throw=\"\")?" update_xml "${update_xml}") string(REGEX REPLACE "size=\"[0-9]+\" align=\"[0-9]+\"" "size=\"[0-9]+\" align=\"[0-9]+\"" update_xml "${update_xml}") string(REGEX REPLACE "<File id=\"(f[0-9]+)\" name=\"[^\"]*/test/input/([^\"]*)\"/>" "<File id=\"\\1\" name=\".*/test/input/\\2\"/>" update_xml "${update_xml}") + if(update_xml MATCHES "<Base.*<Base") # multiple inheritance has ABI-specific offsets + string(REGEX REPLACE "<Base type=\"([^\"]*)\" access=\"([^\"]*)\" virtual=\"0\" offset=\"[0-9]+\"/>" "<Base type=\"\\1\" access=\"\\2\" virtual=\"0\" offset=\"[0-9]+\"/>" update_xml "${update_xml}") + endif() string(REGEX REPLACE "</GCC_XML>$" "</GCC_XML>$" update_xml "${update_xml}") file(WRITE "${expect_xml_file}" "${update_xml}\n") endif() |