示例#1
0
文件: Sema.cpp 项目: jsgf/clang
/// Obtains a sorted list of functions that are undefined but ODR-used.
void Sema::getUndefinedButUsed(
    SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) {
  for (llvm::DenseMap<NamedDecl *, SourceLocation>::iterator
         I = UndefinedButUsed.begin(), E = UndefinedButUsed.end();
       I != E; ++I) {
    NamedDecl *ND = I->first;

    // Ignore attributes that have become invalid.
    if (ND->isInvalidDecl()) continue;

    // __attribute__((weakref)) is basically a definition.
    if (ND->hasAttr<WeakRefAttr>()) continue;

    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
      if (FD->isDefined())
        continue;
      if (FD->hasExternalLinkage() &&
          !FD->getMostRecentDecl()->isInlined())
        continue;
    } else {
      if (cast<VarDecl>(ND)->hasDefinition() != VarDecl::DeclarationOnly)
        continue;
      if (ND->hasExternalLinkage())
        continue;
    }

    Undefined.push_back(std::make_pair(ND, I->second));
  }

  // Sort (in order of use site) so that we're not dependent on the iteration
  // order through an llvm::DenseMap.
  std::sort(Undefined.begin(), Undefined.end(),
            SortUndefinedButUsed(Context.getSourceManager()));
}
示例#2
0
文件: Sema.cpp 项目: dmpots/clang
/// checkUndefinedInternals - Check for undefined objects with internal linkage.
static void checkUndefinedInternals(Sema &S) {
  if (S.UndefinedInternals.empty()) return;

  // Collect all the still-undefined entities with internal linkage.
  SmallVector<UndefinedInternal, 16> undefined;
  for (llvm::MapVector<NamedDecl*,SourceLocation>::iterator
         i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end();
       i != e; ++i) {
    NamedDecl *decl = i->first;

    // Ignore attributes that have become invalid.
    if (decl->isInvalidDecl()) continue;

    // If we found out that the decl is external, don't warn.
    if (decl->getLinkage() == ExternalLinkage) continue;

    // __attribute__((weakref)) is basically a definition.
    if (decl->hasAttr<WeakRefAttr>()) continue;

    if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
      if (fn->isPure() || fn->hasBody())
        continue;
    } else {
      if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly)
        continue;
    }

    S.Diag(decl->getLocation(), diag::warn_undefined_internal)
      << isa<VarDecl>(decl) << decl;
    S.Diag(i->second, diag::note_used_here);
  }
}
示例#3
0
/// checkUndefinedInternals - Check for undefined objects with internal linkage.
static void checkUndefinedInternals(Sema &S) {
  if (S.UndefinedInternals.empty()) return;

  // Collect all the still-undefined entities with internal linkage.
  SmallVector<UndefinedInternal, 16> undefined;
  for (llvm::DenseMap<NamedDecl*,SourceLocation>::iterator
         i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end();
       i != e; ++i) {
    NamedDecl *decl = i->first;

    // Ignore attributes that have become invalid.
    if (decl->isInvalidDecl()) continue;

    // __attribute__((weakref)) is basically a definition.
    if (decl->hasAttr<WeakRefAttr>()) continue;

    if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
      if (fn->isPure() || fn->hasBody())
        continue;
    } else {
      if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly)
        continue;
    }

    // We build a FullSourceLoc so that we can sort with array_pod_sort.
    FullSourceLoc loc(i->second, S.Context.getSourceManager());
    undefined.push_back(UndefinedInternal(decl, loc));
  }

  if (undefined.empty()) return;

  // Sort (in order of use site) so that we're not (as) dependent on
  // the iteration order through an llvm::DenseMap.
  llvm::array_pod_sort(undefined.begin(), undefined.end());

  for (SmallVectorImpl<UndefinedInternal>::iterator
         i = undefined.begin(), e = undefined.end(); i != e; ++i) {
    NamedDecl *decl = i->decl;
    S.Diag(decl->getLocation(), diag::warn_undefined_internal)
      << isa<VarDecl>(decl) << decl;
    S.Diag(i->useLoc, diag::note_used_here);
  }
}
  ///\brief Checks for clashing names when trying to extract a declaration.
  ///
  ///\returns true if there is another declaration with the same name
  bool DeclExtractor::CheckForClashingNames(
                                  const llvm::SmallVector<NamedDecl*, 4>& Decls,
                                            DeclContext* DC, Scope* S) {
    for (size_t i = 0; i < Decls.size(); ++i) {
      NamedDecl* ND = Decls[i];

      if (TagDecl* TD = dyn_cast<TagDecl>(ND)) {
        LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(),
                              Sema::LookupTagName, Sema::ForRedeclaration
                              );

        m_Sema->LookupName(Previous, S);

        // There is no function diagnosing the redeclaration of tags (eg. enums).
        // So either we have to do it by hand or we can call the top-most
        // function that does the check. Currently the top-most clang function
        // doing the checks creates an AST node, which we don't want.
        CheckTagDeclaration(TD, Previous);

      }
      else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
        LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(),
                              Sema::LookupOrdinaryName, Sema::ForRedeclaration
                              );

        m_Sema->LookupName(Previous, S);

        m_Sema->CheckVariableDeclaration(VD, Previous);
      }

      if (ND->isInvalidDecl())
        return true;
    }

    return false;
  }
示例#5
0
Action::OwningExprResult
Sema::BuildMemberReferenceExpr(Expr *BaseExpr, const Type *BaseExprType,
                               SourceLocation OpLoc, LookupResult &R) {
  const Type* BaseType = BaseExprType;

  if (const PointerType *P = dyn_cast<PointerType>(BaseType))
    BaseType = P->getPointeeType();
  //R.setBaseObjectType(BaseType);

  //const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
  //DeclarationName MemberName = MemberNameInfo.getName();
  //SourceLocation MemberLoc = MemberNameInfo.getLoc();
  IdentifierInfo *II = R.getLookupName();

  if (R.isAmbiguous())
    return ExprError();

  if (R.empty()) {
    // FIXME: make sure this prints the '*' for pointer-to-struct types (?)
    //DeclContext *DC = BaseType->getAs<StructType>()->getDecl();
    // FIXME: clang prints DC instead of BaseExprType here. Don't do that,
    // else we don't print struct names right. However, make sure ParenTypes
    // get desugared once they exist.
    Diag(R.getNameLoc(), diag::no_field) << II << BaseExprType;
    //Diag(R.getNameLoc(), diag::err_no_member)
      //<< MemberName << DC
      //<< (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
    return ExprError();
  }

  assert(R.isSingleResult());
  NamedDecl *MemberDecl = R.getFoundDecl();
#if 0
  DeclAccessPair FoundDecl = R.begin().getPair();

  // If the decl being referenced had an error, return an error for this
  // sub-expr without emitting another error, in order to avoid cascading
  // error cases.
  if (MemberDecl->isInvalidDecl())
    return ExprError();

  bool ShouldCheckUse = true;
  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MemberDecl)) {
    // Don't diagnose the use of a virtual member function unless it's
    // explicitly qualified.
    if (MD->isVirtual())
      ShouldCheckUse = false;
  }

  // Check the use of this member.
  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc)) {
    Owned(BaseExpr);
    return ExprError();
  }
#endif

  if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
    //return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
                                   //FD, FoundDecl, MemberNameInfo);
    return Owned(BuildMemberExpr(*this, Context, BaseExpr, FD,
                                 R.getNameLoc(), FD->getType()));
  }

#if 0
  if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
    // We may have found a field within an anonymous union or struct
    // (C++ [class.union]).
    return BuildAnonymousStructUnionMemberReference(MemberLoc, FD,
                                                    BaseExpr, OpLoc);

  if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow,
                                 Var, FoundDecl, MemberNameInfo,
                                 Var->getType().getNonReferenceType(),
                                 VK_LValue, OK_Ordinary));
  }

  if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
    ExprValueKind valueKind;
    QualType type;
    if (MemberFn->isInstance()) {
      valueKind = VK_RValue;
      type = Context.BoundMemberTy;
    } else {
      valueKind = VK_LValue;
      type = MemberFn->getType();
    }

    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow,
                                 MemberFn, FoundDecl, 
                                 MemberNameInfo, type, valueKind,
                                 OK_Ordinary));
  }
  assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");

  if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow,
                                 Enum, FoundDecl, MemberNameInfo,
                                 Enum->getType(), VK_RValue, OK_Ordinary));
  }

  Owned(BaseExpr);

  // We found something that we didn't expect. Complain.
  if (isa<TypeDecl>(MemberDecl))
    Diag(MemberLoc, diag::err_typecheck_member_reference_type)
      << MemberName << BaseType << int(IsArrow);
  else
    Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
      << MemberName << BaseType << int(IsArrow);

  Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
    << MemberName;
  R.suppressDiagnostics();
#endif
  return ExprError();
}