[analyzer] when scanning FIDs in a PathDiagnostic, correctly recurse calls and macros.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151774 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 2adc0f2..a082bba 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -93,26 +93,43 @@
     // Verify that the entire path is from the same FileID.
     FileID FID;
     const SourceManager &SMgr = (*D->path.begin())->getLocation().getManager();
+    llvm::SmallVector<const PathPieces *, 5> WorkList;
+    WorkList.push_back(&D->path);
 
-    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
-         I != E; ++I) {
-      FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
+    while (!WorkList.empty()) {
+      const PathPieces &path = *WorkList.back();
+      WorkList.pop_back();
+
+      for (PathPieces::const_iterator I = path.begin(), E = path.end();
+           I != E; ++I) {
+        const PathDiagnosticPiece *piece = I->getPtr();
+        FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc();
       
-      if (FID.isInvalid()) {
-        FID = SMgr.getFileID(L);
-      } else if (SMgr.getFileID(L) != FID)
-        return; // FIXME: Emit a warning?
+        if (FID.isInvalid()) {
+          FID = SMgr.getFileID(L);
+        } else if (SMgr.getFileID(L) != FID)
+          return; // FIXME: Emit a warning?
       
-      // Check the source ranges.
-      for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
-           RE = (*I)->ranges_end();
-           RI != RE; ++RI) {
-        SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
-        if (!L.isFileID() || SMgr.getFileID(L) != FID)
-          return; // FIXME: Emit a warning?
-        L = SMgr.getExpansionLoc(RI->getEnd());
-        if (!L.isFileID() || SMgr.getFileID(L) != FID)
-          return; // FIXME: Emit a warning?
+        // Check the source ranges.
+        for (PathDiagnosticPiece::range_iterator RI = piece->ranges_begin(),
+             RE = piece->ranges_end();
+             RI != RE; ++RI) {
+          SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
+          if (!L.isFileID() || SMgr.getFileID(L) != FID)
+            return; // FIXME: Emit a warning?
+          L = SMgr.getExpansionLoc(RI->getEnd());
+          if (!L.isFileID() || SMgr.getFileID(L) != FID)
+            return; // FIXME: Emit a warning?
+        }
+        
+        if (const PathDiagnosticCallPiece *call =
+            dyn_cast<PathDiagnosticCallPiece>(piece)) {
+          WorkList.push_back(&call->path);
+        }
+        else if (const PathDiagnosticMacroPiece *macro =
+                 dyn_cast<PathDiagnosticMacroPiece>(piece)) {
+          WorkList.push_back(&macro->subPieces);
+        }
       }
     }
     
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 03e0d89..6f2a5ca 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -324,19 +324,38 @@
   if (!Diags.empty())
     SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager();
 
+  
   for (std::vector<const PathDiagnostic*>::iterator DI = Diags.begin(),
        DE = Diags.end(); DI != DE; ++DI) {
 
     const PathDiagnostic *D = *DI;
 
-    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
-         I!=E; ++I) {
-      AddFID(FM, Fids, SM, (*I)->getLocation().asLocation());
+    llvm::SmallVector<const PathPieces *, 5> WorkList;
+    WorkList.push_back(&D->path);
 
-      for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
-           RE= (*I)->ranges_end(); RI != RE; ++RI) {
-        AddFID(FM, Fids, SM, RI->getBegin());
-        AddFID(FM, Fids, SM, RI->getEnd());
+    while (!WorkList.empty()) {
+      const PathPieces &path = *WorkList.back();
+      WorkList.pop_back();
+    
+      for (PathPieces::const_iterator I = path.begin(), E = path.end();
+           I!=E; ++I) {
+        const PathDiagnosticPiece *piece = I->getPtr();
+        AddFID(FM, Fids, SM, piece->getLocation().asLocation());
+
+        for (PathDiagnosticPiece::range_iterator RI = piece->ranges_begin(),
+             RE= piece->ranges_end(); RI != RE; ++RI) {
+          AddFID(FM, Fids, SM, RI->getBegin());
+          AddFID(FM, Fids, SM, RI->getEnd());
+        }
+
+        if (const PathDiagnosticCallPiece *call =
+            dyn_cast<PathDiagnosticCallPiece>(piece)) {
+          WorkList.push_back(&call->path);
+        }
+        else if (const PathDiagnosticMacroPiece *macro =
+                 dyn_cast<PathDiagnosticMacroPiece>(piece)) {
+          WorkList.push_back(&macro->subPieces);
+        }
       }
     }
   }