summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2013-10-04 21:28:06 +0000
committerDeLesley Hutchins <delesley@google.com>2013-10-04 21:28:06 +0000
commit210791a021a18e3eb60d4a67df6cd452006aa338 (patch)
tree9ad11e882dc8256f24f8bd6f8f5388de78c8279a /clang/lib/Sema/SemaDeclAttr.cpp
parent721726adfc043224c9e5e0925b581d0448c6723d (diff)
downloadbcm5719-llvm-210791a021a18e3eb60d4a67df6cd452006aa338.tar.gz
bcm5719-llvm-210791a021a18e3eb60d4a67df6cd452006aa338.zip
Consumed Analysis: Change callable_when so that it can take a list of states
that a function can be called in. This reduced the total number of annotations needed and makes writing more complicated behaviour less burdensome. Patch by chriswails@gmail.com. llvm-svn: 191983
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp40
1 files changed, 34 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c6337a5015e..41cc3fd285a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1041,8 +1041,11 @@ static void handleConsumesAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Attr.getAttributeSpellingListIndex()));
}
-static void handleCallableWhenUnconsumedAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
+static void handleCallableWhenAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+
+ if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) return;
+
if (!isa<CXXMethodDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
Attr.getName() << ExpectedMethod;
@@ -1052,9 +1055,34 @@ static void handleCallableWhenUnconsumedAttr(Sema &S, Decl *D,
if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
return;
+ SmallVector<CallableWhenAttr::ConsumedState, 3> States;
+ for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) {
+ CallableWhenAttr::ConsumedState CallableState;
+
+ if (Attr.isArgExpr(ArgIndex) &&
+ isa<StringLiteral>(Attr.getArgAsExpr(ArgIndex))) {
+
+ Expr *Arg = Attr.getArgAsExpr(ArgIndex);
+ StringRef StateString = cast<StringLiteral>(Arg)->getString();
+
+ if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
+ CallableState)) {
+ S.Diag(Arg->getExprLoc(), diag::warn_attribute_type_not_supported)
+ << Attr.getName() << StateString;
+ return;
+ }
+
+ States.push_back(CallableState);
+ } else {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
+ << AANT_ArgumentString;
+ return;
+ }
+ }
+
D->addAttr(::new (S.Context)
- CallableWhenUnconsumedAttr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
+ CallableWhenAttr(Attr.getRange(), S.Context, States.data(),
+ States.size(), Attr.getAttributeSpellingListIndex()));
}
static void handleTestsConsumedAttr(Sema &S, Decl *D,
@@ -4767,8 +4795,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_Consumes:
handleConsumesAttr(S, D, Attr);
break;
- case AttributeList::AT_CallableWhenUnconsumed:
- handleCallableWhenUnconsumedAttr(S, D, Attr);
+ case AttributeList::AT_CallableWhen:
+ handleCallableWhenAttr(S, D, Attr);
break;
case AttributeList::AT_TestsConsumed:
handleTestsConsumedAttr(S, D, Attr);
OpenPOWER on IntegriCloud