 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
76.1% |
535 / 703 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.0% |
647 / 703 |
| |
|
Line Coverage: |
87.1% |
646 / 742 |
| |
 |
|
 |
1 : //===--- Decl.cpp - 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 Decl subclasses.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/AST/Decl.h"
15 : #include "clang/AST/DeclCXX.h"
16 : #include "clang/AST/DeclObjC.h"
17 : #include "clang/AST/DeclTemplate.h"
18 : #include "clang/AST/ASTContext.h"
19 : #include "clang/AST/TypeLoc.h"
20 : #include "clang/AST/Stmt.h"
21 : #include "clang/AST/Expr.h"
22 : #include "clang/AST/ExprCXX.h"
23 : #include "clang/AST/PrettyPrinter.h"
24 : #include "clang/Basic/Builtins.h"
25 : #include "clang/Basic/IdentifierTable.h"
26 : #include "clang/Parse/DeclSpec.h"
27 : #include "llvm/Support/ErrorHandling.h"
28 : #include <vector>
29 :
30 : using namespace clang;
31 :
32 0: void Attr::Destroy(ASTContext &C) {
0: branch 0 not taken
0: branch 1 not taken
33 0: if (Next) {
34 0: Next->Destroy(C);
35 0: Next = 0;
36 : }
37 0: this->~Attr();
38 0: C.Deallocate((void*)this);
39 0: }
40 :
41 : /// \brief Return the TypeLoc wrapper for the type source info.
42 92752: TypeLoc TypeSourceInfo::getTypeLoc() const {
43 92752: return TypeLoc(Ty, (void*)(this + 1));
44 : }
45 :
46 : //===----------------------------------------------------------------------===//
47 : // NamedDecl Implementation
48 : //===----------------------------------------------------------------------===//
49 :
50 : /// \brief Get the most restrictive linkage for the types in the given
51 : /// template parameter list.
52 : static Linkage
53 1084: getLinkageForTemplateParameterList(const TemplateParameterList *Params) {
54 1084: Linkage L = ExternalLinkage;
1345: branch 1 taken
1084: branch 2 taken
55 3513: for (TemplateParameterList::const_iterator P = Params->begin(),
56 1084: PEnd = Params->end();
57 : P != PEnd; ++P) {
149: branch 1 taken
1196: branch 2 taken
58 1345: if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
147: branch 3 taken
2: branch 4 taken
59 149: if (!NTTP->getType()->isDependentType()) {
60 147: L = minLinkage(L, NTTP->getType()->getLinkage());
61 147: continue;
62 : }
63 :
8: branch 0 taken
1190: branch 1 taken
64 1198: if (TemplateTemplateParmDecl *TTP
65 1198: = dyn_cast<TemplateTemplateParmDecl>(*P)) {
66 : L = minLinkage(L,
67 8: getLinkageForTemplateParameterList(TTP->getTemplateParameters()));
68 : }
69 : }
70 :
71 1084: return L;
72 : }
73 :
74 : /// \brief Get the most restrictive linkage for the types and
75 : /// declarations in the given template argument list.
76 : static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args,
77 1060: unsigned NumArgs) {
78 1060: Linkage L = ExternalLinkage;
79 :
1320: branch 0 taken
1060: branch 1 taken
80 2380: for (unsigned I = 0; I != NumArgs; ++I) {
115: branch 1 taken
1173: branch 2 taken
24: branch 3 taken
8: branch 4 taken
0: branch 5 not taken
0: branch 6 not taken
81 1320: switch (Args[I].getKind()) {
82 : case TemplateArgument::Null:
83 : case TemplateArgument::Integral:
84 : case TemplateArgument::Expression:
85 115: break;
86 :
87 : case TemplateArgument::Type:
88 1173: L = minLinkage(L, Args[I].getAsType()->getLinkage());
89 1173: break;
90 :
91 : case TemplateArgument::Declaration:
24: branch 2 taken
0: branch 3 not taken
92 24: if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl()))
93 24: L = minLinkage(L, ND->getLinkage());
24: branch 2 taken
0: branch 3 not taken
94 24: if (ValueDecl *VD = dyn_cast<ValueDecl>(Args[I].getAsDecl()))
95 24: L = minLinkage(L, VD->getType()->getLinkage());
96 24: break;
97 :
98 : case TemplateArgument::Template:
8: branch 0 taken
0: branch 1 not taken
99 8: if (TemplateDecl *Template
100 8: = Args[I].getAsTemplate().getAsTemplateDecl())
101 8: L = minLinkage(L, Template->getLinkage());
102 8: break;
103 :
104 : case TemplateArgument::Pack:
105 : L = minLinkage(L,
106 : getLinkageForTemplateArgumentList(Args[I].pack_begin(),
107 0: Args[I].pack_size()));
108 : break;
109 : }
110 : }
111 :
112 1060: return L;
113 : }
114 :
115 65526: static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
116 : assert(D->getDeclContext()->getLookupContext()->isFileContext() &&
65526: branch 3 taken
0: branch 4 not taken
117 65526: "Not a name having namespace scope");
118 65526: ASTContext &Context = D->getASTContext();
119 :
120 : // C++ [basic.link]p3:
121 : // A name having namespace scope (3.3.6) has internal linkage if it
122 : // is the name of
123 : // - an object, reference, function or function template that is
124 : // explicitly declared static; or,
125 : // (This bullet corresponds to C99 6.2.2p3.)
22228: branch 1 taken
43298: branch 2 taken
126 65526: if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
127 : // Explicitly declared static.
622: branch 1 taken
21606: branch 2 taken
128 22228: if (Var->getStorageClass() == VarDecl::Static)
129 622: return InternalLinkage;
130 :
131 : // - an object or reference that is explicitly declared const
132 : // and neither explicitly declared extern nor previously
133 : // declared to have external linkage; or
134 : // (there is no equivalent in C99)
8439: branch 1 taken
13167: branch 2 taken
185: branch 5 taken
8254: branch 6 taken
144: branch 8 taken
41: branch 9 taken
144: branch 11 taken
0: branch 12 not taken
144: branch 13 taken
21462: branch 14 taken
135 21606: if (Context.getLangOptions().CPlusPlus &&
136 : Var->getType().isConstant(Context) &&
137 : Var->getStorageClass() != VarDecl::Extern &&
138 : Var->getStorageClass() != VarDecl::PrivateExtern) {
139 144: bool FoundExtern = false;
11: branch 2 taken
144: branch 3 taken
11: branch 4 taken
0: branch 5 not taken
140 155: for (const VarDecl *PrevVar = Var->getPreviousDeclaration();
141 : PrevVar && !FoundExtern;
142 : PrevVar = PrevVar->getPreviousDeclaration())
11: branch 2 taken
0: branch 3 not taken
143 11: if (isExternalLinkage(PrevVar->getLinkage()))
144 11: FoundExtern = true;
145 :
133: branch 0 taken
11: branch 1 taken
146 144: if (!FoundExtern)
147 133: return InternalLinkage;
148 : }
17745: branch 1 taken
25553: branch 2 taken
187: branch 4 taken
17558: branch 5 taken
25740: branch 6 taken
17558: branch 7 taken
149 43298: } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
150 : // C++ [temp]p4:
151 : // A non-member function template can have internal linkage; any
152 : // other template name shall have external linkage.
153 25740: const FunctionDecl *Function = 0;
187: branch 0 taken
25553: branch 1 taken
154 25740: if (const FunctionTemplateDecl *FunTmpl
155 25740: = dyn_cast<FunctionTemplateDecl>(D))
156 187: Function = FunTmpl->getTemplatedDecl();
157 : else
158 25553: Function = cast<FunctionDecl>(D);
159 :
160 : // Explicitly declared static.
3145: branch 1 taken
22595: branch 2 taken
161 25740: if (Function->getStorageClass() == FunctionDecl::Static)
162 3145: return InternalLinkage;
0: branch 1 not taken
17558: branch 2 taken
163 17558: } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
164 : // - a data member of an anonymous union.
0: branch 3 not taken
0: branch 4 not taken
165 0: if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
166 0: return InternalLinkage;
167 : }
168 :
169 : // C++ [basic.link]p4:
170 :
171 : // A name having namespace scope has external linkage if it is the
172 : // name of
173 : //
174 : // - an object or reference, unless it has internal linkage; or
21473: branch 1 taken
40153: branch 2 taken
175 61626: if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
13167: branch 1 taken
8306: branch 2 taken
12433: branch 4 taken
734: branch 5 taken
20: branch 7 taken
12413: branch 8 taken
754: branch 9 taken
20719: branch 10 taken
176 21473: if (!Context.getLangOptions().CPlusPlus &&
177 : (Var->getStorageClass() == VarDecl::Extern ||
178 : Var->getStorageClass() == VarDecl::PrivateExtern)) {
179 : // C99 6.2.2p4:
180 : // For an identifier declared with the storage-class specifier
181 : // extern in a scope in which a prior declaration of that
182 : // identifier is visible, if the prior declaration specifies
183 : // internal or external linkage, the linkage of the identifier
184 : // at the later declaration is the same as the linkage
185 : // specified at the prior declaration. If no prior declaration
186 : // is visible, or if the prior declaration specifies no
187 : // linkage, then the identifier has external linkage.
0: branch 1 not taken
754: branch 2 taken
188 754: if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) {
0: branch 1 not taken
0: branch 2 not taken
189 0: if (Linkage L = PrevVar->getLinkage())
190 0: return L;
191 : }
192 : }
193 :
194 : // C99 6.2.2p5:
195 : // If the declaration of an identifier for an object has file
196 : // scope and no storage-class specifier, its linkage is
197 : // external.
40: branch 1 taken
21433: branch 2 taken
198 21473: if (Var->isInAnonymousNamespace())
199 40: return UniqueExternalLinkage;
200 :
201 21433: return ExternalLinkage;
202 : }
203 :
204 : // - a function, unless it has internal linkage; or
22408: branch 1 taken
17745: branch 2 taken
205 40153: if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
206 : // C99 6.2.2p5:
207 : // If the declaration of an identifier for a function has no
208 : // storage-class specifier, its linkage is determined exactly
209 : // as if it were declared with the storage-class specifier
210 : // extern.
15101: branch 1 taken
7307: branch 2 taken
12718: branch 4 taken
2383: branch 5 taken
12713: branch 7 taken
5: branch 8 taken
12713: branch 10 taken
0: branch 11 not taken
15101: branch 12 taken
7307: branch 13 taken
211 22408: if (!Context.getLangOptions().CPlusPlus &&
212 : (Function->getStorageClass() == FunctionDecl::Extern ||
213 : Function->getStorageClass() == FunctionDecl::PrivateExtern ||
214 : Function->getStorageClass() == FunctionDecl::None)) {
215 : // C99 6.2.2p4:
216 : // For an identifier declared with the storage-class specifier
217 : // extern in a scope in which a prior declaration of that
218 : // identifier is visible, if the prior declaration specifies
219 : // internal or external linkage, the linkage of the identifier
220 : // at the later declaration is the same as the linkage
221 : // specified at the prior declaration. If no prior declaration
222 : // is visible, or if the prior declaration specifies no
223 : // linkage, then the identifier has external linkage.
545: branch 1 taken
14556: branch 2 taken
224 15101: if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) {
545: branch 1 taken
0: branch 2 not taken
225 545: if (Linkage L = PrevFunc->getLinkage())
226 545: return L;
227 : }
228 : }
229 :
27: branch 1 taken
21836: branch 2 taken
230 21863: if (Function->isInAnonymousNamespace())
231 27: return UniqueExternalLinkage;
232 :
179: branch 0 taken
21657: branch 1 taken
233 21836: if (FunctionTemplateSpecializationInfo *SpecInfo
234 21836: = Function->getTemplateSpecializationInfo()) {
235 179: Linkage L = SpecInfo->getTemplate()->getLinkage();
236 179: const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments;
237 : L = minLinkage(L,
238 : getLinkageForTemplateArgumentList(
239 : TemplateArgs.getFlatArgumentList(),
240 179: TemplateArgs.flat_size()));
241 179: return L;
242 : }
243 :
244 21657: return ExternalLinkage;
245 : }
246 :
247 : // - a named class (Clause 9), or an unnamed class defined in a
248 : // typedef declaration in which the class has the typedef name
249 : // for linkage purposes (7.1.3); or
250 : // - a named enumeration (7.2), or an unnamed enumeration
251 : // defined in a typedef declaration in which the enumeration
252 : // has the typedef name for linkage purposes (7.1.3); or
10727: branch 1 taken
7018: branch 2 taken
253 17745: if (const TagDecl *Tag = dyn_cast<TagDecl>(D))
38: branch 2 taken
10689: branch 3 taken
14: branch 5 taken
24: branch 6 taken
10703: branch 7 taken
24: branch 8 taken
254 10727: if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) {
49: branch 1 taken
10654: branch 2 taken
255 10703: if (Tag->isInAnonymousNamespace())
256 49: return UniqueExternalLinkage;
257 :
258 : // If this is a class template specialization, consider the
259 : // linkage of the template and template arguments.
881: branch 0 taken
9773: branch 1 taken
260 10654: if (const ClassTemplateSpecializationDecl *Spec
261 10654: = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
262 881: const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
263 : Linkage L = getLinkageForTemplateArgumentList(
264 : TemplateArgs.getFlatArgumentList(),
265 881: TemplateArgs.flat_size());
266 881: return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage());
267 : }
268 :
269 9773: return ExternalLinkage;
270 : }
271 :
272 : // - an enumerator belonging to an enumeration with external linkage;
0: branch 1 not taken
7042: branch 2 taken
273 7042: if (isa<EnumConstantDecl>(D)) {
274 0: Linkage L = cast<NamedDecl>(D->getDeclContext())->getLinkage();
0: branch 1 not taken
0: branch 2 not taken
275 0: if (isExternalLinkage(L))
276 0: return L;
277 : }
278 :
279 : // - a template, unless it is a function template that has
280 : // internal linkage (Clause 14);
1076: branch 1 taken
5966: branch 2 taken
281 7042: if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
0: branch 1 not taken
1076: branch 2 taken
282 1076: if (D->isInAnonymousNamespace())
283 0: return UniqueExternalLinkage;
284 :
285 : return getLinkageForTemplateParameterList(
286 1076: Template->getTemplateParameters());
287 : }
288 :
289 : // - a namespace (7.3), unless it is declared within an unnamed
290 : // namespace.
1: branch 1 taken
5965: branch 2 taken
1: branch 4 taken
0: branch 5 not taken
1: branch 6 taken
5965: branch 7 taken
291 5966: if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace())
292 1: return ExternalLinkage;
293 :
294 5965: return NoLinkage;
295 : }
296 :
297 94339: Linkage NamedDecl::getLinkage() const {
298 : // Handle linkage for namespace-scope names.
65526: branch 3 taken
28813: branch 4 taken
299 94339: if (getDeclContext()->getLookupContext()->isFileContext())
59363: branch 1 taken
6163: branch 2 taken
300 65526: if (Linkage L = getLinkageForNamespaceScopeDecl(this))
301 59363: return L;
302 :
303 : // C++ [basic.link]p5:
304 : // In addition, a member function, static data member, a named
305 : // class or enumeration of class scope, or an unnamed class or
306 : // enumeration defined in a class-scope typedef declaration such
307 : // that the class or enumeration has the typedef name for linkage
308 : // purposes (7.1.3), has external linkage if the name of the class
309 : // has external linkage.
12948: branch 2 taken
22028: branch 3 taken
5194: branch 5 taken
7754: branch 6 taken
4615: branch 8 taken
579: branch 9 taken
359: branch 11 taken
4256: branch 12 taken
15: branch 15 taken
344: branch 16 taken
0: branch 19 not taken
15: branch 20 taken
8677: branch 21 taken
26299: branch 22 taken
310 34976: if (getDeclContext()->isRecord() &&
311 : (isa<CXXMethodDecl>(this) || isa<VarDecl>(this) ||
312 : (isa<TagDecl>(this) &&
313 : (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl())))) {
314 8677: Linkage L = cast<RecordDecl>(getDeclContext())->getLinkage();
8341: branch 1 taken
336: branch 2 taken
315 8677: if (isExternalLinkage(L))
316 8341: return L;
317 : }
318 :
319 : // C++ [basic.link]p6:
320 : // The name of a function declared in block scope and the name of
321 : // an object declared by a block scope extern declaration have
322 : // linkage. If there is a visible declaration of an entity with
323 : // linkage having the same name and type, ignoring entities
324 : // declared outside the innermost enclosing namespace scope, the
325 : // block scope declaration declares that same entity and receives
326 : // the linkage of the previous declaration. If there is more than
327 : // one such matching entity, the program is ill-formed. Otherwise,
328 : // if no matching entity is found, the block scope entity receives
329 : // external linkage.
14736: branch 2 taken
11899: branch 3 taken
330 26635: if (getLexicalDeclContext()->isFunctionOrMethod()) {
354: branch 1 taken
14382: branch 2 taken
331 14736: if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) {
20: branch 1 taken
334: branch 2 taken
332 354: if (Function->getPreviousDeclaration())
20: branch 2 taken
0: branch 3 not taken
333 20: if (Linkage L = Function->getPreviousDeclaration()->getLinkage())
334 20: return L;
335 :
0: branch 1 not taken
334: branch 2 taken
336 334: if (Function->isInAnonymousNamespace())
337 0: return UniqueExternalLinkage;
338 :
339 334: return ExternalLinkage;
340 : }
341 :
14134: branch 1 taken
248: branch 2 taken
342 14382: if (const VarDecl *Var = dyn_cast<VarDecl>(this))
13928: branch 1 taken
206: branch 2 taken
30: branch 4 taken
13898: branch 5 taken
236: branch 6 taken
13898: branch 7 taken
343 14134: if (Var->getStorageClass() == VarDecl::Extern ||
344 : Var->getStorageClass() == VarDecl::PrivateExtern) {
15: branch 1 taken
221: branch 2 taken
345 236: if (Var->getPreviousDeclaration())
13: branch 2 taken
2: branch 3 taken
346 15: if (Linkage L = Var->getPreviousDeclaration()->getLinkage())
347 13: return L;
348 :
0: branch 1 not taken
223: branch 2 taken
349 223: if (Var->isInAnonymousNamespace())
350 0: return UniqueExternalLinkage;
351 :
352 223: return ExternalLinkage;
353 : }
354 : }
355 :
356 : // C++ [basic.link]p6:
357 : // Names not covered by these rules have no linkage.
358 26045: return NoLinkage;
359 : }
360 :
361 1067: std::string NamedDecl::getQualifiedNameAsString() const {
362 1067: return getQualifiedNameAsString(getASTContext().getLangOptions());
363 : }
364 :
365 1376: std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
366 : // FIXME: Collect contexts, then accumulate names to avoid unnecessary
367 : // std::string thrashing.
368 1376: std::vector<std::string> Names;
369 1376: std::string QualName;
370 1376: const DeclContext *Ctx = getDeclContext();
371 :
25: branch 1 taken
1351: branch 2 taken
372 1376: if (Ctx->isFunctionOrMethod())
373 25: return getNameAsString();
374 :
1758: branch 0 taken
0: branch 1 not taken
375 3109: while (Ctx) {
120: branch 0 taken
1638: branch 1 taken
376 1758: if (const ClassTemplateSpecializationDecl *Spec
377 1758: = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
378 120: const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
379 : std::string TemplateArgsStr
380 : = TemplateSpecializationType::PrintTemplateArgumentList(
381 : TemplateArgs.getFlatArgumentList(),
382 : TemplateArgs.flat_size(),
383 120: P);
384 120: Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr);
213: branch 1 taken
1425: branch 2 taken
385 1638: } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Ctx)) {
10: branch 1 taken
203: branch 2 taken
386 213: if (ND->isAnonymousNamespace())
387 10: Names.push_back("<anonymous namespace>");
388 : else
389 203: Names.push_back(ND->getNameAsString());
72: branch 1 taken
1353: branch 2 taken
390 1425: } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(Ctx)) {
6: branch 1 taken
66: branch 2 taken
391 72: if (!RD->getIdentifier()) {
392 6: std::string RecordString = "<anonymous ";
393 6: RecordString += RD->getKindName();
394 6: RecordString += ">";
395 6: Names.push_back(RecordString);
396 : } else {
397 66: Names.push_back(RD->getNameAsString());
398 : }
2: branch 1 taken
1351: branch 2 taken
399 1353: } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Ctx)) {
400 2: std::string Proto = FD->getNameAsString();
401 :
402 2: const FunctionProtoType *FT = 0;
2: branch 1 taken
0: branch 2 not taken
403 2: if (FD->hasWrittenPrototype())
404 2: FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
405 :
406 2: Proto += "(";
2: branch 0 taken
0: branch 1 not taken
407 2: if (FT) {
408 2: llvm::raw_string_ostream POut(Proto);
409 2: unsigned NumParams = FD->getNumParams();
2: branch 1 taken
2: branch 2 taken
410 4: for (unsigned i = 0; i < NumParams; ++i) {
0: branch 0 not taken
2: branch 1 taken
411 2: if (i)
412 0: POut << ", ";
413 2: std::string Param;
414 2: FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
415 2: POut << Param;
416 : }
417 :
0: branch 1 not taken
2: branch 2 taken
418 2: if (FT->isVariadic()) {
0: branch 0 not taken
0: branch 1 not taken
419 0: if (NumParams > 0)
420 0: POut << ", ";
421 0: POut << "...";
422 2: }
423 : }
424 2: Proto += ")";
425 :
426 2: Names.push_back(Proto);
1351: branch 1 taken
0: branch 2 not taken
427 1351: } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
428 0: Names.push_back(ND->getNameAsString());
429 : else
430 1351: break;
431 :
432 407: Ctx = Ctx->getParent();
433 : }
434 :
435 : std::vector<std::string>::reverse_iterator
436 1351: I = Names.rbegin(),
437 1351: End = Names.rend();
438 :
407: branch 2 taken
1351: branch 3 taken
439 1758: for (; I!=End; ++I)
440 407: QualName += *I + "::";
441 :
442 1351: QualName += getNameAsString();
443 :
444 1351: return QualName;
445 : }
446 :
447 9214: bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
9214: branch 3 taken
0: branch 4 not taken
448 9214: assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
449 :
450 : // UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
451 : // We want to keep it, unless it nominates same namespace.
34: branch 1 taken
9180: branch 2 taken
452 9214: if (getKind() == Decl::UsingDirective) {
453 : return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() ==
454 34: cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace();
455 : }
456 :
6496: branch 1 taken
2684: branch 2 taken
457 9180: if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
458 : // For function declarations, we keep track of redeclarations.
459 6496: return FD->getPreviousDeclaration() == OldD;
460 :
461 : // For function templates, the underlying function declarations are linked.
286: branch 0 taken
2398: branch 1 taken
462 2684: if (const FunctionTemplateDecl *FunctionTemplate
463 2684: = dyn_cast<FunctionTemplateDecl>(this))
206: branch 0 taken
80: branch 1 taken
464 286: if (const FunctionTemplateDecl *OldFunctionTemplate
465 286: = dyn_cast<FunctionTemplateDecl>(OldD))
466 : return FunctionTemplate->getTemplatedDecl()
467 206: ->declarationReplaces(OldFunctionTemplate->getTemplatedDecl());
468 :
469 : // For method declarations, we keep track of redeclarations.
28: branch 1 taken
2450: branch 2 taken
470 2478: if (isa<ObjCMethodDecl>(this))
471 28: return false;
472 :
110: branch 1 taken
2340: branch 2 taken
0: branch 4 not taken
110: branch 5 taken
0: branch 6 not taken
2450: branch 7 taken
473 2450: if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
474 0: return true;
475 :
224: branch 1 taken
2226: branch 2 taken
66: branch 4 taken
158: branch 5 taken
66: branch 6 taken
2384: branch 7 taken
476 2450: if (isa<UsingShadowDecl>(this) && isa<UsingShadowDecl>(OldD))
477 : return cast<UsingShadowDecl>(this)->getTargetDecl() ==
478 66: cast<UsingShadowDecl>(OldD)->getTargetDecl();
479 :
480 : // For non-function declarations, if the declarations are of the
481 : // same kind then this must be a redeclaration, or semantic analysis
482 : // would not have given us the new declaration.
483 2384: return this->getKind() == OldD->getKind();
484 : }
485 :
486 74267: bool NamedDecl::hasLinkage() const {
487 74267: return getLinkage() != NoLinkage;
488 : }
489 :
490 189606: NamedDecl *NamedDecl::getUnderlyingDecl() {
491 189606: NamedDecl *ND = this;
492 639: while (true) {
639: branch 1 taken
189606: branch 2 taken
493 190245: if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
494 639: ND = UD->getTargetDecl();
11: branch 0 taken
189595: branch 1 taken
495 189606: else if (ObjCCompatibleAliasDecl *AD
496 189606: = dyn_cast<ObjCCompatibleAliasDecl>(ND))
497 11: return AD->getClassInterface();
498 : else
499 189595: return ND;
500 : }
501 : }
502 :
503 : //===----------------------------------------------------------------------===//
504 : // DeclaratorDecl Implementation
505 : //===----------------------------------------------------------------------===//
506 :
507 19038: SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
9814: branch 0 taken
9224: branch 1 taken
508 19038: if (DeclInfo) {
509 9814: TypeLoc TL = DeclInfo->getTypeLoc();
510 5988: while (true) {
511 15802: TypeLoc NextTL = TL.getNextTypeLoc();
9814: branch 1 taken
5988: branch 2 taken
512 15802: if (!NextTL)
513 9814: return TL.getSourceRange().getBegin();
514 5988: TL = NextTL;
515 : }
516 : }
517 9224: return SourceLocation();
518 : }
519 :
520 : //===----------------------------------------------------------------------===//
521 : // VarDecl Implementation
522 : //===----------------------------------------------------------------------===//
523 :
524 1: const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
1: branch 5 taken
0: branch 6 not taken
525 1: switch (SC) {
526 0: case VarDecl::None: break;
527 0: case VarDecl::Auto: return "auto"; break;
528 0: case VarDecl::Extern: return "extern"; break;
529 0: case VarDecl::PrivateExtern: return "__private_extern__"; break;
530 0: case VarDecl::Register: return "register"; break;
531 1: case VarDecl::Static: return "static"; break;
532 : }
533 :
534 0: assert(0 && "Invalid storage class");
535 : return 0;
536 : }
537 :
538 : VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
539 : IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
540 10922: StorageClass S) {
10922: branch 1 taken
0: branch 2 not taken
541 10922: return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S);
542 : }
543 :
544 1070: void VarDecl::Destroy(ASTContext& C) {
545 1070: Expr *Init = getInit();
0: branch 0 not taken
1070: branch 1 taken
546 1070: if (Init) {
547 0: Init->Destroy(C);
0: branch 1 not taken
0: branch 2 not taken
548 0: if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) {
549 0: Eval->~EvaluatedStmt();
550 0: C.Deallocate(Eval);
551 : }
552 : }
553 1070: this->~VarDecl();
554 1070: C.Deallocate((void *)this);
555 1070: }
556 :
557 1070: VarDecl::~VarDecl() {
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
4: branch 6 taken
0: branch 9 not taken
1066: branch 10 taken
558 1070: }
559 :
560 18203: SourceRange VarDecl::getSourceRange() const {
561 18203: SourceLocation Start = getTypeSpecStartLoc();
9238: branch 1 taken
8965: branch 2 taken
562 18203: if (Start.isInvalid())
563 9238: Start = getLocation();
564 :
125: branch 1 taken
18078: branch 2 taken
565 18203: if (getInit())
566 125: return SourceRange(Start, getInit()->getLocEnd());
567 18078: return SourceRange(Start, getLocation());
568 : }
569 :
570 17221: bool VarDecl::isExternC() const {
571 17221: ASTContext &Context = getASTContext();
11338: branch 1 taken
5883: branch 2 taken
572 17221: if (!Context.getLangOptions().CPlusPlus)
573 : return (getDeclContext()->isTranslationUnit() &&
574 : getStorageClass() != Static) ||
1776: branch 2 taken
9562: branch 3 taken
122: branch 5 taken
1654: branch 6 taken
9562: branch 9 taken
122: branch 10 taken
88: branch 12 taken
9474: branch 13 taken
575 11338: (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
576 :
5086: branch 3 taken
1501: branch 4 taken
577 6587: for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
578 : DC = DC->getParent()) {
21: branch 1 taken
5065: branch 2 taken
579 5086: if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
20: branch 1 taken
1: branch 2 taken
580 21: if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
581 20: return getStorageClass() != Static;
582 :
583 1: break;
584 : }
585 :
4361: branch 1 taken
704: branch 2 taken
586 5065: if (DC->isFunctionOrMethod())
587 4361: return false;
588 : }
589 :
590 1502: return false;
591 : }
592 :
593 1798: VarDecl *VarDecl::getCanonicalDecl() {
594 1798: return getFirstDeclaration();
595 : }
596 :
597 14419: VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
598 : // C++ [basic.def]p2:
599 : // A declaration is a definition unless [...] it contains the 'extern'
600 : // specifier or a linkage-specification and neither an initializer [...],
601 : // it declares a static data member in a class declaration [...].
602 : // C++ [temp.expl.spec]p15:
603 : // An explicit specialization of a static data member of a template is a
604 : // definition if the declaration includes an initializer; otherwise, it is
605 : // a declaration.
756: branch 1 taken
13663: branch 2 taken
606 14419: if (isStaticDataMember()) {
258: branch 1 taken
498: branch 2 taken
254: branch 4 taken
4: branch 5 taken
215: branch 7 taken
39: branch 8 taken
219: branch 9 taken
537: branch 10 taken
607 756: if (isOutOfLine() && (hasInit() ||
608 : getTemplateSpecializationKind() != TSK_ExplicitSpecialization))
609 219: return Definition;
610 : else
611 537: return DeclarationOnly;
612 : }
613 : // C99 6.7p5:
614 : // A definition of an identifier is a declaration for that identifier that
615 : // [...] causes storage to be reserved for that object.
616 : // Note: that applies for all non-file-scope objects.
617 : // C99 6.9.2p1:
618 : // If the declaration of an identifier for an object has file scope and an
619 : // initializer, the declaration is an external definition for the identifier
441: branch 1 taken
13222: branch 2 taken
620 13663: if (hasInit())
621 441: return Definition;
622 : // AST for 'extern "C" int foo;' is annotated with 'extern'.
713: branch 1 taken
12509: branch 2 taken
623 13222: if (hasExternalStorage())
624 713: return DeclarationOnly;
625 :
626 : // C99 6.9.2p2:
627 : // A declaration of an object that has file scope without an initializer,
628 : // and without a storage class specifier or the scs 'static', constitutes
629 : // a tentative definition.
630 : // No such thing in C++.
9095: branch 2 taken
3414: branch 3 taken
4371: branch 5 taken
4724: branch 6 taken
4371: branch 7 taken
8138: branch 8 taken
631 12509: if (!getASTContext().getLangOptions().CPlusPlus && isFileVarDecl())
632 4371: return TentativeDefinition;
633 :
634 : // What's left is (in C, block-scope) declarations without initializers or
635 : // external storage. These are definitions.
636 8138: return Definition;
637 : }
638 :
639 855: VarDecl *VarDecl::getActingDefinition() {
640 855: DefinitionKind Kind = isThisDeclarationADefinition();
0: branch 0 not taken
855: branch 1 taken
641 855: if (Kind != TentativeDefinition)
642 0: return 0;
643 :
644 855: VarDecl *LastTentative = false;
645 855: VarDecl *First = getFirstDeclaration();
1348: branch 4 taken
835: branch 5 taken
646 2183: for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
647 : I != E; ++I) {
648 1348: Kind = (*I)->isThisDeclarationADefinition();
20: branch 0 taken
1328: branch 1 taken
649 1348: if (Kind == Definition)
650 20: return 0;
1316: branch 0 taken
12: branch 1 taken
651 1328: else if (Kind == TentativeDefinition)
652 1316: LastTentative = *I;
653 : }
654 835: return LastTentative;
655 : }
656 :
657 0: bool VarDecl::isTentativeDefinitionNow() const {
658 0: DefinitionKind Kind = isThisDeclarationADefinition();
0: branch 0 not taken
0: branch 1 not taken
659 0: if (Kind != TentativeDefinition)
660 0: return false;
661 :
0: branch 4 not taken
0: branch 5 not taken
662 0: for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
0: branch 2 not taken
0: branch 3 not taken
663 0: if ((*I)->isThisDeclarationADefinition() == Definition)
664 0: return false;
665 : }
666 0: return true;
667 : }
668 :
669 6198: VarDecl *VarDecl::getDefinition() {
670 6198: VarDecl *First = getFirstDeclaration();
6668: branch 4 taken
1241: branch 5 taken
671 7909: for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
672 : I != E; ++I) {
4957: branch 2 taken
1711: branch 3 taken
673 6668: if ((*I)->isThisDeclarationADefinition() == Definition)
674 4957: return *I;
675 : }
676 1241: return 0;
677 : }
678 :
679 2407: const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
680 2407: redecl_iterator I = redecls_begin(), E = redecls_end();
2482: branch 1 taken
826: branch 2 taken
901: branch 5 taken
1581: branch 6 taken
901: branch 7 taken
2407: branch 8 taken
681 5715: while (I != E && !I->getInit())
682 901: ++I;
683 :
1581: branch 1 taken
826: branch 2 taken
684 2407: if (I != E) {
685 1581: D = *I;
686 1581: return I->getInit();
687 : }
688 826: return 0;
689 : }
690 :
691 21280: bool VarDecl::isOutOfLine() const {
19054: branch 1 taken
2226: branch 2 taken
692 21280: if (!isStaticDataMember())
693 19054: return false;
694 :
417: branch 1 taken
1809: branch 2 taken
695 2226: if (Decl::isOutOfLine())
696 417: return true;
697 :
698 : // If this static data member was instantiated from a static data member of
699 : // a class template, check whether that static data member was defined
700 : // out-of-line.
348: branch 1 taken
1461: branch 2 taken
701 1809: if (VarDecl *VD = getInstantiatedFromStaticDataMember())
702 348: return VD->isOutOfLine();
703 :
704 1461: return false;
705 : }
706 :
707 64: VarDecl *VarDecl::getOutOfLineDefinition() {
0: branch 1 not taken
64: branch 2 taken
708 64: if (!isStaticDataMember())
709 0: return 0;
710 :
101: branch 4 taken
27: branch 5 taken
711 128: for (VarDecl::redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
712 : RD != RDEnd; ++RD) {
37: branch 3 taken
64: branch 4 taken
713 101: if (RD->getLexicalDeclContext()->isFileContext())
714 37: return *RD;
715 : }
716 :
717 27: return 0;
718 : }
719 :
720 6509: void VarDecl::setInit(ASTContext &C, Expr *I) {
0: branch 1 not taken
6509: branch 2 taken
721 6509: if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
722 0: Eval->~EvaluatedStmt();
723 0: C.Deallocate(Eval);
724 : }
725 :
726 6509: Init = I;
727 6509: }
728 :
729 1977: VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
487: branch 1 taken
1490: branch 2 taken
730 1977: if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
731 487: return cast<VarDecl>(MSI->getInstantiatedFrom());
732 :
733 1490: return 0;
734 : }
735 :
736 376: TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
191: branch 1 taken
185: branch 2 taken
737 376: if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
738 191: return MSI->getTemplateSpecializationKind();
739 :
740 185: return TSK_Undeclared;
741 : }
742 :
743 2543: MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
744 2543: return getASTContext().getInstantiatedFromStaticDataMember(this);
745 : }
746 :
747 : void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
748 67: SourceLocation PointOfInstantiation) {
749 67: MemberSpecializationInfo *MSI = getMemberSpecializationInfo();
0: branch 0 not taken
67: branch 1 taken
750 67: assert(MSI && "Not an instantiated static data member?");
751 67: MSI->setTemplateSpecializationKind(TSK);
51: branch 0 taken
16: branch 1 taken
51: branch 3 taken
0: branch 4 not taken
50: branch 7 taken
1: branch 8 taken
50: branch 9 taken
17: branch 10 taken
752 67: if (TSK != TSK_ExplicitSpecialization &&
753 : PointOfInstantiation.isValid() &&
754 : MSI->getPointOfInstantiation().isInvalid())
755 50: MSI->setPointOfInstantiation(PointOfInstantiation);
756 67: }
757 :
758 : //===----------------------------------------------------------------------===//
759 : // ParmVarDecl Implementation
760 : //===----------------------------------------------------------------------===//
761 :
762 : ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
763 : SourceLocation L, IdentifierInfo *Id,
764 : QualType T, TypeSourceInfo *TInfo,
765 27417: StorageClass S, Expr *DefArg) {
27417: branch 1 taken
0: branch 2 not taken
766 27417: return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg);
767 : }
768 :
769 1606: Expr *ParmVarDecl::getDefaultArg() {
1606: branch 1 taken
0: branch 2 not taken
770 1606: assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
771 : assert(!hasUninstantiatedDefaultArg() &&
1606: branch 1 taken
0: branch 2 not taken
772 1606: "Default argument is not yet instantiated!");
773 :
774 1606: Expr *Arg = getInit();
22: branch 1 taken
1584: branch 2 taken
775 1606: if (CXXExprWithTemporaries *E = dyn_cast_or_null<CXXExprWithTemporaries>(Arg))
776 22: return E->getSubExpr();
777 :
778 1584: return Arg;
779 : }
780 :
781 141: unsigned ParmVarDecl::getNumDefaultArgTemporaries() const {
20: branch 0 taken
121: branch 1 taken
782 141: if (const CXXExprWithTemporaries *E =
783 141: dyn_cast<CXXExprWithTemporaries>(getInit()))
784 20: return E->getNumTemporaries();
785 :
786 121: return 0;
787 : }
788 :
789 10: CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) {
790 : assert(getNumDefaultArgTemporaries() &&
10: branch 1 taken
0: branch 2 not taken
791 10: "Default arguments does not have any temporaries!");
792 :
793 10: CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit());
794 10: return E->getTemporary(i);
795 : }
796 :
797 18: SourceRange ParmVarDecl::getDefaultArgRange() const {
17: branch 1 taken
1: branch 2 taken
798 18: if (const Expr *E = getInit())
799 17: return E->getSourceRange();
800 :
0: branch 1 not taken
1: branch 2 taken
801 1: if (hasUninstantiatedDefaultArg())
802 0: return getUninstantiatedDefaultArg()->getSourceRange();
803 :
804 1: return SourceRange();
805 : }
806 :
807 : //===----------------------------------------------------------------------===//
808 : // FunctionDecl Implementation
809 : //===----------------------------------------------------------------------===//
810 :
811 0: void FunctionDecl::Destroy(ASTContext& C) {
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
812 0: if (Body && Body.isOffset())
813 0: Body.get(C.getExternalSource())->Destroy(C);
814 :
0: branch 2 not taken
0: branch 3 not taken
815 0: for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
816 0: (*I)->Destroy(C);
817 :
818 : FunctionTemplateSpecializationInfo *FTSInfo
819 0: = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
0: branch 0 not taken
0: branch 1 not taken
820 0: if (FTSInfo)
821 0: C.Deallocate(FTSInfo);
822 :
823 : MemberSpecializationInfo *MSInfo
824 0: = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
0: branch 0 not taken
0: branch 1 not taken
825 0: if (MSInfo)
826 0: C.Deallocate(MSInfo);
827 :
828 0: C.Deallocate(ParamInfo);
829 :
830 0: Decl::Destroy(C);
831 0: }
832 :
833 : void FunctionDecl::getNameForDiagnostic(std::string &S,
834 : const PrintingPolicy &Policy,
835 183: bool Qualified) const {
836 183: NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
837 183: const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
40: branch 0 taken
143: branch 1 taken
838 183: if (TemplateArgs)
839 : S += TemplateSpecializationType::PrintTemplateArgumentList(
840 : TemplateArgs->getFlatArgumentList(),
841 : TemplateArgs->flat_size(),
842 40: Policy);
843 :
844 183: }
845 :
846 40156: Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
42435: branch 4 taken
23733: branch 5 taken
847 66168: for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
16423: branch 2 taken
26012: branch 3 taken
848 42435: if (I->Body) {
849 16423: Definition = *I;
850 16423: return I->Body.get(getASTContext().getExternalSource());
851 : }
852 : }
853 :
854 23733: return 0;
855 : }
856 :
857 8803: void FunctionDecl::setBody(Stmt *B) {
858 8803: Body = B;
8722: branch 0 taken
81: branch 1 taken
859 8803: if (B)
860 8722: EndRangeLoc = B->getLocEnd();
861 8803: }
862 :
863 30651: bool FunctionDecl::isMain() const {
864 30651: ASTContext &Context = getASTContext();
865 : return !Context.getLangOptions().Freestanding &&
866 : getDeclContext()->getLookupContext()->isTranslationUnit() &&
30624: branch 1 taken
27: branch 2 taken
23508: branch 6 taken
7116: branch 7 taken
23410: branch 9 taken
98: branch 10 taken
686: branch 13 taken
22724: branch 14 taken
867 30651: getIdentifier() && getIdentifier()->isStr("main");
868 : }
869 :
870 13194: bool FunctionDecl::isExternC() const {
871 13194: ASTContext &Context = getASTContext();
872 : // In C, any non-static, non-overloadable function has external
873 : // linkage.
6797: branch 1 taken
6397: branch 2 taken
874 13194: if (!Context.getLangOptions().CPlusPlus)
5774: branch 1 taken
1023: branch 2 taken
5774: branch 4 taken
0: branch 5 not taken
875 6797: return getStorageClass() != Static && !getAttr<OverloadableAttr>();
876 :
4805: branch 3 taken
6080: branch 4 taken
877 10885: for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
878 : DC = DC->getParent()) {
317: branch 1 taken
4488: branch 2 taken
879 4805: if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
310: branch 1 taken
7: branch 2 taken
880 317: if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
881 : return getStorageClass() != Static &&
310: branch 1 taken
0: branch 2 not taken
310: branch 4 taken
0: branch 5 not taken
882 310: !getAttr<OverloadableAttr>();
883 :
884 7: break;
885 : }
886 : }
887 :
888 6087: return false;
889 : }
890 :
891 8722: bool FunctionDecl::isGlobal() const {
1709: branch 1 taken
7013: branch 2 taken
892 8722: if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
893 1709: return Method->isStatic();
894 :
1425: branch 1 taken
5588: branch 2 taken
895 7013: if (getStorageClass() == Static)
896 1425: return false;
897 :
311: branch 3 taken
5277: branch 4 taken
898 5588: for (const DeclContext *DC = getDeclContext();
899 : DC->isNamespace();
900 : DC = DC->getParent()) {
311: branch 1 taken
0: branch 2 not taken
901 311: if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) {
6: branch 2 taken
305: branch 3 taken
902 311: if (!Namespace->getDeclName())
903 6: return false;
904 305: break;
905 : }
906 : }
907 :
908 5582: return true;
909 : }
910 :
911 : void
912 831: FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
913 831: redeclarable_base::setPreviousDeclaration(PrevDecl);
914 :
35: branch 1 taken
796: branch 2 taken
915 831: if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
916 : FunctionTemplateDecl *PrevFunTmpl
35: branch 0 taken
0: branch 1 not taken
917 35: = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
35: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
35: branch 3 taken
918 35: assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
919 35: FunTmpl->setPreviousDeclaration(PrevFunTmpl);
920 : }
921 831: }
922 :
923 1133: const FunctionDecl *FunctionDecl::getCanonicalDecl() const {
924 1133: return getFirstDeclaration();
925 : }
926 :
927 77372: FunctionDecl *FunctionDecl::getCanonicalDecl() {
928 77372: return getFirstDeclaration();
929 : }
930 :
931 : /// \brief Returns a value indicating whether this function
932 : /// corresponds to a builtin function.
933 : ///
934 : /// The function corresponds to a built-in function if it is
935 : /// declared at translation scope or within an extern "C" block and
936 : /// its name matches with the name of a builtin. The returned value
937 : /// will be 0 for functions that do not correspond to a builtin, a
938 : /// value of type \c Builtin::ID if in the target-independent range
939 : /// \c [1,Builtin::First), or a target-specific builtin value.
940 35401: unsigned FunctionDecl::getBuiltinID() const {
941 35401: ASTContext &Context = getASTContext();
33421: branch 1 taken
1980: branch 2 taken
26713: branch 5 taken
6708: branch 6 taken
28693: branch 7 taken
6708: branch 8 taken
942 35401: if (!getIdentifier() || !getIdentifier()->getBuiltinID())
943 28693: return 0;
944 :
945 6708: unsigned BuiltinID = getIdentifier()->getBuiltinID();
4095: branch 1 taken
2613: branch 2 taken
946 6708: if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
947 4095: return BuiltinID;
948 :
949 : // This function has the name of a known C library
950 : // function. Determine whether it actually refers to the C library
951 : // function or whether it just has the same name.
952 :
953 : // If this is a static function, it's not a builtin.
137: branch 1 taken
2476: branch 2 taken
954 2613: if (getStorageClass() == Static)
955 137: return 0;
956 :
957 : // If this function is at translation-unit scope and we're not in
958 : // C++, it refers to the C library function.
1061: branch 1 taken
1415: branch 2 taken
1061: branch 5 taken
0: branch 6 not taken
1061: branch 7 taken
1415: branch 8 taken
959 2476: if (!Context.getLangOptions().CPlusPlus &&
960 : getDeclContext()->isTranslationUnit())
961 1061: return BuiltinID;
962 :
963 : // If the function is in an extern "C" linkage specification and is
964 : // not marked "overloadable", it's the real function.
1052: branch 2 taken
363: branch 3 taken
1052: branch 7 taken
0: branch 8 not taken
1052: branch 10 taken
0: branch 11 not taken
1052: branch 12 taken
363: branch 13 taken
965 1415: if (isa<LinkageSpecDecl>(getDeclContext()) &&
966 : cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
967 : == LinkageSpecDecl::lang_c &&
968 : !getAttr<OverloadableAttr>())
969 1052: return BuiltinID;
970 :
971 : // Not a builtin
972 363: return 0;
973 : }
974 :
975 :
976 : /// getNumParams - Return the number of parameters this function must have
977 : /// based on its FunctionType. This is the length of the PararmInfo array
978 : /// after it has been created.
979 151132: unsigned FunctionDecl::getNumParams() const {
980 151132: const FunctionType *FT = getType()->getAs<FunctionType>();
8454: branch 1 taken
142678: branch 2 taken
981 151132: if (isa<FunctionNoProtoType>(FT))
982 8454: return 0;
983 142678: return cast<FunctionProtoType>(FT)->getNumArgs();
984 :
985 : }
986 :
987 : void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo,
988 23819: unsigned NumParams) {
0: branch 0 not taken
23819: branch 1 taken
989 23819: assert(ParamInfo == 0 && "Already has param info!");
23819: branch 1 taken
0: branch 2 not taken
990 23819: assert(NumParams == getNumParams() && "Parameter count mismatch!");
991 :
992 : // Zero params -> null pointer.
17539: branch 0 taken
6280: branch 1 taken
993 23819: if (NumParams) {
994 17539: void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
995 17539: ParamInfo = new (Mem) ParmVarDecl*[NumParams];
996 17539: memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
997 :
998 : // Update source range. The check below allows us to set EndRangeLoc before
999 : // setting the parameters.
17310: branch 1 taken
229: branch 2 taken
17277: branch 5 taken
33: branch 6 taken
17506: branch 7 taken
33: branch 8 taken
1000 17539: if (EndRangeLoc.isInvalid() || EndRangeLoc == getLocation())
1001 17506: EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd();
1002 : }
1003 23819: }
1004 :
1005 : /// getMinRequiredArguments - Returns the minimum number of arguments
1006 : /// needed to call this function. This may be fewer than the number of
1007 : /// function parameters, if some of the parameters have default
1008 : /// arguments (in C++).
1009 8143: unsigned FunctionDecl::getMinRequiredArguments() const {
1010 8143: unsigned NumRequiredArgs = getNumParams();
6544: branch 0 taken
1964: branch 1 taken
365: branch 4 taken
6179: branch 5 taken
365: branch 6 taken
8143: branch 7 taken
1011 16651: while (NumRequiredArgs > 0
1012 : && getParamDecl(NumRequiredArgs-1)->hasDefaultArg())
1013 365: --NumRequiredArgs;
1014 :
1015 8143: return NumRequiredArgs;
1016 : }
1017 :
1018 5969: bool FunctionDecl::isInlined() const {
1019 : // FIXME: This is not enough. Consider:
1020 : //
1021 : // inline void f();
1022 : // void f() { }
1023 : //
1024 : // f is inlined, but does not have inline specified.
1025 : // To fix this we should add an 'inline' flag to FunctionDecl.
565: branch 1 taken
5404: branch 2 taken
1026 5969: if (isInlineSpecified())
1027 565: return true;
1028 :
1475: branch 1 taken
3929: branch 2 taken
1029 5404: if (isa<CXXMethodDecl>(this)) {
401: branch 1 taken
1074: branch 2 taken
3: branch 5 taken
398: branch 6 taken
1077: branch 7 taken
398: branch 8 taken
1030 1475: if (!isOutOfLine() || getCanonicalDecl()->isInlineSpecified())
1031 1077: return true;
1032 : }
1033 :
4262: branch 1 taken
65: branch 2 taken
1034 4327: switch (getTemplateSpecializationKind()) {
1035 : case TSK_Undeclared:
1036 : case TSK_ExplicitSpecialization:
1037 4262: return false;
1038 :
1039 : case TSK_ImplicitInstantiation:
1040 : case TSK_ExplicitInstantiationDeclaration:
1041 : case TSK_ExplicitInstantiationDefinition:
1042 : // Handle below.
1043 : break;
1044 : }
1045 :
1046 65: const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
1047 65: Stmt *Pattern = 0;
65: branch 0 taken
0: branch 1 not taken
1048 65: if (PatternDecl)
1049 65: Pattern = PatternDecl->getBody(PatternDecl);
1050 :
65: branch 0 taken
0: branch 1 not taken
65: branch 2 taken
0: branch 3 not taken
1051 65: if (Pattern && PatternDecl)
1052 65: return PatternDecl->isInlined();
1053 :
1054 0: return false;
1055 : }
1056 :
1057 : /// \brief For an inline function definition in C or C++, determine whether the
1058 : /// definition will be externally visible.
1059 : ///
1060 : /// Inline function definitions are always available for inlining optimizations.
1061 : /// However, depending on the language dialect, declaration specifiers, and
1062 : /// attributes, the definition of an inline function may or may not be
1063 : /// "externally" visible to other translation units in the program.
1064 : ///
1065 : /// In C99, inline definitions are not externally visible by default. However,
1066 : /// if even one of the global-scope declarations is marked "extern inline", the
1067 : /// inline definition becomes externally visible (C99 6.7.4p6).
1068 : ///
1069 : /// In GNU89 mode, or if the gnu_inline attribute is attached to the function
1070 : /// definition, we use the GNU semantics for inline, which are nearly the
1071 : /// opposite of C99 semantics. In particular, "inline" by itself will create
1072 : /// an externally visible symbol, but "extern inline" will not create an
1073 : /// externally visible symbol.
1074 113: bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
113: branch 1 taken
0: branch 2 not taken
1075 113: assert(isThisDeclarationADefinition() && "Must have the function definition");
113: branch 1 taken
0: branch 2 not taken
1076 113: assert(isInlined() && "Function must be inline");
1077 113: ASTContext &Context = getASTContext();
1078 :
54: branch 1 taken
59: branch 2 taken
13: branch 4 taken
41: branch 5 taken
72: branch 6 taken
41: branch 7 taken
1079 167: if (!Context.getLangOptions().C99 || hasAttr<GNUInlineAttr>()) {
1080 : // GNU inline semantics. Based on a number of examples, we came up with the
1081 : // following heuristic: if the "inline" keyword is present on a
1082 : // declaration of the function but "extern" is not present on that
1083 : // declaration, then the symbol is externally visible. Otherwise, the GNU
1084 : // "extern inline" semantics applies and the symbol is not externally
1085 : // visible.
93: branch 4 taken
30: branch 5 taken
1086 123: for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
1087 : Redecl != RedeclEnd;
1088 : ++Redecl) {
83: branch 2 taken
10: branch 3 taken
42: branch 6 taken
41: branch 7 taken
42: branch 8 taken
51: branch 9 taken
1089 93: if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != Extern)
1090 42: return true;
1091 : }
1092 :
1093 : // GNU "extern inline" semantics; no externally visible symbol.
1094 30: return false;
1095 : }
1096 :
1097 : // C99 6.7.4p6:
1098 : // [...] If all of the file scope declarations for a function in a
1099 : // translation unit include the inline function specifier without extern,
1100 : // then the definition in that translation unit is an inline definition.
52: branch 4 taken
12: branch 5 taken
1101 64: for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
1102 : Redecl != RedeclEnd;
1103 : ++Redecl) {
1104 : // Only consider file-scope declarations in this test.
52: branch 3 taken
0: branch 4 not taken
1105 52: if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
1106 0: continue;
1107 :
44: branch 2 taken
8: branch 3 taken
21: branch 6 taken
23: branch 7 taken
29: branch 8 taken
23: branch 9 taken
1108 52: if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == Extern)
1109 29: return true; // Not an inline definition
1110 : }
1111 :
1112 : // C99 6.7.4p6:
1113 : // An inline definition does not provide an external definition for the
1114 : // function, and does not forbid an external definition in another
1115 : // translation unit.
1116 12: return false;
1117 : }
1118 :
1119 : /// getOverloadedOperator - Which C++ overloaded operator this
1120 : /// function represents, if any.
1121 8353: OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
1203: branch 2 taken
7150: branch 3 taken
1122 8353: if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
1123 1203: return getDeclName().getCXXOverloadedOperator();
1124 : else
1125 7150: return OO_None;
1126 : }
1127 :
1128 : /// getLiteralIdentifier - The literal suffix identifier this function
1129 : /// represents, if any.
1130 7381: const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
21: branch 2 taken
7360: branch 3 taken
1131 7381: if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName)
1132 21: return getDeclName().getCXXLiteralIdentifier();
1133 : else
1134 7360: return 0;
1135 : }
1136 :
1137 26838: FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
1143: branch 1 taken
25695: branch 2 taken
1138 26838: if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
1139 1143: return cast<FunctionDecl>(Info->getInstantiatedFrom());
1140 :
1141 25695: return 0;
1142 : }
1143 :
1144 27299: MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const {
1145 27299: return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
1146 : }
1147 :
1148 : void
1149 : FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD,
1150 582: TemplateSpecializationKind TSK) {
1151 : assert(TemplateOrSpecialization.isNull() &&
582: branch 1 taken
0: branch 2 not taken
1152 582: "Member function is already a specialization");
1153 : MemberSpecializationInfo *Info
582: branch 2 taken
0: branch 3 not taken
1154 1164: = new (getASTContext()) MemberSpecializationInfo(FD, TSK);
1155 582: TemplateOrSpecialization = Info;
1156 582: }
1157 :
1158 4928: bool FunctionDecl::isImplicitlyInstantiable() const {
1159 : // If this function already has a definition or is invalid, it can't be
1160 : // implicitly instantiated.
4912: branch 1 taken
16: branch 2 taken
0: branch 4 not taken
4912: branch 5 taken
16: branch 6 taken
4912: branch 7 taken
1161 4928: if (isInvalidDecl() || getBody())
1162 16: return false;
1163 :
4394: branch 1 taken
500: branch 2 taken
18: branch 3 taken
1164 4912: switch (getTemplateSpecializationKind()) {
1165 : case TSK_Undeclared:
1166 : case TSK_ExplicitSpecialization:
1167 : case TSK_ExplicitInstantiationDefinition:
1168 4394: return false;
1169 :
1170 : case TSK_ImplicitInstantiation:
1171 500: return true;
1172 :
1173 : case TSK_ExplicitInstantiationDeclaration:
1174 : // Handled below.
1175 : break;
1176 : }
1177 :
1178 : // Find the actual template from which we will instantiate.
1179 18: const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
1180 18: Stmt *Pattern = 0;
18: branch 0 taken
0: branch 1 not taken
1181 18: if (PatternDecl)
1182 18: Pattern = PatternDecl->getBody(PatternDecl);
1183 :
1184 : // C++0x [temp.explicit]p9:
1185 : // Except for inline functions, other explicit instantiation declarations
1186 : // have the effect of suppressing the implicit instantiation of the entity
1187 : // to which they refer.
18: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
18: branch 3 taken
1188 18: if (!Pattern || !PatternDecl)
1189 0: return true;
1190 :
1191 18: return PatternDecl->isInlined();
1192 : }
1193 :
1194 5016: FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
408: branch 1 taken
4608: branch 2 taken
1195 5016: if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
31: branch 1 taken
405: branch 2 taken
1196 844: while (Primary->getInstantiatedFromMemberTemplate()) {
1197 : // If we have hit a point where the user provided a specialization of
1198 : // this template, we're done looking.
3: branch 1 taken
28: branch 2 taken
1199 31: if (Primary->isMemberSpecialization())
1200 3: break;
1201 :
1202 28: Primary = Primary->getInstantiatedFromMemberTemplate();
1203 : }
1204 :
1205 408: return Primary->getTemplatedDecl();
1206 : }
1207 :
1208 4608: return getInstantiatedFromMemberFunction();
1209 : }
1210 :
1211 104996: FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
3636: branch 0 taken
101360: branch 1 taken
1212 104996: if (FunctionTemplateSpecializationInfo *Info
1213 : = TemplateOrSpecialization
1214 104996: .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
1215 3636: return Info->Template.getPointer();
1216 : }
1217 101360: return 0;
1218 : }
1219 :
1220 : const TemplateArgumentList *
1221 1982: FunctionDecl::getTemplateSpecializationArgs() const {
1460: branch 0 taken
522: branch 1 taken
1222 1982: if (FunctionTemplateSpecializationInfo *Info
1223 : = TemplateOrSpecialization
1224 1982: .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
1225 1460: return Info->TemplateArguments;
1226 : }
1227 522: return 0;
1228 : }
1229 :
1230 : void
1231 : FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context,
1232 : FunctionTemplateDecl *Template,
1233 : const TemplateArgumentList *TemplateArgs,
1234 : void *InsertPos,
1235 516: TemplateSpecializationKind TSK) {
1236 : assert(TSK != TSK_Undeclared &&
0: branch 0 not taken
516: branch 1 taken
1237 516: "Must specify the type of function template specialization");
1238 : FunctionTemplateSpecializationInfo *Info
1239 516: = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
516: branch 0 taken
0: branch 1 not taken
1240 516: if (!Info)
516: branch 1 taken
0: branch 2 not taken
1241 516: Info = new (Context) FunctionTemplateSpecializationInfo;
1242 :
1243 516: Info->Function = this;
1244 516: Info->Template.setPointer(Template);
1245 516: Info->Template.setInt(TSK - 1);
1246 516: Info->TemplateArguments = TemplateArgs;
1247 516: TemplateOrSpecialization = Info;
1248 :
1249 : // Insert this function template specialization into the set of known
1250 : // function template specializations.
473: branch 0 taken
43: branch 1 taken
1251 516: if (InsertPos)
1252 473: Template->getSpecializations().InsertNode(Info, InsertPos);
1253 : else {
1254 : // Try to insert the new node. If there is an existing node, remove it
1255 : // first.
1256 : FunctionTemplateSpecializationInfo *Existing
1257 43: = Template->getSpecializations().GetOrInsertNode(Info);
43: branch 0 taken
0: branch 1 not taken
1258 43: if (Existing) {
1259 43: Template->getSpecializations().RemoveNode(Existing);
1260 43: Template->getSpecializations().GetOrInsertNode(Info);
1261 : }
1262 : }
1263 516: }
1264 :
1265 19111: TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
1266 : // For a function template specialization, query the specialization
1267 : // information object.
1268 : FunctionTemplateSpecializationInfo *FTSInfo
1269 19111: = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
1459: branch 0 taken
17652: branch 1 taken
1270 19111: if (FTSInfo)
1271 1459: return FTSInfo->getTemplateSpecializationKind();
1272 :
1273 : MemberSpecializationInfo *MSInfo
1274 17652: = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
1878: branch 0 taken
15774: branch 1 taken
1275 17652: if (MSInfo)
1276 1878: return MSInfo->getTemplateSpecializationKind();
1277 :
1278 15774: return TSK_Undeclared;
1279 : }
1280 :
1281 : void
1282 : FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
1283 308: SourceLocation PointOfInstantiation) {
76: branch 0 taken
232: branch 1 taken
1284 308: if (FunctionTemplateSpecializationInfo *FTSInfo
1285 : = TemplateOrSpecialization.dyn_cast<
1286 308: FunctionTemplateSpecializationInfo*>()) {
1287 76: FTSInfo->setTemplateSpecializationKind(TSK);
76: branch 0 taken
0: branch 1 not taken
76: branch 3 taken
0: branch 4 not taken
76: branch 7 taken
0: branch 8 not taken
76: branch 9 taken
0: branch 10 not taken
1288 76: if (TSK != TSK_ExplicitSpecialization &&
1289 : PointOfInstantiation.isValid() &&
1290 : FTSInfo->getPointOfInstantiation().isInvalid())
1291 76: FTSInfo->setPointOfInstantiation(PointOfInstantiation);
232: branch 0 taken
0: branch 1 not taken
1292 232: } else if (MemberSpecializationInfo *MSInfo
1293 232: = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) {
1294 232: MSInfo->setTemplateSpecializationKind(TSK);
212: branch 0 taken
20: branch 1 taken
212: branch 3 taken
0: branch 4 not taken
209: branch 7 taken
3: branch 8 taken
209: branch 9 taken
23: branch 10 taken
1295 232: if (TSK != TSK_ExplicitSpecialization &&
1296 : PointOfInstantiation.isValid() &&
1297 : MSInfo->getPointOfInstantiation().isInvalid())
1298 209: MSInfo->setPointOfInstantiation(PointOfInstantiation);
1299 : } else
1300 0: assert(false && "Function cannot have a template specialization kind");
1301 308: }
1302 :
1303 5: SourceLocation FunctionDecl::getPointOfInstantiation() const {
2: branch 0 taken
3: branch 1 taken
1304 5: if (FunctionTemplateSpecializationInfo *FTSInfo
1305 : = TemplateOrSpecialization.dyn_cast<
1306 5: FunctionTemplateSpecializationInfo*>())
1307 2: return FTSInfo->getPointOfInstantiation();
3: branch 0 taken
0: branch 1 not taken
1308 3: else if (MemberSpecializationInfo *MSInfo
1309 3: = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>())
1310 3: return MSInfo->getPointOfInstantiation();
1311 :
1312 0: return SourceLocation();
1313 : }
1314 :
1315 22504: bool FunctionDecl::isOutOfLine() const {
1533: branch 1 taken
20971: branch 2 taken
1316 22504: if (Decl::isOutOfLine())
1317 1533: return true;
1318 :
1319 : // If this function was instantiated from a member function of a
1320 : // class template, check whether that member function was defined out-of-line.
293: branch 1 taken
20678: branch 2 taken
1321 20971: if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) {
1322 : const FunctionDecl *Definition;
293: branch 1 taken
0: branch 2 not taken
1323 293: if (FD->getBody(Definition))
1324 293: return Definition->isOutOfLine();
1325 : }
1326 :
1327 : // If this function was instantiated from a function template,
1328 : // check whether that function template was defined out-of-line.
8: branch 1 taken
20670: branch 2 taken
1329 20678: if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) {
1330 : const FunctionDecl *Definition;
8: branch 2 taken
0: branch 3 not taken
1331 8: if (FunTmpl->getTemplatedDecl()->getBody(Definition))
1332 8: return Definition->isOutOfLine();
1333 : }
1334 :
1335 20670: return false;
1336 : }
1337 :
1338 : //===----------------------------------------------------------------------===//
1339 : // FieldDecl Implementation
1340 : //===----------------------------------------------------------------------===//
1341 :
1342 : FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1343 : IdentifierInfo *Id, QualType T,
1344 5209: TypeSourceInfo *TInfo, Expr *BW, bool Mutable) {
5209: branch 1 taken
0: branch 2 not taken
1345 5209: return new (C) FieldDecl(Decl::Field, DC, L, Id, T, TInfo, BW, Mutable);
1346 : }
1347 :
1348 5697: bool FieldDecl::isAnonymousStructOrUnion() const {
77: branch 1 taken
5620: branch 2 taken
0: branch 5 not taken
77: branch 6 taken
5620: branch 7 taken
77: branch 8 taken
1349 5697: if (!isImplicit() || getDeclName())
1350 5620: return false;
1351 :
77: branch 3 taken
0: branch 4 not taken
1352 77: if (const RecordType *Record = getType()->getAs<RecordType>())
1353 77: return Record->getDecl()->isAnonymousStructOrUnion();
1354 :
1355 0: return false;
1356 : }
1357 :
1358 : //===----------------------------------------------------------------------===//
1359 : // TagDecl Implementation
1360 : //===----------------------------------------------------------------------===//
1361 :
1362 22260: SourceRange TagDecl::getSourceRange() const {
22257: branch 1 taken
3: branch 2 taken
1363 22260: SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
1364 22260: return SourceRange(TagKeywordLoc, E);
1365 : }
1366 :
1367 44287: TagDecl* TagDecl::getCanonicalDecl() {
1368 44287: return getFirstDeclaration();
1369 : }
1370 :
1371 7007: void TagDecl::startDefinition() {
6923: branch 1 taken
84: branch 2 taken
1372 7007: if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
1373 6923: TagT->decl.setPointer(this);
1374 6923: TagT->decl.setInt(1);
1375 : }
1376 :
4836: branch 1 taken
2171: branch 2 taken
1377 7007: if (isa<CXXRecordDecl>(this)) {
1378 4836: CXXRecordDecl *D = cast<CXXRecordDecl>(this);
1379 : struct CXXRecordDecl::DefinitionData *Data =
4836: branch 2 taken
0: branch 3 not taken
1380 4836: new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
93: branch 0 taken
4836: branch 1 taken
1381 4929: do {
1382 4929: D->DefinitionData = Data;
1383 4929: D = cast_or_null<CXXRecordDecl>(D->getPreviousDeclaration());
1384 : } while (D);
1385 : }
1386 7007: }
1387 :
1388 7154: void TagDecl::completeDefinition() {
1389 : assert((!isa<CXXRecordDecl>(this) ||
1390 : cast<CXXRecordDecl>(this)->hasDefinition()) &&
4832: branch 1 taken
2322: branch 2 taken
4832: branch 5 taken
0: branch 6 not taken
1391 7154: "definition completed but not started");
1392 :
1393 7154: IsDefinition = true;
7070: branch 1 taken
84: branch 2 taken
1394 7154: if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
1395 : assert(TagT->decl.getPointer() == this &&
7070: branch 1 taken
0: branch 2 not taken
1396 7070: "Attempt to redefine a tag definition?");
1397 7070: TagT->decl.setInt(0);
1398 : }
1399 7154: }
1400 :
1401 23175: TagDecl* TagDecl::getDefinition(ASTContext& C) const {
23028: branch 1 taken
147: branch 2 taken
1402 23175: if (isDefinition())
1403 23028: return const_cast<TagDecl *>(this);
1404 :
153: branch 4 taken
147: branch 5 taken
1405 300: for (redecl_iterator R = redecls_begin(), REnd = redecls_end();
1406 : R != REnd; ++R)
0: branch 2 not taken
153: branch 3 taken
1407 153: if (R->isDefinition())
1408 0: return *R;
1409 :
1410 147: return 0;
1411 : }
1412 :
1413 8461: TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) {
0: branch 0 not taken
6593: branch 1 taken
1088: branch 2 taken
375: branch 3 taken
405: branch 4 taken
1414 8461: switch (TypeSpec) {
1415 0: default: llvm_unreachable("unexpected type specifier");
1416 6593: case DeclSpec::TST_struct: return TK_struct;
1417 1088: case DeclSpec::TST_class: return TK_class;
1418 375: case DeclSpec::TST_union: return TK_union;
1419 405: case DeclSpec::TST_enum: return TK_enum;
1420 : }
1421 : }
1422 :
1423 : //===----------------------------------------------------------------------===//
1424 : // EnumDecl Implementation
1425 : //===----------------------------------------------------------------------===//
1426 :
1427 : EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1428 : IdentifierInfo *Id, SourceLocation TKL,
1429 689: EnumDecl *PrevDecl) {
689: branch 1 taken
0: branch 2 not taken
1430 689: EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL);
1431 689: C.getTypeDeclType(Enum, PrevDecl);
1432 689: return Enum;
1433 : }
1434 :
1435 0: void EnumDecl::Destroy(ASTContext& C) {
1436 0: Decl::Destroy(C);
1437 0: }
1438 :
1439 : void EnumDecl::completeDefinition(ASTContext &C,
1440 : QualType NewType,
1441 668: QualType NewPromotionType) {
668: branch 1 taken
0: branch 2 not taken
1442 668: assert(!isDefinition() && "Cannot redefine enums!");
1443 668: IntegerType = NewType;
1444 668: PromotionType = NewPromotionType;
1445 668: TagDecl::completeDefinition();
1446 668: }
1447 :
1448 : //===----------------------------------------------------------------------===//
1449 : // RecordDecl Implementation
1450 : //===----------------------------------------------------------------------===//
1451 :
1452 : RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
1453 : IdentifierInfo *Id, RecordDecl *PrevDecl,
1454 12453: SourceLocation TKL)
1455 12453: : TagDecl(DK, TK, DC, L, Id, PrevDecl, TKL) {
1456 12453: HasFlexibleArrayMember = false;
1457 12453: AnonymousStructOrUnion = false;
1458 12453: HasObjectMember = false;
2213: branch 1 taken
0: branch 2 not taken
10240: branch 5 taken
0: branch 6 not taken
1459 12453: assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
1460 12453: }
1461 :
1462 : RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
1463 : SourceLocation L, IdentifierInfo *Id,
1464 2213: SourceLocation TKL, RecordDecl* PrevDecl) {
1465 :
2213: branch 1 taken
0: branch 2 not taken
1466 2213: RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, PrevDecl, TKL);
1467 2213: C.getTypeDeclType(R, PrevDecl);
1468 2213: return R;
1469 : }
1470 :
1471 0: RecordDecl::~RecordDecl() {
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
1472 0: }
1473 :
1474 0: void RecordDecl::Destroy(ASTContext& C) {
1475 0: TagDecl::Destroy(C);
1476 0: }
1477 :
1478 12149: bool RecordDecl::isInjectedClassName() const {
1479 : return isImplicit() && getDeclName() && getDeclContext()->isRecord() &&
8286: branch 1 taken
3863: branch 2 taken
8286: branch 5 taken
0: branch 6 not taken
8286: branch 9 taken
0: branch 10 not taken
8286: branch 16 taken
0: branch 17 not taken
1480 12149: cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName();
1481 : }
1482 :
1483 : /// completeDefinition - Notes that the definition of this type is now
1484 : /// complete.
1485 6486: void RecordDecl::completeDefinition(ASTContext& C) {
6486: branch 1 taken
0: branch 2 not taken
1486 6486: assert(!isDefinition() && "Cannot redefine record!");
1487 6486: TagDecl::completeDefinition();
1488 6486: }
1489 :
1490 : //===----------------------------------------------------------------------===//
1491 : // BlockDecl Implementation
1492 : //===----------------------------------------------------------------------===//
1493 :
1494 0: BlockDecl::~BlockDecl() {
0: branch 2 not taken
0: branch 3 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 12 not taken
0: branch 13 not taken
1495 0: }
1496 :
1497 0: void BlockDecl::Destroy(ASTContext& C) {
0: branch 0 not taken
0: branch 1 not taken
1498 0: if (Body)
1499 0: Body->Destroy(C);
1500 :
0: branch 2 not taken
0: branch 3 not taken
1501 0: for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
1502 0: (*I)->Destroy(C);
1503 :
1504 0: C.Deallocate(ParamInfo);
1505 0: Decl::Destroy(C);
1506 0: }
1507 :
1508 : void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo,
1509 258: unsigned NParms) {
0: branch 0 not taken
258: branch 1 taken
1510 258: assert(ParamInfo == 0 && "Already has param info!");
1511 :
1512 : // Zero params -> null pointer.
58: branch 0 taken
200: branch 1 taken
1513 258: if (NParms) {
1514 58: NumParams = NParms;
1515 58: void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
1516 58: ParamInfo = new (Mem) ParmVarDecl*[NumParams];
1517 58: memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
1518 : }
1519 258: }
1520 :
1521 302: unsigned BlockDecl::getNumParams() const {
1522 302: return NumParams;
1523 : }
1524 :
1525 :
1526 : //===----------------------------------------------------------------------===//
1527 : // Other Decl Allocation/Deallocation Method Implementations
1528 : //===----------------------------------------------------------------------===//
1529 :
1530 2250: TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
2250: branch 1 taken
0: branch 2 not taken
1531 2250: return new (C) TranslationUnitDecl(C);
1532 : }
1533 :
1534 : NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
1535 710: SourceLocation L, IdentifierInfo *Id) {
710: branch 1 taken
0: branch 2 not taken
1536 710: return new (C) NamespaceDecl(DC, L, Id);
1537 : }
1538 :
1539 0: void NamespaceDecl::Destroy(ASTContext& C) {
1540 : // NamespaceDecl uses "NextDeclarator" to chain namespace declarations
1541 : // together. They are all top-level Decls.
1542 :
1543 0: this->~NamespaceDecl();
1544 0: C.Deallocate((void *)this);
1545 0: }
1546 :
1547 :
1548 : ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
1549 3333: SourceLocation L, IdentifierInfo *Id, QualType T) {
3333: branch 1 taken
0: branch 2 not taken
1550 3333: return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T);
1551 : }
1552 :
1553 : FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
1554 : SourceLocation L,
1555 : DeclarationName N, QualType T,
1556 : TypeSourceInfo *TInfo,
1557 : StorageClass S, bool isInline,
1558 12814: bool hasWrittenPrototype) {
1559 : FunctionDecl *New
12814: branch 1 taken
0: branch 2 not taken
1560 12814: = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline);
1561 12814: New->HasWrittenPrototype = hasWrittenPrototype;
1562 12814: return New;
1563 : }
1564 :
1565 265: BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
265: branch 1 taken
0: branch 2 not taken
1566 265: return new (C) BlockDecl(DC, L);
1567 : }
1568 :
1569 : EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
1570 : SourceLocation L,
1571 : IdentifierInfo *Id, QualType T,
1572 1602: Expr *E, const llvm::APSInt &V) {
1602: branch 1 taken
0: branch 2 not taken
1596: branch 3 taken
6: branch 4 taken
1573 1602: return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
1574 : }
1575 :
1576 0: void EnumConstantDecl::Destroy(ASTContext& C) {
0: branch 0 not taken
0: branch 1 not taken
1577 0: if (Init) Init->Destroy(C);
1578 0: Decl::Destroy(C);
1579 0: }
1580 :
1581 : TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
1582 : SourceLocation L, IdentifierInfo *Id,
1583 8891: TypeSourceInfo *TInfo) {
8891: branch 1 taken
0: branch 2 not taken
1584 8891: return new (C) TypedefDecl(DC, L, Id, TInfo);
1585 : }
1586 :
1587 : // Anchor TypedefDecl's vtable here.
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
1588 0: TypedefDecl::~TypedefDecl() {}
1589 :
1590 : FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
1591 : SourceLocation L,
1592 15: StringLiteral *Str) {
15: branch 1 taken
0: branch 2 not taken
1593 15: return new (C) FileScopeAsmDecl(DC, L, Str);
1594 : }
Generated: 2010-02-10 01:31 by zcov