mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Let front-end tie subprogram declaration with subprogram definition directly.
llvm-svn: 130028
This commit is contained in:
parent
4de9ef5cf7
commit
929bbb6bf9
@ -433,15 +433,16 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
|
||||
i32, ;; Line number where defined
|
||||
metadata, ;; Reference to type descriptor
|
||||
i1, ;; True if the global is local to compile unit (static)
|
||||
i1 ;; True if the global is defined in the compile unit (not extern)
|
||||
i32 ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual
|
||||
i32 ;; Index into a virtual function
|
||||
i1, ;; True if the global is defined in the compile unit (not extern)
|
||||
i32, ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual
|
||||
i32, ;; Index into a virtual function
|
||||
metadata, ;; indicates which base type contains the vtable pointer for the
|
||||
;; derived class
|
||||
i1 ;; isArtificial
|
||||
i1 ;; isOptimized
|
||||
Function *;; Pointer to LLVM function
|
||||
metadata ;; Lists function template parameters
|
||||
i1, ;; isArtificial
|
||||
i1, ;; isOptimized
|
||||
Function *,;; Pointer to LLVM function
|
||||
metadata, ;; Lists function template parameters
|
||||
metadata ;; Function declaration descriptor
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -401,7 +401,8 @@ namespace llvm {
|
||||
unsigned Flags = 0,
|
||||
bool isOptimized = false,
|
||||
Function *Fn = 0,
|
||||
MDNode *TParam = 0);
|
||||
MDNode *TParam = 0,
|
||||
MDNode *Decl = 0);
|
||||
|
||||
/// createMethod - Create a new descriptor for the specified C++ method.
|
||||
/// See comments in DISubprogram for descriptions of these fields.
|
||||
|
@ -538,6 +538,9 @@ namespace llvm {
|
||||
|
||||
Function *getFunction() const { return getFunctionField(16); }
|
||||
DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
|
||||
DISubprogram getFunctionDeclaration() const {
|
||||
return getFieldAs<DISubprogram>(18);
|
||||
}
|
||||
};
|
||||
|
||||
/// DIGlobalVariable - This is a wrapper for a global variable.
|
||||
|
@ -672,7 +672,8 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context,
|
||||
bool isLocalToUnit, bool isDefinition,
|
||||
unsigned Flags, bool isOptimized,
|
||||
Function *Fn,
|
||||
MDNode *TParams) {
|
||||
MDNode *TParams,
|
||||
MDNode *Decl) {
|
||||
Value *Elts[] = {
|
||||
GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
|
||||
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
|
||||
@ -691,7 +692,8 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context,
|
||||
ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
|
||||
ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
|
||||
Fn,
|
||||
TParams
|
||||
TParams,
|
||||
Decl
|
||||
};
|
||||
MDNode *Node = MDNode::get(VMContext, Elts);
|
||||
|
||||
|
@ -322,6 +322,21 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {
|
||||
return SPDie;
|
||||
|
||||
SPDie = new DIE(dwarf::DW_TAG_subprogram);
|
||||
|
||||
// DW_TAG_inlined_subroutine may refer to this DIE.
|
||||
SPCU->insertDIE(SP, SPDie);
|
||||
|
||||
// Add to context owner.
|
||||
SPCU->addToContextOwner(SPDie, SP.getContext());
|
||||
|
||||
// Add function template parameters.
|
||||
SPCU->addTemplateParams(*SPDie, SP.getTemplateParams());
|
||||
|
||||
// If this DIE is going to refer declaration info using AT_specification
|
||||
// then there is no need to add other attributes.
|
||||
if (SP.getFunctionDeclaration().isSubprogram())
|
||||
return SPDie;
|
||||
|
||||
// Constructors and operators for anonymous aggregates do not have names.
|
||||
if (!SP.getName().empty())
|
||||
SPCU->addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
|
||||
@ -336,7 +351,7 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {
|
||||
|
||||
if (SP.isPrototyped())
|
||||
SPCU->addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
|
||||
|
||||
|
||||
// Add Return Type.
|
||||
DICompositeType SPTy = SP.getType();
|
||||
DIArray Args = SPTy.getTypeArray();
|
||||
@ -391,15 +406,6 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {
|
||||
SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
|
||||
}
|
||||
|
||||
// Add function template parameters.
|
||||
SPCU->addTemplateParams(*SPDie, SP.getTemplateParams());
|
||||
|
||||
// DW_TAG_inlined_subroutine may refer to this DIE.
|
||||
SPCU->insertDIE(SP, SPDie);
|
||||
|
||||
// Add to context owner.
|
||||
SPCU->addToContextOwner(SPDie, SP.getContext());
|
||||
|
||||
return SPDie;
|
||||
}
|
||||
|
||||
@ -454,36 +460,42 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {
|
||||
assert(SPDie && "Unable to find subprogram DIE!");
|
||||
DISubprogram SP(SPNode);
|
||||
|
||||
// There is not any need to generate specification DIE for a function
|
||||
// defined at compile unit level. If a function is defined inside another
|
||||
// function then gdb prefers the definition at top level and but does not
|
||||
// expect specification DIE in parent function. So avoid creating
|
||||
// specification DIE for a function defined inside a function.
|
||||
if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
|
||||
!SP.getContext().isFile() &&
|
||||
!isSubprogramContext(SP.getContext())) {
|
||||
SPCU-> addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
|
||||
|
||||
// Add arguments.
|
||||
DICompositeType SPTy = SP.getType();
|
||||
DIArray Args = SPTy.getTypeArray();
|
||||
unsigned SPTag = SPTy.getTag();
|
||||
if (SPTag == dwarf::DW_TAG_subroutine_type)
|
||||
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
|
||||
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
|
||||
DIType ATy = DIType(DIType(Args.getElement(i)));
|
||||
SPCU->addType(Arg, ATy);
|
||||
if (ATy.isArtificial())
|
||||
SPCU->addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
|
||||
SPDie->addChild(Arg);
|
||||
}
|
||||
DIE *SPDeclDie = SPDie;
|
||||
SPDie = new DIE(dwarf::DW_TAG_subprogram);
|
||||
DISubprogram SPDecl = SP.getFunctionDeclaration();
|
||||
if (SPDecl.isSubprogram())
|
||||
// Refer function declaration directly.
|
||||
SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
|
||||
SPDeclDie);
|
||||
SPCU->addDie(SPDie);
|
||||
createSubprogramDIE(SPDecl));
|
||||
else {
|
||||
// There is not any need to generate specification DIE for a function
|
||||
// defined at compile unit level. If a function is defined inside another
|
||||
// function then gdb prefers the definition at top level and but does not
|
||||
// expect specification DIE in parent function. So avoid creating
|
||||
// specification DIE for a function defined inside a function.
|
||||
if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
|
||||
!SP.getContext().isFile() &&
|
||||
!isSubprogramContext(SP.getContext())) {
|
||||
SPCU-> addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
|
||||
|
||||
// Add arguments.
|
||||
DICompositeType SPTy = SP.getType();
|
||||
DIArray Args = SPTy.getTypeArray();
|
||||
unsigned SPTag = SPTy.getTag();
|
||||
if (SPTag == dwarf::DW_TAG_subroutine_type)
|
||||
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
|
||||
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
|
||||
DIType ATy = DIType(DIType(Args.getElement(i)));
|
||||
SPCU->addType(Arg, ATy);
|
||||
if (ATy.isArtificial())
|
||||
SPCU->addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
|
||||
SPDie->addChild(Arg);
|
||||
}
|
||||
DIE *SPDeclDie = SPDie;
|
||||
SPDie = new DIE(dwarf::DW_TAG_subprogram);
|
||||
SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
|
||||
SPDeclDie);
|
||||
SPCU->addDie(SPDie);
|
||||
}
|
||||
}
|
||||
|
||||
// Pick up abstract subprogram DIE.
|
||||
if (DIE *AbsSPDIE = AbstractSPDies.lookup(SPNode)) {
|
||||
SPDie = new DIE(dwarf::DW_TAG_subprogram);
|
||||
|
Loading…
Reference in New Issue
Block a user