summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2010-09-14 21:59:34 +0000
committerSean Callanan <scallanan@apple.com>2010-09-14 21:59:34 +0000
commit44096b1a7e04ef2aa2e24db9360b843bff88a33c (patch)
treef3134d39a9b9c0c84e57efdd11305f1f3f358471
parent86ac3fc9af774b49ed51a446830e5c4382bc8199 (diff)
downloadbcm5719-llvm-44096b1a7e04ef2aa2e24db9360b843bff88a33c.tar.gz
bcm5719-llvm-44096b1a7e04ef2aa2e24db9360b843bff88a33c.zip
Added code to support use of "this" and "self" in
expressions. This involved three main changes: - In ClangUserExpression::ClangUserExpression(), we now insert the following lines into the expression: #define this ___clang_this #define self ___clang_self - In ClangExpressionDeclMap::GetDecls(), we special-case ___clang_(this|self) and instead look up "this" or "self" - In ClangASTSource, we introduce the capability to generate Decls with a different, overridden, name from the one that was requested, e.g. this for ___clang_this. llvm-svn: 113866
-rw-r--r--lldb/include/lldb/Expression/ClangASTSource.h11
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h27
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp13
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp69
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp8
5 files changed, 106 insertions, 22 deletions
diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h
index d9ea2a23360..4a6f2a522ba 100644
--- a/lldb/include/lldb/Expression/ClangASTSource.h
+++ b/lldb/include/lldb/Expression/ClangASTSource.h
@@ -161,8 +161,15 @@ struct NameSearchContext {
///
/// @param[in] type
/// The opaque QualType for the VarDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddVarDecl(void *type);
+ ///
+ /// @param[in] override_name
+ /// In some cases, the name needs to be overridden (such as when
+ /// searching for ___clang_this, which should resolve to this).
+ /// This is the name to be used instead of what is being searched
+ /// for.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddVarDecl(void *type,
+ const char *override_name = NULL);
//------------------------------------------------------------------
/// Create a FunDecl with the name being searched for and the provided
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
index 7c85857f753..82f2c818f47 100644
--- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
+++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -342,14 +342,13 @@ private:
std::string m_result_name; ///< The name of the result variable ($1, for example)
//------------------------------------------------------------------
- /// Given a symbol context, find a variable that matches the given
- /// name and type. We need this for expression re-use; we may not
- /// always get the same lldb::Variable back, and we want the expression
- /// to work wherever it can. Returns the variable defined in the
- /// tightest scope.
+ /// Given a stack frame, find a variable that matches the given name and
+ /// type. We need this for expression re-use; we may not always get the
+ /// same lldb::Variable back, and we want the expression to work wherever
+ /// it can. Returns the variable defined in the tightest scope.
///
- /// @param[in] sym_ctx
- /// The SymbolContext to search for the variable.
+ /// @param[in] frame
+ /// The stack frame to use as a basis for finding the variable.
///
/// @param[in] name
/// The name as a plain C string.
@@ -362,9 +361,15 @@ private:
/// @return
/// The LLDB Variable found, or NULL if none was found.
//------------------------------------------------------------------
+#ifdef OLD_CODE
Variable *FindVariableInScope(const SymbolContext &sym_ctx,
const char *name,
TypeFromUser *type = NULL);
+#endif
+
+ Variable *FindVariableInScope(StackFrame &frame,
+ const char *name,
+ TypeFromUser *type = NULL);
//------------------------------------------------------------------
/// Get the value of a variable in a given execution context and return
@@ -410,8 +415,14 @@ private:
///
/// @param[in] var
/// The LLDB Variable that needs a Decl.
+ ///
+ /// @param[in] override_name
+ /// A new name to give the Decl, if the one being looked for needs
+ /// to be overriden. Example: this for ___clang_this.
//------------------------------------------------------------------
- void AddOneVariable(NameSearchContext &context, Variable *var);
+ void AddOneVariable(NameSearchContext &context,
+ Variable *var,
+ const char *override_name);
//------------------------------------------------------------------
/// Use the NameSearchContext to generate a Decl for the given
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp
index 7176cbef76f..299524b144f 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Expression/ClangASTSource.cpp
@@ -85,11 +85,20 @@ clang::ASTContext *NameSearchContext::GetASTContext() {
return &ASTSource.Context;
}
-clang::NamedDecl *NameSearchContext::AddVarDecl(void *type) {
+clang::NamedDecl *NameSearchContext::AddVarDecl(void *type,
+ const char *override_name) {
+ IdentifierInfo *ii = NULL;
+
+ if (override_name)
+ ii = &ASTSource.Context.Idents.get(override_name);
+ else
+ ii = Name.getAsIdentifierInfo();
+
+
clang::NamedDecl *Decl = VarDecl::Create(ASTSource.Context,
const_cast<DeclContext*>(DC),
SourceLocation(),
- Name.getAsIdentifierInfo(),
+ ii,
QualType::getFromOpaquePtr(type),
0,
VarDecl::Static,
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index e3e5d9467f4..3846a7f7392 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -539,7 +539,10 @@ ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
- Variable *var = FindVariableInScope(sym_ctx, name, &type);
+ if (!exe_ctx.frame)
+ return false;
+
+ Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
if (!var)
{
@@ -612,6 +615,7 @@ ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
return true;
}
+#ifdef OLD_CODE
Variable*
ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
const char *name,
@@ -715,6 +719,43 @@ ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
return NULL;
}
+#endif
+
+Variable *
+ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
+ const char *name,
+ TypeFromUser *type)
+{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+ ConstString name_cs(name);
+
+ VariableList *var_list = frame.GetVariableList(true);
+
+ lldb::VariableSP var = var_list->FindVariable(name_cs);
+
+ if (!var)
+ return NULL;
+
+ if (!type)
+ return var.get();
+
+ if (type->GetASTContext() == var->GetType()->GetClangAST())
+ {
+ if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
+ return NULL;
+ }
+ else
+ {
+ if (log)
+ log->PutCString("Skipping a candidate variable because of different AST contexts");
+ return NULL;
+ }
+
+ return var.get();
+
+ return NULL;
+}
// Interface for ClangASTSource
void
@@ -723,14 +764,23 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+ const char* override_name = NULL;
+
+ if (!strcmp(name, "___clang_this"))
+ override_name = "this";
+ if (!strcmp(name, "___clang_self"))
+ override_name = "self";
+
+ const char *search_name = (override_name ? override_name : name);
+
if (log)
- log->Printf("Hunting for a definition for %s", name);
+ log->Printf("Hunting for a definition for %s", search_name);
// Back out in all cases where we're not fully initialized
if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
return;
-
- ConstString name_cs(name);
+
+ ConstString name_cs(search_name);
SymbolContextList sym_ctxs;
m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
@@ -763,10 +813,10 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
}
}
- Variable *var = FindVariableInScope(*m_sym_ctx, name);
+ Variable *var = FindVariableInScope(*m_exe_ctx->frame, search_name);
if (var)
- AddOneVariable(context, var);
+ AddOneVariable(context, var, override_name);
ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
@@ -893,7 +943,8 @@ ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
void
ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
- Variable* var)
+ Variable* var,
+ const char *override_name)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
@@ -906,10 +957,10 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
&ut,
&pt);
- NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
+ NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType(), override_name);
ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
- entity.m_name = context.Name.getAsString();
+ entity.m_name = (override_name ? override_name : context.Name.getAsString());
entity.m_user_type = ut;
entity.EnableParserVars();
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 4e49c4875a2..6b376560218 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -38,7 +38,13 @@ ClangUserExpression::ClangUserExpression (const char *expr) :
{
StreamString m_transformed_stream;
- m_transformed_stream.Printf("extern \"C\" void %s(void *___clang_arg) { %s; }\n",
+ m_transformed_stream.Printf("#define this ___clang_this \n"
+ "#define self ___clang_self \n"
+ "extern \"C\" void \n"
+ "%s(void *___clang_arg) \n"
+ "{ \n"
+ "%s; \n"
+ "} \n",
FunctionName(),
m_expr_text.c_str());
OpenPOWER on IntegriCloud