From c72c57c9e9b69944e3e009cd5e209634839581d3 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Mon, 8 Apr 2013 18:45:10 +0000
Subject: Vendor import of clang trunk r178860:
 http://llvm.org/svn/llvm-project/cfe/trunk@178860

---
 lib/Tooling/JSONCompilationDatabase.cpp | 94 ++++++++++++++++++++-------------
 1 file changed, 57 insertions(+), 37 deletions(-)

(limited to 'lib/Tooling/JSONCompilationDatabase.cpp')

diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp
index cf35a25..254b069 100644
--- a/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/lib/Tooling/JSONCompilationDatabase.cpp
@@ -12,7 +12,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Tooling/JSONCompilationDatabase.h"
-
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/CompilationDatabasePluginRegistry.h"
 #include "clang/Tooling/Tooling.h"
@@ -50,7 +49,9 @@ class CommandLineArgumentParser {
   bool parseStringInto(std::string &String) {
     do {
       if (*Position == '"') {
-        if (!parseQuotedStringInto(String)) return false;
+        if (!parseDoubleQuotedStringInto(String)) return false;
+      } else if (*Position == '\'') {
+        if (!parseSingleQuotedStringInto(String)) return false;
       } else {
         if (!parseFreeStringInto(String)) return false;
       }
@@ -58,7 +59,7 @@ class CommandLineArgumentParser {
     return true;
   }
 
-  bool parseQuotedStringInto(std::string &String) {
+  bool parseDoubleQuotedStringInto(std::string &String) {
     if (!next()) return false;
     while (*Position != '"') {
       if (!skipEscapeCharacter()) return false;
@@ -68,12 +69,21 @@ class CommandLineArgumentParser {
     return next();
   }
 
+  bool parseSingleQuotedStringInto(std::string &String) {
+    if (!next()) return false;
+    while (*Position != '\'') {
+      String.push_back(*Position);
+      if (!next()) return false;
+    }
+    return next();
+  }
+
   bool parseFreeStringInto(std::string &String) {
     do {
       if (!skipEscapeCharacter()) return false;
       String.push_back(*Position);
       if (!next()) return false;
-    } while (*Position != ' ' && *Position != '"');
+    } while (*Position != ' ' && *Position != '"' && *Position != '\'');
     return true;
   }
 
@@ -112,9 +122,9 @@ std::vector<std::string> unescapeCommandLine(
 class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
   virtual CompilationDatabase *loadFromDirectory(
       StringRef Directory, std::string &ErrorMessage) {
-    llvm::SmallString<1024> JSONDatabasePath(Directory);
+    SmallString<1024> JSONDatabasePath(Directory);
     llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
-    llvm::OwningPtr<CompilationDatabase> Database(
+    OwningPtr<CompilationDatabase> Database(
         JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage));
     if (!Database)
       return NULL;
@@ -134,14 +144,14 @@ volatile int JSONAnchorSource = 0;
 JSONCompilationDatabase *
 JSONCompilationDatabase::loadFromFile(StringRef FilePath,
                                       std::string &ErrorMessage) {
-  llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer;
+  OwningPtr<llvm::MemoryBuffer> DatabaseBuffer;
   llvm::error_code Result =
     llvm::MemoryBuffer::getFile(FilePath, DatabaseBuffer);
   if (Result != 0) {
     ErrorMessage = "Error while opening JSON database: " + Result.message();
     return NULL;
   }
-  llvm::OwningPtr<JSONCompilationDatabase> Database(
+  OwningPtr<JSONCompilationDatabase> Database(
     new JSONCompilationDatabase(DatabaseBuffer.take()));
   if (!Database->parse(ErrorMessage))
     return NULL;
@@ -151,10 +161,10 @@ JSONCompilationDatabase::loadFromFile(StringRef FilePath,
 JSONCompilationDatabase *
 JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString,
                                         std::string &ErrorMessage) {
-  llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer(
+  OwningPtr<llvm::MemoryBuffer> DatabaseBuffer(
       llvm::MemoryBuffer::getMemBuffer(DatabaseString));
-  llvm::OwningPtr<JSONCompilationDatabase> Database(
-    new JSONCompilationDatabase(DatabaseBuffer.take()));
+  OwningPtr<JSONCompilationDatabase> Database(
+      new JSONCompilationDatabase(DatabaseBuffer.take()));
   if (!Database->parse(ErrorMessage))
     return NULL;
   return Database.take();
@@ -162,32 +172,20 @@ JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString,
 
 std::vector<CompileCommand>
 JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const {
-  llvm::SmallString<128> NativeFilePath;
+  SmallString<128> NativeFilePath;
   llvm::sys::path::native(FilePath, NativeFilePath);
   std::vector<StringRef> PossibleMatches;
   std::string Error;
   llvm::raw_string_ostream ES(Error);
   StringRef Match = MatchTrie.findEquivalent(NativeFilePath.str(), ES);
-  if (Match.empty()) {
-    if (Error.empty())
-      Error = "No match found.";
-    llvm::outs() << Error << "\n";
+  if (Match.empty())
     return std::vector<CompileCommand>();
-  }
   llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
     CommandsRefI = IndexByFile.find(Match);
   if (CommandsRefI == IndexByFile.end())
     return std::vector<CompileCommand>();
-  const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue();
   std::vector<CompileCommand> Commands;
-  for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
-    llvm::SmallString<8> DirectoryStorage;
-    llvm::SmallString<1024> CommandStorage;
-    Commands.push_back(CompileCommand(
-      // FIXME: Escape correctly:
-      CommandsRef[I].first->getValue(DirectoryStorage),
-      unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage))));
-  }
+  getCommands(CommandsRefI->getValue(), Commands);
   return Commands;
 }
 
@@ -206,6 +204,30 @@ JSONCompilationDatabase::getAllFiles() const {
   return Result;
 }
 
+std::vector<CompileCommand>
+JSONCompilationDatabase::getAllCompileCommands() const {
+  std::vector<CompileCommand> Commands;
+  for (llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
+        CommandsRefI = IndexByFile.begin(), CommandsRefEnd = IndexByFile.end();
+      CommandsRefI != CommandsRefEnd; ++CommandsRefI) {
+    getCommands(CommandsRefI->getValue(), Commands);
+  }
+  return Commands;
+}
+
+void JSONCompilationDatabase::getCommands(
+                                  ArrayRef<CompileCommandRef> CommandsRef,
+                                  std::vector<CompileCommand> &Commands) const {
+  for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
+    SmallString<8> DirectoryStorage;
+    SmallString<1024> CommandStorage;
+    Commands.push_back(CompileCommand(
+      // FIXME: Escape correctly:
+      CommandsRef[I].first->getValue(DirectoryStorage),
+      unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage))));
+  }
+}
+
 bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
   llvm::yaml::document_iterator I = YAMLStream.begin();
   if (I == YAMLStream.end()) {
@@ -217,8 +239,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
     ErrorMessage = "Error while parsing YAML.";
     return false;
   }
-  llvm::yaml::SequenceNode *Array =
-    llvm::dyn_cast<llvm::yaml::SequenceNode>(Root);
+  llvm::yaml::SequenceNode *Array = dyn_cast<llvm::yaml::SequenceNode>(Root);
   if (Array == NULL) {
     ErrorMessage = "Expected array.";
     return false;
@@ -226,8 +247,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
   for (llvm::yaml::SequenceNode::iterator AI = Array->begin(),
                                           AE = Array->end();
        AI != AE; ++AI) {
-    llvm::yaml::MappingNode *Object =
-      llvm::dyn_cast<llvm::yaml::MappingNode>(&*AI);
+    llvm::yaml::MappingNode *Object = dyn_cast<llvm::yaml::MappingNode>(&*AI);
     if (Object == NULL) {
       ErrorMessage = "Expected object.";
       return false;
@@ -244,18 +264,18 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
         return false;
       }
       llvm::yaml::ScalarNode *ValueString =
-        llvm::dyn_cast<llvm::yaml::ScalarNode>(Value);
+          dyn_cast<llvm::yaml::ScalarNode>(Value);
       if (ValueString == NULL) {
         ErrorMessage = "Expected string as value.";
         return false;
       }
       llvm::yaml::ScalarNode *KeyString =
-        llvm::dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
+          dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
       if (KeyString == NULL) {
         ErrorMessage = "Expected strings as key.";
         return false;
       }
-      llvm::SmallString<8> KeyStorage;
+      SmallString<8> KeyStorage;
       if (KeyString->getValue(KeyStorage) == "directory") {
         Directory = ValueString;
       } else if (KeyString->getValue(KeyStorage) == "command") {
@@ -280,12 +300,12 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
       ErrorMessage = "Missing key: \"directory\".";
       return false;
     }
-    llvm::SmallString<8> FileStorage;
+    SmallString<8> FileStorage;
     StringRef FileName = File->getValue(FileStorage);
-    llvm::SmallString<128> NativeFilePath;
+    SmallString<128> NativeFilePath;
     if (llvm::sys::path::is_relative(FileName)) {
-      llvm::SmallString<8> DirectoryStorage;
-      llvm::SmallString<128> AbsolutePath(
+      SmallString<8> DirectoryStorage;
+      SmallString<128> AbsolutePath(
           Directory->getValue(DirectoryStorage));
       llvm::sys::path::append(AbsolutePath, FileName);
       llvm::sys::path::native(AbsolutePath.str(), NativeFilePath);
-- 
cgit v1.1