/// ComputeQualifierFlags - Compute the pointer type info flags from the /// given qualifier. static unsigned ComputeQualifierFlags(Qualifiers Quals) { unsigned Flags = 0; if (Quals.hasConst()) Flags |= RTTIBuilder::PTI_Const; if (Quals.hasVolatile()) Flags |= RTTIBuilder::PTI_Volatile; if (Quals.hasRestrict()) Flags |= RTTIBuilder::PTI_Restrict; return Flags; }
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; } // 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 ReferenceType *RT = T->getAs<ReferenceType>()) { Out << '&'; T = RT->getPointeeType(); continue; } if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { Out << 'F'; VisitType(FT->getResultType()); for (FunctionProtoType::arg_type_iterator I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) { VisitType(*I); } if (FT->isVariadic()) Out << '.'; return; } if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { Out << 'B'; T = BT->getPointeeType(); continue; } if (const ComplexType *CT = T->getAs<ComplexType>()) { Out << '<'; T = CT->getElementType(); continue; } if (const TagType *TT = T->getAs<TagType>()) { Out << '$'; VisitTagDecl(TT->getDecl()); return; } if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); return; } if (const TemplateSpecializationType *Spec = T->getAs<TemplateSpecializationType>()) { Out << '>'; VisitTemplateName(Spec->getTemplateName()); Out << Spec->getNumArgs(); for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) VisitTemplateArgument(Spec->getArg(I)); return; } // Unhandled type. Out << ' '; break; } while (true); }
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; 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()); for (const auto &I : FT->param_types()) VisitType(I); if (FT->isVariadic()) Out << '.'; return; } if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { Out << 'B'; T = BT->getPointeeType(); continue; } if (const ComplexType *CT = T->getAs<ComplexType>()) { Out << '<'; T = CT->getElementType(); continue; } if (const TagType *TT = T->getAs<TagType>()) { Out << '$'; VisitTagDecl(TT->getDecl()); return; } if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) { Out << '$'; VisitObjCInterfaceDecl(OIT->getDecl()); return; } if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) { Out << 'Q'; VisitType(OIT->getBaseType()); for (auto *Prot : OIT->getProtocols()) VisitObjCProtocolDecl(Prot); return; } if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); return; } if (const TemplateSpecializationType *Spec = T->getAs<TemplateSpecializationType>()) { Out << '>'; VisitTemplateName(Spec->getTemplateName()); Out << Spec->getNumArgs(); for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) VisitTemplateArgument(Spec->getArg(I)); return; } if (const DependentNameType *DNT = T->getAs<DependentNameType>()) { Out << '^'; // FIXME: Encode the qualifier, don't just print it. PrintingPolicy PO(Ctx.getLangOpts()); PO.SuppressTagKeyword = true; PO.SuppressUnwrittenScope = true; PO.ConstantArraySizeAsWritten = false; PO.AnonymousTagLocations = false; DNT->getQualifier()->print(Out, PO); Out << ':' << DNT->getIdentifier()->getName(); return; } if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) { T = InjT->getInjectedSpecializationType(); continue; } // Unhandled type. Out << ' '; break; } while (true); }