Author: Jonathan Camilleri Date: 2022-09-22T17:08:41Z New Revision: 4cd7529e4caa00fa7ba27d9de18adea3c702ad8f
URL: https://github.com/llvm/llvm-project/commit/4cd7529e4caa00fa7ba27d9de18adea3c702ad8f DIFF: https://github.com/llvm/llvm-project/commit/4cd7529e4caa00fa7ba27d9de18adea3c702ad8f.diff LOG: [clang][DebugInfo] Emit access specifiers for typedefs The accessibility level of a typedef or using declaration in a struct or class was being lost when producing debug information. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D134339 Added: Modified: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-access.cpp llvm/include/llvm/IR/DIBuilder.h llvm/lib/IR/DIBuilder.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 73cb80816fae7..a5cc5930728aa 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1283,6 +1283,33 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, getDeclContextDescriptor(AliasDecl)); } +/// Convert an AccessSpecifier into the corresponding DINode flag. +/// As an optimization, return 0 if the access specifier equals the +/// default for the containing type. +static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, + const RecordDecl *RD) { + AccessSpecifier Default = clang::AS_none; + if (RD && RD->isClass()) + Default = clang::AS_private; + else if (RD && (RD->isStruct() || RD->isUnion())) + Default = clang::AS_public; + + if (Access == Default) + return llvm::DINode::FlagZero; + + switch (Access) { + case clang::AS_private: + return llvm::DINode::FlagPrivate; + case clang::AS_protected: + return llvm::DINode::FlagProtected; + case clang::AS_public: + return llvm::DINode::FlagPublic; + case clang::AS_none: + return llvm::DINode::FlagZero; + } + llvm_unreachable("unexpected access enumerator"); +} + llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { llvm::DIType *Underlying = @@ -1298,10 +1325,16 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, uint32_t Align = getDeclAlignIfRequired(Ty->getDecl(), CGM.getContext()); // Typedefs are derived from some other type. llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->getDecl()); + + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + const DeclContext *DC = Ty->getDecl()->getDeclContext(); + if (isa<RecordDecl>(DC)) + Flags = getAccessFlag(Ty->getDecl()->getAccess(), cast<RecordDecl>(DC)); + return DBuilder.createTypedef(Underlying, Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), getDeclContextDescriptor(Ty->getDecl()), Align, - Annotations); + Flags, Annotations); } static unsigned getDwarfCC(CallingConv CC) { @@ -1395,33 +1428,6 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, return F; } -/// Convert an AccessSpecifier into the corresponding DINode flag. -/// As an optimization, return 0 if the access specifier equals the -/// default for the containing type. -static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, - const RecordDecl *RD) { - AccessSpecifier Default = clang::AS_none; - if (RD && RD->isClass()) - Default = clang::AS_private; - else if (RD && (RD->isStruct() || RD->isUnion())) - Default = clang::AS_public; - - if (Access == Default) - return llvm::DINode::FlagZero; - - switch (Access) { - case clang::AS_private: - return llvm::DINode::FlagPrivate; - case clang::AS_protected: - return llvm::DINode::FlagProtected; - case clang::AS_public: - return llvm::DINode::FlagPublic; - case clang::AS_none: - return llvm::DINode::FlagZero; - } - llvm_unreachable("unexpected access enumerator"); -} - llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl, llvm::DIScope *RecordTy, const RecordDecl *RD) { diff --git a/clang/test/CodeGenCXX/debug-info-access.cpp b/clang/test/CodeGenCXX/debug-info-access.cpp index cd5328be0a85c..9f2c044843d0f 100644 --- a/clang/test/CodeGenCXX/debug-info-access.cpp +++ b/clang/test/CodeGenCXX/debug-info-access.cpp @@ -9,7 +9,6 @@ struct A { static int pub_default_static; }; - // CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: ![[A]],{{.*}} flags: DIFlagPublic, extraData: i32 0) class B : public A { public: @@ -17,9 +16,17 @@ class B : public A { void pub(); // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "public_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagStaticMember) static int public_static; + protected: + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_typedef",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected) + typedef int prot_typedef; + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_using",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected) + using prot_using = prot_typedef; + prot_using prot_member; + // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected | DIFlagPrototyped, void prot(); + private: // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, void priv_default(); diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 9afa715b650c5..371a70fd1ee9c 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -282,10 +282,12 @@ namespace llvm { /// \param LineNo Line number. /// \param Context The surrounding context for the typedef. /// \param AlignInBits Alignment. (optional) + /// \param Flags Flags to describe inheritance attribute, e.g. private /// \param Annotations Annotations. (optional) DIDerivedType *createTypedef(DIType *Ty, StringRef Name, DIFile *File, unsigned LineNo, DIScope *Context, uint32_t AlignInBits = 0, + DINode::DIFlags Flags = DINode::FlagZero, DINodeArray Annotations = nullptr); /// Create debugging information entry for a 'friend'. diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 34ffc94252813..fada07ac383ae 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -348,11 +348,11 @@ DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits, DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, DIFile *File, unsigned LineNo, DIScope *Context, uint32_t AlignInBits, + DINode::DIFlags Flags, DINodeArray Annotations) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File, LineNo, getNonCompileUnitScope(Context), Ty, 0, - AlignInBits, 0, None, DINode::FlagZero, nullptr, - Annotations); + AlignInBits, 0, None, Flags, nullptr, Annotations); } DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits