diff --git a/kdevplatform/language/duchain/classmemberdeclaration.h b/kdevplatform/language/duchain/classmemberdeclaration.h --- a/kdevplatform/language/duchain/classmemberdeclaration.h +++ b/kdevplatform/language/duchain/classmemberdeclaration.h @@ -71,6 +71,38 @@ bool isMutable() const; void setMutable(bool isMutable); + /** + * \returns The size in bytes or -1 if unknown. + */ + int64_t sizeOf() const; + + /** + * Set the size to given number of bytes. Use -1 to represent unknown size. + */ + void setSizeOf(int64_t sizeOf); + + /** + * \returns The offset of the field in bits or -1 if unknown or not applicable. + */ + int64_t bitOffsetOf() const; + + /** + * Set the offset to given number of bits. Use -1 to represent unknown offset. + */ + void setBitOffsetOf(int64_t bitOffsetOf); + + /** + * \returns The alignment in bytes or -1 if unknown. + */ + int64_t alignOf() const; + + /** + * Set the alignment to given number of bytes. + * + * The value must be non-negative power of 2 or -1 to represent unknown alignment. + */ + void setAlignOf(int64_t alignedTo); + enum { Identity = 9 }; diff --git a/kdevplatform/language/duchain/classmemberdeclaration.cpp b/kdevplatform/language/duchain/classmemberdeclaration.cpp --- a/kdevplatform/language/duchain/classmemberdeclaration.cpp +++ b/kdevplatform/language/duchain/classmemberdeclaration.cpp @@ -29,12 +29,15 @@ ClassMemberDeclarationData::ClassMemberDeclarationData() : m_accessPolicy(Declaration::Public) + , m_alignOfExponent(ClassMemberDeclarationData::MaxAlignOfExponent) , m_isStatic(false) , m_isAuto(false) , m_isFriend(false) , m_isRegister(false) , m_isExtern(false) , m_isMutable(false) + , m_sizeOf(-1) + , m_bitOffsetOf(-1) { } @@ -150,4 +153,48 @@ d->m_isExtern = specifiers & ExternSpecifier; d->m_isMutable = specifiers & MutableSpecifier; } + + +int64_t ClassMemberDeclaration::sizeOf() const +{ + return d_func()->m_sizeOf; +} + +void ClassMemberDeclaration::setSizeOf(int64_t sizeOf) +{ + d_func_dynamic()->m_sizeOf = sizeOf; +} + +int64_t ClassMemberDeclaration::bitOffsetOf() const +{ + return d_func()->m_bitOffsetOf; +} + +void ClassMemberDeclaration::setBitOffsetOf(int64_t bitOffsetOf) +{ + d_func_dynamic()->m_bitOffsetOf = bitOffsetOf; +} + +int64_t ClassMemberDeclaration::alignOf() const +{ + if (d_func()->m_alignOfExponent == ClassMemberDeclarationData::MaxAlignOfExponent) { + return -1; + } else { + return 1 << d_func()->m_alignOfExponent; + } +} + +void ClassMemberDeclaration::setAlignOf(int64_t alignedTo) +{ + if (alignedTo <= 0) { + d_func_dynamic()->m_alignOfExponent = ClassMemberDeclarationData::MaxAlignOfExponent; + return; + } + + unsigned int alignOfExponent = 0; + while (alignedTo >>= 1) + alignOfExponent++; + d_func_dynamic()->m_alignOfExponent = alignOfExponent; +} + } diff --git a/kdevplatform/language/duchain/classmemberdeclarationdata.h b/kdevplatform/language/duchain/classmemberdeclarationdata.h --- a/kdevplatform/language/duchain/classmemberdeclarationdata.h +++ b/kdevplatform/language/duchain/classmemberdeclarationdata.h @@ -35,12 +35,26 @@ ClassMemberDeclarationData( const ClassMemberDeclarationData& rhs ) = default; Declaration::AccessPolicy m_accessPolicy; + + /** + * Since alignOf must be integral power of 2, we only need to store the power. + * The max value (63) represents unknown alignment. + */ + unsigned m_alignOfExponent : 6; + static constexpr unsigned MaxAlignOfExponent = 63; + bool m_isStatic: 1; bool m_isAuto: 1; bool m_isFriend: 1; bool m_isRegister: 1; bool m_isExtern: 1; bool m_isMutable: 1; + + /// Stores sizeOf in bytes or -1 if unknown. + int64_t m_sizeOf; + + /// Stores bitOffsetOf in bits or -1 if unknown. + int64_t m_bitOffsetOf; }; } diff --git a/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.h b/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.h --- a/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.h +++ b/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.h @@ -67,6 +67,7 @@ static QString stringFromAccess(const DeclarationPointer& decl); QString declarationName( const DeclarationPointer& decl ) const; static QStringList declarationDetails(const DeclarationPointer& decl); + static QString declarationSizeInformation(const DeclarationPointer& decl); ///This can be used for example to resolve typedefs within the type. ///All types that are visualized in the navigation-context are/should be mangled through this. diff --git a/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp b/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp --- a/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp +++ b/kdevplatform/language/duchain/navigation/abstractdeclarationnavigationcontext.cpp @@ -330,6 +330,10 @@ } } + if(!shorten) { + modifyHtml() += declarationSizeInformation(d->m_declaration); + } + if(!shorten && doc) { modifyHtml() += QLatin1String("
") + i18n("Show documentation for ");
makeLink(prettyQualifiedName(d->m_declaration),
@@ -784,4 +788,37 @@
return details;
}
+QString AbstractDeclarationNavigationContext::declarationSizeInformation(const DeclarationPointer& decl)
+{
+ // Note that ClassMemberDeclaration also includes ClassDeclaration, which uses the sizeOf and alignOf fields,
+ // but normally leaves the bitOffsetOf unset (-1).
+ const ClassMemberDeclaration* memberDecl = dynamic_cast ";
+
+ if (memberDecl->bitOffsetOf() >= 0) {
+ const auto byteOffset = memberDecl->bitOffsetOf() / 8;
+ const auto bitOffset = memberDecl->bitOffsetOf() % 8;
+ const QString byteOffsetStr = i18np("1 Byte", "%1 Bytes", byteOffset);
+ const QString bitOffsetStr = bitOffset ? i18np("1 Bit", "%1 Bits", bitOffset) : QString();
+ sizeInfo += i18n("offset in parent: %1", bitOffset ? i18nc("%1: bytes, %2: bits", "%1, %2", byteOffsetStr, bitOffsetStr) : byteOffsetStr);
+ sizeInfo += "; ";
+ }
+
+ if (memberDecl->sizeOf() >= 0) {
+ sizeInfo += i18n("size: %1 Bytes", memberDecl->sizeOf());
+ sizeInfo += "; ";
+ }
+
+ if (memberDecl->alignOf() >= 0) {
+ sizeInfo += i18n("aligned to: %1 Bytes", memberDecl->alignOf());
+ }
+
+ sizeInfo += " offset in parent: %1; "
- "size: %2 Bytes; "
- "aligned to: %3 Bytes size: %1 Bytes; "
- "aligned to: %2 Bytes