Consumed Analysis: The 'consumable' attribute now takes a identifier specifying the default assumed state for objects of this class

This information is used for return states and pass-by-value parameter
states.

Patch by Chris Wailes.

Review by DeLesley Hutchins and Aaron Ballman.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190116 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 97d12d5..39347fa 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -968,7 +968,30 @@
 }
 
 static void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkAttributeNumArgs(S, Attr, 0)) return;
+  if (!checkAttributeNumArgs(S, Attr, 1))
+    return;
+
+  ConsumableAttr::ConsumedState DefaultState;
+
+  if (Attr.isArgIdent(0)) {
+    StringRef Param = Attr.getArgAsIdent(0)->Ident->getName();
+
+    if (Param == "unknown")
+      DefaultState = ConsumableAttr::Unknown;
+    else if (Param == "consumed")
+      DefaultState = ConsumableAttr::Consumed;
+    else if (Param == "unconsumed")
+      DefaultState = ConsumableAttr::Unconsumed;
+    else {
+      S.Diag(Attr.getLoc(), diag::warn_unknown_consumed_state) << Param;
+      return;
+    }
+
+  } else {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+        << Attr.getName() << AANT_ArgumentIdentifier;
+    return;
+  }
 
   if (!isa<CXXRecordDecl>(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
@@ -977,7 +1000,7 @@
   }
   
   D->addAttr(::new (S.Context)
-             ConsumableAttr(Attr.getRange(), S.Context,
+             ConsumableAttr(Attr.getRange(), S.Context, DefaultState,
                             Attr.getAttributeSpellingListIndex()));
 }