本文整理汇总了C++中QualType::getPointeeType方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::getPointeeType方法的具体用法?C++ QualType::getPointeeType怎么用?C++ QualType::getPointeeType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::getPointeeType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: new
// access 2D memory array at given index
Expr *ASTTranslate::accessMem2DAt(DeclRefExpr *LHS, Expr *idx_x, Expr *idx_y) {
QualType QT = LHS->getType();
QualType QT2 = QT->getPointeeType()->getAsArrayTypeUnsafe()->getElementType();
// mark image as being used within the kernel
Kernel->setUsed(LHS->getNameInfo().getAsString());
Expr *result = new (Ctx) ArraySubscriptExpr(createImplicitCastExpr(Ctx, QT,
CK_LValueToRValue, LHS, nullptr, VK_RValue), idx_y,
QT->getPointeeType(), VK_LValue, OK_Ordinary, SourceLocation());
result = new (Ctx) ArraySubscriptExpr(createImplicitCastExpr(Ctx,
Ctx.getPointerType(QT2), CK_ArrayToPointerDecay, result, nullptr,
VK_RValue), idx_x, QT2, VK_LValue, OK_Ordinary, SourceLocation());
return result;
}
示例2: evalDynamicCast
SVal StoreManager::evalDynamicCast(SVal Base, QualType DerivedType,
bool &Failed) {
Failed = false;
loc::MemRegionVal *BaseRegVal = dyn_cast<loc::MemRegionVal>(&Base);
if (!BaseRegVal)
return UnknownVal();
const MemRegion *BaseRegion = BaseRegVal->stripCasts(/*StripBases=*/false);
// Assume the derived class is a pointer or a reference to a CXX record.
DerivedType = DerivedType->getPointeeType();
assert(!DerivedType.isNull());
const CXXRecordDecl *DerivedDecl = DerivedType->getAsCXXRecordDecl();
if (!DerivedDecl && !DerivedType->isVoidType())
return UnknownVal();
// Drill down the CXXBaseObject chains, which represent upcasts (casts from
// derived to base).
const MemRegion *SR = BaseRegion;
while (const TypedRegion *TSR = dyn_cast_or_null<TypedRegion>(SR)) {
QualType BaseType = TSR->getLocationType()->getPointeeType();
assert(!BaseType.isNull());
const CXXRecordDecl *SRDecl = BaseType->getAsCXXRecordDecl();
if (!SRDecl)
return UnknownVal();
// If found the derived class, the cast succeeds.
if (SRDecl == DerivedDecl)
return loc::MemRegionVal(TSR);
if (!DerivedType->isVoidType()) {
// Static upcasts are marked as DerivedToBase casts by Sema, so this will
// only happen when multiple or virtual inheritance is involved.
CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (SRDecl->isDerivedFrom(DerivedDecl, Paths))
return evalDerivedToBase(loc::MemRegionVal(TSR), Paths.front());
}
if (const CXXBaseObjectRegion *R = dyn_cast<CXXBaseObjectRegion>(TSR))
// Drill down the chain to get the derived classes.
SR = R->getSuperRegion();
else {
// We reached the bottom of the hierarchy.
// If this is a cast to void*, return the region.
if (DerivedType->isVoidType())
return loc::MemRegionVal(TSR);
// We did not find the derived class. We we must be casting the base to
// derived, so the cast should fail.
Failed = true;
return UnknownVal();
}
}
return UnknownVal();
}
示例3: isPointerToConst
/// \brief Returns true if a type is a pointer-to-const or reference-to-const
/// with no further indirection.
static bool isPointerToConst(QualType Ty) {
QualType PointeeTy = Ty->getPointeeType();
if (PointeeTy == QualType())
return false;
if (!PointeeTy.isConstQualified())
return false;
if (PointeeTy->isAnyPointerType())
return false;
return true;
}
示例4: 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 NonTemplateOverloads - 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 &NonTemplateOverloads) {
ZeroArgCallReturnTy = QualType();
NonTemplateOverloads.clear();
if (const OverloadExpr *Overloads = dyn_cast<OverloadExpr>(&E)) {
for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
// Our overload set may include TemplateDecls, which we'll ignore for our
// present purpose.
if (const FunctionDecl *OverloadDecl = dyn_cast<FunctionDecl>(*it)) {
NonTemplateOverloads.addDecl(*it);
if (OverloadDecl->getMinRequiredArguments() == 0)
ZeroArgCallReturnTy = OverloadDecl->getResultType();
}
}
return true;
}
if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(&E)) {
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;
}
示例5: assert
PathDiagnosticPiece *
UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) {
ProgramStateRef State = N->getState();
ProgramPoint ProgLoc = N->getLocation();
// We are only interested in visiting CallEnter nodes.
Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
if (!CEnter)
return 0;
// Check if one of the arguments is the region the visitor is tracking.
CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
unsigned Idx = 0;
for (CallEvent::param_iterator I = Call->param_begin(),
E = Call->param_end(); I != E; ++I, ++Idx) {
const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
// Are we tracking the argument or its subregion?
if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
continue;
// Check the function parameter type.
const ParmVarDecl *ParamDecl = *I;
assert(ParamDecl && "Formal parameter has no decl?");
QualType T = ParamDecl->getType();
if (!(T->isAnyPointerType() || T->isReferenceType())) {
// Function can only change the value passed in by address.
continue;
}
// If it is a const pointer value, the function does not intend to
// change the value.
if (T->getPointeeType().isConstQualified())
continue;
// Mark the call site (LocationContext) as interesting if the value of the
// argument is undefined or '0'/'NULL'.
SVal BoundVal = State->getSVal(R);
if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
BR.markInteresting(CEnter->getCalleeContext());
return 0;
}
}
return 0;
}
示例6: IsFieldPointer
// Check if type is a "Field() *" pointer type, or alternatively a pointer to
// any type in "alt" if provided.
bool CheckAllocationsInFunctionVisitor::IsFieldPointer(
const QualType& qtype, const char* alt)
{
if (qtype->isPointerType())
{
auto name = qtype->getPointeeType()
.getDesugaredType(_mainVisitor->getContext()).getAsString();
return StartsWith(name, "class Memory::WriteBarrierPtr<")
|| StartsWith(name, "typename WriteBarrierFieldTypeTraits<")
|| (alt && strstr(alt, name.c_str()));
}
return false;
}
示例7: checkASTDecl
void edmChecker::checkASTDecl(const clang::CXXRecordDecl *RD, clang::ento::AnalysisManager& mgr,
clang::ento::BugReporter &BR) const {
const clang::SourceManager &SM = BR.getSourceManager();
clang::ento::PathDiagnosticLocation DLoc =clang::ento::PathDiagnosticLocation::createBegin( RD, SM );
if ( !m_exception.reportClass( DLoc, BR ) ) return;
// Check the class methods (member methods).
for (clang::CXXRecordDecl::method_iterator
I = RD->method_begin(), E = RD->method_end(); I != E; ++I)
{
if ( !llvm::isa<clang::CXXMethodDecl>((*I)) ) continue;
clang::CXXMethodDecl * MD = llvm::cast<clang::CXXMethodDecl>((*I));
if ( MD->getNameAsString() == "beginRun"
|| MD->getNameAsString() == "endRun"
|| MD->getNameAsString() == "beginLuminosityBlock"
|| MD->getNameAsString() == "endLuminosityBlock" )
{
// llvm::errs()<<MD->getQualifiedNameAsString()<<"\n";
for (auto J=RD->bases_begin(), F=RD->bases_end();J != F; ++J)
{
std::string name = J->getType()->castAs<RecordType>()->getDecl()->getQualifiedNameAsString();
// llvm::errs()<<RD->getQualifiedNameAsString()<<"\n";
// llvm::errs() << "inherits from " <<name<<"\n";
if (name=="edm::EDProducer" || name=="edm::EDFilter")
{
llvm::SmallString<100> buf;
llvm::raw_svector_ostream os(buf);
os << RD->getQualifiedNameAsString() << " inherits from edm::EDProducer or edm::EDFilter";
os << "\n";
llvm::errs()<<os.str();
CXXMethodDecl::param_iterator I = MD->param_begin();
ParmVarDecl * PVD = *(I);
QualType PQT = PVD->getType();
if ( PQT->isReferenceType() ) {
QualType RQT = PQT->getPointeeType();
if (RQT.isConstQualified()) continue;
}
clang::ento::PathDiagnosticLocation ELoc =clang::ento::PathDiagnosticLocation::createBegin( MD, SM );
clang::SourceLocation SL = MD->getLocStart();
BR.EmitBasicReport(MD, "Class Checker : inherits from edm::EDProducer or edm::EDFilter","optional",os.str(),ELoc,SL);
}
}
}
}
} //end of class
示例8: PerformReturnAdjustment
static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
QualType ResultType, RValue RV,
const ThunkInfo &Thunk) {
// Emit the return adjustment.
bool NullCheckValue = !ResultType->isReferenceType();
llvm::BasicBlock *AdjustNull = nullptr;
llvm::BasicBlock *AdjustNotNull = nullptr;
llvm::BasicBlock *AdjustEnd = nullptr;
llvm::Value *ReturnValue = RV.getScalarVal();
if (NullCheckValue) {
AdjustNull = CGF.createBasicBlock("adjust.null");
AdjustNotNull = CGF.createBasicBlock("adjust.notnull");
AdjustEnd = CGF.createBasicBlock("adjust.end");
llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue);
CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
CGF.EmitBlock(AdjustNotNull);
}
auto ClassDecl = ResultType->getPointeeType()->getAsCXXRecordDecl();
auto ClassAlign = CGF.CGM.getClassPointerAlignment(ClassDecl);
ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment(CGF,
Address(ReturnValue, ClassAlign),
Thunk.Return);
if (NullCheckValue) {
CGF.Builder.CreateBr(AdjustEnd);
CGF.EmitBlock(AdjustNull);
CGF.Builder.CreateBr(AdjustEnd);
CGF.EmitBlock(AdjustEnd);
llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2);
PHI->addIncoming(ReturnValue, AdjustNotNull);
PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
AdjustNull);
ReturnValue = PHI;
}
return RValue::get(ReturnValue);
}
示例9: isCallback
static bool isCallback(QualType T) {
// If a parameter is a block or a callback, assume it can modify pointer.
if (T->isBlockPointerType() ||
T->isFunctionPointerType() ||
T->isObjCSelType())
return true;
// Check if a callback is passed inside a struct (for both, struct passed by
// reference and by value). Dig just one level into the struct for now.
if (T->isAnyPointerType() || T->isReferenceType())
T = T->getPointeeType();
if (const RecordType *RT = T->getAsStructureType()) {
const RecordDecl *RD = RT->getDecl();
for (const auto *I : RD->fields()) {
QualType FieldT = I->getType();
if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
return true;
}
}
return false;
}
示例10:
Optional<SVal> GenericTaintChecker::getPointedToSVal(CheckerContext &C,
const Expr *Arg) {
ProgramStateRef State = C.getState();
SVal AddrVal = C.getSVal(Arg->IgnoreParens());
if (AddrVal.isUnknownOrUndef())
return None;
Optional<Loc> AddrLoc = AddrVal.getAs<Loc>();
if (!AddrLoc)
return None;
QualType ArgTy = Arg->getType().getCanonicalType();
if (!ArgTy->isPointerType())
return None;
QualType ValTy = ArgTy->getPointeeType();
// Do not dereference void pointers. Treat them as byte pointers instead.
// FIXME: we might want to consider more than just the first byte.
if (ValTy->isVoidType())
ValTy = C.getASTContext().CharTy;
return State->getSVal(*AddrLoc, ValTy);
}
示例11: attemptDownCast
SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType,
bool &Failed) {
Failed = false;
const MemRegion *MR = Base.getAsRegion();
if (!MR)
return UnknownVal();
// Assume the derived class is a pointer or a reference to a CXX record.
TargetType = TargetType->getPointeeType();
assert(!TargetType.isNull());
const CXXRecordDecl *TargetClass = TargetType->getAsCXXRecordDecl();
if (!TargetClass && !TargetType->isVoidType())
return UnknownVal();
// Drill down the CXXBaseObject chains, which represent upcasts (casts from
// derived to base).
while (const CXXRecordDecl *MRClass = getCXXRecordType(MR)) {
// If found the derived class, the cast succeeds.
if (MRClass == TargetClass)
return loc::MemRegionVal(MR);
// We skip over incomplete types. They must be the result of an earlier
// reinterpret_cast, as one can only dynamic_cast between types in the same
// class hierarchy.
if (!TargetType->isVoidType() && MRClass->hasDefinition()) {
// Static upcasts are marked as DerivedToBase casts by Sema, so this will
// only happen when multiple or virtual inheritance is involved.
CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (MRClass->isDerivedFrom(TargetClass, Paths))
return evalDerivedToBase(loc::MemRegionVal(MR), Paths.front());
}
if (const auto *BaseR = dyn_cast<CXXBaseObjectRegion>(MR)) {
// Drill down the chain to get the derived classes.
MR = BaseR->getSuperRegion();
continue;
}
// If this is a cast to void*, return the region.
if (TargetType->isVoidType())
return loc::MemRegionVal(MR);
// Strange use of reinterpret_cast can give us paths we don't reason
// about well, by putting in ElementRegions where we'd expect
// CXXBaseObjectRegions. If it's a valid reinterpret_cast (i.e. if the
// derived class has a zero offset from the base class), then it's safe
// to strip the cast; if it's invalid, -Wreinterpret-base-class should
// catch it. In the interest of performance, the analyzer will silently
// do the wrong thing in the invalid case (because offsets for subregions
// will be wrong).
const MemRegion *Uncasted = MR->StripCasts(/*IncludeBaseCasts=*/false);
if (Uncasted == MR) {
// We reached the bottom of the hierarchy and did not find the derived
// class. We must be casting the base to derived, so the cast should
// fail.
break;
}
MR = Uncasted;
}
// If we're casting a symbolic base pointer to a derived class, use
// CXXDerivedObjectRegion to represent the cast. If it's a pointer to an
// unrelated type, it must be a weird reinterpret_cast and we have to
// be fine with ElementRegion. TODO: Should we instead make
// Derived{TargetClass, Element{SourceClass, SR}}?
if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
QualType T = SR->getSymbol()->getType();
const CXXRecordDecl *SourceClass = T->getPointeeCXXRecordDecl();
if (TargetClass && SourceClass && TargetClass->isDerivedFrom(SourceClass))
return loc::MemRegionVal(
MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
return loc::MemRegionVal(GetElementZeroRegion(SR, TargetType));
}
// We failed if the region we ended up with has perfect type info.
Failed = isa<TypedValueRegion>(MR);
return UnknownVal();
}
示例12: checkOverridingFunctionReturnType
/// Checks whether the return types are covariant, according to
/// C++[class.virtual]p7.
///
/// Similar with clang::Sema::CheckOverridingFunctionReturnType.
/// \returns true if the return types of BaseMD and DerivedMD are covariant.
static bool checkOverridingFunctionReturnType(const ASTContext *Context,
const CXXMethodDecl *BaseMD,
const CXXMethodDecl *DerivedMD) {
QualType BaseReturnTy = BaseMD->getType()
->getAs<FunctionType>()
->getReturnType()
.getCanonicalType();
QualType DerivedReturnTy = DerivedMD->getType()
->getAs<FunctionType>()
->getReturnType()
.getCanonicalType();
if (DerivedReturnTy->isDependentType() || BaseReturnTy->isDependentType())
return false;
// Check if return types are identical.
if (Context->hasSameType(DerivedReturnTy, BaseReturnTy))
return true;
/// Check if the return types are covariant.
// Both types must be pointers or references to classes.
if (!(BaseReturnTy->isPointerType() && DerivedReturnTy->isPointerType()) &&
!(BaseReturnTy->isReferenceType() && DerivedReturnTy->isReferenceType()))
return false;
/// BTy is the class type in return type of BaseMD. For example,
/// B* Base::md()
/// While BRD is the declaration of B.
QualType DTy = DerivedReturnTy->getPointeeType().getCanonicalType();
QualType BTy = BaseReturnTy->getPointeeType().getCanonicalType();
const CXXRecordDecl *DRD = DTy->getAsCXXRecordDecl();
const CXXRecordDecl *BRD = BTy->getAsCXXRecordDecl();
if (DRD == nullptr || BRD == nullptr)
return false;
if (!DRD->hasDefinition() || !BRD->hasDefinition())
return false;
if (DRD == BRD)
return true;
if (!Context->hasSameUnqualifiedType(DTy, BTy)) {
// Begin checking whether the conversion from D to B is valid.
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
// Check whether D is derived from B, and fill in a CXXBasePaths object.
if (!DRD->isDerivedFrom(BRD, Paths))
return false;
// Check ambiguity.
if (Paths.isAmbiguous(Context->getCanonicalType(BTy).getUnqualifiedType()))
return false;
// Check accessibility.
// FIXME: We currently only support checking if B is accessible base class
// of D, or D is the same class which DerivedMD is in.
bool IsItself =
DRD->getCanonicalDecl() == DerivedMD->getParent()->getCanonicalDecl();
bool HasPublicAccess = false;
for (const auto &Path : Paths) {
if (Path.Access == AS_public)
HasPublicAccess = true;
}
if (!HasPublicAccess && !IsItself)
return false;
// End checking conversion from D to B.
}
// Both pointers or references should have the same cv-qualification.
if (DerivedReturnTy.getLocalCVRQualifiers() !=
BaseReturnTy.getLocalCVRQualifiers())
return false;
// The class type D should have the same cv-qualification as or less
// cv-qualification than the class type B.
if (DTy.isMoreQualifiedThan(BTy))
return false;
return true;
}
示例13: fixType
bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
ASTContext &Ctx, bool IsObjCLiteral) {
// %n is different from other conversion specifiers; don't try to fix it.
if (CS.getKind() == ConversionSpecifier::nArg)
return false;
// Handle Objective-C objects first. Note that while the '%@' specifier will
// not warn for structure pointer or void pointer arguments (because that's
// how CoreFoundation objects are implemented), we only show a fixit for '%@'
// if we know it's an object (block, id, class, or __attribute__((NSObject))).
if (QT->isObjCRetainableType()) {
if (!IsObjCLiteral)
return false;
CS.setKind(ConversionSpecifier::ObjCObjArg);
// Disable irrelevant flags
HasThousandsGrouping = false;
HasPlusPrefix = false;
HasSpacePrefix = false;
HasAlternativeForm = false;
HasLeadingZeroes = false;
Precision.setHowSpecified(OptionalAmount::NotSpecified);
LM.setKind(LengthModifier::None);
return true;
}
// Handle strings next (char *, wchar_t *)
if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
CS.setKind(ConversionSpecifier::sArg);
// Disable irrelevant flags
HasAlternativeForm = 0;
HasLeadingZeroes = 0;
// Set the long length modifier for wide characters
if (QT->getPointeeType()->isWideCharType())
LM.setKind(LengthModifier::AsWideChar);
else
LM.setKind(LengthModifier::None);
return true;
}
// If it's an enum, get its underlying type.
if (const EnumType *ETy = QT->getAs<EnumType>())
QT = ETy->getDecl()->getIntegerType();
// We can only work with builtin types.
const BuiltinType *BT = QT->getAs<BuiltinType>();
if (!BT)
return false;
// Set length modifier
switch (BT->getKind()) {
case BuiltinType::Bool:
case BuiltinType::WChar_U:
case BuiltinType::WChar_S:
case BuiltinType::Char16:
case BuiltinType::Char32:
case BuiltinType::UInt128:
case BuiltinType::Int128:
case BuiltinType::Half:
case BuiltinType::Float128:
// Various types which are non-trivial to correct.
return false;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
#define SIGNED_TYPE(Id, SingletonId)
#define UNSIGNED_TYPE(Id, SingletonId)
#define FLOATING_TYPE(Id, SingletonId)
#define BUILTIN_TYPE(Id, SingletonId) \
case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
// Misc other stuff which doesn't make sense here.
return false;
case BuiltinType::UInt:
case BuiltinType::Int:
case BuiltinType::Float:
case BuiltinType::Double:
LM.setKind(LengthModifier::None);
break;
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::Char_S:
case BuiltinType::SChar:
LM.setKind(LengthModifier::AsChar);
break;
case BuiltinType::Short:
case BuiltinType::UShort:
LM.setKind(LengthModifier::AsShort);
break;
case BuiltinType::Long:
//.........这里部分代码省略.........
示例14: EmitAtomicExpr
RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
QualType AtomicTy = E->getPtr()->getType()->getPointeeType();
QualType MemTy = AtomicTy;
if (const AtomicType *AT = AtomicTy->getAs<AtomicType>())
MemTy = AT->getValueType();
CharUnits sizeChars = getContext().getTypeSizeInChars(AtomicTy);
uint64_t Size = sizeChars.getQuantity();
CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy);
unsigned Align = alignChars.getQuantity();
unsigned MaxInlineWidthInBits =
getTarget().getMaxAtomicInlineWidth();
bool UseLibcall = (Size != Align ||
getContext().toBits(sizeChars) > MaxInlineWidthInBits);
llvm::Value *IsWeak = nullptr, *OrderFail = nullptr, *Val1 = nullptr,
*Val2 = nullptr;
llvm::Value *Ptr = EmitScalarExpr(E->getPtr());
if (E->getOp() == AtomicExpr::AO__c11_atomic_init) {
assert(!Dest && "Init does not return a value");
LValue lvalue = LValue::MakeAddr(Ptr, AtomicTy, alignChars, getContext());
EmitAtomicInit(E->getVal1(), lvalue);
return RValue::get(nullptr);
}
llvm::Value *Order = EmitScalarExpr(E->getOrder());
switch (E->getOp()) {
case AtomicExpr::AO__c11_atomic_init:
llvm_unreachable("Already handled!");
case AtomicExpr::AO__c11_atomic_load:
case AtomicExpr::AO__atomic_load_n:
break;
case AtomicExpr::AO__atomic_load:
Dest = EmitScalarExpr(E->getVal1());
break;
case AtomicExpr::AO__atomic_store:
Val1 = EmitScalarExpr(E->getVal1());
break;
case AtomicExpr::AO__atomic_exchange:
Val1 = EmitScalarExpr(E->getVal1());
Dest = EmitScalarExpr(E->getVal2());
break;
case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
case AtomicExpr::AO__atomic_compare_exchange_n:
case AtomicExpr::AO__atomic_compare_exchange:
Val1 = EmitScalarExpr(E->getVal1());
if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange)
Val2 = EmitScalarExpr(E->getVal2());
else
Val2 = EmitValToTemp(*this, E->getVal2());
OrderFail = EmitScalarExpr(E->getOrderFail());
if (E->getNumSubExprs() == 6)
IsWeak = EmitScalarExpr(E->getWeak());
break;
case AtomicExpr::AO__c11_atomic_fetch_add:
case AtomicExpr::AO__c11_atomic_fetch_sub:
if (MemTy->isPointerType()) {
// For pointer arithmetic, we're required to do a bit of math:
// adding 1 to an int* is not the same as adding 1 to a uintptr_t.
// ... but only for the C11 builtins. The GNU builtins expect the
// user to multiply by sizeof(T).
QualType Val1Ty = E->getVal1()->getType();
llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1());
CharUnits PointeeIncAmt =
getContext().getTypeSizeInChars(MemTy->getPointeeType());
Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt));
Val1 = CreateMemTemp(Val1Ty, ".atomictmp");
EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Val1, Val1Ty));
break;
}
// Fall through.
case AtomicExpr::AO__atomic_fetch_add:
case AtomicExpr::AO__atomic_fetch_sub:
case AtomicExpr::AO__atomic_add_fetch:
case AtomicExpr::AO__atomic_sub_fetch:
case AtomicExpr::AO__c11_atomic_store:
case AtomicExpr::AO__c11_atomic_exchange:
case AtomicExpr::AO__atomic_store_n:
case AtomicExpr::AO__atomic_exchange_n:
case AtomicExpr::AO__c11_atomic_fetch_and:
case AtomicExpr::AO__c11_atomic_fetch_or:
case AtomicExpr::AO__c11_atomic_fetch_xor:
case AtomicExpr::AO__atomic_fetch_and:
case AtomicExpr::AO__atomic_fetch_or:
case AtomicExpr::AO__atomic_fetch_xor:
case AtomicExpr::AO__atomic_fetch_nand:
case AtomicExpr::AO__atomic_and_fetch:
case AtomicExpr::AO__atomic_or_fetch:
case AtomicExpr::AO__atomic_xor_fetch:
case AtomicExpr::AO__atomic_nand_fetch:
Val1 = EmitValToTemp(*this, E->getVal1());
break;
//.........这里部分代码省略.........
示例15: 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;
//.........这里部分代码省略.........