本文整理汇总了C++中QualType::isFunctionType方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::isFunctionType方法的具体用法?C++ QualType::isFunctionType怎么用?C++ QualType::isFunctionType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::isFunctionType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CheckAllocatedType
/// CheckAllocatedType - Checks that a type is suitable as the allocated type
/// in a new-expression.
/// dimension off and stores the size expression in ArraySize.
bool Sema::CheckAllocatedType(QualType AllocType, const Declarator &D)
{
// C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
// abstract class type or array thereof.
if (AllocType->isFunctionType())
return Diag(D.getSourceRange().getBegin(), diag::err_bad_new_type)
<< AllocType << 0 << D.getSourceRange();
else if (AllocType->isReferenceType())
return Diag(D.getSourceRange().getBegin(), diag::err_bad_new_type)
<< AllocType << 1 << D.getSourceRange();
else if (!AllocType->isDependentType() &&
RequireCompleteType(D.getSourceRange().getBegin(), AllocType,
diag::err_new_incomplete_type,
D.getSourceRange()))
return true;
else if (RequireNonAbstractType(D.getSourceRange().getBegin(), AllocType,
diag::err_allocation_of_abstract_type))
return true;
// Every dimension shall be of constant size.
unsigned i = 1;
while (const ArrayType *Array = Context.getAsArrayType(AllocType)) {
if (!Array->isConstantArrayType()) {
Diag(D.getTypeObject(i).Loc, diag::err_new_array_nonconst)
<< static_cast<Expr*>(D.getTypeObject(i).Arr.NumElts)->getSourceRange();
return true;
}
AllocType = Array->getElementType();
++i;
}
return false;
}
示例2: clang_Type_getSizeOf
long long clang_Type_getSizeOf(CXType T) {
if (T.kind == CXType_Invalid)
return CXTypeLayoutError_Invalid;
ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
QualType QT = GetQualType(T);
// [expr.sizeof] p2: if reference type, return size of referenced type
if (QT->isReferenceType())
QT = QT.getNonReferenceType();
// [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
// enumeration
// Note: We get the cxtype, not the cxcursor, so we can't call
// FieldDecl->isBitField()
// [expr.sizeof] p3: pointer ok, function not ok.
// [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
if (QT->isIncompleteType())
return CXTypeLayoutError_Incomplete;
if (QT->isDependentType())
return CXTypeLayoutError_Dependent;
if (!QT->isConstantSizeType())
return CXTypeLayoutError_NotConstantSize;
// [gcc extension] lib/AST/ExprConstant.cpp:1372
// HandleSizeof : {voidtype,functype} == 1
// not handled by ASTContext.cpp:1313 getTypeInfoImpl
if (QT->isVoidType() || QT->isFunctionType())
return 1;
return Ctx.getTypeSizeInChars(QT).getQuantity();
}
示例3: LookupInlineAsmIdentifier
ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) {
Info.clear();
if (IsUnevaluatedContext)
PushExpressionEvaluationContext(UnevaluatedAbstract,
ReuseLambdaContextDecl);
ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id,
/*trailing lparen*/ false,
/*is & operand*/ false,
/*CorrectionCandidateCallback=*/nullptr,
/*IsInlineAsmIdentifier=*/ true);
if (IsUnevaluatedContext)
PopExpressionEvaluationContext();
if (!Result.isUsable()) return Result;
Result = CheckPlaceholderExpr(Result.get());
if (!Result.isUsable()) return Result;
QualType T = Result.get()->getType();
// For now, reject dependent types.
if (T->isDependentType()) {
Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T;
return ExprError();
}
// Any sort of function type is fine.
if (T->isFunctionType()) {
return Result;
}
// Otherwise, it needs to be a complete type.
if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) {
return ExprError();
}
// Compute the type size (and array length if applicable?).
Info.Type = Info.Size = Context.getTypeSizeInChars(T).getQuantity();
if (T->isArrayType()) {
const ArrayType *ATy = Context.getAsArrayType(T);
Info.Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();
Info.Length = Info.Size / Info.Type;
}
// We can work with the expression as long as it's not an r-value.
if (!Result.get()->isRValue())
Info.IsVarDecl = true;
return Result;
}
示例4: LookupInlineAsmIdentifier
ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) {
Info.clear();
if (IsUnevaluatedContext)
PushExpressionEvaluationContext(UnevaluatedAbstract,
ReuseLambdaContextDecl);
ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id,
/*trailing lparen*/ false,
/*is & operand*/ false,
/*CorrectionCandidateCallback=*/nullptr,
/*IsInlineAsmIdentifier=*/ true);
if (IsUnevaluatedContext)
PopExpressionEvaluationContext();
if (!Result.isUsable()) return Result;
Result = CheckPlaceholderExpr(Result.get());
if (!Result.isUsable()) return Result;
// Referring to parameters is not allowed in naked functions.
if (CheckNakedParmReference(Result.get(), *this))
return ExprError();
QualType T = Result.get()->getType();
// For now, reject dependent types.
if (T->isDependentType()) {
Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T;
return ExprError();
}
// Any sort of function type is fine.
if (T->isFunctionType()) {
return Result;
}
// Otherwise, it needs to be a complete type.
if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) {
return ExprError();
}
fillInlineAsmTypeInfo(Context, T, Info);
// We can work with the expression as long as it's not an r-value.
if (!Result.get()->isRValue())
Info.IsVarDecl = true;
return Result;
}
示例5: ExprError
/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
/// C++ if/switch/while/for statement.
/// e.g: "if (int x = f()) {...}"
Action::OwningExprResult
Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
Declarator &D,
SourceLocation EqualLoc,
ExprArg AssignExprVal) {
assert(AssignExprVal.get() && "Null assignment expression");
// C++ 6.4p2:
// The declarator shall not specify a function or an array.
// The type-specifier-seq shall not contain typedef and shall not declare a
// new class or enumeration.
assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
"Parser allowed 'typedef' as storage class of condition decl.");
QualType Ty = GetTypeForDeclarator(D, S);
if (Ty->isFunctionType()) { // The declarator shall not specify a function...
// We exit without creating a CXXConditionDeclExpr because a FunctionDecl
// would be created and CXXConditionDeclExpr wants a VarDecl.
return ExprError(Diag(StartLoc, diag::err_invalid_use_of_function_type)
<< SourceRange(StartLoc, EqualLoc));
} else if (Ty->isArrayType()) { // ...or an array.
Diag(StartLoc, diag::err_invalid_use_of_array_type)
<< SourceRange(StartLoc, EqualLoc);
} else if (const RecordType *RT = Ty->getAsRecordType()) {
RecordDecl *RD = RT->getDecl();
// The type-specifier-seq shall not declare a new class...
if (RD->isDefinition() &&
(RD->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(RD))))
Diag(RD->getLocation(), diag::err_type_defined_in_condition);
} else if (const EnumType *ET = Ty->getAsEnumType()) {
EnumDecl *ED = ET->getDecl();
// ...or enumeration.
if (ED->isDefinition() &&
(ED->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(ED))))
Diag(ED->getLocation(), diag::err_type_defined_in_condition);
}
DeclPtrTy Dcl = ActOnDeclarator(S, D, DeclPtrTy());
if (!Dcl)
return ExprError();
AddInitializerToDecl(Dcl, move(AssignExprVal));
// Mark this variable as one that is declared within a conditional.
// We know that the decl had to be a VarDecl because that is the only type of
// decl that can be assigned and the grammar requires an '='.
VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>());
VD->setDeclaredInCondition(true);
return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc, VD));
}
示例6: mangleType
// <type> ::= <pointer-type>
// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
void MicrosoftCXXNameMangler::mangleType(const PointerType *T) {
QualType PointeeTy = T->getPointeeType();
if (PointeeTy->isArrayType()) {
// Pointers to arrays are mangled like arrays.
mangleExtraDimensions(T->getPointeeType());
} else if (PointeeTy->isFunctionType()) {
// Function pointers are special.
Out << '6';
mangleType(static_cast<const FunctionType *>(PointeeTy.getTypePtr()),
NULL, false, false);
} else {
if (!PointeeTy.hasQualifiers())
// Lack of qualifiers is mangled as 'A'.
Out << 'A';
mangleType(PointeeTy);
}
}
示例7: SynthesizeVP
// We need to artificially create:
// cling_PrintValue(void* (ASTContext)C, void* (Expr)E, const void* (&i)
Expr* ValuePrinterSynthesizer::SynthesizeVP(Expr* E) {
QualType QT = E->getType();
// For now we skip void and function pointer types.
if (!QT.isNull() && (QT->isVoidType() || QT->isFunctionType()))
return 0;
// Find cling_PrintValue
SourceLocation NoSLoc = SourceLocation();
DeclarationName PVName = &m_Context->Idents.get("cling_PrintValue");
LookupResult R(*m_Sema, PVName, NoSLoc, Sema::LookupOrdinaryName,
Sema::ForRedeclaration);
Scope* S = m_Sema->getScopeForContext(m_Sema->CurContext);
m_Sema->LookupName(R, S);
assert(!R.empty() && "Cannot find cling_PrintValue(...)");
CXXScopeSpec CSS;
Expr* UnresolvedLookup
= m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).take();
Expr* VoidEArg = utils::Synthesize::CStyleCastPtrExpr(m_Sema,
m_Context->VoidPtrTy,
(uint64_t)E);
Expr* VoidCArg = utils::Synthesize::CStyleCastPtrExpr(m_Sema,
m_Context->VoidPtrTy,
(uint64_t)m_Context);
if (!QT->isPointerType()) {
while(ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(E))
E = ICE->getSubExpr();
E = m_Sema->BuildUnaryOp(S, NoSLoc, UO_AddrOf, E).take();
}
llvm::SmallVector<Expr*, 4> CallArgs;
CallArgs.push_back(VoidEArg);
CallArgs.push_back(VoidCArg);
CallArgs.push_back(E);
Expr* Result = m_Sema->ActOnCallExpr(S, UnresolvedLookup, NoSLoc,
CallArgs, NoSLoc).take();
assert(Result && "Cannot create value printer!");
return Result;
}
示例8: SynthesizeVP
// We need to artificially create:
// cling_PrintValue(void* (ASTContext)C, void* (Expr)E, const void* (&i)
Expr* ValuePrinterSynthesizer::SynthesizeVP(Expr* E) {
QualType QT = E->getType();
// For now we skip void and function pointer types.
if (!QT.isNull() && (QT->isVoidType() || QT->isFunctionType()))
return 0;
// Find cling_PrintValue
if (!m_LookupResult)
FindAndCacheRuntimeLookupResult(E->getLocStart());
Expr* VoidEArg = utils::Synthesize::CStyleCastPtrExpr(m_Sema,
m_Context->VoidPtrTy,
(uint64_t)E);
Expr* VoidCArg = utils::Synthesize::CStyleCastPtrExpr(m_Sema,
m_Context->VoidPtrTy,
(uint64_t)m_Context);
SourceLocation NoSLoc = SourceLocation();
Scope* S = m_Sema->getScopeForContext(m_Sema->CurContext);
if (!QT->isPointerType()) {
while(ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(E))
E = ICE->getSubExpr();
E = m_Sema->BuildUnaryOp(S, NoSLoc, UO_AddrOf, E).get();
}
llvm::SmallVector<Expr*, 4> CallArgs;
CallArgs.push_back(VoidEArg);
CallArgs.push_back(VoidCArg);
CallArgs.push_back(E);
CXXScopeSpec CSS;
Expr* unresolvedLookup
= m_Sema->BuildDeclarationNameExpr(CSS, *m_LookupResult,
/*ADL*/ false).get();
Expr* Result = m_Sema->ActOnCallExpr(S, unresolvedLookup, E->getLocStart(),
CallArgs, E->getLocEnd()).get();
assert(Result && "Cannot create value printer!");
return Result;
}
示例9: 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:
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!");
}
示例10: evalCast
//.........这里部分代码省略.........
if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
Context.getPointerType(originalTy)))
return val;
// Check for casts from pointers to integers.
if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
return evalCastFromLoc(val.castAs<Loc>(), castTy);
// Check for casts from integers to pointers.
if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) {
if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) {
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
StoreManager &storeMgr = StateMgr.getStoreManager();
R = storeMgr.castRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
}
return LV->getLoc();
}
return dispatchCast(val, castTy);
}
// Just pass through function and block pointers.
if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
assert(Loc::isLocType(castTy));
return val;
}
// Check for casts from array type to another type.
if (const ArrayType *arrayT =
dyn_cast<ArrayType>(originalTy.getCanonicalType())) {
// We will always decay to a pointer.
QualType elemTy = arrayT->getElementType();
val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy);
// Are we casting from an array to a pointer? If so just pass on
// the decayed value.
if (castTy->isPointerType() || castTy->isReferenceType())
return val;
// Are we casting from an array to an integer? If so, cast the decayed
// pointer value to an integer.
assert(castTy->isIntegralOrEnumerationType());
// FIXME: Keep these here for now in case we decide soon that we
// need the original decayed type.
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
// QualType pointerTy = C.getPointerType(elemTy);
return evalCastFromLoc(val.castAs<Loc>(), castTy);
}
// Check for casts from a region to a specific type.
if (const MemRegion *R = val.getAsRegion()) {
// Handle other casts of locations to integers.
if (castTy->isIntegralOrEnumerationType())
return evalCastFromLoc(loc::MemRegionVal(R), castTy);
// FIXME: We should handle the case where we strip off view layers to get
// to a desugared type.
if (!Loc::isLocType(castTy)) {
// FIXME: There can be gross cases where one casts the result of a function
// (that returns a pointer) to some other value that happens to fit
// within that pointer value. We currently have no good way to
// model such operations. When this happens, the underlying operation
// is that the caller is reasoning about bits. Conceptually we are
// layering a "view" of a location on top of those bits. Perhaps
// we need to be more lazy about mutual possible views, even on an
// SVal? This may be necessary for bit-level reasoning as well.
return UnknownVal();
}
// We get a symbolic function pointer for a dereference of a function
// pointer, but it is of function type. Example:
// struct FPRec {
// void (*my_func)(int * x);
// };
//
// int bar(int x);
//
// int f1_a(struct FPRec* foo) {
// int x;
// (*foo->my_func)(&x);
// return bar(x)+1; // no-warning
// }
assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
originalTy->isBlockPointerType() || castTy->isReferenceType());
StoreManager &storeMgr = StateMgr.getStoreManager();
// Delegate to store manager to get the result of casting a region to a
// different type. If the MemRegion* returned is NULL, this expression
// Evaluates to UnknownVal.
R = storeMgr.castRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
}
return dispatchCast(val, castTy);
}
示例11: printAttributedAfter
void TypePrinter::printAttributedAfter(const AttributedType *T,
raw_ostream &OS) {
// Prefer the macro forms of the GC and ownership qualifiers.
if (T->getAttrKind() == AttributedType::attr_objc_gc ||
T->getAttrKind() == AttributedType::attr_objc_ownership)
return printAfter(T->getEquivalentType(), OS);
// TODO: not all attributes are GCC-style attributes.
OS << " __attribute__((";
switch (T->getAttrKind()) {
case AttributedType::attr_address_space:
OS << "address_space(";
OS << T->getEquivalentType().getAddressSpace();
OS << ')';
break;
case AttributedType::attr_vector_size: {
OS << "__vector_size__(";
if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
OS << vector->getNumElements();
OS << " * sizeof(";
print(vector->getElementType(), OS, StringRef());
OS << ')';
}
OS << ')';
break;
}
case AttributedType::attr_neon_vector_type:
case AttributedType::attr_neon_polyvector_type: {
if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
OS << "neon_vector_type(";
else
OS << "neon_polyvector_type(";
const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
OS << vector->getNumElements();
OS << ')';
break;
}
case AttributedType::attr_regparm: {
OS << "regparm(";
QualType t = T->getEquivalentType();
while (!t->isFunctionType())
t = t->getPointeeType();
OS << t->getAs<FunctionType>()->getRegParmType();
OS << ')';
break;
}
case AttributedType::attr_objc_gc: {
OS << "objc_gc(";
QualType tmp = T->getEquivalentType();
while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
QualType next = tmp->getPointeeType();
if (next == tmp) break;
tmp = next;
}
if (tmp.isObjCGCWeak())
OS << "weak";
else
OS << "strong";
OS << ')';
break;
}
case AttributedType::attr_objc_ownership:
OS << "objc_ownership(";
switch (T->getEquivalentType().getObjCLifetime()) {
case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
case Qualifiers::OCL_ExplicitNone: OS << "none"; break;
case Qualifiers::OCL_Strong: OS << "strong"; break;
case Qualifiers::OCL_Weak: OS << "weak"; break;
case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break;
}
OS << ')';
break;
case AttributedType::attr_noreturn: OS << "noreturn"; break;
case AttributedType::attr_cdecl: OS << "cdecl"; break;
case AttributedType::attr_fastcall: OS << "fastcall"; break;
case AttributedType::attr_stdcall: OS << "stdcall"; break;
case AttributedType::attr_thiscall: OS << "thiscall"; break;
case AttributedType::attr_pascal: OS << "pascal"; break;
case AttributedType::attr_pcs: {
OS << "pcs(";
QualType t = T->getEquivalentType();
while (!t->isFunctionType())
t = t->getPointeeType();
OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
"\"aapcs\"" : "\"aapcs-vfp\"");
OS << ')';
break;
}
case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break;
case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;
}
OS << "))";
//.........这里部分代码省略.........
示例12: evalCast
// FIXME: should rewrite according to the cast kind.
SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
castTy = Context.getCanonicalType(castTy);
originalTy = Context.getCanonicalType(originalTy);
if (val.isUnknownOrUndef() || castTy == originalTy)
return val;
// For const casts, just propagate the value.
if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
if (haveSimilarTypes(Context, Context.getPointerType(castTy),
Context.getPointerType(originalTy)))
return val;
// Check for casts from pointers to integers.
if (castTy->isIntegerType() && Loc::isLocType(originalTy))
return evalCastFromLoc(cast<Loc>(val), castTy);
// Check for casts from integers to pointers.
if (Loc::isLocType(castTy) && originalTy->isIntegerType()) {
if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
StoreManager &storeMgr = StateMgr.getStoreManager();
R = storeMgr.castRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
}
return LV->getLoc();
}
return dispatchCast(val, castTy);
}
// Just pass through function and block pointers.
if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
assert(Loc::isLocType(castTy));
return val;
}
// Check for casts from array type to another type.
if (originalTy->isArrayType()) {
// We will always decay to a pointer.
val = StateMgr.ArrayToPointer(cast<Loc>(val));
// Are we casting from an array to a pointer? If so just pass on
// the decayed value.
if (castTy->isPointerType())
return val;
// Are we casting from an array to an integer? If so, cast the decayed
// pointer value to an integer.
assert(castTy->isIntegerType());
// FIXME: Keep these here for now in case we decide soon that we
// need the original decayed type.
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
// QualType pointerTy = C.getPointerType(elemTy);
return evalCastFromLoc(cast<Loc>(val), castTy);
}
// Check for casts from a region to a specific type.
if (const MemRegion *R = val.getAsRegion()) {
// Handle other casts of locations to integers.
if (castTy->isIntegerType())
return evalCastFromLoc(loc::MemRegionVal(R), castTy);
// FIXME: We should handle the case where we strip off view layers to get
// to a desugared type.
if (!Loc::isLocType(castTy)) {
// FIXME: There can be gross cases where one casts the result of a function
// (that returns a pointer) to some other value that happens to fit
// within that pointer value. We currently have no good way to
// model such operations. When this happens, the underlying operation
// is that the caller is reasoning about bits. Conceptually we are
// layering a "view" of a location on top of those bits. Perhaps
// we need to be more lazy about mutual possible views, even on an
// SVal? This may be necessary for bit-level reasoning as well.
return UnknownVal();
}
// We get a symbolic function pointer for a dereference of a function
// pointer, but it is of function type. Example:
// struct FPRec {
// void (*my_func)(int * x);
// };
//
// int bar(int x);
//
// int f1_a(struct FPRec* foo) {
// int x;
// (*foo->my_func)(&x);
// return bar(x)+1; // no-warning
// }
assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
originalTy->isBlockPointerType() || castTy->isReferenceType());
StoreManager &storeMgr = StateMgr.getStoreManager();
// Delegate to store manager to get the result of casting a region to a
// different type. If the MemRegion* returned is NULL, this expression
// Evaluates to UnknownVal.
//.........这里部分代码省略.........
示例13: Transform
void ValueExtractionSynthesizer::Transform() {
const CompilationOptions& CO = getTransaction()->getCompilationOpts();
// If we do not evaluate the result, or printing out the result return.
if (!(CO.ResultEvaluation || CO.ValuePrinting))
return;
FunctionDecl* FD = getTransaction()->getWrapperFD();
int foundAtPos = -1;
Expr* lastExpr = utils::Analyze::GetOrCreateLastExpr(FD, &foundAtPos,
/*omitDS*/false,
m_Sema);
if (foundAtPos < 0)
return;
typedef llvm::SmallVector<Stmt**, 4> StmtIters;
StmtIters returnStmts;
ReturnStmtCollector collector(returnStmts);
CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
collector.VisitStmt(CS);
if (isa<Expr>(*(CS->body_begin() + foundAtPos)))
returnStmts.push_back(CS->body_begin() + foundAtPos);
// We want to support cases such as:
// gCling->evaluate("if() return 'A' else return 12", V), that puts in V,
// either A or 12.
// In this case the void wrapper is compiled with the stmts returning
// values. Sema would cast them to void, but the code will still be
// executed. For example:
// int g(); void f () { return g(); } will still call g().
//
for (StmtIters::iterator I = returnStmts.begin(), E = returnStmts.end();
I != E; ++I) {
ReturnStmt* RS = dyn_cast<ReturnStmt>(**I);
if (RS) {
// When we are handling a return stmt, the last expression must be the
// return stmt value. Ignore the calculation of the lastStmt because it
// might be wrong, in cases where the return is not in the end of the
// function.
lastExpr = RS->getRetValue();
if (lastExpr) {
assert (lastExpr->getType()->isVoidType() && "Must be void type.");
// Any return statement will have been "healed" by Sema
// to correspond to the original void return type of the
// wrapper, using a ImplicitCastExpr 'void' <ToVoid>.
// Remove that.
if (ImplicitCastExpr* VoidCast
= dyn_cast<ImplicitCastExpr>(lastExpr)) {
lastExpr = VoidCast->getSubExpr();
}
}
// if no value assume void
else {
// We can't PushDeclContext, because we don't have scope.
Sema::ContextRAII pushedDC(*m_Sema, FD);
RS->setRetValue(SynthesizeSVRInit(0));
}
}
else
lastExpr = cast<Expr>(**I);
if (lastExpr) {
QualType lastExprTy = lastExpr->getType();
// May happen on auto types which resolve to dependent.
if (lastExprTy->isDependentType())
continue;
// Set up lastExpr properly.
// Change the void function's return type
// We can't PushDeclContext, because we don't have scope.
Sema::ContextRAII pushedDC(*m_Sema, FD);
if (lastExprTy->isFunctionType()) {
// A return type of function needs to be converted to
// pointer to function.
lastExprTy = m_Context->getPointerType(lastExprTy);
lastExpr = m_Sema->ImpCastExprToType(lastExpr, lastExprTy,
CK_FunctionToPointerDecay,
VK_RValue).take();
}
//
// Here we don't want to depend on the JIT runFunction, because of its
// limitations, when it comes to return value handling. There it is
// not clear who provides the storage and who cleans it up in a
// platform independent way.
//
// Depending on the type we need to synthesize a call to cling:
// 0) void : set the value's type to void;
// 1) enum, integral, float, double, referece, pointer types :
// call to cling::internal::setValueNoAlloc(...);
// 2) object type (alloc on the stack) :
// cling::internal::setValueWithAlloc
// 2.1) constant arrays:
// call to cling::runtime::internal::copyArray(...)
//
// We need to synthesize later:
// Wrapper has signature: void w(cling::Value SVR)
// case 1):
//.........这里部分代码省略.........
示例14: printAttributed
void TypePrinter::printAttributed(const AttributedType *T,
std::string &S) {
// Prefer the macro forms of the GC and ownership qualifiers.
if (T->getAttrKind() == AttributedType::attr_objc_gc ||
T->getAttrKind() == AttributedType::attr_objc_ownership)
return print(T->getEquivalentType(), S);
print(T->getModifiedType(), S);
// TODO: not all attributes are GCC-style attributes.
S += " __attribute__((";
switch (T->getAttrKind()) {
case AttributedType::attr_address_space:
S += "address_space(";
S += T->getEquivalentType().getAddressSpace();
S += ")";
break;
case AttributedType::attr_vector_size: {
S += "__vector_size__(";
if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
S += vector->getNumElements();
S += " * sizeof(";
std::string tmp;
print(vector->getElementType(), tmp);
S += tmp;
S += ")";
}
S += ")";
break;
}
case AttributedType::attr_neon_vector_type:
case AttributedType::attr_neon_polyvector_type: {
if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
S += "neon_vector_type(";
else
S += "neon_polyvector_type(";
const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
S += llvm::utostr_32(vector->getNumElements());
S += ")";
break;
}
case AttributedType::attr_regparm: {
S += "regparm(";
QualType t = T->getEquivalentType();
while (!t->isFunctionType())
t = t->getPointeeType();
S += t->getAs<FunctionType>()->getRegParmType();
S += ")";
break;
}
case AttributedType::attr_objc_gc: {
S += "objc_gc(";
QualType tmp = T->getEquivalentType();
while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
QualType next = tmp->getPointeeType();
if (next == tmp) break;
tmp = next;
}
if (tmp.isObjCGCWeak())
S += "weak";
else
S += "strong";
S += ")";
break;
}
case AttributedType::attr_objc_ownership:
S += "objc_ownership(";
switch (T->getEquivalentType().getObjCLifetime()) {
case Qualifiers::OCL_None: llvm_unreachable("no ownership!"); break;
case Qualifiers::OCL_ExplicitNone: S += "none"; break;
case Qualifiers::OCL_Strong: S += "strong"; break;
case Qualifiers::OCL_Weak: S += "weak"; break;
case Qualifiers::OCL_Autoreleasing: S += "autoreleasing"; break;
}
S += ")";
break;
case AttributedType::attr_noreturn: S += "noreturn"; break;
case AttributedType::attr_cdecl: S += "cdecl"; break;
case AttributedType::attr_fastcall: S += "fastcall"; break;
case AttributedType::attr_stdcall: S += "stdcall"; break;
case AttributedType::attr_thiscall: S += "thiscall"; break;
case AttributedType::attr_pascal: S += "pascal"; break;
case AttributedType::attr_pcs: {
S += "pcs(";
QualType t = T->getEquivalentType();
while (!t->isFunctionType())
t = t->getPointeeType();
S += (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
"\"aapcs\"" : "\"aapcs-vfp\"");
S += ")";
break;
//.........这里部分代码省略.........
示例15: getTypeForFormat
//.........这里部分代码省略.........
return llvm::VectorType::get(ConvertTypeRecursive(VT.getElementType()),
VT.getNumElements());
}
case Type::FunctionNoProto:
case Type::FunctionProto: {
// First, check whether we can build the full function type.
if (const TagType* TT = VerifyFuncTypeComplete(&Ty)) {
// This function's type depends on an incomplete tag type; make sure
// we have an opaque type corresponding to the tag type.
ConvertTagDeclType(TT->getDecl());
// Create an opaque type for this function type, save it, and return it.
llvm::Type *ResultType = llvm::OpaqueType::get(getLLVMContext());
FunctionTypes.insert(std::make_pair(&Ty, ResultType));
return ResultType;
}
// The function type can be built; call the appropriate routines to
// build it.
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(&Ty))
return GetFunctionType(getFunctionInfo(FPT), FPT->isVariadic());
const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(&Ty);
return GetFunctionType(getFunctionInfo(FNPT), true);
}
case Type::ObjCInterface: {
// Objective-C interfaces are always opaque (outside of the
// runtime, which can do whatever it likes); we never refine
// these.
const llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(&Ty)];
if (!T)
T = llvm::OpaqueType::get(getLLVMContext());
return T;
}
case Type::ObjCObjectPointer: {
// Protocol qualifications do not influence the LLVM type, we just return a
// pointer to the underlying interface type. We don't need to worry about
// recursive conversion.
const llvm::Type *T =
ConvertTypeRecursive(cast<ObjCObjectPointerType>(Ty).getPointeeType());
return llvm::PointerType::getUnqual(T);
}
case Type::Record:
case Type::Enum: {
const TagDecl *TD = cast<TagType>(Ty).getDecl();
const llvm::Type *Res = ConvertTagDeclType(TD);
std::string TypeName(TD->getKindName());
TypeName += '.';
// Name the codegen type after the typedef name
// if there is no tag type name available
if (TD->getIdentifier())
// FIXME: We should not have to check for a null decl context here.
// Right now we do it because the implicit Obj-C decls don't have one.
TypeName += TD->getDeclContext() ? TD->getQualifiedNameAsString() :
TD->getNameAsString();
else if (const TypedefType *TdT = dyn_cast<TypedefType>(T))
// FIXME: We should not have to check for a null decl context here.
// Right now we do it because the implicit Obj-C decls don't have one.
TypeName += TdT->getDecl()->getDeclContext() ?
TdT->getDecl()->getQualifiedNameAsString() :
TdT->getDecl()->getNameAsString();
else
TypeName += "anon";
TheModule.addTypeName(TypeName, Res);
return Res;
}
case Type::BlockPointer: {
const QualType FTy = cast<BlockPointerType>(Ty).getPointeeType();
llvm::OpaqueType *PointeeType = llvm::OpaqueType::get(getLLVMContext());
PointersToResolve.push_back(std::make_pair(FTy, PointeeType));
return llvm::PointerType::get(PointeeType, FTy.getAddressSpace());
}
case Type::MemberPointer: {
// FIXME: This is ABI dependent. We use the Itanium C++ ABI.
// http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
// If we ever want to support other ABIs this needs to be abstracted.
QualType ETy = cast<MemberPointerType>(Ty).getPointeeType();
const llvm::Type *PtrDiffTy =
ConvertTypeRecursive(Context.getPointerDiffType());
if (ETy->isFunctionType()) {
return llvm::StructType::get(TheModule.getContext(), PtrDiffTy, PtrDiffTy,
NULL);
} else
return PtrDiffTy;
}
case Type::TemplateSpecialization:
assert(false && "Dependent types can't get here");
}
// FIXME: implement.
return llvm::OpaqueType::get(getLLVMContext());
}