summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Attr.td6
-rw-r--r--clang/include/clang/Basic/AttrDocs.td4
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp4
-rw-r--r--clang/test/CodeGenCXX/debug-info-nodebug.cpp5
-rw-r--r--clang/test/CodeGenObjC/debug-info-nodebug.m26
-rw-r--r--clang/test/Sema/attr-nodebug.c4
6 files changed, 42 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index f483fc32341..fcf457a40cc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -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];
}
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 3f19772517e..dfaa2144f4c 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -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.
}];
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index e2000ea79aa..0e756d348c4 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -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>();
diff --git a/clang/test/CodeGenCXX/debug-info-nodebug.cpp b/clang/test/CodeGenCXX/debug-info-nodebug.cpp
index 7a10e6708cc..9f140efaed6 100644
--- a/clang/test/CodeGenCXX/debug-info-nodebug.cpp
+++ b/clang/test/CodeGenCXX/debug-info-nodebug.cpp
@@ -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"
diff --git a/clang/test/CodeGenObjC/debug-info-nodebug.m b/clang/test/CodeGenObjC/debug-info-nodebug.m
new file mode 100644
index 00000000000..42d630b4ac1
--- /dev/null
+++ b/clang/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
diff --git a/clang/test/Sema/attr-nodebug.c b/clang/test/Sema/attr-nodebug.c
index 39643bfb70d..e7ca58d3ba1 100644
--- a/clang/test/Sema/attr-nodebug.c
+++ b/clang/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));
OpenPOWER on IntegriCloud