Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -816,8 +816,6 @@
       continue;
     }
 
-    // TODO: Handle tok::hash and tok::hashhash.
-
     // If control reached here, then this token isn't a macro identifier, nor an
     // unexpanded macro argument that we need to handle, print it.
     Printer.printToken(T);
@@ -978,14 +976,25 @@
 }
 
 inline void TokenPrinter::printToken(const Token &Tok) {
-  // If the tokens were already space separated, or if they must be to avoid
-  // them being implicitly pasted, add a space between them.
   // If this is the first token to be printed, don't print space.
-  if (PrevTok.isNot(tok::unknown) && (Tok.hasLeadingSpace() ||
-      ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok)))
-    OS << ' ';
+  if (PrevTok.isNot(tok::unknown)) {
+    // If the tokens were already space separated, or if they must be to avoid
+    // them being implicitly pasted, add a space between them.
+    if(Tok.hasLeadingSpace() || ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok,
+                                                       Tok)) {
+      // AvoidConcat doesn't check for ##, don't print a space around it.
+      if (PrevTok.isNot(tok::hashhash) && Tok.isNot(tok::hashhash)) {
+        OS << ' ';
+      }
+    }
+  }
 
-  OS << PP.getSpelling(Tok);
+  if (!Tok.isOneOf(tok::hash, tok::hashhash)) {
+    if (PrevTok.is(tok::hash))
+      OS << '\"' << PP.getSpelling(Tok) << '\"';
+    else
+      OS << PP.getSpelling(Tok);
+  }
 
   PrevPrevTok = PrevTok;
   PrevTok = Tok;
Index: test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
===================================================================
--- test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -3755,7 +3755,7 @@
       file0
      
      nameDECLARE_FUNC_AND_SET_TO_NULL
-     expansionvoid generated_##whatever(); ptr = nullptr;
+     expansionvoid generated_whatever(); ptr = nullptr;
     
     
      kindevent
@@ -3887,12 +3887,12 @@
         start
          
           
-           line290
+           line285
            col3
            file0
           
           
-           line290
+           line285
            col5
            file0
           
@@ -3900,12 +3900,179 @@
         end
          
           
-           line291
+           line286
            col3
            file0
           
           
-           line291
+           line286
+           col19
+           file0
+          
+         
+       
+      
+    
+    
+     kindmacro_expansion
+     location
+     
+      line286
+      col3
+      file0
+     
+     nameTO_NULL_AND_PRINT
+     expansiona = 0; print( "Will this ## cause a crash?")
+    
+    
+     kindevent
+     location
+     
+      line286
+      col3
+      file0
+     
+     ranges
+     
+       
+        
+         line286
+         col3
+         file0
+        
+        
+         line286
+         col53
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Null pointer value stored to 'a'
+     message
+     Null pointer value stored to 'a'
+    
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line287
+           col3
+           file0
+          
+          
+           line287
+           col3
+           file0
+          
+         
+        end
+         
+          
+           line287
+           col6
+           file0
+          
+          
+           line287
+           col6
+           file0
+          
+         
+       
+      
+    
+    
+     kindevent
+     location
+     
+      line287
+      col6
+      file0
+     
+     ranges
+     
+       
+        
+         line287
+         col4
+         file0
+        
+        
+         line287
+         col4
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Dereference of null pointer (loaded from variable 'a')
+     message
+     Dereference of null pointer (loaded from variable 'a')
+    
+   
+   descriptionDereference of null pointer (loaded from variable 'a')
+   categoryLogic error
+   typeDereference of null pointer
+   check_namecore.NullDereference
+   
+   issue_hash_content_of_line_in_context6817572ced27cb7d28fc87b2aba75fb4
+  issue_context_kindfunction
+  issue_contextmacroArgContainsHashHashInStringTest
+  issue_hash_function_offset3
+  location
+  
+   line287
+   col6
+   file0
+  
+  ExecutedLines
+  
+   0
+   
+    284
+    285
+    286
+    287
+   
+  
+  
+  
+   path
+   
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line298
+           col3
+           file0
+          
+          
+           line298
+           col5
+           file0
+          
+         
+        end
+         
+          
+           line299
+           col3
+           file0
+          
+          
+           line299
            col11
            file0
           
@@ -3917,18 +4084,18 @@
      kindmacro_expansion
      location
      
-      line291
+      line299
       col3
       file0
      
      namePRINT_STR
-     expansionprint(#Hello); ptr = nullptr
+     expansionprint("Hello"); ptr = nullptr
     
     
      kindevent
      location
      
-      line291
+      line299
       col3
       file0
      
@@ -3936,12 +4103,12 @@
      
        
         
-         line291
+         line299
          col3
          file0
         
         
-         line291
+         line299
          col23
          file0
         
@@ -3961,12 +4128,12 @@
         start
          
           
-           line292
+           line300
            col3
            file0
           
           
-           line292
+           line300
            col3
            file0
           
@@ -3974,12 +4141,12 @@
         end
          
           
-           line292
+           line300
            col8
            file0
           
           
-           line292
+           line300
            col8
            file0
           
@@ -3991,7 +4158,7 @@
      kindevent
      location
      
-      line292
+      line300
       col8
       file0
      
@@ -3999,12 +4166,12 @@
      
        
         
-         line292
+         line300
          col4
          file0
         
         
-         line292
+         line300
          col6
          file0
         
@@ -4028,7 +4195,7 @@
   issue_hash_function_offset3
   location
   
-   line292
+   line300
    col8
    file0
   
@@ -4036,10 +4203,452 @@
   
    0
    
-    289
-    290
-    291
-    292
+    297
+    298
+    299
+    300
+   
+  
+  
+  
+   path
+   
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line307
+           col3
+           file0
+          
+          
+           line307
+           col5
+           file0
+          
+         
+        end
+         
+          
+           line308
+           col3
+           file0
+          
+          
+           line308
+           col19
+           file0
+          
+         
+       
+      
+    
+    
+     kindmacro_expansion
+     location
+     
+      line308
+      col3
+      file0
+     
+     nameTO_NULL_AND_PRINT
+     expansiona = 0; print( "Will this # cause a crash?")
+    
+    
+     kindevent
+     location
+     
+      line308
+      col3
+      file0
+     
+     ranges
+     
+       
+        
+         line308
+         col3
+         file0
+        
+        
+         line308
+         col52
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Null pointer value stored to 'a'
+     message
+     Null pointer value stored to 'a'
+    
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line309
+           col3
+           file0
+          
+          
+           line309
+           col3
+           file0
+          
+         
+        end
+         
+          
+           line309
+           col6
+           file0
+          
+          
+           line309
+           col6
+           file0
+          
+         
+       
+      
+    
+    
+     kindevent
+     location
+     
+      line309
+      col6
+      file0
+     
+     ranges
+     
+       
+        
+         line309
+         col4
+         file0
+        
+        
+         line309
+         col4
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Dereference of null pointer (loaded from variable 'a')
+     message
+     Dereference of null pointer (loaded from variable 'a')
+    
+   
+   descriptionDereference of null pointer (loaded from variable 'a')
+   categoryLogic error
+   typeDereference of null pointer
+   check_namecore.NullDereference
+   
+   issue_hash_content_of_line_in_contextb1da2db423e721067ed5cfda858890be
+  issue_context_kindfunction
+  issue_contextmacroArgContainsHashInStringTest
+  issue_hash_function_offset3
+  location
+  
+   line309
+   col6
+   file0
+  
+  ExecutedLines
+  
+   0
+   
+    306
+    307
+    308
+    309
+   
+  
+  
+  
+   path
+   
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line323
+           col3
+           file0
+          
+          
+           line323
+           col5
+           file0
+          
+         
+        end
+         
+          
+           line324
+           col3
+           file0
+          
+          
+           line324
+           col8
+           file0
+          
+         
+       
+      
+    
+    
+     kindmacro_expansion
+     location
+     
+      line324
+      col3
+      file0
+     
+     nameCONCAT
+     expansionllvm_clang_ento
+    
+    
+     kindevent
+     location
+     
+      line324
+      col3
+      file0
+     
+     ranges
+     
+       
+        
+         line324
+         col3
+         file0
+        
+        
+         line324
+         col31
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Calling 'llvm_clang_ento'
+     message
+     Calling 'llvm_clang_ento'
+    
+    
+     kindevent
+     location
+     
+      line318
+      col1
+      file0
+     
+     depth1
+     extended_message
+     Entered call from 'spaceAroundHashHashTest'
+     message
+     Entered call from 'spaceAroundHashHashTest'
+    
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line318
+           col1
+           file0
+          
+          
+           line318
+           col4
+           file0
+          
+         
+        end
+         
+          
+           line319
+           col3
+           file0
+          
+          
+           line319
+           col3
+           file0
+          
+         
+       
+      
+    
+    
+     kindevent
+     location
+     
+      line319
+      col3
+      file0
+     
+     ranges
+     
+       
+        
+         line319
+         col3
+         file0
+        
+        
+         line319
+         col16
+         file0
+        
+       
+     
+     depth1
+     extended_message
+     Null pointer value stored to 'a'
+     message
+     Null pointer value stored to 'a'
+    
+    
+     kindevent
+     location
+     
+      line324
+      col3
+      file0
+     
+     ranges
+     
+       
+        
+         line324
+         col3
+         file0
+        
+        
+         line324
+         col31
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Returning from 'llvm_clang_ento'
+     message
+     Returning from 'llvm_clang_ento'
+    
+    
+     kindcontrol
+     edges
+      
+       
+        start
+         
+          
+           line325
+           col3
+           file0
+          
+          
+           line325
+           col3
+           file0
+          
+         
+        end
+         
+          
+           line325
+           col6
+           file0
+          
+          
+           line325
+           col6
+           file0
+          
+         
+       
+      
+    
+    
+     kindevent
+     location
+     
+      line325
+      col6
+      file0
+     
+     ranges
+     
+       
+        
+         line325
+         col4
+         file0
+        
+        
+         line325
+         col4
+         file0
+        
+       
+     
+     depth0
+     extended_message
+     Dereference of null pointer (loaded from variable 'a')
+     message
+     Dereference of null pointer (loaded from variable 'a')
+    
+   
+   descriptionDereference of null pointer (loaded from variable 'a')
+   categoryLogic error
+   typeDereference of null pointer
+   check_namecore.NullDereference
+   
+   issue_hash_content_of_line_in_contextb06e6762f3e7dfa054c56754b0a82afd
+  issue_context_kindfunction
+  issue_contextspaceAroundHashHashTest
+  issue_hash_function_offset3
+  location
+  
+   line325
+   col6
+   file0
+  
+  ExecutedLines
+  
+   0
+   
+    318
+    319
+    322
+    323
+    324
+    325
    
   
   
Index: test/Analysis/plist-macros-with-expansion.cpp
===================================================================
--- test/Analysis/plist-macros-with-expansion.cpp
+++ test/Analysis/plist-macros-with-expansion.cpp
@@ -278,9 +278,17 @@
   *ptr = 5; // expected-warning{{Dereference of null pointer}}
 }
 
-// TODO: Should expand correctly.
 // CHECK: nameDECLARE_FUNC_AND_SET_TO_NULL
-// CHECK: expansionvoid generated_##whatever(); ptr = nullptr;
+// CHECK: expansionvoid generated_whatever(); ptr = nullptr;
+
+void macroArgContainsHashHashInStringTest() {
+  int *a;
+  TO_NULL_AND_PRINT(a, "Will this ## cause a crash?");
+  *a = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameTO_NULL_AND_PRINT
+// CHECK: expansiona = 0; print( "Will this ## cause a crash?")
 
 #define PRINT_STR(str, ptr) \
   print(#str);              \
@@ -292,6 +300,30 @@
   *ptr = 5; // expected-warning{{Dereference of null pointer}}
 }
 
-// TODO: Should expand correctly.
 // CHECK: namePRINT_STR
-// CHECK: expansionprint(#Hello); ptr = nullptr
+// CHECK: expansionprint("Hello"); ptr = nullptr
+
+void macroArgContainsHashInStringTest() {
+  int *a;
+  TO_NULL_AND_PRINT(a, "Will this # cause a crash?");
+  *a = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameTO_NULL_AND_PRINT
+// CHECK: expansiona = 0; print( "Will this # cause a crash?")
+
+#define CONCAT(a, b, c) \
+  a ## _ ## b ## _ ## c
+
+void CONCAT(llvm, clang, ento)(int **ptr) {
+  *ptr = nullptr;
+}
+
+void spaceAroundHashHashTest() {
+  int* a;
+  CONCAT(llvm, clang, ento)(&a);
+  *a = 3; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameCONCAT
+// CHECK: expansionllvm_clang_ento