summaryrefslogtreecommitdiffstats
path: root/source/Expression/ClangExpressionParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Expression/ClangExpressionParser.cpp')
-rw-r--r--source/Expression/ClangExpressionParser.cpp83
1 files changed, 71 insertions, 12 deletions
diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp
index f32ca3a..4906108 100644
--- a/source/Expression/ClangExpressionParser.cpp
+++ b/source/Expression/ClangExpressionParser.cpp
@@ -22,6 +22,7 @@
#include "lldb/Expression/ClangASTSource.h"
#include "lldb/Expression/ClangExpression.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Expression/IRInterpreter.h"
@@ -92,6 +93,47 @@ std::string GetBuiltinIncludePath(const char *Argv0) {
return P.str();
}
+class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks
+{
+ ClangModulesDeclVendor &m_decl_vendor;
+ StreamString m_error_stream;
+ bool m_has_errors = false;
+public:
+ LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor) :
+ m_decl_vendor(decl_vendor)
+ {
+ }
+
+ virtual void moduleImport(SourceLocation import_location,
+ ModuleIdPath path,
+ const clang::Module * /*null*/)
+ {
+ std::vector<llvm::StringRef> string_path;
+
+ for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
+ {
+ string_path.push_back(component.first->getName());
+ }
+
+ StreamString error_stream;
+
+ if (!m_decl_vendor.AddModule(string_path, m_error_stream))
+ {
+ m_has_errors = true;
+ }
+ }
+
+ bool hasErrors()
+ {
+ return m_has_errors;
+ }
+
+ const std::string &getErrorString()
+ {
+ return m_error_stream.GetString();
+ }
+};
+
//===----------------------------------------------------------------------===//
// Implementation of ClangExpressionParser
//===----------------------------------------------------------------------===//
@@ -101,7 +143,8 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
bool generate_debug_info) :
m_expr (expr),
m_compiler (),
- m_code_generator ()
+ m_code_generator (),
+ m_pp_callbacks(nullptr)
{
// 1. Create a new compiler instance.
m_compiler.reset(new CompilerInstance());
@@ -165,6 +208,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
case lldb::eLanguageTypeC_plus_plus:
m_compiler->getLangOpts().CPlusPlus = true;
m_compiler->getLangOpts().CPlusPlus11 = true;
+ m_compiler->getHeaderSearchOpts().UseLibcxx = true;
break;
case lldb::eLanguageTypeObjC_plus_plus:
default:
@@ -172,6 +216,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().ObjC2 = true;
m_compiler->getLangOpts().CPlusPlus = true;
m_compiler->getLangOpts().CPlusPlus11 = true;
+ m_compiler->getHeaderSearchOpts().UseLibcxx = true;
break;
}
@@ -246,7 +291,14 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->createFileManager();
m_compiler->createPreprocessor(TU_Complete);
-
+
+ if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor())
+ {
+ std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor));
+ m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get());
+ m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
+ }
+
// 6. Most of this we get from the CompilerInstance, but we
// also want to give the context an ExternalASTSource.
m_selector_table.reset(new SelectorTable());
@@ -257,6 +309,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getPreprocessor().getIdentifierTable(),
*m_selector_table.get(),
*m_builtin_context.get()));
+
ast_context->InitBuiltinTypes(m_compiler->getTarget());
ClangExpressionDeclMap *decl_map = m_expr.DeclMap();
@@ -299,22 +352,23 @@ ClangExpressionParser::Parse (Stream &stream)
{
std::string temp_source_path;
+ int temp_fd = -1;
+ llvm::SmallString<PATH_MAX> result_path;
FileSpec tmpdir_file_spec;
if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
{
- tmpdir_file_spec.AppendPathComponent("expr.XXXXXX");
+ tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
temp_source_path = std::move(tmpdir_file_spec.GetPath());
+ llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
}
else
{
- temp_source_path = "/tmp/expr.XXXXXX";
+ llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
}
-
- if (mktemp(&temp_source_path[0]))
+
+ if (temp_fd != -1)
{
- lldb_private::File file (temp_source_path.c_str(),
- File::eOpenOptionWrite | File::eOpenOptionCanCreateNewOnly,
- lldb::eFilePermissionsFileDefault);
+ lldb_private::File file (temp_fd, true);
const size_t expr_text_len = strlen(expr_text);
size_t bytes_written = expr_text_len;
if (file.Write(expr_text, bytes_written).Success())
@@ -323,7 +377,7 @@ ClangExpressionParser::Parse (Stream &stream)
{
file.Close();
SourceMgr.setMainFileID(SourceMgr.createFileID(
- m_file_manager->getFile(temp_source_path),
+ m_file_manager->getFile(result_path),
SourceLocation(), SrcMgr::C_User));
created_main_file = true;
}
@@ -351,14 +405,19 @@ ClangExpressionParser::Parse (Stream &stream)
TextDiagnosticBuffer::const_iterator diag_iterator;
int num_errors = 0;
+
+ if (m_pp_callbacks && m_pp_callbacks->hasErrors())
+ {
+ num_errors++;
+
+ stream.PutCString(m_pp_callbacks->getErrorString().c_str());
+ }
for (diag_iterator = diag_buf->warn_begin();
diag_iterator != diag_buf->warn_end();
++diag_iterator)
stream.Printf("warning: %s\n", (*diag_iterator).second.c_str());
- num_errors = 0;
-
for (diag_iterator = diag_buf->err_begin();
diag_iterator != diag_buf->err_end();
++diag_iterator)
OpenPOWER on IntegriCloud