本文整理汇总了C++中QualType::isNull方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::isNull方法的具体用法?C++ QualType::isNull怎么用?C++ QualType::isNull使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::isNull方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: printPretty
void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
switch (getKind()) {
case APValue::Uninitialized:
Out << "<uninitialized>";
return;
case APValue::Int:
if (Ty->isBooleanType())
Out << (getInt().getBoolValue() ? "true" : "false");
else
Out << getInt();
return;
case APValue::Float:
Out << GetApproxValue(getFloat());
return;
case APValue::Vector: {
Out << '{';
QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
getVectorElt(0).printPretty(Out, Ctx, ElemTy);
for (unsigned i = 1; i != getVectorLength(); ++i) {
Out << ", ";
getVectorElt(i).printPretty(Out, Ctx, ElemTy);
}
Out << '}';
return;
}
case APValue::ComplexInt:
Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
return;
case APValue::ComplexFloat:
Out << GetApproxValue(getComplexFloatReal()) << "+"
<< GetApproxValue(getComplexFloatImag()) << "i";
return;
case APValue::LValue: {
LValueBase Base = getLValueBase();
if (!Base) {
Out << "0";
return;
}
bool IsReference = Ty->isReferenceType();
QualType InnerTy
= IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
if (InnerTy.isNull())
InnerTy = Ty;
if (!hasLValuePath()) {
// No lvalue path: just print the offset.
CharUnits O = getLValueOffset();
CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
if (!O.isZero()) {
if (IsReference)
Out << "*(";
if (O % S) {
Out << "(char*)";
S = CharUnits::One();
}
Out << '&';
} else if (!IsReference)
Out << '&';
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
Out << *VD;
else {
assert(Base.get<const Expr *>() != nullptr &&
"Expecting non-null Expr");
Base.get<const Expr*>()->printPretty(Out, nullptr,
Ctx.getPrintingPolicy());
}
if (!O.isZero()) {
Out << " + " << (O / S);
if (IsReference)
Out << ')';
}
return;
}
// We have an lvalue path. Print it out nicely.
if (!IsReference)
Out << '&';
else if (isLValueOnePastTheEnd())
Out << "*(&";
QualType ElemTy;
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
Out << *VD;
ElemTy = VD->getType();
} else {
const Expr *E = Base.get<const Expr*>();
assert(E != nullptr && "Expecting non-null Expr");
E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
ElemTy = E->getType();
}
ArrayRef<LValuePathEntry> Path = getLValuePath();
const CXXRecordDecl *CastToBase = nullptr;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
if (ElemTy->getAs<RecordType>()) {
// The lvalue refers to a class type, so the next path entry is a base
// or member.
//.........这里部分代码省略.........
示例2: checkPostObjCMessage
/// This callback is used to infer the types for Class variables. This info is
/// used later to validate messages that sent to classes. Class variables are
/// initialized with by invoking the 'class' method on a class.
/// This method is also used to infer the type information for the return
/// types.
// TODO: right now it only tracks generic types. Extend this to track every
// type in the DynamicTypeMap and diagnose type errors!
void DynamicTypePropagation::checkPostObjCMessage(const ObjCMethodCall &M,
CheckerContext &C) const {
const ObjCMessageExpr *MessageExpr = M.getOriginExpr();
SymbolRef RetSym = M.getReturnValue().getAsSymbol();
if (!RetSym)
return;
Selector Sel = MessageExpr->getSelector();
ProgramStateRef State = C.getState();
// Inference for class variables.
// We are only interested in cases where the class method is invoked on a
// class. This method is provided by the runtime and available on all classes.
if (MessageExpr->getReceiverKind() == ObjCMessageExpr::Class &&
Sel.getAsString() == "class") {
QualType ReceiverType = MessageExpr->getClassReceiver();
const auto *ReceiverClassType = ReceiverType->getAs<ObjCObjectType>();
QualType ReceiverClassPointerType =
C.getASTContext().getObjCObjectPointerType(
QualType(ReceiverClassType, 0));
if (!ReceiverClassType->isSpecialized())
return;
const auto *InferredType =
ReceiverClassPointerType->getAs<ObjCObjectPointerType>();
assert(InferredType);
State = State->set<MostSpecializedTypeArgsMap>(RetSym, InferredType);
C.addTransition(State);
return;
}
// Tracking for return types.
SymbolRef RecSym = M.getReceiverSVal().getAsSymbol();
if (!RecSym)
return;
const ObjCObjectPointerType *const *TrackedType =
State->get<MostSpecializedTypeArgsMap>(RecSym);
if (!TrackedType)
return;
ASTContext &ASTCtxt = C.getASTContext();
const ObjCMethodDecl *Method =
findMethodDecl(MessageExpr, *TrackedType, ASTCtxt);
if (!Method)
return;
Optional<ArrayRef<QualType>> TypeArgs =
(*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
if (!TypeArgs)
return;
QualType ResultType =
getReturnTypeForMethod(Method, *TypeArgs, *TrackedType, ASTCtxt);
// The static type is the same as the deduced type.
if (ResultType.isNull())
return;
const MemRegion *RetRegion = M.getReturnValue().getAsRegion();
ExplodedNode *Pred = C.getPredecessor();
// When there is an entry available for the return symbol in DynamicTypeMap,
// the call was inlined, and the information in the DynamicTypeMap is should
// be precise.
if (RetRegion && !State->get<DynamicTypeMap>(RetRegion)) {
// TODO: we have duplicated information in DynamicTypeMap and
// MostSpecializedTypeArgsMap. We should only store anything in the later if
// the stored data differs from the one stored in the former.
State = setDynamicTypeInfo(State, RetRegion, ResultType,
/*CanBeSubclass=*/true);
Pred = C.addTransition(State);
}
const auto *ResultPtrType = ResultType->getAs<ObjCObjectPointerType>();
if (!ResultPtrType || ResultPtrType->isUnspecialized())
return;
// When the result is a specialized type and it is not tracked yet, track it
// for the result symbol.
if (!State->get<MostSpecializedTypeArgsMap>(RetSym)) {
State = State->set<MostSpecializedTypeArgsMap>(RetSym, ResultPtrType);
C.addTransition(State, Pred);
}
}
示例3: BuildCXXNestedNameSpecifier
/// \brief Build a new nested-name-specifier for "identifier::", as described
/// by ActOnCXXNestedNameSpecifier.
///
/// \param S Scope in which the nested-name-specifier occurs.
/// \param Identifier Identifier in the sequence "identifier" "::".
/// \param IdentifierLoc Location of the \p Identifier.
/// \param CCLoc Location of "::" following Identifier.
/// \param ObjectType Type of postfix expression if the nested-name-specifier
/// occurs in construct like: <tt>ptr->nns::f</tt>.
/// \param EnteringContext If true, enter the context specified by the
/// nested-name-specifier.
/// \param SS Optional nested name specifier preceding the identifier.
/// \param ScopeLookupResult Provides the result of name lookup within the
/// scope of the nested-name-specifier that was computed at template
/// definition time.
/// \param ErrorRecoveryLookup Specifies if the method is called to improve
/// error recovery and what kind of recovery is performed.
/// \param IsCorrectedToColon If not null, suggestion of replace '::' -> ':'
/// are allowed. The bool value pointed by this parameter is set to
/// 'true' if the identifier is treated as if it was followed by ':',
/// not '::'.
///
/// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
/// that it contains an extra parameter \p ScopeLookupResult, which provides
/// the result of name lookup within the scope of the nested-name-specifier
/// that was computed at template definition time.
///
/// If ErrorRecoveryLookup is true, then this call is used to improve error
/// recovery. This means that it should not emit diagnostics, it should
/// just return true on failure. It also means it should only return a valid
/// scope if it *knows* that the result is correct. It should not return in a
/// dependent context, for example. Nor will it extend \p SS with the scope
/// specifier.
bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
IdentifierInfo &Identifier,
SourceLocation IdentifierLoc,
SourceLocation CCLoc,
QualType ObjectType,
bool EnteringContext,
CXXScopeSpec &SS,
NamedDecl *ScopeLookupResult,
bool ErrorRecoveryLookup,
bool *IsCorrectedToColon) {
LookupResult Found(*this, &Identifier, IdentifierLoc,
LookupNestedNameSpecifierName);
// Determine where to perform name lookup
DeclContext *LookupCtx = nullptr;
bool isDependent = false;
if (IsCorrectedToColon)
*IsCorrectedToColon = false;
if (!ObjectType.isNull()) {
// This nested-name-specifier occurs in a member access expression, e.g.,
// x->B::f, and we are looking into the type of the object.
assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
LookupCtx = computeDeclContext(ObjectType);
isDependent = ObjectType->isDependentType();
} else if (SS.isSet()) {
// This nested-name-specifier occurs after another nested-name-specifier,
// so look into the context associated with the prior nested-name-specifier.
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = isDependentScopeSpecifier(SS);
Found.setContextRange(SS.getRange());
}
bool ObjectTypeSearchedInScope = false;
if (LookupCtx) {
// Perform "qualified" name lookup into the declaration context we
// computed, which is either the type of the base of a member access
// expression or the declaration context associated with a prior
// nested-name-specifier.
// The declaration context must be complete.
if (!LookupCtx->isDependentContext() &&
RequireCompleteDeclContext(SS, LookupCtx))
return true;
LookupQualifiedName(Found, LookupCtx);
if (!ObjectType.isNull() && Found.empty()) {
// C++ [basic.lookup.classref]p4:
// If the id-expression in a class member access is a qualified-id of
// the form
//
// class-name-or-namespace-name::...
//
// the class-name-or-namespace-name following the . or -> operator is
// looked up both in the context of the entire postfix-expression and in
// the scope of the class of the object expression. If the name is found
// only in the scope of the class of the object expression, the name
// shall refer to a class-name. If the name is found only in the
// context of the entire postfix-expression, the name shall refer to a
// class-name or namespace-name. [...]
//
// Qualified name lookup into a class will not find a namespace-name,
// so we do not need to diagnose that case specifically. However,
// this qualified name lookup may find nothing. In that case, perform
// unqualified name lookup in the given scope (if available) or
// reconstruct the result from when name lookup was performed at template
// definition time.
//.........这里部分代码省略.........
示例4: isDependentName
bool DeclarationName::isDependentName() const {
QualType T = getCXXNameType();
return !T.isNull() && T->isDependentType();
}
示例5: SynthesizeCppVP
// We need to artificially create:
// cling::valuePrinterInternal::Select((void*) raw_ostream,
// (ASTContext)Ctx, (Expr*)E, &i);
Expr* ValuePrinterSynthesizer::SynthesizeCppVP(Expr* E) {
QualType QT = E->getType();
// For now we skip void and function pointer types.
if (QT.isNull() || QT->isVoidType())
return 0;
// 1. Call gCling->getValuePrinterStream()
// 1.1. Find gCling
SourceLocation NoSLoc = SourceLocation();
NamespaceDecl* NSD = utils::Lookup::Namespace(m_Sema, "cling");
NSD = utils::Lookup::Namespace(m_Sema, "valuePrinterInternal", NSD);
DeclarationName PVName = &m_Context->Idents.get("Select");
LookupResult R(*m_Sema, PVName, NoSLoc, Sema::LookupOrdinaryName,
Sema::ForRedeclaration);
assert(NSD && "There must be a valid namespace.");
m_Sema->LookupQualifiedName(R, NSD);
assert(!R.empty() && "Cannot find valuePrinterInternal::Select(...)");
CXXScopeSpec CSS;
Expr* UnresolvedLookup
= m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).take();
// 2.4. Prepare the params
// 2.4.1 Lookup the llvm::raw_ostream
CXXRecordDecl* RawOStreamRD
= dyn_cast<CXXRecordDecl>(utils::Lookup::Named(m_Sema, "raw_ostream",
utils::Lookup::Namespace(m_Sema,
"llvm")));
assert(RawOStreamRD && "Declaration of the expr not found!");
QualType RawOStreamRDTy = m_Context->getTypeDeclType(RawOStreamRD);
// 2.4.2 Lookup the expr type
CXXRecordDecl* ExprRD
= dyn_cast<CXXRecordDecl>(utils::Lookup::Named(m_Sema, "Expr",
utils::Lookup::Namespace(m_Sema,
"clang")));
assert(ExprRD && "Declaration of the expr not found!");
QualType ExprRDTy = m_Context->getTypeDeclType(ExprRD);
// 2.4.3 Lookup ASTContext type
CXXRecordDecl* ASTContextRD
= dyn_cast<CXXRecordDecl>(utils::Lookup::Named(m_Sema, "ASTContext",
utils::Lookup::Namespace(m_Sema,
"clang")));
assert(ASTContextRD && "Declaration of the expr not found!");
QualType ASTContextRDTy = m_Context->getTypeDeclType(ASTContextRD);
Expr* RawOStreamTy
= utils::Synthesize::CStyleCastPtrExpr(m_Sema, RawOStreamRDTy,
(uint64_t)m_ValuePrinterStream.get()
);
Expr* ExprTy = utils::Synthesize::CStyleCastPtrExpr(m_Sema, ExprRDTy,
(uint64_t)E);
Expr* ASTContextTy
= utils::Synthesize::CStyleCastPtrExpr(m_Sema, ASTContextRDTy,
(uint64_t)m_Context);
// E might contain temporaries. This means that the topmost expr is
// ExprWithCleanups. This contains the information about the temporaries and
// signals when they should be destroyed.
// Here we replace E with call to value printer and we must extend the life
// time of those temporaries to the end of the new CallExpr.
bool NeedsCleanup = false;
if (ExprWithCleanups* EWC = dyn_cast<ExprWithCleanups>(E)) {
E = EWC->getSubExpr();
NeedsCleanup = true;
}
if (QT->isFunctionPointerType()) {
// convert func ptr to void*:
E = utils::Synthesize::CStyleCastPtrExpr(m_Sema, m_Context->VoidPtrTy, E);
}
llvm::SmallVector<Expr*, 4> CallArgs;
CallArgs.push_back(RawOStreamTy);
CallArgs.push_back(ExprTy);
CallArgs.push_back(ASTContextTy);
CallArgs.push_back(E);
Scope* S = m_Sema->getScopeForContext(m_Sema->CurContext);
// Here we expect a template instantiation. We need to open the transaction
// that we are currently work with.
Transaction::State oldState = getTransaction()->getState();
getTransaction()->setState(Transaction::kCollecting);
Expr* Result = m_Sema->ActOnCallExpr(S, UnresolvedLookup, NoSLoc,
CallArgs, NoSLoc).take();
getTransaction()->setState(oldState);
Result = m_Sema->ActOnFinishFullExpr(Result).take();
if (NeedsCleanup && !isa<ExprWithCleanups>(Result)) {
llvm::ArrayRef<ExprWithCleanups::CleanupObject> Cleanups;
ExprWithCleanups* EWC
//.........这里部分代码省略.........
示例6: isDeclarationOfFunction
bool Declarator::isDeclarationOfFunction() const {
for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
switch (DeclTypeInfo[i].Kind) {
case DeclaratorChunk::Function:
return true;
case DeclaratorChunk::Paren:
continue;
case DeclaratorChunk::Pointer:
case DeclaratorChunk::Reference:
case DeclaratorChunk::Array:
case DeclaratorChunk::BlockPointer:
case DeclaratorChunk::MemberPointer:
return false;
}
llvm_unreachable("Invalid type chunk");
}
switch (DS.getTypeSpecType()) {
case TST_atomic:
case TST_auto:
case TST_bool:
case TST_char:
case TST_char16:
case TST_char32:
case TST_class:
case TST_decimal128:
case TST_decimal32:
case TST_decimal64:
case TST_double:
case TST_enum:
case TST_error:
case TST_float:
case TST_half:
case TST_int:
case TST_int128:
case TST_struct:
case TST_interface:
case TST_union:
case TST_unknown_anytype:
case TST_unspecified:
case TST_void:
case TST_wchar:
case TST_image1d_t:
case TST_image1d_array_t:
case TST_image1d_buffer_t:
case TST_image2d_t:
case TST_image2d_array_t:
case TST_image3d_t:
case TST_sampler_t:
case TST_event_t:
return false;
case TST_decltype_auto:
// This must have an initializer, so can't be a function declaration,
// even if the initializer has function type.
return false;
case TST_decltype:
case TST_typeofExpr:
if (Expr *E = DS.getRepAsExpr())
return E->getType()->isFunctionType();
return false;
case TST_underlyingType:
case TST_typename:
case TST_typeofType: {
QualType QT = DS.getRepAsType().get();
if (QT.isNull())
return false;
if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
QT = LIT->getType();
if (QT.isNull())
return false;
return QT->isFunctionType();
}
}
llvm_unreachable("Invalid TypeSpecType!");
}
示例7: isExprCallable
/// \brief Figure out if an expression could be turned into a call.
///
/// Use this when trying to recover from an error where the programmer may have
/// written just the name of a function instead of actually calling it.
///
/// \param E - The expression to examine.
/// \param ZeroArgCallReturnTy - If the expression can be turned into a call
/// with no arguments, this parameter is set to the type returned by such a
/// call; otherwise, it is set to an empty QualType.
/// \param OverloadSet - If the expression is an overloaded function
/// name, this parameter is populated with the decls of the various overloads.
bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy,
UnresolvedSetImpl &OverloadSet) {
ZeroArgCallReturnTy = QualType();
OverloadSet.clear();
if (E.getType() == Context.OverloadTy) {
OverloadExpr::FindResult FR = OverloadExpr::find(const_cast<Expr*>(&E));
const OverloadExpr *Overloads = FR.Expression;
for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
OverloadSet.addDecl(*it);
// Check whether the function is a non-template which takes no
// arguments.
if (const FunctionDecl *OverloadDecl
= dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl())) {
if (OverloadDecl->getMinRequiredArguments() == 0)
ZeroArgCallReturnTy = OverloadDecl->getResultType();
}
}
// Ignore overloads that are pointer-to-member constants.
if (FR.HasFormOfMemberPointer)
return false;
return true;
}
if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) {
if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) {
if (Fun->getMinRequiredArguments() == 0)
ZeroArgCallReturnTy = Fun->getResultType();
return true;
}
}
// We don't have an expression that's convenient to get a FunctionDecl from,
// but we can at least check if the type is "function of 0 arguments".
QualType ExprTy = E.getType();
const FunctionType *FunTy = NULL;
QualType PointeeTy = ExprTy->getPointeeType();
if (!PointeeTy.isNull())
FunTy = PointeeTy->getAs<FunctionType>();
if (!FunTy)
FunTy = ExprTy->getAs<FunctionType>();
if (!FunTy && ExprTy == Context.BoundMemberTy) {
// Look for the bound-member type. If it's still overloaded, give up,
// although we probably should have fallen into the OverloadExpr case above
// if we actually have an overloaded bound member.
QualType BoundMemberTy = Expr::findBoundMemberType(&E);
if (!BoundMemberTy.isNull())
FunTy = BoundMemberTy->castAs<FunctionType>();
}
if (const FunctionProtoType *FPT =
dyn_cast_or_null<FunctionProtoType>(FunTy)) {
if (FPT->getNumArgs() == 0)
ZeroArgCallReturnTy = FunTy->getResultType();
return true;
}
return false;
}
示例8: isDeclarationOfFunction
bool Declarator::isDeclarationOfFunction() const {
for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
switch (DeclTypeInfo[i].Kind) {
case DeclaratorChunk::Function:
return true;
case DeclaratorChunk::Paren:
continue;
case DeclaratorChunk::Pointer:
case DeclaratorChunk::Reference:
case DeclaratorChunk::Array:
case DeclaratorChunk::BlockPointer:
case DeclaratorChunk::MemberPointer:
return false;
}
llvm_unreachable("Invalid type chunk");
}
switch (DS.getTypeSpecType()) {
case TST_atomic:
case TST_auto:
case TST_bool:
case TST_char:
case TST_char16:
case TST_char32:
case TST_class:
case TST_decimal128:
case TST_decimal32:
case TST_decimal64:
case TST_double:
case TST_enum:
case TST_error:
case TST_float:
case TST_half:
case TST_int:
case TST_int128:
case TST_struct:
case TST_union:
case TST_unknown_anytype:
case TST_unspecified:
case TST_void:
case TST_wchar:
case TST_cbit: //Scaffold addition
case TST_qbit: //Scaffold addition
case TST_qstruct:
case TST_qunion:
return false;
case TST_decltype:
case TST_typeofExpr:
if (Expr *E = DS.getRepAsExpr())
return E->getType()->isFunctionType();
return false;
case TST_underlyingType:
case TST_typename:
case TST_typeofType: {
QualType QT = DS.getRepAsType().get();
if (QT.isNull())
return false;
if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
QT = LIT->getType();
if (QT.isNull())
return false;
return QT->isFunctionType();
}
}
llvm_unreachable("Invalid TypeSpecType!");
}
示例9: check
void ScopeChecker::check(
const MatchFinder::MatchResult &Result) {
// There are a variety of different reasons why something could be allocated
AllocationVariety Variety = AV_None;
SourceLocation Loc;
QualType T;
if (const ParmVarDecl *D =
Result.Nodes.getNodeAs<ParmVarDecl>("parm_vardecl")) {
if (D->hasUnparsedDefaultArg() || D->hasUninstantiatedDefaultArg()) {
return;
}
if (const Expr *Default = D->getDefaultArg()) {
if (const MaterializeTemporaryExpr *E =
dyn_cast<MaterializeTemporaryExpr>(Default)) {
// We have just found a ParmVarDecl which has, as its default argument,
// a MaterializeTemporaryExpr. We mark that MaterializeTemporaryExpr as
// automatic, by adding it to the AutomaticTemporaryMap.
// Reporting on this type will occur when the MaterializeTemporaryExpr
// is matched against.
AutomaticTemporaries[E] = D;
}
}
return;
}
// Determine the type of allocation which we detected
if (const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>("node")) {
if (D->hasGlobalStorage()) {
Variety = AV_Global;
} else {
Variety = AV_Automatic;
}
T = D->getType();
Loc = D->getLocStart();
} else if (const CXXNewExpr *E = Result.Nodes.getNodeAs<CXXNewExpr>("node")) {
// New allocates things on the heap.
// We don't consider placement new to do anything, as it doesn't actually
// allocate the storage, and thus gives us no useful information.
if (!isPlacementNew(E)) {
Variety = AV_Heap;
T = E->getAllocatedType();
Loc = E->getLocStart();
}
} else if (const MaterializeTemporaryExpr *E =
Result.Nodes.getNodeAs<MaterializeTemporaryExpr>("node")) {
// Temporaries can actually have varying storage durations, due to temporary
// lifetime extension. We consider the allocation variety of this temporary
// to be the same as the allocation variety of its lifetime.
// XXX We maybe should mark these lifetimes as being due to a temporary
// which has had its lifetime extended, to improve the error messages.
switch (E->getStorageDuration()) {
case SD_FullExpression: {
// Check if this temporary is allocated as a default argument!
// if it is, we want to pretend that it is automatic.
AutomaticTemporaryMap::iterator AutomaticTemporary =
AutomaticTemporaries.find(E);
if (AutomaticTemporary != AutomaticTemporaries.end()) {
Variety = AV_Automatic;
} else {
Variety = AV_Temporary;
}
} break;
case SD_Automatic:
Variety = AV_Automatic;
break;
case SD_Thread:
case SD_Static:
Variety = AV_Global;
break;
case SD_Dynamic:
assert(false && "I don't think that this ever should occur...");
Variety = AV_Heap;
break;
}
T = E->getType().getUnqualifiedType();
Loc = E->getLocStart();
} else if (const CallExpr *E = Result.Nodes.getNodeAs<CallExpr>("node")) {
T = E->getType()->getPointeeType();
if (!T.isNull()) {
// This will always allocate on the heap, as the heapAllocator() check
// was made in the matcher
Variety = AV_Heap;
Loc = E->getLocStart();
}
}
// Error messages for incorrect allocations.
const char* Stack =
"variable of type %0 only valid on the stack";
const char* Global =
"variable of type %0 only valid as global";
const char* Heap =
"variable of type %0 only valid on the heap";
const char* NonHeap =
"variable of type %0 is not valid on the heap";
const char* NonTemporary =
"variable of type %0 is not valid in a temporary";
//.........这里部分代码省略.........
示例10: getVarRegion
const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
const LocationContext *LC) {
const MemRegion *sReg = nullptr;
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) {
// FIXME: Assign a more sensible memory space to static locals
// we see from within blocks that we analyze as top-level declarations.
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,
getFunctionCodeRegion(cast<NamedDecl>(STCD)));
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
// FIXME: The fallback type here is totally bogus -- though it should
// never be queried, it will prevent uniquing with the real
// BlockCodeRegion. Ideally we'd fix the AST so that we always had a
// signature.
QualType T;
if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
T = TSI->getType();
if (T.isNull())
T = getContext().VoidTy;
if (!T->getAs<FunctionType>())
T = getContext().getFunctionNoProtoType(T);
T = getContext().getBlockPointerType(T);
const BlockCodeRegion *BTR =
getBlockCodeRegion(BD, C.getCanonicalType(T),
STC->getAnalysisDeclContext());
sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
BTR);
}
else {
sReg = getGlobalsRegion();
}
}
}
}
return getSubRegion<VarRegion>(D, sReg);
}
示例11: EmitVectorVariantsMetadata
// The following is common part for 'cilk vector functions' and
// 'omp declare simd' functions metadata generation.
//
void CodeGenModule::EmitVectorVariantsMetadata(const CGFunctionInfo &FnInfo,
const FunctionDecl *FD,
llvm::Function *Fn,
GroupMap &Groups) {
// Do not emit any vector variant if there is an unsupported feature.
bool HasImplicitThis = false;
if (!CheckElementalArguments(*this, FD, Fn, HasImplicitThis))
return;
llvm::LLVMContext &Context = getLLVMContext();
ASTContext &C = getContext();
// Common metadata nodes.
llvm::NamedMDNode *CilkElementalMetadata =
getModule().getOrInsertNamedMetadata("cilk.functions");
llvm::Metadata *ElementalMDArgs[] = {
llvm::MDString::get(Context, "elemental")
};
llvm::MDNode *ElementalNode = llvm::MDNode::get(Context, ElementalMDArgs);
llvm::Metadata *MaskMDArgs[] = {
llvm::MDString::get(Context, "mask"),
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::IntegerType::getInt1Ty(Context), 1))
};
llvm::MDNode *MaskNode = llvm::MDNode::get(Context, MaskMDArgs);
MaskMDArgs[1] = llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::IntegerType::getInt1Ty(Context), 0));
llvm::MDNode *NoMaskNode = llvm::MDNode::get(Context, MaskMDArgs);
SmallVector<llvm::Metadata*, 8> ParameterNameArgs;
ParameterNameArgs.push_back(llvm::MDString::get(Context, "arg_name"));
llvm::MDNode *ParameterNameNode = 0;
// // Vector variant metadata.
// llvm::Value *VariantMDArgs[] = {
// llvm::MDString::get(Context, "variant"),
// llvm::UndefValue::get(llvm::Type::getVoidTy(Context))
// };
// llvm::MDNode *VariantNode = llvm::MDNode::get(Context, VariantMDArgs);
for (GroupMap::iterator GI = Groups.begin(), GE = Groups.end();
GI != GE;
++GI) {
CilkElementalGroup &G = GI->second;
// Parameter information.
QualType FirstNonStepParmType;
SmallVector<llvm::Metadata *, 8> AligArgs;
SmallVector<llvm::Metadata *, 8> StepArgs;
AligArgs.push_back(llvm::MDString::get(Context, "arg_alig"));
StepArgs.push_back(llvm::MDString::get(Context, "arg_step"));
// Handle implicit 'this' parameter if necessary.
if (HasImplicitThis) {
ParameterNameArgs.push_back(llvm::MDString::get(Context, "this"));
bool IsNonStepParm = handleParameter(*this, G, "this",
StepArgs, AligArgs);
if (IsNonStepParm)
FirstNonStepParmType = cast<CXXMethodDecl>(FD)->getThisType(C);
}
// Handle explicit paramenters.
for (unsigned I = 0; I != FD->getNumParams(); ++I) {
const ParmVarDecl *Parm = FD->getParamDecl(I);
StringRef ParmName = Parm->getName();
if (!ParameterNameNode)
ParameterNameArgs.push_back(llvm::MDString::get(Context, ParmName));
bool IsNonStepParm = handleParameter(*this, G, ParmName,
StepArgs, AligArgs);
if (IsNonStepParm && FirstNonStepParmType.isNull())
FirstNonStepParmType = Parm->getType();
}
llvm::MDNode *StepNode = llvm::MDNode::get(Context, StepArgs);
llvm::MDNode *AligNode = llvm::MDNode::get(Context, AligArgs);
if (!ParameterNameNode)
ParameterNameNode = llvm::MDNode::get(Context, ParameterNameArgs);
// If there is no vectorlengthfor() in this group, determine the
// characteristic type. This can depend on the linear/uniform attributes,
// so it can differ between groups.
//
// The rules for computing the characteristic type are:
//
// a) For a non-void function, the characteristic data type is the
// return type.
//
// b) If the function has any non-uniform, non-linear parameters, the
// the characteristic data type is the type of the first such parameter.
//
// c) If the characteristic data type determined by a) or b) above is
// struct, union, or class type which is pass-by-value (except fo
// the type that maps to the built-in complex data type)
// the characteristic data type is int.
//
// d) If none of the above three cases is applicable,
// the characteristic data type is int.
//.........这里部分代码省略.........
示例12: processCallExit
/// The call exit is simulated with a sequence of nodes, which occur between
/// CallExitBegin and CallExitEnd. The following operations occur between the
/// two program points:
/// 1. CallExitBegin (triggers the start of call exit sequence)
/// 2. Bind the return value
/// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
/// 4. CallExitEnd (switch to the caller context)
/// 5. PostStmt<CallExpr>
void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
// Step 1 CEBNode was generated before the call.
const StackFrameContext *calleeCtx =
CEBNode->getLocationContext()->getCurrentStackFrame();
// The parent context might not be a stack frame, so make sure we
// look up the first enclosing stack frame.
const StackFrameContext *callerCtx =
calleeCtx->getParent()->getCurrentStackFrame();
const Stmt *CE = calleeCtx->getCallSite();
ProgramStateRef state = CEBNode->getState();
// Find the last statement in the function and the corresponding basic block.
const Stmt *LastSt = 0;
const CFGBlock *Blk = 0;
llvm::tie(LastSt, Blk) = getLastStmt(CEBNode);
// Generate a CallEvent /before/ cleaning the state, so that we can get the
// correct value for 'this' (if necessary).
CallEventManager &CEMgr = getStateManager().getCallEventManager();
CallEventRef<> Call = CEMgr.getCaller(calleeCtx, state);
// Step 2: generate node with bound return value: CEBNode -> BindedRetNode.
// If the callee returns an expression, bind its value to CallExpr.
if (CE) {
if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
const LocationContext *LCtx = CEBNode->getLocationContext();
SVal V = state->getSVal(RS, LCtx);
// Ensure that the return type matches the type of the returned Expr.
if (wasDifferentDeclUsedForInlining(Call, calleeCtx)) {
QualType ReturnedTy =
CallEvent::getDeclaredResultType(calleeCtx->getDecl());
if (!ReturnedTy.isNull()) {
if (const Expr *Ex = dyn_cast<Expr>(CE)) {
V = adjustReturnValue(V, Ex->getType(), ReturnedTy,
getStoreManager());
}
}
}
state = state->BindExpr(CE, callerCtx, V);
}
// Bind the constructed object value to CXXConstructExpr.
if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
loc::MemRegionVal This =
svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
SVal ThisV = state->getSVal(This);
// If the constructed object is a prvalue, get its bindings.
// Note that we have to be careful here because constructors embedded
// in DeclStmts are not marked as lvalues.
if (!CCE->isGLValue())
if (const MemRegion *MR = ThisV.getAsRegion())
if (isa<CXXTempObjectRegion>(MR))
ThisV = state->getSVal(cast<Loc>(ThisV));
state = state->BindExpr(CCE, callerCtx, ThisV);
}
}
// Step 3: BindedRetNode -> CleanedNodes
// If we can find a statement and a block in the inlined function, run remove
// dead bindings before returning from the call. This is important to ensure
// that we report the issues such as leaks in the stack contexts in which
// they occurred.
ExplodedNodeSet CleanedNodes;
if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
static SimpleProgramPointTag retValBind("ExprEngine : Bind Return Value");
PostStmt Loc(LastSt, calleeCtx, &retValBind);
bool isNew;
ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
BindedRetNode->addPredecessor(CEBNode, G);
if (!isNew)
return;
NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
currBldrCtx = &Ctx;
// Here, we call the Symbol Reaper with 0 statement and callee location
// context, telling it to clean up everything in the callee's context
// (and its children). We use the callee's function body as a diagnostic
// statement, with which the program point will be associated.
removeDead(BindedRetNode, CleanedNodes, 0, calleeCtx,
calleeCtx->getAnalysisDeclContext()->getBody(),
ProgramPoint::PostStmtPurgeDeadSymbolsKind);
currBldrCtx = 0;
} else {
CleanedNodes.Add(CEBNode);
}
//.........这里部分代码省略.........
示例13: findStyleKind
static StyleKind findStyleKind(
const NamedDecl *D,
const std::vector<llvm::Optional<IdentifierNamingCheck::NamingStyle>>
&NamingStyles) {
if (isa<TypedefDecl>(D) && NamingStyles[SK_Typedef])
return SK_Typedef;
if (isa<TypeAliasDecl>(D) && NamingStyles[SK_TypeAlias])
return SK_TypeAlias;
if (const auto *Decl = dyn_cast<NamespaceDecl>(D)) {
if (Decl->isAnonymousNamespace())
return SK_Invalid;
if (Decl->isInline() && NamingStyles[SK_InlineNamespace])
return SK_InlineNamespace;
if (NamingStyles[SK_Namespace])
return SK_Namespace;
}
if (isa<EnumDecl>(D) && NamingStyles[SK_Enum])
return SK_Enum;
if (isa<EnumConstantDecl>(D)) {
if (NamingStyles[SK_EnumConstant])
return SK_EnumConstant;
if (NamingStyles[SK_Constant])
return SK_Constant;
return SK_Invalid;
}
if (const auto *Decl = dyn_cast<CXXRecordDecl>(D)) {
if (Decl->isAnonymousStructOrUnion())
return SK_Invalid;
if (!Decl->getCanonicalDecl()->isThisDeclarationADefinition())
return SK_Invalid;
if (Decl->hasDefinition() && Decl->isAbstract() &&
NamingStyles[SK_AbstractClass])
return SK_AbstractClass;
if (Decl->isStruct() && NamingStyles[SK_Struct])
return SK_Struct;
if (Decl->isStruct() && NamingStyles[SK_Class])
return SK_Class;
if (Decl->isClass() && NamingStyles[SK_Class])
return SK_Class;
if (Decl->isClass() && NamingStyles[SK_Struct])
return SK_Struct;
if (Decl->isUnion() && NamingStyles[SK_Union])
return SK_Union;
if (Decl->isEnum() && NamingStyles[SK_Enum])
return SK_Enum;
return SK_Invalid;
}
if (const auto *Decl = dyn_cast<FieldDecl>(D)) {
QualType Type = Decl->getType();
if (!Type.isNull() && Type.isConstQualified()) {
if (NamingStyles[SK_ConstantMember])
return SK_ConstantMember;
if (NamingStyles[SK_Constant])
return SK_Constant;
}
if (Decl->getAccess() == AS_private && NamingStyles[SK_PrivateMember])
return SK_PrivateMember;
if (Decl->getAccess() == AS_protected && NamingStyles[SK_ProtectedMember])
return SK_ProtectedMember;
if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMember])
return SK_PublicMember;
if (NamingStyles[SK_Member])
return SK_Member;
return SK_Invalid;
}
if (const auto *Decl = dyn_cast<ParmVarDecl>(D)) {
QualType Type = Decl->getType();
if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable])
return SK_ConstexprVariable;
if (!Type.isNull() && Type.isConstQualified()) {
if (NamingStyles[SK_ConstantParameter])
//.........这里部分代码省略.........
示例14: DecodeTypeFromStr
/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
/// pointer over the consumed characters. This returns the resultant type.
static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
Builtin::Context::GetBuiltinTypeError &Error,
bool AllowTypeModifiers = true) {
// Modifiers.
int HowLong = 0;
bool Signed = false, Unsigned = false;
// Read the modifiers first.
bool Done = false;
while (!Done) {
switch (*Str++) {
default: Done = true; --Str; break;
case 'S':
assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
assert(!Signed && "Can't use 'S' modifier multiple times!");
Signed = true;
break;
case 'U':
assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
assert(!Unsigned && "Can't use 'S' modifier multiple times!");
Unsigned = true;
break;
case 'L':
assert(HowLong <= 2 && "Can't have LLLL modifier");
++HowLong;
break;
}
}
QualType Type;
// Read the base type.
switch (*Str++) {
default: assert(0 && "Unknown builtin type letter!");
case 'v':
assert(HowLong == 0 && !Signed && !Unsigned &&
"Bad modifiers used with 'v'!");
Type = Context.VoidTy;
break;
case 'f':
assert(HowLong == 0 && !Signed && !Unsigned &&
"Bad modifiers used with 'f'!");
Type = Context.FloatTy;
break;
case 'd':
assert(HowLong < 2 && !Signed && !Unsigned &&
"Bad modifiers used with 'd'!");
if (HowLong)
Type = Context.LongDoubleTy;
else
Type = Context.DoubleTy;
break;
case 's':
assert(HowLong == 0 && "Bad modifiers used with 's'!");
if (Unsigned)
Type = Context.UnsignedShortTy;
else
Type = Context.ShortTy;
break;
case 'i':
if (HowLong == 3)
Type = Unsigned ? Context.UnsignedInt128Ty : Context.Int128Ty;
else if (HowLong == 2)
Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
else if (HowLong == 1)
Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy;
else
Type = Unsigned ? Context.UnsignedIntTy : Context.IntTy;
break;
case 'c':
assert(HowLong == 0 && "Bad modifiers used with 'c'!");
if (Signed)
Type = Context.SignedCharTy;
else if (Unsigned)
Type = Context.UnsignedCharTy;
else
Type = Context.CharTy;
break;
case 'b': // boolean
assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!");
Type = Context.BoolTy;
break;
case 'z': // size_t.
assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!");
Type = Context.getSizeType();
break;
case 'F':
Type = Context.getCFConstantStringType();
break;
case 'a':
Type = Context.getBuiltinVaListType();
assert(!Type.isNull() && "builtin va list type not initialized!");
break;
case 'A':
// This is a "reference" to a va_list; however, what exactly
// this means depends on how va_list is defined. There are two
// different kinds of va_list: ones passed by value, and ones
// passed by reference. An example of a by-value va_list is
//.........这里部分代码省略.........
示例15: VisitDeclContext
void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
if (Policy.TerseOutput)
return;
if (Indent)
Indentation += Policy.Indentation;
SmallVector<Decl*, 2> Decls;
for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
D != DEnd; ++D) {
// Don't print ObjCIvarDecls, as they are printed when visiting the
// containing ObjCInterfaceDecl.
if (isa<ObjCIvarDecl>(*D))
continue;
// Skip over implicit declarations in pretty-printing mode.
if (D->isImplicit())
continue;
// The next bits of code handles stuff like "struct {int x;} a,b"; we're
// forced to merge the declarations because there's no other way to
// refer to the struct in question. This limited merging is safe without
// a bunch of other checks because it only merges declarations directly
// referring to the tag, not typedefs.
//
// Check whether the current declaration should be grouped with a previous
// unnamed struct.
QualType CurDeclType = getDeclType(*D);
if (!Decls.empty() && !CurDeclType.isNull()) {
QualType BaseType = GetBaseType(CurDeclType);
if (!BaseType.isNull() && isa<ElaboratedType>(BaseType))
BaseType = cast<ElaboratedType>(BaseType)->getNamedType();
if (!BaseType.isNull() && isa<TagType>(BaseType) &&
cast<TagType>(BaseType)->getDecl() == Decls[0]) {
Decls.push_back(*D);
continue;
}
}
// If we have a merged group waiting to be handled, handle it now.
if (!Decls.empty())
ProcessDeclGroup(Decls);
// If the current declaration is an unnamed tag type, save it
// so we can merge it with the subsequent declaration(s) using it.
if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) {
Decls.push_back(*D);
continue;
}
if (isa<AccessSpecDecl>(*D)) {
Indentation -= Policy.Indentation;
this->Indent();
Print(D->getAccess());
Out << ":\n";
Indentation += Policy.Indentation;
continue;
}
this->Indent();
Visit(*D);
// FIXME: Need to be able to tell the DeclPrinter when
const char *Terminator = nullptr;
if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D))
Terminator = nullptr;
else if (isa<FunctionDecl>(*D) &&
cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
Terminator = nullptr;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
Terminator = nullptr;
else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) ||
isa<ObjCImplementationDecl>(*D) ||
isa<ObjCInterfaceDecl>(*D) ||
isa<ObjCProtocolDecl>(*D) ||
isa<ObjCCategoryImplDecl>(*D) ||
isa<ObjCCategoryDecl>(*D))
Terminator = nullptr;
else if (isa<EnumConstantDecl>(*D)) {
DeclContext::decl_iterator Next = D;
++Next;
if (Next != DEnd)
Terminator = ",";
} else
Terminator = ";";
if (Terminator)
Out << Terminator;
Out << "\n";
// Declare target attribute is special one, natural spelling for the pragma
// assumes "ending" construct so print it here.
if (D->hasAttr<OMPDeclareTargetDeclAttr>())
Out << "#pragma omp end declare target\n";
}
if (!Decls.empty())
ProcessDeclGroup(Decls);
//.........这里部分代码省略.........