evgeny777 created this revision. evgeny777 added reviewers: clayborg, paulherman. evgeny777 added subscribers: lldb-commits, KLapshin.
Current revision contains bug, related to evaluation of global variables. Imagine you have the following code ``` int _g = 1; int func(void) { int _g = 2; return _g; // BP here and evaluate ::_g } ``` evaluation of ::_g will return 2, while the correct value is 1 Another example: ``` namespace test { int test_var = 1; } int test_var = 2; int func(void) { using namespace test; return ::test_var; // BP here and try to evaluate ::test_var } ``` Evaluation will return error (multiple candidates), while correct behaviour is to return '2' http://reviews.llvm.org/D13350 Files: clang/include/clang/AST/DeclBase.h clang/lib/Sema/SemaLookup.cpp lldb/include/lldb/Symbol/ClangASTContext.h lldb/include/lldb/Symbol/CompilerDeclContext.h lldb/include/lldb/Symbol/TypeSystem.h lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp lldb/source/Symbol/ClangASTContext.cpp lldb/source/Symbol/CompilerDeclContext.cpp
Index: lldb/source/Symbol/CompilerDeclContext.cpp =================================================================== --- lldb/source/Symbol/CompilerDeclContext.cpp +++ lldb/source/Symbol/CompilerDeclContext.cpp @@ -15,12 +15,13 @@ using namespace lldb_private; std::vector<CompilerDecl> -CompilerDeclContext::FindDeclByName (ConstString name) +CompilerDeclContext::FindDeclByName (ConstString name, const clang::DeclContext* lookupCtx) { std::vector<CompilerDecl> found_decls; if (IsValid()) { - std::vector<void *> found_opaque_decls = m_type_system->DeclContextFindDeclByName(m_opaque_decl_ctx, name); + std::vector<void *> found_opaque_decls = + m_type_system->DeclContextFindDeclByNameEx(m_opaque_decl_ctx, name, (void*)lookupCtx); for (void *opaque_decl : found_opaque_decls) found_decls.push_back(CompilerDecl(m_type_system, opaque_decl)); } Index: lldb/source/Symbol/ClangASTContext.cpp =================================================================== --- lldb/source/Symbol/ClangASTContext.cpp +++ lldb/source/Symbol/ClangASTContext.cpp @@ -8975,9 +8975,24 @@ // CompilerDeclContext functions //---------------------------------------------------------------------- +static inline bool +NamedDeclDoesQualify (NamedDecl* nd, const DeclContext* lookupCtx) +{ + if(lookupCtx == nullptr || lookupCtx->shouldUseQualifiedLookup() == false) + return true; + return nd->getLexicalDeclContext()->getDeclKind() == lookupCtx->getDeclKind(); +} + std::vector<void *> ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name) { + return DeclContextFindDeclByNameEx(opaque_decl_ctx, name, nullptr); +} + +std::vector<void *> +ClangASTContext::DeclContextFindDeclByNameEx (void *opaque_decl_ctx, ConstString name, void* extra) +{ + const DeclContext* lookupCtx = (const DeclContext*)(extra); std::vector<void *> found_decls; if (opaque_decl_ctx) { @@ -9011,16 +9026,24 @@ if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target)) { IdentifierInfo *ii = nd->getIdentifier(); - if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr))) + if (ii != nullptr && + ii->getName().equals(name.AsCString(nullptr)) && + NamedDeclDoesQualify(nd, lookupCtx)) + { found_decls.push_back(nd); + } } } } else if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(child)) { IdentifierInfo *ii = nd->getIdentifier(); - if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr))) + if (ii != nullptr && + ii->getName().equals(name.AsCString(nullptr)) && + NamedDeclDoesQualify(nd, lookupCtx)) + { found_decls.push_back(nd); + } } } } Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -1366,7 +1366,8 @@ vars->GetVariableAtIndex(i)->GetDecl(); // Search for declarations matching the name - std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name); + std::vector<CompilerDecl> found_decls = + compiler_decl_context.FindDeclByName(name, context.m_decl_context); bool variable_found = false; for (CompilerDecl decl : found_decls) Index: lldb/include/lldb/Symbol/TypeSystem.h =================================================================== --- lldb/include/lldb/Symbol/TypeSystem.h +++ lldb/include/lldb/Symbol/TypeSystem.h @@ -118,6 +118,14 @@ virtual std::vector<void *> DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name) = 0; + // extra is language dependant + virtual std::vector<void *> + DeclContextFindDeclByNameEx (void *opaque_decl_ctx, ConstString name, void* extra) + { + // By default fall back to old one + return DeclContextFindDeclByName(opaque_decl_ctx, name); + } + virtual bool DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) = 0; Index: lldb/include/lldb/Symbol/CompilerDeclContext.h =================================================================== --- lldb/include/lldb/Symbol/CompilerDeclContext.h +++ lldb/include/lldb/Symbol/CompilerDeclContext.h @@ -14,6 +14,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" +#include "clang/AST/DeclBase.h" namespace lldb_private { @@ -66,7 +67,7 @@ IsClang () const; std::vector<CompilerDecl> - FindDeclByName (ConstString name); + FindDeclByName (ConstString name, const clang::DeclContext* lookupCtx); //---------------------------------------------------------------------- /// Checks if this decl context represents a method of a class. Index: lldb/include/lldb/Symbol/ClangASTContext.h =================================================================== --- lldb/include/lldb/Symbol/ClangASTContext.h +++ lldb/include/lldb/Symbol/ClangASTContext.h @@ -536,6 +536,9 @@ std::vector<void *> DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name) override; + std::vector<void *> + DeclContextFindDeclByNameEx (void *opaque_decl_ctx, ConstString name, void* extra) override; + bool DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) override; Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -204,6 +204,13 @@ UnqualUsingEntry::Comparator())); } }; + + class Deinitializer { + std::function<void()> Deinit; + public: + Deinitializer(const std::function<void()>& d): Deinit(d) {} + ~Deinitializer() { Deinit(); } + }; } // Retrieve the set of identifier namespaces that correspond to a @@ -1852,6 +1859,9 @@ "Declaration context must already be complete!"); // Perform qualified name lookup into the LookupCtx. + bool oldval = LookupCtx->setUseQualifiedLookup(); + Deinitializer deinit([&]() { LookupCtx->setUseQualifiedLookup(oldval); }); + if (LookupDirect(*this, R, LookupCtx)) { R.resolveKind(); if (isa<CXXRecordDecl>(LookupCtx)) Index: clang/include/clang/AST/DeclBase.h =================================================================== --- clang/include/clang/AST/DeclBase.h +++ clang/include/clang/AST/DeclBase.h @@ -1142,6 +1142,11 @@ /// that are missing from the lookup table. mutable bool HasLazyExternalLexicalLookups : 1; + /// \brief If \c true, lookups should only return identifier from + /// DeclContext scope (for example TranslationUnit). Used in + /// LookupQualifiedName() + mutable bool UseQualifiedLookup : 1; + /// \brief Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a /// dependent context). We maintain the invariant that, if the map @@ -1176,6 +1181,7 @@ ExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), + UseQualifiedLookup(false), LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {} public: @@ -1756,6 +1762,16 @@ D == LastDecl); } + bool setUseQualifiedLookup(bool use = true) { + bool old_value = UseQualifiedLookup; + UseQualifiedLookup = use; + return old_value; + } + + bool shouldUseQualifiedLookup() const { + return UseQualifiedLookup; + } + static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits