summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2010-07-22 22:29:16 +0000
committerDevang Patel <dpatel@apple.com>2010-07-22 22:29:16 +0000
commit0884a60eb5b26a9a9fd716e408cf6dcd8b4d1d7d (patch)
tree15b2dcaa83124ae80b3ca56d2eea6542a0d37a39 /clang/lib/CodeGen/CGDebugInfo.cpp
parentc2f81007c01b2c791c656f5d8c69f1d585b1b6df (diff)
downloadbcm5719-llvm-0884a60eb5b26a9a9fd716e408cf6dcd8b4d1d7d.tar.gz
bcm5719-llvm-0884a60eb5b26a9a9fd716e408cf6dcd8b4d1d7d.zip
Keep track of artificial scopes introduced by line directives. For example,
#line 41 "bar.c" dummy (1, i); #line 24 "bar.h" i = f2 (i); #line 44 "bar.c" This is tested by step-line.exp in gdb testsuite. llvm-svn: 109189
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index fdc8a35d9d6..753cdcddd28 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1349,6 +1349,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
llvm::StringRef Name;
llvm::StringRef LinkageName;
+ FnBeginRegionCount.push_back(RegionStack.size());
+
const Decl *D = GD.getDecl();
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// If there is a DISubprogram for this function available then use it.
@@ -1392,6 +1394,9 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
llvm::MDNode *SPN = SP;
RegionStack.push_back(SPN);
RegionMap[D] = llvm::WeakVH(SP);
+
+ // Clear stack used to keep track of #line directives.
+ LineDirectiveFiles.clear();
}
@@ -1417,6 +1422,55 @@ void CGDebugInfo::EmitStopPoint(CGBuilderTy &Builder) {
Scope));
}
+/// UpdateLineDirectiveRegion - Update region stack only if #line directive
+/// has introduced scope change.
+void CGDebugInfo::UpdateLineDirectiveRegion(CGBuilderTy &Builder) {
+ if (CurLoc.isInvalid() || CurLoc.isMacroID() ||
+ PrevLoc.isInvalid() || PrevLoc.isMacroID())
+ return;
+ SourceManager &SM = CGM.getContext().getSourceManager();
+ PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);
+ PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc);
+
+ if (!strcmp(PPLoc.getFilename(), PCLoc.getFilename()))
+ return;
+
+ // If #line directive stack is empty then we are entering a new scope.
+ if (LineDirectiveFiles.empty()) {
+ EmitRegionStart(Builder);
+ LineDirectiveFiles.push_back(PCLoc.getFilename());
+ return;
+ }
+
+ assert (RegionStack.size() >= LineDirectiveFiles.size()
+ && "error handling #line regions!");
+
+ bool SeenThisFile = false;
+ for(std::vector<const char *>::iterator I = LineDirectiveFiles.begin(),
+ E = LineDirectiveFiles.end(); I != E; ++I)
+ if (!strcmp(PPLoc.getFilename(), *I)) {
+ SeenThisFile = true;
+ break;
+ }
+
+ // If #line for this file is seen earlier then pop out #line regions.
+ if (SeenThisFile) {
+ while (!LineDirectiveFiles.empty()) {
+ const char *LastFile = LineDirectiveFiles.back();
+ RegionStack.pop_back();
+ LineDirectiveFiles.pop_back();
+ if (!strcmp(PPLoc.getFilename(), LastFile))
+ break;
+ }
+ return;
+ }
+
+ // .. otherwise insert new #line region.
+ EmitRegionStart(Builder);
+ LineDirectiveFiles.push_back(PCLoc.getFilename());
+
+ return;
+}
/// EmitRegionStart- Constructs the debug code for entering a declarative
/// region - "llvm.dbg.region.start.".
void CGDebugInfo::EmitRegionStart(CGBuilderTy &Builder) {
@@ -1442,6 +1496,18 @@ void CGDebugInfo::EmitRegionEnd(CGBuilderTy &Builder) {
RegionStack.pop_back();
}
+/// EmitFunctionEnd - Constructs the debug code for exiting a function.
+void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
+ assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
+ unsigned RCount = FnBeginRegionCount.back();
+ assert(RCount <= RegionStack.size() && "Region stack mismatch");
+
+ // Pop all regions for this function.
+ while (RegionStack.size() != RCount)
+ EmitRegionEnd(Builder);
+ FnBeginRegionCount.pop_back();
+}
+
// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.
// See BuildByRefType.
llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
OpenPOWER on IntegriCloud