Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/AST/ASTImporterLookupTable.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines the ASTImporterLookupTable class which implements a
10
//  lookup procedure for the import mechanism.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/ASTImporterLookupTable.h"
15
#include "clang/AST/Decl.h"
16
#include "clang/AST/RecursiveASTVisitor.h"
17
18
namespace clang {
19
20
namespace {
21
22
struct Builder : RecursiveASTVisitor<Builder> {
23
  ASTImporterLookupTable &LT;
24
1.21k
  Builder(ASTImporterLookupTable &LT) : LT(LT) {}
25
9.44k
  bool VisitNamedDecl(NamedDecl *D) {
26
9.44k
    LT.add(D);
27
9.44k
    return true;
28
9.44k
  }
29
  // In most cases the FriendDecl contains the declaration of the befriended
30
  // class as a child node, so it is discovered during the recursive
31
  // visitation. However, there are cases when the befriended class is not a
32
  // child, thus it must be fetched explicitly from the FriendDecl, and only
33
  // then can we add it to the lookup table.
34
104
  bool VisitFriendDecl(FriendDecl *D) {
35
104
    if (D->getFriendType()) {
36
60
      QualType Ty = D->getFriendType()->getType();
37
60
      if (isa<ElaboratedType>(Ty))
38
44
        Ty = cast<ElaboratedType>(Ty)->getNamedType();
39
60
      // A FriendDecl with a dependent type (e.g. ClassTemplateSpecialization)
40
60
      // always has that decl as child node.
41
60
      // However, there are non-dependent cases which does not have the
42
60
      // type as a child node. We have to dig up that type now.
43
60
      if (!Ty->isDependentType()) {
44
52
        if (const auto *RTy = dyn_cast<RecordType>(Ty))
45
36
          LT.add(RTy->getAsCXXRecordDecl());
46
16
        else if (const auto *SpecTy = dyn_cast<TemplateSpecializationType>(Ty))
47
8
          LT.add(SpecTy->getAsCXXRecordDecl());
48
8
        else if (isa<TypedefType>(Ty)) {
49
8
          // We do not put friend typedefs to the lookup table because
50
8
          // ASTImporter does not organize typedefs into redecl chains.
51
8
        } else {
52
0
          llvm_unreachable("Unhandled type of friend class");
53
0
        }
54
104
      }
55
60
    }
56
104
    return true;
57
104
  }
58
59
  // Override default settings of base.
60
172
  bool shouldVisitTemplateInstantiations() const { return true; }
61
11.1k
  bool shouldVisitImplicitCode() const { return true; }
62
};
63
64
} // anonymous namespace
65
66
1.21k
ASTImporterLookupTable::ASTImporterLookupTable(TranslationUnitDecl &TU) {
67
1.21k
  Builder B(*this);
68
1.21k
  B.TraverseDecl(&TU);
69
1.21k
}
70
71
16.4k
void ASTImporterLookupTable::add(DeclContext *DC, NamedDecl *ND) {
72
16.4k
  DeclList &Decls = LookupTable[DC][ND->getDeclName()];
73
16.4k
  // Inserts if and only if there is no element in the container equal to it.
74
16.4k
  Decls.insert(ND);
75
16.4k
}
76
77
89
void ASTImporterLookupTable::remove(DeclContext *DC, NamedDecl *ND) {
78
89
  DeclList &Decls = LookupTable[DC][ND->getDeclName()];
79
89
  bool EraseResult = Decls.remove(ND);
80
89
  (void)EraseResult;
81
89
  assert(EraseResult == true && "Trying to remove not contained Decl");
82
89
}
83
84
16.4k
void ASTImporterLookupTable::add(NamedDecl *ND) {
85
16.4k
  assert(ND);
86
16.4k
  DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
87
16.4k
  add(DC, ND);
88
16.4k
  DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
89
16.4k
  if (DC != ReDC)
90
73
    add(ReDC, ND);
91
16.4k
}
92
93
89
void ASTImporterLookupTable::remove(NamedDecl *ND) {
94
89
  assert(ND);
95
89
  DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
96
89
  remove(DC, ND);
97
89
  DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
98
89
  if (DC != ReDC)
99
0
    remove(ReDC, ND);
100
89
}
101
102
ASTImporterLookupTable::LookupResult
103
5.83k
ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const {
104
5.83k
  auto DCI = LookupTable.find(DC->getPrimaryContext());
105
5.83k
  if (DCI == LookupTable.end())
106
893
    return {};
107
4.93k
108
4.93k
  const auto &FoundNameMap = DCI->second;
109
4.93k
  auto NamesI = FoundNameMap.find(Name);
110
4.93k
  if (NamesI == FoundNameMap.end())
111
2.46k
    return {};
112
2.47k
113
2.47k
  return NamesI->second;
114
2.47k
}
115
116
0
void ASTImporterLookupTable::dump(DeclContext *DC) const {
117
0
  auto DCI = LookupTable.find(DC->getPrimaryContext());
118
0
  if (DCI == LookupTable.end())
119
0
    llvm::errs() << "empty\n";
120
0
  const auto &FoundNameMap = DCI->second;
121
0
  for (const auto &Entry : FoundNameMap) {
122
0
    DeclarationName Name = Entry.first;
123
0
    llvm::errs() << "==== Name: ";
124
0
    Name.dump();
125
0
    const DeclList& List = Entry.second;
126
0
    for (NamedDecl *ND : List) {
127
0
      ND->dump();
128
0
    }
129
0
  }
130
0
}
131
132
0
void ASTImporterLookupTable::dump() const {
133
0
  for (const auto &Entry : LookupTable) {
134
0
    DeclContext *DC = Entry.first;
135
0
    StringRef Primary = DC->getPrimaryContext() ? " primary" : "";
136
0
    llvm::errs() << "== DC:" << cast<Decl>(DC) << Primary << "\n";
137
0
    dump(DC);
138
0
  }
139
0
}
140
141
} // namespace clang