Few little fixes to reading in inlined functions. Also added a test case with some inlining.

llvm-svn: 110892
This commit is contained in:
Jim Ingham 2010-08-12 01:20:14 +00:00
parent 12d53da8cb
commit b0be442408
3 changed files with 190 additions and 6 deletions

View File

@ -1144,8 +1144,8 @@ SymbolFileDWARF::ParseFunctionBlocks
switch (tag)
{
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
case DW_TAG_lexical_block:
{
DWARFDebugRanges::RangeList ranges;
@ -1160,25 +1160,44 @@ SymbolFileDWARF::ParseFunctionBlocks
int call_file = 0;
int call_line = 0;
int call_column = 0;
if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column))
if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges,
decl_file, decl_line, decl_column,
call_file, call_line, call_column))
{
if (tag == DW_TAG_subprogram)
{
assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
subprogram_low_pc = ranges.LowestAddress(0);
}
else if (tag == DW_TAG_inlined_subroutine)
{
// We get called here for inlined subroutines in two ways.
// The first time is when we are making the Function object
// for this inlined concrete instance. Since we're creating a top level block at
// here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
// adjust the containing address.
// The second time is when we are parsing the blocks inside the function that contains
// the inlined concrete instance. Since these will be blocks inside the containing "real"
// function the offset will be for that function.
if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
{
subprogram_low_pc = ranges.LowestAddress(0);
}
}
AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc);
if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
{
std::auto_ptr<Declaration> decl_ap;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
decl_line, decl_column));
std::auto_ptr<Declaration> call_ap;
if (call_file != 0 || call_line != 0 || call_column != 0)
call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column));
call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
call_line, call_column));
blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get());
}
@ -1187,7 +1206,8 @@ SymbolFileDWARF::ParseFunctionBlocks
if (parse_children && die->HasChildren())
{
blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true);
blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(),
subprogram_low_pc, true, true);
}
}
}
@ -2854,6 +2874,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
}
break;
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
case DW_TAG_subroutine_type:
{

125
lldb/test/inlines/Makefile Normal file
View File

@ -0,0 +1,125 @@
#----------------------------------------------------------------------
# Fill in the source files to build
#----------------------------------------------------------------------
C_SOURCES := inlines.c
CXX_SOURCES :=
OBJC_SOURCES :=
OBJCXX_SOURCES :=
# Uncomment line below for debugging shell commands
# SHELL = /bin/sh -x
#----------------------------------------------------------------------
# Change any build/tool options needed
#----------------------------------------------------------------------
DS := /usr/bin/dsymutil
DSFLAGS =
CFLAGS ?=-arch x86_64 -gdwarf-2 -O0
CPLUSPLUSFLAGS +=$(CFLAGS)
CPPFLAGS +=$(CFLAGS)
LD = gcc
LDFLAGS = $(CFLAGS)
OBJECTS =
EXE=a.out
DSYM=$(EXE).dSYM
#----------------------------------------------------------------------
# Check if we have any C source files
#----------------------------------------------------------------------
ifneq "$(strip $(C_SOURCES))" ""
OBJECTS +=$(strip $(C_SOURCES:.c=.o))
endif
#----------------------------------------------------------------------
# Check if we have any C++ source files
#----------------------------------------------------------------------
ifneq "$(strip $(CXX_SOURCES))" ""
OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o))
LD = g++
endif
#----------------------------------------------------------------------
# Check if we have any ObjC source files
#----------------------------------------------------------------------
ifneq "$(strip $(OBJC_SOURCES))" ""
OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o))
LDFLAGS +=-lobjc
endif
#----------------------------------------------------------------------
# Check if we have any ObjC++ source files
#----------------------------------------------------------------------
ifneq "$(strip $(OBJCXX_SOURCES))" ""
OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o))
LD = g++
ifeq $(findstring lobjc,$(LDFLAGS)) ""
LDFLAGS +=-lobjc
endif
endif
#----------------------------------------------------------------------
# Make the dSYM file from the executable
#----------------------------------------------------------------------
$(DSYM) : $(EXE)
$(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)"
#----------------------------------------------------------------------
# Compile the executable from all the objects (default rule) with no
# dsym file.
#----------------------------------------------------------------------
$(EXE) : $(OBJECTS)
$(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)"
#----------------------------------------------------------------------
# Automatic variables based on items already entered. Below we create
# an objects lists from the list of sources by replacing all entries
# that end with .c with .o, and we also create a list of prerequisite
# files by replacing all .c files with .d.
#----------------------------------------------------------------------
PREREQS := $(OBJECTS:.o=.d)
#----------------------------------------------------------------------
# Rule for Generating Prerequisites Automatically using .d files and
# the compiler -MM option. The -M option will list all system headers,
# and the -MM option will list all non-system dependencies.
#----------------------------------------------------------------------
%.d: %.c
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
%.d: %.cpp
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
%.d: %.m
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
%.d: %.mm
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
#----------------------------------------------------------------------
# Include all of the makefiles for each source file so we don't have
# to manually track all of the prerequisites for each source file.
#----------------------------------------------------------------------
sinclude $(PREREQS)
.PHONY: clean
dsym: $(DSYM)
all: $(EXE) $(DSYM)
clean:
rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) *~

View File

@ -0,0 +1,38 @@
#include <stdio.h>
#define INLINE_ME __inline__ __attribute__((always_inline))
INLINE_ME int
inner_inline (int inner_input, int mod_value)
{
int inner_result;
inner_result = inner_input % mod_value;
printf ("Returning: %d.\n", inner_result);
return inner_result;
}
INLINE_ME int
outer_inline (int outer_input)
{
int outer_result;
outer_result = inner_inline (outer_input, outer_input % 3);
return outer_result;
}
int
main (int argc, char **argv)
{
printf ("Starting...\n");
int (*func_ptr) (int);
func_ptr = outer_inline;
outer_inline (argc);
func_ptr (argc);
return 0;
}