Exemplo n.º 1
0
CXType clang_getPointeeType(CXType CT) {
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();
  
  if (!TP)
    return MakeCXType(QualType(), GetTU(CT));
  
  switch (TP->getTypeClass()) {
    case Type::Pointer:
      T = cast<PointerType>(TP)->getPointeeType();
      break;
    case Type::BlockPointer:
      T = cast<BlockPointerType>(TP)->getPointeeType();
      break;
    case Type::LValueReference:
    case Type::RValueReference:
      T = cast<ReferenceType>(TP)->getPointeeType();
      break;
    case Type::ObjCObjectPointer:
      T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
      break;
    default:
      T = QualType();
      break;
  }
  return MakeCXType(T, GetTU(CT));
}
Exemplo n.º 2
0
bool ReserveCandidates::expressionIsComplex(clang::Expr *expr) const
{
    if (!expr)
        return false;

    vector<CallExpr*> callExprs;
    HierarchyUtils::getChilds<CallExpr>(expr, callExprs);

    for (CallExpr *callExpr : callExprs) {
        if (QtUtils::isJavaIterator(dyn_cast<CXXMemberCallExpr>(callExpr)))
            continue;

        QualType qt = callExpr->getType();
        const Type *t = qt.getTypePtrOrNull();
        if (t && (!t->isIntegerType() || t->isBooleanType()))
            return true;
    }

    vector<ArraySubscriptExpr*> subscriptExprs;
    HierarchyUtils::getChilds<ArraySubscriptExpr>(expr, subscriptExprs);
    if (!subscriptExprs.empty())
        return true;

    BinaryOperator* binary = dyn_cast<BinaryOperator>(expr);
    if (binary && binary->isAssignmentOp()) { // Filter things like for ( ...; ...; next = node->next)

        Expr *rhs = binary->getRHS();
        if (isa<MemberExpr>(rhs) || (isa<ImplicitCastExpr>(rhs) && dyn_cast_or_null<MemberExpr>(HierarchyUtils::getFirstChildAtDepth(rhs, 1))))
            return true;
    }

    // llvm::errs() << expr->getStmtClassName() << "\n";
    return false;
}
Exemplo n.º 3
0
static CXTypeKind GetTypeKind(QualType T) {
  const Type *TP = T.getTypePtrOrNull();
  if (!TP)
    return CXType_Invalid;

#define TKCASE(K) case Type::K: return CXType_##K
  switch (TP->getTypeClass()) {
    case Type::Builtin:
      return GetBuiltinTypeKind(cast<BuiltinType>(TP));
    TKCASE(Complex);
    TKCASE(Pointer);
    TKCASE(BlockPointer);
    TKCASE(LValueReference);
    TKCASE(RValueReference);
    TKCASE(Record);
    TKCASE(Enum);
    TKCASE(Typedef);
    TKCASE(ObjCInterface);
    TKCASE(ObjCObjectPointer);
    TKCASE(FunctionNoProto);
    TKCASE(FunctionProto);
    TKCASE(ConstantArray);
    TKCASE(Vector);
    default:
      return CXType_Unexposed;
  }
#undef TKCASE
}
Exemplo n.º 4
0
CXCursor clang_getTypeDeclaration(CXType CT) {
  if (CT.kind == CXType_Invalid)
    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);

  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (!TP)
    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);

  Decl *D = nullptr;

try_again:
  switch (TP->getTypeClass()) {
  case Type::Typedef:
    D = cast<TypedefType>(TP)->getDecl();
    break;
  case Type::ObjCObject:
    D = cast<ObjCObjectType>(TP)->getInterface();
    break;
  case Type::ObjCInterface:
    D = cast<ObjCInterfaceType>(TP)->getDecl();
    break;
  case Type::Record:
  case Type::Enum:
    D = cast<TagType>(TP)->getDecl();
    break;
  case Type::TemplateSpecialization:
    if (const RecordType *Record = TP->getAs<RecordType>())
      D = Record->getDecl();
    else
      D = cast<TemplateSpecializationType>(TP)->getTemplateName()
                                                         .getAsTemplateDecl();
    break;

  case Type::Auto:
    TP = cast<AutoType>(TP)->getDeducedType().getTypePtrOrNull();
    if (TP)
      goto try_again;
    break;

  case Type::InjectedClassName:
    D = cast<InjectedClassNameType>(TP)->getDecl();
    break;

  // FIXME: Template type parameters!      

  case Type::Elaborated:
    TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
    goto try_again;

  default:
    break;
  }

  if (!D)
    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);

  return cxcursor::MakeCXCursor(D, GetTU(CT));
}
Exemplo n.º 5
0
CXType clang_getArrayElementType(CXType CT) {
  QualType ET = QualType();
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (TP) {
    switch (TP->getTypeClass()) {
    case Type::ConstantArray:
      ET = cast<ConstantArrayType> (TP)->getElementType();
      break;
    case Type::IncompleteArray:
      ET = cast<IncompleteArrayType> (TP)->getElementType();
      break;
    case Type::VariableArray:
      ET = cast<VariableArrayType> (TP)->getElementType();
      break;
    case Type::DependentSizedArray:
      ET = cast<DependentSizedArrayType> (TP)->getElementType();
      break;
    default:
      break;
    }
  }
  return MakeCXType(ET, GetTU(CT));
}
Exemplo n.º 6
0
unsigned clang_Type_isTransparentTagTypedef(CXType TT){
  QualType T = GetQualType(TT);
  if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
    if (auto *D = TT->getDecl())
      return D->isTransparentTag();
  }
  return false;
}
Exemplo n.º 7
0
Arquivo: Utils.cpp Projeto: KDE/clazy
CXXRecordDecl * Utils::namedCastOuterDecl(CXXNamedCastExpr *staticOrDynamicCast)
{
    QualType qt = staticOrDynamicCast->getTypeAsWritten();
    const Type *t = qt.getTypePtrOrNull();
    QualType qt2 = t->getPointeeType();
    const Type *t2 = qt2.getTypePtrOrNull();
    if (!t2) return nullptr;
    return t2->getAsCXXRecordDecl();
}
Exemplo n.º 8
0
CXType clang_Type_getNamedType(CXType CT){
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (TP && TP->getTypeClass() == Type::Elaborated)
    return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));

  return MakeCXType(QualType(), GetTU(CT));
}
Exemplo n.º 9
0
unsigned clang_isPODType(CXType X) {
  QualType T = GetQualType(X);
  if (!T.getTypePtrOrNull())
    return 0;
  
  CXTranslationUnit TU = GetTU(X);
  ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);

  return T.isPODType(AU->getASTContext()) ? 1 : 0;
}
Exemplo n.º 10
0
CXType clang_Type_getClassType(CXType CT) {
  QualType ET = QualType();
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (TP && TP->getTypeClass() == Type::MemberPointer) {
    ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
  }
  return MakeCXType(ET, GetTU(CT));
}
Exemplo n.º 11
0
CXType clang_getResultType(CXType X) {
  QualType T = GetQualType(X);
  if (!T.getTypePtrOrNull())
    return MakeCXType(QualType(), GetTU(X));
  
  if (const FunctionType *FD = T->getAs<FunctionType>())
    return MakeCXType(FD->getResultType(), GetTU(X));
  
  return MakeCXType(QualType(), GetTU(X));
}
Exemplo n.º 12
0
Arquivo: Utils.cpp Projeto: KDE/clazy
CXXRecordDecl * Utils::namedCastInnerDecl(CXXNamedCastExpr *staticOrDynamicCast)
{
    Expr *e = staticOrDynamicCast->getSubExpr();
    if (!e) return nullptr;
    QualType qt = e->getType();
    const Type *t = qt.getTypePtrOrNull();
    if (!t) return nullptr;
    QualType qt2 = t->getPointeeType();
    const Type *t2 = qt2.getTypePtrOrNull();
    if (!t2) return nullptr;
    return t2->getAsCXXRecordDecl();
}
Exemplo n.º 13
0
Arquivo: Utils.cpp Projeto: KDE/clazy
CXXRecordDecl *Utils::recordFromVarDecl(Decl *decl)
{
    auto varDecl = dyn_cast<VarDecl>(decl);
    if (!varDecl)
        return nullptr;

    QualType qt = varDecl->getType();
    const Type *t = qt.getTypePtrOrNull();
    if (!t)
        return nullptr;

    return t->getAsCXXRecordDecl();
}
Exemplo n.º 14
0
ClassTemplateSpecializationDecl *TemplateUtils::templateDecl(Decl *decl)
{
    if (isa<ClassTemplateSpecializationDecl>(decl))
        return dyn_cast<ClassTemplateSpecializationDecl>(decl);

    VarDecl *varDecl = dyn_cast<VarDecl>(decl);
    if (!varDecl) return nullptr;
    QualType qt = varDecl->getType();
    const Type *t = qt.getTypePtrOrNull();
    if (!t) return nullptr;
    CXXRecordDecl *classDecl = t->getAsCXXRecordDecl();
    if (!classDecl) return nullptr;
    return dyn_cast<ClassTemplateSpecializationDecl>(classDecl);
}
Exemplo n.º 15
0
void ImplicitCasts::VisitStmt(clang::Stmt *stmt)
{
    auto implicitCast = dyn_cast<ImplicitCastExpr>(stmt);
    if (implicitCast == nullptr)
        return;

    if (implicitCast->getCastKind() == clang::CK_LValueToRValue)
        return;

    if (implicitCast->getType().getTypePtrOrNull()->isBooleanType())
        return;

    Expr *expr = implicitCast->getSubExpr();
    QualType qt = expr->getType();

    if (!qt.getTypePtrOrNull()->isBooleanType()) // Filter out some bool to const bool
        return;

    Stmt *p = Utils::parent(m_parentMap, stmt);
    if (p && isa<BinaryOperator>(p))
        return;

    if (p && (isa<CStyleCastExpr>(p) || isa<CXXFunctionalCastExpr>(p)))
        return;

    if (Utils::isInsideOperatorCall(m_parentMap, stmt, {"QTextStream", "QAtomicInt", "QBasicAtomicInt"}))
        return;

    if (Utils::insideCTORCall(m_parentMap, stmt, {"QAtomicInt", "QBasicAtomicInt"}))
        return;

    if (Utils::parent(m_parentMap, implicitCast) == nullptr)
        return;

    StringUtils::printLocation(stmt->getLocStart());

    EnumConstantDecl *enumerator = m_lastDecl ? dyn_cast<EnumConstantDecl>(m_lastDecl) : nullptr;
    if (enumerator) {
        // False positive in Qt headers which generates a lot of noise
        return;
    }

    auto macro = Lexer::getImmediateMacroName(stmt->getLocStart(), m_ci.getSourceManager(), m_ci.getLangOpts());
    if (macro == "Q_UNLIKELY" || macro == "Q_LIKELY") {
        return;
    }

    emitWarning(stmt->getLocStart(), "Implicit cast from bool");
}
Exemplo n.º 16
0
void FunctionArgsByRef::VisitDecl(Decl *decl)
{
    FunctionDecl *functionDecl = dyn_cast<FunctionDecl>(decl);
    if (functionDecl == nullptr || !functionDecl->hasBody() || shouldIgnoreFunction(functionDecl->getNameAsString())
            || !functionDecl->isThisDeclarationADefinition()) return;

    Stmt *body = functionDecl->getBody();

    for (auto it = functionDecl->param_begin(), end = functionDecl->param_end(); it != end; ++it) {
        const ParmVarDecl *param = *it;
        QualType paramQt = param->getType();
        const Type *paramType = paramQt.getTypePtrOrNull();
        if (paramType == nullptr || paramType->isDependentType())
            continue;

        const int size_of_T = m_ci.getASTContext().getTypeSize(paramQt) / 8;
        const bool isSmall = size_of_T <= 16; // TODO: What about arm ?
        CXXRecordDecl *recordDecl = paramType->getAsCXXRecordDecl();
        const bool isUserNonTrivial = recordDecl && (recordDecl->hasUserDeclaredCopyConstructor() || recordDecl->hasUserDeclaredDestructor());
        const bool isReference = paramType->isLValueReferenceType();
        const bool isConst = paramQt.isConstQualified();
        if (recordDecl && shouldIgnoreClass(recordDecl->getQualifiedNameAsString()))
            continue;

        std::string error;
        if (isConst && !isReference) {
            if (!isSmall) {
                error += warningMsgForSmallType(size_of_T, paramQt.getAsString());
            } else if (isUserNonTrivial) {
                error += "Missing reference on non-trivial type " + recordDecl->getQualifiedNameAsString();
            }
        } else if (isConst && isReference && !isUserNonTrivial && isSmall) {
            //error += "Don't use by-ref on small trivial type";
        } else if (!isConst && !isReference && (!isSmall || isUserNonTrivial)) {
            if (Utils::containsNonConstMemberCall(body, param) || Utils::containsCallByRef(body, param))
                continue;
            if (!isSmall) {
                error += warningMsgForSmallType(size_of_T, paramQt.getAsString());
            } else if (isUserNonTrivial) {
                error += "Missing reference on non-trivial type " + recordDecl->getQualifiedNameAsString();
            }
        }

        if (!error.empty()) {
            emitWarning(param->getLocStart(), error.c_str());
        }
    }
}
Exemplo n.º 17
0
void MissingTypeinfo::registerQTypeInfo(ClassTemplateSpecializationDecl *decl)
{
    if (decl->getName() == "QTypeInfo") {
        auto &args = decl->getTemplateArgs();
        if (args.size() != 1)
            return;

        QualType qt = args[0].getAsType();
        const Type *t = qt.getTypePtrOrNull();
        CXXRecordDecl *recordDecl =  t ? t->getAsCXXRecordDecl() : nullptr;
        // llvm::errs() << qt.getAsString() << " foo\n";
        if (recordDecl != nullptr) {
            m_typeInfos.insert(recordDecl->getQualifiedNameAsString());
        }
    }
}
Exemplo n.º 18
0
long long clang_getArraySize(CXType CT) {
  long long result = -1;
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (TP) {
    switch (TP->getTypeClass()) {
    case Type::ConstantArray:
      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
      break;
    default:
      break;
    }
  }
  return result;
}
Exemplo n.º 19
0
Arquivo: Utils.cpp Projeto: KDE/clazy
bool Utils::hasMember(CXXRecordDecl *record, const string &memberTypeName)
{
    if (!record)
        return false;

    for (auto field : record->fields()) {
        field->getParent()->getNameAsString();
        QualType qt = field->getType();
        const Type *t = qt.getTypePtrOrNull();
        if (t && t->getAsCXXRecordDecl()) {
            CXXRecordDecl *rec = t->getAsCXXRecordDecl();
            if (rec->getNameAsString() == memberTypeName)
                return true;
        }
    }

    return false;
}
Exemplo n.º 20
0
bool HostProgramTuning::VisitCallExpr(CallExpr *E) {

	if (E != NULL){
		QualType q = E->getType();
		const Type *t = q.getTypePtrOrNull();

		if(t != NULL)
		{
			FunctionDecl *func = E->getDirectCallee();
			
			if (!func) return false;
			ProcessFuncCall(func->getNameInfo().getName().getAsString(), E);
		}
	}


	return true;
}
Exemplo n.º 21
0
Arquivo: Utils.cpp Projeto: KDE/clazy
static bool isArgOfFunc(T expr, FunctionDecl *fDecl, const VarDecl *varDecl, bool byRefOrPtrOnly)
{
    unsigned int param = -1;
    for (auto arg : expr->arguments()) {
        ++param;
        DeclRefExpr *refExpr = dyn_cast<DeclRefExpr>(arg);
        if (!refExpr)  {
            if (clazy_std::hasChildren(arg)) {
                Stmt* firstChild = *(arg->child_begin()); // Can be null (bug #362236)
                refExpr = firstChild ? dyn_cast<DeclRefExpr>(firstChild) : nullptr;
                if (!refExpr)
                    continue;
            } else {
                continue;
            }
        }

        if (refExpr->getDecl() != varDecl) // It's our variable ?
            continue;

        if (!byRefOrPtrOnly) {
            // We found it
            return true;
        }

        // It is, lets see if the callee takes our variable by const-ref
        if (param >= fDecl->param_size())
            continue;

        ParmVarDecl *paramDecl = fDecl->getParamDecl(param);
        if (!paramDecl)
            continue;

        QualType qt = paramDecl->getType();
        const Type *t = qt.getTypePtrOrNull();
        if (!t)
            continue;

        if ((t->isReferenceType() || t->isPointerType()) && !t->getPointeeType().isConstQualified())
            return true; // function receives non-const ref, so our foreach variable cant be const-ref
    }

    return false;
}
Exemplo n.º 22
0
  bool VisitVarDecl(const VarDecl *D) {
    // Bail out early if this location should not be checked.
    if (doIgnore(D->getLocation())) {
      return true;
    }

    const QualType qualType = D->getType();
    // Bail out if this type is either an enum or does not look like a real
    // value.
    if (qualType->isEnumeralType() || qualType->isBooleanType() ||
        qualType->isArithmeticType() == false) {
      return true;
    }

    const Type *t = qualType.getTypePtrOrNull();
    assert(t && "Type of arithmetic types has to be available.");
    const std::string typeName = qualType.getAsString();
    // If it is of the same type as "size_t" and does have "size_t" somewhere in
    // its name we can go with it.
    // Please note: This also allows a typedef for "unsigned long" to be named
    // e.g. "size_type" without any size indicator - which may or may not be a
    // good thing.
    if (context->hasSameUnqualifiedType(qualType, context->getSizeType()) &&
        typeName.find("size_t") != std::string::npos) {
      return true;
    }

    // char_t and wchar_t are not subject to this rule.
    const std::string needle = "char_t";
    if (std::equal(needle.rbegin(), needle.rend(), typeName.rbegin())) {
      return true;
    }

    const uint64_t typeSize = context->getTypeSize(t);
    const std::string sizeStr = llvm::utostr(typeSize);
    // For all remaining types, the number of occupied bits must be embedded in
    // the typename.
    if (typeName.rfind(sizeStr) == std::string::npos) {
      reportError(D->getLocation());
    }

    return true;
  }
Exemplo n.º 23
0
string TemplateUtils::getTemplateArgumentTypeStr(ClassTemplateSpecializationDecl *specialization,
                                                 unsigned int index, const LangOptions &lo, bool recordOnly)
{
    if (!specialization)
        return {};

    auto &args = specialization->getTemplateArgs();
    if (args.size() <= index)
        return {};

    QualType qt = args[index].getAsType();
    if (recordOnly) {
        const Type *t = qt.getTypePtrOrNull();
        if (!t || !t->getAsCXXRecordDecl())
            return {};
    }

    return StringUtils::simpleTypeName(args[index].getAsType(), lo);
}
Exemplo n.º 24
0
bool TypeUtils::classifyQualType(const CompilerInstance &ci, const VarDecl *varDecl, QualTypeClassification &classif, clang::Stmt *body)
{
    if (!varDecl)
        return false;

    QualType qualType = TypeUtils::unrefQualType(varDecl->getType());
    const Type *paramType = qualType.getTypePtrOrNull();
    if (!paramType || paramType->isIncompleteType())
        return false;

    if (isUndeducibleAuto(paramType))
        return false;

    classif.size_of_T = ci.getASTContext().getTypeSize(qualType) / 8;
    classif.isBig = classif.size_of_T > 16;
    CXXRecordDecl *recordDecl = paramType->getAsCXXRecordDecl();
    classif.isNonTriviallyCopyable = recordDecl && (recordDecl->hasNonTrivialCopyConstructor() || recordDecl->hasNonTrivialDestructor());
    classif.isReference = varDecl->getType()->isLValueReferenceType();
    classif.isConst = qualType.isConstQualified();

    if (varDecl->getType()->isRValueReferenceType()) // && ref, nothing to do here
        return true;

    if (classif.isConst && !classif.isReference) {
        classif.passNonTriviallyCopyableByConstRef = classif.isNonTriviallyCopyable;
        if (classif.isBig) {
            classif.passBigTypeByConstRef = true;
        }
    } else if (classif.isConst && classif.isReference && !classif.isNonTriviallyCopyable && !classif.isBig) {
        classif.passSmallTrivialByValue = true;
    } else if (!classif.isConst && !classif.isReference && (classif.isBig || classif.isNonTriviallyCopyable)) {
        if (body && (Utils::containsNonConstMemberCall(body, varDecl) || Utils::isPassedToFunction(StmtBodyRange(body), varDecl, /*byrefonly=*/ true)))
            return true;
        classif.passNonTriviallyCopyableByConstRef = classif.isNonTriviallyCopyable;
        if (classif.isBig) {
            classif.passBigTypeByConstRef = true;
        }
    }

    return true;
}
Exemplo n.º 25
0
static bool iterateCallExpr2(T* callExpr, CheckBase *check, ParentMap *parentMap)
{
    if (!callExpr)
        return false;

    bool result = false;

    int i = 0;
    for (auto arg : callExpr->arguments()) {
        ++i;
        auto implicitCast = dyn_cast<ImplicitCastExpr>(arg);
        if (!implicitCast || implicitCast->getCastKind() != clang::CK_IntegralCast)
            continue;

        if (implicitCast->getType().getTypePtrOrNull()->isBooleanType())
            continue;

        Expr *expr = implicitCast->getSubExpr();
        QualType qt = expr->getType();

        if (!qt.getTypePtrOrNull()->isBooleanType()) // Filter out some bool to const bool
            continue;

        if (HierarchyUtils::getFirstChildOfType<CXXFunctionalCastExpr>(implicitCast))
            continue;

        if (HierarchyUtils::getFirstChildOfType<CStyleCastExpr>(implicitCast))
            continue;

        if (Utils::isInsideOperatorCall(parentMap, implicitCast, {"QTextStream", "QAtomicInt", "QBasicAtomicInt"}))
            continue;

        if (Utils::insideCTORCall(parentMap, implicitCast, {"QAtomicInt", "QBasicAtomicInt"}))
            continue;

        check->emitWarning(implicitCast->getLocStart(), "Implicit bool to int cast (argument " + std::to_string(i) + ')');
        result = true;
    }

    return result;
}
Exemplo n.º 26
0
	bool is_of_class_for_MemberExpr(MemberExpr const * const e, std::string const & class_name)
	{
		ValueDecl const * decl = e->getMemberDecl();
		QualType qt = decl->getType();
		Type const * t = qt.getTypePtrOrNull();
		if( t )
		{
			RecordType const * rec = t->getAs<RecordType>();
			if( rec )
			{
				TagDecl const * tagdecl = rec->getDecl();
				IdentifierInfo * idinfo = tagdecl->getIdentifier();
				if( idinfo->getName() == class_name )
				{
					return true;
				}
			}
		}

		return false;
	}
Exemplo n.º 27
0
CXType clang_getElementType(CXType CT) {
  QualType ET = QualType();
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (TP) {
    switch (TP->getTypeClass()) {
    case Type::ConstantArray:
      ET = cast<ConstantArrayType> (TP)->getElementType();
      break;
    case Type::Vector:
      ET = cast<VectorType> (TP)->getElementType();
      break;
    case Type::Complex:
      ET = cast<ComplexType> (TP)->getElementType();
      break;
    default:
      break;
    }
  }
  return MakeCXType(ET, GetTU(CT));
}
Exemplo n.º 28
0
void MutableContainerKey::VisitDecl(clang::Decl *decl)
{
    auto tsdecl = Utils::templateSpecializationFromVarDecl(decl);
    if (!tsdecl || !isInterestingContainer(tsdecl->getName()))
        return;

    const TemplateArgumentList &templateArguments = tsdecl->getTemplateArgs();
    if (templateArguments.size() != 2)
        return;

    QualType qt = templateArguments[0].getAsType();
    const Type *t = qt.getTypePtrOrNull();
    if (!t)
        return;

    auto record = t->isRecordType() ? t->getAsCXXRecordDecl() : nullptr;
    if (!StringUtils::classIsOneOf(record, {"QPointer", "QWeakPointer",
                                            "QPersistentModelIndex", "weak_ptr"}))
        return;


    emitWarning(decl->getLocStart(), "Associative container key might be modified externally");
}
Exemplo n.º 29
0
CXType clang_getPointeeType(CXType CT) {
  QualType T = GetQualType(CT);
  const Type *TP = T.getTypePtrOrNull();

  if (!TP)
    return MakeCXType(QualType(), GetTU(CT));

try_again:
  switch (TP->getTypeClass()) {
    case Type::Pointer:
      T = cast<PointerType>(TP)->getPointeeType();
      break;
    case Type::BlockPointer:
      T = cast<BlockPointerType>(TP)->getPointeeType();
      break;
    case Type::LValueReference:
    case Type::RValueReference:
      T = cast<ReferenceType>(TP)->getPointeeType();
      break;
    case Type::ObjCObjectPointer:
      T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
      break;
    case Type::MemberPointer:
      T = cast<MemberPointerType>(TP)->getPointeeType();
      break;
    case Type::Auto:
    case Type::DeducedTemplateSpecialization:
      TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
      if (TP)
        goto try_again;
      break;
    default:
      T = QualType();
      break;
  }
  return MakeCXType(T, GetTU(CT));
}
Exemplo n.º 30
0
const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
                                                const LocationContext *LC) {
  const MemRegion *sReg = 0;

  if (D->hasGlobalStorage() && !D->isStaticLocal()) {

    // First handle the globals defined in system headers.
    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
      // Whitelist the system globals which often DO GET modified, assume the
      // rest are immutable.
      if (D->getName().find("errno") != StringRef::npos)
        sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
      else
        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);

    // Treat other globals as GlobalInternal unless they are constants.
    } else {
      QualType GQT = D->getType();
      const Type *GT = GQT.getTypePtrOrNull();
      // TODO: We could walk the complex types here and see if everything is
      // constified.
      if (GT && GQT.isConstQualified() && GT->isArithmeticType())
        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
      else
        sReg = getGlobalsRegion();
    }
  
  // Finally handle static locals.  
  } else {
    // FIXME: Once we implement scope handling, we will need to properly lookup
    // 'D' to the proper LocationContext.
    const DeclContext *DC = D->getDeclContext();
    llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
      getStackOrCaptureRegionForDeclContext(LC, DC, D);
    
    if (V.is<const VarRegion*>())
      return V.get<const VarRegion*>();
    
    const StackFrameContext *STC = V.get<const StackFrameContext*>();

    if (!STC)
      sReg = getUnknownRegion();
    else {
      if (D->hasLocalStorage()) {
        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
      }
      else {
        assert(D->isStaticLocal());
        const Decl *STCD = STC->getDecl();
        if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
                                  getFunctionTextRegion(cast<NamedDecl>(STCD)));
        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
          const BlockTextRegion *BTR =
            getBlockTextRegion(BD,
                     C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
                     STC->getAnalysisDeclContext());
          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
                                  BTR);
        }
        else {
          sReg = getGlobalsRegion();
        }
      }
    }
  }

  return getSubRegion<VarRegion>(D, sReg);
}