aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2013-01-16 01:22:23 +0000
committerEric Christopher <echristo@gmail.com>2013-01-16 01:22:23 +0000
commit6b6061f01171bd3d4e32022efa45428d4f9941ee (patch)
treeaae4e22e2a4ca079f2ff59c85f524318eb91d5a0
parent171192f149dce679cd520f85ffced4789448b017 (diff)
Define metadata interfaces for describing a static data member
of a class. Emit static data member declarations and definitions through correctly. Part of PR14471. Patch by Paul Robinson! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172590 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/DIBuilder.h17
-rw-r--r--include/llvm/DebugInfo.h17
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp137
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.h6
-rw-r--r--lib/IR/DIBuilder.cpp32
-rw-r--r--lib/IR/DebugInfo.cpp2
6 files changed, 162 insertions, 49 deletions
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h
index e0e3fc90e7..fb7aa8b38a 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -172,6 +172,19 @@ namespace llvm {
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty);
+ /// createStaticMemberType - Create debugging information entry for a
+ /// C++ static data member.
+ /// @param Scope Member scope.
+ /// @param Name Member name.
+ /// @param File File where this member is declared.
+ /// @param LineNo Line number.
+ /// @param Ty Type of the static member.
+ /// @param Flags Flags to encode member attribute, e.g. private.
+ /// @param Val Const initializer of the member.
+ DIType createStaticMemberType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNo, DIType Ty,
+ unsigned Flags, llvm::Value *Val);
+
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
/// @param Name Member name.
@@ -402,10 +415,12 @@ namespace llvm {
/// @param isLocalToUnit Boolean flag indicate whether this variable is
/// externally visible or not.
/// @param Val llvm::Value of the variable.
+ /// @param Decl Reference to the corresponding declaration.
DIGlobalVariable
createStaticVariable(DIDescriptor Context, StringRef Name,
StringRef LinkageName, DIFile File, unsigned LineNo,
- DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+ DIType Ty, bool isLocalToUnit, llvm::Value *Val,
+ MDNode *Decl = NULL);
/// createLocalVariable - Create a new descriptor for the specified
diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h
index ec0f0006ea..fdf6e96917 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -62,7 +62,8 @@ namespace llvm {
FlagPrototyped = 1 << 8,
FlagObjcClassComplete = 1 << 9,
FlagObjectPointer = 1 << 10,
- FlagVector = 1 << 11
+ FlagVector = 1 << 11,
+ FlagStaticMember = 1 << 12
};
protected:
const MDNode *DbgNode;
@@ -300,6 +301,9 @@ namespace llvm {
bool isVector() const {
return (getFlags() & FlagVector) != 0;
}
+ bool isStaticMember() const {
+ return (getFlags() & FlagStaticMember) != 0;
+ }
bool isValid() const {
return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
}
@@ -337,7 +341,8 @@ namespace llvm {
};
/// DIDerivedType - A simple derived type, like a const qualified type,
- /// a typedef, a pointer or reference, etc.
+ /// a typedef, a pointer or reference, et cetera. Or, a data member of
+ /// a class/struct/union.
class DIDerivedType : public DIType {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
@@ -363,6 +368,11 @@ namespace llvm {
return getFieldAs<DIType>(10);
}
+ Constant *getConstant() const {
+ assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
+ return getConstantField(10);
+ }
+
StringRef getObjCPropertyName() const {
if (getVersion() > LLVMDebugVersion11)
return StringRef();
@@ -620,6 +630,9 @@ namespace llvm {
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
Constant *getConstant() const { return getConstantField(11); }
+ DIDerivedType getStaticDataMemberDeclaration() const {
+ return getFieldAs<DIDerivedType>(12);
+ }
/// Verify - Verify that a global variable descriptor is well formed.
bool Verify() const;
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 589606522a..e98b118225 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -670,18 +670,21 @@ void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
}
}
+/// getOrCreateContextDIE - Get context owner's DIE.
+DIE *CompileUnit::getOrCreateContextDIE(DIDescriptor Context) {
+ if (Context.isType())
+ return getOrCreateTypeDIE(DIType(Context));
+ else if (Context.isNameSpace())
+ return getOrCreateNameSpace(DINameSpace(Context));
+ else if (Context.isSubprogram())
+ return getOrCreateSubprogramDIE(DISubprogram(Context));
+ else
+ return getDIE(Context);
+}
+
/// addToContextOwner - Add Die into the list of its context owner's children.
void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
- if (Context.isType()) {
- DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
- ContextDIE->addChild(Die);
- } else if (Context.isNameSpace()) {
- DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
- ContextDIE->addChild(Die);
- } else if (Context.isSubprogram()) {
- DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context));
- ContextDIE->addChild(Die);
- } else if (DIE *ContextDIE = getDIE(Context))
+ if (DIE *ContextDIE = getOrCreateContextDIE(Context))
ContextDIE->addChild(Die);
else
addDie(Die);
@@ -925,22 +928,15 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
dwarf::DW_ACCESS_public);
if (SP.isExplicit())
addFlag(ElemDie, dwarf::DW_AT_explicit);
- }
- else if (Element.isVariable()) {
- DIVariable DV(Element);
- ElemDie = new DIE(dwarf::DW_TAG_variable);
- addString(ElemDie, dwarf::DW_AT_name, DV.getName());
- addType(ElemDie, DV.getType());
- addFlag(ElemDie, dwarf::DW_AT_declaration);
- addFlag(ElemDie, dwarf::DW_AT_external);
- addSourceLine(ElemDie, DV);
} else if (Element.isDerivedType()) {
DIDerivedType DDTy(Element);
if (DDTy.getTag() == dwarf::DW_TAG_friend) {
ElemDie = new DIE(dwarf::DW_TAG_friend);
addType(ElemDie, DDTy.getTypeDerivedFrom(), dwarf::DW_AT_friend);
- } else
- ElemDie = createMemberDIE(DIDerivedType(Element));
+ } else if (DDTy.isStaticMember())
+ ElemDie = createStaticMemberDIE(DDTy);
+ else
+ ElemDie = createMemberDIE(DDTy);
} else if (Element.isObjCProperty()) {
DIObjCProperty Property(Element);
ElemDie = new DIE(Property.getTag());
@@ -1256,33 +1252,48 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
if (!GV.Verify())
return;
- DIE *VariableDIE = new DIE(GV.getTag());
- // Add to map.
- insertDIE(N, VariableDIE);
-
- // Add name.
- addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
- StringRef LinkageName = GV.getLinkageName();
- bool isGlobalVariable = GV.getGlobal() != NULL;
- if (!LinkageName.empty() && isGlobalVariable)
- addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
- getRealLinkageName(LinkageName));
- // Add type.
+ DIDescriptor GVContext = GV.getContext();
DIType GTy = GV.getType();
- addType(VariableDIE, GTy);
- // Add scoping info.
- if (!GV.isLocalToUnit())
- addFlag(VariableDIE, dwarf::DW_AT_external);
+ // If this is a static data member definition, some attributes belong
+ // to the declaration DIE.
+ DIE *VariableDIE = NULL;
+ DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration();
+ if (SDMDecl.Verify()) {
+ assert(SDMDecl.isStaticMember() && "Expected static member decl");
+ // We need the declaration DIE that is in the static member's class.
+ // But that class might not exist in the DWARF yet.
+ // Creating the class will create the static member decl DIE.
+ getOrCreateContextDIE(SDMDecl.getContext());
+ VariableDIE = getDIE(SDMDecl);
+ assert(VariableDIE && "Static member decl has no context?");
+ }
+
+ // If this is not a static data member definition, create the variable
+ // DIE and add the initial set of attributes to it.
+ if (!VariableDIE) {
+ VariableDIE = new DIE(GV.getTag());
+ // Add to map.
+ insertDIE(N, VariableDIE);
+
+ // Add name and type.
+ addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
+ addType(VariableDIE, GTy);
+
+ // Add scoping info.
+ if (!GV.isLocalToUnit())
+ addFlag(VariableDIE, dwarf::DW_AT_external);
+
+ // Add line number info.
+ addSourceLine(VariableDIE, GV);
+ // Add to context owner.
+ addToContextOwner(VariableDIE, GVContext);
+ }
- // Add line number info.
- addSourceLine(VariableDIE, GV);
- // Add to context owner.
- DIDescriptor GVContext = GV.getContext();
- addToContextOwner(VariableDIE, GVContext);
// Add location.
bool addToAccelTable = false;
DIE *VariableSpecDIE = NULL;
+ bool isGlobalVariable = GV.getGlobal() != NULL;
if (isGlobalVariable) {
addToAccelTable = true;
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -1298,11 +1309,18 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
dwarf::DW_FORM_ref4, VariableDIE);
addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
- addFlag(VariableDIE, dwarf::DW_AT_declaration);
+ // A static member's declaration is already flagged as such.
+ if (!SDMDecl.Verify())
+ addFlag(VariableDIE, dwarf::DW_AT_declaration);
addDie(VariableSpecDIE);
} else {
addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
}
+ // Add linkage name.
+ StringRef LinkageName = GV.getLinkageName();
+ if (!LinkageName.empty() && isGlobalVariable)
+ addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
+ getRealLinkageName(LinkageName));
} else if (const ConstantInt *CI =
dyn_cast_or_null<ConstantInt>(GV.getConstant()))
addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
@@ -1638,3 +1656,36 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
}
return MemberDie;
}
+
+/// createStaticMemberDIE - Create new DIE for C++ static member.
+DIE *CompileUnit::createStaticMemberDIE(const DIDerivedType DT) {
+ if (!DT.Verify())
+ return NULL;
+
+ DIE *StaticMemberDIE = new DIE(DT.getTag());
+ DIType Ty = DT.getTypeDerivedFrom();
+
+ addString(StaticMemberDIE, dwarf::DW_AT_name, DT.getName());
+ addType(StaticMemberDIE, Ty);
+ addSourceLine(StaticMemberDIE, DT);
+ addFlag(StaticMemberDIE, dwarf::DW_AT_external);
+ addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);
+
+ // FIXME: We could omit private if the parent is a class_type, and
+ // public if the parent is something else.
+ if (DT.isProtected())
+ addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
+ dwarf::DW_ACCESS_protected);
+ else if (DT.isPrivate())
+ addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
+ dwarf::DW_ACCESS_private);
+ else
+ addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
+ dwarf::DW_ACCESS_public);
+
+ if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT.getConstant()))
+ addConstantValue(StaticMemberDIE, CI, Ty.isUnsignedDIType());
+
+ insertDIE(DT, StaticMemberDIE);
+ return StaticMemberDIE;
+}
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 0d84ca561b..e576ff294e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -86,6 +86,9 @@ class CompileUnit {
/// DWARF version doesn't handle the language, return -1.
int64_t getDefaultLowerBound() const;
+ /// getOrCreateContextDIE - Get context owner's DIE.
+ DIE *getOrCreateContextDIE(DIDescriptor Context);
+
public:
CompileUnit(unsigned UID, unsigned L, DIE *D, AsmPrinter *A, DwarfDebug *DW,
DwarfUnits *);
@@ -344,6 +347,9 @@ public:
/// createMemberDIE - Create new member DIE.
DIE *createMemberDIE(DIDerivedType DT);
+ /// createStaticMemberDIE - Create new static data member DIE.
+ DIE *createStaticMemberDIE(DIDerivedType DT);
+
private:
// DIEValueAllocator - All DIEValues are allocated through this allocator.
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp
index bd7f0e3ffb..0d106ace11 100644
--- a/lib/IR/DIBuilder.cpp
+++ b/lib/IR/DIBuilder.cpp
@@ -350,6 +350,30 @@ DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name,
return DIType(MDNode::get(VMContext, Elts));
}
+/// createStaticMemberType - Create debugging information entry for a
+/// C++ static data member.
+DIType DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ DIType Ty, unsigned Flags,
+ llvm::Value *Val) {
+ // TAG_member is encoded in DIDerivedType format.
+ Flags |= DIDescriptor::FlagStaticMember;
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_member),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ File,
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0/*SizeInBits*/),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0/*AlignInBits*/),
+ ConstantInt::get(Type::getInt64Ty(VMContext), 0/*OffsetInBits*/),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ Ty,
+ Val
+ };
+ return DIType(MDNode::get(VMContext, Elts));
+}
+
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
DIType DIBuilder::createObjCIVar(StringRef Name,
@@ -787,7 +811,8 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber,
Ty,
ConstantInt::get(Type::getInt32Ty(VMContext), isLocalToUnit),
ConstantInt::get(Type::getInt32Ty(VMContext), 1), /* isDefinition*/
- Val
+ Val,
+ DIDescriptor()
};
MDNode *Node = MDNode::get(VMContext, Elts);
AllGVs.push_back(Node);
@@ -799,7 +824,7 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber,
DIGlobalVariable DIBuilder::
createStaticVariable(DIDescriptor Context, StringRef Name,
StringRef LinkageName, DIFile F, unsigned LineNumber,
- DIType Ty, bool isLocalToUnit, Value *Val) {
+ DIType Ty, bool isLocalToUnit, Value *Val, MDNode *Decl) {
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_variable),
Constant::getNullValue(Type::getInt32Ty(VMContext)),
@@ -812,7 +837,8 @@ createStaticVariable(DIDescriptor Context, StringRef Name,
Ty,
ConstantInt::get(Type::getInt32Ty(VMContext), isLocalToUnit),
ConstantInt::get(Type::getInt32Ty(VMContext), 1), /* isDefinition*/
- Val
+ Val,
+ DIDescriptor(Decl)
};
MDNode *Node = MDNode::get(VMContext, Elts);
AllGVs.push_back(Node);
diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp
index 7083495c72..876aff8575 100644
--- a/lib/IR/DebugInfo.cpp
+++ b/lib/IR/DebugInfo.cpp
@@ -1101,6 +1101,8 @@ void DIType::printInternal(raw_ostream &OS) const {
OS << " [fwd]";
if (isVector())
OS << " [vector]";
+ if (isStaticMember())
+ OS << " [static]";
}
void DIDerivedType::printInternal(raw_ostream &OS) const {