CarlosAlbertoEnciso updated this revision to Diff 154091.
CarlosAlbertoEnciso added a comment.

Update the patch to address the comments from the reviewers.


https://reviews.llvm.org/D46190

Files:
  include/clang/Sema/Lookup.h
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaInternal.h
  lib/Sema/SemaCXXScopeSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  test/PCH/cxx-templates.cpp
  test/SemaCXX/referenced_alias_declaration_1.cpp
  test/SemaCXX/referenced_alias_declaration_2.cpp
  test/SemaCXX/referenced_using_all.cpp
  test/SemaCXX/referenced_using_declaration_1.cpp
  test/SemaCXX/referenced_using_declaration_2.cpp
  test/SemaCXX/referenced_using_directive.cpp

Index: test/SemaCXX/referenced_using_directive.cpp
===================================================================
--- test/SemaCXX/referenced_using_directive.cpp
+++ test/SemaCXX/referenced_using_directive.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+namespace N {
+  typedef int Integer;
+  int var;
+}
+
+void Fa() {
+  using namespace N;  // Referenced
+  var = 1;
+}
+
+void Fb() {
+  using namespace N;
+  N::var = 1;
+}
+
+void Fc() {
+  using namespace N;  // Referenced
+  Integer var = 1;
+}
+
+void Fd() {
+  using namespace N;
+  N::Integer var = 1;
+}
+
+//CHECK:      |-FunctionDecl {{.*}} Fa 'void ()'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-UsingDirectiveDecl {{.*}} referenced Namespace {{.*}} 'N'
+//CHECK-NEXT: |   `-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT: |     |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int'
+//CHECK-NEXT: |     `-IntegerLiteral {{.*}} 'int' 1
+//CHECK-NEXT: |-FunctionDecl {{.*}} Fb 'void ()'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-UsingDirectiveDecl {{.*}} Namespace {{.*}} 'N'
+//CHECK-NEXT: |   `-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT: |     |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int'
+//CHECK-NEXT: |     `-IntegerLiteral {{.*}} 'int' 1
+//CHECK-NEXT: |-FunctionDecl {{.*}} Fc 'void ()'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-UsingDirectiveDecl {{.*}} referenced Namespace {{.*}} 'N'
+//CHECK-NEXT: |   `-DeclStmt {{.*}}
+//CHECK-NEXT: |     `-VarDecl {{.*}} var 'N::Integer':'int' cinit
+//CHECK-NEXT: |       `-IntegerLiteral {{.*}} 'int' 1
+//CHECK-NEXT: `-FunctionDecl {{.*}} Fd 'void ()'
+//CHECK-NEXT:   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDirectiveDecl {{.*}} Namespace {{.*}} 'N'
+//CHECK-NEXT:     `-DeclStmt {{.*}}
+//CHECK-NEXT:       `-VarDecl {{.*}} var 'N::Integer':'int' cinit
+//CHECK-NEXT:         `-IntegerLiteral {{.*}} 'int' 1
Index: test/SemaCXX/referenced_using_declaration_2.cpp
===================================================================
--- test/SemaCXX/referenced_using_declaration_2.cpp
+++ test/SemaCXX/referenced_using_declaration_2.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+namespace N {
+  typedef int Integer;
+  typedef char Char;
+}
+
+using N::Integer;
+using N::Char;      // Referenced
+
+void Foo(int p1, N::Integer p2, Char p3) {
+  N::Integer var;
+  var = 0;
+}
+
+using N::Integer;   // Referenced
+Integer Bar() {
+  using N::Char;
+  return 0;
+}
+
+//CHECK:      |-UsingDecl {{.*}} N::Integer
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Typedef {{.*}} 'Integer'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'N::Integer' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Integer'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'int'
+//CHECK-NEXT: |-UsingDecl {{.*}} referenced N::Char
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit referenced Typedef {{.*}} 'Char'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'N::Char' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Char'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'char'
+//CHECK-NEXT: |-FunctionDecl {{.*}} Foo 'void (int, N::Integer, N::Char)'
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} p1 'int'
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} p2 'N::Integer':'int'
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} p3 'N::Char':'char'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-VarDecl {{.*}} used var 'N::Integer':'int'
+//CHECK-NEXT: |   `-BinaryOperator {{.*}} 'N::Integer':'int' lvalue '='
+//CHECK-NEXT: |     |-DeclRefExpr {{.*}} 'N::Integer':'int' lvalue Var {{.*}} 'var' 'N::Integer':'int'
+//CHECK-NEXT: |     `-IntegerLiteral {{.*}} 'int' 0
+//CHECK-NEXT: |-UsingDecl {{.*}} referenced N::Integer
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit referenced Typedef {{.*}} 'Integer'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'N::Integer' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Integer'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'int'
+//CHECK-NEXT: `-FunctionDecl {{.*}} Bar 'N::Integer ()'
+//CHECK-NEXT:   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} N::Char
+//CHECK-NEXT:     `-ReturnStmt {{.*}}
+//CHECK-NEXT:       `-IntegerLiteral {{.*}} 'int' 0
Index: test/SemaCXX/referenced_using_declaration_1.cpp
===================================================================
--- test/SemaCXX/referenced_using_declaration_1.cpp
+++ test/SemaCXX/referenced_using_declaration_1.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+namespace N {
+  // Types.
+  typedef int Integer;
+  struct Record {
+    int a;
+  };
+
+  // Variables.
+  int var1;
+  int var2;
+
+  // Functions.
+  void func1();
+  void func2();
+}
+
+using N::Integer;
+using N::Record;
+using N::var1;
+using N::var2;
+using N::func1;
+using N::func2;
+
+void Foo() {
+  using N::Integer;
+  N::Integer int_var;
+  int_var = 1;
+
+  using N::Record;  // Referenced
+  Record rec_var;
+  rec_var.a = 2;
+
+  using N::var1;
+  N::var1 = 3;
+
+  using N::var2;    // Referenced
+  var2 = 4;
+
+  using N::func1;
+  N::func1();
+
+  using N::func2;   // Referenced
+  func2();
+}
+
+//CHECK:      |-UsingDecl {{.*}} N::Integer
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Typedef {{.*}} 'Integer'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'N::Integer' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Integer'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'int'
+//CHECK-NEXT: |-UsingDecl {{.*}} N::Record
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit CXXRecord {{.*}} 'Record'
+//CHECK-NEXT: | `-RecordType {{.*}} 'N::Record'
+//CHECK-NEXT: |   `-CXXRecord {{.*}} 'Record'
+//CHECK-NEXT: |-UsingDecl {{.*}} N::var1
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Var {{.*}} 'var1' 'int'
+//CHECK-NEXT: |-UsingDecl {{.*}} N::var2
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Var {{.*}} 'var2' 'int'
+//CHECK-NEXT: |-UsingDecl {{.*}} N::func1
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Function {{.*}} 'func1' 'void ()'
+//CHECK-NEXT: |-UsingDecl {{.*}} N::func2
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Function {{.*}} 'func2' 'void ()'
+//CHECK-NEXT: `-FunctionDecl {{.*}} Foo 'void ()'
+//CHECK-NEXT:   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} N::Integer
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-VarDecl {{.*}} used int_var 'N::Integer':'int'
+//CHECK-NEXT:     |-BinaryOperator {{.*}} 'N::Integer':'int' lvalue '='
+//CHECK-NEXT:     | |-DeclRefExpr {{.*}} 'N::Integer':'int' lvalue Var {{.*}} 'int_var' 'N::Integer':'int'
+//CHECK-NEXT:     | `-IntegerLiteral {{.*}} 'int' 1
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} referenced N::Record
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-VarDecl {{.*}} used rec_var 'N::Record' callinit
+//CHECK-NEXT:     |   `-CXXConstructExpr {{.*}} 'N::Record' 'void () noexcept'
+//CHECK-NEXT:     |-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT:     | |-MemberExpr {{.*}} 'int' lvalue .a {{.*}}
+//CHECK-NEXT:     | | `-DeclRefExpr {{.*}} 'N::Record' lvalue Var {{.*}} 'rec_var' 'N::Record'
+//CHECK-NEXT:     | `-IntegerLiteral {{.*}} 'int' 2
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} N::var1
+//CHECK-NEXT:     |-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT:     | |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var1' 'int'
+//CHECK-NEXT:     | `-IntegerLiteral {{.*}} 'int' 3
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} referenced N::var2
+//CHECK-NEXT:     |-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT:     | |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var2' 'int' (UsingShadow {{.*}} 'var2')
+//CHECK-NEXT:     | `-IntegerLiteral {{.*}} 'int' 4
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} N::func1
+//CHECK-NEXT:     |-CallExpr {{.*}} 'void'
+//CHECK-NEXT:     | `-ImplicitCastExpr {{.*}} 'void (*)()' <FunctionToPointerDecay>
+//CHECK-NEXT:     |   `-DeclRefExpr {{.*}} 'void ()' lvalue Function {{.*}} 'func1' 'void ()'
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} referenced N::func2
+//CHECK-NEXT:     `-CallExpr {{.*}} 'void'
+//CHECK-NEXT:       `-ImplicitCastExpr {{.*}} 'void (*)()' <FunctionToPointerDecay>
+//CHECK-NEXT:         `-DeclRefExpr {{.*}} 'void ()' lvalue Function {{.*}} 'func2' 'void ()' (UsingShadow {{.*}} 'func2')
Index: test/SemaCXX/referenced_using_all.cpp
===================================================================
--- test/SemaCXX/referenced_using_all.cpp
+++ test/SemaCXX/referenced_using_all.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+namespace A {
+  typedef char Char;
+  typedef int Integer;
+  typedef float Float;
+  int var;
+}
+
+using A::Char;
+using A::Integer;               // Referenced
+using A::Float;
+
+namespace B {
+  using A::Char;                // Referenced
+  template <class T>
+  T FuncTempl(T p1,Char p2) {
+    using A::Float;             // Referenced
+    typedef Float Type;
+    Integer I;
+    return p1;
+  }
+}
+
+using A::Char;                  // Referenced
+using A::Integer;
+namespace ND1 = A;
+void foo() {
+  using A::Integer;             // Referenced
+  namespace ND2 = ND1;          // Referenced
+  {
+    Integer Ivar;
+    namespace ND3 = ND2;        // Referenced
+    {
+      namespace ND4 = ND3;      // Referenced
+      Char Cvar;
+      {
+        using ND4::var;         // Referenced
+        var = 1;
+      }
+    }
+  }
+  using A::Char;                // Referenced
+  using namespace::B;           // Referenced
+  FuncTempl<Char>(1,'a');
+}
+
+//CHECK:      |-UsingDecl {{.*}} A::Char
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Typedef {{.*}} 'Char'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'A::Char' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Char'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'char'
+//CHECK-NEXT: |-UsingDecl {{.*}} referenced A::Integer
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit referenced Typedef {{.*}} 'Integer'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'A::Integer' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Integer'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'int'
+//CHECK-NEXT: |-UsingDecl {{.*}} A::Float
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Typedef {{.*}} 'Float'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'A::Float' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Float'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'float'
+//CHECK-NEXT: |-NamespaceDecl {{.*}} B
+//CHECK-NEXT: | |-UsingDecl {{.*}} referenced A::Char
+//CHECK-NEXT: | |-UsingShadowDecl {{.*}} implicit referenced Typedef {{.*}} 'Char'
+//CHECK-NEXT: | | `-TypedefType {{.*}} 'A::Char' sugar
+//CHECK-NEXT: | |   |-Typedef {{.*}} 'Char'
+//CHECK-NEXT: | |   `-BuiltinType {{.*}} 'char'
+//CHECK-NEXT: | `-FunctionTemplateDecl {{.*}} FuncTempl
+//CHECK-NEXT: |   |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 T
+//CHECK-NEXT: |   |-FunctionDecl {{.*}} FuncTempl 'T (T, A::Char)'
+//CHECK-NEXT: |   | |-ParmVarDecl {{.*}} referenced p1 'T'
+//CHECK-NEXT: |   | |-ParmVarDecl {{.*}} 'A::Char':'char'
+//CHECK-NEXT: |   | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   |   | `-UsingDecl {{.*}} referenced A::Float
+//CHECK-NEXT: |   |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   |   | `-TypedefDecl {{.*}} Type 'A::Float':'float'
+//CHECK-NEXT: |   |   |   `-TypedefType {{.*}} 'A::Float' sugar
+//CHECK-NEXT: |   |   |     |-Typedef {{.*}} 'Float'
+//CHECK-NEXT: |   |   |     `-BuiltinType {{.*}} 'float'
+//CHECK-NEXT: |   |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   |   | `-VarDecl {{.*}} I 'A::Integer':'int'
+//CHECK-NEXT: |   |   `-ReturnStmt {{.*}}
+//CHECK-NEXT: |   |     `-DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 'p1' 'T'
+//CHECK-NEXT: |   `-FunctionDecl {{.*}} used FuncTempl 'char (char, A::Char)'
+//CHECK-NEXT: |     |-TemplateArgument type 'char'
+//CHECK-NEXT: |     |-ParmVarDecl {{.*}} used p1 'char':'char'
+//CHECK-NEXT: |     |-ParmVarDecl {{.*}} p2 'A::Char':'char'
+//CHECK-NEXT: |     `-CompoundStmt {{.*}}
+//CHECK-NEXT: |       |-DeclStmt {{.*}}
+//CHECK-NEXT: |       | `-UsingDecl {{.*}} A::Float
+//CHECK-NEXT: |       |-DeclStmt {{.*}}
+//CHECK-NEXT: |       | `-TypedefDecl {{.*}} Type 'A::Float':'float'
+//CHECK-NEXT: |       |   `-TypedefType {{.*}} 'A::Float' sugar
+//CHECK-NEXT: |       |     |-Typedef {{.*}} 'Float'
+//CHECK-NEXT: |       |     `-BuiltinType {{.*}} 'float'
+//CHECK-NEXT: |       |-DeclStmt {{.*}}
+//CHECK-NEXT: |       | `-VarDecl {{.*}} I 'A::Integer':'int'
+//CHECK-NEXT: |       `-ReturnStmt {{.*}}
+//CHECK-NEXT: |         `-ImplicitCastExpr {{.*}} 'char':'char' <LValueToRValue>
+//CHECK-NEXT: |           `-DeclRefExpr {{.*}} 'char':'char' lvalue ParmVar {{.*}} 'p1' 'char':'char'
+//CHECK-NEXT: |-UsingDecl {{.*}} referenced A::Char
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit referenced Typedef {{.*}} 'Char'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'A::Char' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Char'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'char'
+//CHECK-NEXT: |-UsingDecl {{.*}} A::Integer
+//CHECK-NEXT: |-UsingShadowDecl {{.*}} implicit Typedef {{.*}} 'Integer'
+//CHECK-NEXT: | `-TypedefType {{.*}} 'A::Integer' sugar
+//CHECK-NEXT: |   |-Typedef {{.*}} 'Integer'
+//CHECK-NEXT: |   `-BuiltinType {{.*}} 'int'
+//CHECK-NEXT: |-NamespaceAliasDecl {{.*}} referenced ND1
+//CHECK-NEXT: | `-Namespace {{.*}} 'A'
+//CHECK-NEXT: `-FunctionDecl {{.*}} foo 'void ()'
+//CHECK-NEXT:   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} referenced A::Integer
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-NamespaceAliasDecl {{.*}} referenced ND2
+//CHECK-NEXT:     |   `-NamespaceAlias {{.*}} 'ND1'
+//CHECK-NEXT:     |-CompoundStmt {{.*}}
+//CHECK-NEXT:     | |-DeclStmt {{.*}}
+//CHECK-NEXT:     | | `-VarDecl {{.*}} Ivar 'A::Integer':'int'
+//CHECK-NEXT:     | |-DeclStmt {{.*}}
+//CHECK-NEXT:     | | `-NamespaceAliasDecl {{.*}} referenced ND3
+//CHECK-NEXT:     | |   `-NamespaceAlias {{.*}} 'ND2'
+//CHECK-NEXT:     | `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |   |-DeclStmt {{.*}}
+//CHECK-NEXT:     |   | `-NamespaceAliasDecl {{.*}} referenced ND4
+//CHECK-NEXT:     |   |   `-NamespaceAlias {{.*}} 'ND3'
+//CHECK-NEXT:     |   |-DeclStmt {{.*}}
+//CHECK-NEXT:     |   | `-VarDecl {{.*}} Cvar 'A::Char':'char'
+//CHECK-NEXT:     |   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |     |-DeclStmt {{.*}}
+//CHECK-NEXT:     |     | `-UsingDecl {{.*}} referenced ND4::var
+//CHECK-NEXT:     |     `-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT:     |       |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int' (UsingShadow {{.*}} 'var')
+//CHECK-NEXT:     |       `-IntegerLiteral {{.*}} <col:15> 'int' 1
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDecl {{.*}} referenced A::Char
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-UsingDirectiveDecl {{.*}} referenced Namespace {{.*}} 'B'
+//CHECK-NEXT:     `-CallExpr {{.*}} 'char':'char'
+//CHECK-NEXT:       |-ImplicitCastExpr {{.*}} 'char (*)(char, A::Char)' <FunctionToPointerDecay>
+//CHECK-NEXT:       | `-DeclRefExpr {{.*}} 'char (char, A::Char)' lvalue Function {{.*}} 'FuncTempl' 'char (char, A::Char)' (FunctionTemplate {{.*}} 'FuncTempl')
+//CHECK-NEXT:       |-ImplicitCastExpr {{.*}} 'char':'char' <IntegralCast>
+//CHECK-NEXT:       | `-IntegerLiteral {{.*}} 'int' 1
+//CHECK-NEXT:       `-CharacterLiteral {{.*}} 'char' 97
Index: test/SemaCXX/referenced_alias_declaration_2.cpp
===================================================================
--- test/SemaCXX/referenced_alias_declaration_2.cpp
+++ test/SemaCXX/referenced_alias_declaration_2.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+namespace A {
+  namespace B {
+    namespace C {
+      typedef int Integer;
+    }
+  }
+}
+
+void foo() {
+  {
+    namespace N_A = A;                // Referenced
+    {
+      namespace N_AB = N_A::B;        // Referenced
+      {
+        namespace N_ABC = N_AB::C;    // Referenced
+        {
+          using N_ABC::Integer;       // Referenced
+          Integer var;
+        }
+      }
+    }
+  }
+  {
+    namespace N_A = A;
+    {
+      namespace N_AB = N_A::B;
+      {
+        namespace N_ABC = N_AB::C;
+        {
+          A::B::C::Integer var;
+        }
+      }
+    }
+  }
+}
+
+//CHECK:      `-FunctionDecl {{.*}} foo 'void ()'
+//CHECK-NEXT:   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |-CompoundStmt {{.*}}
+//CHECK-NEXT:     | |-DeclStmt {{.*}}
+//CHECK-NEXT:     | | `-NamespaceAliasDecl {{.*}} referenced N_A
+//CHECK-NEXT:     | |   `-Namespace {{.*}} 'A'
+//CHECK-NEXT:     | `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |   |-DeclStmt {{.*}}
+//CHECK-NEXT:     |   | `-NamespaceAliasDecl {{.*}} referenced N_AB
+//CHECK-NEXT:     |   |   `-Namespace {{.*}} 'B'
+//CHECK-NEXT:     |   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |     |-DeclStmt {{.*}}
+//CHECK-NEXT:     |     | `-NamespaceAliasDecl {{.*}} referenced N_ABC
+//CHECK-NEXT:     |     |   `-Namespace {{.*}} 'C'
+//CHECK-NEXT:     |     `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |       |-DeclStmt {{.*}}
+//CHECK-NEXT:     |       | `-UsingDecl {{.*}} referenced N_ABC::Integer
+//CHECK-NEXT:     |       `-DeclStmt {{.*}}
+//CHECK-NEXT:     |         `-VarDecl {{.*}} var 'A::B::C::Integer':'int'
+//CHECK-NEXT:     `-CompoundStmt {{.*}}
+//CHECK-NEXT:       |-DeclStmt {{.*}}
+//CHECK-NEXT:       | `-NamespaceAliasDecl {{.*}} N_A
+//CHECK-NEXT:       |   `-Namespace {{.*}} 'A'
+//CHECK-NEXT:       `-CompoundStmt {{.*}}
+//CHECK-NEXT:         |-DeclStmt {{.*}}
+//CHECK-NEXT:         | `-NamespaceAliasDecl {{.*}} N_AB
+//CHECK-NEXT:         |   `-Namespace {{.*}} 'B'
+//CHECK-NEXT:         `-CompoundStmt {{.*}}
+//CHECK-NEXT:           |-DeclStmt {{.*}}
+//CHECK-NEXT:           | `-NamespaceAliasDecl {{.*}} N_ABC
+//CHECK-NEXT:           |   `-Namespace {{.*}} 'C'
+//CHECK-NEXT:           `-CompoundStmt {{.*}}
+//CHECK-NEXT:             `-DeclStmt {{.*}}
+//CHECK-NEXT:               `-VarDecl {{.*}} var 'A::B::C::Integer':'int'
Index: test/SemaCXX/referenced_alias_declaration_1.cpp
===================================================================
--- test/SemaCXX/referenced_alias_declaration_1.cpp
+++ test/SemaCXX/referenced_alias_declaration_1.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+namespace N {
+  int var;
+}
+
+void Fa() {
+  namespace NN = N;     // Referenced
+  using namespace NN;   // Referenced
+  var = 1;
+}
+
+void Fb() {
+  namespace NA = N;     // Referenced
+  namespace NB = NA;    // Referenced
+  namespace NC = NB;    // Referenced
+  using namespace NC;   // Referenced
+  var = 2;
+  namespace ND = NC;
+}
+
+void Fc() {
+  namespace NA = N;
+  using namespace NA;
+  N::var = 3;
+}
+
+void Fd() {
+  namespace NA = N;     // Referenced
+  namespace NB = NA;    // Referenced
+  NB::var = 4;
+}
+
+//CHECK:      |-FunctionDecl {{.*}} Fa 'void ()'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-NamespaceAliasDecl {{.*}} referenced NN
+//CHECK-NEXT: |   |   `-Namespace {{.*}} 'N'
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-UsingDirectiveDecl {{.*}} referenced Namespace {{.*}} 'N'
+//CHECK-NEXT: |   `-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT: |     |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int'
+//CHECK-NEXT: |     `-IntegerLiteral {{.*}} 'int' 1
+//CHECK-NEXT: |-FunctionDecl {{.*}} Fb 'void ()'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-NamespaceAliasDecl {{.*}} referenced NA
+//CHECK-NEXT: |   |   `-Namespace {{.*}} 'N'
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-NamespaceAliasDecl {{.*}} referenced NB
+//CHECK-NEXT: |   |   `-NamespaceAlias {{.*}} 'NA'
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-NamespaceAliasDecl {{.*}} referenced NC
+//CHECK-NEXT: |   |   `-NamespaceAlias {{.*}} 'NB'
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-UsingDirectiveDecl {{.*}} referenced Namespace {{.*}} 'N'
+//CHECK-NEXT: |   |-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT: |   | |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int'
+//CHECK-NEXT: |   | `-IntegerLiteral {{.*}} 'int' 2
+//CHECK-NEXT: |   `-DeclStmt {{.*}}
+//CHECK-NEXT: |     `-NamespaceAliasDecl {{.*}} ND
+//CHECK-NEXT: |       `-NamespaceAlias {{.*}} 'NC'
+//CHECK-NEXT: |-FunctionDecl {{.*}} Fc 'void ()'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-NamespaceAliasDecl {{.*}} NA
+//CHECK-NEXT: |   |   `-Namespace {{.*}} 'N'
+//CHECK-NEXT: |   |-DeclStmt {{.*}}
+//CHECK-NEXT: |   | `-UsingDirectiveDecl {{.*}} Namespace {{.*}} 'N'
+//CHECK-NEXT: |   `-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT: |     |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int'
+//CHECK-NEXT: |     `-IntegerLiteral {{.*}} 'int' 3
+//CHECK-NEXT: `-FunctionDecl {{.*}} Fd 'void ()'
+//CHECK-NEXT:   `-CompoundStmt {{.*}}
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-NamespaceAliasDecl {{.*}} referenced NA
+//CHECK-NEXT:     |   `-Namespace {{.*}} 'N'
+//CHECK-NEXT:     |-DeclStmt {{.*}}
+//CHECK-NEXT:     | `-NamespaceAliasDecl {{.*}} referenced NB
+//CHECK-NEXT:     |   `-NamespaceAlias {{.*}} 'NA'
+//CHECK-NEXT:     `-BinaryOperator {{.*}} 'int' lvalue '='
+//CHECK-NEXT:       |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'var' 'int'
+//CHECK-NEXT:       `-IntegerLiteral {{.*}} 'int' 4
Index: test/PCH/cxx-templates.cpp
===================================================================
--- test/PCH/cxx-templates.cpp
+++ test/PCH/cxx-templates.cpp
@@ -5,12 +5,12 @@
 // Test with pch.
 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump  -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
 
 // Test with modules.
 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump  -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS -fmodules-ignore-macro=NO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -DNO_ERRORS -fmodules-ignore-macro=NO_ERRORS | FileCheck %s
 
 // Test with pch and delayed template parsing.
 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -9688,7 +9688,7 @@
 
       // We found a type. Build an ElaboratedType, since the
       // typename-specifier was just sugar.
-      MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
+      MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false, &SS);
       return Context.getElaboratedType(Keyword,
                                        QualifierLoc.getNestedNameSpecifier(),
                                        Context.getTypeDeclType(Type));
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -95,6 +95,9 @@
     ListTy list;
     llvm::SmallPtrSet<DeclContext*, 8> visited;
 
+    using UDirs = llvm::SmallPtrSet<UsingDirectiveDecl*, 8>;
+    UDirs usings;
+
   public:
     UnqualUsingDirectiveSet(Sema &SemaRef) : SemaRef(SemaRef) {}
 
@@ -184,6 +187,14 @@
       Common = Common->getPrimaryContext();
 
       list.push_back(UnqualUsingEntry(UD->getNominatedNamespace(), Common));
+      // Insert the using directive.
+      usings.insert(UD);
+    }
+
+    // Add the collected using directives to the given lookup results.
+    void addUsingDirective(LookupResult &R) {
+      for (auto I = usings.begin(), E = usings.end(); I != E; ++I)
+        R.addDecl((*I));
     }
 
     void done() {
@@ -1048,6 +1059,13 @@
 };
 } // end anonymous namespace
 
+// Add any using directives to the lookup results.
+static void
+AddUsingDirectives(LookupResult &R,UnqualUsingDirectiveSet &UDirs) {
+  if (R.isAddUsingDirectives())
+    UDirs.addUsingDirective(R);
+}
+
 bool Sema::CppLookupName(LookupResult &R, Scope *S) {
   assert(getLangOpts().CPlusPlus && "Can perform only C++ lookup");
 
@@ -1215,6 +1233,7 @@
             UDirs.visitScopeChain(Initial, InnermostFileScope);
 
             UDirs.done();
+            AddUsingDirectives(R,UDirs);
 
             VisitedUsingDirectives = true;
           }
@@ -1255,6 +1274,7 @@
   if (!VisitedUsingDirectives) {
     UDirs.visitScopeChain(Initial, S);
     UDirs.done();
+    AddUsingDirectives(R,UDirs);
   }
 
   // If we're not performing redeclaration lookup, do not look for local
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -250,7 +250,7 @@
 
     if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
       QualType T = Context.getTypeDeclType(Type);
-      MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
+      MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false, &SS);
 
       if (SearchType.isNull() || SearchType->isDependentType() ||
           Context.hasSameUnqualifiedType(T, SearchType)) {
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -14290,7 +14290,7 @@
 /// Mark a function referenced, and check whether it is odr-used
 /// (C++ [basic.def.odr]p2, C99 6.9p3)
 void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
-                                  bool MightBeOdrUse) {
+                                  bool MightBeOdrUse, Expr *E) {
   assert(Func && "No function?");
 
   Func->setReferenced();
@@ -14457,6 +14457,7 @@
   }
 
   Func->markUsed(Context);
+  MarkUsingReferenced(Func, Loc, /*CXXScopeSpec*=*/nullptr, E);
 }
 
 static void
@@ -15321,7 +15322,7 @@
       SemaRef.MaybeODRUseExprs.insert(E);
   } else if (OdrUseContext) {
     MarkVarDeclODRUsed(Var, Loc, SemaRef,
-                       /*MaxFunctionScopeIndex ptr*/ nullptr);
+                       /*MaxFunctionScopeIndex ptr*/ nullptr, E);
   } else if (isOdrUseContext(SemaRef, /*SkipDependentUses*/false)) {
     // If this is a dependent context, we don't need to mark variables as
     // odr-used, but we may still need to track them for lambda capture.
@@ -15369,7 +15370,8 @@
     return;
   }
 
-  SemaRef.MarkAnyDeclReferenced(Loc, D, MightBeOdrUse);
+  SemaRef.MarkAnyDeclReferenced(Loc, D, MightBeOdrUse,
+                                /*CXXScopeSpec*=*/nullptr, E);
 
   // If this is a call to a method via a cast, also mark the method in the
   // derived class used in case codegen can devirtualize the call.
@@ -15390,7 +15392,8 @@
   CXXMethodDecl *DM = MD->getDevirtualizedMethod(
       ME->getBase(), SemaRef.getLangOpts().AppleKext);
   if (DM)
-    SemaRef.MarkAnyDeclReferenced(Loc, DM, MightBeOdrUse);
+    SemaRef.MarkAnyDeclReferenced(Loc, DM, MightBeOdrUse,
+                                  /*CXXScopeSpec*=*/nullptr, E);
 }
 
 /// Perform reference-marking and odr-use handling for a DeclRefExpr.
@@ -15430,18 +15433,20 @@
 /// functions and variables. This method should not be used when building a
 /// normal expression which refers to a variable.
 void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D,
-                                 bool MightBeOdrUse) {
+                                 bool MightBeOdrUse, CXXScopeSpec *SS,
+                                 Expr *E) {
   if (MightBeOdrUse) {
     if (auto *VD = dyn_cast<VarDecl>(D)) {
       MarkVariableReferenced(Loc, VD);
       return;
     }
   }
   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
-    MarkFunctionReferenced(Loc, FD, MightBeOdrUse);
+    MarkFunctionReferenced(Loc, FD, MightBeOdrUse, E);
     return;
   }
   D->setReferenced();
+  MarkUsingReferenced(dyn_cast<NamedDecl>(D), Loc, SS, E);
 }
 
 namespace {
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -3916,7 +3916,7 @@
 
     if (BaseType.isNull()) {
       BaseType = Context.getTypeDeclType(TyD);
-      MarkAnyDeclReferenced(TyD->getLocation(), TyD, /*OdrUse=*/false);
+      MarkAnyDeclReferenced(TyD->getLocation(), TyD, /*OdrUse=*/false, &SS);
       if (SS.isSet()) {
         BaseType = Context.getElaboratedType(ETK_None, SS.getScopeRep(),
                                              BaseType);
@@ -15496,3 +15496,78 @@
 
   return NewPD;
 }
+
+// Mark the alias declaration and any associated chain as referenced.
+void Sema::MarkNamespaceAliasReferenced(NamedDecl *ND) {
+  if (!ND || ND->isReferenced())
+    return;
+  NamespaceAliasDecl *NA;
+  while ((NA = dyn_cast<NamespaceAliasDecl>(ND)) && !NA->isReferenced()) {
+    NA->setReferenced();
+    ND = NA->getAliasedNamespace();
+    if (auto *NNS = NA->getQualifier())
+      MarkNamespaceAliasReferenced(NNS->getAsNamespaceAlias());
+  }
+}
+
+/// Mark as referenced any 'using' statement (using-declaration,
+/// using directive or namespace alias), that have introduced the
+/// given declaration into the current context.
+void Sema::MarkUsingReferenced(NamedDecl *ND, SourceLocation Loc,
+                               CXXScopeSpec *SS, Expr *E) {
+  // The declaration was not defined in a namespace.
+  auto *DC = ND->getDeclContext();
+  if (!DC->isNamespace())
+    return;
+
+  // If the declaration was accessed explicitly using a namespace context,
+  // follow any associated namespace chain, as those declarations must be
+  // marked as referenced as well.
+  // Example:
+  //
+  //   namespace N {
+  //     int var;
+  //   }
+  //
+  //   void Fd() {
+  //     namespace NA = N;     // Referenced
+  //     namespace NB = NA;    // Referenced
+  //     NB::var = 4;
+  //   }
+
+  if (auto *NNS = SS ? SS->getScopeRep()
+                     : E ? cast<DeclRefExpr>(E)->getQualifier()
+                         : nullptr) {
+    MarkNamespaceAliasReferenced(NNS->getAsNamespaceAlias());
+    return;
+  }
+
+  // Lookup the named declaration.
+  LookupResult R(*this, ND->getDeclName(), Loc, LookupAnyName);
+  R.suppressDiagnostics();
+  R.setAddUsingDirectives();
+  LookupName(R,getCurScope());
+
+  // Any using-directive namespace target.
+  auto *Target = dyn_cast<NamespaceDecl>(DC);
+
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    NamedDecl *D = (*I)->getUnderlyingDecl();
+    // Check if the declaration was introduced by a 'using-declaration'.
+    if (auto *UD = dyn_cast<UsingDecl>(D)) {
+      UD->setReferenced();
+      for (auto *UsingShadow : UD->shadows())
+        UsingShadow->setReferenced();
+      if (auto *NNS = UD->getQualifier())
+        MarkNamespaceAliasReferenced(NNS->getAsNamespaceAlias());
+      return;
+    }
+    // Check if the declaration was introduced by a 'using-directive'.
+    if (auto *UDir = dyn_cast<UsingDirectiveDecl>(D))
+      if (UDir->getNominatedNamespace() == Target) {
+        UDir->setReferenced();
+        MarkNamespaceAliasReferenced(UDir->getNominatedNamespaceAsWritten());
+        return;
+      }
+  }
+}
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -477,7 +477,7 @@
     DiagnoseUseOfDecl(IIDecl, NameLoc);
 
     T = Context.getTypeDeclType(TD);
-    MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
+    MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false, SS);
   } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
     (void)DiagnoseUseOfDecl(IDecl, NameLoc);
     if (!HasTrailingDot)
@@ -1091,7 +1091,7 @@
   NamedDecl *FirstDecl = (*Result.begin())->getUnderlyingDecl();
   if (TypeDecl *Type = dyn_cast<TypeDecl>(FirstDecl)) {
     DiagnoseUseOfDecl(Type, NameLoc);
-    MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
+    MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false, &SS);
     QualType T = Context.getTypeDeclType(Type);
     if (SS.isNotEmpty())
       return buildNestedType(*this, SS, T, NameLoc);
Index: lib/Sema/SemaCXXScopeSpec.cpp
===================================================================
--- lib/Sema/SemaCXXScopeSpec.cpp
+++ lib/Sema/SemaCXXScopeSpec.cpp
@@ -694,7 +694,7 @@
     }
 
     if (auto *TD = dyn_cast_or_null<TypedefNameDecl>(SD))
-      MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
+      MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false, &SS);
 
     // If we're just performing this lookup for error-recovery purposes,
     // don't extend the nested-name-specifier. Just return now.
Index: include/clang/Sema/SemaInternal.h
===================================================================
--- include/clang/Sema/SemaInternal.h
+++ include/clang/Sema/SemaInternal.h
@@ -69,7 +69,7 @@
 //    *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.  
 inline void MarkVarDeclODRUsed(VarDecl *Var,
     SourceLocation Loc, Sema &SemaRef,
-    const unsigned *const FunctionScopeIndexToStopAt) {
+    const unsigned *const FunctionScopeIndexToStopAt, Expr *RefExpr = nullptr) {
   // Keep track of used but undefined variables.
   // FIXME: We shouldn't suppress this warning for static data members.
   if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
@@ -88,6 +88,7 @@
     FunctionScopeIndexToStopAt);
 
   Var->markUsed(SemaRef.Context);
+  SemaRef.MarkUsingReferenced(Var, Loc, /*CXXScopeSpec*=*/nullptr, RefExpr);
 }
 
 /// Return a DLL attribute from the declaration.
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4017,16 +4017,22 @@
   // odr-use cannot be determined from the current context (for instance,
   // because the name denotes a virtual function and was written without an
   // explicit nested-name-specifier).
-  void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse);
+  void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse,
+                             CXXScopeSpec *SS = nullptr, Expr *E = nullptr);
   void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
-                              bool MightBeOdrUse = true);
+                              bool MightBeOdrUse = true,
+                              Expr *E = nullptr);
   void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
   void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr);
   void MarkMemberReferenced(MemberExpr *E);
 
   void UpdateMarkingForLValueToRValue(Expr *E);
   void CleanupVarDeclMarking();
 
+  void MarkNamespaceAliasReferenced(NamedDecl *ND);
+  void MarkUsingReferenced(NamedDecl *ND, SourceLocation Loc,
+                           CXXScopeSpec *SS = nullptr, Expr *E = nullptr);
+
   enum TryCaptureKind {
     TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
   };
Index: include/clang/Sema/Lookup.h
===================================================================
--- include/clang/Sema/Lookup.h
+++ include/clang/Sema/Lookup.h
@@ -197,6 +197,7 @@
         Shadowed(std::move(Other.Shadowed)) {
     Other.Paths = nullptr;
     Other.Diagnose = false;
+    Other.AddUsingDirectives = false;
   }
 
   LookupResult &operator=(LookupResult &&Other) {
@@ -219,6 +220,7 @@
     Shadowed = std::move(Other.Shadowed);
     Other.Paths = nullptr;
     Other.Diagnose = false;
+    Other.AddUsingDirectives = false;
     return *this;
   }
 
@@ -451,6 +453,10 @@
   /// lookup.
   void setShadowed() { Shadowed = true; }
 
+  /// Determine wheter the lookup result should store using directives.
+  bool isAddUsingDirectives() const { return AddUsingDirectives; }
+  void setAddUsingDirectives() { AddUsingDirectives = true; }
+
   /// Resolves the result kind of the lookup, possibly hiding
   /// decls.
   ///
@@ -738,6 +744,9 @@
   /// declaration that we skipped. This only happens when \c LookupKind
   /// is \c LookupRedeclarationWithLinkage.
   bool Shadowed = false;
+
+  /// True if the using directives should be added to the results.
+  bool AddUsingDirectives = false;
 };
 
 /// Consumes visible declarations found when searching for
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to