本文整理汇总了C++中QualType::getQualifiers方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::getQualifiers方法的具体用法?C++ QualType::getQualifiers怎么用?C++ QualType::getQualifiers使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::getQualifiers方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: mangleExtraDimensions
void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) {
llvm::SmallVector<llvm::APInt, 3> Dimensions;
for (;;) {
if (ElementTy->isConstantArrayType()) {
const ConstantArrayType *CAT =
static_cast<const ConstantArrayType *>(ElementTy.getTypePtr());
Dimensions.push_back(CAT->getSize());
ElementTy = CAT->getElementType();
} else if (ElementTy->isVariableArrayType()) {
assert(false && "Don't know how to mangle VLAs!");
} else if (ElementTy->isDependentSizedArrayType()) {
// The dependent expression has to be folded into a constant (TODO).
assert(false && "Don't know how to mangle dependent-sized arrays!");
} else if (ElementTy->isIncompleteArrayType()) continue;
else break;
}
mangleQualifiers(ElementTy.getQualifiers(), false);
// If there are any additional dimensions, mangle them now.
if (Dimensions.size() > 0) {
Out << 'Y';
// <dimension-count> ::= <number> # number of extra dimensions
mangleNumber(Dimensions.size());
for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim) {
mangleNumber(Dimensions[Dim].getLimitedValue());
}
}
mangleType(ElementTy.getLocalUnqualifiedType());
}
示例2: rewriteToObjCProperty
static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter,
const ObjCMethodDecl *Setter,
const NSAPI &NS, edit::Commit &commit) {
ASTContext &Context = NS.getASTContext();
std::string PropertyString = "@property";
const ParmVarDecl *argDecl = *Setter->param_begin();
QualType ArgType = Context.getCanonicalType(argDecl->getType());
Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
if (ArgType->isObjCRetainableType() &&
propertyLifetime == Qualifiers::OCL_Strong) {
if (const ObjCObjectPointerType *ObjPtrTy =
ArgType->getAs<ObjCObjectPointerType>()) {
ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
if (IDecl &&
IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
PropertyString += "(copy)";
}
}
else if (propertyLifetime == Qualifiers::OCL_Weak)
// TODO. More precise determination of 'weak' attribute requires
// looking into setter's implementation for backing weak ivar.
PropertyString += "(weak)";
else
PropertyString += "(unsafe_unretained)";
// strip off any ARC lifetime qualifier.
QualType CanResultTy = Context.getCanonicalType(Getter->getResultType());
if (CanResultTy.getQualifiers().hasObjCLifetime()) {
Qualifiers Qs = CanResultTy.getQualifiers();
Qs.removeObjCLifetime();
CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
}
PropertyString += " ";
PropertyString += CanResultTy.getAsString(Context.getPrintingPolicy());
PropertyString += " ";
PropertyString += Getter->getNameAsString();
commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
Getter->getDeclaratorEndLoc()),
PropertyString);
SourceLocation EndLoc = Setter->getDeclaratorEndLoc();
// Get location past ';'
EndLoc = EndLoc.getLocWithOffset(1);
commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc));
return true;
}
示例3: ExprError
static ExprResult
BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
const CXXScopeSpec &SS, FieldDecl *Field,
DeclAccessPair FoundDecl,
const DeclarationNameInfo &MemberNameInfo) {
// x.a is an l-value if 'a' has a reference type. Otherwise:
// x.a is an l-value/x-value/pr-value if the base is (and note
// that *x is always an l-value), except that if the base isn't
// an ordinary object then we must have an rvalue.
ExprValueKind VK = VK_LValue;
ExprObjectKind OK = OK_Ordinary;
if (!IsArrow) {
if (BaseExpr->getObjectKind() == OK_Ordinary)
VK = BaseExpr->getValueKind();
else
VK = VK_RValue;
}
if (VK != VK_RValue && Field->isBitField())
OK = OK_BitField;
// Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
QualType MemberType = Field->getType();
if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
MemberType = Ref->getPointeeType();
VK = VK_LValue;
} else {
QualType BaseType = BaseExpr->getType();
if (IsArrow) BaseType = BaseType->getAs<PointerType>()->getPointeeType();
Qualifiers BaseQuals = BaseType.getQualifiers();
// CVR attributes from the base are picked up by members,
// except that 'mutable' members don't pick up 'const'.
if (Field->isMutable()) BaseQuals.removeConst();
Qualifiers MemberQuals
= S.Context.getCanonicalType(MemberType).getQualifiers();
assert(!MemberQuals.hasAddressSpace());
Qualifiers Combined = BaseQuals + MemberQuals;
if (Combined != MemberQuals)
MemberType = S.Context.getQualifiedType(MemberType, Combined);
}
S.UnusedPrivateFields.remove(Field);
ExprResult Base =
S.PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
FoundDecl, Field);
if (Base.isInvalid())
return ExprError();
return S.Owned(BuildMemberExpr(S, S.Context, Base.take(), IsArrow,
Field, FoundDecl, MemberNameInfo,
MemberType, VK, OK));
}
示例4: VisitTypedefType
void VisitTypedefType(const TypedefType *T) {
AddDecl(T->getDecl());
QualType UnderlyingType = T->getDecl()->getUnderlyingType();
VisitQualifiers(UnderlyingType.getQualifiers());
while (const TypedefType *Underlying =
dyn_cast<TypedefType>(UnderlyingType.getTypePtr())) {
UnderlyingType = Underlying->getDecl()->getUnderlyingType();
}
AddType(UnderlyingType.getTypePtr());
VisitType(T);
}
示例5: mangleType
// <type> ::= <pointer-to-member-type>
// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
// <class name> <type>
void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T) {
QualType PointeeType = T->getPointeeType();
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
Out << '8';
mangleName(cast<RecordType>(T->getClass())->getDecl());
mangleType(FPT, NULL, false, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
mangleName(cast<RecordType>(T->getClass())->getDecl());
mangleType(PointeeType.getLocalUnqualifiedType());
}
}
示例6: clang_getAddressSpace
unsigned clang_getAddressSpace(CXType CT) {
QualType T = GetQualType(CT);
// For non language-specific address space, use separate helper function.
if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) {
return T.getQualifiers().getAddressSpaceAttributePrintValue();
}
// FIXME: this function returns either a LangAS or a target AS
// Those values can overlap which makes this function rather unpredictable
// for any caller
return (unsigned)T.getAddressSpace();
}
示例7: EmitUPCPointerGetPhase
llvm::Value *CodeGenFunction::EmitUPCPointerDiff(
llvm::Value *Pointer1, llvm::Value *Pointer2, const Expr *E) {
const BinaryOperator *expr = cast<BinaryOperator>(E);
Expr *LHSOperand = expr->getLHS();
QualType PtrTy = LHSOperand->getType();
llvm::Value *Phase1 = EmitUPCPointerGetPhase(Pointer1);
llvm::Value *Thread1 = EmitUPCPointerGetThread(Pointer1);
llvm::Value *Addr1 = EmitUPCPointerGetAddr(Pointer1);
llvm::Value *Phase2 = EmitUPCPointerGetPhase(Pointer2);
llvm::Value *Thread2 = EmitUPCPointerGetThread(Pointer2);
llvm::Value *Addr2 = EmitUPCPointerGetAddr(Pointer2);
QualType PointeeTy = PtrTy->getAs<PointerType>()->getPointeeType();
QualType ElemTy;
llvm::Value *Dim;
llvm::tie(ElemTy, Dim) = unwrapArray(*this, PointeeTy);
Qualifiers Quals = ElemTy.getQualifiers();
llvm::Constant *ElemSize =
llvm::ConstantInt::get(SizeTy, getContext().getTypeSizeInChars(ElemTy).getQuantity());
llvm::Value *AddrByteDiff = Builder.CreateSub(Addr1, Addr2, "addr.diff");
llvm::Value *AddrDiff = Builder.CreateExactSDiv(AddrByteDiff, ElemSize);
llvm::Value *Result;
if (Quals.getLayoutQualifier() == 0) {
Result = AddrDiff;
} else {
llvm::Constant *B = llvm::ConstantInt::get(SizeTy, Quals.getLayoutQualifier());
llvm::Value *Threads = Builder.CreateZExt(EmitUPCThreads(), SizeTy);
llvm::Value *ThreadDiff = Builder.CreateMul(Builder.CreateSub(Thread1, Thread2, "thread.diff"), B);
llvm::Value *PhaseDiff = Builder.CreateSub(Phase1, Phase2, "phase.diff");
llvm::Value *BlockDiff =
Builder.CreateMul(Builder.CreateSub(AddrDiff, PhaseDiff), Threads, "block.diff");
Result = Builder.CreateAdd(BlockDiff, Builder.CreateAdd(ThreadDiff, PhaseDiff), "ptr.diff");
}
if (Dim) {
Result = Builder.CreateExactSDiv(Result, Dim, "diff.dim");
}
// FIXME: Divide by the array dimension
return Result;
}
示例8: GetBestOverloadCandidateSimple
CXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const {
ASTContext &Context = getASTContext();
QualType Class = Context.getTypeDeclType(const_cast<CXXRecordDecl *>(this));
DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found;
DeclContext::lookup_const_iterator Op, OpEnd;
for (llvm::tie(Op, OpEnd) = this->lookup(Name); Op != OpEnd; ++Op) {
// C++ [class.copy]p9:
// A user-declared copy assignment operator is a non-static non-template
// member function of class X with exactly one parameter of type X, X&,
// const X&, volatile X& or const volatile X&.
const CXXMethodDecl* Method = dyn_cast<CXXMethodDecl>(*Op);
if (!Method || Method->isStatic() || Method->getPrimaryTemplate())
continue;
const FunctionProtoType *FnType
= Method->getType()->getAs<FunctionProtoType>();
assert(FnType && "Overloaded operator has no prototype.");
// Don't assert on this; an invalid decl might have been left in the AST.
if (FnType->getNumArgs() != 1 || FnType->isVariadic())
continue;
QualType ArgType = FnType->getArgType(0);
Qualifiers Quals;
if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) {
ArgType = Ref->getPointeeType();
// If we have a const argument and we have a reference to a non-const,
// this function does not match.
if (ArgIsConst && !ArgType.isConstQualified())
continue;
Quals = ArgType.getQualifiers();
} else {
// By-value copy-assignment operators are treated like const X&
// copy-assignment operators.
Quals = Qualifiers::fromCVRMask(Qualifiers::Const);
}
if (!Context.hasSameUnqualifiedType(ArgType, Class))
continue;
// Save this copy-assignment operator. It might be "the one".
Found.push_back(std::make_pair(const_cast<CXXMethodDecl *>(Method), Quals));
}
// Use a simplistic form of overload resolution to find the candidate.
return GetBestOverloadCandidateSimple(Found);
}
示例9: TypeInfoIsInStandardLibrary
static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
QualType PointeeTy = PointerTy->getPointeeType();
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
if (!BuiltinTy)
return false;
// Check the qualifiers.
Qualifiers Quals = PointeeTy.getQualifiers();
Quals.removeConst();
if (!Quals.empty())
return false;
return TypeInfoIsInStandardLibrary(BuiltinTy);
}
示例10: printType_Default
void printType_Default(llvm::raw_ostream& o, const Value& V) {
using namespace clang;
QualType QT = V.getType().getNonReferenceType();
std::string ValueTyStr;
if (const TypedefType* TDTy = dyn_cast<TypedefType>(QT))
ValueTyStr = TDTy->getDecl()->getQualifiedNameAsString();
else if (const TagType* TTy = dyn_cast<TagType>(QT))
ValueTyStr = TTy->getDecl()->getQualifiedNameAsString();
if (ValueTyStr.empty())
ValueTyStr = QT.getAsString();
else if (QT.hasQualifiers())
ValueTyStr = QT.getQualifiers().getAsString() + " " + ValueTyStr;
o << "(";
o << ValueTyStr;
if (V.getType()->isReferenceType())
o << " &";
o << ") ";
}
示例11: EmitUPCAggregateCopy
void CodeGenFunction::EmitUPCAggregateCopy(llvm::Value *Dest, llvm::Value *Src,
QualType DestTy, QualType SrcTy,
SourceLocation Loc) {
const ASTContext& Context = getContext();
QualType ArgTy = Context.getPointerType(Context.getSharedType(Context.VoidTy));
QualType SizeType = Context.getSizeType();
assert(DestTy->getCanonicalTypeUnqualified() == SrcTy->getCanonicalTypeUnqualified());
llvm::Constant *Len =
llvm::ConstantInt::get(ConvertType(SizeType),
Context.getTypeSizeInChars(DestTy).getQuantity());
llvm::SmallString<16> Name;
const char *OpName;
QualType DestArgTy, SrcArgTy;
if (DestTy.getQualifiers().hasShared() && SrcTy.getQualifiers().hasShared()) {
// both shared
OpName = "copy";
DestArgTy = SrcArgTy = ArgTy;
} else if (DestTy.getQualifiers().hasShared()) {
OpName = "put";
DestArgTy = ArgTy;
SrcArgTy = Context.VoidPtrTy;
} else if (SrcTy.getQualifiers().hasShared()) {
OpName = "get";
DestArgTy = Context.VoidPtrTy;
SrcArgTy = ArgTy;
} else {
llvm_unreachable("expected at least one shared argument");
}
Name += "__";
Name += OpName;
if (DestTy.getQualifiers().hasStrict() || SrcTy.getQualifiers().hasStrict())
Name += 's';
if (CGM.getCodeGenOpts().UPCDebug) Name += "g";
Name += "blk";
CallArgList Args;
Args.add(RValue::get(Dest), DestArgTy);
Args.add(RValue::get(Src), SrcArgTy);
Args.add(RValue::get(Len), SizeType);
if (CGM.getCodeGenOpts().UPCDebug) {
getFileAndLine(*this, Loc, &Args);
Name += '5';
} else {
Name += '3';
}
EmitUPCCall(*this, Name, Context.VoidTy, Args);
}
示例12: EmitUPCPointer
llvm::Value *CodeGenFunction::EmitUPCPointerArithmetic(
llvm::Value *Pointer, llvm::Value *Index, QualType PtrTy, QualType IndexTy, bool IsSubtraction) {
llvm::Value *Phase = EmitUPCPointerGetPhase(Pointer);
llvm::Value *Thread = EmitUPCPointerGetThread(Pointer);
llvm::Value *Addr = EmitUPCPointerGetAddr(Pointer);
bool isSigned = IndexTy->isSignedIntegerOrEnumerationType();
unsigned width = cast<llvm::IntegerType>(Index->getType())->getBitWidth();
if (width != PointerWidthInBits) {
// Zero-extend or sign-extend the pointer value according to
// whether the index is signed or not.
Index = Builder.CreateIntCast(Index, PtrDiffTy, isSigned,
"idx.ext");
}
QualType PointeeTy = PtrTy->getAs<PointerType>()->getPointeeType();
QualType ElemTy;
llvm::Value *Dim;
llvm::tie(ElemTy, Dim) = unwrapArray(*this, PointeeTy);
if (Dim) {
Index = Builder.CreateMul(Index, Dim, "idx.dim", !isSigned, isSigned);
}
Qualifiers Quals = ElemTy.getQualifiers();
if (IsSubtraction)
Index = Builder.CreateNeg(Index);
if (Quals.getLayoutQualifier() == 0) {
// UPC 1.2 6.4.2p2
// If the shared array is declared with indefinite block size,
// the result of the pointer-to-shared arithmetic is identical
// to that described for normal C pointers in [IOS/IEC00 Sec 6.5.2]
// except that the thread of the new pointer shall be the
// same as that of the original pointer and the phase
// component is defined to always be zero.
uint64_t ElemSize = getContext().getTypeSizeInChars(ElemTy).getQuantity();
llvm::Value *ByteIndex = Builder.CreateMul(Index, llvm::ConstantInt::get(SizeTy, ElemSize));
Addr = Builder.CreateAdd(Addr, ByteIndex, "add.addr");
} else {
llvm::Value *OldPhase = Phase;
llvm::Constant *B = llvm::ConstantInt::get(SizeTy, Quals.getLayoutQualifier());
llvm::Value *Threads = Builder.CreateZExt(EmitUPCThreads(), SizeTy);
llvm::Value *GlobalBlockSize = Builder.CreateNUWMul(Threads, B);
// Combine the Phase and Thread into a single unit
llvm::Value *TmpPhaseThread =
Builder.CreateNUWAdd(Builder.CreateNUWMul(Thread, B),
Phase);
TmpPhaseThread = Builder.CreateAdd(TmpPhaseThread, Index);
// Div is the number of (B * THREADS) blocks that we need to jump
// Rem is Thread * B + Phase
llvm::Value *Div = Builder.CreateSDiv(TmpPhaseThread, GlobalBlockSize);
llvm::Value *Rem = Builder.CreateSRem(TmpPhaseThread, GlobalBlockSize);
// Fix the result of the division/modulus
llvm::Value *Test = Builder.CreateICmpSLT(Rem, llvm::ConstantInt::get(SizeTy, 0));
Rem = Builder.CreateSelect(Test, Builder.CreateAdd(Rem, GlobalBlockSize), Rem);
llvm::Value *DecDiv = Builder.CreateSub(Div, llvm::ConstantInt::get(SizeTy, 1));
Div = Builder.CreateSelect(Test, DecDiv, Div);
// Split out the Phase and Thread components
Thread = Builder.CreateUDiv(Rem, B);
Phase = Builder.CreateURem(Rem, B);
uint64_t ElemSize = getContext().getTypeSizeInChars(ElemTy).getQuantity();
// Compute the final Addr.
llvm::Value *AddrInc =
Builder.CreateMul(Builder.CreateAdd(Builder.CreateSub(Phase, OldPhase),
Builder.CreateMul(Div, B)),
llvm::ConstantInt::get(SizeTy, ElemSize));
Addr = Builder.CreateAdd(Addr, AddrInc);
}
return EmitUPCPointer(Phase, Thread, Addr);
}
示例13: VisitType
void USRGenerator::VisitType(QualType T) {
// This method mangles in USR information for types. It can possibly
// just reuse the naming-mangling logic used by codegen, although the
// requirements for USRs might not be the same.
ASTContext &Ctx = *Context;
do {
T = Ctx.getCanonicalType(T);
Qualifiers Q = T.getQualifiers();
unsigned qVal = 0;
if (Q.hasConst())
qVal |= 0x1;
if (Q.hasVolatile())
qVal |= 0x2;
if (Q.hasRestrict())
qVal |= 0x4;
if(qVal)
Out << ((char) ('0' + qVal));
// Mangle in ObjC GC qualifiers?
if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
Out << 'P';
T = Expansion->getPattern();
}
if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
unsigned char c = '\0';
switch (BT->getKind()) {
case BuiltinType::Void:
c = 'v'; break;
case BuiltinType::Bool:
c = 'b'; break;
case BuiltinType::Char_U:
case BuiltinType::UChar:
c = 'c'; break;
case BuiltinType::Char16:
c = 'q'; break;
case BuiltinType::Char32:
c = 'w'; break;
case BuiltinType::UShort:
c = 's'; break;
case BuiltinType::UInt:
c = 'i'; break;
case BuiltinType::ULong:
c = 'l'; break;
case BuiltinType::ULongLong:
c = 'k'; break;
case BuiltinType::UInt128:
c = 'j'; break;
case BuiltinType::Char_S:
case BuiltinType::SChar:
c = 'C'; break;
case BuiltinType::WChar_S:
case BuiltinType::WChar_U:
c = 'W'; break;
case BuiltinType::Short:
c = 'S'; break;
case BuiltinType::Int:
c = 'I'; break;
case BuiltinType::Long:
c = 'L'; break;
case BuiltinType::LongLong:
c = 'K'; break;
case BuiltinType::Int128:
c = 'J'; break;
case BuiltinType::Half:
c = 'h'; break;
case BuiltinType::Float:
c = 'f'; break;
case BuiltinType::Double:
c = 'd'; break;
case BuiltinType::LongDouble:
c = 'D'; break;
case BuiltinType::NullPtr:
c = 'n'; break;
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
case BuiltinType::Dependent:
case BuiltinType::OCLImage1d:
case BuiltinType::OCLImage1dArray:
case BuiltinType::OCLImage1dBuffer:
case BuiltinType::OCLImage2d:
case BuiltinType::OCLImage2dArray:
case BuiltinType::OCLImage3d:
case BuiltinType::OCLEvent:
case BuiltinType::OCLSampler:
IgnoreResults = true;
return;
case BuiltinType::ObjCId:
c = 'o'; break;
case BuiltinType::ObjCClass:
c = 'O'; break;
case BuiltinType::ObjCSel:
c = 'e'; break;
}
Out << c;
return;
}
//.........这里部分代码省略.........
示例14: VisitInitListExpr
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
#if 0
// FIXME: Assess perf here? Figure out what cases are worth optimizing here
// (Length of globals? Chunks of zeroed-out space?).
//
// If we can, prefer a copy from a global; this is a lot less code for long
// globals, and it's easier for the current optimizers to analyze.
if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
llvm::GlobalVariable* GV =
new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
llvm::GlobalValue::InternalLinkage, C, "");
EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
return;
}
#endif
if (E->hadArrayRangeDesignator())
CGF.ErrorUnsupported(E, "GNU array range designator extension");
llvm::Value *DestPtr = Dest.getAddr();
// Handle initialization of an array.
if (E->getType()->isArrayType()) {
llvm::PointerType *APType =
cast<llvm::PointerType>(DestPtr->getType());
llvm::ArrayType *AType =
cast<llvm::ArrayType>(APType->getElementType());
uint64_t NumInitElements = E->getNumInits();
if (E->getNumInits() > 0) {
QualType T1 = E->getType();
QualType T2 = E->getInit(0)->getType();
if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
EmitAggLoadOfLValue(E->getInit(0));
return;
}
}
uint64_t NumArrayElements = AType->getNumElements();
assert(NumInitElements <= NumArrayElements);
QualType elementType = E->getType().getCanonicalType();
elementType = CGF.getContext().getQualifiedType(
cast<ArrayType>(elementType)->getElementType(),
elementType.getQualifiers() + Dest.getQualifiers());
// DestPtr is an array*. Construct an elementType* by drilling
// down a level.
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
llvm::Value *indices[] = { zero, zero };
llvm::Value *begin =
Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin");
// Exception safety requires us to destroy all the
// already-constructed members if an initializer throws.
// For that, we'll need an EH cleanup.
QualType::DestructionKind dtorKind = elementType.isDestructedType();
llvm::AllocaInst *endOfInit = 0;
EHScopeStack::stable_iterator cleanup;
llvm::Instruction *cleanupDominator = 0;
if (CGF.needsEHCleanup(dtorKind)) {
// In principle we could tell the cleanup where we are more
// directly, but the control flow can get so varied here that it
// would actually be quite complex. Therefore we go through an
// alloca.
endOfInit = CGF.CreateTempAlloca(begin->getType(),
"arrayinit.endOfInit");
cleanupDominator = Builder.CreateStore(begin, endOfInit);
CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
CGF.getDestroyer(dtorKind));
cleanup = CGF.EHStack.stable_begin();
// Otherwise, remember that we didn't need a cleanup.
} else {
dtorKind = QualType::DK_none;
}
llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
// The 'current element to initialize'. The invariants on this
// variable are complicated. Essentially, after each iteration of
// the loop, it points to the last initialized element, except
// that it points to the beginning of the array before any
// elements have been initialized.
llvm::Value *element = begin;
// Emit the explicit initializers.
for (uint64_t i = 0; i != NumInitElements; ++i) {
// Advance to the next element.
if (i > 0) {
element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");
// Tell the cleanup that it needs to destroy up to this
// element. TODO: some of these stores can be trivially
// observed to be unnecessary.
if (endOfInit) Builder.CreateStore(element, endOfInit);
}
LValue elementLV = CGF.MakeAddrLValue(element, elementType);
EmitInitializationToLValue(E->getInit(i), elementLV);
//.........这里部分代码省略.........
示例15: VisitType
void USRGenerator::VisitType(QualType T) {
// This method mangles in USR information for types. It can possibly
// just reuse the naming-mangling logic used by codegen, although the
// requirements for USRs might not be the same.
ASTContext &Ctx = *Context;
do {
T = Ctx.getCanonicalType(T);
Qualifiers Q = T.getQualifiers();
unsigned qVal = 0;
if (Q.hasConst())
qVal |= 0x1;
if (Q.hasVolatile())
qVal |= 0x2;
if (Q.hasRestrict())
qVal |= 0x4;
if(qVal)
Out << ((char) ('0' + qVal));
// Mangle in ObjC GC qualifiers?
if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
Out << 'P';
T = Expansion->getPattern();
}
if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
unsigned char c = '\0';
switch (BT->getKind()) {
case BuiltinType::Void:
c = 'v'; break;
case BuiltinType::Bool:
c = 'b'; break;
case BuiltinType::UChar:
c = 'c'; break;
case BuiltinType::Char16:
c = 'q'; break;
case BuiltinType::Char32:
c = 'w'; break;
case BuiltinType::UShort:
c = 's'; break;
case BuiltinType::UInt:
c = 'i'; break;
case BuiltinType::ULong:
c = 'l'; break;
case BuiltinType::ULongLong:
c = 'k'; break;
case BuiltinType::UInt128:
c = 'j'; break;
case BuiltinType::Char_U:
case BuiltinType::Char_S:
c = 'C'; break;
case BuiltinType::SChar:
c = 'r'; break;
case BuiltinType::WChar_S:
case BuiltinType::WChar_U:
c = 'W'; break;
case BuiltinType::Short:
c = 'S'; break;
case BuiltinType::Int:
c = 'I'; break;
case BuiltinType::Long:
c = 'L'; break;
case BuiltinType::LongLong:
c = 'K'; break;
case BuiltinType::Int128:
c = 'J'; break;
case BuiltinType::Half:
c = 'h'; break;
case BuiltinType::Float:
c = 'f'; break;
case BuiltinType::Double:
c = 'd'; break;
case BuiltinType::LongDouble:
c = 'D'; break;
case BuiltinType::NullPtr:
c = 'n'; break;
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
case BuiltinType::Dependent:
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/AST/OpenCLImageTypes.def"
case BuiltinType::OCLEvent:
case BuiltinType::OCLClkEvent:
case BuiltinType::OCLQueue:
case BuiltinType::OCLNDRange:
case BuiltinType::OCLReserveID:
case BuiltinType::OCLSampler:
IgnoreResults = true;
return;
case BuiltinType::ObjCId:
c = 'o'; break;
case BuiltinType::ObjCClass:
c = 'O'; break;
case BuiltinType::ObjCSel:
c = 'e'; break;
}
Out << c;
//.........这里部分代码省略.........