let Subjects = [CXXRecord];
}
+def WarnUnused : InheritableAttr {
+ let Spellings = [GNU<"warn_unused">, CXX11<"gnu", "warn_unused">];
+ let Subjects = [Record];
+}
+
def WarnUnusedResult : InheritableAttr {
let Spellings = [GNU<"warn_unused_result">,
CXX11<"clang", "warn_unused_result">,
return false;
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
- if (!RD->hasTrivialDestructor())
+ if (!RD->hasTrivialDestructor() && !RD->hasAttr<WarnUnusedAttr>())
return false;
if (const Expr *Init = VD->getInit()) {
dyn_cast<CXXConstructExpr>(Init);
if (Construct && !Construct->isElidable()) {
CXXConstructorDecl *CD = Construct->getConstructor();
- if (!CD->isTrivial())
+ if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>())
return false;
}
}
Attr.getAttributeSpellingListIndex()));
}
+static void handleWarnUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ // Check the attribute arguments.
+ if (!checkAttributeNumArgs(S, Attr, 0))
+ return;
+
+ if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
+ RD->addAttr(::new (S.Context) WarnUnusedAttr(Attr.getRange(), S.Context));
+ else
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+}
+
static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (!checkAttributeNumArgs(S, Attr, 0))
case AttributeList::AT_TypeVisibility:
handleVisibilityAttr(S, D, Attr, true);
break;
+ case AttributeList::AT_WarnUnused:
+ handleWarnUnusedAttr(S, D, Attr);
+ break;
case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
break;
case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break;