aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CXX/drs/cwg177x.cpp
blob: cc62bdac4cf06aaa5e26dba0724895180bc0ef6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s
// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s --check-prefixes=CHECK,CXX11
// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s --check-prefixes=CHECK,CXX11,CXX14
// RUN: %clang_cc1 -std=c++1z %s -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s --check-prefixes=CHECK,CXX11,CXX14
// RUN: %clang_cc1 -std=c++1z %s -fexceptions -fcxx-exceptions -pedantic-errors -triple i386-windows-pc -ast-dump | FileCheck %s --check-prefixes=CHECK,CXX11,CXX14

namespace cwg1772 { // cwg1772: 14
  // __func__ in a lambda should name operator(), not the containing function.
  // CHECK: NamespaceDecl{{.+}}cwg1772
#if __cplusplus >= 201103L
  auto x = []() { __func__; };
  // CXX11: LambdaExpr
  // CXX11: CXXRecordDecl
  // CXX11: CXXMethodDecl{{.+}} operator() 'void () {{.*}}const'
  // CXX11-NEXT: CompoundStmt
  // CXX11-NEXT: PredefinedExpr{{.+}} 'const char[11]' lvalue __func__
  // CXX11-NEXT: StringLiteral{{.+}} 'const char[11]' lvalue "operator()"

  void func() {
    // CXX11: FunctionDecl{{.+}} func
  (void)[]() { __func__; };
  // CXX11-NEXT: CompoundStmt
  // CXX11: LambdaExpr
  // CXX11: CXXRecordDecl
  // CXX11: CXXMethodDecl{{.+}} operator() 'void () {{.*}}const'
  // CXX11-NEXT: CompoundStmt
  // CXX11-NEXT: PredefinedExpr{{.+}} 'const char[11]' lvalue __func__
  // CXX11-NEXT: StringLiteral{{.+}} 'const char[11]' lvalue "operator()"
  }
#endif // __cplusplus >= 201103L
}

namespace cwg1779 { // cwg1779: 14
  // __func__ in a function template, member function template, or generic
  //  lambda should have a dependent type.
  // CHECK: NamespaceDecl{{.+}}cwg1779

  template<typename T>
  void FuncTemplate() {
    __func__;
    // CHECK: FunctionDecl{{.+}} FuncTemplate
    // CHECK-NEXT: CompoundStmt
    // CHECK-NEXT: PredefinedExpr{{.+}} '<dependent type>' lvalue __func__
  }

  template<typename T>
  class ClassTemplate {
    // CHECK: ClassTemplateDecl{{.+}} ClassTemplate
    void MemFunc() {
      // CHECK: CXXMethodDecl{{.+}} MemFunc 'void (){{.*}}'
      // CHECK-NEXT: CompoundStmt
      // CHECK-NEXT: PredefinedExpr{{.+}} '<dependent type>' lvalue __func__
      __func__;
    }
    void OutOfLineMemFunc();
  };

  template <typename T> void ClassTemplate<T>::OutOfLineMemFunc() {
    // CHECK: CXXMethodDecl{{.+}}parent{{.+}} OutOfLineMemFunc 'void (){{.*}}'
    // CHECK-NEXT: CompoundStmt
    // CHECK-NEXT: PredefinedExpr{{.+}} '<dependent type>' lvalue __func__
    __func__;
  }

#if __cplusplus >= 201402L
  void contains_generic_lambda() {
    // CXX14: FunctionDecl{{.+}}contains_generic_lambda
    // CXX14: LambdaExpr
    // CXX14: CXXRecordDecl
    // CXX14: CXXMethodDecl{{.+}} operator() 'auto (auto) {{.*}}const'
    // CXX14-NEXT: ParmVarDecl
    // CXX14-NEXT: CompoundStmt
    // CXX14-NEXT: PredefinedExpr{{.+}} '<dependent type>' lvalue __func__
    (void)[](auto x) {
      __func__;
    };
  }
#endif // __cplusplus >= 201402L
}