 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
73.7% |
274 / 372 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
91.9% |
342 / 372 |
| |
|
Line Coverage: |
87.4% |
382 / 437 |
| |
 |
|
 |
1 : //===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
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 C++ related Decl classes.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/AST/DeclCXX.h"
15 : #include "clang/AST/DeclTemplate.h"
16 : #include "clang/AST/ASTContext.h"
17 : #include "clang/AST/Expr.h"
18 : #include "clang/AST/TypeLoc.h"
19 : #include "clang/Basic/IdentifierTable.h"
20 : #include "llvm/ADT/STLExtras.h"
21 : #include "llvm/ADT/SmallPtrSet.h"
22 : using namespace clang;
23 :
24 : //===----------------------------------------------------------------------===//
25 : // Decl Allocation/Deallocation Method Implementations
26 : //===----------------------------------------------------------------------===//
27 :
28 4836: CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
29 : : UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
30 : UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
31 : Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
32 : Abstract(false), HasTrivialConstructor(true),
33 : HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
34 : HasTrivialDestructor(true), ComputedVisibleConversions(false),
35 : Bases(0), NumBases(0), VBases(0), NumVBases(0),
36 4836: Definition(D) {
37 4836: }
38 :
39 : CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
40 : SourceLocation L, IdentifierInfo *Id,
41 : CXXRecordDecl *PrevDecl,
42 10240: SourceLocation TKL)
43 : : RecordDecl(K, TK, DC, L, Id, PrevDecl, TKL),
44 : DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
4806: branch 1 taken
3739: branch 2 taken
18: branch 5 taken
1677: branch 6 taken
45 10240: TemplateOrInstantiation() { }
46 :
47 : CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
48 : SourceLocation L, IdentifierInfo *Id,
49 : SourceLocation TKL,
50 : CXXRecordDecl* PrevDecl,
51 8545: bool DelayTypeCreation) {
52 : CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id,
8545: branch 1 taken
0: branch 2 not taken
53 8545: PrevDecl, TKL);
54 :
55 : // FIXME: DelayTypeCreation seems like such a hack
7509: branch 0 taken
1036: branch 1 taken
56 8545: if (!DelayTypeCreation)
57 7509: C.getTypeDeclType(R, PrevDecl);
58 8545: return R;
59 : }
60 :
61 0: CXXRecordDecl::~CXXRecordDecl() {
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 9 not taken
0: branch 10 not taken
62 0: }
63 :
64 0: void CXXRecordDecl::Destroy(ASTContext &C) {
0: branch 1 not taken
0: branch 2 not taken
65 0: if (data().Definition == this) {
66 0: C.Deallocate(data().Bases);
67 0: C.Deallocate(data().VBases);
68 0: C.Deallocate(&data());
69 : }
70 0: this->RecordDecl::Destroy(C);
71 0: }
72 :
73 : void
74 : CXXRecordDecl::setBases(ASTContext &C,
75 : CXXBaseSpecifier const * const *Bases,
76 763: unsigned NumBases) {
77 : // C++ [dcl.init.aggr]p1:
78 : // An aggregate is an array or a class (clause 9) with [...]
79 : // no base classes [...].
80 763: data().Aggregate = false;
81 :
0: branch 1 not taken
763: branch 2 taken
82 763: if (data().Bases)
83 0: C.Deallocate(data().Bases);
84 :
85 763: int vbaseCount = 0;
86 763: llvm::SmallVector<const CXXBaseSpecifier*, 8> UniqueVbases;
87 763: bool hasDirectVirtualBase = false;
88 :
763: branch 2 taken
0: branch 3 not taken
975: branch 5 taken
763: branch 6 taken
89 763: data().Bases = new(C) CXXBaseSpecifier [NumBases];
90 763: data().NumBases = NumBases;
975: branch 0 taken
763: branch 1 taken
91 1738: for (unsigned i = 0; i < NumBases; ++i) {
92 975: data().Bases[i] = *Bases[i];
93 : // Keep track of inherited vbases for this base class.
94 975: const CXXBaseSpecifier *Base = Bases[i];
95 975: QualType BaseType = Base->getType();
96 : // Skip template types.
97 : // FIXME. This means that this list must be rebuilt during template
98 : // instantiation.
74: branch 2 taken
901: branch 3 taken
99 975: if (BaseType->isDependentType())
100 74: continue;
101 : CXXRecordDecl *BaseClassDecl
102 901: = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
198: branch 1 taken
703: branch 2 taken
103 901: if (Base->isVirtual())
104 198: hasDirectVirtualBase = true;
188: branch 0 taken
901: branch 1 taken
105 1089: for (CXXRecordDecl::base_class_iterator VBase =
106 901: BaseClassDecl->vbases_begin(),
107 901: E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
108 : // Add this vbase to the array of vbases for current class if it is
109 : // not already in the list.
110 : // FIXME. Note that we do a linear search as number of such classes are
111 : // very few.
112 : int i;
205: branch 0 taken
167: branch 1 taken
113 372: for (i = 0; i < vbaseCount; ++i)
21: branch 4 taken
184: branch 5 taken
114 205: if (UniqueVbases[i]->getType() == VBase->getType())
115 21: break;
167: branch 0 taken
21: branch 1 taken
116 188: if (i == vbaseCount) {
117 167: UniqueVbases.push_back(VBase);
118 167: ++vbaseCount;
119 : }
120 : }
121 : }
163: branch 0 taken
600: branch 1 taken
122 763: if (hasDirectVirtualBase) {
123 : // Iterate one more time through the direct bases and add the virtual
124 : // base to the list of vritual bases for current class.
249: branch 0 taken
163: branch 1 taken
125 412: for (unsigned i = 0; i < NumBases; ++i) {
126 249: const CXXBaseSpecifier *VBase = Bases[i];
51: branch 1 taken
198: branch 2 taken
127 249: if (!VBase->isVirtual())
128 51: continue;
129 : int j;
230: branch 0 taken
190: branch 1 taken
130 420: for (j = 0; j < vbaseCount; ++j)
8: branch 4 taken
222: branch 5 taken
131 230: if (UniqueVbases[j]->getType() == VBase->getType())
132 8: break;
190: branch 0 taken
8: branch 1 taken
133 198: if (j == vbaseCount) {
134 190: UniqueVbases.push_back(VBase);
135 190: ++vbaseCount;
136 : }
137 : }
138 : }
202: branch 0 taken
561: branch 1 taken
139 763: if (vbaseCount > 0) {
140 : // build AST for inhireted, direct or indirect, virtual bases.
202: branch 2 taken
0: branch 3 not taken
357: branch 5 taken
202: branch 6 taken
141 202: data().VBases = new (C) CXXBaseSpecifier [vbaseCount];
142 202: data().NumVBases = vbaseCount;
357: branch 0 taken
202: branch 1 taken
143 559: for (int i = 0; i < vbaseCount; i++) {
144 357: QualType QT = UniqueVbases[i]->getType();
145 : CXXRecordDecl *VBaseClassDecl
146 357: = cast<CXXRecordDecl>(QT->getAs<RecordType>()->getDecl());
147 : data().VBases[i] =
148 : CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
149 : VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
150 357: UniqueVbases[i]->getAccessSpecifier(), QT);
151 : }
152 763: }
153 763: }
154 :
155 : /// Callback function for CXXRecordDecl::forallBases that acknowledges
156 : /// that it saw a base class.
157 1: static bool SawBase(const CXXRecordDecl *, void *) {
158 1: return true;
159 : }
160 :
161 20: bool CXXRecordDecl::hasAnyDependentBases() const {
0: branch 1 not taken
20: branch 2 taken
162 20: if (!isDependentContext())
163 0: return false;
164 :
165 20: return !forallBases(SawBase, 0);
166 : }
167 :
168 1032: bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
169 1032: return getCopyConstructor(Context, Qualifiers::Const) != 0;
170 : }
171 :
172 : CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
173 1068: unsigned TypeQuals) const{
174 : QualType ClassType
175 1068: = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
176 : DeclarationName ConstructorName
177 : = Context.DeclarationNames.getCXXConstructorName(
178 1068: Context.getCanonicalType(ClassType));
179 : unsigned FoundTQs;
180 : DeclContext::lookup_const_iterator Con, ConEnd;
2133: branch 3 taken
4: branch 4 taken
181 2137: for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
182 : Con != ConEnd; ++Con) {
183 : // C++ [class.copy]p2:
184 : // A non-template constructor for class X is a copy constructor if [...]
2133: branch 1 taken
0: branch 2 not taken
185 2133: if (isa<FunctionTemplateDecl>(*Con))
186 0: continue;
187 :
1068: branch 2 taken
1065: branch 3 taken
188 2133: if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(FoundTQs)) {
10: branch 0 taken
1058: branch 1 taken
6: branch 2 taken
4: branch 3 taken
6: branch 4 taken
0: branch 5 not taken
189 1068: if (((TypeQuals & Qualifiers::Const) == (FoundTQs & Qualifiers::Const)) ||
190 : (!(TypeQuals & Qualifiers::Const) && (FoundTQs & Qualifiers::Const)))
191 1064: return cast<CXXConstructorDecl>(*Con);
192 :
193 : }
194 : }
195 4: return 0;
196 : }
197 :
198 : bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context,
199 1043: const CXXMethodDecl *& MD) const {
200 : QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
201 1043: const_cast<CXXRecordDecl*>(this)));
202 1043: DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
203 :
204 : DeclContext::lookup_const_iterator Op, OpEnd;
1050: branch 3 taken
0: branch 4 not taken
205 1050: for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
206 : Op != OpEnd; ++Op) {
207 : // C++ [class.copy]p9:
208 : // A user-declared copy assignment operator is a non-static non-template
209 : // member function of class X with exactly one parameter of type X, X&,
210 : // const X&, volatile X& or const volatile X&.
211 1050: const CXXMethodDecl* Method = dyn_cast<CXXMethodDecl>(*Op);
1049: branch 0 taken
1: branch 1 taken
212 1050: if (!Method)
213 1: continue;
214 :
0: branch 1 not taken
1049: branch 2 taken
215 1049: if (Method->isStatic())
216 0: continue;
0: branch 1 not taken
1049: branch 2 taken
217 1049: if (Method->getPrimaryTemplate())
218 0: continue;
219 : const FunctionProtoType *FnType =
220 1049: Method->getType()->getAs<FunctionProtoType>();
0: branch 0 not taken
1049: branch 1 taken
221 1049: assert(FnType && "Overloaded operator has no prototype.");
222 : // Don't assert on this; an invalid decl might have been left in the AST.
1049: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
1049: branch 5 taken
0: branch 6 not taken
1049: branch 7 taken
223 1049: if (FnType->getNumArgs() != 1 || FnType->isVariadic())
224 0: continue;
225 1049: bool AcceptsConst = true;
226 1049: QualType ArgType = FnType->getArgType(0);
1046: branch 2 taken
3: branch 3 taken
227 1049: if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) {
228 1046: ArgType = Ref->getPointeeType();
229 : // Is it a non-const lvalue reference?
6: branch 1 taken
1040: branch 2 taken
230 1046: if (!ArgType.isConstQualified())
231 6: AcceptsConst = false;
232 : }
6: branch 1 taken
1043: branch 2 taken
233 1049: if (!Context.hasSameUnqualifiedType(ArgType, ClassType))
234 6: continue;
235 1043: MD = Method;
236 : // We have a single argument of type cv X or cv X&, i.e. we've found the
237 : // copy assignment operator. Return whether it accepts const arguments.
238 1043: return AcceptsConst;
239 : }
240 : assert(isInvalidDecl() &&
0: branch 1 not taken
0: branch 2 not taken
241 0: "No copy assignment operator declared in valid code.");
242 0: return false;
243 : }
244 :
245 : void
246 : CXXRecordDecl::addedConstructor(ASTContext &Context,
247 798: CXXConstructorDecl *ConDecl) {
798: branch 1 taken
0: branch 2 not taken
248 798: assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl");
249 : // Note that we have a user-declared constructor.
250 798: data().UserDeclaredConstructor = true;
251 :
252 : // C++ [dcl.init.aggr]p1:
253 : // An aggregate is an array or a class (clause 9) with no
254 : // user-declared constructors (12.1) [...].
255 798: data().Aggregate = false;
256 :
257 : // C++ [class]p4:
258 : // A POD-struct is an aggregate class [...]
259 798: data().PlainOldData = false;
260 :
261 : // C++ [class.ctor]p5:
262 : // A constructor is trivial if it is an implicitly-declared default
263 : // constructor.
264 : // FIXME: C++0x: don't do this for "= default" default constructors.
265 798: data().HasTrivialConstructor = false;
266 :
267 : // Note when we have a user-declared copy constructor, which will
268 : // suppress the implicit declaration of a copy constructor.
64: branch 1 taken
734: branch 2 taken
269 798: if (ConDecl->isCopyConstructor()) {
270 64: data().UserDeclaredCopyConstructor = true;
271 :
272 : // C++ [class.copy]p6:
273 : // A copy constructor is trivial if it is implicitly declared.
274 : // FIXME: C++0x: don't do this for "= default" copy constructors.
275 64: data().HasTrivialCopyConstructor = false;
276 : }
277 798: }
278 :
279 : void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
280 47: CXXMethodDecl *OpDecl) {
281 : // We're interested specifically in copy assignment operators.
282 47: const FunctionProtoType *FnType = OpDecl->getType()->getAs<FunctionProtoType>();
0: branch 0 not taken
47: branch 1 taken
283 47: assert(FnType && "Overloaded operator has no proto function type.");
47: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
47: branch 5 taken
284 47: assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
285 :
286 : // Copy assignment operators must be non-templates.
43: branch 1 taken
4: branch 2 taken
6: branch 4 taken
37: branch 5 taken
10: branch 6 taken
37: branch 7 taken
287 47: if (OpDecl->getPrimaryTemplate() || OpDecl->getDescribedFunctionTemplate())
288 10: return;
289 :
290 37: QualType ArgType = FnType->getArgType(0);
30: branch 2 taken
7: branch 3 taken
291 37: if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>())
292 30: ArgType = Ref->getPointeeType();
293 :
294 37: ArgType = ArgType.getUnqualifiedType();
295 : QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
296 37: const_cast<CXXRecordDecl*>(this)));
297 :
14: branch 1 taken
23: branch 2 taken
298 37: if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
299 14: return;
300 :
301 : // This is a copy assignment operator.
302 : // Note on the decl that it is a copy assignment operator.
303 23: OpDecl->setCopyAssignment(true);
304 :
305 : // Suppress the implicit declaration of a copy constructor.
306 23: data().UserDeclaredCopyAssignment = true;
307 :
308 : // C++ [class.copy]p11:
309 : // A copy assignment operator is trivial if it is implicitly declared.
310 : // FIXME: C++0x: don't do this for "= default" copy operators.
311 23: data().HasTrivialCopyAssignment = false;
312 :
313 : // C++ [class]p4:
314 : // A POD-struct is an aggregate class that [...] has no user-defined copy
315 : // assignment operator [...].
316 23: data().PlainOldData = false;
317 : }
318 :
319 : void
320 : CXXRecordDecl::collectConversionFunctions(
321 114: llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const
322 : {
323 114: const UnresolvedSetImpl *Cs = getConversionFunctions();
16: branch 4 taken
114: branch 5 taken
324 130: for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
325 : I != E; ++I) {
326 16: NamedDecl *TopConv = *I;
327 16: CanQualType TConvType;
1: branch 0 taken
15: branch 1 taken
328 16: if (FunctionTemplateDecl *TConversionTemplate =
329 16: dyn_cast<FunctionTemplateDecl>(TopConv))
330 : TConvType =
331 : getASTContext().getCanonicalType(
332 1: TConversionTemplate->getTemplatedDecl()->getResultType());
333 : else
334 : TConvType =
335 : getASTContext().getCanonicalType(
336 15: cast<CXXConversionDecl>(TopConv)->getConversionType());
337 16: ConversionsTypeSet.insert(TConvType);
338 : }
339 114: }
340 :
341 : /// getNestedVisibleConversionFunctions - imports unique conversion
342 : /// functions from base classes into the visible conversion function
343 : /// list of the class 'RD'. This is a private helper method.
344 : /// TopConversionsTypeSet is the set of conversion functions of the class
345 : /// we are interested in. HiddenConversionTypes is set of conversion functions
346 : /// of the immediate derived class which hides the conversion functions found
347 : /// in current class.
348 : void
349 : CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
350 : const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet,
351 223: const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes)
352 : {
353 223: bool inTopClass = (RD == this);
354 223: QualType ClassType = getASTContext().getTypeDeclType(this);
223: branch 2 taken
0: branch 3 not taken
355 223: if (const RecordType *Record = ClassType->getAs<RecordType>()) {
356 : const UnresolvedSetImpl *Cs
357 223: = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
358 :
53: branch 4 taken
223: branch 5 taken
359 276: for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
360 : I != E; ++I) {
361 53: NamedDecl *Conv = *I;
362 : // Only those conversions not exact match of conversions in current
363 : // class are candidateconversion routines.
364 53: CanQualType ConvType;
2: branch 0 taken
51: branch 1 taken
365 53: if (FunctionTemplateDecl *ConversionTemplate =
366 53: dyn_cast<FunctionTemplateDecl>(Conv))
367 : ConvType =
368 : getASTContext().getCanonicalType(
369 2: ConversionTemplate->getTemplatedDecl()->getResultType());
370 : else
371 : ConvType =
372 : getASTContext().getCanonicalType(
373 51: cast<CXXConversionDecl>(Conv)->getConversionType());
374 : // We only add conversion functions found in the base class if they
375 : // are not hidden by those found in HiddenConversionTypes which are
376 : // the conversion functions in its derived class.
40: branch 0 taken
13: branch 1 taken
36: branch 3 taken
4: branch 4 taken
33: branch 6 taken
3: branch 7 taken
46: branch 8 taken
7: branch 9 taken
377 53: if (inTopClass ||
378 : (!TopConversionsTypeSet.count(ConvType) &&
379 : !HiddenConversionTypes.count(ConvType)) ) {
1: branch 0 taken
45: branch 1 taken
380 46: if (FunctionTemplateDecl *ConversionTemplate =
381 46: dyn_cast<FunctionTemplateDecl>(Conv))
382 1: RD->addVisibleConversionFunction(ConversionTemplate);
383 : else
384 45: RD->addVisibleConversionFunction(cast<CXXConversionDecl>(Conv));
385 : }
386 : }
387 : }
388 :
109: branch 1 taken
114: branch 2 taken
109: branch 4 taken
0: branch 5 not taken
109: branch 6 taken
114: branch 7 taken
389 223: if (getNumBases() == 0 && getNumVBases() == 0)
390 109: return;
391 :
392 114: llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions;
37: branch 0 taken
77: branch 1 taken
393 114: if (!inTopClass)
394 37: collectConversionFunctions(ConversionFunctions);
395 :
24: branch 1 taken
114: branch 2 taken
396 252: for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(),
397 114: E = vbases_end(); VBase != E; ++VBase) {
24: branch 3 taken
0: branch 4 not taken
398 24: if (const RecordType *RT = VBase->getType()->getAs<RecordType>()) {
399 : CXXRecordDecl *VBaseClassDecl
400 24: = cast<CXXRecordDecl>(RT->getDecl());
401 : VBaseClassDecl->getNestedVisibleConversionFunctions(RD,
402 : TopConversionsTypeSet,
13: branch 0 taken
11: branch 1 taken
403 24: (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
404 : }
405 : }
140: branch 1 taken
114: branch 2 taken
406 368: for (CXXRecordDecl::base_class_iterator Base = bases_begin(),
407 114: E = bases_end(); Base != E; ++Base) {
18: branch 1 taken
122: branch 2 taken
408 140: if (Base->isVirtual())
409 18: continue;
122: branch 3 taken
0: branch 4 not taken
410 122: if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
411 : CXXRecordDecl *BaseClassDecl
412 122: = cast<CXXRecordDecl>(RT->getDecl());
413 :
414 : BaseClassDecl->getNestedVisibleConversionFunctions(RD,
415 : TopConversionsTypeSet,
91: branch 0 taken
31: branch 1 taken
416 122: (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
417 : }
418 114: }
419 : }
420 :
421 : /// getVisibleConversionFunctions - get all conversion functions visible
422 : /// in current class; including conversion function templates.
423 17856: const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() {
424 : // If root class, all conversions are visible.
16714: branch 2 taken
1142: branch 3 taken
425 17856: if (bases_begin() == bases_end())
426 16714: return &data().Conversions;
427 : // If visible conversion list is already evaluated, return it.
1065: branch 1 taken
77: branch 2 taken
428 1142: if (data().ComputedVisibleConversions)
429 1065: return &data().VisibleConversions;
430 77: llvm::SmallPtrSet<CanQualType, 8> TopConversionsTypeSet;
431 77: collectConversionFunctions(TopConversionsTypeSet);
432 : getNestedVisibleConversionFunctions(this, TopConversionsTypeSet,
433 77: TopConversionsTypeSet);
434 77: data().ComputedVisibleConversions = true;
435 77: return &data().VisibleConversions;
436 : }
437 :
438 : void CXXRecordDecl::addVisibleConversionFunction(
439 45: CXXConversionDecl *ConvDecl) {
440 : assert(!ConvDecl->getDescribedFunctionTemplate() &&
45: branch 1 taken
0: branch 2 not taken
441 45: "Conversion function templates should cast to FunctionTemplateDecl.");
442 45: data().VisibleConversions.addDecl(ConvDecl);
443 45: }
444 :
445 : void CXXRecordDecl::addVisibleConversionFunction(
446 1: FunctionTemplateDecl *ConvDecl) {
447 : assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
1: branch 2 taken
0: branch 3 not taken
448 1: "Function template is not a conversion function template");
449 1: data().VisibleConversions.addDecl(ConvDecl);
450 1: }
451 :
452 228: void CXXRecordDecl::addConversionFunction(CXXConversionDecl *ConvDecl) {
453 : assert(!ConvDecl->getDescribedFunctionTemplate() &&
228: branch 1 taken
0: branch 2 not taken
454 228: "Conversion function templates should cast to FunctionTemplateDecl.");
455 228: data().Conversions.addDecl(ConvDecl);
456 228: }
457 :
458 19: void CXXRecordDecl::addConversionFunction(FunctionTemplateDecl *ConvDecl) {
459 : assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
19: branch 2 taken
0: branch 3 not taken
460 19: "Function template is not a conversion function template");
461 19: data().Conversions.addDecl(ConvDecl);
462 19: }
463 :
464 :
465 575: void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
466 575: Method->setVirtualAsWritten(true);
467 575: setAggregate(false);
468 575: setPOD(false);
469 575: setEmpty(false);
470 575: setPolymorphic(true);
471 575: setHasTrivialConstructor(false);
472 575: setHasTrivialCopyConstructor(false);
473 575: setHasTrivialCopyAssignment(false);
474 575: }
475 :
476 257: CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
145: branch 1 taken
112: branch 2 taken
477 257: if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
478 145: return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
479 :
480 112: return 0;
481 : }
482 :
483 2444: MemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const {
484 2444: return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
485 : }
486 :
487 : void
488 : CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
489 119: TemplateSpecializationKind TSK) {
490 : assert(TemplateOrInstantiation.isNull() &&
119: branch 1 taken
0: branch 2 not taken
491 119: "Previous template or instantiation?");
0: branch 1 not taken
119: branch 2 taken
492 119: assert(!isa<ClassTemplateSpecializationDecl>(this));
493 : TemplateOrInstantiation
119: branch 2 taken
0: branch 3 not taken
494 119: = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
495 119: }
496 :
497 717: TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
63: branch 0 taken
654: branch 1 taken
498 717: if (const ClassTemplateSpecializationDecl *Spec
499 717: = dyn_cast<ClassTemplateSpecializationDecl>(this))
500 63: return Spec->getSpecializationKind();
501 :
43: branch 1 taken
611: branch 2 taken
502 654: if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
503 43: return MSInfo->getTemplateSpecializationKind();
504 :
505 611: return TSK_Undeclared;
506 : }
507 :
508 : void
509 1393: CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
1381: branch 0 taken
12: branch 1 taken
510 1393: if (ClassTemplateSpecializationDecl *Spec
511 1393: = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
512 1381: Spec->setSpecializationKind(TSK);
513 1381: return;
514 : }
515 :
12: branch 1 taken
0: branch 2 not taken
516 12: if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
517 12: MSInfo->setTemplateSpecializationKind(TSK);
518 12: return;
519 : }
520 :
521 0: assert(false && "Not a class template or member class specialization");
522 : }
523 :
524 : CXXConstructorDecl *
525 0: CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
526 0: QualType ClassType = Context.getTypeDeclType(this);
527 : DeclarationName ConstructorName
528 : = Context.DeclarationNames.getCXXConstructorName(
529 0: Context.getCanonicalType(ClassType.getUnqualifiedType()));
530 :
531 : DeclContext::lookup_const_iterator Con, ConEnd;
0: branch 4 not taken
0: branch 5 not taken
532 0: for (llvm::tie(Con, ConEnd) = lookup(ConstructorName);
533 : Con != ConEnd; ++Con) {
534 : // FIXME: In C++0x, a constructor template can be a default constructor.
0: branch 1 not taken
0: branch 2 not taken
535 0: if (isa<FunctionTemplateDecl>(*Con))
536 0: continue;
537 :
538 0: CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
0: branch 1 not taken
0: branch 2 not taken
539 0: if (Constructor->isDefaultConstructor())
540 0: return Constructor;
541 : }
542 0: return 0;
543 : }
544 :
545 529: CXXDestructorDecl *CXXRecordDecl::getDestructor(ASTContext &Context) {
546 529: QualType ClassType = Context.getTypeDeclType(this);
547 :
548 : DeclarationName Name
549 : = Context.DeclarationNames.getCXXDestructorName(
550 529: Context.getCanonicalType(ClassType));
551 :
552 : DeclContext::lookup_iterator I, E;
553 529: llvm::tie(I, E) = lookup(Name);
0: branch 0 not taken
529: branch 1 taken
554 529: assert(I != E && "Did not find a destructor!");
555 :
556 529: CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
529: branch 0 taken
0: branch 1 not taken
557 529: assert(++I == E && "Found more than one destructor!");
558 :
559 529: return Dtor;
560 : }
561 :
562 : CXXMethodDecl *
563 : CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
564 : SourceLocation L, DeclarationName N,
565 : QualType T, TypeSourceInfo *TInfo,
566 6349: bool isStatic, bool isInline) {
567 : return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
6349: branch 1 taken
0: branch 2 not taken
568 6349: isStatic, isInline);
569 : }
570 :
571 11: bool CXXMethodDecl::isUsualDeallocationFunction() const {
0: branch 1 not taken
11: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
11: branch 7 taken
572 11: if (getOverloadedOperator() != OO_Delete &&
573 : getOverloadedOperator() != OO_Array_Delete)
574 0: return false;
575 :
576 : // C++ [basic.stc.dynamic.deallocation]p2:
577 : // If a class T has a member deallocation function named operator delete
578 : // with exactly one parameter, then that function is a usual (non-placement)
579 : // deallocation function. [...]
0: branch 1 not taken
11: branch 2 taken
580 11: if (getNumParams() == 1)
581 0: return true;
582 :
583 : // C++ [basic.stc.dynamic.deallocation]p2:
584 : // [...] If class T does not declare such an operator delete but does
585 : // declare a member deallocation function named operator delete with
586 : // exactly two parameters, the second of which has type std::size_t (18.1),
587 : // then this function is a usual deallocation function.
588 11: ASTContext &Context = getASTContext();
11: branch 1 taken
0: branch 2 not taken
8: branch 8 taken
3: branch 9 taken
8: branch 10 taken
3: branch 11 taken
589 11: if (getNumParams() != 2 ||
590 : !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(),
591 : Context.getSizeType()))
592 8: return false;
593 :
594 : // This function is a usual deallocation function if there are no
595 : // single-parameter deallocation functions of the same kind.
3: branch 3 taken
3: branch 4 taken
596 6: for (DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName());
597 : R.first != R.second; ++R.first) {
3: branch 1 taken
0: branch 2 not taken
598 3: if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*R.first))
0: branch 1 not taken
3: branch 2 taken
599 3: if (FD->getNumParams() == 1)
600 0: return false;
601 : }
602 :
603 3: return true;
604 : }
605 :
606 : typedef llvm::DenseMap<const CXXMethodDecl*,
607 : std::vector<const CXXMethodDecl *> *>
608 : OverriddenMethodsMapTy;
609 :
610 : // FIXME: We hate static data. This doesn't survive PCH saving/loading, and
611 : // the vtable building code uses it at CG time.
612 : static OverriddenMethodsMapTy *OverriddenMethods = 0;
613 :
614 147: void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
147: branch 1 taken
0: branch 2 not taken
615 147: assert(MD->isCanonicalDecl() && "Method is not canonical!");
616 : assert(!MD->getParent()->isDependentContext() &&
147: branch 2 taken
0: branch 3 not taken
617 147: "Can't add an overridden method to a class template!");
618 :
619 : // FIXME: The CXXMethodDecl dtor needs to remove and free the entry.
620 :
27: branch 0 taken
120: branch 1 taken
621 147: if (!OverriddenMethods)
622 27: OverriddenMethods = new OverriddenMethodsMapTy();
623 :
624 147: std::vector<const CXXMethodDecl *> *&Methods = (*OverriddenMethods)[this];
141: branch 0 taken
6: branch 1 taken
625 147: if (!Methods)
626 141: Methods = new std::vector<const CXXMethodDecl *>;
627 :
628 147: Methods->push_back(MD);
629 147: }
630 :
631 55673: CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
24839: branch 0 taken
30834: branch 1 taken
632 55673: if (!OverriddenMethods)
633 24839: return 0;
634 :
635 30834: OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this);
1785: branch 3 taken
29049: branch 4 taken
0: branch 7 not taken
1785: branch 8 taken
29049: branch 9 taken
1785: branch 10 taken
636 30834: if (it == OverriddenMethods->end() || it->second->empty())
637 29049: return 0;
638 :
639 1785: return &(*it->second)[0];
640 : }
641 :
642 55673: CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
24839: branch 0 taken
30834: branch 1 taken
643 55673: if (!OverriddenMethods)
644 24839: return 0;
645 :
646 30834: OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this);
1785: branch 3 taken
29049: branch 4 taken
0: branch 7 not taken
1785: branch 8 taken
29049: branch 9 taken
1785: branch 10 taken
647 30834: if (it == OverriddenMethods->end() || it->second->empty())
648 29049: return 0;
649 :
650 1785: return &(*it->second)[0] + it->second->size();
651 : }
652 :
653 10800: QualType CXXMethodDecl::getThisType(ASTContext &C) const {
654 : // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
655 : // If the member function is declared const, the type of this is const X*,
656 : // if the member function is declared volatile, the type of this is
657 : // volatile X*, and if the member function is declared const volatile,
658 : // the type of this is const volatile X*.
659 :
10800: branch 1 taken
0: branch 2 not taken
660 10800: assert(isInstance() && "No 'this' for static methods!");
661 :
662 10800: QualType ClassTy;
112: branch 2 taken
10688: branch 3 taken
663 10800: if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate())
664 112: ClassTy = TD->getInjectedClassNameType(C);
665 : else
666 10688: ClassTy = C.getTagDeclType(getParent());
667 : ClassTy = C.getQualifiedType(ClassTy,
668 10800: Qualifiers::fromCVRMask(getTypeQualifiers()));
669 10800: return C.getPointerType(ClassTy);
670 : }
671 :
672 4160: bool CXXMethodDecl::hasInlineBody() const {
673 : // If this function is a template instantiation, look at the template from
674 : // which it was instantiated.
675 4160: const FunctionDecl *CheckFn = getTemplateInstantiationPattern();
4029: branch 0 taken
131: branch 1 taken
676 4160: if (!CheckFn)
677 4029: CheckFn = this;
678 :
679 : const FunctionDecl *fn;
3694: branch 1 taken
466: branch 2 taken
3261: branch 4 taken
433: branch 5 taken
680 4160: return CheckFn->getBody(fn) && !fn->isOutOfLine();
681 : }
682 :
683 : CXXBaseOrMemberInitializer::
684 : CXXBaseOrMemberInitializer(ASTContext &Context,
685 : TypeSourceInfo *TInfo,
686 541: SourceLocation L, Expr *Init, SourceLocation R)
687 : : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0),
688 541: LParenLoc(L), RParenLoc(R)
689 : {
690 541: }
691 :
692 : CXXBaseOrMemberInitializer::
693 : CXXBaseOrMemberInitializer(ASTContext &Context,
694 : FieldDecl *Member, SourceLocation MemberLoc,
695 313: SourceLocation L, Expr *Init, SourceLocation R)
696 : : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
697 313: AnonUnionMember(0), LParenLoc(L), RParenLoc(R)
698 : {
699 313: }
700 :
701 0: void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
0: branch 0 not taken
0: branch 1 not taken
702 0: if (Init)
703 0: Init->Destroy(Context);
704 0: this->~CXXBaseOrMemberInitializer();
705 0: }
706 :
707 25: TypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
25: branch 1 taken
0: branch 2 not taken
708 25: if (isBaseInitializer())
709 25: return BaseOrMember.get<TypeSourceInfo*>()->getTypeLoc();
710 : else
711 0: return TypeLoc();
712 : }
713 :
714 643: Type *CXXBaseOrMemberInitializer::getBaseClass() {
643: branch 1 taken
0: branch 2 not taken
715 643: if (isBaseInitializer())
716 643: return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
717 : else
718 0: return 0;
719 : }
720 :
721 0: const Type *CXXBaseOrMemberInitializer::getBaseClass() const {
0: branch 1 not taken
0: branch 2 not taken
722 0: if (isBaseInitializer())
723 0: return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
724 : else
725 0: return 0;
726 : }
727 :
728 50: SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
25: branch 1 taken
25: branch 2 taken
729 50: if (isMemberInitializer())
730 25: return getMemberLocation();
731 :
732 25: return getBaseClassLoc().getSourceRange().getBegin();
733 : }
734 :
735 3: SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
736 3: return SourceRange(getSourceLocation(), getRParenLoc());
737 : }
738 :
739 : CXXConstructorDecl *
740 : CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
741 : SourceLocation L, DeclarationName N,
742 : QualType T, TypeSourceInfo *TInfo,
743 : bool isExplicit,
744 7995: bool isInline, bool isImplicitlyDeclared) {
745 : assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
7995: branch 1 taken
0: branch 2 not taken
746 7995: "Name must refer to a constructor");
747 : return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit, isInline,
7995: branch 1 taken
0: branch 2 not taken
748 15990: isImplicitlyDeclared);
749 : }
750 :
751 1792: bool CXXConstructorDecl::isDefaultConstructor() const {
752 : // C++ [class.ctor]p5:
753 : // A default constructor for a class X is a constructor of class
754 : // X that can be called without an argument.
755 : return (getNumParams() == 0) ||
209: branch 1 taken
1583: branch 2 taken
209: branch 4 taken
0: branch 5 not taken
0: branch 8 not taken
209: branch 9 taken
756 1792: (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg());
757 : }
758 :
759 : bool
760 7094: CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
761 : // C++ [class.copy]p2:
762 : // A non-template constructor for class X is a copy constructor
763 : // if its first parameter is of type X&, const X&, volatile X& or
764 : // const volatile X&, and either there are no other parameters
765 : // or else all other parameters have default arguments (8.3.6).
3642: branch 1 taken
3452: branch 2 taken
207: branch 4 taken
3435: branch 5 taken
78: branch 8 taken
129: branch 9 taken
3459: branch 11 taken
54: branch 12 taken
22: branch 14 taken
3437: branch 15 taken
3657: branch 16 taken
3437: branch 17 taken
766 7094: if ((getNumParams() < 1) ||
767 : (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
768 : (getPrimaryTemplate() != 0) ||
769 : (getDescribedFunctionTemplate() != 0))
770 3657: return false;
771 :
772 3437: const ParmVarDecl *Param = getParamDecl(0);
773 :
774 : // Do we have a reference type? Rvalue references don't count.
775 : const LValueReferenceType *ParamRefType =
776 3437: Param->getType()->getAs<LValueReferenceType>();
679: branch 0 taken
2758: branch 1 taken
777 3437: if (!ParamRefType)
778 679: return false;
779 :
780 : // Is it a reference to our class type?
781 2758: ASTContext &Context = getASTContext();
782 :
783 : CanQualType PointeeType
784 2758: = Context.getCanonicalType(ParamRefType->getPointeeType());
785 : CanQualType ClassTy
786 2758: = Context.getCanonicalType(Context.getTagDeclType(getParent()));
178: branch 2 taken
2580: branch 3 taken
787 2758: if (PointeeType.getUnqualifiedType() != ClassTy)
788 178: return false;
789 :
790 : // FIXME: other qualifiers?
791 :
792 : // We have a copy constructor.
793 2580: TypeQuals = PointeeType.getCVRQualifiers();
794 2580: return true;
795 : }
796 :
797 2235: bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
798 : // C++ [class.conv.ctor]p1:
799 : // A constructor declared without the function-specifier explicit
800 : // that can be called with a single parameter specifies a
801 : // conversion from the type of its first parameter to the type of
802 : // its class. Such a constructor is called a converting
803 : // constructor.
27: branch 1 taken
2208: branch 2 taken
27: branch 3 taken
0: branch 4 not taken
27: branch 5 taken
2208: branch 6 taken
804 2235: if (isExplicit() && !AllowExplicit)
805 27: return false;
806 :
807 : return (getNumParams() == 0 &&
808 : getType()->getAs<FunctionProtoType>()->isVariadic()) ||
809 : (getNumParams() == 1) ||
698: branch 1 taken
1510: branch 2 taken
691: branch 7 taken
7: branch 8 taken
763: branch 10 taken
1438: branch 11 taken
72: branch 13 taken
691: branch 14 taken
25: branch 17 taken
47: branch 18 taken
810 2208: (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
811 : }
812 :
813 2602: bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
2240: branch 1 taken
362: branch 2 taken
68: branch 4 taken
2172: branch 5 taken
43: branch 8 taken
25: branch 9 taken
48: branch 11 taken
2167: branch 12 taken
0: branch 14 not taken
48: branch 15 taken
2554: branch 16 taken
48: branch 17 taken
814 2602: if ((getNumParams() < 1) ||
815 : (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
816 : (getPrimaryTemplate() == 0) ||
817 : (getDescribedFunctionTemplate() != 0))
818 2554: return false;
819 :
820 48: const ParmVarDecl *Param = getParamDecl(0);
821 :
822 48: ASTContext &Context = getASTContext();
823 48: CanQualType ParamType = Context.getCanonicalType(Param->getType());
824 :
825 : // Strip off the lvalue reference, if any.
14: branch 1 taken
34: branch 2 taken
826 48: if (CanQual<LValueReferenceType> ParamRefType
827 48: = ParamType->getAs<LValueReferenceType>())
828 14: ParamType = ParamRefType->getPointeeType();
829 :
830 :
831 : // Is it the same as our our class type?
832 : CanQualType ClassTy
833 48: = Context.getCanonicalType(Context.getTagDeclType(getParent()));
41: branch 2 taken
7: branch 3 taken
834 48: if (ParamType.getUnqualifiedType() != ClassTy)
835 41: return false;
836 :
837 7: return true;
838 : }
839 :
840 : CXXDestructorDecl *
841 : CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
842 : SourceLocation L, DeclarationName N,
843 : QualType T, bool isInline,
844 3932: bool isImplicitlyDeclared) {
845 : assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
3932: branch 1 taken
0: branch 2 not taken
846 3932: "Name must refer to a destructor");
847 : return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
3932: branch 1 taken
0: branch 2 not taken
848 7864: isImplicitlyDeclared);
849 : }
850 :
851 : void
852 0: CXXConstructorDecl::Destroy(ASTContext& C) {
853 0: C.Deallocate(BaseOrMemberInitializers);
854 0: CXXMethodDecl::Destroy(C);
855 0: }
856 :
857 : CXXConversionDecl *
858 : CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
859 : SourceLocation L, DeclarationName N,
860 : QualType T, TypeSourceInfo *TInfo,
861 305: bool isInline, bool isExplicit) {
862 : assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
305: branch 1 taken
0: branch 2 not taken
863 305: "Name must refer to a conversion function");
305: branch 1 taken
0: branch 2 not taken
864 610: return new (C) CXXConversionDecl(RD, L, N, T, TInfo, isInline, isExplicit);
865 : }
866 :
867 : FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
868 : SourceLocation L,
869 : FriendUnion Friend,
870 96: SourceLocation FriendL) {
871 : #ifndef NDEBUG
59: branch 1 taken
37: branch 2 taken
872 96: if (Friend.is<NamedDecl*>()) {
873 59: NamedDecl *D = Friend.get<NamedDecl*>();
874 : assert(isa<FunctionDecl>(D) ||
875 : isa<CXXRecordDecl>(D) ||
876 : isa<FunctionTemplateDecl>(D) ||
30: branch 1 taken
29: branch 2 taken
30: branch 4 taken
0: branch 5 not taken
19: branch 7 taken
11: branch 8 taken
0: branch 10 not taken
19: branch 11 taken
877 59: isa<ClassTemplateDecl>(D));
878 :
879 : // As a temporary hack, we permit template instantiation to point
880 : // to the original declaration when instantiating members.
881 : assert(D->getFriendObjectKind() ||
0: branch 1 not taken
59: branch 2 taken
0: branch 5 not taken
0: branch 6 not taken
882 59: (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind()));
883 : }
884 : #endif
885 :
96: branch 1 taken
0: branch 2 not taken
886 96: return new (C) FriendDecl(DC, L, Friend, FriendL);
887 : }
888 :
889 : LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
890 : DeclContext *DC,
891 : SourceLocation L,
892 111: LanguageIDs Lang, bool Braces) {
111: branch 1 taken
0: branch 2 not taken
893 111: return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
894 : }
895 :
896 : UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
897 : SourceLocation L,
898 : SourceLocation NamespaceLoc,
899 : SourceRange QualifierRange,
900 : NestedNameSpecifier *Qualifier,
901 : SourceLocation IdentLoc,
902 : NamedDecl *Used,
903 100: DeclContext *CommonAncestor) {
99: branch 1 taken
1: branch 2 taken
904 100: if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
905 99: Used = NS->getOriginalNamespace();
906 : return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
100: branch 1 taken
0: branch 2 not taken
907 100: Qualifier, IdentLoc, Used, CommonAncestor);
908 : }
909 :
910 3512: NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
47: branch 0 taken
3465: branch 1 taken
911 3512: if (NamespaceAliasDecl *NA =
912 3512: dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
913 47: return NA->getNamespace();
914 3465: return cast_or_null<NamespaceDecl>(NominatedNamespace);
915 : }
916 :
917 : NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
918 : SourceLocation L,
919 : SourceLocation AliasLoc,
920 : IdentifierInfo *Alias,
921 : SourceRange QualifierRange,
922 : NestedNameSpecifier *Qualifier,
923 : SourceLocation IdentLoc,
924 22: NamedDecl *Namespace) {
21: branch 1 taken
1: branch 2 taken
925 22: if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
926 21: Namespace = NS->getOriginalNamespace();
927 : return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange,
22: branch 1 taken
0: branch 2 not taken
928 22: Qualifier, IdentLoc, Namespace);
929 : }
930 :
931 : UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
932 : SourceLocation L, SourceRange NNR, SourceLocation UL,
933 : NestedNameSpecifier* TargetNNS, DeclarationName Name,
934 114: bool IsTypeNameArg) {
114: branch 1 taken
0: branch 2 not taken
935 114: return new (C) UsingDecl(DC, L, NNR, UL, TargetNNS, Name, IsTypeNameArg);
936 : }
937 :
938 : UnresolvedUsingValueDecl *
939 : UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
940 : SourceLocation UsingLoc,
941 : SourceRange TargetNNR,
942 : NestedNameSpecifier *TargetNNS,
943 : SourceLocation TargetNameLoc,
944 16: DeclarationName TargetName) {
945 : return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
946 : TargetNNR, TargetNNS,
16: branch 2 taken
0: branch 3 not taken
947 16: TargetNameLoc, TargetName);
948 : }
949 :
950 : UnresolvedUsingTypenameDecl *
951 : UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
952 : SourceLocation UsingLoc,
953 : SourceLocation TypenameLoc,
954 : SourceRange TargetNNR,
955 : NestedNameSpecifier *TargetNNS,
956 : SourceLocation TargetNameLoc,
957 4: DeclarationName TargetName) {
958 : return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
959 : TargetNNR, TargetNNS,
960 : TargetNameLoc,
4: branch 2 taken
0: branch 3 not taken
961 4: TargetName.getAsIdentifierInfo());
962 : }
963 :
964 : StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
965 : SourceLocation L, Expr *AssertExpr,
966 64: StringLiteral *Message) {
64: branch 1 taken
0: branch 2 not taken
967 64: return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
968 : }
969 :
970 0: void StaticAssertDecl::Destroy(ASTContext& C) {
971 0: AssertExpr->Destroy(C);
972 0: Message->Destroy(C);
973 0: this->~StaticAssertDecl();
974 0: C.Deallocate((void *)this);
975 0: }
976 :
977 0: StaticAssertDecl::~StaticAssertDecl() {
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 9 not taken
0: branch 10 not taken
978 0: }
979 :
980 25: static const char *getAccessName(AccessSpecifier AS) {
0: branch 0 not taken
3: branch 1 taken
21: branch 2 taken
1: branch 3 taken
981 25: switch (AS) {
982 : default:
983 : case AS_none:
984 : assert("Invalid access specifier!");
985 0: return 0;
986 : case AS_public:
987 3: return "public";
988 : case AS_private:
989 21: return "private";
990 : case AS_protected:
991 1: return "protected";
992 : }
993 : }
994 :
995 : const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
996 25: AccessSpecifier AS) {
997 25: return DB << getAccessName(AS);
998 : }
999 :
1000 :
Generated: 2010-02-10 01:31 by zcov