Index: cfe/trunk/include/clang/Basic/Attr.td =================================================================== --- cfe/trunk/include/clang/Basic/Attr.td +++ cfe/trunk/include/clang/Basic/Attr.td @@ -82,6 +82,8 @@ S->getKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && S->getKind() != Decl::NonTypeTemplateParm}]>; +def NonParmVar : SubsetSubjectgetKind() != Decl::ParmVar}]>; def NonBitField : SubsetSubjectisBitField()}]>; @@ -994,8 +996,8 @@ 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]; } Index: cfe/trunk/include/clang/Basic/AttrDocs.td =================================================================== --- cfe/trunk/include/clang/Basic/AttrDocs.td +++ cfe/trunk/include/clang/Basic/AttrDocs.td @@ -524,8 +524,8 @@ 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. }]; } Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp @@ -3019,6 +3019,8 @@ CGBuilderTy &Builder) { assert(DebugKind >= codegenoptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); + if (VD->hasAttr()) + return; bool Unwritten = VD->isImplicit() || (isa(VD->getDeclContext()) && @@ -3163,6 +3165,8 @@ if (Builder.GetInsertBlock() == nullptr) return; + if (VD->hasAttr()) + return; bool isByRef = VD->hasAttr(); Index: cfe/trunk/test/CodeGenCXX/debug-info-nodebug.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/debug-info-nodebug.cpp +++ cfe/trunk/test/CodeGenCXX/debug-info-nodebug.cpp @@ -44,9 +44,12 @@ // 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" Index: cfe/trunk/test/CodeGenObjC/debug-info-nodebug.m =================================================================== --- cfe/trunk/test/CodeGenObjC/debug-info-nodebug.m +++ cfe/trunk/test/CodeGenObjC/debug-info-nodebug.m @@ -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 Index: cfe/trunk/test/Sema/attr-nodebug.c =================================================================== --- cfe/trunk/test/Sema/attr-nodebug.c +++ cfe/trunk/test/Sema/attr-nodebug.c @@ -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));