Some name-lookup-related fixes, from Piotr Rak!

- Changes Lookup*Name functions to return NamedDecls, instead of
Decls. Unfortunately my recent statement that it will simplify lot of
code, was not quite right, but it simplifies some...
- Makes MergeLookupResult SmallPtrSet instead of vector, following
Douglas suggestions.
- Adds %qN format for printing qualified names to Diagnostic.
- Avoids searching for using-directives in Scopes, which are not
DeclScope, during unqualified name lookup.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63739 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 6bc02e0..b95ff3e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/IdentifierTable.h"
+#include <vector>
 
 using namespace clang;
 
@@ -144,6 +145,41 @@
 // NamedDecl Implementation
 //===----------------------------------------------------------------------===//
 
+std::string NamedDecl::getQualifiedNameAsString() const {
+  std::vector<std::string> Names;
+  std::string QualName;
+  const DeclContext *Ctx = getDeclContext();
+
+  if (Ctx->isFunctionOrMethod())
+    return getNameAsString();
+
+  while (Ctx) {
+    if (Ctx->isFunctionOrMethod())
+      // FIXME: That probably will happen, when D was member of local
+      // scope class/struct/union. How do we handle this case?
+      break;
+
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
+      Names.push_back(ND->getNameAsString());
+    else
+      break;
+
+    Ctx = Ctx->getParent();
+  }
+
+  std::vector<std::string>::reverse_iterator
+    I = Names.rbegin(),
+    End = Names.rend();
+
+  for (; I!=End; ++I)
+    QualName += *I + "::";
+
+  QualName += getNameAsString();
+
+  return QualName;
+}
+
+
 bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
   assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");