summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBFrame.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp2
-rw-r--r--lldb/source/Core/ValueObject.cpp2
-rw-r--r--lldb/source/Expression/CMakeLists.txt12
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp2
-rw-r--r--lldb/source/Expression/ExpressionSourceCode.cpp4
-rw-r--r--lldb/source/Expression/FunctionCaller.cpp1
-rw-r--r--lldb/source/Expression/Materializer.cpp4
-rw-r--r--lldb/source/Expression/UserExpression.cpp3
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp (renamed from lldb/source/Expression/ASTDumper.cpp)3
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h42
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp (renamed from lldb/source/Expression/ASTResultSynthesizer.cpp)6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h185
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp (renamed from lldb/source/Expression/ASTStructExtractor.cpp)3
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h158
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt12
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (renamed from lldb/source/Expression/ClangASTSource.cpp)7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h526
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (renamed from lldb/source/Expression/ClangExpressionDeclMap.cpp)12
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h705
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (renamed from lldb/source/Expression/ClangExpressionParser.cpp)13
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h138
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp (renamed from lldb/source/Expression/ClangFunctionCaller.cpp)7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h175
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (renamed from lldb/source/Expression/ClangModulesDeclVendor.cpp)2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h128
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp (renamed from lldb/source/Expression/ClangPersistentVariables.cpp)3
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h91
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp (renamed from lldb/source/Expression/ClangUserExpression.cpp)14
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h204
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp (renamed from lldb/source/Expression/ClangUtilityFunction.cpp)7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h137
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp (renamed from lldb/source/Expression/IRForTarget.cpp)5
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h745
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp2
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp9
-rw-r--r--lldb/source/Target/ABI.cpp2
-rw-r--r--lldb/source/Target/Target.cpp6
39 files changed, 3312 insertions, 69 deletions
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index ee467402569..5862b9570b0 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -21,7 +21,7 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectVariable.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/Block.h"
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index 5ee5e1e0588..c38cb2b595c 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -23,7 +23,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandReturnObject.h"
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 7ca9ebf08d5..93454b13bdc 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -35,7 +35,7 @@
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Host/Endian.h"
diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
index 4b689da027b..5382da6a5ab 100644
--- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt
@@ -1,15 +1,4 @@
add_lldb_library(lldbExpression
- ASTDumper.cpp
- ASTResultSynthesizer.cpp
- ASTStructExtractor.cpp
- ClangASTSource.cpp
- ClangExpressionDeclMap.cpp
- ClangExpressionParser.cpp
- ClangFunctionCaller.cpp
- ClangModulesDeclVendor.cpp
- ClangPersistentVariables.cpp
- ClangUserExpression.cpp
- ClangUtilityFunction.cpp
DWARFExpression.cpp
Expression.cpp
ExpressionSourceCode.cpp
@@ -17,7 +6,6 @@ add_lldb_library(lldbExpression
FunctionCaller.cpp
IRDynamicChecks.cpp
IRExecutionUnit.cpp
- IRForTarget.cpp
IRInterpreter.cpp
IRMemoryMap.cpp
Materializer.cpp
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 1d0ad6f7bf3..ebcc2846039 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -24,7 +24,7 @@
#include "lldb/Core/Value.h"
#include "lldb/Core/VMRange.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
#include "lldb/Host/Endian.h"
diff --git a/lldb/source/Expression/ExpressionSourceCode.cpp b/lldb/source/Expression/ExpressionSourceCode.cpp
index 9a42510d0a2..4c0370389f3 100644
--- a/lldb/source/Expression/ExpressionSourceCode.cpp
+++ b/lldb/source/Expression/ExpressionSourceCode.cpp
@@ -10,8 +10,8 @@
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
diff --git a/lldb/source/Expression/FunctionCaller.cpp b/lldb/source/Expression/FunctionCaller.cpp
index d52eb5b1378..ddc378dcb41 100644
--- a/lldb/source/Expression/FunctionCaller.cpp
+++ b/lldb/source/Expression/FunctionCaller.cpp
@@ -19,7 +19,6 @@
#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/ASTStructExtractor.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 450d1adc939..84e04bd3f35 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -12,7 +12,7 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
@@ -1016,7 +1016,7 @@ private:
};
uint32_t
-Materializer::AddResultVariable (const TypeFromUser &type, bool is_program_reference, bool keep_in_memory, Error &err)
+Materializer::AddResultVariable (const CompilerType &type, bool is_program_reference, bool keep_in_memory, Error &err)
{
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
iter->reset (new EntityResultVariable (type, is_program_reference, keep_in_memory));
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp
index a2984363a06..1537e031d37 100644
--- a/lldb/source/Expression/UserExpression.cpp
+++ b/lldb/source/Expression/UserExpression.cpp
@@ -22,13 +22,12 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Expression/ASTResultSynthesizer.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Expression/UserExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
diff --git a/lldb/source/Expression/ASTDumper.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
index c63e4cc2862..976310610f5 100644
--- a/lldb/source/Expression/ASTDumper.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#include "ASTDumper.h"
+
#include "lldb/Core/Log.h"
-#include "lldb/Expression/ASTDumper.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompilerType.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h
new file mode 100644
index 00000000000..c8dc6847d6c
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h
@@ -0,0 +1,42 @@
+//===-- ASTDumper.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ASTDumper_h_
+#define liblldb_ASTDumper_h_
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+#include "lldb/Core/Stream.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace lldb_private
+{
+
+class ASTDumper
+{
+public:
+ ASTDumper (clang::Decl *decl);
+ ASTDumper (clang::DeclContext *decl_ctx);
+ ASTDumper (const clang::Type *type);
+ ASTDumper (clang::QualType type);
+ ASTDumper (lldb::opaque_compiler_type_t type);
+ ASTDumper (const CompilerType &compiler_type);
+
+ const char *GetCString();
+ void ToSTDERR();
+ void ToLog(Log *log, const char *prefix);
+ void ToStream(lldb::StreamSP &stream);
+private:
+ std::string m_dump;
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/source/Expression/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index c3d42cb49ec..5bba7a9c2bc 100644
--- a/lldb/source/Expression/ASTResultSynthesizer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+#include "ASTResultSynthesizer.h"
+
+#include "ClangPersistentVariables.h"
+
#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -20,8 +24,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "lldb/Core/Log.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
-#include "lldb/Expression/ASTResultSynthesizer.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Target/Target.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
new file mode 100644
index 00000000000..b8063a380ca
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -0,0 +1,185 @@
+//===-- ASTResultSynthesizer.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ASTResultSynthesizer_h_
+#define liblldb_ASTResultSynthesizer_h_
+
+#include "clang/Sema/SemaConsumer.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/TaggedASTType.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h"
+/// @brief Adds a result variable declaration to the ASTs for an expression.
+///
+/// Users expect the expression "i + 3" to return a result, even if a result
+/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds
+/// a result variable to the expression, transforming it to
+/// "int $__lldb_expr_result = i + 3." The IR transformers ensure that the
+/// resulting variable is mapped to the right piece of memory.
+/// ASTResultSynthesizer's job is to add the variable and its initialization to
+/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
+/// Clang.
+//----------------------------------------------------------------------
+class ASTResultSynthesizer : public clang::SemaConsumer
+{
+public:
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] target
+ /// The target, which contains the persistent variable store and the
+ /// AST importer.
+ //----------------------------------------------------------------------
+ ASTResultSynthesizer(clang::ASTConsumer *passthrough,
+ Target &target);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTResultSynthesizer() override;
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context) override;
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats() override;
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S) override;
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema() override;
+
+private:
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
+ /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
+ /// anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void TransformTopLevelDecl(clang::Decl *D);
+
+ //----------------------------------------------------------------------
+ /// Process an Objective-C method and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] MethodDecl
+ /// The method to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function and produce the result variable and initialization
+ ///
+ /// @param[in] FunDecl
+ /// The function to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function body and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ ///
+ /// @param[in] DC
+ /// The DeclContext of the function, into which the result variable
+ /// is inserted.
+ //----------------------------------------------------------------------
+ bool SynthesizeBodyResult(clang::CompoundStmt *Body,
+ clang::DeclContext *DC);
+
+ //----------------------------------------------------------------------
+ /// Given a DeclContext for a function or method, find all types
+ /// declared in the context and record any persistent types found.
+ ///
+ /// @param[in] FunDeclCtx
+ /// The context for the function to process.
+ //----------------------------------------------------------------------
+ void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
+
+ //----------------------------------------------------------------------
+ /// Given a TypeDecl, if it declares a type whose name starts with a
+ /// dollar sign, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void MaybeRecordPersistentType(clang::TypeDecl *D);
+
+ clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
+ Target &m_target; ///< The target, which contains the persistent variable store and the
+ clang::Sema *m_sema; ///< The Sema to use.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ASTResultSynthesizer_h_
diff --git a/lldb/source/Expression/ASTStructExtractor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index 049173e32f3..38a2b6b33a8 100644
--- a/lldb/source/Expression/ASTStructExtractor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "ASTStructExtractor.h"
+
#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -20,7 +22,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "lldb/Core/Log.h"
-#include "lldb/Expression/ASTStructExtractor.h"
using namespace llvm;
using namespace clang;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
new file mode 100644
index 00000000000..2152cff911f
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
@@ -0,0 +1,158 @@
+//===-- ASTStructExtractor.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ASTStructExtractor_h_
+#define liblldb_ASTStructExtractor_h_
+
+#include "ClangExpressionVariable.h"
+#include "ClangFunctionCaller.h"
+
+#include "clang/Sema/SemaConsumer.h"
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
+/// @brief Extracts and describes the argument structure for a wrapped function.
+///
+/// This pass integrates with ClangFunctionCaller, which calls functions with custom
+/// sets of arguments. To avoid having to implement the full calling convention
+/// for the target's architecture, ClangFunctionCaller writes a simple wrapper
+/// function that takes a pointer to an argument structure that contains room
+/// for the address of the function to be called, the values of all its
+/// arguments, and room for the function's return value.
+///
+/// The definition of this struct is itself in the body of the wrapper function,
+/// so Clang does the structure layout itself. ASTStructExtractor reads through
+/// the AST for the wrapper function and finds the struct.
+//----------------------------------------------------------------------
+class ASTStructExtractor : public clang::SemaConsumer
+{
+public:
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] struct_name
+ /// The name of the structure to extract from the wrapper function.
+ ///
+ /// @param[in] function
+ /// The caller object whose members should be populated with information
+ /// about the argument struct. ClangFunctionCaller friends ASTStructExtractor
+ /// for this purpose.
+ //----------------------------------------------------------------------
+ ASTStructExtractor(clang::ASTConsumer *passthrough,
+ const char *struct_name,
+ ClangFunctionCaller &function);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTStructExtractor() override;
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context) override;
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats() override;
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S) override;
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema() override;
+
+private:
+ //----------------------------------------------------------------------
+ /// Hunt the given FunctionDecl for the argument struct and place
+ /// information about it into m_function
+ ///
+ /// @param[in] F
+ /// The FunctionDecl to hunt.
+ //----------------------------------------------------------------------
+ void
+ ExtractFromFunctionDecl(clang::FunctionDecl* F);
+
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named the same as the wrapper
+ /// function name, recursing as necessary through LinkageSpecDecls, and
+ /// calling ExtractFromFunctionDecl on anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void
+ ExtractFromTopLevelDecl(clang::Decl* D);
+
+ clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
+ clang::Sema *m_sema; ///< The Sema to use.
+ clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.
+
+ ClangFunctionCaller &m_function; ///< The function to populate with information about the argument structure.
+ std::string m_struct_name; ///< The name of the structure to extract.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ASTStructExtractor_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt b/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
index ed8930a06b6..e18dde6b700 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
@@ -1,3 +1,15 @@
add_lldb_library(lldbPluginExpressionParserClang
+ ASTDumper.cpp
+ ASTResultSynthesizer.cpp
+ ASTStructExtractor.cpp
+ ClangASTSource.cpp
+ ClangExpressionDeclMap.cpp
+ ClangExpressionParser.cpp
ClangExpressionVariable.cpp
+ ClangFunctionCaller.cpp
+ ClangModulesDeclVendor.cpp
+ ClangPersistentVariables.cpp
+ ClangUserExpression.cpp
+ ClangUtilityFunction.cpp
+ IRForTarget.cpp
)
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index a3d380c2125..82ffdf16040 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -7,15 +7,16 @@
//
//===----------------------------------------------------------------------===//
+#include "ClangASTSource.h"
+
+#include "ASTDumper.h"
+#include "ClangModulesDeclVendor.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
-#include "lldb/Expression/ASTDumper.h"
-#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
new file mode 100644
index 00000000000..9f4d238cacd
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -0,0 +1,526 @@
+//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangASTSource_h_
+#define liblldb_ClangASTSource_h_
+
+#include <set>
+
+#include "clang/Basic/IdentifierTable.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Target.h"
+
+#include "llvm/ADT/SmallSet.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+/// @brief Provider for named objects defined in the debug info for Clang
+///
+/// As Clang parses an expression, it may encounter names that are not
+/// defined inside the expression, including variables, functions, and
+/// types. Clang knows the name it is looking for, but nothing else.
+/// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl)
+/// to Clang for these names, consulting the ClangExpressionDeclMap to do
+/// the actual lookups.
+//----------------------------------------------------------------------
+class ClangASTSource :
+ public ClangExternalASTSourceCommon,
+ public ClangASTImporter::MapCompleter
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] declMap
+ /// A reference to the LLDB object that handles entity lookup.
+ //------------------------------------------------------------------
+ ClangASTSource (const lldb::TargetSP &target) :
+ m_import_in_progress (false),
+ m_lookups_enabled (false),
+ m_target (target),
+ m_ast_context (NULL),
+ m_active_lexical_decls (),
+ m_active_lookups ()
+ {
+ m_ast_importer = m_target->GetClangASTImporter();
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangASTSource() override;
+
+ //------------------------------------------------------------------
+ /// Interface stubs.
+ //------------------------------------------------------------------
+ clang::Decl *GetExternalDecl (uint32_t) override { return NULL; }
+ clang::Stmt *GetExternalDeclStmt (uint64_t) override { return NULL; }
+ clang::Selector GetExternalSelector (uint32_t) override { return clang::Selector(); }
+ uint32_t GetNumExternalSelectors () override { return 0; }
+ clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) override
+ { return NULL; }
+ void MaterializeVisibleDecls (const clang::DeclContext *DC)
+ { return; }
+
+ void InstallASTContext (clang::ASTContext *ast_context)
+ {
+ m_ast_context = ast_context;
+ m_ast_importer->InstallMapCompleter(ast_context, *this);
+ }
+
+ //
+ // APIs for ExternalASTSource
+ //
+
+ //------------------------------------------------------------------
+ /// Look up all Decls that match a particular name. Only handles
+ /// Identifiers and DeclContexts that are either NamespaceDecls or
+ /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
+ /// the result.
+ ///
+ /// The work for this function is done by
+ /// void FindExternalVisibleDecls (NameSearchContext &);
+ ///
+ /// @param[in] DC
+ /// The DeclContext to register the found Decls in.
+ ///
+ /// @param[in] Name
+ /// The name to find entries for.
+ ///
+ /// @return
+ /// Whatever SetExternalVisibleDeclsForName returns.
+ //------------------------------------------------------------------
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override;
+
+ //------------------------------------------------------------------
+ /// Enumerate all Decls in a given lexical context.
+ ///
+ /// @param[in] DC
+ /// The DeclContext being searched.
+ ///
+ /// @param[in] isKindWeWant
+ /// A callback function that returns true given the
+ /// DeclKinds of desired Decls, and false otherwise.
+ ///
+ /// @param[in] Decls
+ /// A vector that is filled in with matching Decls.
+ //------------------------------------------------------------------
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC, llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
+
+ //------------------------------------------------------------------
+ /// Specify the layout of the contents of a RecordDecl.
+ ///
+ /// @param[in] Record
+ /// The record (in the parser's AST context) that needs to be
+ /// laid out.
+ ///
+ /// @param[out] Size
+ /// The total size of the record in bits.
+ ///
+ /// @param[out] Alignment
+ /// The alignment of the record in bits.
+ ///
+ /// @param[in] FieldOffsets
+ /// A map that must be populated with pairs of the record's
+ /// fields (in the parser's AST context) and their offsets
+ /// (measured in bits).
+ ///
+ /// @param[in] BaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ concrete base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @param[in] VirtualBaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ virtual base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @return
+ /// True <=> the layout is valid.
+ //-----------------------------------------------------------------
+ bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override;
+
+ //------------------------------------------------------------------
+ /// Complete a TagDecl.
+ ///
+ /// @param[in] Tag
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ void CompleteType(clang::TagDecl *Tag) override;
+
+ //------------------------------------------------------------------
+ /// Complete an ObjCInterfaceDecl.
+ ///
+ /// @param[in] Class
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override;
+
+ //------------------------------------------------------------------
+ /// Called on entering a translation unit. Tells Clang by calling
+ /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
+ /// that this object has something to say about undefined names.
+ ///
+ /// @param[in] ASTConsumer
+ /// Unused.
+ //------------------------------------------------------------------
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
+
+ //
+ // APIs for NamespaceMapCompleter
+ //
+
+ //------------------------------------------------------------------
+ /// Look up the modules containing a given namespace and put the
+ /// appropriate entries in the namespace map.
+ ///
+ /// @param[in] namespace_map
+ /// The map to be completed.
+ ///
+ /// @param[in] name
+ /// The name of the namespace to be found.
+ ///
+ /// @param[in] parent_map
+ /// The map for the namespace's parent namespace, if there is
+ /// one.
+ //------------------------------------------------------------------
+ void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
+ ClangASTImporter::NamespaceMapSP &parent_map) const override;
+
+ //
+ // Helper APIs
+ //
+
+ clang::NamespaceDecl *
+ AddNamespace (NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls);
+
+ //------------------------------------------------------------------
+ /// The worker function for FindExternalVisibleDeclsByName.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when filing results.
+ //------------------------------------------------------------------
+ virtual void FindExternalVisibleDecls (NameSearchContext &context);
+
+ void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
+ bool GetImportInProgress () { return m_import_in_progress; }
+
+ void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
+ bool GetLookupsEnabled () { return m_lookups_enabled; }
+
+ //----------------------------------------------------------------------
+ /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+ /// @brief Proxy for ClangASTSource
+ ///
+ /// Clang AST contexts like to own their AST sources, so this is a
+ /// state-free proxy object.
+ //----------------------------------------------------------------------
+ class ClangASTSourceProxy : public ClangExternalASTSourceCommon
+ {
+ public:
+ ClangASTSourceProxy (ClangASTSource &original) :
+ m_original(original)
+ {
+ }
+
+ bool
+ FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
+ {
+ return m_original.FindExternalVisibleDeclsByName(DC, Name);
+ }
+
+ void
+ FindExternalLexicalDecls(const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override
+ {
+ return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
+ }
+
+ void
+ CompleteType(clang::TagDecl *Tag) override
+ {
+ return m_original.CompleteType(Tag);
+ }
+
+ void
+ CompleteType(clang::ObjCInterfaceDecl *Class) override
+ {
+ return m_original.CompleteType(Class);
+ }
+
+ bool
+ layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override
+ {
+ return m_original.layoutRecordType(Record,
+ Size,
+ Alignment,
+ FieldOffsets,
+ BaseOffsets,
+ VirtualBaseOffsets);
+ }
+
+ void
+ StartTranslationUnit(clang::ASTConsumer *Consumer) override
+ {
+ return m_original.StartTranslationUnit(Consumer);
+ }
+
+ ClangASTMetadata *
+ GetMetadata(const void * object)
+ {
+ return m_original.GetMetadata(object);
+ }
+
+ void
+ SetMetadata(const void * object, ClangASTMetadata &metadata)
+ {
+ return m_original.SetMetadata(object, metadata);
+ }
+
+ bool
+ HasMetadata(const void * object)
+ {
+ return m_original.HasMetadata(object);
+ }
+ private:
+ ClangASTSource &m_original;
+ };
+
+ clang::ExternalASTSource *CreateProxy()
+ {
+ return new ClangASTSourceProxy(*this);
+ }
+
+protected:
+ //------------------------------------------------------------------
+ /// Look for the complete version of an Objective-C interface, and
+ /// return it if found.
+ ///
+ /// @param[in] interface_decl
+ /// An ObjCInterfaceDecl that may not be the complete one.
+ ///
+ /// @return
+ /// NULL if the complete interface couldn't be found;
+ /// the complete interface otherwise.
+ //------------------------------------------------------------------
+ clang::ObjCInterfaceDecl *
+ GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void
+ FindExternalVisibleDecls (NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C methods matching a given selector.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the selector and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void
+ FindObjCMethodDecls (NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C properties and ivars with a given name.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the name and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void
+ FindObjCPropertyAndIvarDecls (NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// A wrapper for ClangASTContext::CopyType that sets a flag that
+ /// indicates that we should not respond to queries during import.
+ ///
+ /// @param[in] dest_context
+ /// The target AST context, typically the parser's AST context.
+ ///
+ /// @param[in] source_context
+ /// The source AST context, typically the AST context of whatever
+ /// symbol file the type was found in.
+ ///
+ /// @param[in] src_type
+ /// The source type.
+ ///
+ /// @return
+ /// The imported type.
+ //------------------------------------------------------------------
+ CompilerType
+ GuardedCopyType (const CompilerType &src_type);
+
+ friend struct NameSearchContext;
+
+ bool m_import_in_progress;
+ bool m_lookups_enabled;
+
+ const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
+ clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
+ ClangASTImporter *m_ast_importer; ///< The target's AST importer.
+ std::set<const clang::Decl *> m_active_lexical_decls;
+ std::set<const char *> m_active_lookups;
+};
+
+//----------------------------------------------------------------------
+/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+/// @brief Container for all objects relevant to a single name lookup
+///
+/// LLDB needs to create Decls for entities it finds. This class communicates
+/// what name is being searched for and provides helper functions to construct
+/// Decls given appropriate type information.
+//----------------------------------------------------------------------
+struct NameSearchContext {
+ ClangASTSource &m_ast_source; ///< The AST source making the request
+ llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed
+ ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules
+ const clang::DeclarationName &m_decl_name; ///< The name being looked for
+ const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into
+ llvm::SmallSet <CompilerType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts
+
+ struct {
+ bool variable : 1;
+ bool function_with_type_info : 1;
+ bool function : 1;
+ } m_found;
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] astSource
+ /// A reference to the AST source making a request.
+ ///
+ /// @param[in] decls
+ /// A reference to a list into which new Decls will be placed. This
+ /// list is typically empty when the function is called.
+ ///
+ /// @param[in] name
+ /// The name being searched for (always an Identifier).
+ ///
+ /// @param[in] dc
+ /// The DeclContext to register Decls in.
+ //------------------------------------------------------------------
+ NameSearchContext (ClangASTSource &astSource,
+ llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
+ clang::DeclarationName &name,
+ const clang::DeclContext *dc) :
+ m_ast_source(astSource),
+ m_decls(decls),
+ m_decl_name(name),
+ m_decl_context(dc)
+ {
+ memset(&m_found, 0, sizeof(m_found));
+ }
+
+ //------------------------------------------------------------------
+ /// Create a VarDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the VarDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddVarDecl(const CompilerType &type);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the FunDecl being registered.
+ ///
+ /// @param[in] extern_c
+ /// If true, build an extern "C" linkage specification for this.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddFunDecl(const CompilerType &type,
+ bool extern_c = false);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and generic
+ /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
+ /// right places.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddGenericFunDecl();
+
+ //------------------------------------------------------------------
+ /// Create a TypeDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] compiler_type
+ /// The opaque QualType for the TypeDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
+
+
+ //------------------------------------------------------------------
+ /// Add Decls from the provided DeclContextLookupResult to the list
+ /// of results.
+ ///
+ /// @param[in] result
+ /// The DeclContextLookupResult, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddLookupResult (clang::DeclContextLookupResult result);
+
+ //------------------------------------------------------------------
+ /// Add a NamedDecl to the list of results.
+ ///
+ /// @param[in] decl
+ /// The NamedDecl, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddNamedDecl (clang::NamedDecl *decl);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangASTSource_h_
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 5bf939e8375..533f7c268c7 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -7,7 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "ClangExpressionDeclMap.h"
+
+#include "ASTDumper.h"
+#include "ClangASTSource.h"
+#include "ClangModulesDeclVendor.h"
+#include "ClangPersistentVariables.h"
+
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
@@ -21,10 +27,6 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
-#include "lldb/Expression/ASTDumper.h"
-#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
new file mode 100644
index 00000000000..1ed2c4e3f20
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -0,0 +1,705 @@
+//===-- ClangExpressionDeclMap.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExpressionDeclMap_h_
+#define liblldb_ClangExpressionDeclMap_h_
+
+// C Includes
+#include <signal.h>
+#include <stdint.h>
+
+// C++ Includes
+#include <vector>
+
+#include "ClangExpressionVariable.h"
+#include "ClangASTSource.h"
+
+// Other libraries and framework includes
+// Project includes
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/Decl.h"
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ExecutionContext.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h"
+/// @brief Manages named entities that are defined in LLDB's debug information.
+///
+/// The Clang parser uses the ClangASTSource as an interface to request named
+/// entities from outside an expression. The ClangASTSource reports back, listing
+/// all possible objects corresponding to a particular name. But it in turn
+/// relies on ClangExpressionDeclMap, which performs several important functions.
+///
+/// First, it records what variables and functions were looked up and what Decls
+/// were returned for them.
+///
+/// Second, it constructs a struct on behalf of IRForTarget, recording which
+/// variables should be placed where and relaying this information back so that
+/// IRForTarget can generate context-independent code.
+///
+/// Third, it "materializes" this struct on behalf of the expression command,
+/// finding the current values of each variable and placing them into the
+/// struct so that it can be passed to the JITted version of the IR.
+///
+/// Fourth and finally, it "dematerializes" the struct after the JITted code has
+/// has executed, placing the new values back where it found the old ones.
+//----------------------------------------------------------------------
+class ClangExpressionDeclMap :
+ public ClangASTSource
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// If true, inhibits the normal deallocation of the memory for
+ /// the result persistent variable, and instead marks the variable
+ /// as persisting.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when parsing.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap (bool keep_result_in_memory,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionDeclMap() override;
+
+ //------------------------------------------------------------------
+ /// Enable the state needed for parsing and IR transformation.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when finding types for variables.
+ /// Also used to find a "scratch" AST context to store result types.
+ ///
+ /// @param[in] materializer
+ /// If non-NULL, the materializer to populate with information about
+ /// the variables to use
+ ///
+ /// @return
+ /// True if parsing is possible; false if it is unsafe to continue.
+ //------------------------------------------------------------------
+ bool
+ WillParse (ExecutionContext &exe_ctx,
+ Materializer *materializer);
+
+ void
+ InstallCodeGenerator (clang::ASTConsumer *code_gen);
+
+ //------------------------------------------------------------------
+ /// [Used by ClangExpressionParser] For each variable that had an unknown
+ /// type at the beginning of parsing, determine its final type now.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveUnknownTypes();
+
+ //------------------------------------------------------------------
+ /// Disable the state needed for parsing and IR transformation.
+ //------------------------------------------------------------------
+ void
+ DidParse ();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the list of persistent
+ /// variables for the process.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the persistent variable, used for
+ /// lookup during parsing.
+ ///
+ /// @param[in] name
+ /// The name of the persistent variable, usually $something.
+ ///
+ /// @param[in] type
+ /// The type of the variable, in the Clang parser's context.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ AddPersistentVariable (const clang::NamedDecl *decl,
+ const ConstString &name,
+ TypeFromParser type,
+ bool is_result,
+ bool is_lvalue);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the struct that needs to
+ /// be materialized each time the expression runs.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the variable.
+ ///
+ /// @param[in] value
+ /// The LLVM IR value for this variable.
+ ///
+ /// @param[in] size
+ /// The size of the variable in bytes.
+ ///
+ /// @param[in] alignment
+ /// The required alignment of the variable in bytes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ AddValueToStruct (const clang::NamedDecl *decl,
+ const ConstString &name,
+ llvm::Value *value,
+ size_t size,
+ lldb::offset_t alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Finalize the struct, laying out the position
+ /// of each object in it.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ DoStructLayout ();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get general information about the laid-out
+ /// struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] num_elements
+ /// The number of elements in the struct.
+ ///
+ /// @param[out] size
+ /// The size of the struct, in bytes.
+ ///
+ /// @param[out] alignment
+ /// The alignment of the struct, in bytes.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetStructInfo (uint32_t &num_elements,
+ size_t &size,
+ lldb::offset_t &alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get specific information about one field
+ /// of the laid-out struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] decl
+ /// The parsed Decl for the field, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf. In the case of the result
+ /// value, this will have the name $__lldb_result even if the
+ /// result value ends up having the name $1. This is an
+ /// implementation detail of IRForTarget.
+ ///
+ /// @param[out] value
+ /// The IR value for the field (usually a GlobalVariable). In
+ /// the case of the result value, this will have the correct
+ /// name ($1, for instance). This is an implementation detail
+ /// of IRForTarget.
+ ///
+ /// @param[out] offset
+ /// The offset of the field from the beginning of the struct.
+ /// As long as the struct is aligned according to its required
+ /// alignment, this offset will align the field correctly.
+ ///
+ /// @param[out] name
+ /// The name of the field as used in materialization.
+ ///
+ /// @param[in] index
+ /// The index of the field about which information is requested.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetStructElement (const clang::NamedDecl *&decl,
+ llvm::Value *&value,
+ lldb::offset_t &offset,
+ ConstString &name,
+ uint32_t index);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get information about a function given its
+ /// Decl.
+ ///
+ /// @param[in] decl
+ /// The parsed Decl for the Function, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf.
+ ///
+ /// @param[out] ptr
+ /// The absolute address of the function in the target.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionInfo (const clang::NamedDecl *decl,
+ uint64_t &ptr);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get the address of a function given nothing
+ /// but its name. Some functions are needed but didn't get Decls made
+ /// during parsing -- specifically, sel_registerName is never called
+ /// in the generated IR but we need to call it nonetheless.
+ ///
+ /// @param[in] name
+ /// The name of the function.
+ ///
+ /// @param[out] ptr
+ /// The absolute address of the function in the target.
+ ///
+ /// @return
+ /// True if the address could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionAddress (const ConstString &name,
+ uint64_t &ptr);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get the address of a symbol given nothing
+ /// but its name.
+ ///
+ /// @param[in] target
+ /// The target to find the symbol in. If not provided,
+ /// then the current parsing context's Target.
+ ///
+ /// @param[in] process
+ /// The process to use. For Objective-C symbols, the process's
+ /// Objective-C language runtime may be queried if the process
+ /// is non-NULL.
+ ///
+ /// @param[in] name
+ /// The name of the symbol.
+ ///
+ /// @param[in] module
+ /// The module to limit the search to. This can be NULL
+ ///
+ /// @return
+ /// Valid load address for the symbol
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetSymbolAddress (Target &target,
+ Process *process,
+ const ConstString &name,
+ lldb::SymbolType symbol_type,
+ Module *module = NULL);
+
+ lldb::addr_t
+ GetSymbolAddress (const ConstString &name,
+ lldb::SymbolType symbol_type);
+
+ //------------------------------------------------------------------
+ /// [Used by IRInterpreter] Get basic target information.
+ ///
+ /// @param[out] byte_order
+ /// The byte order of the target.
+ ///
+ /// @param[out] address_byte_size
+ /// The size of a pointer in bytes.
+ ///
+ /// @return
+ /// True if the information could be determined; false
+ /// otherwise.
+ //------------------------------------------------------------------
+ struct TargetInfo
+ {
+ lldb::ByteOrder byte_order;
+ size_t address_byte_size;
+
+ TargetInfo() :
+ byte_order(lldb::eByteOrderInvalid),
+ address_byte_size(0)
+ {
+ }
+
+ bool IsValid()
+ {
+ return (byte_order != lldb::eByteOrderInvalid &&
+ address_byte_size != 0);
+ }
+ };
+ TargetInfo GetTargetInfo();
+
+ //------------------------------------------------------------------
+ /// [Used by ClangASTSource] Find all entities matching a given name,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void
+ FindExternalVisibleDecls(NameSearchContext &context) override;
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module/namespace,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string. The NameSearchContext contains
+ /// a DeclarationName for the name so at first the name may seem
+ /// redundant, but ClangExpressionDeclMap operates in RTTI land so
+ /// it can't access DeclarationName.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void
+ FindExternalVisibleDecls (NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl,
+ unsigned int current_id);
+private:
+ ExpressionVariableList m_found_entities; ///< All entities that were looked up for the parser.
+ ExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct.
+ bool m_keep_result_in_memory; ///< True if result persistent variables generated by this expression should stay in memory.
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars
+ {
+ public:
+ ParserVars(ClangExpressionDeclMap &decl_map) :
+ m_decl_map(decl_map)
+ {
+ }
+
+ Target *
+ GetTarget()
+ {
+ if (m_exe_ctx.GetTargetPtr())
+ return m_exe_ctx.GetTargetPtr();
+ else if (m_sym_ctx.target_sp)
+ m_sym_ctx.target_sp.get();
+ return NULL;
+ }
+
+ ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
+ SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables and types.
+ ClangPersistentVariables *m_persistent_vars = nullptr; ///< The persistent variables for the process.
+ bool m_enable_lookups = false; ///< Set to true during parsing if we have found the first "$__lldb" name.
+ TargetInfo m_target_info; ///< Basic information about the target.
+ Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer to use when reporting used variables.
+ clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator that receives new top-level functions.
+ private:
+ ClangExpressionDeclMap &m_decl_map;
+ DISALLOW_COPY_AND_ASSIGN (ParserVars);
+ };
+
+ std::unique_ptr<ParserVars> m_parser_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate parser-specific variables
+ //----------------------------------------------------------------------
+ void
+ EnableParserVars()
+ {
+ if (!m_parser_vars.get())
+ m_parser_vars.reset(new ParserVars(*this));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void
+ DisableParserVars()
+ {
+ m_parser_vars.reset();
+ }
+
+ //----------------------------------------------------------------------
+ /// The following values contain layout information for the materialized
+ /// struct, but are not specific to a single materialization
+ //----------------------------------------------------------------------
+ struct StructVars {
+ StructVars() :
+ m_struct_alignment(0),
+ m_struct_size(0),
+ m_struct_laid_out(false),
+ m_result_name(),
+ m_object_pointer_type(NULL, NULL)
+ {
+ }
+
+ lldb::offset_t m_struct_alignment; ///< The alignment of the struct in bytes.
+ size_t m_struct_size; ///< The size of the struct in bytes.
+ bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
+ ConstString m_result_name; ///< The name of the result variable ($1, for example)
+ TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if one exists
+ };
+
+ std::unique_ptr<StructVars> m_struct_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate struct variables
+ //----------------------------------------------------------------------
+ void
+ EnableStructVars()
+ {
+ if (!m_struct_vars.get())
+ m_struct_vars.reset(new struct StructVars);
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate struct variables
+ //----------------------------------------------------------------------
+ void
+ DisableStructVars()
+ {
+ m_struct_vars.reset();
+ }
+
+ //----------------------------------------------------------------------
+ /// Get this parser's ID for use in extracting parser- and JIT-specific
+ /// data from persistent variables.
+ //----------------------------------------------------------------------
+ uint64_t
+ GetParserID()
+ {
+ return (uint64_t)this;
+ }
+
+ //------------------------------------------------------------------
+ /// Given a target, find a data symbol that has the given name.
+ ///
+ /// @param[in] target
+ /// The target to use as the basis for the search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] module
+ /// The module to limit the search to. This can be NULL
+ ///
+ /// @return
+ /// The LLDB Symbol found, or NULL if none was found.
+ //------------------------------------------------------------------
+ const Symbol *
+ FindGlobalDataSymbol (Target &target,
+ const ConstString &name,
+ Module *module = NULL);
+
+ //------------------------------------------------------------------
+ /// Given a target, find a variable that matches the given name and
+ /// type.
+ ///
+ /// @param[in] target
+ /// The target to use as a basis for finding the variable.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] namespace_decl
+ /// If non-NULL and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] type
+ /// The required type for the variable. This function may be called
+ /// during parsing, in which case we don't know its type; hence the
+ /// default.
+ ///
+ /// @return
+ /// The LLDB Variable found, or NULL if none was found.
+ //------------------------------------------------------------------
+ lldb::VariableSP
+ FindGlobalVariable (Target &target,
+ lldb::ModuleSP &module,
+ const ConstString &name,
+ CompilerDeclContext *namespace_decl,
+ TypeFromUser *type = NULL);
+
+ //------------------------------------------------------------------
+ /// Get the value of a variable in a given execution context and return
+ /// the associated Types if needed.
+ ///
+ /// @param[in] var
+ /// The variable to evaluate.
+ ///
+ /// @param[out] var_location
+ /// The variable location value to fill in
+ ///
+ /// @param[out] found_type
+ /// The type of the found value, as it was found in the user process.
+ /// This is only useful when the variable is being inspected on behalf
+ /// of the parser, hence the default.
+ ///
+ /// @param[out] parser_type
+ /// The type of the found value, as it was copied into the parser's
+ /// AST context. This is only useful when the variable is being
+ /// inspected on behalf of the parser, hence the default.
+ ///
+ /// @param[in] decl
+ /// The Decl to be looked up.
+ ///
+ /// @return
+ /// Return true if the value was successfully filled in.
+ //------------------------------------------------------------------
+ bool
+ GetVariableValue (lldb::VariableSP &var,
+ lldb_private::Value &var_location,
+ TypeFromUser *found_type = NULL,
+ TypeFromParser *parser_type = NULL);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// Variable, and put it in the Tuple list.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ ///
+ /// @param[in] valobj
+ /// The LLDB ValueObject for that variable.
+ //------------------------------------------------------------------
+ void
+ AddOneVariable (NameSearchContext &context,
+ lldb::VariableSP var,
+ lldb::ValueObjectSP valobj,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// persistent variable, and put it in the list of found entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] pvar
+ /// The persistent variable that needs a Decl.
+ ///
+ /// @param[in] current_id
+ /// The ID of the current invocation of FindExternalVisibleDecls
+ /// for logging purposes.
+ //------------------------------------------------------------------
+ void
+ AddOneVariable (NameSearchContext &context,
+ lldb::ExpressionVariableSP &pvar_sp,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// symbol (treated as a variable), and put it in the list of found
+ /// entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ //------------------------------------------------------------------
+ void
+ AddOneGenericVariable (NameSearchContext &context,
+ const Symbol &symbol,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// function. (Functions are not placed in the Tuple list.) Can
+ /// handle both fully typed functions and generic functions.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] fun
+ /// The Function that needs to be created. If non-NULL, this is
+ /// a fully-typed function.
+ ///
+ /// @param[in] sym
+ /// The Symbol that corresponds to a function that needs to be
+ /// created with generic type (unitptr_t foo(...)).
+ //------------------------------------------------------------------
+ void
+ AddOneFunction (NameSearchContext &context,
+ Function *fun,
+ Symbol *sym,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// register.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] reg_info
+ /// The information corresponding to that register.
+ //------------------------------------------------------------------
+ void
+ AddOneRegister (NameSearchContext &context,
+ const RegisterInfo *reg_info,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// type. (Types are not placed in the Tuple list.)
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+ void
+ AddOneType (NameSearchContext &context,
+ TypeFromUser &type,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Copy a C++ class type into the parser's AST context and add a
+ /// member function declaration to it for the expression.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+
+ TypeFromParser
+ CopyClassType(TypeFromUser &type,
+ unsigned int current_id);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangExpressionDeclMap_h_
diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 432ddbb5505..8b679a9edc9 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -7,7 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Expression/ClangExpressionParser.h"
+#include "ClangExpressionParser.h"
+
+#include "ClangASTSource.h"
+#include "ClangExpressionHelper.h"
+#include "ClangExpressionDeclMap.h"
+#include "ClangModulesDeclVendor.h"
+#include "ClangPersistentVariables.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -18,11 +24,6 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangExpressionHelper.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Expression/IRInterpreter.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
new file mode 100644
index 00000000000..01ab3d8f2d2
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -0,0 +1,138 @@
+//===-- ClangExpressionParser.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExpressionParser_h_
+#define liblldb_ClangExpressionParser_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/ExpressionParser.h"
+
+#include "IRForTarget.h"
+
+#include <string>
+#include <vector>
+
+namespace lldb_private
+{
+
+class IRExecutionUnit;
+
+//----------------------------------------------------------------------
+/// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
+/// @brief Encapsulates an instance of Clang that can parse expressions.
+///
+/// ClangExpressionParser is responsible for preparing an instance of
+/// ClangExpression for execution. ClangExpressionParser uses ClangExpression
+/// as a glorified parameter list, performing the required parsing and
+/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
+/// that can be executed.
+//----------------------------------------------------------------------
+class ClangExpressionParser : public ExpressionParser
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] exe_scope,
+ /// If non-NULL, an execution context scope that can help to
+ /// correctly create an expression with a valid process for
+ /// optional tuning Objective-C runtime support. Can be NULL.
+ ///
+ /// @param[in] expr
+ /// The expression to be parsed.
+ //------------------------------------------------------------------
+ ClangExpressionParser (ExecutionContextScope *exe_scope,
+ Expression &expr,
+ bool generate_debug_info);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionParser () override;
+
+ //------------------------------------------------------------------
+ /// Parse a single expression and convert it to IR using Clang. Don't
+ /// wrap the expression in anything at all.
+ ///
+ /// @param[in] stream
+ /// The stream to print errors to.
+ ///
+ /// @return
+ /// The number of errors encountered during parsing. 0 means
+ /// success.
+ //------------------------------------------------------------------
+ unsigned
+ Parse (Stream &stream) override;
+
+ //------------------------------------------------------------------
+ /// Ready an already-parsed expression for execution, possibly
+ /// evaluating it statically.
+ ///
+ /// @param[out] func_addr
+ /// The address to which the function has been written.
+ ///
+ /// @param[out] func_end
+ /// The end of the function's allocated memory region. (func_addr
+ /// and func_end do not delimit an allocated region; the allocated
+ /// region may begin before func_addr.)
+ ///
+ /// @param[in] execution_unit_sp
+ /// After parsing, ownership of the execution unit for
+ /// for the expression is handed to this shared pointer.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to write the function into.
+ ///
+ /// @param[out] evaluated_statically
+ /// Set to true if the expression could be interpreted statically;
+ /// untouched otherwise.
+ ///
+ /// @param[out] const_result
+ /// If the result of the expression is constant, and the
+ /// expression has no side effects, this is set to the result of the
+ /// expression.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether the expression must be JIT-compiled, must be
+ /// evaluated statically, or whether this decision may be made
+ /// opportunistically.
+ ///
+ /// @return
+ /// An error code indicating the success or failure of the operation.
+ /// Test with Success().
+ //------------------------------------------------------------------
+ Error
+ PrepareForExecution (lldb::addr_t &func_addr,
+ lldb::addr_t &func_end,
+ std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
+ ExecutionContext &exe_ctx,
+ bool &can_interpret,
+ lldb_private::ExecutionPolicy execution_policy) override;
+
+private:
+ std::unique_ptr<llvm::LLVMContext> m_llvm_context; ///< The LLVM context to generate IR into
+ std::unique_ptr<clang::FileManager> m_file_manager; ///< The Clang file manager object used by the compiler
+ std::unique_ptr<clang::CompilerInstance> m_compiler; ///< The Clang compiler used to parse expressions into IR
+ std::unique_ptr<clang::Builtin::Context> m_builtin_context; ///< Context for Clang built-ins
+ std::unique_ptr<clang::SelectorTable> m_selector_table; ///< Selector table for Objective-C methods
+ std::unique_ptr<clang::CodeGenerator> m_code_generator; ///< The Clang object that generates IR
+
+ class LLDBPreprocessorCallbacks;
+ LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor encounters module imports
+ std::unique_ptr<ClangASTContext> m_ast_context;
+};
+
+}
+
+#endif // liblldb_ClangExpressionParser_h_
diff --git a/lldb/source/Expression/ClangFunctionCaller.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 628952fe6b8..0d0d7475a00 100644
--- a/lldb/source/Expression/ClangFunctionCaller.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+#include "ClangFunctionCaller.h"
+
+#include "ASTStructExtractor.h"
+#include "ClangExpressionParser.h"
// C Includes
// C++ Includes
@@ -28,9 +32,6 @@
#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/ASTStructExtractor.h"
-#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunctionCaller.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
new file mode 100644
index 00000000000..7922f14edd8
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -0,0 +1,175 @@
+//===-- ClangFunctionCaller.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangFunctionCaller_h_
+#define liblldb_ClangFunctionCaller_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <list>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Process.h"
+
+namespace lldb_private
+{
+
+class ASTStructExtractor;
+class ClangExpressionParser;
+
+//----------------------------------------------------------------------
+/// @class ClangFunctionCaller ClangFunctionCaller.h "lldb/Expression/ClangFunctionCaller.h"
+/// @brief Encapsulates a function that can be called.
+///
+/// A given ClangFunctionCaller object can handle a single function signature.
+/// Once constructed, it can set up any number of concurrent calls to
+/// functions with that signature.
+///
+/// It performs the call by synthesizing a structure that contains the pointer
+/// to the function and the arguments that should be passed to that function,
+/// and producing a special-purpose JIT-compiled function that accepts a void*
+/// pointing to this struct as its only argument and calls the function in the
+/// struct with the written arguments. This method lets Clang handle the
+/// vagaries of function calling conventions.
+///
+/// The simplest use of the ClangFunctionCaller is to construct it with a
+/// function representative of the signature you want to use, then call
+/// ExecuteFunction(ExecutionContext &, Stream &, Value &).
+///
+/// If you need to reuse the arguments for several calls, you can call
+/// InsertFunction() followed by WriteFunctionArguments(), which will return
+/// the location of the args struct for the wrapper function in args_addr_ref.
+///
+/// If you need to call the function on the thread plan stack, you can also
+/// call InsertFunction() followed by GetThreadPlanToCallFunction().
+///
+/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
+/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
+/// and its address returned in that variable.
+///
+/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
+/// argument space will be managed for you.
+//----------------------------------------------------------------------
+class ClangFunctionCaller : public FunctionCaller
+{
+ friend class ASTStructExtractor;
+
+ class ClangFunctionCallerHelper : public ClangExpressionHelper
+ {
+ public:
+ ClangFunctionCallerHelper (ClangFunctionCaller &owner) :
+ m_owner(owner)
+ {
+ }
+
+ ~ClangFunctionCallerHelper() {}
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap *
+ DeclMap() override
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override;
+ private:
+ ClangFunctionCaller &m_owner;
+ std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that generates the argument struct layout.
+ };
+
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] exe_scope
+ /// An execution context scope that gets us at least a target and
+ /// process.
+ ///
+ /// @param[in] ast_context
+ /// The AST context to evaluate argument types in.
+ ///
+ /// @param[in] return_qualtype
+ /// An opaque Clang QualType for the function result. Should be
+ /// defined in ast_context.
+ ///
+ /// @param[in] function_address
+ /// The address of the function to call.
+ ///
+ /// @param[in] arg_value_list
+ /// The default values to use when calling this function. Can
+ /// be overridden using WriteFunctionArguments().
+ //------------------------------------------------------------------
+ ClangFunctionCaller (ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
+ const Address& function_address,
+ const ValueList &arg_value_list,
+ const char *name);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangFunctionCaller() override;
+
+ //------------------------------------------------------------------
+ /// Compile the wrapper function
+ ///
+ /// @param[in] errors
+ /// The stream to print parser errors to.
+ ///
+ /// @return
+ /// The number of errors.
+ //------------------------------------------------------------------
+ unsigned
+ CompileFunction (Stream &errors) override;
+
+ ExpressionTypeSystemHelper *
+ GetTypeSystemHelper () override
+ {
+ return &m_type_system_helper;
+ }
+protected:
+ const char *GetWrapperStructName()
+ {
+ return m_wrapper_struct_name.c_str();
+ }
+private:
+ //------------------------------------------------------------------
+ // For ClangFunctionCaller only
+ //------------------------------------------------------------------
+
+ // Note: the parser needs to be destructed before the execution unit, so
+ // declare the execution unit first.
+ ClangFunctionCallerHelper m_type_system_helper;
+
+};
+
+} // Namespace lldb_private
+
+#endif // liblldb_ClangFunctionCaller_h_
diff --git a/lldb/source/Expression/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index e8253630724..65ee3e0ff5c 100644
--- a/lldb/source/Expression/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -9,7 +9,7 @@
#include <mutex> // std::once
-#include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "ClangModulesDeclVendor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
new file mode 100644
index 00000000000..df3b20550f9
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -0,0 +1,128 @@
+//===-- ClangModulesDeclVendor.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangModulesDeclVendor_h
+#define liblldb_ClangModulesDeclVendor_h
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/DeclVendor.h"
+#include "lldb/Target/Platform.h"
+
+#include <set>
+#include <vector>
+
+namespace lldb_private
+{
+
+class ClangModulesDeclVendor : public DeclVendor
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ClangModulesDeclVendor();
+
+ ~ClangModulesDeclVendor() override;
+
+ static ClangModulesDeclVendor *
+ Create(Target &target);
+
+ typedef std::vector<ConstString> ModulePath;
+ typedef uintptr_t ModuleID;
+ typedef std::vector<ModuleID> ModuleVector;
+
+ //------------------------------------------------------------------
+ /// Add a module to the list of modules to search.
+ ///
+ /// @param[in] path
+ /// The path to the exact module to be loaded. E.g., if the desired
+ /// module is std.io, then this should be { "std", "io" }.
+ ///
+ /// @param[in] exported_modules
+ /// If non-NULL, a pointer to a vector to populate with the ID of every
+ /// module that is re-exported by the specified module.
+ ///
+ /// @param[in] error_stream
+ /// A stream to populate with the output of the Clang parser when
+ /// it tries to load the module.
+ ///
+ /// @return
+ /// True if the module could be loaded; false if not. If the
+ /// compiler encountered a fatal error during a previous module
+ /// load, then this will always return false for this ModuleImporter.
+ //------------------------------------------------------------------
+ virtual bool
+ AddModule(ModulePath &path,
+ ModuleVector *exported_modules,
+ Stream &error_stream) = 0;
+
+ //------------------------------------------------------------------
+ /// Add all modules referred to in a given compilation unit to the list
+ /// of modules to search.
+ ///
+ /// @param[in] cu
+ /// The compilation unit to scan for imported modules.
+ ///
+ /// @param[in] exported_modules
+ /// A vector to populate with the ID of each module loaded (directly
+ /// and via re-exports) in this way.
+ ///
+ /// @param[in] error_stream
+ /// A stream to populate with the output of the Clang parser when
+ /// it tries to load the modules.
+ ///
+ /// @return
+ /// True if all modules referred to by the compilation unit could be
+ /// loaded; false if one could not be loaded. If the compiler
+ /// encountered a fatal error during a previous module
+ /// load, then this will always return false for this ModuleImporter.
+ //------------------------------------------------------------------
+ virtual bool
+ AddModulesForCompileUnit(CompileUnit &cu,
+ ModuleVector &exported_modules,
+ Stream &error_stream) = 0;
+
+ //------------------------------------------------------------------
+ /// Enumerate all the macros that are defined by a given set of modules
+ /// that are already imported.
+ ///
+ /// @param[in] modules
+ /// The unique IDs for all modules to query. Later modules have higher
+ /// priority, just as if you @imported them in that order. This matters
+ /// if module A #defines a macro and module B #undefs it.
+ ///
+ /// @param[in] handler
+ /// A function to call with the text of each #define (including the
+ /// #define directive). #undef directives are not included; we simply
+ /// elide any corresponding #define. If this function returns true,
+ /// we stop the iteration immediately.
+ //------------------------------------------------------------------
+ virtual void
+ ForEachMacro(const ModuleVector &modules,
+ std::function<bool (const std::string &)> handler) = 0;
+
+ //------------------------------------------------------------------
+ /// Query whether Clang supports modules for a particular language.
+ /// LLDB uses this to decide whether to try to find the modules loaded
+ /// by a gaiven compile unit.
+ ///
+ /// @param[in] language
+ /// The language to query for.
+ ///
+ /// @return
+ /// True if Clang has modules for the given language.
+ //------------------------------------------------------------------
+ static bool
+ LanguageSupportsClangModules (lldb::LanguageType language);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangModulesDeclVendor_h
diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 13859b81ac8..beaa1d69da3 100644
--- a/lldb/source/Expression/ClangPersistentVariables.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "ClangPersistentVariables.h"
+
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
new file mode 100644
index 00000000000..828badb9564
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -0,0 +1,91 @@
+//===-- ClangPersistentVariables.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangPersistentVariables_h_
+#define liblldb_ClangPersistentVariables_h_
+
+#include "ClangExpressionVariable.h"
+#include "ClangModulesDeclVendor.h"
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h"
+/// @brief Manages persistent values that need to be preserved between expression invocations.
+///
+/// A list of variables that can be accessed and updated by any expression. See
+/// ClangPersistentVariable for more discussion. Also provides an increasing,
+/// 0-based counter for naming result variables.
+//----------------------------------------------------------------------
+class ClangPersistentVariables : public ExpressionVariableList
+{
+public:
+
+ //----------------------------------------------------------------------
+ /// Constructor
+ //----------------------------------------------------------------------
+ ClangPersistentVariables ();
+
+ lldb::ExpressionVariableSP
+ CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp);
+
+ ClangExpressionVariable *
+ CreatePersistentVariable (ExecutionContextScope *exe_scope,
+ const ConstString &name,
+ const TypeFromUser& user_type,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size);
+
+ //----------------------------------------------------------------------
+ /// Return the next entry in the sequence of strings "$0", "$1", ... for
+ /// use naming persistent expression convenience variables.
+ ///
+ /// @return
+ /// A string that contains the next persistent variable name.
+ //----------------------------------------------------------------------
+ ConstString
+ GetNextPersistentVariableName ();
+
+ void
+ RemovePersistentVariable (lldb::ExpressionVariableSP variable);
+
+ void
+ RegisterPersistentType (const ConstString &name,
+ clang::TypeDecl *tag_decl);
+
+ clang::TypeDecl *
+ GetPersistentType (const ConstString &name);
+
+ void
+ AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
+ {
+ m_hand_loaded_clang_modules.push_back(module);
+ }
+
+ const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules()
+ {
+ return m_hand_loaded_clang_modules;
+ }
+
+private:
+ uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
+
+ typedef llvm::DenseMap<const char *, clang::TypeDecl *> PersistentTypeMap;
+ PersistentTypeMap m_persistent_types; ///< The persistent types declared by the user.
+
+ ClangModulesDeclVendor::ModuleVector m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded; these are the highest-
+ ///< priority source for macros.
+};
+
+}
+
+#endif
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index a6e5923bf28..3d86c521738 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -16,18 +16,20 @@
#include <string>
#include <map>
+#include "ClangUserExpression.h"
+
+#include "ASTResultSynthesizer.h"
+#include "ClangExpressionDeclMap.h"
+#include "ClangExpressionParser.h"
+#include "ClangModulesDeclVendor.h"
+#include "ClangPersistentVariables.h"
+
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Expression/ASTResultSynthesizer.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
-#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
-#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
new file mode 100644
index 00000000000..a2b8beda0ac
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -0,0 +1,204 @@
+//===-- ClangUserExpression.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangUserExpression_h_
+#define liblldb_ClangUserExpression_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "ASTStructExtractor.h"
+#include "ASTResultSynthesizer.h"
+#include "ClangExpressionDeclMap.h"
+#include "ClangExpressionHelper.h"
+#include "ClangExpressionVariable.h"
+#include "IRForTarget.h"
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Target/ExecutionContext.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
+/// @brief Encapsulates a single expression for use with Clang
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. ClangUserExpression encapsulates
+/// the objects needed to parse and interpret or JIT an expression. It
+/// uses the Clang parser to produce LLVM IR from the expression.
+//----------------------------------------------------------------------
+class ClangUserExpression : public UserExpression
+{
+public:
+
+ enum { kDefaultTimeout = 500000u };
+
+
+ class ClangUserExpressionHelper : public ClangExpressionHelper
+ {
+ public:
+ ClangUserExpressionHelper (Target &target) :
+ m_target(target)
+ {
+ }
+
+ ~ClangUserExpressionHelper() {}
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap *
+ DeclMap() override
+ {
+ return m_expr_decl_map_up.get();
+ }
+
+ void
+ ResetDeclMap()
+ {
+ m_expr_decl_map_up.reset();
+ }
+
+ void
+ ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override;
+ private:
+ Target &m_target;
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+ std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class that generates the argument struct layout.
+ std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
+ };
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] expr
+ /// The expression to parse.
+ ///
+ /// @param[in] expr_prefix
+ /// If non-NULL, a C string containing translation-unit level
+ /// definitions to be included when the expression is parsed.
+ ///
+ /// @param[in] language
+ /// If not eLanguageTypeUnknown, a language to use when parsing
+ /// the expression. Currently restricted to those languages
+ /// supported by Clang.
+ ///
+ /// @param[in] desired_type
+ /// If not eResultTypeAny, the type to use for the expression
+ /// result.
+ //------------------------------------------------------------------
+ ClangUserExpression (ExecutionContextScope &exe_scope,
+ const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ ResultType desired_type);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangUserExpression() override;
+
+ //------------------------------------------------------------------
+ /// Parse the expression
+ ///
+ /// @param[in] error_stream
+ /// A stream to print parse errors and warnings to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when looking up entities that
+ /// are needed for parsing (locations of functions, types of
+ /// variables, persistent variables, etc.)
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether interpretation is possible or mandatory.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// True if the resulting persistent variable should reside in
+ /// target memory, if applicable.
+ ///
+ /// @return
+ /// True on success (no errors); false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Parse (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory,
+ bool generate_debug_info) override;
+
+ ExpressionTypeSystemHelper *
+ GetTypeSystemHelper () override
+ {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *
+ DeclMap ()
+ {
+ return m_type_system_helper.DeclMap();
+ }
+
+ void
+ ResetDeclMap ()
+ {
+ m_type_system_helper.ResetDeclMap();
+ }
+
+ void
+ ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
+ {
+ m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ }
+
+private:
+ //------------------------------------------------------------------
+ /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
+ //------------------------------------------------------------------
+
+ void
+ ScanContext (ExecutionContext &exe_ctx,
+ lldb_private::Error &err) override;
+
+ bool
+ AddInitialArguments (ExecutionContext &exe_ctx,
+ std::vector<lldb::addr_t> &args,
+ Stream &error_stream) override;
+
+ ClangUserExpressionHelper m_type_system_helper;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangUserExpression_h_
diff --git a/lldb/source/Expression/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 2a07a428803..457056c64a0 100644
--- a/lldb/source/Expression/ClangUtilityFunction.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+#include "ClangExpressionDeclMap.h"
+#include "ClangExpressionParser.h"
+#include "ClangUtilityFunction.h"
+
// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
@@ -20,9 +24,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
-#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Host/Host.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
new file mode 100644
index 00000000000..37b1ebbba12
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -0,0 +1,137 @@
+//===-- ClangUtilityFunction.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangUtilityFunction_h_
+#define liblldb_ClangUtilityFunction_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
+#include "lldb/Expression/UtilityFunction.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h"
+/// @brief Encapsulates a single expression for use with Clang
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. ClangUtilityFunction encapsulates
+/// a self-contained function meant to be used from other code. Utility
+/// functions can perform error-checking for ClangUserExpressions, or can
+/// simply provide a way to push a function into the target for the debugger to
+/// call later on.
+//----------------------------------------------------------------------
+class ClangUtilityFunction : public UtilityFunction
+{
+public:
+ class ClangUtilityFunctionHelper : public ClangExpressionHelper
+ {
+ public:
+ ClangUtilityFunctionHelper ()
+ {
+ }
+
+ ~ClangUtilityFunctionHelper() override {}
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap *
+ DeclMap() override
+ {
+ return m_expr_decl_map_up.get();
+ }
+
+ void
+ ResetDeclMap()
+ {
+ m_expr_decl_map_up.reset();
+ }
+
+ void
+ ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override
+ {
+ return nullptr;
+ }
+ private:
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+ };
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] text
+ /// The text of the function. Must be a full translation unit.
+ ///
+ /// @param[in] name
+ /// The name of the function, as used in the text.
+ //------------------------------------------------------------------
+ ClangUtilityFunction (ExecutionContextScope &exe_scope,
+ const char *text,
+ const char *name);
+
+ ~ClangUtilityFunction() override;
+
+ ExpressionTypeSystemHelper *
+ GetTypeSystemHelper () override
+ {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *
+ DeclMap()
+ {
+ return m_type_system_helper.DeclMap();
+ }
+
+ void
+ ResetDeclMap ()
+ {
+ m_type_system_helper.ResetDeclMap();
+ }
+
+ void
+ ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
+ {
+ m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ }
+
+ bool
+ Install (Stream &error_stream, ExecutionContext &exe_ctx) override;
+
+private:
+ ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when parsing and materializing the expression.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangUtilityFunction_h_
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 862e6f6cfaa..862f63b2908 100644
--- a/lldb/source/Expression/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -7,7 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Expression/IRForTarget.h"
+#include "IRForTarget.h"
+
+#include "ClangExpressionDeclMap.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Constants.h"
@@ -29,7 +31,6 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/Endian.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
new file mode 100644
index 00000000000..fb4abcc103d
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -0,0 +1,745 @@
+//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IRForTarget_h_
+#define liblldb_IRForTarget_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "llvm/Pass.h"
+
+#include <map>
+#include <functional>
+
+namespace llvm {
+ class BasicBlock;
+ class CallInst;
+ class Constant;
+ class ConstantInt;
+ class Function;
+ class GlobalValue;
+ class GlobalVariable;
+ class Instruction;
+ class IntegerType;
+ class Module;
+ class StoreInst;
+ class DataLayout;
+ class Type;
+ class Value;
+}
+
+namespace lldb_private {
+ class ClangExpressionDeclMap;
+ class IRExecutionUnit;
+ class IRMemoryMap;
+}
+
+//----------------------------------------------------------------------
+/// @class IRForTarget IRForTarget.h "lldb/Expression/IRForTarget.h"
+/// @brief Transforms the IR for a function to run in the target
+///
+/// Once an expression has been parsed and converted to IR, it can run
+/// in two contexts: interpreted by LLDB as a DWARF location expression,
+/// or compiled by the JIT and inserted into the target process for
+/// execution.
+///
+/// IRForTarget makes the second possible, by applying a series of
+/// transformations to the IR which make it relocatable. These
+/// transformations are discussed in more detail next to their relevant
+/// functions.
+//----------------------------------------------------------------------
+class IRForTarget : public llvm::ModulePass
+{
+public:
+ enum class LookupResult {
+ Success,
+ Fail,
+ Ignore
+ };
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] decl_map
+ /// The list of externally-referenced variables for the expression,
+ /// for use in looking up globals and allocating the argument
+ /// struct. See the documentation for ClangExpressionDeclMap.
+ ///
+ /// @param[in] resolve_vars
+ /// True if the external variable references (including persistent
+ /// variables) should be resolved. If not, only external functions
+ /// are resolved.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether an IR interpreter can be used to statically
+ /// evaluate the expression.
+ ///
+ /// @param[in] const_result
+ /// This variable is populated with the statically-computed result
+ /// of the function, if it has no side-effects and the result can
+ /// be computed statically.
+ ///
+ /// @param[in] execution_unit
+ /// The holder for raw data associated with the expression.
+ ///
+ /// @param[in] error_stream
+ /// If non-NULL, a stream on which errors can be printed.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to prepare for execution in the target.
+ //------------------------------------------------------------------
+ IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
+ bool resolve_vars,
+ lldb_private::IRExecutionUnit &execution_unit,
+ lldb_private::Stream *error_stream,
+ const char* func_name = "$__lldb_expr");
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~IRForTarget() override;
+
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single module
+ ///
+ /// Implementation of the llvm::ModulePass::runOnModule() function.
+ ///
+ /// @param[in] llvm_module
+ /// The module to run on. This module is searched for the function
+ /// $__lldb_expr, and that function is passed to the passes one by
+ /// one.
+ ///
+ /// @param[in] interpreter_error
+ /// An error. If the expression fails to be interpreted, this error
+ /// is set to a reason why.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ runOnModule(llvm::Module &llvm_module) override;
+
+ //------------------------------------------------------------------
+ /// Interface stub
+ ///
+ /// Implementation of the llvm::ModulePass::assignPassManager()
+ /// function.
+ //------------------------------------------------------------------
+ void
+ assignPassManager(llvm::PMStack &pass_mgr_stack,
+ llvm::PassManagerType pass_mgr_type = llvm::PMT_ModulePassManager) override;
+
+ //------------------------------------------------------------------
+ /// Returns PMT_ModulePassManager
+ ///
+ /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
+ /// function.
+ //------------------------------------------------------------------
+ llvm::PassManagerType
+ getPotentialPassManagerType() const override;
+
+private:
+ //------------------------------------------------------------------
+ /// Ensures that the current function's linkage is set to external.
+ /// Otherwise the JIT may not return an address for it.
+ ///
+ /// @param[in] llvm_function
+ /// The function whose linkage is to be fixed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ FixFunctionLinkage (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to replace all function pointers with their
+ /// integer equivalents.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_module
+ /// The module currently being processed.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ HasSideEffects (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to check whether the function has side
+ /// effects.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Get the address of a function, and a location to put the complete
+ /// Value of the function if one is available.
+ ///
+ /// @param[in] function
+ /// The function to find the location of.
+ ///
+ /// @param[out] ptr
+ /// The location of the function in the target.
+ ///
+ /// @param[out] name
+ /// The resolved name of the function (matters for intrinsics).
+ ///
+ /// @param[out] value_ptr
+ /// A variable to put the function's completed Value* in, or NULL
+ /// if the Value* shouldn't be stored anywhere.
+ ///
+ /// @return
+ /// The pointer.
+ //------------------------------------------------------------------
+ LookupResult
+ GetFunctionAddress (llvm::Function *function,
+ uint64_t &ptr,
+ lldb_private::ConstString &name,
+ llvm::Constant **&value_ptr);
+
+ //------------------------------------------------------------------
+ /// Build a function pointer given a type and a raw pointer.
+ ///
+ /// @param[in] type
+ /// The type of the function pointer to be built.
+ ///
+ /// @param[in] ptr
+ /// The value of the pointer.
+ ///
+ /// @return
+ /// The pointer.
+ //------------------------------------------------------------------
+ llvm::Constant *
+ BuildFunctionPointer (llvm::Type *type,
+ uint64_t ptr);
+
+ void
+ RegisterFunctionMetadata (llvm::LLVMContext &context,
+ llvm::Value *function_ptr,
+ const char *name);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True if the function has side effects (or if this cannot
+ /// be determined); false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveFunctionPointers (llvm::Module &llvm_module);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to take the generated global value
+ /// $__lldb_expr_result and make it into a persistent variable.
+ /// Also see ASTResultSynthesizer.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Find the NamedDecl corresponding to a Value. This interface is
+ /// exposed for the IR interpreter.
+ ///
+ /// @param[in] module
+ /// The module containing metadata to search
+ ///
+ /// @param[in] global
+ /// The global entity to search for
+ ///
+ /// @return
+ /// The corresponding variable declaration
+ //------------------------------------------------------------------
+public:
+ static clang::NamedDecl *
+ DeclForGlobal (const llvm::GlobalValue *global_val, llvm::Module *module);
+private:
+ clang::NamedDecl *
+ DeclForGlobal (llvm::GlobalValue *global);
+
+ //------------------------------------------------------------------
+ /// Set the constant result variable m_const_result to the provided
+ /// constant, assuming it can be evaluated. The result variable
+ /// will be reset to NULL later if the expression has side effects.
+ ///
+ /// @param[in] initializer
+ /// The constant initializer for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the result variable.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void
+ MaybeSetConstantResult (llvm::Constant *initializer,
+ const lldb_private::ConstString &name,
+ lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// If the IR represents a cast of a variable, set m_const_result
+ /// to the result of the cast. The result variable will be reset to
+ /// NULL latger if the expression has side effects.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void
+ MaybeSetCastResult (lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ CreateResultVariable (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to find Objective-C constant strings and
+ /// transform them to calls to CFStringCreateWithBytes.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a single Objective-C constant string.
+ ///
+ /// @param[in] NSStr
+ /// The constant NSString to be transformed
+ ///
+ /// @param[in] CStr
+ /// The constant C string inside the NSString. This will be
+ /// passed as the bytes argument to CFStringCreateWithBytes.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCConstString (llvm::GlobalVariable *NSStr,
+ llvm::GlobalVariable *CStr);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCConstStrings ();
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all Objective-C method calls and
+ /// rewrite them to use sel_registerName instead of statically allocated
+ /// selectors. The reason is that the selectors are created on the
+ /// assumption that the Objective-C runtime will scan the appropriate
+ /// section and prepare them. This doesn't happen when code is copied
+ /// into the target, though, and there's no easy way to induce the
+ /// runtime to scan them. So instead we get our selectors from
+ /// sel_registerName.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Replace a single selector reference
+ ///
+ /// @param[in] selector_load
+ /// The load of the statically-allocated selector.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCSelector (llvm::Instruction* selector_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCSelectors (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all newly-declared persistent
+ /// variables and register them with the ClangExprDeclMap. This
+ /// allows them to be materialized and dematerialized like normal
+ /// external variables. Before transformation, these persistent
+ /// variables look like normal locals, so they have an allocation.
+ /// This pass excises these allocations and makes references look
+ /// like external references where they will be resolved -- like all
+ /// other external references -- by ResolveExternals().
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Handle a single allocation of a persistent variable
+ ///
+ /// @param[in] persistent_alloc
+ /// The allocation of the persistent variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewritePersistentAlloc (llvm::Instruction *persistent_alloc);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ //------------------------------------------------------------------
+ bool
+ RewritePersistentAllocs (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to find all external variables and functions
+ /// used in the IR. Each found external variable is added to the
+ /// struct, and each external function is resolved in place, its call
+ /// replaced with a call to a function pointer whose value is the
+ /// address of the function in the target process.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Write an initializer to a memory array of assumed sufficient
+ /// size.
+ ///
+ /// @param[in] data
+ /// A pointer to the data to write to.
+ ///
+ /// @param[in] initializer
+ /// The initializer itself.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaterializeInitializer (uint8_t *data, llvm::Constant *initializer);
+
+ //------------------------------------------------------------------
+ /// Move an internal variable into the static allocation section.
+ ///
+ /// @param[in] global_variable
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaterializeInternalVariable (llvm::GlobalVariable *global_variable);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined variable
+ ///
+ /// @param[in] value
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaybeHandleVariable (llvm::Value *value);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined symbol
+ ///
+ /// @param[in] symbol
+ /// The symbol.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ HandleSymbol (llvm::Value *symbol);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined Objective-C class
+ ///
+ /// @param[in] classlist_reference
+ /// The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
+ /// where n (if present) is an index.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ HandleObjCClass(llvm::Value *classlist_reference);
+
+ //------------------------------------------------------------------
+ /// Handle all the arguments to a function call
+ ///
+ /// @param[in] C
+ /// The call instruction.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaybeHandleCallArguments (llvm::CallInst *call_inst);
+
+ //------------------------------------------------------------------
+ /// Resolve variable references in calls to external functions
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ResolveCalls (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// Remove calls to __cxa_atexit, which should never be generated by
+ /// expressions.
+ ///
+ /// @param[in] call_inst
+ /// The call instruction.
+ ///
+ /// @return
+ /// True if the scan was successful; false if some operation
+ /// failed
+ //------------------------------------------------------------------
+ bool
+ RemoveCXAAtExit (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ResolveExternals (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to excise guard variables from the code.
+ /// The result for the function is passed through Clang as a static
+ /// variable. Static variables normally have guard variables to
+ /// ensure that they are only initialized once.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a load to a guard variable to return constant 0.
+ ///
+ /// @param[in] guard_load
+ /// The load instruction to zero out.
+ //------------------------------------------------------------------
+ void
+ TurnGuardLoadIntoZero(llvm::Instruction* guard_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RemoveGuards (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to allocate all string literals in a separate
+ /// allocation and redirect references to them.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ReplaceStrings ();
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all literals that will be
+ /// allocated as statics by the JIT (in contrast to the Strings,
+ /// which already are statics) and synthesize loads for them.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ReplaceStaticLiterals (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to make all external variable references
+ /// point at the correct offsets from the void* passed into the
+ /// function. ClangExpressionDeclMap::DoStructLayout() must be called
+ /// beforehand, so that the offsets are valid.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ReplaceVariables (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to remove all global variables from the
+ /// module since it no longer should export or import any symbols.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_module
+ /// The module currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ StripAllGVs (llvm::Module &llvm_module);
+
+ class StaticDataAllocator {
+ public:
+ StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit);
+ lldb_private::StreamString &GetStream()
+ {
+ return m_stream_string;
+ }
+ lldb::addr_t Allocate();
+
+ lldb::TargetSP
+ GetTarget();
+ private:
+ lldb_private::IRExecutionUnit &m_execution_unit;
+ lldb_private::StreamString m_stream_string;
+ lldb::addr_t m_allocation;
+ };
+
+ /// Flags
+ bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
+ std::string m_func_name; ///< The name of the function to translate
+ lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
+ lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
+ llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
+ std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
+ lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
+ StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings
+ llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type
+ llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type
+ llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
+ lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed
+
+ llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL.
+ bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in ASTResultSynthesizer::SynthesizeBodyResult)
+
+ llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final location of the static allocation.
+
+ //------------------------------------------------------------------
+ /// UnfoldConstant operates on a constant [Old] which has just been
+ /// replaced with a value [New]. We assume that new_value has
+ /// been properly placed early in the function, in front of the
+ /// first instruction in the entry basic block
+ /// [FirstEntryInstruction].
+ ///
+ /// UnfoldConstant reads through the uses of Old and replaces Old
+ /// in those uses with New. Where those uses are constants, the
+ /// function generates new instructions to compute the result of the
+ /// new, non-constant expression and places them before
+ /// FirstEntryInstruction. These instructions replace the constant
+ /// uses, so UnfoldConstant calls itself recursively for those.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+
+ class FunctionValueCache {
+ public:
+ typedef std::function <llvm::Value *(llvm::Function *)> Maker;
+
+ FunctionValueCache (Maker const &maker);
+ ~FunctionValueCache ();
+ llvm::Value *GetValue (llvm::Function *function);
+ private:
+ Maker const m_maker;
+ typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
+ FunctionValueMap m_values;
+ };
+
+ FunctionValueCache m_entry_instruction_finder;
+
+ static bool
+ UnfoldConstant (llvm::Constant *old_constant,
+ FunctionValueCache &value_maker,
+ FunctionValueCache &entry_instruction_finder);
+
+ //------------------------------------------------------------------
+ /// Construct a reference to m_reloc_placeholder with a given type
+ /// and offset. This typically happens after inserting data into
+ /// m_data_allocator.
+ ///
+ /// @param[in] type
+ /// The type of the value being loaded.
+ ///
+ /// @param[in] offset
+ /// The offset of the value from the base of m_data_allocator.
+ ///
+ /// @return
+ /// The Constant for the reference, usually a ConstantExpr.
+ //------------------------------------------------------------------
+ llvm::Constant *
+ BuildRelocation(llvm::Type *type,
+ uint64_t offset);
+
+ //------------------------------------------------------------------
+ /// Commit the allocation in m_data_allocator and use its final
+ /// location to replace m_reloc_placeholder.
+ ///
+ /// @param[in] module
+ /// The module that m_data_allocator resides in
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ CompleteDataAllocation ();
+
+};
+
+#endif // liblldb_IRForTarget_h_
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 23ac29ebe80..cd6ece297ed 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -11,7 +11,7 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
-#include "lldb/Expression/ASTDumper.h"
+#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 4db11b26845..34a2d4b3930 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -25,7 +25,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index d3195edffb9..7f6cf3fa42e 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -70,12 +70,9 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "lldb/Expression/ASTDumper.h"
-#include "lldb/Expression/ASTResultSynthesizer.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
-#include "lldb/Expression/ClangUserExpression.h"
-#include "lldb/Expression/ClangFunctionCaller.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
diff --git a/lldb/source/Target/ABI.cpp b/lldb/source/Target/ABI.cpp
index f5df97c9c50..aab4bd31a03 100644
--- a/lldb/source/Target/ABI.cpp
+++ b/lldb/source/Target/ABI.cpp
@@ -11,7 +11,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index dc478bb08c1..1ba10f41c38 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -31,10 +31,10 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
-#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Expression/UserExpression.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/CommandInterpreter.h"
OpenPOWER on IntegriCloud