Allow 'nodebug' on local variables.

Parameters and non-static members of aggregates are still excluded,
and probably should remain that way.

Differential Revision: http://reviews.llvm.org/D19754

llvm-svn: 272859
This commit is contained in:
Paul Robinson 2016-06-16 00:42:36 +00:00
parent d01720d46d
commit afd2dde2fd
6 changed files with 42 additions and 7 deletions

View File

@ -82,6 +82,8 @@ def NormalVar : SubsetSubject<Var,
S->getKind() != Decl::ImplicitParam &&
S->getKind() != Decl::ParmVar &&
S->getKind() != Decl::NonTypeTemplateParm}]>;
def NonParmVar : SubsetSubject<Var,
[{S->getKind() != Decl::ParmVar}]>;
def NonBitField : SubsetSubject<Field,
[{!S->isBitField()}]>;
@ -994,8 +996,8 @@ def NoCommon : InheritableAttr {
def NoDebug : InheritableAttr {
let Spellings = [GCC<"nodebug">];
let Subjects = SubjectList<[FunctionLike, ObjCMethod, GlobalVar], WarnDiag,
"ExpectedFunctionGlobalVarMethodOrProperty">;
let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar], WarnDiag,
"ExpectedVariableOrFunction">;
let Documentation = [NoDebugDocs];
}

View File

@ -524,8 +524,8 @@ def NoDebugDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``nodebug`` attribute allows you to suppress debugging information for a
function, or for a variable declared with static storage duration, such as
globals, class static data members, and static locals.
function or method, or for a variable that is not a parameter or a non-static
data member.
}];
}

View File

@ -3019,6 +3019,8 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
CGBuilderTy &Builder) {
assert(DebugKind >= codegenoptions::LimitedDebugInfo);
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
if (VD->hasAttr<NoDebugAttr>())
return;
bool Unwritten =
VD->isImplicit() || (isa<Decl>(VD->getDeclContext()) &&
@ -3163,6 +3165,8 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
if (Builder.GetInsertBlock() == nullptr)
return;
if (VD->hasAttr<NoDebugAttr>())
return;
bool isByRef = VD->hasAttr<BlocksAttr>();

View File

@ -44,9 +44,12 @@ void func3() {
// YESINFO-DAG: !DIDerivedType({{.*}} name: "static_const_member"
// NOINFO-NOT: !DIDerivedType({{.*}} name: "static_const_member"
// Function-local static variable.
// Function-local static and auto variables.
void func4() {
NODEBUG static int static_local = 6;
NODEBUG int normal_local = 7;
}
// YESINFO-DAG: !DIGlobalVariable(name: "static_local"
// NOINFO-NOT: !DIGlobalVariable(name: "static_local"
// YESINFO-DAG: !DILocalVariable(name: "normal_local"
// NOINFO-NOT: !DILocalVariable(name: "normal_local"

View File

@ -0,0 +1,26 @@
// RUN: %clang_cc1 -triple arm-apple-ios -emit-llvm -debug-info-kind=limited -fblocks %s -o - | FileCheck %s
// Objective-C code cargo-culted from debug-info-lifetime-crash.m.
@protocol NSObject
- (id)copy;
@end
@class W;
@interface View1
@end
@implementation Controller {
void (^Block)(void);
}
- (void)View:(View1 *)View foo:(W *)W
{
// The reference from inside the block implicitly creates another
// local variable for the referenced member. That is what gets
// suppressed by the attribute. It still gets debug info as a
// member, though.
// CHECK-NOT: !DILocalVariable(name: "weakSelf"
// CHECK: !DIDerivedType({{.*}} name: "weakSelf"
// CHECK-NOT: !DILocalVariable(name: "weakSelf"
__attribute__((nodebug)) __typeof(self) weakSelf = self;
Block = [^{
__typeof(self) strongSelf = weakSelf;
} copy];
}
@end

View File

@ -2,8 +2,8 @@
int a __attribute__((nodebug));
void b() {
int b __attribute__((nodebug)); // expected-warning {{'nodebug' attribute only applies to functions and global variables}}
void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to variables and functions}}
int b __attribute__((nodebug));
}
void t1() __attribute__((nodebug));