diff options
Diffstat (limited to 'lib/AST/TypePrinter.cpp')
| -rw-r--r-- | lib/AST/TypePrinter.cpp | 192 |
1 files changed, 115 insertions, 77 deletions
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index b202523bdaf3..065a2db09141 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -81,12 +81,14 @@ namespace { class TypePrinter { PrintingPolicy Policy; + unsigned Indentation; bool HasEmptyPlaceHolder; bool InsideCCAttribute; public: - explicit TypePrinter(const PrintingPolicy &Policy) - : Policy(Policy), HasEmptyPlaceHolder(false), InsideCCAttribute(false) { } + explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0) + : Policy(Policy), Indentation(Indentation), + HasEmptyPlaceHolder(false), InsideCCAttribute(false) { } void print(const Type *ty, Qualifiers qs, raw_ostream &OS, StringRef PlaceHolder); @@ -110,7 +112,8 @@ namespace { }; } -static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool C99) { +static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, + bool HasRestrictKeyword) { bool appendSpace = false; if (TypeQuals & Qualifiers::Const) { OS << "const"; @@ -123,7 +126,7 @@ static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool C99) { } if (TypeQuals & Qualifiers::Restrict) { if (appendSpace) OS << ' '; - if (C99) { + if (HasRestrictKeyword) { OS << "restrict"; } else { OS << "__restrict"; @@ -411,7 +414,7 @@ void TypePrinter::printMemberPointerBefore(const MemberPointerType *T, OS << '('; PrintingPolicy InnerPolicy(Policy); - InnerPolicy.SuppressTag = false; + InnerPolicy.IncludeTagDefinition = false; TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef()); OS << "::*"; @@ -437,7 +440,8 @@ void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T, raw_ostream &OS) { OS << '['; if (T->getIndexTypeQualifiers().hasQualifiers()) { - AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99); + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), + Policy.Restrict); OS << ' '; } @@ -470,7 +474,7 @@ void TypePrinter::printVariableArrayAfter(const VariableArrayType *T, raw_ostream &OS) { OS << '['; if (T->getIndexTypeQualifiers().hasQualifiers()) { - AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99); + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict); OS << ' '; } @@ -629,6 +633,20 @@ void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T, } } +llvm::StringRef clang::getParameterABISpelling(ParameterABI ABI) { + switch (ABI) { + case ParameterABI::Ordinary: + llvm_unreachable("asking for spelling of ordinary parameter ABI"); + case ParameterABI::SwiftContext: + return "swift_context"; + case ParameterABI::SwiftErrorResult: + return "swift_error_result"; + case ParameterABI::SwiftIndirectResult: + return "swift_indirect_result"; + } + llvm_unreachable("bad parameter ABI kind"); +} + void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, raw_ostream &OS) { // If needed for precedence reasons, wrap the inner part in grouping parens. @@ -641,6 +659,13 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, ParamPolicyRAII ParamPolicy(Policy); for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) { if (i) OS << ", "; + + auto EPI = T->getExtParameterInfo(i); + if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) "; + auto ABI = EPI.getABI(); + if (ABI != ParameterABI::Ordinary) + OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) "; + print(T->getParamType(i), OS, StringRef()); } } @@ -649,7 +674,7 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, if (T->getNumParams()) OS << ", "; OS << "..."; - } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) { + } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) { // Do not emit int() if we have a proto, emit 'int(void)'. OS << "void"; } @@ -700,9 +725,18 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, OS << " __attribute__((sysv_abi))"; break; case CC_SpirFunction: - case CC_SpirKernel: + case CC_OpenCLKernel: // Do nothing. These CCs are not available as attributes. break; + case CC_Swift: + OS << " __attribute__((swiftcall))"; + break; + case CC_PreserveMost: + OS << " __attribute__((preserve_most))"; + break; + case CC_PreserveAll: + OS << " __attribute__((preserve_all))"; + break; } } @@ -714,7 +748,7 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, if (unsigned quals = T->getTypeQuals()) { OS << ' '; - AppendTypeQualList(OS, quals, Policy.LangOpts.C99); + AppendTypeQualList(OS, quals, Policy.Restrict); } switch (T->getRefQualifier()) { @@ -863,7 +897,8 @@ void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { } void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); - OS << "pipe"; + OS << "pipe "; + print(T->getElementType(), OS, StringRef()); spaceBeforePlaceHolder(OS); } @@ -888,10 +923,8 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); OS << Spec->getIdentifier()->getName(); const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - TemplateSpecializationType::PrintTemplateArgumentList(OS, - TemplateArgs.data(), - TemplateArgs.size(), - Policy); + TemplateSpecializationType::PrintTemplateArgumentList( + OS, TemplateArgs.asArray(), Policy); OS << "::"; } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl()) @@ -904,18 +937,19 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { } void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { - if (Policy.SuppressTag) + if (Policy.IncludeTagDefinition) { + PrintingPolicy SubPolicy = Policy; + SubPolicy.IncludeTagDefinition = false; + D->print(OS, SubPolicy, Indentation); + spaceBeforePlaceHolder(OS); return; + } bool HasKindDecoration = false; - // bool SuppressTagKeyword - // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; - // We don't print tags unless this is an elaborated type. // In C, we just assume every RecordType is an elaborated type. - if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || - D->getTypedefNameForAnonDecl())) { + if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) { HasKindDecoration = true; OS << D->getKindName(); OS << ' '; @@ -967,22 +1001,17 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { // arguments. if (ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateArgument *Args; - unsigned NumArgs; + ArrayRef<TemplateArgument> Args; if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { const TemplateSpecializationType *TST = cast<TemplateSpecializationType>(TAW->getType()); - Args = TST->getArgs(); - NumArgs = TST->getNumArgs(); + Args = TST->template_arguments(); } else { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - Args = TemplateArgs.data(); - NumArgs = TemplateArgs.size(); + Args = TemplateArgs.asArray(); } IncludeStrongLifetimeRAII Strong(Policy); - TemplateSpecializationType::PrintTemplateArgumentList(OS, - Args, NumArgs, - Policy); + TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, Policy); } spaceBeforePlaceHolder(OS); @@ -1040,11 +1069,9 @@ void TypePrinter::printTemplateSpecializationBefore( raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); T->getTemplateName().print(OS, Policy); - - TemplateSpecializationType::PrintTemplateArgumentList(OS, - T->getArgs(), - T->getNumArgs(), - Policy); + + TemplateSpecializationType::PrintTemplateArgumentList( + OS, T->template_arguments(), Policy); spaceBeforePlaceHolder(OS); } void TypePrinter::printTemplateSpecializationAfter( @@ -1060,14 +1087,16 @@ void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T, void TypePrinter::printElaboratedBefore(const ElaboratedType *T, raw_ostream &OS) { - if (Policy.SuppressTag && isa<TagType>(T->getNamedType())) - return; - OS << TypeWithKeyword::getKeywordName(T->getKeyword()); - if (T->getKeyword() != ETK_None) - OS << " "; - NestedNameSpecifier* Qualifier = T->getQualifier(); - if (Qualifier) - Qualifier->print(OS, Policy); + // The tag definition will take care of these. + if (!Policy.IncludeTagDefinition) + { + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; + NestedNameSpecifier* Qualifier = T->getQualifier(); + if (Qualifier) + Qualifier->print(OS, Policy); + } ElaboratedTypePolicyRAII PolicyRAII(Policy); printBefore(T->getNamedType(), OS); @@ -1119,8 +1148,7 @@ void TypePrinter::printDependentTemplateSpecializationBefore( T->getQualifier()->print(OS, Policy); OS << T->getIdentifier()->getName(); TemplateSpecializationType::PrintTemplateArgumentList(OS, - T->getArgs(), - T->getNumArgs(), + T->template_arguments(), Policy); spaceBeforePlaceHolder(OS); } @@ -1305,6 +1333,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case AttributedType::attr_fastcall: OS << "fastcall"; break; case AttributedType::attr_stdcall: OS << "stdcall"; break; case AttributedType::attr_thiscall: OS << "thiscall"; break; + case AttributedType::attr_swiftcall: OS << "swiftcall"; break; case AttributedType::attr_vectorcall: OS << "vectorcall"; break; case AttributedType::attr_pascal: OS << "pascal"; break; case AttributedType::attr_ms_abi: OS << "ms_abi"; break; @@ -1321,6 +1350,12 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, break; } case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; + case AttributedType::attr_preserve_most: + OS << "preserve_most"; + break; + case AttributedType::attr_preserve_all: + OS << "preserve_all"; + break; } OS << "))"; } @@ -1400,50 +1435,46 @@ void TemplateSpecializationType:: const TemplateArgumentListInfo &Args, const PrintingPolicy &Policy) { return PrintTemplateArgumentList(OS, - Args.getArgumentArray(), - Args.size(), + Args.arguments(), Policy); } -void -TemplateSpecializationType::PrintTemplateArgumentList( - raw_ostream &OS, - const TemplateArgument *Args, - unsigned NumArgs, - const PrintingPolicy &Policy, - bool SkipBrackets) { +void TemplateSpecializationType::PrintTemplateArgumentList( + raw_ostream &OS, ArrayRef<TemplateArgument> Args, + const PrintingPolicy &Policy, bool SkipBrackets) { const char *Comma = Policy.MSVCFormatting ? "," : ", "; if (!SkipBrackets) OS << '<'; - + bool needSpace = false; - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + bool FirstArg = true; + for (const TemplateArgument &Arg : Args) { // Print the argument into a string. SmallString<128> Buf; llvm::raw_svector_ostream ArgOS(Buf); - if (Args[Arg].getKind() == TemplateArgument::Pack) { - if (Args[Arg].pack_size() && Arg > 0) + if (Arg.getKind() == TemplateArgument::Pack) { + if (Arg.pack_size() && !FirstArg) OS << Comma; PrintTemplateArgumentList(ArgOS, - Args[Arg].pack_begin(), - Args[Arg].pack_size(), + Arg.getPackAsArray(), Policy, true); } else { - if (Arg > 0) + if (!FirstArg) OS << Comma; - Args[Arg].print(Policy, ArgOS); + Arg.print(Policy, ArgOS); } StringRef ArgString = ArgOS.str(); // If this is the first argument and its string representation // begins with the global scope specifier ('::foo'), add a space // to avoid printing the diagraph '<:'. - if (!Arg && !ArgString.empty() && ArgString[0] == ':') + if (FirstArg && !ArgString.empty() && ArgString[0] == ':') OS << ' '; OS << ArgString; needSpace = (!ArgString.empty() && ArgString.back() == '>'); + FirstArg = false; } // If the last character of our string is '>', add another space to @@ -1459,40 +1490,41 @@ TemplateSpecializationType::PrintTemplateArgumentList( // Sadly, repeat all that with TemplateArgLoc. void TemplateSpecializationType:: PrintTemplateArgumentList(raw_ostream &OS, - const TemplateArgumentLoc *Args, unsigned NumArgs, + ArrayRef<TemplateArgumentLoc> Args, const PrintingPolicy &Policy) { OS << '<'; const char *Comma = Policy.MSVCFormatting ? "," : ", "; bool needSpace = false; - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { - if (Arg > 0) + bool FirstArg = true; + for (const TemplateArgumentLoc &Arg : Args) { + if (!FirstArg) OS << Comma; - + // Print the argument into a string. SmallString<128> Buf; llvm::raw_svector_ostream ArgOS(Buf); - if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) { + if (Arg.getArgument().getKind() == TemplateArgument::Pack) { PrintTemplateArgumentList(ArgOS, - Args[Arg].getArgument().pack_begin(), - Args[Arg].getArgument().pack_size(), + Arg.getArgument().getPackAsArray(), Policy, true); } else { - Args[Arg].getArgument().print(Policy, ArgOS); + Arg.getArgument().print(Policy, ArgOS); } StringRef ArgString = ArgOS.str(); - + // If this is the first argument and its string representation // begins with the global scope specifier ('::foo'), add a space // to avoid printing the diagraph '<:'. - if (!Arg && !ArgString.empty() && ArgString[0] == ':') + if (FirstArg && !ArgString.empty() && ArgString[0] == ':') OS << ' '; OS << ArgString; needSpace = (!ArgString.empty() && ArgString.back() == '>'); + FirstArg = false; } - + // If the last character of our string is '>', add another space to // keep the two '>''s separate tokens. We don't *have* to do this in // C++0x, but it's still good hygiene. @@ -1543,7 +1575,13 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, unsigned quals = getCVRQualifiers(); if (quals) { - AppendTypeQualList(OS, quals, Policy.LangOpts.C99); + AppendTypeQualList(OS, quals, Policy.Restrict); + addSpace = true; + } + if (hasUnaligned()) { + if (addSpace) + OS << ' '; + OS << "__unaligned"; addSpace = true; } if (unsigned addrspace = getAddressSpace()) { @@ -1617,11 +1655,11 @@ std::string QualType::getAsString(const Type *ty, Qualifiers qs) { void QualType::print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, - const Twine &PlaceHolder) { + const Twine &PlaceHolder, unsigned Indentation) { SmallString<128> PHBuf; StringRef PH = PlaceHolder.toStringRef(PHBuf); - TypePrinter(policy).print(ty, qs, OS, PH); + TypePrinter(policy, Indentation).print(ty, qs, OS, PH); } void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, |
