本文整理汇总了C++中QualType::getTypePtr方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::getTypePtr方法的具体用法?C++ QualType::getTypePtr怎么用?C++ QualType::getTypePtr使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::getTypePtr方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: VisitFieldDecl
bool FindSignals::VisitFieldDecl (FieldDecl * fd)
{
// _os << "####################### FindSignals::VisitFieldDecl\n ";
QualType
q = fd->getType ();
if (IdentifierInfo * info = fd->getIdentifier ())
{
// fname = info->getNameStart();
// _os << "\n+ Name: " << info->getNameStart();
// _os << "\n+ Type: " << q.getAsString();
// _os << "\n+ also name: " << fd->getNameAsString();
/// We are going to store these. So use pointers.
const Type *
tp = q.getTypePtr ();
FindTemplateTypes *
te = new FindTemplateTypes ();
te->Enumerate (tp);
// te->printTemplateArguments(_os);
string
tt = te->getTemplateType ();
// _os << "OUTPUT ============ " << tt << "\n";
if ((signed) tt.find ("sc_signal") == -1)
{
delete
te;
return true;
}
SignalContainer *
sc = new SignalContainer (fd->getNameAsString (), te, fd);
_signals->insert (FindSignals::
signalPairType (fd->getNameAsString (), sc));
}
return true;
}
示例2: replaceCallExpr
void SimplifyCallExpr::replaceCallExpr(void)
{
std::string CommaStr("");
unsigned int NumArg = TheCallExpr->getNumArgs();
if (NumArg == 0) {
RewriteHelper->replaceExpr(TheCallExpr, CommaStr);
return;
}
const Expr *Arg = TheCallExpr->getArg(0);
std::string ArgStr;
handleOneArgStr(Arg, ArgStr);
CommaStr += ("(" + ArgStr);
for (unsigned int I = 1; I < NumArg; ++I) {
Arg = TheCallExpr->getArg(I);
handleOneArgStr(Arg, ArgStr);
CommaStr += ("," + ArgStr);
}
QualType RVQualType = TheCallExpr->getType();
const Type *RVType = RVQualType.getTypePtr();
if (RVType->isVoidType()) {
// Nothing to do
}
else if (RVType->isUnionType() || RVType->isStructureType()) {
std::string RVStr("");
RewriteHelper->getTmpTransName(NamePostfix, RVStr);
NamePostfix++;
CommaStr += ("," + RVStr);
RVQualType.getAsStringInternal(RVStr, Context->getPrintingPolicy());
RVStr += ";\n";
RewriteHelper->insertStringBeforeFunc(CurrentFD, RVStr);
}
else {
CommaStr += ",0";
}
CommaStr += ")";
RewriteHelper->replaceExpr(TheCallExpr, CommaStr);
}
示例3: StructTypeDecl
StructTypeDecl* C2Sema::ActOnStructType(const char* name, SourceLocation loc,
bool isStruct, bool is_public, bool is_global) {
#ifdef SEMA_DEBUG
std::cerr << COL_SEMA << "SEMA: Struct/Union Type '" << (name ? name : "<anonymous>");
std::cerr << ANSI_NORMAL << '\n';
#endif
if (ast.isInterface()) {
if (is_public) Diag(loc, diag::err_public_in_interface);
is_public = true;
}
QualType qt = typeContext.getStructType();
StructTypeDecl* S = new StructTypeDecl(name, loc, qt, isStruct, is_global, is_public);
StructType* ST = cast<StructType>(qt.getTypePtr());
ST->setDecl(S);
if (is_global) {
ast.addType(S);
addSymbol(S);
}
return S;
}
示例4: ActOnTypeName
/// \brief Convert the specified DeclSpec to the appropriate type object.
QualType Sema::ActOnTypeName(ASTContext &C, DeclSpec &DS) {
QualType Result;
switch (DS.getTypeSpecType()) {
case DeclSpec::TST_integer:
Result = C.IntegerTy;
break;
case DeclSpec::TST_unspecified: // FIXME: Correct?
case DeclSpec::TST_real:
Result = C.RealTy;
break;
case DeclSpec::TST_doubleprecision:
Result = C.DoublePrecisionTy;
break;
case DeclSpec::TST_character:
Result = C.CharacterTy;
break;
case DeclSpec::TST_logical:
Result = C.LogicalTy;
break;
case DeclSpec::TST_complex:
Result = C.ComplexTy;
break;
case DeclSpec::TST_struct:
// FIXME: Finish this.
break;
}
if (!DS.hasAttributes())
return Result;
const Type *TypeNode = Result.getTypePtr();
Qualifiers Quals = Qualifiers::fromOpaqueValue(DS.getAttributeSpecs());
Quals.setIntentAttr(DS.getIntentSpec());
Quals.setAccessAttr(DS.getAccessSpec());
QualType EQs = C.getExtQualType(TypeNode, Quals, DS.getKindSelector(),
DS.getLengthSelector());
if (!Quals.hasAttributeSpec(Qualifiers::AS_dimension))
return EQs;
return ActOnArraySpec(C, EQs, DS.getDimensions());
}
示例5: writeAST
void DepGenerator::writeAST(const AST& ast, StringBuilder& output, unsigned indent) const {
if (showExternals) {
for (unsigned i=0; i<ast.numImports(); i++) {
const ImportDecl* U = ast.getImport(i);
QualType Q = U->getType();
const ModuleType* T = cast<ModuleType>(Q.getTypePtr());
const Module* P = T->getModule();
assert(P);
if (P->isExternal()) addExternal(P);
}
}
for (unsigned i=0; i<ast.numTypes(); i++) {
writeDecl(ast.getType(i), output, indent);
}
for (unsigned i=0; i<ast.numVars(); i++) {
writeDecl(ast.getVar(i), output, indent);
}
for (unsigned i=0; i<ast.numFunctions(); i++) {
writeDecl(ast.getFunction(i), output, indent);
}
}
示例6: mangleVariableEncoding
void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
// <type-encoding> ::= <storage-class> <variable-type>
// <storage-class> ::= 0 # private static member
// ::= 1 # protected static member
// ::= 2 # public static member
// ::= 3 # global
// ::= 4 # static local
// The first character in the encoding (after the name) is the storage class.
if (VD->isStaticDataMember()) {
// If it's a static member, it also encodes the access level.
switch (VD->getAccess()) {
default:
case AS_private: Out << '0'; break;
case AS_protected: Out << '1'; break;
case AS_public: Out << '2'; break;
}
}
else if (!VD->isStaticLocal())
Out << '3';
else
Out << '4';
// Now mangle the type.
// <variable-type> ::= <type> <cvr-qualifiers>
// ::= <type> A # pointers, references, arrays
// Pointers and references are odd. The type of 'int * const foo;' gets
// mangled as 'QAHA' instead of 'PAHB', for example.
QualType Ty = VD->getType();
if (Ty->isPointerType() || Ty->isReferenceType()) {
mangleType(Ty);
Out << 'A';
} else if (Ty->isArrayType()) {
// Global arrays are funny, too.
mangleType(cast<ArrayType>(Ty.getTypePtr()), true);
Out << 'A';
} else {
mangleType(Ty.getLocalUnqualifiedType());
mangleQualifiers(Ty.getLocalQualifiers(), false);
}
}
示例7: isRefType
bool cocoa::isRefType(QualType RetTy, StringRef Prefix,
StringRef Name) {
// Recursively walk the typedef stack, allowing typedefs of reference types.
while (const TypedefType *TD = dyn_cast<TypedefType>(RetTy.getTypePtr())) {
StringRef TDName = TD->getDecl()->getIdentifier()->getName();
if (TDName.startswith(Prefix) && TDName.endswith("Ref"))
return true;
RetTy = TD->getDecl()->getUnderlyingType();
}
if (Name.empty())
return false;
// Is the type void*?
const PointerType* PT = RetTy->getAs<PointerType>();
if (!(PT->getPointeeType().getUnqualifiedType()->isVoidType()))
return false;
// Does the name start with the prefix?
return Name.startswith(Prefix);
}
示例8: VisitBinAssign
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
// For an assignment to work, the value on the right has
// to be compatible with the value on the left.
assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
E->getRHS()->getType())
&& "Invalid assignment");
LValue LHS = CGF.EmitLValue(E->getLHS());
// We have to special case property setters, otherwise we must have
// a simple lvalue (no aggregates inside vectors, bitfields).
if (LHS.isPropertyRef()) {
llvm::Value *AggLoc = DestPtr;
if (!AggLoc)
AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
RValue::getAggregate(AggLoc, VolatileDest));
} else if (LHS.isKVCRef()) {
llvm::Value *AggLoc = DestPtr;
if (!AggLoc)
AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
RValue::getAggregate(AggLoc, VolatileDest));
} else {
bool RequiresGCollection = false;
if (CGF.getContext().getLangOptions().NeXTRuntime) {
QualType LHSTy = E->getLHS()->getType();
if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>())
RequiresGCollection = FDTTy->getDecl()->hasObjectMember();
}
// Codegen the RHS so that it stores directly into the LHS.
CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
false, false, RequiresGCollection);
EmitFinalDestCopy(E, LHS, true);
}
}
示例9: getTypeString
bool InstantiateTemplateParam::getTypeString(
const QualType &QT, std::string &Str, std::string &ForwardStr)
{
const Type *Ty = QT.getTypePtr();
Type::TypeClass TC = Ty->getTypeClass();
switch (TC) {
case Type::Elaborated: {
const ElaboratedType *ETy = dyn_cast<ElaboratedType>(Ty);
return getTypeString(ETy->getNamedType(), Str, ForwardStr);
}
case Type::Typedef: {
const TypedefType *TdefTy = dyn_cast<TypedefType>(Ty);
const TypedefNameDecl *TdefD = TdefTy->getDecl();
return getTypeString(TdefD->getUnderlyingType(), Str, ForwardStr);
}
case Type::Record: {
RecordDeclSet TempAvailableRecordDecls;
getForwardDeclStr(Ty, ForwardStr, TempAvailableRecordDecls);
QT.getAsStringInternal(Str, Context->getPrintingPolicy());
return true;
}
case Type::Builtin: {
QT.getAsStringInternal(Str, Context->getPrintingPolicy());
return true;
}
default:
return false;
}
TransAssert(0 && "Unreachable code!");
return false;
}
示例10: EmitComplexBinOpLibCall
/// \brief Emit a libcall for a binary operation on complex types.
ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
const BinOpInfo &Op) {
CallArgList Args;
Args.add(RValue::get(Op.LHS.first),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.LHS.second),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.RHS.first),
Op.Ty->castAs<ComplexType>()->getElementType());
Args.add(RValue::get(Op.RHS.second),
Op.Ty->castAs<ComplexType>()->getElementType());
// We *must* use the full CG function call building logic here because the
// complex type has special ABI handling. We also should not forget about
// special calling convention which may be used for compiler builtins.
// We create a function qualified type to state that this call does not have
// any exceptions.
FunctionProtoType::ExtProtoInfo EPI;
EPI = EPI.withExceptionSpec(
FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept));
SmallVector<QualType, 4> ArgsQTys(
4, Op.Ty->castAs<ComplexType>()->getElementType());
QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI);
const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall(
Args, cast<FunctionType>(FQTy.getTypePtr()), false);
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>());
llvm::Instruction *Call;
RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call);
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
return Res.getComplexVal();
}
示例11: EmitCXXTryStmt
//.........这里部分代码省略.........
VarDecl *CatchParam = C->getExceptionDecl();
Stmt *CatchBody = C->getHandlerBlock();
llvm::BasicBlock *Next = 0;
if (SelectorArgs[i+2] != Null) {
llvm::BasicBlock *Match = createBasicBlock("match");
Next = createBasicBlock("catch.next");
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
llvm::Value *Id
= Builder.CreateCall(llvm_eh_typeid_for,
Builder.CreateBitCast(SelectorArgs[i+2],
Int8PtrTy));
Builder.CreateCondBr(Builder.CreateICmpEQ(Selector, Id),
Match, Next);
EmitBlock(Match);
}
llvm::BasicBlock *MatchEnd = createBasicBlock("match.end");
llvm::BasicBlock *MatchHandler = createBasicBlock("match.handler");
PushCleanupBlock(MatchEnd);
setInvokeDest(MatchHandler);
llvm::Value *ExcObject = Builder.CreateCall(getBeginCatchFn(*this), Exc);
{
CleanupScope CatchScope(*this);
// Bind the catch parameter if it exists.
if (CatchParam) {
QualType CatchType = CatchParam->getType().getNonReferenceType();
setInvokeDest(TerminateHandler);
bool WasPointer = true;
if (!CatchType.getTypePtr()->isPointerType()) {
if (!isa<ReferenceType>(CatchParam->getType()))
WasPointer = false;
CatchType = getContext().getPointerType(CatchType);
}
ExcObject = Builder.CreateBitCast(ExcObject, ConvertType(CatchType));
EmitLocalBlockVarDecl(*CatchParam);
// FIXME: we need to do this sooner so that the EH region for the
// cleanup doesn't start until after the ctor completes, use a decl
// init?
CopyObject(*this, CatchParam->getType().getNonReferenceType(),
WasPointer, ExcObject, GetAddrOfLocalVar(CatchParam));
setInvokeDest(MatchHandler);
}
EmitStmt(CatchBody);
}
EmitBranchThroughCleanup(FinallyEnd);
EmitBlock(MatchHandler);
llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
// We are required to emit this call to satisfy LLVM, even
// though we don't use the result.
Args.clear();
Args.push_back(Exc);
Args.push_back(Personality);
Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
0));
Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
Builder.CreateStore(Exc, RethrowPtr);
EmitBranchThroughCleanup(FinallyRethrow);
示例12: VisitType
//.........这里部分代码省略.........
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;
return;
}
// If we have already seen this (non-built-in) type, use a substitution
// encoding.
llvm::DenseMap<const Type *, unsigned>::iterator Substitution
= TypeSubstitutions.find(T.getTypePtr());
if (Substitution != TypeSubstitutions.end()) {
Out << 'S' << Substitution->second << '_';
return;
} else {
// Record this as a substitution.
unsigned Number = TypeSubstitutions.size();
TypeSubstitutions[T.getTypePtr()] = Number;
}
if (const PointerType *PT = T->getAs<PointerType>()) {
Out << '*';
T = PT->getPointeeType();
continue;
}
if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
Out << '*';
T = OPT->getPointeeType();
continue;
}
if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
Out << "&&";
T = RT->getPointeeType();
continue;
}
if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
Out << '&';
T = RT->getPointeeType();
continue;
}
if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
Out << 'F';
VisitType(FT->getReturnType());
示例13: Found
//.........这里部分代码省略.........
<< Name << LookupCtx << Found.getLookupName() << SS.getRange()
<< CodeModificationHint::CreateReplacement(Found.getNameLoc(),
Found.getLookupName().getAsString());
else
Diag(Found.getNameLoc(), diag::err_undeclared_var_use_suggest)
<< Name << Found.getLookupName()
<< CodeModificationHint::CreateReplacement(Found.getNameLoc(),
Found.getLookupName().getAsString());
if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
Diag(ND->getLocation(), diag::note_previous_decl)
<< ND->getDeclName();
} else
Found.clear();
}
NamedDecl *SD = Found.getAsSingle<NamedDecl>();
if (isAcceptableNestedNameSpecifier(SD)) {
if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
// C++ [basic.lookup.classref]p4:
// [...] If the name is found in both contexts, the
// class-name-or-namespace-name shall refer to the same entity.
//
// We already found the name in the scope of the object. Now, look
// into the current scope (the scope of the postfix-expression) to
// see if we can find the same name there. As above, if there is no
// scope, reconstruct the result from the template instantiation itself.
NamedDecl *OuterDecl;
if (S) {
LookupResult FoundOuter(*this, &II, IdLoc, LookupNestedNameSpecifierName);
LookupName(FoundOuter, S);
OuterDecl = FoundOuter.getAsSingle<NamedDecl>();
} else
OuterDecl = ScopeLookupResult;
if (isAcceptableNestedNameSpecifier(OuterDecl) &&
OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
(!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
!Context.hasSameType(
Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
if (ErrorRecoveryLookup)
return 0;
Diag(IdLoc, diag::err_nested_name_member_ref_lookup_ambiguous)
<< &II;
Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
<< ObjectType;
Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
// Fall through so that we'll pick the name we found in the object
// type, since that's probably what the user wanted anyway.
}
}
if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD))
return NestedNameSpecifier::Create(Context, Prefix, Namespace);
// FIXME: It would be nice to maintain the namespace alias name, then
// see through that alias when resolving the nested-name-specifier down to
// a declaration context.
if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD))
return NestedNameSpecifier::Create(Context, Prefix,
Alias->getNamespace());
QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
return NestedNameSpecifier::Create(Context, Prefix, false,
T.getTypePtr());
}
// Otherwise, we have an error case. If we don't want diagnostics, just
// return an error now.
if (ErrorRecoveryLookup)
return 0;
// If we didn't find anything during our lookup, try again with
// ordinary name lookup, which can help us produce better error
// messages.
if (Found.empty()) {
Found.clear(LookupOrdinaryName);
LookupName(Found, S);
}
unsigned DiagID;
if (!Found.empty())
DiagID = diag::err_expected_class_or_namespace;
else if (SS.isSet()) {
Diag(IdLoc, diag::err_no_member) << &II << LookupCtx << SS.getRange();
return 0;
} else
DiagID = diag::err_undeclared_var_use;
if (SS.isSet())
Diag(IdLoc, DiagID) << &II << SS.getRange();
else
Diag(IdLoc, DiagID) << &II;
return 0;
}
示例14: getFullyQualifiedType
/// \brief Return the fully qualified type, including fully-qualified
/// versions of any template parameters.
QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx) {
// In case of myType* we need to strip the pointer first, fully
// qualify and attach the pointer once again.
if (isa<PointerType>(QT.getTypePtr())) {
// Get the qualifiers.
Qualifiers Quals = QT.getQualifiers();
QT = getFullyQualifiedType(QT->getPointeeType(), Ctx);
QT = Ctx.getPointerType(QT);
// Add back the qualifiers.
QT = Ctx.getQualifiedType(QT, Quals);
return QT;
}
// In case of myType& we need to strip the reference first, fully
// qualify and attach the reference once again.
if (isa<ReferenceType>(QT.getTypePtr())) {
// Get the qualifiers.
bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
Qualifiers Quals = QT.getQualifiers();
QT = getFullyQualifiedType(QT->getPointeeType(), Ctx);
// Add the r- or l-value reference type back to the fully
// qualified one.
if (IsLValueRefTy)
QT = Ctx.getLValueReferenceType(QT);
else
QT = Ctx.getRValueReferenceType(QT);
// Add back the qualifiers.
QT = Ctx.getQualifiedType(QT, Quals);
return QT;
}
// Remove the part of the type related to the type being a template
// parameter (we won't report it as part of the 'type name' and it
// is actually make the code below to be more complex (to handle
// those)
while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
// Get the qualifiers.
Qualifiers Quals = QT.getQualifiers();
QT = dyn_cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
// Add back the qualifiers.
QT = Ctx.getQualifiedType(QT, Quals);
}
NestedNameSpecifier *Prefix = nullptr;
Qualifiers PrefixQualifiers;
ElaboratedTypeKeyword Keyword = ETK_None;
if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
QT = ETypeInput->getNamedType();
Keyword = ETypeInput->getKeyword();
}
// Create a nested name specifier if needed (i.e. if the decl context
// is not the global scope.
Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
true /*FullyQualified*/);
// move the qualifiers on the outer type (avoid 'std::const string'!)
if (Prefix) {
PrefixQualifiers = QT.getLocalQualifiers();
QT = QualType(QT.getTypePtr(), 0);
}
// In case of template specializations iterate over the arguments and
// fully qualify them as well.
if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
isa<const RecordType>(QT.getTypePtr())) {
// We are asked to fully qualify and we have a Record Type (which
// may pont to a template specialization) or Template
// Specialization Type. We need to fully qualify their arguments.
Qualifiers Quals = QT.getLocalQualifiers();
const Type *TypePtr = getFullyQualifiedTemplateType(Ctx, QT.getTypePtr());
QT = Ctx.getQualifiedType(TypePtr, Quals);
}
if (Prefix || Keyword != ETK_None) {
QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
}
return QT;
}
示例15: lookupPromiseType
/// Look up the std::coroutine_traits<...>::promise_type for the given
/// function type.
static QualType lookupPromiseType(Sema &S, const FunctionProtoType *FnType,
SourceLocation KwLoc,
SourceLocation FuncLoc) {
// FIXME: Cache std::coroutine_traits once we've found it.
NamespaceDecl *StdExp = S.lookupStdExperimentalNamespace();
if (!StdExp) {
S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
<< "std::experimental::coroutine_traits";
return QualType();
}
LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_traits"),
FuncLoc, Sema::LookupOrdinaryName);
if (!S.LookupQualifiedName(Result, StdExp)) {
S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
<< "std::experimental::coroutine_traits";
return QualType();
}
ClassTemplateDecl *CoroTraits = Result.getAsSingle<ClassTemplateDecl>();
if (!CoroTraits) {
Result.suppressDiagnostics();
// We found something weird. Complain about the first thing we found.
NamedDecl *Found = *Result.begin();
S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
return QualType();
}
// Form template argument list for coroutine_traits<R, P1, P2, ...>.
TemplateArgumentListInfo Args(KwLoc, KwLoc);
Args.addArgument(TemplateArgumentLoc(
TemplateArgument(FnType->getReturnType()),
S.Context.getTrivialTypeSourceInfo(FnType->getReturnType(), KwLoc)));
// FIXME: If the function is a non-static member function, add the type
// of the implicit object parameter before the formal parameters.
for (QualType T : FnType->getParamTypes())
Args.addArgument(TemplateArgumentLoc(
TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, KwLoc)));
// Build the template-id.
QualType CoroTrait =
S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args);
if (CoroTrait.isNull())
return QualType();
if (S.RequireCompleteType(KwLoc, CoroTrait,
diag::err_coroutine_type_missing_specialization))
return QualType();
auto *RD = CoroTrait->getAsCXXRecordDecl();
assert(RD && "specialization of class template is not a class?");
// Look up the ::promise_type member.
LookupResult R(S, &S.PP.getIdentifierTable().get("promise_type"), KwLoc,
Sema::LookupOrdinaryName);
S.LookupQualifiedName(R, RD);
auto *Promise = R.getAsSingle<TypeDecl>();
if (!Promise) {
S.Diag(FuncLoc,
diag::err_implied_std_coroutine_traits_promise_type_not_found)
<< RD;
return QualType();
}
// The promise type is required to be a class type.
QualType PromiseType = S.Context.getTypeDeclType(Promise);
auto buildElaboratedType = [&]() {
auto *NNS = NestedNameSpecifier::Create(S.Context, nullptr, StdExp);
NNS = NestedNameSpecifier::Create(S.Context, NNS, false,
CoroTrait.getTypePtr());
return S.Context.getElaboratedType(ETK_None, NNS, PromiseType);
};
if (!PromiseType->getAsCXXRecordDecl()) {
S.Diag(FuncLoc,
diag::err_implied_std_coroutine_traits_promise_type_not_class)
<< buildElaboratedType();
return QualType();
}
if (S.RequireCompleteType(FuncLoc, buildElaboratedType(),
diag::err_coroutine_promise_type_incomplete))
return QualType();
return PromiseType;
}