TypeCheck TypeCheck::NonConst() const { return !type_.isNull() && !type_.isConstQualified()
? *this : TypeCheck(); // returning TypeCheck(type_.getUnqualifiedType()) instead of *this // may look tempting, but could remove sugar we might be interested in // checking for
}
TypeCheck TypeCheck::NonConstVolatile() const { return
(!type_.isNull() && !type_.isConstQualified()
&& !type_.isVolatileQualified())
? *this : TypeCheck(); // returning TypeCheck(type_.getUnqualifiedType()) instead of *this // may look tempting, but could remove sugar we might be interested in // checking for
}
TypeCheck TypeCheck::Const() const { return
(!type_.isNull() && type_.isConstQualified()
&& !type_.isVolatileQualified())
? *this : TypeCheck(); // returning TypeCheck(type_.getUnqualifiedType()) instead of *this // may look tempting, but could remove sugar we might be interested in // checking for
}
TypeCheck TypeCheck::Volatile() const { return
(!type_.isNull() && !type_.isConstQualified()
&& type_.isVolatileQualified())
? *this : TypeCheck(); // returning TypeCheck(type_.getUnqualifiedType()) instead of *this // may look tempting, but could remove sugar we might be interested in // checking for
}
TypeCheck TypeCheck::ConstVolatile() const { return
(!type_.isNull() && type_.isConstQualified()
&& type_.isVolatileQualified())
? *this : TypeCheck(); // returning TypeCheck(type_.getUnqualifiedType()) instead of *this // may look tempting, but could remove sugar we might be interested in // checking for
}
TypeCheck TypeCheck::ConstNonVolatile() const { return
(!type_.isNull() && type_.isConstQualified()
&& !type_.isVolatileQualified())
? *this : TypeCheck(); // returning TypeCheck(type_.getUnqualifiedType()) instead of *this // may look tempting, but could remove sugar we might be interested in // checking for
}
TerminalCheck TypeCheck::AnyBoolean() const { if (type_->isBooleanType()) { return TerminalCheck(true);
} auto t = type_->getAs<clang::TypedefType>(); if (t == nullptr) { return TerminalCheck(false);
} auto n =t->getDecl()->getName(); return TerminalCheck(
n == "sal_Bool" || n == "BOOL" || n == "Boolean" || n == "FT_Bool"
|| n == "FcBool" || n == "GLboolean" || n == "NPBool" || n == "TW_BOOL"
|| n == "UBool" || n == "boolean" || n == "dbus_bool_t"
|| n == "gboolean" || n == "hb_bool_t" || n == "jboolean" || n == "my_bool");
}
TypeCheck TypeCheck::LvalueReference() const { if (!type_.isNull()) { autoconst t = type_->getAs<clang::LValueReferenceType>(); if (t != nullptr) { return TypeCheck(t->getPointeeType());
}
} return TypeCheck();
}
TypeCheck TypeCheck::RvalueReference() const { if (!type_.isNull()) { autoconst t = type_->getAs<clang::RValueReferenceType>(); if (t != nullptr) { return TypeCheck(t->getPointeeType());
}
} return TypeCheck();
}
TypeCheck TypeCheck::Pointer() const { if (!type_.isNull()) { autoconst t = type_->getAs<clang::PointerType>(); if (t != nullptr) { return TypeCheck(t->getPointeeType());
}
} return TypeCheck();
}
TypeCheck TypeCheck::MemberPointerOf() const { if (!type_.isNull()) { autoconst t = type_->getAs<clang::MemberPointerType>(); if (t != nullptr) { return TypeCheck(compat::getClass(t));
}
} return TypeCheck();
}
TerminalCheck TypeCheck::Enum() const { if (!type_.isNull()) { autoconst t = type_->getAs<clang::EnumType>(); if (t != nullptr) { return TerminalCheck(true);
}
} return TerminalCheck(false);
}
TypeCheck TypeCheck::Typedef() const { if (!type_.isNull()) { if (autoconst t = type_->getAs<clang::TypedefType>()) { return TypeCheck(t->desugar());
}
} return TypeCheck();
}
DeclCheck TypeCheck::TemplateSpecializationClass() const { if (!type_.isNull()) { if (autoconst t = type_->getAs<clang::TemplateSpecializationType>()) { if (!t->isTypeAlias()) { if (autoconst d = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(
t->getTemplateName().getAsTemplateDecl()))
{ return DeclCheck(d->getTemplatedDecl());
}
}
}
} return DeclCheck();
}
bool BaseCheckNotSomethingInterestingSubclass(const clang::CXXRecordDecl *BaseDefinition) { if (BaseDefinition) { auto tc = TypeCheck(BaseDefinition); if (tc.Class("Dialog").GlobalNamespace() || tc.Class("SfxPoolItem").GlobalNamespace()) { returnfalse;
}
} returntrue;
}
bool isDerivedFromSomethingInteresting(const clang::CXXRecordDecl *decl) { if (!decl) returnfalse; auto tc = TypeCheck(decl); if (tc.Class("Dialog")) returntrue; if (tc.Class("SfxPoolItem")) returntrue; if (!decl->hasDefinition()) { returnfalse;
} if (// not sure what hasAnyDependentBases() does, // but it avoids classes we don't want, e.g. WeakAggComponentImplHelper1
!decl->hasAnyDependentBases() &&
!decl->forallBases(BaseCheckNotSomethingInterestingSubclass)) { returntrue;
} returnfalse;
}
// Make sure Foo and ::Foo are considered equal: bool areSameSugaredType(clang::QualType type1, clang::QualType type2) { auto t1 = type1.getLocalUnqualifiedType(); if (autoconst et = llvm::dyn_cast<clang::ElaboratedType>(t1)) {
t1 = et->getNamedType();
} auto t2 = type2.getLocalUnqualifiedType(); if (autoconst et = llvm::dyn_cast<clang::ElaboratedType>(t2)) {
t2 = et->getNamedType();
} return t1 == t2;
}
bool isArithmeticOp(clang::Expr const * expr) {
expr = expr->IgnoreParenImpCasts(); if (autoconst e = llvm::dyn_cast<clang::BinaryOperator>(expr)) { switch (e->getOpcode()) { case clang::BO_Mul: case clang::BO_Div: case clang::BO_Rem: case clang::BO_Add: case clang::BO_Sub: case clang::BO_Shl: case clang::BO_Shr: case clang::BO_And: case clang::BO_Xor: case clang::BO_Or: returntrue; case clang::BO_Comma: return isArithmeticOp(e->getRHS()); default: returnfalse;
}
} return llvm::isa<clang::UnaryOperator>(expr)
|| llvm::isa<clang::AbstractConditionalOperator>(expr);
}
}
bool isOkToRemoveArithmeticCast(
clang::ASTContext & context, clang::QualType t1, clang::QualType t2, const clang::Expr* subExpr)
{ // Don't warn if the types are arithmetic (in the C++ meaning), and: either // at least one is a typedef or decltype (and if both are, they're different), // or the sub-expression involves some operation that is likely to change // types through promotion, or the sub-expression is an integer literal (so // its type generally depends on its value and suffix if any---even with a // suffix like L it could still be either long or long long): if ((t1->isIntegralType(context)
|| t1->isRealFloatingType())
&& ((!areSameSugaredType(t1, t2)
&& (loplugin::TypeCheck(t1).Typedef()
|| loplugin::TypeCheck(t2).Typedef()
|| llvm::isa<clang::DecltypeType>(t1) || llvm::isa<clang::DecltypeType>(t2)))
|| isArithmeticOp(subExpr)
|| llvm::isa<clang::IntegerLiteral>(subExpr->IgnoreParenImpCasts())))
{ returnfalse;
} returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.