Coverage Report

Created: 2018-12-11 17:59

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/AST/GlobalDecl.h
Line
Count
Source
1
//===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
11
// together with its type.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_AST_GLOBALDECL_H
16
#define LLVM_CLANG_AST_GLOBALDECL_H
17
18
#include "clang/AST/DeclCXX.h"
19
#include "clang/AST/DeclObjC.h"
20
#include "clang/AST/DeclOpenMP.h"
21
#include "clang/Basic/ABI.h"
22
#include "clang/Basic/LLVM.h"
23
#include "llvm/ADT/DenseMapInfo.h"
24
#include "llvm/ADT/PointerIntPair.h"
25
#include "llvm/Support/Casting.h"
26
#include "llvm/Support/type_traits.h"
27
#include <cassert>
28
29
namespace clang {
30
31
/// GlobalDecl - represents a global declaration. This can either be a
32
/// CXXConstructorDecl and the constructor type (Base, Complete).
33
/// a CXXDestructorDecl and the destructor type (Base, Complete) or
34
/// a VarDecl, a FunctionDecl or a BlockDecl.
35
class GlobalDecl {
36
  llvm::PointerIntPair<const Decl *, 2> Value;
37
  unsigned MultiVersionIndex = 0;
38
39
9.19M
  void Init(const Decl *D) {
40
9.19M
    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
41
9.19M
    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
42
9.19M
43
9.19M
    Value.setPointer(D);
44
9.19M
  }
45
46
public:
47
35.6M
  GlobalDecl() = default;
48
1.95M
  GlobalDecl(const VarDecl *D) { Init(D);}
49
  GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
50
7.18M
      : MultiVersionIndex(MVIndex) {
51
7.18M
    Init(D);
52
7.18M
  }
53
5.90k
  GlobalDecl(const BlockDecl *D) { Init(D); }
54
41.9k
  GlobalDecl(const CapturedDecl *D) { Init(D); }
55
4.49k
  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
56
6
  GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
57
1.30M
  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
58
490k
  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
59
60
5.53M
  GlobalDecl getCanonicalDecl() const {
61
5.53M
    GlobalDecl CanonGD;
62
5.53M
    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
63
5.53M
    CanonGD.Value.setInt(Value.getInt());
64
5.53M
    CanonGD.MultiVersionIndex = MultiVersionIndex;
65
5.53M
66
5.53M
    return CanonGD;
67
5.53M
  }
68
69
37.9M
  const Decl *getDecl() const { return Value.getPointer(); }
70
71
575k
  CXXCtorType getCtorType() const {
72
575k
    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
73
575k
    return static_cast<CXXCtorType>(Value.getInt());
74
575k
  }
75
76
475k
  CXXDtorType getDtorType() const {
77
475k
    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
78
475k
    return static_cast<CXXDtorType>(Value.getInt());
79
475k
  }
80
81
84
  unsigned getMultiVersionIndex() const {
82
84
    assert(isa<FunctionDecl>(getDecl()) &&
83
84
           !isa<CXXConstructorDecl>(getDecl()) &&
84
84
           !isa<CXXDestructorDecl>(getDecl()) &&
85
84
           "Decl is not a plain FunctionDecl!");
86
84
    return MultiVersionIndex;
87
84
  }
88
89
74.9M
  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
90
74.9M
    return LHS.Value == RHS.Value &&
91
74.9M
           
LHS.MultiVersionIndex == RHS.MultiVersionIndex19.9M
;
92
74.9M
  }
93
94
11.6M
  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
95
96
11.7M
  static GlobalDecl getFromOpaquePtr(void *P) {
97
11.7M
    GlobalDecl GD;
98
11.7M
    GD.Value.setFromOpaqueValue(P);
99
11.7M
    return GD;
100
11.7M
  }
101
102
37.7k
  GlobalDecl getWithDecl(const Decl *D) {
103
37.7k
    GlobalDecl Result(*this);
104
37.7k
    Result.Value.setPointer(D);
105
37.7k
    return Result;
106
37.7k
  }
107
108
70
  GlobalDecl getWithMultiVersionIndex(unsigned Index) {
109
70
    assert(isa<FunctionDecl>(getDecl()) &&
110
70
           !isa<CXXConstructorDecl>(getDecl()) &&
111
70
           !isa<CXXDestructorDecl>(getDecl()) &&
112
70
           "Decl is not a plain FunctionDecl!");
113
70
    GlobalDecl Result(*this);
114
70
    Result.MultiVersionIndex = Index;
115
70
    return Result;
116
70
  }
117
};
118
119
} // namespace clang
120
121
namespace llvm {
122
123
  template<> struct DenseMapInfo<clang::GlobalDecl> {
124
14.4M
    static inline clang::GlobalDecl getEmptyKey() {
125
14.4M
      return clang::GlobalDecl();
126
14.4M
    }
127
128
11.7M
    static inline clang::GlobalDecl getTombstoneKey() {
129
11.7M
      return clang::GlobalDecl::
130
11.7M
        getFromOpaquePtr(reinterpret_cast<void*>(-1));
131
11.7M
    }
132
133
11.6M
    static unsigned getHashValue(clang::GlobalDecl GD) {
134
11.6M
      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
135
11.6M
    }
136
137
    static bool isEqual(clang::GlobalDecl LHS,
138
74.9M
                        clang::GlobalDecl RHS) {
139
74.9M
      return LHS == RHS;
140
74.9M
    }
141
  };
142
143
  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
144
  // copy assignment operator, and destructor are all trivial.
145
  template <>
146
  struct isPodLike<clang::GlobalDecl> {
147
    static const bool value = true;
148
  };
149
150
} // namespace llvm
151
152
#endif // LLVM_CLANG_AST_GLOBALDECL_H