[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
This commit is contained in:
parent
08288052ae
commit
4cd7529e4c
|
@ -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) {
|
||||
|
|
|
@ -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 @@ public:
|
|||
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();
|
||||
|
|
|
@ -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'.
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue