Example #1
0
    Record* HandleRecordDecl(CXXRecordDecl *D) {
        assert(D && "Class missing in HandleRecordDecl");
        if (!D->hasDefinition())
            return NULL;

        // skip duplication
        if(records.find(D->getQualifiedNameAsString()) != records.end()) return 0;

        Record *r = new Record;
        r->qualifiedname = D->getQualifiedNameAsString();
        //find all base classes
        //we skip all the template classes or there will be Assertion failed
        if (!D->getDescribedClassTemplate ()) {
            for (CXXRecordDecl::base_class_iterator iter = D->bases_begin();
                    iter != D->bases_end(); ++iter) {
                if (iter) {
                    QualType type = iter->getType();
                    std::string tmp = type.getAsString();
                    //remove "class "
                    tmp.erase(0, 6);
                    r->bases.insert(tmp);
                }
            }
        }

        return r;
    }
Example #2
0
  void addSubNodes(CXXRecordDecl* RD) {
    addSubNodes(cast<RecordDecl>(RD));

    if (RD->isDefinition()) {
      // FIXME: This breaks XML generation
      //Doc.addAttribute("num_bases", RD->getNumBases());

      for (CXXRecordDecl::base_class_iterator 
             base = RD->bases_begin(),
             bend = RD->bases_end();
           base != bend;
           ++base) {
        Doc.addSubNode("Base");
        Doc.addAttribute("id", base->getType());
        AccessSpecifier as = base->getAccessSpecifierAsWritten();
        const char* as_name = "";
        switch(as) {
        case AS_none:      as_name = ""; break;
        case AS_public:    as_name = "public"; break;
        case AS_protected: as_name = "protected"; break;
        case AS_private:   as_name = "private"; break;
        }
        Doc.addAttributeOptional("access", as_name);
        Doc.addAttribute("is_virtual", base->isVirtual());
        Doc.toParent();
      }
    }
  }
Example #3
0
File: DeclCXX.cpp Project: CPFL/guc
/// Collect the visible conversions of a base class.
///
/// \param Base a base class of the class we're considering
/// \param InVirtual whether this base class is a virtual base (or a base
///   of a virtual base)
/// \param Access the access along the inheritance path to this base
/// \param ParentHiddenTypes the conversions provided by the inheritors
///   of this base
/// \param Output the set to which to add conversions from non-virtual bases
/// \param VOutput the set to which to add conversions from virtual bases
/// \param HiddenVBaseCs the set of conversions which were hidden in a
///   virtual base along some inheritance path
static void CollectVisibleConversions(ASTContext &Context,
                                      CXXRecordDecl *Record,
                                      bool InVirtual,
                                      AccessSpecifier Access,
                  const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes,
                                      UnresolvedSetImpl &Output,
                                      UnresolvedSetImpl &VOutput,
                           llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) {
  // The set of types which have conversions in this class or its
  // subclasses.  As an optimization, we don't copy the derived set
  // unless it might change.
  const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes;
  llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer;

  // Collect the direct conversions and figure out which conversions
  // will be hidden in the subclasses.
  UnresolvedSetImpl &Cs = *Record->getConversionFunctions();
  if (!Cs.empty()) {
    HiddenTypesBuffer = ParentHiddenTypes;
    HiddenTypes = &HiddenTypesBuffer;

    for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) {
      bool Hidden =
        !HiddenTypesBuffer.insert(GetConversionType(Context, I.getDecl()));

      // If this conversion is hidden and we're in a virtual base,
      // remember that it's hidden along some inheritance path.
      if (Hidden && InVirtual)
        HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()));

      // If this conversion isn't hidden, add it to the appropriate output.
      else if (!Hidden) {
        AccessSpecifier IAccess
          = CXXRecordDecl::MergeAccess(Access, I.getAccess());

        if (InVirtual)
          VOutput.addDecl(I.getDecl(), IAccess);
        else
          Output.addDecl(I.getDecl(), IAccess);
      }
    }
  }

  // Collect information recursively from any base classes.
  for (CXXRecordDecl::base_class_iterator
         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
    const RecordType *RT = I->getType()->getAs<RecordType>();
    if (!RT) continue;

    AccessSpecifier BaseAccess
      = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier());
    bool BaseInVirtual = InVirtual || I->isVirtual();

    CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
    CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
                              *HiddenTypes, Output, VOutput, HiddenVBaseCs);
  }
}
Example #4
0
   /**
    * Once the recursive visitor has completed, this routine analyzes the
    * MostDerivedTypeMap to find errors in the structure of the OMR classes
    */
   void VerifyTypeStructure() {
      trace("Starting Structure Verification");

      for (std::map<CXXRecordDecl*, bool>::iterator I = Types.begin(), E=Types.end(); I != E; ++I) {
         CXXRecordDecl * Type        = I->first;
         bool extensible             = I->second;
         trace(Type << " " << extensible << " " << getAssociatedConcreteType(Type));
         if (extensible && !getAssociatedConcreteType(Type)) {
            trace("xxxx Issue diagnostic because there's no associated concrete type");
            continue;
         }
         if (extensible) {  //Extnsible type .
            trace("xxxx Verifying " << Type->getQualifiedNameAsString() << " has no non-extensible base classes." );
            for (CXXRecordDecl::base_class_iterator BI = Type->bases_begin(), BE = Type->bases_end(); BI != BE; ++BI) {
               CXXRecordDecl * base_class = BI->getType()->getAsCXXRecordDecl();
               if (base_class
                   && !isExtensible(base_class) // Ensure extensible parent.
                   && !isOMRRootType(Type)) {   // OMR Root type can have non-extensible parents.
                  //Base is not extensible, but an extensible type reaches it, with no concrete class in the middle.
                  //Issue diagnostic.
                  std::string diagnostic("OMR_EXTENSIBLE Type ");
                  diagnostic += Type->getQualifiedNameAsString();
                  diagnostic += " derives from ";
                  diagnostic += base_class->getQualifiedNameAsString();
                  diagnostic += " that is not marked as OMR_EXTENSIBLE.\n";

                  DiagnosticsEngine &diagEngine = Context->getDiagnostics();
                  unsigned diagID = diagEngine.getCustomDiagID(DiagnosticsEngine::Error, "%0");
                  diagEngine.Report(base_class->getLocation(), diagID) << diagnostic;
               }
            }
         } else {
            trace("xxxx Verifying " << Type->getQualifiedNameAsString() << " has no non-extensible base classes." );
            for (CXXRecordDecl::base_class_iterator BI = Type->bases_begin(), BE = Type->bases_end(); BI != BE; ++BI) {
               CXXRecordDecl * base_class = BI->getType()->getAsCXXRecordDecl();
               if (base_class && isExtensible(base_class) && !isOMRConcreteType(base_class)) {
                  //Base is not extensible, but an extensible type reaches it, with no concrete class in the middle.
                  //Issue diagnostic.
                  std::string diagnostic("Type ");
                  diagnostic += Type->getQualifiedNameAsString();
                  diagnostic += " derives from ";
                  diagnostic += base_class->getQualifiedNameAsString();
                  diagnostic += " that is  marked as OMR_EXTENSIBLE.\n";

                  DiagnosticsEngine &diagEngine = Context->getDiagnostics();
                  unsigned diagID = diagEngine.getCustomDiagID(DiagnosticsEngine::Error, "%0");
                  diagEngine.Report(Type->getLocation(), diagID) << diagnostic;
               }
            }
         }
      } //each most derived type
   }
Example #5
0
void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
  // FIXME: add printing of pragma attributes if required.
  if (!Policy.SuppressSpecifiers && D->isModulePrivate())
    Out << "__module_private__ ";
  Out << D->getKindName();

  prettyPrintAttributes(D);

  if (D->getIdentifier()) {
    Out << ' ' << *D;

    if (auto S = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
      printTemplateArguments(S->getTemplateArgs(), S->getTemplateParameters());
    else if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D))
      printTemplateArguments(S->getTemplateArgs());
  }

  if (D->isCompleteDefinition()) {
    // Print the base classes
    if (D->getNumBases()) {
      Out << " : ";
      for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
             BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
        if (Base != D->bases_begin())
          Out << ", ";

        if (Base->isVirtual())
          Out << "virtual ";

        AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
        if (AS != AS_none) {
          Print(AS);
          Out << " ";
        }
        Out << Base->getType().getAsString(Policy);

        if (Base->isPackExpansion())
          Out << "...";
      }
    }

    // Print the class definition
    // FIXME: Doesn't print access specifiers, e.g., "public:"
    if (Policy.TerseOutput) {
      Out << " {}";
    } else {
      Out << " {\n";
      VisitDeclContext(D);
      Indent() << "}";
    }
  }
}
CXXRecordDecl* BlinkGCPluginConsumer::GetLeftMostBase(
    CXXRecordDecl* left_most) {
  CXXRecordDecl::base_class_iterator it = left_most->bases_begin();
  while (it != left_most->bases_end()) {
    if (it->getType()->isDependentType())
      left_most = RecordInfo::GetDependentTemplatedDecl(*it->getType());
    else
      left_most = it->getType()->getAsCXXRecordDecl();
    if (!left_most || !left_most->hasDefinition())
      return 0;
    it = left_most->bases_begin();
  }
  return left_most;
}
void ASTDumper::VisitCXXRecordDecl(CXXRecordDecl *D) {
  VisitRecordDecl(D);
  if (!D->isCompleteDefinition())
    return;

  for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
       E = D->bases_end(); I != E; ++I) {
    IndentScope Indent(*this);
    if (I->isVirtual())
      OS << "virtual ";
    dumpAccessSpecifier(I->getAccessSpecifier());
    dumpType(I->getType());
    if (I->isPackExpansion())
      OS << "...";
  }
}
Example #8
0
bool FindModule::VisitCXXRecordDecl (CXXRecordDecl * d)
{

	if (_decl->getNumBases () <= 0)
		{
			return true;
		}

	for (CXXRecordDecl::base_class_iterator bi = _decl->bases_begin (), be =
			 _decl->bases_end (); bi != be; ++bi)
		{
			QualType
				q = bi->getType ();

			string
				baseName = q.getAsString ();

			if (baseName == "::sc_core::sc_module"
					|| baseName == "sc_core::sc_module"
					|| baseName == "class sc_core::sc_module")
				{

					_isSystemCModule = true;
					IdentifierInfo *
						info = _decl->getIdentifier ();

					if (info != NULL)
						{
							_moduleName = info->getNameStart ();
						}
				}
		}

	if (_isSystemCModule == false)
		{
			return true;
		}

	return false;
}
Example #9
0
File: DeclCXX.cpp Project: CPFL/guc
/// Collect the visible conversions of a class.
///
/// This would be extremely straightforward if it weren't for virtual
/// bases.  It might be worth special-casing that, really.
static void CollectVisibleConversions(ASTContext &Context,
                                      CXXRecordDecl *Record,
                                      UnresolvedSetImpl &Output) {
  // The collection of all conversions in virtual bases that we've
  // found.  These will be added to the output as long as they don't
  // appear in the hidden-conversions set.
  UnresolvedSet<8> VBaseCs;
  
  // The set of conversions in virtual bases that we've determined to
  // be hidden.
  llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs;

  // The set of types hidden by classes derived from this one.
  llvm::SmallPtrSet<CanQualType, 8> HiddenTypes;

  // Go ahead and collect the direct conversions and add them to the
  // hidden-types set.
  UnresolvedSetImpl &Cs = *Record->getConversionFunctions();
  Output.append(Cs.begin(), Cs.end());
  for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I)
    HiddenTypes.insert(GetConversionType(Context, I.getDecl()));

  // Recursively collect conversions from base classes.
  for (CXXRecordDecl::base_class_iterator
         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
    const RecordType *RT = I->getType()->getAs<RecordType>();
    if (!RT) continue;

    CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
                              I->isVirtual(), I->getAccessSpecifier(),
                              HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
  }

  // Add any unhidden conversions provided by virtual bases.
  for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end();
         I != E; ++I) {
    if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())))
      Output.addDecl(I.getDecl(), I.getAccess());
  }
}
Example #10
0
bool ClassTemplateToClass::hasUsedNameDecl(
       ClassTemplatePartialSpecializationDecl *PartialD)
{
  if (!PartialD->isCompleteDefinition())
    return false;

  SmallPtrSet<NamedDecl *, 8> Params;
  TemplateParameterList *PartialTPList = PartialD->getTemplateParameters();
  for (unsigned PI = 0; PI < PartialTPList->size(); ++PI) {
    NamedDecl *ND = PartialTPList->getParam(PI);
    if (dyn_cast<NonTypeTemplateParmDecl>(ND))
      continue;
    Params.insert(ND);  
  }

  TemplateParameterTypeVisitor ParamVisitor(Context);

  // Skip visiting parameters and arguments
  for (CXXRecordDecl::base_class_iterator I = PartialD->bases_begin(),
       E = PartialD->bases_end(); I != E; ++I) {
    ParamVisitor.TraverseType(I->getType());
  }

  DeclContext *Ctx = dyn_cast<DeclContext>(PartialD);
  for (DeclContext::decl_iterator DI = Ctx->decls_begin(), 
       DE = Ctx->decls_end(); DI != DE; ++DI) {
    ParamVisitor.TraverseDecl(*DI);
  }

  for (SmallPtrSet<NamedDecl *, 8>::iterator I = Params.begin(), 
       E = Params.end(); I != E; ++I) {
    if (ParamVisitor.isAUsedParameter(*I))
      return true;
  }
  return false;
}
// The GC infrastructure assumes that if the vtable of a polymorphic
// base-class is not initialized for a given object (ie, it is partially
// initialized) then the object does not need to be traced. Thus, we must
// ensure that any polymorphic class with a trace method does not have any
// tractable fields that are initialized before we are sure that the vtable
// and the trace method are both defined.  There are two cases that need to
// hold to satisfy that assumption:
//
// 1. If trace is virtual, then it must be defined in the left-most base.
// This ensures that if the vtable is initialized then it contains a pointer
// to the trace method.
//
// 2. If trace is non-virtual, then the trace method is defined and we must
// ensure that the left-most base defines a vtable. This ensures that the
// first thing to be initialized when constructing the object is the vtable
// itself.
void BlinkGCPluginConsumer::CheckPolymorphicClass(
    RecordInfo* info,
    CXXMethodDecl* trace) {
  CXXRecordDecl* left_most = info->record();
  CXXRecordDecl::base_class_iterator it = left_most->bases_begin();
  CXXRecordDecl* left_most_base = 0;
  while (it != left_most->bases_end()) {
    left_most_base = it->getType()->getAsCXXRecordDecl();
    if (!left_most_base && it->getType()->isDependentType())
      left_most_base = RecordInfo::GetDependentTemplatedDecl(*it->getType());

    // TODO: Find a way to correctly check actual instantiations
    // for dependent types. The escape below will be hit, eg, when
    // we have a primary template with no definition and
    // specializations for each case (such as SupplementBase) in
    // which case we don't succeed in checking the required
    // properties.
    if (!left_most_base || !left_most_base->hasDefinition())
      return;

    StringRef name = left_most_base->getName();
    // We know GCMixin base defines virtual trace.
    if (Config::IsGCMixinBase(name))
      return;

    // Stop with the left-most prior to a safe polymorphic base (a safe base
    // is non-polymorphic and contains no fields).
    if (Config::IsSafePolymorphicBase(name))
      break;

    left_most = left_most_base;
    it = left_most->bases_begin();
  }

  if (RecordInfo* left_most_info = cache_.Lookup(left_most)) {
    // Check condition (1):
    if (trace && trace->isVirtual()) {
      if (CXXMethodDecl* trace = left_most_info->GetTraceMethod()) {
        if (trace->isVirtual())
          return;
      }
      ReportBaseClassMustDeclareVirtualTrace(info, left_most);
      return;
    }

    // Check condition (2):
    if (DeclaresVirtualMethods(left_most))
      return;
    if (left_most_base) {
      // Get the base next to the "safe polymorphic base"
      if (it != left_most->bases_end())
        ++it;
      if (it != left_most->bases_end()) {
        if (CXXRecordDecl* next_base = it->getType()->getAsCXXRecordDecl()) {
          if (CXXRecordDecl* next_left_most = GetLeftMostBase(next_base)) {
            if (DeclaresVirtualMethods(next_left_most))
              return;
            ReportLeftMostBaseMustBePolymorphic(info, next_left_most);
            return;
          }
        }
      }
    }
    ReportLeftMostBaseMustBePolymorphic(info, left_most);
  }
}
Example #12
0
File: DeclCXX.cpp Project: CPFL/guc
void
CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
                        unsigned NumBases) {
  ASTContext &C = getASTContext();
  
  // C++ [dcl.init.aggr]p1:
  //   An aggregate is an array or a class (clause 9) with [...]
  //   no base classes [...].
  data().Aggregate = false;

  if (data().Bases)
    C.Deallocate(data().Bases);

  // The set of seen virtual base types.
  llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
  
  // The virtual bases of this class.
  llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases;

  data().Bases = new(C) CXXBaseSpecifier [NumBases];
  data().NumBases = NumBases;
  for (unsigned i = 0; i < NumBases; ++i) {
    data().Bases[i] = *Bases[i];
    // Keep track of inherited vbases for this base class.
    const CXXBaseSpecifier *Base = Bases[i];
    QualType BaseType = Base->getType();
    // Skip dependent types; we can't do any checking on them now.
    if (BaseType->isDependentType())
      continue;
    CXXRecordDecl *BaseClassDecl
      = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());

    // Now go through all virtual bases of this base and add them.
    for (CXXRecordDecl::base_class_iterator VBase =
          BaseClassDecl->vbases_begin(),
         E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
      // Add this base if it's not already in the list.
      if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType())))
        VBases.push_back(VBase);
    }

    if (Base->isVirtual()) {
      // Add this base if it's not already in the list.
      if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
          VBases.push_back(Base);
    }

  }
  
  if (VBases.empty())
    return;

  // Create base specifier for any direct or indirect virtual bases.
  data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
  data().NumVBases = VBases.size();
  for (int I = 0, E = VBases.size(); I != E; ++I) {
    TypeSourceInfo *VBaseTypeInfo = VBases[I]->getTypeSourceInfo();

    // Skip dependent types; we can't do any checking on them now.
    if (VBaseTypeInfo->getType()->isDependentType())
      continue;

    CXXRecordDecl *VBaseClassDecl = cast<CXXRecordDecl>(
      VBaseTypeInfo->getType()->getAs<RecordType>()->getDecl());

    data().VBases[I] =
      CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
                       VBaseClassDecl->getTagKind() == TTK_Class,
                       VBases[I]->getAccessSpecifier(), VBaseTypeInfo);
  }
}
void
CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
                        unsigned NumBases) {
  ASTContext &C = getASTContext();
  
  // C++ [dcl.init.aggr]p1:
  //   An aggregate is an array or a class (clause 9) with [...]
  //   no base classes [...].
  data().Aggregate = false;

  if (data().Bases)
    C.Deallocate(data().Bases);

  int vbaseCount = 0;
  llvm::SmallVector<const CXXBaseSpecifier*, 8> UniqueVbases;
  bool hasDirectVirtualBase = false;

  data().Bases = new(C) CXXBaseSpecifier [NumBases];
  data().NumBases = NumBases;
  for (unsigned i = 0; i < NumBases; ++i) {
    data().Bases[i] = *Bases[i];
    // Keep track of inherited vbases for this base class.
    const CXXBaseSpecifier *Base = Bases[i];
    QualType BaseType = Base->getType();
    // Skip dependent types; we can't do any checking on them now.
    if (BaseType->isDependentType())
      continue;
    CXXRecordDecl *BaseClassDecl
      = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
    if (Base->isVirtual())
      hasDirectVirtualBase = true;
    for (CXXRecordDecl::base_class_iterator VBase =
          BaseClassDecl->vbases_begin(),
         E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
      // Add this vbase to the array of vbases for current class if it is
      // not already in the list.
      // FIXME. Note that we do a linear search as number of such classes are
      // very few.
      int i;
      for (i = 0; i < vbaseCount; ++i)
        if (UniqueVbases[i]->getType() == VBase->getType())
          break;
      if (i == vbaseCount) {
        UniqueVbases.push_back(VBase);
        ++vbaseCount;
      }
    }
  }
  if (hasDirectVirtualBase) {
    // Iterate one more time through the direct bases and add the virtual
    // base to the list of vritual bases for current class.
    for (unsigned i = 0; i < NumBases; ++i) {
      const CXXBaseSpecifier *VBase = Bases[i];
      if (!VBase->isVirtual())
        continue;
      int j;
      for (j = 0; j < vbaseCount; ++j)
        if (UniqueVbases[j]->getType() == VBase->getType())
          break;
      if (j == vbaseCount) {
        UniqueVbases.push_back(VBase);
        ++vbaseCount;
      }
    }
  }
  if (vbaseCount > 0) {
    // build AST for inhireted, direct or indirect, virtual bases.
    data().VBases = new (C) CXXBaseSpecifier [vbaseCount];
    data().NumVBases = vbaseCount;
    for (int i = 0; i < vbaseCount; i++) {
      QualType QT = UniqueVbases[i]->getType();
      // Skip dependent types; we can't do any checking on them now.
      if (QT->isDependentType())
        continue;
      CXXRecordDecl *VBaseClassDecl
        = cast<CXXRecordDecl>(QT->getAs<RecordType>()->getDecl());
      data().VBases[i] =
        CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
                         VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
                         UniqueVbases[i]->getAccessSpecifier(), QT);
    }
  }
}
/// getNestedVisibleConversionFunctions - imports unique conversion 
/// functions from base classes into the visible conversion function
/// list of the class 'RD'. This is a private helper method.
/// TopConversionsTypeSet is the set of conversion functions of the class
/// we are interested in. HiddenConversionTypes is set of conversion functions
/// of the immediate derived class which  hides the conversion functions found 
/// in current class.
void
CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
                const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet,                               
                const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes) 
{
  bool inTopClass = (RD == this);
  QualType ClassType = getASTContext().getTypeDeclType(this);
  if (const RecordType *Record = ClassType->getAs<RecordType>()) {
    const UnresolvedSetImpl *Cs
      = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
    
    for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
           I != E; ++I) {
      NamedDecl *Conv = *I;
      // Only those conversions not exact match of conversions in current
      // class are candidateconversion routines.
      CanQualType ConvType;
      if (FunctionTemplateDecl *ConversionTemplate = 
            dyn_cast<FunctionTemplateDecl>(Conv))
        ConvType = 
          getASTContext().getCanonicalType(
                      ConversionTemplate->getTemplatedDecl()->getResultType());
      else
        ConvType = 
          getASTContext().getCanonicalType(
                          cast<CXXConversionDecl>(Conv)->getConversionType());
      // We only add conversion functions found in the base class if they
      // are not hidden by those found in HiddenConversionTypes which are
      // the conversion functions in its derived class.
      if (inTopClass || 
          (!TopConversionsTypeSet.count(ConvType) && 
           !HiddenConversionTypes.count(ConvType)) ) {
        if (FunctionTemplateDecl *ConversionTemplate =
              dyn_cast<FunctionTemplateDecl>(Conv))
          RD->addVisibleConversionFunction(ConversionTemplate);
        else
          RD->addVisibleConversionFunction(cast<CXXConversionDecl>(Conv));
      }
    }
  }

  if (getNumBases() == 0 && getNumVBases() == 0)
    return;

  llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions;
  if (!inTopClass)
    collectConversionFunctions(ConversionFunctions);

  for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(),
       E = vbases_end(); VBase != E; ++VBase) {
    if (const RecordType *RT = VBase->getType()->getAs<RecordType>()) {
      CXXRecordDecl *VBaseClassDecl
        = cast<CXXRecordDecl>(RT->getDecl());
      VBaseClassDecl->getNestedVisibleConversionFunctions(RD,
                    TopConversionsTypeSet,
                    (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
    }
  }
  for (CXXRecordDecl::base_class_iterator Base = bases_begin(),
       E = bases_end(); Base != E; ++Base) {
    if (Base->isVirtual())
      continue;
    if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
      CXXRecordDecl *BaseClassDecl
        = cast<CXXRecordDecl>(RT->getDecl());

      BaseClassDecl->getNestedVisibleConversionFunctions(RD,
                    TopConversionsTypeSet,
                    (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
    }
  }
}
Example #15
0
		/*
		   this helper function is called when the traversal reaches a node of type Decl
		 */
		bool DeclHelper(Decl *D){

			const Stmt* parent = getStmtParent(D, Context);
			//const Stmt* parentsParent = getStmtParent(parent, Context);

			//if it is part of the (init; condition; increment) of a for loop, we don't care about it
			if(isFlowControl(D, Context)){
				return false;
			}


			//supresses the catch stmt's arguments
			if(parent != NULL && strcmp(parent->getStmtClassName(), "CXXCatchStmt") == 0){
				return true;
			}


			string filename;
			if(!isInCurFile(Context, D, filename) && filename.size() != 0){
				return false;
			}else if(filename.size() == 0){
				return true;
			}



			string output = "";
			//get the name of the node type
			string node = D->getDeclKindName();
			//calculate the current level, nextLevel, and previousLevel
			int intLevel = getLevelDecl(D);int intNextLevel = intLevel+1;
			int intNextNextLevel = intLevel+2; int intPrevLevel = intLevel-1;
			//create string values for the levels to use as output
			string level; string nextLevel;
			string nextNextLevel; string prevLevel;
			stringstream ss; stringstream ss2; stringstream ss3; stringstream ss4;
			ss << intLevel;
			level = ss.str();
			ss2 << intNextLevel;
			nextLevel = ss2.str();
			ss3 << intPrevLevel;
			prevLevel = ss3.str();
			ss4 << intNextNextLevel;
			nextNextLevel = ss4.str();



			if(callStackDebug && !callStack.empty()){
				cerr << "decl: call stack top: " << callStack.top()->getStmtClassName() << endl;
			}

			//if top of stack is no longer a parent
			while(!callStack.empty() && numClosingArgsNeeded > 0
					&& !isParentDecl(D, callStack.top()->getStmtClassName())){

				if(debugPrint){
					cerr << "adding args" << endl;
				}
				numClosingArgsNeeded--;
				output += "</args,1>\n";

				callStack.pop();
				if(callStackDebug){
					cerr << "poping" << endl;
					printCallStack();
				}
			}


			//add new calls to stack
			if(isParentDeclInCurFile(D,"CXXConstructExpr") && isParentDecl(D, "CXXConstructExpr")){

				if(debugPrint){
					cerr << "setting previousConstructorCall to true" << endl;
				}


			}else if(isParentDeclInCurFile(D,"CXXTemporaryObjectExpr") && isParentDecl(D, "CXXTemporaryObjectExpr")){

				if(debugPrint){
					cerr << "setting previousTempConstructorCallArg" << endl;
				}


			}else if(isParentDecl(D, "CallExpr")){

				if(debugPrint){
					cerr << "setting previousCallArgs to true" << endl;
				}


			}else if(isParentDecl(D, "CXXMemberCallExpr")){

				if(debugPrint){
					cerr << "setting previousMemberCallArg to true" << endl;
				}

			}


			if(isParentDecl(getDeclParent(D, Context), "Var")){
				previousRhsDecl = true;
				if(debugPrint){
					cout << "setting prev var to true" << endl;
				}
			}else if(previousRhsDecl && numClosingVarsNeeded > 0){
				//if the current node is not a child of a variable declaration 
				//but the previous node was a child of a variable declation 
				//then we know to print a </decl>
				output +="</variableDecl,1>\n";
				numClosingVarsNeeded--;
				previousRhsDecl = false;
			}


			if(node == "Var"){
				output += "<variableDecl, " + prevLevel +  ">";
				numClosingVarsNeeded++;
				VarDecl* VD = (VarDecl*) D;
				if(!VD->hasInit()){
					output +="\n</variableDecl,1>\n";
					numClosingVarsNeeded--;
				}
			}else if(node == "Function"){
				FunctionDecl* FD = (FunctionDecl*) D; 
				output += "<functionDef," + level +">";
				//add function name to the output
				output += "\n<name: " + FD->getNameInfo().getAsString()
					+ "," + nextLevel + ">";

			}else if(node == "CXXRecord"){
				const Decl* parent = getDeclParent(D, Context);
				if(parent && strcmp(parent->getDeclKindName(), "CXXRecord") != 0){
					CXXRecordDecl* CD = (CXXRecordDecl*) D;
					output += "<classDef," + level + ">";
					output += "\n<name: " + CD->getNameAsString() + "," + nextLevel + ">";
					output += "\n<bases," + nextLevel + ">";

					//iterate over all bases and add them to the output
					CXXRecordDecl::base_class_iterator basesItr =  CD->bases_begin();
					while(basesItr != CD->bases_end()){
						QualType qt = basesItr->getType();
						output +=  "\n<base: " +  qt.getBaseTypeIdentifier()->getName().str();
						output +=  "," + nextNextLevel + ">";
						basesItr++;
					}

					//iterate over all of the virtual bases and add them to the output
					auto vBasesItr = CD->vbases_begin();
					while(vBasesItr != CD->vbases_end()){
						QualType qt = vBasesItr->getType();
						output +=  "\n<base: " +  qt.getBaseTypeIdentifier()->getName().str();
						output +=  "," + nextNextLevel + ">";
						vBasesItr++;
					}

				}
			}else if(node == "CXXDestructor"){
				CXXDestructorDecl* CD = (CXXDestructorDecl*) D;
				if(!CD->isImplicit()){
					output += "<functionDef," + level +">";
					//add function name to the output
					output += "\n<name: ~" + CD->getNameInfo().getAsString()
						+ "," + nextLevel + ">";
				}


			}else if(node == "CXXConstructor"){
				CXXConstructorDecl* CD = (CXXConstructorDecl*) D;
				if(!CD->isImplicit()){
					output += "<functionDef," + level +">";
					//add function name to the output
					output += "\n<name: " + CD->getNameInfo().getAsString()
						+ "," + nextLevel + ">";
				}
			}else if(node == "CXXMethod"){
				CXXMethodDecl* CM = (CXXMethodDecl*) D;
				if(!CM->isImplicit()){
					output += "<functionDef," + level +">";
					//add function name to the output
					output += "\n<name: " + CM->getNameInfo().getAsString()
						+ "," + nextLevel + ">";
				}
			}else{

				if(debugPrint){
					output += "<";
					output += node;
					output += ">";
				}
			}

			if(output.size() != 0){
				cout << output << endl;
			}

			return true;
		}