zcov: / lib/AST/TypePrinter.cpp


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


Programs: 2 Runs 3018


       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