Force column info to be generated for call expressions so we can

differentiate multiple inlined call sites on the same line
in the debug info.

Fixes rdar://problem/13036237

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176895 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl 2013-03-12 20:43:25 +00:00
Родитель 61d16c1f49
Коммит 00df5eaa9f
4 изменённых файлов: 90 добавлений и 15 удалений

Просмотреть файл

@ -262,9 +262,9 @@ unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {
}
/// getColumnNumber - Get column number for the location.
unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc) {
unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) {
// We may not want column information at all.
if (!CGM.getCodeGenOpts().DebugColumnInfo)
if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo)
return 0;
// If the location is invalid then use the current column.
@ -1872,9 +1872,9 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
TC = llvm::DIType(cast<llvm::MDNode>(it->second.first));
else
TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
Decl->getName(), TheCU, Unit,
getLineNumber(Decl->getLocation()),
TheCU.getLanguage());
Decl->getName(), TheCU, Unit,
getLineNumber(Decl->getLocation()),
TheCU.getLanguage());
// Store the forward declaration in the cache.
ObjCInterfaceCache[TyPtr] = std::make_pair(TC, Checksum(Decl));
@ -1891,7 +1891,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
/// Currently the checksum merely consists of the number of ivars.
unsigned CGDebugInfo::Checksum(const ObjCInterfaceDecl
*InterfaceDecl) {
*InterfaceDecl) {
unsigned IvarNo = 0;
for (const ObjCIvarDecl *Ivar = InterfaceDecl->all_declared_ivar_begin();
Ivar != 0; Ivar = Ivar->getNextIvar()) ++IvarNo;
@ -2055,7 +2055,7 @@ llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
llvm::DIArray());
} else
RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
Size, Align, 0, llvm::DIType(), llvm::DIArray());
Size, Align, 0, llvm::DIType(), llvm::DIArray());
RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = llvm::DIType(RealDecl);
@ -2291,7 +2291,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
/// EmitLocation - Emit metadata to indicate a change in line/column
/// information in the source file.
void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,
bool ForceColumnInfo) {
// Update our current location
setLocation(Loc);
@ -2312,9 +2313,10 @@ void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
PrevLoc = CurLoc;
llvm::MDNode *Scope = LexicalBlockStack.back();
Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(CurLoc),
getColumnNumber(CurLoc),
Scope));
Builder.SetCurrentDebugLocation(llvm::DebugLoc::get
(getLineNumber(CurLoc),
getColumnNumber(CurLoc, ForceColumnInfo),
Scope));
}
/// CreateLexicalBlock - Creates a new lexical block node and pushes it on

Просмотреть файл

@ -207,7 +207,9 @@ public:
/// EmitLocation - Emit metadata to indicate a change in line/column
/// information in the source file.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
/// \param ForceColumnInfo Assume DebugColumnInfo option is true.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,
bool ForceColumnInfo = false);
/// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate
/// start of a new function.
@ -356,7 +358,8 @@ private:
/// getColumnNumber - Get column number for the location. If location is
/// invalid then use current location.
unsigned getColumnNumber(SourceLocation Loc);
/// \param Force Assume DebugColumnInfo option is true.
unsigned getColumnNumber(SourceLocation Loc, bool Force=false);
};
} // namespace CodeGen
} // namespace clang

Просмотреть файл

@ -2849,8 +2849,12 @@ RValue CodeGenFunction::EmitRValueForField(LValue LV,
RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue) {
if (CGDebugInfo *DI = getDebugInfo())
DI->EmitLocation(Builder, E->getLocStart());
if (CGDebugInfo *DI = getDebugInfo()) {
SourceLocation Loc = E->getLocStart();
DI->EmitLocation(Builder, Loc,
/* Force column info to be generated so we can differentiate
multiple call sites on the same line in the debug info. */ true);
}
// Builtins never have block type.
if (E->getCallee()->getType()->isBlockPointerType())

Просмотреть файл

@ -0,0 +1,66 @@
// RUN: %clang_cc1 -g -emit-obj -o %t %s
// RUN: llvm-dwarfdump %t | FileCheck %s
// In the attached test case a post-r166236 clang coalesces two
// instances of an inlined function in a way that makes it appear as
// if the function was only inlined once.
#define INLINE inline __attribute__((always_inline))
INLINE int
product (int x, int y)
{
int result = x * y;
return result;
}
INLINE int
sum (int a, int b)
{
int result = a + b;
return result;
}
int
strange_max (int m, int n)
{
if (m > n)
return m;
else if (n > m)
return n;
else
return 0;
}
int
foo (int i, int j)
{
if (strange_max (i, j) == i)
return product (i, j);
else if (strange_max (i, j) == j)
return sum (i, j);
else
return product (sum (i, i), sum (j, j));
}
int
main(int argc, char const *argv[])
{
int array[3];
array[0] = foo (1238, 78392);
array[1] = foo (379265, 23674);
array[2] = foo (872934, 234);
return 0;
}
// CHECK: DW_TAG_inlined_subroutine
// CHECK: DW_TAG_inlined_subroutine
// CHECK: DW_TAG_inlined_subroutine
// CHECK: DW_TAG_inlined_subroutine
// CHECK-NOT: DW_TAG_inlined_subroutine
// CHECK: DW_AT_call_line {{.*}} (0x2a)
// CHECK: DW_TAG_inlined_subroutine
// CHECK-NOT: DW_TAG_inlined_subroutine
// CHECK: DW_AT_call_line {{.*}} (0x2a)