diff options
| author | Sean Callanan <scallanan@apple.com> | 2010-09-14 21:59:34 +0000 |
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2010-09-14 21:59:34 +0000 |
| commit | 44096b1a7e04ef2aa2e24db9360b843bff88a33c (patch) | |
| tree | f3134d39a9b9c0c84e57efdd11305f1f3f358471 | |
| parent | 86ac3fc9af774b49ed51a446830e5c4382bc8199 (diff) | |
| download | bcm5719-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.h | 11 | ||||
| -rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 27 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 13 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 69 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 8 |
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()); |

