Example #1
0
bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc,
                                    SourceLocation ColonColonLoc,
                                    CXXScopeSpec &SS) {
  CXXRecordDecl *RD = nullptr;
  for (Scope *S = getCurScope(); S; S = S->getParent()) {
    if (S->isFunctionScope()) {
      if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S->getEntity()))
        RD = MD->getParent();
      break;
    }
    if (S->isClassScope()) {
      RD = cast<CXXRecordDecl>(S->getEntity());
      break;
    }
  }

  if (!RD) {
    Diag(SuperLoc, diag::err_invalid_super_scope);
    return true;
  } else if (RD->isLambda()) {
    Diag(SuperLoc, diag::err_super_in_lambda_unsupported);
    return true;
  } else if (RD->getNumBases() == 0) {
    Diag(SuperLoc, diag::err_no_base_classes) << RD->getName();
    return true;
  }

  SS.MakeSuper(Context, RD, SuperLoc, ColonColonLoc);
  return false;
}
void RecordInfo::walkBases() {
  // This traversal is akin to CXXRecordDecl::forallBases()'s,
  // but without stepping over dependent bases -- these might also
  // have a "GC base name", so are to be included and considered.
  SmallVector<const CXXRecordDecl*, 8> queue;

  const CXXRecordDecl *base_record = record();
  while (true) {
    for (const auto& it : base_record->bases()) {
      const RecordType *type = it.getType()->getAs<RecordType>();
      CXXRecordDecl* base;
      if (!type)
        base = GetDependentTemplatedDecl(*it.getType());
      else {
        base = cast_or_null<CXXRecordDecl>(type->getDecl()->getDefinition());
        if (base)
          queue.push_back(base);
      }
      if (!base)
        continue;

      const std::string& name = base->getName();
      if (Config::IsGCBase(name)) {
        gc_base_names_.push_back(name);
        is_gc_derived_ = true;
      }
    }

    if (queue.empty())
      break;
    base_record = queue.pop_back_val(); // not actually a queue.
  }
}
Example #3
0
// A GC mixin is a class that inherits from a GC mixin base and has
// has not yet been "mixed in" with another GC base class.
bool RecordInfo::IsGCMixin() {
  if (!IsGCDerived() || base_paths_->begin() == base_paths_->end())
    return false;
  // Get the last element of the first path.
  CXXBasePaths::paths_iterator it = base_paths_->begin();
  const CXXBasePathElement& elem = (*it)[it->size() - 1];
  CXXRecordDecl* base = elem.Base->getType()->getAsCXXRecordDecl();
  // If it is not a mixin base we are done.
  if (!Config::IsGCMixinBase(base->getName()))
    return false;
  // This is a mixin if there are no other paths to GC bases.
  return ++it == base_paths_->end();
}
Example #4
0
bool RecordInfo::IsGCFinalized() {
  if (!IsGCDerived())
    return false;
  for (CXXBasePaths::paths_iterator it = base_paths_->begin();
       it != base_paths_->end();
       ++it) {
    const CXXBasePathElement& elem = (*it)[it->size() - 1];
    CXXRecordDecl* base = elem.Base->getType()->getAsCXXRecordDecl();
    if (Config::IsGCFinalizedBase(base->getName()))
      return true;
  }
  return false;
}
Example #5
0
void VarCheckVisitor::checkClass(clang::Decl* d)
{
  auto loc = getDeclLocation(d);

  CXXRecordDecl* c = (CXXRecordDecl*)d;

  string name = c->getName();

  boost::regex r{CLASS_NAME};

  if(!boost::regex_match(name, r)){
    lineIssues_.push_back(Issue(loc.first, loc.second,
    "Incorrect Class/Struct name",
    "Classes and Structures should be named in upper camel case.",
    WARNING));
  }
}
Example #6
0
bool RecordInfo::IsTreeShared() {
  if (Config::IsTreeSharedBase(name_))
    return true;
  if (!IsGCDerived())
    return false;
  for (CXXBasePaths::paths_iterator it = base_paths_->begin();
       it != base_paths_->end();
       ++it) {
    // TreeShared is an immediate base of GCFinalized.
    if (it->size() < 2) continue;
    const CXXBasePathElement& elem = (*it)[it->size() - 2];
    CXXRecordDecl* base = elem.Base->getType()->getAsCXXRecordDecl();
    if (Config::IsTreeSharedBase(base->getName()))
      return true;
  }
  return false;
}