CarlosAlbertoEnciso updated this revision to Diff 147050.
CarlosAlbertoEnciso edited the summary of this revision.
CarlosAlbertoEnciso added a comment.

Address the issues raised by the reviewer (rsmith).


https://reviews.llvm.org/D46190

Files:
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaCXXScopeSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.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;
+  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
@@ -9667,7 +9667,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/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -206,7 +206,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
@@ -14196,10 +14196,11 @@
 /// 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();
+  MarkUsingReferenced(Func, /*CXXScopeSpec*=*/nullptr, E);
 
   // C++11 [basic.def.odr]p3:
   //   A function whose name appears as a potentially-evaluated expression is
@@ -15143,6 +15144,7 @@
   assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) &&
          "Invalid Expr argument to DoMarkVarDeclReferenced");
   Var->setReferenced();
+  SemaRef.MarkUsingReferenced(Var, /*CXXScopeSpec*=*/nullptr, E);
 
   TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
 
@@ -15275,7 +15277,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.
@@ -15296,7 +15299,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.
@@ -15336,18 +15340,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(D, SS, E);
 }
 
 namespace {
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -3880,7 +3880,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);
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: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1873,3 +1873,63 @@
   return checkOpenCLDisabledTypeOrDecl(&D, E.getLocStart(), FnName,
                                        OpenCLDeclExtMap, 1, D.getSourceRange());
 }
+
+// Mark the alias declaration and any associated chain as referenced.
+void Sema::MarkNamespaceAliasReferenced(NamedDecl *ND) {
+  if (ND && !ND->isReferenced()) {
+    NamespaceAliasDecl *NA = nullptr;
+    while ((NA = dyn_cast<NamespaceAliasDecl>(ND)) && !NA->isReferenced()) {
+      NA->setReferenced();
+      ND = NA->getAliasedNamespace();
+      if (auto *NNS = NA->getQualifier())
+        MarkNamespaceAliasReferenced(NNS->getAsNamespaceAlias());
+    }
+  }
+}
+
+/// \brief Mark as referenced any 'using declaration' that have introduced
+/// the given declaration in the current context.
+void Sema::MarkUsingReferenced(Decl *D, CXXScopeSpec *SS, Expr *E) {
+  // If the declaration is defined in a namespace, check if it was
+  // introduced in the currect context via any 'using' statement:
+  // using declaration, using directive or namespace alias.
+  auto *DC = D->getDeclContext();
+  if (!DC->isNamespace())
+    return;
+
+  // The presence of a nested-name-specifier, means the namespace reference
+  // is being accessed explicitly or via a namespace alias.
+  if (auto *NNS = SS ? SS->getScopeRep()
+                     : E ? dyn_cast<DeclRefExpr>(E)->getQualifier()
+                         : nullptr) {
+    MarkNamespaceAliasReferenced(NNS->getAsNamespaceAlias());
+    return;
+  }
+
+  // Traverse scope hierarchy, looking for the given declaration.
+  for (auto *S = getCurScope(); S; S = S->getParent()) {
+
+    // Check if the declaration was introduced by a 'using-declaration'.
+    UsingShadowDecl *USD = nullptr;
+    for (auto *DR : S->decls())
+      if ((USD = dyn_cast<UsingShadowDecl>(DR)) && !USD->isReferenced()) {
+        if (USD->getTargetDecl() == D) {
+          USD->setReferenced();
+          auto *UD = USD->getUsingDecl();
+          UD->setReferenced();
+          if (auto *NNS = UD->getQualifier())
+            MarkNamespaceAliasReferenced(NNS->getAsNamespaceAlias());
+          return;
+        }
+      }
+
+    // Check if the declaration was introduced by a 'using-directive'.
+    auto *Target = dyn_cast<NamespaceDecl>(DC);
+    for (auto *UD : S->using_directives())
+      if (!UD->isReferenced() && (UD->getNominatedNamespace() == Target)) {
+        UD->setReferenced();
+        MarkNamespaceAliasReferenced(UD->getNominatedNamespaceAsWritten());
+        return;
+      }
+  }
+}
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4010,16 +4010,21 @@
   // 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(Decl *D, CXXScopeSpec *SS = nullptr,
+                           Expr *E = nullptr);
+
   enum TryCaptureKind {
     TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
   };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D46190: For ... Carlos Alberto Enciso via Phabricator via cfe-commits

Reply via email to