Implement support for the format_arg attribute. Fixes PR4442.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74369 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index a2ceafa..f6d6623 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -717,6 +717,8 @@
   if (E->isTypeDependent() || E->isValueDependent())
     return false;
 
+  E = E->IgnoreParenCasts();
+  
   switch (E->getStmtClass()) {
   case Stmt::ConditionalOperatorClass: {
     const ConditionalOperator *C = cast<ConditionalOperator>(E);
@@ -766,6 +768,25 @@
     return false;
   }
 
+  case Stmt::CallExprClass: {
+    const CallExpr *CE = cast<CallExpr>(E);
+    if (const ImplicitCastExpr *ICE 
+          = dyn_cast<ImplicitCastExpr>(CE->getCallee())) {
+      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
+        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
+          if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>(Context)) {
+            unsigned ArgIndex = FA->getFormatIdx();
+            const Expr *Arg = CE->getArg(ArgIndex - 1);
+            
+            return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg, 
+                                          format_idx, firstDataArg);
+          }
+        }
+      }
+    }
+    
+    return false;
+  }
   case Stmt::ObjCStringLiteralClass:
   case Stmt::StringLiteralClass: {
     const StringLiteral *StrE = NULL;