Let front-end tie subprogram declaration with subprogram definition directly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130028 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2011-04-22 23:10:17 +00:00
parent 3728b4ad8b
commit 5e06bb83f4
5 changed files with 67 additions and 48 deletions

View File

@ -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>

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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);