 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
74.0% |
191 / 258 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
89.1% |
230 / 258 |
| |
|
Line Coverage: |
76.2% |
342 / 449 |
| |
 |
|
 |
1 : //===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
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 contains code to print types from Clang's type system.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/AST/Decl.h"
15 : #include "clang/AST/DeclObjC.h"
16 : #include "clang/AST/DeclTemplate.h"
17 : #include "clang/AST/Expr.h"
18 : #include "clang/AST/Type.h"
19 : #include "clang/AST/PrettyPrinter.h"
20 : #include "clang/Basic/LangOptions.h"
21 : #include "llvm/ADT/StringExtras.h"
22 : #include "llvm/Support/raw_ostream.h"
23 : using namespace clang;
24 :
25 : namespace {
26 : class TypePrinter {
27 : PrintingPolicy Policy;
28 :
29 : public:
30 5934: explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
31 :
32 : void Print(QualType T, std::string &S);
33 : void PrintTag(const TagType *T, std::string &S);
34 : #define ABSTRACT_TYPE(CLASS, PARENT)
35 : #define TYPE(CLASS, PARENT) \
36 : void Print##CLASS(const CLASS##Type *T, std::string &S);
37 : #include "clang/AST/TypeNodes.def"
38 : };
39 : }
40 :
41 929: static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
283: branch 0 taken
646: branch 1 taken
42 929: if (TypeQuals & Qualifiers::Const) {
2: branch 1 taken
281: branch 2 taken
43 283: if (!S.empty()) S += ' ';
44 283: S += "const";
45 : }
35: branch 0 taken
894: branch 1 taken
46 929: if (TypeQuals & Qualifiers::Volatile) {
15: branch 1 taken
20: branch 2 taken
47 35: if (!S.empty()) S += ' ';
48 35: S += "volatile";
49 : }
0: branch 0 not taken
929: branch 1 taken
50 929: if (TypeQuals & Qualifiers::Restrict) {
0: branch 1 not taken
0: branch 2 not taken
51 0: if (!S.empty()) S += ' ';
52 0: S += "restrict";
53 : }
54 929: }
55 :
56 8455: void TypePrinter::Print(QualType T, std::string &S) {
0: branch 1 not taken
8455: branch 2 taken
57 8455: if (T.isNull()) {
58 0: S += "NULL TYPE";
59 0: return;
60 : }
61 :
12: branch 0 taken
8443: branch 1 taken
8: branch 4 taken
4: branch 5 taken
8: branch 6 taken
8447: branch 7 taken
62 8455: if (Policy.SuppressSpecifiers && T->isSpecifierType())
63 8: return;
64 :
65 : // Print qualifiers as appropriate.
66 8447: Qualifiers Quals = T.getLocalQualifiers();
304: branch 1 taken
8143: branch 2 taken
67 8447: if (!Quals.empty()) {
68 304: std::string TQS;
69 304: Quals.getAsStringInternal(TQS, Policy);
70 :
198: branch 1 taken
106: branch 2 taken
71 304: if (!S.empty()) {
72 198: TQS += ' ';
73 198: TQS += S;
74 : }
75 304: std::swap(S, TQS);
76 : }
77 :
3393: branch 2 taken
11: branch 3 taken
1121: branch 4 taken
45: branch 5 taken
166: branch 6 taken
6: branch 7 taken
59: branch 8 taken
77: branch 9 taken
8: branch 10 taken
0: branch 11 not taken
1: branch 12 taken
0: branch 13 not taken
9: branch 14 taken
13: branch 15 taken
336: branch 16 taken
27: branch 17 taken
0: branch 18 not taken
732: branch 19 taken
5: branch 20 taken
1: branch 21 taken
0: branch 22 not taken
1751: branch 23 taken
51: branch 24 taken
29: branch 25 taken
24: branch 26 taken
174: branch 27 taken
57: branch 28 taken
33: branch 29 taken
0: branch 30 not taken
29: branch 31 taken
289: branch 32 taken
0: branch 33 not taken
78 8447: switch (T->getTypeClass()) {
79 : #define ABSTRACT_TYPE(CLASS, PARENT)
80 : #define TYPE(CLASS, PARENT) case Type::CLASS: \
81 : Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S); \
82 : break;
83 : #include "clang/AST/TypeNodes.def"
84 : }
85 : }
86 :
87 3393: void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
1890: branch 1 taken
1503: branch 2 taken
88 3393: if (S.empty()) {
89 1890: S = T->getName(Policy.LangOpts);
90 : } else {
91 : // Prefix the basic type, e.g. 'int X'.
92 1503: S = ' ' + S;
93 1503: S = T->getName(Policy.LangOpts) + S;
94 : }
95 3393: }
96 :
97 11: void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
98 11: Print(T->getElementType(), S);
99 11: S = "_Complex " + S;
100 11: }
101 :
102 1121: void TypePrinter::PrintPointer(const PointerType *T, std::string &S) {
103 1121: S = '*' + S;
104 :
105 : // Handle things like 'int (*A)[4];' correctly.
106 : // FIXME: this should include vectors, but vectors use attributes I guess.
14: branch 2 taken
1107: branch 3 taken
107 1121: if (isa<ArrayType>(T->getPointeeType()))
108 14: S = '(' + S + ')';
109 :
110 1121: Print(T->getPointeeType(), S);
111 1121: }
112 :
113 45: void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
114 45: S = '^' + S;
115 45: Print(T->getPointeeType(), S);
116 45: }
117 :
118 : void TypePrinter::PrintLValueReference(const LValueReferenceType *T,
119 166: std::string &S) {
120 166: S = '&' + S;
121 :
122 : // Handle things like 'int (&A)[4];' correctly.
123 : // FIXME: this should include vectors, but vectors use attributes I guess.
0: branch 2 not taken
166: branch 3 taken
124 166: if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
125 0: S = '(' + S + ')';
126 :
127 166: Print(T->getPointeeTypeAsWritten(), S);
128 166: }
129 :
130 : void TypePrinter::PrintRValueReference(const RValueReferenceType *T,
131 6: std::string &S) {
132 6: S = "&&" + S;
133 :
134 : // Handle things like 'int (&&A)[4];' correctly.
135 : // FIXME: this should include vectors, but vectors use attributes I guess.
0: branch 2 not taken
6: branch 3 taken
136 6: if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
137 0: S = '(' + S + ')';
138 :
139 6: Print(T->getPointeeTypeAsWritten(), S);
140 6: }
141 :
142 : void TypePrinter::PrintMemberPointer(const MemberPointerType *T,
143 59: std::string &S) {
144 59: std::string C;
145 59: Print(QualType(T->getClass(), 0), C);
146 59: C += "::*";
147 59: S = C + S;
148 :
149 : // Handle things like 'int (Cls::*A)[4];' correctly.
150 : // FIXME: this should include vectors, but vectors use attributes I guess.
0: branch 2 not taken
59: branch 3 taken
151 59: if (isa<ArrayType>(T->getPointeeType()))
152 0: S = '(' + S + ')';
153 :
154 59: Print(T->getPointeeType(), S);
155 59: }
156 :
157 : void TypePrinter::PrintConstantArray(const ConstantArrayType *T,
158 77: std::string &S) {
159 77: S += '[';
160 77: S += llvm::utostr(T->getSize().getZExtValue());
161 77: S += ']';
162 :
163 77: Print(T->getElementType(), S);
164 77: }
165 :
166 : void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T,
167 8: std::string &S) {
168 8: S += "[]";
169 8: Print(T->getElementType(), S);
170 8: }
171 :
172 : void TypePrinter::PrintVariableArray(const VariableArrayType *T,
173 0: std::string &S) {
174 0: S += '[';
175 :
0: branch 2 not taken
0: branch 3 not taken
176 0: if (T->getIndexTypeQualifiers().hasQualifiers()) {
177 0: AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
178 0: S += ' ';
179 : }
180 :
0: branch 1 not taken
0: branch 2 not taken
181 0: if (T->getSizeModifier() == VariableArrayType::Static)
182 0: S += "static";
0: branch 1 not taken
0: branch 2 not taken
183 0: else if (T->getSizeModifier() == VariableArrayType::Star)
184 0: S += '*';
185 :
0: branch 1 not taken
0: branch 2 not taken
186 0: if (T->getSizeExpr()) {
187 0: std::string SStr;
188 0: llvm::raw_string_ostream s(SStr);
189 0: T->getSizeExpr()->printPretty(s, 0, Policy);
190 0: S += s.str();
191 : }
192 0: S += ']';
193 :
194 0: Print(T->getElementType(), S);
195 0: }
196 :
197 : void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T,
198 1: std::string &S) {
199 1: S += '[';
200 :
1: branch 1 taken
0: branch 2 not taken
201 1: if (T->getSizeExpr()) {
202 1: std::string SStr;
203 1: llvm::raw_string_ostream s(SStr);
204 1: T->getSizeExpr()->printPretty(s, 0, Policy);
205 1: S += s.str();
206 : }
207 1: S += ']';
208 :
209 1: Print(T->getElementType(), S);
210 1: }
211 :
212 : void TypePrinter::PrintDependentSizedExtVector(
213 : const DependentSizedExtVectorType *T,
214 0: std::string &S) {
215 0: Print(T->getElementType(), S);
216 :
217 0: S += " __attribute__((ext_vector_type(";
0: branch 1 not taken
0: branch 2 not taken
218 0: if (T->getSizeExpr()) {
219 0: std::string SStr;
220 0: llvm::raw_string_ostream s(SStr);
221 0: T->getSizeExpr()->printPretty(s, 0, Policy);
222 0: S += s.str();
223 : }
224 0: S += ")))";
225 0: }
226 :
227 9: void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
2: branch 1 taken
7: branch 2 taken
228 9: if (T->isAltiVec()) {
0: branch 1 not taken
2: branch 2 taken
229 2: if (T->isPixel())
230 0: S = "__vector __pixel " + S;
231 : else {
232 2: Print(T->getElementType(), S);
233 2: S = "__vector " + S;
234 : }
235 : } else {
236 : // FIXME: We prefer to print the size directly here, but have no way
237 : // to get the size of the type.
238 7: Print(T->getElementType(), S);
239 7: std::string V = "__attribute__((__vector_size__(";
240 7: V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
241 7: std::string ET;
242 7: Print(T->getElementType(), ET);
243 7: V += " * sizeof(" + ET + ")))) ";
244 7: S = V + S;
245 : }
246 9: }
247 :
248 13: void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
249 13: S += " __attribute__((ext_vector_type(";
250 13: S += llvm::utostr_32(T->getNumElements());
251 13: S += ")))";
252 13: Print(T->getElementType(), S);
253 13: }
254 :
255 : void TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
256 336: std::string &S) {
257 : // If needed for precedence reasons, wrap the inner part in grouping parens.
226: branch 1 taken
110: branch 2 taken
258 336: if (!S.empty())
259 226: S = "(" + S + ")";
260 :
261 336: S += "(";
262 336: std::string Tmp;
263 336: PrintingPolicy ParamPolicy(Policy);
264 336: ParamPolicy.SuppressSpecifiers = false;
394: branch 1 taken
336: branch 2 taken
265 730: for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
163: branch 0 taken
231: branch 1 taken
266 394: if (i) S += ", ";
267 394: Print(T->getArgType(i), Tmp);
268 394: S += Tmp;
269 394: Tmp.clear();
270 : }
271 :
26: branch 1 taken
310: branch 2 taken
272 336: if (T->isVariadic()) {
25: branch 1 taken
1: branch 2 taken
273 26: if (T->getNumArgs())
274 25: S += ", ";
275 26: S += "...";
104: branch 1 taken
206: branch 2 taken
61: branch 3 taken
43: branch 4 taken
61: branch 5 taken
249: branch 6 taken
276 310: } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
277 : // Do not emit int() if we have a proto, emit 'int(void)'.
278 61: S += "void";
279 : }
280 :
281 336: S += ")";
282 :
334: branch 1 taken
1: branch 2 taken
0: branch 3 not taken
1: branch 4 taken
283 336: switch(T->getCallConv()) {
284 : case CC_Default:
285 334: default: break;
286 : case CC_C:
287 1: S += " __attribute__((cdecl))";
288 1: break;
289 : case CC_X86StdCall:
290 0: S += " __attribute__((stdcall))";
291 0: break;
292 : case CC_X86FastCall:
293 1: S += " __attribute__((fastcall))";
294 : break;
295 : }
1: branch 1 taken
335: branch 2 taken
296 336: if (T->getNoReturnAttr())
297 1: S += " __attribute__((noreturn))";
298 :
299 :
11: branch 1 taken
325: branch 2 taken
300 336: if (T->hasExceptionSpec()) {
301 11: S += " throw(";
0: branch 1 not taken
11: branch 2 taken
302 11: if (T->hasAnyExceptionSpec())
303 0: S += "...";
304 : else
7: branch 2 taken
11: branch 3 taken
305 18: for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) {
0: branch 0 not taken
7: branch 1 taken
306 7: if (I)
307 0: S += ", ";
308 :
309 7: std::string ExceptionType;
310 7: Print(T->getExceptionType(I), ExceptionType);
311 7: S += ExceptionType;
312 : }
313 11: S += ")";
314 : }
315 :
316 336: AppendTypeQualList(S, T->getTypeQuals());
317 :
318 336: Print(T->getResultType(), S);
319 336: }
320 :
321 : void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
322 27: std::string &S) {
323 : // If needed for precedence reasons, wrap the inner part in grouping parens.
16: branch 1 taken
11: branch 2 taken
324 27: if (!S.empty())
325 16: S = "(" + S + ")";
326 :
327 27: S += "()";
0: branch 1 not taken
27: branch 2 taken
328 27: if (T->getNoReturnAttr())
329 0: S += " __attribute__((noreturn))";
330 27: Print(T->getResultType(), S);
331 27: }
332 :
333 : void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
334 0: std::string &S) {
335 0: IdentifierInfo *II = T->getDecl()->getIdentifier();
0: branch 1 not taken
0: branch 2 not taken
336 0: if (S.empty())
337 0: S = II->getName().str();
338 : else
339 0: S = II->getName().str() + ' ' + S;
340 0: }
341 :
342 732: void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
129: branch 1 taken
603: branch 2 taken
343 732: if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
344 129: S = ' ' + S;
345 732: S = T->getDecl()->getIdentifier()->getName().str() + S;
346 732: }
347 :
348 5: void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
3: branch 1 taken
2: branch 2 taken
349 5: if (!S.empty()) // Prefix the basic type, e.g. 'typeof(e) X'.
350 3: S = ' ' + S;
351 5: std::string Str;
352 5: llvm::raw_string_ostream s(Str);
353 5: T->getUnderlyingExpr()->printPretty(s, 0, Policy);
354 5: S = "typeof " + s.str() + S;
355 5: }
356 :
357 1: void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) {
0: branch 1 not taken
1: branch 2 taken
358 1: if (!S.empty()) // Prefix the basic type, e.g. 'typeof(t) X'.
359 0: S = ' ' + S;
360 1: std::string Tmp;
361 1: Print(T->getUnderlyingType(), Tmp);
362 1: S = "typeof(" + Tmp + ")" + S;
363 1: }
364 :
365 0: void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
0: branch 1 not taken
0: branch 2 not taken
366 0: if (!S.empty()) // Prefix the basic type, e.g. 'decltype(t) X'.
367 0: S = ' ' + S;
368 0: std::string Str;
369 0: llvm::raw_string_ostream s(Str);
370 0: T->getUnderlyingExpr()->printPretty(s, 0, Policy);
371 0: S = "decltype(" + s.str() + ")" + S;
372 0: }
373 :
374 1802: void TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
3: branch 0 taken
1799: branch 1 taken
375 1802: if (Policy.SuppressTag)
376 3: return;
377 :
382: branch 1 taken
1417: branch 2 taken
378 1799: if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
379 382: InnerString = ' ' + InnerString;
380 :
115: branch 0 taken
1684: branch 1 taken
381 1799: const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
382 : const char *ID;
1765: branch 2 taken
34: branch 3 taken
383 1799: if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
384 1765: ID = II->getNameStart();
3: branch 2 taken
31: branch 3 taken
385 34: else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
386 3: Kind = 0;
3: branch 1 taken
0: branch 2 not taken
387 3: assert(Typedef->getIdentifier() && "Typedef without identifier?");
388 3: ID = Typedef->getIdentifier()->getNameStart();
389 : } else
390 31: ID = "<anonymous>";
391 :
392 : // If this is a class template specialization, print the template
393 : // arguments.
124: branch 0 taken
1675: branch 1 taken
394 1799: if (ClassTemplateSpecializationDecl *Spec
395 1799: = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
396 124: const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
397 : std::string TemplateArgsStr
398 : = TemplateSpecializationType::PrintTemplateArgumentList(
399 : TemplateArgs.getFlatArgumentList(),
400 : TemplateArgs.flat_size(),
401 124: Policy);
402 124: InnerString = TemplateArgsStr + InnerString;
403 : }
404 :
1727: branch 0 taken
72: branch 1 taken
405 1799: if (!Policy.SuppressScope) {
406 : // Compute the full nested-name-specifier for this type. In C,
407 : // this will always be empty.
408 1727: std::string ContextStr;
343: branch 5 taken
1727: branch 6 taken
409 2070: for (DeclContext *DC = T->getDecl()->getDeclContext();
410 : !DC->isTranslationUnit(); DC = DC->getParent()) {
411 343: std::string MyPart;
227: branch 1 taken
116: branch 2 taken
412 343: if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
227: branch 1 taken
0: branch 2 not taken
413 227: if (NS->getIdentifier())
414 227: MyPart = NS->getNameAsString();
21: branch 0 taken
95: branch 1 taken
415 116: } else if (ClassTemplateSpecializationDecl *Spec
416 116: = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
417 21: const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
418 : std::string TemplateArgsStr
419 : = TemplateSpecializationType::PrintTemplateArgumentList(
420 : TemplateArgs.getFlatArgumentList(),
421 : TemplateArgs.flat_size(),
422 21: Policy);
423 21: MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
31: branch 1 taken
64: branch 2 taken
424 95: } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
0: branch 1 not taken
31: branch 2 taken
425 31: if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
426 0: MyPart = Typedef->getIdentifier()->getName();
31: branch 1 taken
0: branch 2 not taken
427 31: else if (Tag->getIdentifier())
428 31: MyPart = Tag->getIdentifier()->getName();
429 : }
430 :
279: branch 1 taken
64: branch 2 taken
431 343: if (!MyPart.empty())
432 279: ContextStr = MyPart + "::" + ContextStr;
433 : }
434 :
1681: branch 0 taken
46: branch 1 taken
435 1727: if (Kind)
436 1681: InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
437 : else
438 46: InnerString = ContextStr + ID + InnerString;
439 : } else
440 72: InnerString = ID + InnerString;
441 : }
442 :
443 1751: void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
444 1751: PrintTag(T, S);
445 1751: }
446 :
447 51: void TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
448 51: PrintTag(T, S);
449 51: }
450 :
451 29: void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
452 29: std::string TypeStr;
453 29: PrintingPolicy InnerPolicy(Policy);
454 29: InnerPolicy.SuppressTagKind = true;
455 29: TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
456 :
457 29: S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;
458 29: }
459 :
460 : void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T,
461 24: std::string &S) {
8: branch 1 taken
16: branch 2 taken
462 24: if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'.
463 8: S = ' ' + S;
464 :
1: branch 1 taken
23: branch 2 taken
465 24: if (!T->getName())
466 : S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
467 1: llvm::utostr_32(T->getIndex()) + S;
468 : else
469 23: S = T->getName()->getName().str() + S;
470 24: }
471 :
472 : void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T,
473 174: std::string &S) {
474 174: Print(T->getReplacementType(), S);
475 174: }
476 :
477 : void TypePrinter::PrintTemplateSpecialization(
478 : const TemplateSpecializationType *T,
479 57: std::string &S) {
480 57: std::string SpecString;
481 :
482 : {
483 57: llvm::raw_string_ostream OS(SpecString);
484 57: T->getTemplateName().print(OS, Policy);
485 : }
486 :
487 : SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
488 : T->getArgs(),
489 : T->getNumArgs(),
490 57: Policy);
44: branch 1 taken
13: branch 2 taken
491 57: if (S.empty())
492 44: S.swap(SpecString);
493 : else
494 13: S = SpecString + ' ' + S;
495 57: }
496 :
497 : void TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
498 33: std::string &S) {
499 33: std::string MyString;
500 :
501 : {
502 33: llvm::raw_string_ostream OS(MyString);
503 33: T->getQualifier()->print(OS, Policy);
504 : }
505 :
506 33: std::string TypeStr;
507 33: PrintingPolicy InnerPolicy(Policy);
508 33: InnerPolicy.SuppressTagKind = true;
509 33: InnerPolicy.SuppressScope = true;
510 33: TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
511 :
512 33: MyString += TypeStr;
29: branch 1 taken
4: branch 2 taken
513 33: if (S.empty())
514 29: S.swap(MyString);
515 : else
516 4: S = MyString + ' ' + S;
517 33: }
518 :
519 0: void TypePrinter::PrintTypename(const TypenameType *T, std::string &S) {
520 0: std::string MyString;
521 :
522 : {
523 0: llvm::raw_string_ostream OS(MyString);
524 0: OS << "typename ";
525 0: T->getQualifier()->print(OS, Policy);
526 :
0: branch 1 not taken
0: branch 2 not taken
527 0: if (const IdentifierInfo *Ident = T->getIdentifier())
528 0: OS << Ident->getName();
0: branch 1 not taken
0: branch 2 not taken
529 0: else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
530 0: Spec->getTemplateName().print(OS, Policy, true);
531 : OS << TemplateSpecializationType::PrintTemplateArgumentList(
532 : Spec->getArgs(),
533 : Spec->getNumArgs(),
534 0: Policy);
535 0: }
536 : }
537 :
0: branch 1 not taken
0: branch 2 not taken
538 0: if (S.empty())
539 0: S.swap(MyString);
540 : else
541 0: S = MyString + ' ' + S;
542 0: }
543 :
544 : void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T,
545 29: std::string &S) {
1: branch 1 taken
28: branch 2 taken
546 29: if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
547 1: S = ' ' + S;
548 :
549 29: std::string ObjCQIString = T->getDecl()->getNameAsString();
0: branch 1 not taken
29: branch 2 taken
550 29: if (T->getNumProtocols()) {
551 0: ObjCQIString += '<';
552 0: bool isFirst = true;
0: branch 1 not taken
0: branch 2 not taken
553 0: for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
554 0: E = T->qual_end();
555 : I != E; ++I) {
0: branch 0 not taken
0: branch 1 not taken
556 0: if (isFirst)
557 0: isFirst = false;
558 : else
559 0: ObjCQIString += ',';
560 0: ObjCQIString += (*I)->getNameAsString();
561 : }
562 0: ObjCQIString += '>';
563 : }
564 29: S = ObjCQIString + S;
565 29: }
566 :
567 : void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
568 289: std::string &S) {
569 289: std::string ObjCQIString;
570 :
277: branch 1 taken
12: branch 2 taken
87: branch 4 taken
190: branch 5 taken
99: branch 6 taken
190: branch 7 taken
571 289: if (T->isObjCIdType() || T->isObjCQualifiedIdType())
572 99: ObjCQIString = "id";
183: branch 1 taken
7: branch 2 taken
0: branch 4 not taken
183: branch 5 taken
7: branch 6 taken
183: branch 7 taken
573 190: else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
574 7: ObjCQIString = "Class";
0: branch 1 not taken
183: branch 2 taken
575 183: else if (T->isObjCSelType())
576 0: ObjCQIString = "SEL";
577 : else
578 183: ObjCQIString = T->getInterfaceDecl()->getNameAsString();
579 :
127: branch 1 taken
162: branch 2 taken
580 289: if (!T->qual_empty()) {
581 127: ObjCQIString += '<';
154: branch 1 taken
127: branch 2 taken
582 408: for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
583 127: E = T->qual_end();
584 : I != E; ++I) {
585 154: ObjCQIString += (*I)->getNameAsString();
27: branch 0 taken
127: branch 1 taken
586 154: if (I+1 != E)
587 27: ObjCQIString += ',';
588 : }
589 127: ObjCQIString += '>';
590 : }
591 :
592 : T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString,
593 289: Policy);
594 :
277: branch 1 taken
12: branch 2 taken
190: branch 4 taken
87: branch 5 taken
190: branch 6 taken
99: branch 7 taken
595 289: if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
596 190: ObjCQIString += " *"; // Don't forget the implicit pointer.
9: branch 1 taken
90: branch 2 taken
597 99: else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
598 9: S = ' ' + S;
599 :
600 289: S = ObjCQIString + S;
601 289: }
602 :
603 : static void PrintTemplateArgument(std::string &Buffer,
604 : const TemplateArgument &Arg,
605 508: const PrintingPolicy &Policy) {
0: branch 1 not taken
475: branch 2 taken
2: branch 3 taken
1: branch 4 taken
26: branch 5 taken
4: branch 6 taken
0: branch 7 not taken
0: branch 8 not taken
606 508: switch (Arg.getKind()) {
607 : case TemplateArgument::Null:
608 0: assert(false && "Null template argument");
609 : break;
610 :
611 : case TemplateArgument::Type:
612 475: Arg.getAsType().getAsStringInternal(Buffer, Policy);
613 475: break;
614 :
615 : case TemplateArgument::Declaration:
616 2: Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
617 2: break;
618 :
619 : case TemplateArgument::Template: {
620 1: llvm::raw_string_ostream s(Buffer);
621 1: Arg.getAsTemplate().print(s, Policy);
622 1: break;
623 : }
624 :
625 : case TemplateArgument::Integral:
626 26: Buffer = Arg.getAsIntegral()->toString(10, true);
627 26: break;
628 :
629 : case TemplateArgument::Expression: {
630 4: llvm::raw_string_ostream s(Buffer);
631 4: Arg.getAsExpr()->printPretty(s, 0, Policy);
632 4: break;
633 : }
634 :
635 : case TemplateArgument::Pack:
636 0: assert(0 && "FIXME: Implement!");
637 : break;
638 : }
639 508: }
640 :
641 : std::string TemplateSpecializationType::
642 : PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
643 0: const PrintingPolicy &Policy) {
644 : return PrintTemplateArgumentList(Args.getArgumentArray(),
645 : Args.size(),
646 0: Policy);
647 : }
648 :
649 : std::string
650 : TemplateSpecializationType::PrintTemplateArgumentList(
651 : const TemplateArgument *Args,
652 : unsigned NumArgs,
653 405: const PrintingPolicy &Policy) {
654 405: std::string SpecString;
655 405: SpecString += '<';
506: branch 1 taken
405: branch 2 taken
656 911: for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
103: branch 0 taken
403: branch 1 taken
657 506: if (Arg)
658 103: SpecString += ", ";
659 :
660 : // Print the argument into a string.
661 506: std::string ArgString;
662 506: PrintTemplateArgument(ArgString, Args[Arg], Policy);
663 :
664 : // If this is the first argument and its string representation
665 : // begins with the global scope specifier ('::foo'), add a space
666 : // to avoid printing the diagraph '<:'.
403: branch 0 taken
103: branch 1 taken
403: branch 3 taken
0: branch 4 not taken
0: branch 6 not taken
403: branch 7 taken
0: branch 8 not taken
506: branch 9 taken
667 506: if (!Arg && !ArgString.empty() && ArgString[0] == ':')
668 0: SpecString += ' ';
669 :
670 506: SpecString += ArgString;
671 : }
672 :
673 : // If the last character of our string is '>', add another space to
674 : // keep the two '>''s separate tokens. We don't *have* to do this in
675 : // C++0x, but it's still good hygiene.
5: branch 2 taken
400: branch 3 taken
676 405: if (SpecString[SpecString.size() - 1] == '>')
677 5: SpecString += ' ';
678 :
679 405: SpecString += '>';
680 :
681 : return SpecString;
682 : }
683 :
684 : // Sadly, repeat all that with TemplateArgLoc.
685 : std::string TemplateSpecializationType::
686 : PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
687 2: const PrintingPolicy &Policy) {
688 2: std::string SpecString;
689 2: SpecString += '<';
2: branch 1 taken
2: branch 2 taken
690 4: for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
0: branch 0 not taken
2: branch 1 taken
691 2: if (Arg)
692 0: SpecString += ", ";
693 :
694 : // Print the argument into a string.
695 2: std::string ArgString;
696 2: PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
697 :
698 : // If this is the first argument and its string representation
699 : // begins with the global scope specifier ('::foo'), add a space
700 : // to avoid printing the diagraph '<:'.
2: branch 0 taken
0: branch 1 not taken
2: branch 3 taken
0: branch 4 not taken
0: branch 6 not taken
2: branch 7 taken
0: branch 8 not taken
2: branch 9 taken
701 2: if (!Arg && !ArgString.empty() && ArgString[0] == ':')
702 0: SpecString += ' ';
703 :
704 2: SpecString += ArgString;
705 : }
706 :
707 : // If the last character of our string is '>', add another space to
708 : // keep the two '>''s separate tokens. We don't *have* to do this in
709 : // C++0x, but it's still good hygiene.
0: branch 2 not taken
2: branch 3 taken
710 2: if (SpecString[SpecString.size() - 1] == '>')
711 0: SpecString += ' ';
712 :
713 2: SpecString += '>';
714 :
715 : return SpecString;
716 : }
717 :
718 0: void QualType::dump(const char *msg) const {
719 0: std::string R = "identifier";
720 0: LangOptions LO;
721 0: getAsStringInternal(R, PrintingPolicy(LO));
0: branch 0 not taken
0: branch 1 not taken
722 0: if (msg)
723 0: llvm::errs() << msg << ": ";
724 0: llvm::errs() << R << "\n";
725 0: }
726 0: void QualType::dump() const {
727 0: dump("");
728 0: }
729 :
730 0: void Type::dump() const {
731 0: QualType(this, 0).dump();
732 0: }
733 :
734 0: std::string Qualifiers::getAsString() const {
735 0: LangOptions LO;
736 0: return getAsString(PrintingPolicy(LO));
737 : }
738 :
739 : // Appends qualifiers to the given string, separated by spaces. Will
740 : // prefix a space if the string is non-empty. Will not append a final
741 : // space.
742 : void Qualifiers::getAsStringInternal(std::string &S,
743 593: const PrintingPolicy&) const {
744 593: AppendTypeQualList(S, getCVRQualifiers());
2: branch 1 taken
591: branch 2 taken
745 593: if (unsigned AddressSpace = getAddressSpace()) {
1: branch 1 taken
1: branch 2 taken
746 2: if (!S.empty()) S += ' ';
747 2: S += "__attribute__((address_space(";
748 2: S += llvm::utostr_32(AddressSpace);
749 2: S += ")))";
750 : }
2: branch 1 taken
591: branch 2 taken
751 593: if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
0: branch 1 not taken
2: branch 2 taken
752 2: if (!S.empty()) S += ' ';
753 2: S += "__attribute__((objc_gc(";
2: branch 0 taken
0: branch 1 not taken
754 2: if (GCAttrType == Qualifiers::Weak)
755 2: S += "weak";
756 : else
757 0: S += "strong";
758 2: S += ")))";
759 : }
760 593: }
761 :
762 1318: std::string QualType::getAsString() const {
763 1318: std::string S;
764 1318: LangOptions LO;
765 1318: getAsStringInternal(S, PrintingPolicy(LO));
766 1318: return S;
767 : }
768 :
769 : void QualType::getAsStringInternal(std::string &S,
770 5872: const PrintingPolicy &Policy) const {
771 5872: TypePrinter Printer(Policy);
772 5872: Printer.Print(*this, S);
773 5872: }
774 :
Generated: 2010-02-10 01:31 by zcov