aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--lib/Sema/SemaDeclAttr.cpp78
1 files changed, 49 insertions, 29 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3ea2b5064c..347d8f5e07 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -298,7 +298,7 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// prototypes, so we ignore it as well
if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "nonnull" << "function";
+ << "nonnull" << 0 /*function*/;
return;
}
@@ -408,7 +408,7 @@ static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isFunctionOrMethod(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "noreturn" << "function";
+ << "noreturn" << 0 /*function*/;
return;
}
@@ -424,7 +424,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "unused" << "variable and function";
+ << "unused" << 2 /*variable and function*/;
return;
}
@@ -445,7 +445,7 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
} else if (!isFunctionOrMethod(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "used" << "variable and function";
+ << "used" << 2 /*variable and function*/;
return;
}
@@ -475,7 +475,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
if (!Fn) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "constructor" << "function";
+ << "constructor" << 0 /*function*/;
return;
}
@@ -504,7 +504,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isa<FunctionDecl>(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "destructor" << "function";
+ << "destructor" << 0 /*function*/;
return;
}
@@ -712,24 +712,42 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "sentinel" << "function or method";
+ << "sentinel" << 3 /*function or method*/;
return;
}
// FIXME: Actually create the attribute.
}
-static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
+ // check the attribute arguments.
+ if (Attr.getNumArgs() != 0) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ return;
+ }
+
+ // TODO: could also be applied to methods?
+ FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
+ if (!Fn) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << "warn_unused_result" << 0 /*function*/;
+ return;
+ }
+
+ Fn->addAttr(new WarnUnusedResultAttr());
+}
+
+static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- d->addAttr(new WeakAttr());
+ D->addAttr(new WeakAttr());
}
-static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
@@ -737,15 +755,15 @@ static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// Attribute can be applied only to functions or variables.
- if (isa<VarDecl>(d)) {
- d->addAttr(new DLLImportAttr());
+ if (isa<VarDecl>(D)) {
+ D->addAttr(new DLLImportAttr());
return;
}
- FunctionDecl *FD = dyn_cast<FunctionDecl>(d);
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
if (!FD) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "dllimport" << "function or variable";
+ << "dllimport" << 2 /*variable and function*/;
return;
}
@@ -766,15 +784,15 @@ static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
}
- if (d->getAttr<DLLExportAttr>()) {
+ if (D->getAttr<DLLExportAttr>()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
return;
}
- d->addAttr(new DLLImportAttr());
+ D->addAttr(new DLLImportAttr());
}
-static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
@@ -782,15 +800,15 @@ static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// Attribute can be applied only to functions or variables.
- if (isa<VarDecl>(d)) {
- d->addAttr(new DLLExportAttr());
+ if (isa<VarDecl>(D)) {
+ D->addAttr(new DLLExportAttr());
return;
}
- FunctionDecl *FD = dyn_cast<FunctionDecl>(d);
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
if (!FD) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "dllexport" << "function or variable";
+ << "dllexport" << 2 /*variable and function*/;
return;
}
@@ -802,10 +820,10 @@ static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(new DLLExportAttr());
+ D->addAttr(new DLLExportAttr());
}
-static void HandleSectionAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute has no arguments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -821,7 +839,7 @@ static void HandleSectionAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
return;
}
- d->addAttr(new SectionAttr(std::string(SE->getStrData(),
+ D->addAttr(new SectionAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -835,7 +853,7 @@ static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions.
if (!isa<FunctionDecl>(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "stdcall" << "function";
+ << "stdcall" << 0 /*function*/;
return;
}
@@ -858,7 +876,7 @@ static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isa<FunctionDecl>(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "fastcall" << "function";
+ << "fastcall" << 0 /*function*/;
return;
}
@@ -977,7 +995,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "format" << "function";
+ << "format" << 0 /*function*/;
return;
}
@@ -1116,7 +1134,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
if (!TD || !TD->getUnderlyingType()->isUnionType()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "transparent_union" << "union";
+ << "transparent_union" << 1 /*union*/;
return;
}
@@ -1334,7 +1352,7 @@ static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isa<FunctionDecl>(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "nodebug" << "function";
+ << "nodebug" << 0 /*function*/;
return;
}
@@ -1381,6 +1399,8 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break;
case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
+ case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
+ break;
case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
case AttributeList::AT_transparent_union:
HandleTransparentUnionAttr(D, Attr, S);