summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5ba7b50)
raw | patch | inline | side by side (parent: 5ba7b50)
author | Eric Christopher <echristo@apple.com> | |
Tue, 11 Oct 2011 22:59:11 +0000 (22:59 +0000) | ||
committer | Eric Christopher <echristo@apple.com> | |
Tue, 11 Oct 2011 22:59:11 +0000 (22:59 +0000) |
file. Since it should only be used when necessary propagate it through
the backend code generation and tweak testcases accordingly.
This helps with code like in clang's test/CodeGen/debug-info-line.c where
we have multiple #line directives within a single lexical block and want
to generate only a single block that contains each file change.
Part of rdar://10246360
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141729 91177308-0d34-0410-b5e6-96231b3b80d8
the backend code generation and tweak testcases accordingly.
This helps with code like in clang's test/CodeGen/debug-info-line.c where
we have multiple #line directives within a single lexical block and want
to generate only a single block that contains each file change.
Part of rdar://10246360
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141729 91177308-0d34-0410-b5e6-96231b3b80d8
index 98dfc9af0fe6c97246fea12a98eaea64d0e9cc6a..6eaaa240c143033c127cae0ac61b258c4d79bbf8 100644 (file)
</pre>
</div>
-<p>These descriptors provide debug information about nested blocks within a
+<p>This descriptor provides debug information about nested blocks within a
subprogram. The line number and column numbers are used to dinstinguish
two lexical blocks at same depth. </p>
+<div class="doc_code">
+<pre>
+!3 = metadata !{
+ i32, ;; Tag = 11 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a> (DW_TAG_lexical_block)
+ metadata ;; Reference to the scope we're annotating with a file change
+ metadata,;; Reference to the file the scope is enclosed in.
+}
+</pre>
+</div>
+
+<p>This descriptor provides a wrapper around a lexical scope to handle file
+ changes in the middle of a lexical block.</p>
+
</div>
<!-- ======================================================================= -->
index a29d762b46bcc79e4893aa6e0b4b21e125c1471f..ee24226c748fb93759317c48240c3236d424138b 100644 (file)
class DINameSpace;
class DIVariable;
class DISubrange;
+ class DILexicalBlockFile;
class DILexicalBlock;
class DISubprogram;
class DITemplateTypeParameter;
DIFile File, unsigned LineNo);
+ /// createLexicalBlockFile - This creates a descriptor for a lexical
+ /// block with a new file attached. This merely extends the existing
+ /// lexical block as it crosses a file.
+ /// @param Scope Lexical block.
+ /// @param File Source file.
+ DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
+ DIFile File);
+
/// createLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
/// @param Scope Parent lexical scope.
index 1022302868b3faf5a52d68bd0644536d4f6888b2..d2bb29bd71274fae7b447fc31d9d301aed3ef4df 100644 (file)
class DIFile;
class DISubprogram;
class DILexicalBlock;
+ class DILexicalBlockFile;
class DIVariable;
class DIType;
explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
explicit DIDescriptor(const DIFile F);
explicit DIDescriptor(const DISubprogram F);
+ explicit DIDescriptor(const DILexicalBlockFile F);
explicit DIDescriptor(const DILexicalBlock F);
explicit DIDescriptor(const DIVariable F);
explicit DIDescriptor(const DIType F);
bool isFile() const;
bool isCompileUnit() const;
bool isNameSpace() const;
+ bool isLexicalBlockFile() const;
bool isLexicalBlock() const;
bool isSubrange() const;
bool isEnumerator() const;
}
};
+ /// DILexicalBlockFile - This is a wrapper for a lexical block with
+ /// a filename change.
+ class DILexicalBlockFile : public DIScope {
+ public:
+ explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const { return getScope().getFieldAs<DIScope>(1); }
+ unsigned getLineNumber() const { return getScope().getUnsignedField(2); }
+ unsigned getColumnNumber() const { return getScope().getUnsignedField(3); }
+ StringRef getDirectory() const {
+ StringRef dir = getFieldAs<DIFile>(2).getDirectory();
+ return !dir.empty() ? dir : getContext().getDirectory();
+ }
+ StringRef getFilename() const {
+ StringRef filename = getFieldAs<DIFile>(2).getFilename();
+ assert(!filename.empty() && "Why'd you create this then?");
+ return filename;
+ }
+ DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
+ };
+
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
public:
index fd56d369a66744ba1982f050ca71b63f6634f24b..bfa429d5412025a5ead75bc59710899066e278f8 100644 (file)
return DINameSpace(MDNode::get(VMContext, Elts));
}
+/// createLexicalBlockFile - This creates a new MDNode that encapsulates
+/// an existing scope with a new filename.
+DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope,
+ DIFile File) {
+ Value *Elts[] = {
+ GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block),
+ Scope,
+ File
+ };
+ return DILexicalBlockFile(MDNode::get(VMContext, Elts));
+}
+
DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
unsigned Line, unsigned Col) {
// Defeat MDNode uniqing for lexical blocks by using unique id.
index aeb039ce71c19f57c4e1ea66cb8caf7d675b4023..44457d3c3de9d4e82674c2335d33b167e92384d1 100644 (file)
DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) {
}
+DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) {
+}
+
DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) {
}
return DbgNode && getTag() == dwarf::DW_TAG_namespace;
}
+/// isLexicalBlockFile - Return true if the specified descriptor is a
+/// lexical block with an extra file.
+bool DIDescriptor::isLexicalBlockFile() const {
+ return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
+ (DbgNode->getNumOperands() == 3);
+}
+
/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
bool DIDescriptor::isLexicalBlock() const {
- return DbgNode && getTag() == dwarf::DW_TAG_lexical_block;
+ return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
+ (DbgNode->getNumOperands() > 3);
}
/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.
StringRef DIScope::getFilename() const {
if (!DbgNode)
return StringRef();
+ if (isLexicalBlockFile())
+ return DILexicalBlockFile(DbgNode).getFilename();
if (isLexicalBlock())
return DILexicalBlock(DbgNode).getFilename();
if (isSubprogram())
StringRef DIScope::getDirectory() const {
if (!DbgNode)
return StringRef();
+ if (isLexicalBlockFile())
+ return DILexicalBlockFile(DbgNode).getDirectory();
if (isLexicalBlock())
return DILexicalBlock(DbgNode).getDirectory();
if (isSubprogram())
addCompileUnit(DICompileUnit(Scope));
else if (Scope.isSubprogram())
processSubprogram(DISubprogram(Scope));
+ else if (Scope.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF = DILexicalBlockFile(Scope);
+ processLexicalBlock(DILexicalBlock(DBF.getScope()));
+ }
else if (Scope.isLexicalBlock())
processLexicalBlock(DILexicalBlock(Scope));
processSubprogram(DISubprogram(S));
else if (S.isLexicalBlock())
processLexicalBlock(DILexicalBlock(S));
+ else if (S.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF = DILexicalBlockFile(S);
+ processLexicalBlock(DILexicalBlock(DBF.getScope()));
+ }
processLocation(Loc.getOrigLocation());
}
DIScope Context = LB.getContext();
if (Context.isLexicalBlock())
return processLexicalBlock(DILexicalBlock(Context));
+ else if (Context.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF = DILexicalBlockFile(Context);
+ return processLexicalBlock(DILexicalBlock(DBF.getScope()));
+ }
else
return processSubprogram(DISubprogram(Context));
}
if (D.isSubprogram())
return DISubprogram(Scope);
+ if (D.isLexicalBlockFile())
+ return getDISubprogram(DILexicalBlockFile(Scope).getContext());
+
if (D.isLexicalBlock())
return getDISubprogram(DILexicalBlock(Scope).getContext());
index d7c702a5fc45104cd62e9b808d829682089e9cd6..1b7e370fca0989a17df62d5a47020a59b9e59c6e 100644 (file)
@@ -1371,6 +1371,10 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
DISubprogram SP(S);
Fn = SP.getFilename();
Dir = SP.getDirectory();
+ } else if (Scope.isLexicalBlockFile()) {
+ DILexicalBlockFile DBF(S);
+ Fn = DBF.getFilename();
+ Dir = DBF.getDirectory();
} else if (Scope.isLexicalBlock()) {
DILexicalBlock DB(S);
Fn = DB.getFilename();
index ae06a40703772b4ccbceedca8201b91db2b0bf48..02fa52527ddf9396a1c6f44ac8487533fe6bc849 100644 (file)
MDNode *IA = NULL;
DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
if (!Scope) return NULL;
+
+ // The scope that we were created with could have an extra file - which
+ // isn't what we care about in this case.
+ DIDescriptor D = DIDescriptor(Scope);
+ if (D.isLexicalBlockFile())
+ Scope = DILexicalBlockFile(Scope).getScope();
+
if (IA)
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
- return LexicalScopeMap.lookup(DL.getScope(Scope->getContext()));
+ return LexicalScopeMap.lookup(Scope);
}
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
MDNode *Scope = NULL;
MDNode *InlinedAt = NULL;
DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
+
if (InlinedAt) {
// Create an abstract scope for inlined function.
getOrCreateAbstractScope(Scope);
/// getOrCreateRegularScope - Find or create a regular lexical scope.
LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
+ DIDescriptor D = DIDescriptor(Scope);
+ if (D.isLexicalBlockFile())
+ Scope = DILexicalBlockFile(Scope).getScope();
+
LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
if (WScope)
return WScope;
LexicalScope *Parent = NULL;
- if (DIDescriptor(Scope).isLexicalBlock())
+ if (D.isLexicalBlock())
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
LexicalScopeMap.insert(std::make_pair(Scope, WScope));
LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
assert(N && "Invalid Scope encoding!");
+ DIDescriptor Scope(N);
+ if (Scope.isLexicalBlockFile())
+ Scope = DILexicalBlockFile(Scope).getScope();
LexicalScope *AScope = AbstractScopeMap.lookup(N);
if (AScope)
return AScope;
LexicalScope *Parent = NULL;
- DIDescriptor Scope(N);
if (Scope.isLexicalBlock()) {
DILexicalBlock DB(N);
DIDescriptor ParentDesc = DB.getContext();
index ce440e986de008cce7cfd218fbfb7da233bc3af0..a2e7ff718b4aab248ef63f7377c1fb6ec09ea4e5 100644 (file)
declare i32 @foo(i32) ssp
!0 = metadata !{i32 5, i32 2, metadata !1, null}
-!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
+!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ]
!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar", metadata !"bar", metadata !"bar", metadata !3, i32 4, null, i1 false, i1 true}; [DW_TAG_subprogram ]
!3 = metadata !{i32 458769, i32 0, i32 12, metadata !"genmodes.i", metadata !"/Users/yash/Downloads", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
!4 = metadata !{i32 459008, metadata !5, metadata !"count_", metadata !3, i32 5, metadata !6}; [ DW_TAG_auto_variable ]
-!5 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ]
+!5 = metadata !{i32 458763, metadata !1, i32 1, i32 1}; [DW_TAG_lexical_block ]
!6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ]
!7 = metadata !{i32 6, i32 1, metadata !2, null}
index 86c20243c8748524111adeb3d38862ebdd7405af..e41038d3fdcffd0deb4e3c3efe993e93c68f7ea5 100644 (file)
declare i32 @foo(i32) ssp
!0 = metadata !{i32 5, i32 2, metadata !1, null}
-!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
+!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ]
!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar", metadata !"bar", metadata !"bar", metadata !3, i32 4, null, i1 false, i1 true}; [DW_TAG_subprogram ]
!3 = metadata !{i32 458769, i32 0, i32 12, metadata !"genmodes.i", metadata !"/Users/yash/Downloads", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
!4 = metadata !{i32 459008, metadata !5, metadata !"count_", metadata !3, i32 5, metadata !6}; [ DW_TAG_auto_variable ]
-!5 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ]
+!5 = metadata !{i32 458763, metadata !1, i32 1, i32 1}; [DW_TAG_lexical_block ]
!6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ]
!7 = metadata !{i32 6, i32 1, metadata !2, null}
index 8cf20e3146ac638bb6b332b1b14a30982c5e5ab2..ad4c8d7d32ba0f4c40273e62770721029f71919d 100644 (file)
}
!0 = metadata !{i32 571, i32 3, metadata !1, null}
-!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
+!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ]
!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"foo", metadata !"foo", metadata !"foo", metadata !3, i32 561, metadata !4, i1 false, i1 true}; [DW_TAG_subprogram ]
!3 = metadata !{i32 458769, i32 0, i32 12, metadata !"hashtab.c", metadata !"/usr/src/gnu/usr.bin/cc/cc_tools/../../../../contrib/gcclibs/libiberty", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
!4 = metadata !{i32 458773, metadata !3, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0}; [DW_TAG_subroutine_type ]