zcov: / lib/AST/DeclCXX.cpp


Files: 1 Branches Taken: 73.7% 274 / 372
Generated: 2010-02-10 01:31 Branches Executed: 91.9% 342 / 372
Line Coverage: 87.4% 382 / 437


Programs: 2 Runs 3018


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

Generated: 2010-02-10 01:31 by zcov