blob: 4266ef5eaf82fa58048458002567fbfd82d9ccc2 [file] [log] [blame]
Douglas Gregor2e1cd422008-11-17 14:58:09 +00001//===-- DeclarationName.cpp - Declaration names implementation --*- 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// This file implements the DeclarationName and DeclarationNameTable
11// classes.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/DeclarationName.h"
15#include "clang/Basic/IdentifierTable.h"
16#include "llvm/ADT/FoldingSet.h"
17#include "llvm/Bitcode/Serialize.h"
18#include "llvm/Bitcode/Deserialize.h"
19using namespace clang;
20
21namespace clang {
22/// CXXSpecialName - Records the type associated with one of the
23/// "special" kinds of declaration names in C++, e.g., constructors,
24/// destructors, and conversion functions.
25class CXXSpecialName
26 : public DeclarationNameExtra, public llvm::FoldingSetNode {
27public:
Douglas Gregor2def4832008-11-17 20:34:05 +000028 /// Type - The type associated with this declaration name.
Douglas Gregor2e1cd422008-11-17 14:58:09 +000029 QualType Type;
30
Douglas Gregor2def4832008-11-17 20:34:05 +000031 /// FETokenInfo - Extra information associated with this declaration
32 /// name that can be used by the front end.
33 void *FETokenInfo;
34
Douglas Gregor2e1cd422008-11-17 14:58:09 +000035 void Profile(llvm::FoldingSetNodeID &ID) {
36 ID.AddInteger(ExtraKindOrNumArgs);
37 ID.AddPointer(Type.getAsOpaquePtr());
38 }
39};
40
41bool operator<(DeclarationName LHS, DeclarationName RHS) {
42 if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo())
43 if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo())
44 return strcmp(LhsId->getName(), RhsId->getName()) < 0;
45
46 return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger();
47}
48
49} // end namespace clang
50
51DeclarationName::DeclarationName(Selector Sel) {
52 switch (Sel.getNumArgs()) {
53 case 0:
54 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
55 Ptr |= StoredObjCZeroArgSelector;
56 break;
57
58 case 1:
59 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
60 Ptr |= StoredObjCOneArgSelector;
61 break;
62
63 default:
64 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
65 Ptr |= StoredObjCMultiArgSelectorOrCXXName;
66 break;
67 }
68}
69
70DeclarationName::NameKind DeclarationName::getNameKind() const {
71 switch (getStoredNameKind()) {
72 case StoredIdentifier: return Identifier;
73 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
74 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
75
76 case StoredObjCMultiArgSelectorOrCXXName:
77 switch (getExtra()->ExtraKindOrNumArgs) {
78 case DeclarationNameExtra::CXXConstructor:
79 return CXXConstructorName;
80
81 case DeclarationNameExtra::CXXDestructor:
82 return CXXDestructorName;
83
84 case DeclarationNameExtra::CXXConversionFunction:
85 return CXXConversionFunctionName;
86
87 default:
88 return ObjCMultiArgSelector;
89 }
90 break;
91 }
92
93 // Can't actually get here.
94 return Identifier;
95}
96
97QualType DeclarationName::getCXXNameType() const {
98 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
99 return CXXName->Type;
100 else
101 return QualType();
102}
103
104Selector DeclarationName::getObjCSelector() const {
105 switch (getNameKind()) {
106 case ObjCZeroArgSelector:
107 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
108
109 case ObjCOneArgSelector:
110 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
111
112 case ObjCMultiArgSelector:
113 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
114
115 default:
116 break;
117 }
118
119 return Selector();
120}
121
Douglas Gregor2def4832008-11-17 20:34:05 +0000122void *DeclarationName::getFETokenInfoAsVoid() const {
123 switch (getNameKind()) {
124 case Identifier:
125 return getAsIdentifierInfo()->getFETokenInfo<void>();
126
127 case CXXConstructorName:
128 case CXXDestructorName:
129 case CXXConversionFunctionName:
130 return getAsCXXSpecialName()->FETokenInfo;
131
132 default:
133 assert(false && "Declaration name has no FETokenInfo");
134 }
135 return 0;
136}
137
138void DeclarationName::setFETokenInfo(void *T) {
139 switch (getNameKind()) {
140 case Identifier:
141 getAsIdentifierInfo()->setFETokenInfo(T);
142 break;
143
144 case CXXConstructorName:
145 case CXXDestructorName:
146 case CXXConversionFunctionName:
147 getAsCXXSpecialName()->FETokenInfo = T;
148 break;
149
150 default:
151 assert(false && "Declaration name has no FETokenInfo");
152 }
153}
154
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000155DeclarationNameTable::DeclarationNameTable() {
156 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
157}
158
159DeclarationNameTable::~DeclarationNameTable() {
160 delete static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
161}
162
163DeclarationName
164DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
165 QualType Ty) {
166 assert(Kind >= DeclarationName::CXXConstructorName &&
167 Kind <= DeclarationName::CXXConversionFunctionName &&
168 "Kind must be a C++ special name kind");
169
170 llvm::FoldingSet<CXXSpecialName> *SpecialNames
171 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
172
173 DeclarationNameExtra::ExtraKind EKind;
174 switch (Kind) {
175 case DeclarationName::CXXConstructorName:
176 EKind = DeclarationNameExtra::CXXConstructor;
177 break;
178 case DeclarationName::CXXDestructorName:
179 EKind = DeclarationNameExtra::CXXDestructor;
180 break;
181 case DeclarationName::CXXConversionFunctionName:
182 EKind = DeclarationNameExtra::CXXConversionFunction;
183 break;
184 default:
185 return DeclarationName();
186 }
187
188 // Unique selector, to guarantee there is one per name.
189 llvm::FoldingSetNodeID ID;
190 ID.AddInteger(EKind);
191 ID.AddPointer(Ty.getAsOpaquePtr());
192
193 void *InsertPos = 0;
194 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
195 return DeclarationName(Name);
196
197 CXXSpecialName *SpecialName = new CXXSpecialName;
198 SpecialName->ExtraKindOrNumArgs = EKind;
199 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000200 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000201
202 SpecialNames->InsertNode(SpecialName, InsertPos);
203 return DeclarationName(SpecialName);
204}
205