Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -82,6 +82,10 @@ S->getKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && S->getKind() != Decl::NonTypeTemplateParm}]>; +def NonParmVar : SubsetSubjectgetKind() != Decl::ImplicitParam && + S->getKind() != Decl::ParmVar && + S->getKind() != Decl::NonTypeTemplateParm}]>; def NonBitField : SubsetSubjectisBitField()}]>; @@ -973,8 +977,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: include/clang/Basic/AttrDocs.td =================================================================== --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -498,8 +498,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: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -3001,6 +3001,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()) && @@ -3145,6 +3147,8 @@ if (Builder.GetInsertBlock() == nullptr) return; + if (VD->hasAttr()) + return; bool isByRef = VD->hasAttr(); Index: test/CodeGenCXX/debug-info-nodebug.cpp =================================================================== --- test/CodeGenCXX/debug-info-nodebug.cpp +++ test/CodeGenCXX/debug-info-nodebug.cpp @@ -44,9 +44,15 @@ // YESINFO-DAG: !DIDerivedType({{.*}} name: "static_const_member" // NOINFO-NOT: !DIDerivedType({{.*}} name: "static_const_member" -// Function-local static variable. +// Function-local static, const, and normal variables. void func4() { NODEBUG static int static_local = 6; + NODEBUG const int const_local = 7; + NODEBUG int normal_local = 8; } // YESINFO-DAG: !DIGlobalVariable(name: "static_local" // NOINFO-NOT: !DIGlobalVariable(name: "static_local" +// YESINFO-DAG: !DILocalVariable(name: "const_local" +// NOINFO-NOT: !DILocalVariable(name: "const_local" +// YESINFO-DAG: !DILocalVariable(name: "normal_local" +// NOINFO-NOT: !DILocalVariable(name: "normal_local" Index: test/CodeGenObjC/debug-info-nodebug.m =================================================================== --- test/CodeGenObjC/debug-info-nodebug.m +++ test/CodeGenObjC/debug-info-nodebug.m @@ -0,0 +1,22 @@ +// 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 +{ + // Put one inside a block because that's a different path in the compiler. + // CHECK-NOT: !DILocalVariable(name: "weakSelf" + // CHECK-NOT: !DILocalVariable(name: "strongSelf" + __attribute__((nodebug)) __typeof(self) weakSelf = self; + Block = [^{ + __attribute__((nodebug)) __typeof(self) strongSelf = weakSelf; + } copy]; +} +@end Index: test/Sema/attr-nodebug.c =================================================================== --- test/Sema/attr-nodebug.c +++ 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));