зеркало из https://github.com/microsoft/clang.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109189 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
db2cfecf0e
Коммит
5a6fbcfd8c
|
@ -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,
|
||||
|
|
|
@ -58,6 +58,14 @@ class CGDebugInfo {
|
|||
|
||||
std::vector<llvm::TrackingVH<llvm::MDNode> > RegionStack;
|
||||
llvm::DenseMap<const Decl *, llvm::WeakVH> RegionMap;
|
||||
// FnBeginRegionCount - Keep track of RegionStack counter at the beginning
|
||||
// of a function. This is used to pop unbalanced regions at the end of a
|
||||
// function.
|
||||
std::vector<unsigned> FnBeginRegionCount;
|
||||
|
||||
/// LineDirectiveFiles - This stack is used to keep track of
|
||||
/// scopes introduced by #line directives.
|
||||
std::vector<const char *> LineDirectiveFiles;
|
||||
|
||||
/// DebugInfoNames - This is a storage for names that are
|
||||
/// constructed on demand. For example, C++ destructors, C++ operators etc..
|
||||
|
@ -134,6 +142,13 @@ public:
|
|||
void EmitFunctionStart(GlobalDecl GD, QualType FnType,
|
||||
llvm::Function *Fn, CGBuilderTy &Builder);
|
||||
|
||||
/// EmitFunctionEnd - Constructs the debug code for exiting a function.
|
||||
void EmitFunctionEnd(CGBuilderTy &Builder);
|
||||
|
||||
/// UpdateLineDirectiveRegion - Update region stack only if #line directive
|
||||
/// has introduced scope change.
|
||||
void UpdateLineDirectiveRegion(CGBuilderTy &Builder);
|
||||
|
||||
/// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start
|
||||
/// of a new block.
|
||||
void EmitRegionStart(CGBuilderTy &Builder);
|
||||
|
|
|
@ -34,6 +34,7 @@ void CodeGenFunction::EmitStopPoint(const Stmt *S) {
|
|||
DI->setLocation(S->getLocEnd());
|
||||
else
|
||||
DI->setLocation(S->getLocStart());
|
||||
DI->UpdateLineDirectiveRegion(Builder);
|
||||
DI->EmitStopPoint(Builder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
|
|||
// Emit debug descriptor for function end.
|
||||
if (CGDebugInfo *DI = getDebugInfo()) {
|
||||
DI->setLocation(EndLoc);
|
||||
DI->EmitRegionEnd(Builder);
|
||||
DI->EmitFunctionEnd(Builder);
|
||||
}
|
||||
|
||||
EmitFunctionEpilog(*CurFnInfo);
|
||||
|
|
Загрузка…
Ссылка в новой задаче