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

Reply via email to