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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the data structures used in the implementation
// of DeclContext.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
/// StoredDeclsList - This is an array of decls optimized a common case of only
/// containing one entry.
struct StoredDeclsList {
/// VectorTy - When in vector form, this is what the Data pointer points to.
typedef llvm::SmallVector<NamedDecl*, 4> VectorTy;
/// Data - Union of NamedDecl*/VectorTy*.
llvm::PointerUnion<NamedDecl*, VectorTy*> Data;
public:
StoredDeclsList() {}
StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
if (isVector())
Data = new VectorTy(*Data.get<VectorTy*>());
}
~StoredDeclsList() {
// If this is a vector-form, free the vector.
if (isVector())
delete Data.get<VectorTy*>();
}
StoredDeclsList &operator=(const StoredDeclsList &RHS) {
if (isVector())
delete Data.get<VectorTy*>();
Data = RHS.Data;
if (isVector())
Data = new VectorTy(*Data.get<VectorTy*>());
return *this;
}
bool isVector() const { return Data.is<VectorTy*>(); }
bool isInline() const { return Data.is<NamedDecl*>(); }
bool isNull() const { return Data.isNull(); }
void setOnlyValue(NamedDecl *ND) {
assert(isInline() && "Not inline");
Data = ND;
}
/// getLookupResult - Return an array of all the decls that this list
/// represents.
DeclContext::lookup_result getLookupResult() {
// If we have a single inline unit, return it.
if (isInline()) {
assert(!isNull() && "Empty list isn't allowed");
// Data is a raw pointer to a NamedDecl*, return it.
void *Ptr = &Data;
return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
}
// Otherwise, we have a range result.
VectorTy &V = *Data.get<VectorTy*>();
return DeclContext::lookup_result(&V[0], &V[0]+V.size());
}
/// HandleRedeclaration - If this is a redeclaration of an existing decl,
/// replace the old one with D and return true. Otherwise return false.
bool HandleRedeclaration(NamedDecl *D) {
// Most decls only have one entry in their list, special case it.
if (isInline()) {
if (!D->declarationReplaces(Data.get<NamedDecl*>()))
return false;
setOnlyValue(D);
return true;
}
// Determine if this declaration is actually a redeclaration.
VectorTy &Vec = *Data.get<VectorTy*>();
VectorTy::iterator RDI
= std::find_if(Vec.begin(), Vec.end(),
std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
D));
if (RDI == Vec.end())
return false;
*RDI = D;
return true;
}
/// AddSubsequentDecl - This is called on the second and later decl when it is
/// not a redeclaration to merge it into the appropriate place in our list.
///
void AddSubsequentDecl(NamedDecl *D) {
// If this is the second decl added to the list, convert this to vector
// form.
if (isInline()) {
NamedDecl *OldD = Data.get<NamedDecl*>();
VectorTy *VT = new VectorTy();
VT->push_back(OldD);
Data = VT;
}
VectorTy &Vec = *Data.get<VectorTy*>();
if (isa<UsingDirectiveDecl>(D) ||
D->getIdentifierNamespace() == Decl::IDNS_Tag)
Vec.push_back(D);
else if (Vec.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
NamedDecl *TagD = Vec.back();
Vec.back() = D;
Vec.push_back(TagD);
} else
Vec.push_back(D);
}
};
typedef llvm::DenseMap<DeclarationName, StoredDeclsList> StoredDeclsMap;
} // end namespace clang
#endif
|