void SpecifierTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { if (getKind() == TypeReprKind::InOut) { Printer.printKeyword("inout"); } else { assert((getKind() == TypeReprKind::Shared) && "Unknown kind"); Printer.printKeyword("shared"); } Printer << " "; printTypeRepr(Base, Printer, Opts); }
void FunctionTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { Printer.callPrintStructurePre(PrintStructureKind::FunctionType); printTypeRepr(ArgsTy, Printer, Opts); if (throws()) { Printer << " "; Printer.printKeyword("throws"); } Printer << " -> "; Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType); printTypeRepr(RetTy, Printer, Opts); Printer.printStructurePost(PrintStructureKind::FunctionReturnType); Printer.printStructurePost(PrintStructureKind::FunctionType); }
void ComponentIdentTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(getBoundDecl())) { if (auto MD = dyn_cast<ModuleDecl>(TD)) Printer.printModuleRef(MD, getIdentifier()); else Printer.printTypeRef(Type(), TD, getIdentifier()); } else { Printer.printName(getIdentifier()); } if (auto GenIdT = dyn_cast<GenericIdentTypeRepr>(this)) printGenericArgs(Printer, Opts, GenIdT->getGenericArgs()); }
void TypeRepr::print(ASTPrinter &Printer, const PrintOptions &Opts) const { Printer.printTypePre(TypeLoc(const_cast<TypeRepr *>(this))); SWIFT_DEFER { Printer.printTypePost(TypeLoc(const_cast<TypeRepr *>(this))); }; switch (getKind()) { #define TYPEREPR(CLASS, PARENT) \ case TypeReprKind::CLASS: { \ auto Ty = static_cast<const CLASS##TypeRepr*>(this); \ return Ty->printImpl(Printer, Opts); \ } #include "swift/AST/TypeReprNodes.def" } llvm_unreachable("unknown kind!"); }
void NamedTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { if (!Id.empty()) { Printer.printName(Id, PrintNameContext::TupleElement); Printer << ": "; } printTypeRepr(Ty, Printer, Opts); }
void TupleTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { Printer.callPrintStructurePre(PrintStructureKind::TupleType); SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::TupleType); }; Printer << "("; for (unsigned i = 0, e = Bits.TupleTypeRepr.NumElements; i != e; ++i) { if (i) Printer << ", "; Printer.callPrintStructurePre(PrintStructureKind::TupleElement); auto name = getElementName(i); if (isNamedParameter(i)) { // Printing empty Identifier is same as printing '_'. Printer.printName(Identifier(), PrintNameContext::FunctionParameterExternal); if (!name.empty()) { Printer << " "; Printer.printName(name, PrintNameContext::FunctionParameterLocal); } Printer << ": "; } else { if (!name.empty()) { Printer.printName(name, PrintNameContext::TupleElement); Printer << ": "; } } printTypeRepr(getElementType(i), Printer, Opts); Printer.printStructurePost(PrintStructureKind::TupleElement); if (hasEllipsis() && getEllipsisIndex() == i) Printer << "..."; } Printer << ")"; }
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer, const PrintOptions &Options) const { const TypeAttributes &Attrs = getAttrs(); auto hasAttr = [&](TypeAttrKind K) -> bool { if (Options.excludeAttrKind(K)) return false; return Attrs.has(K); }; if (hasAttr(TAK_autoclosure)) Printer.printSimpleAttr("@autoclosure") << " "; if (hasAttr(TAK_escaping)) Printer.printSimpleAttr("@escaping") << " "; if (hasAttr(TAK_thin)) Printer.printSimpleAttr("@thin") << " "; if (hasAttr(TAK_thick)) Printer.printSimpleAttr("@thick") << " "; if (hasAttr(TAK_convention) && Attrs.convention.hasValue()) { Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); Printer.printAttrName("@convention"); Printer << "(" << Attrs.convention.getValue() << ")"; Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); Printer << " "; } }
void TupleTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { Printer.callPrintStructurePre(PrintStructureKind::TupleType); defer { Printer.printStructurePost(PrintStructureKind::TupleType); }; Printer << "("; for (unsigned i = 0, e = Elements.size(); i != e; ++i) { if (i) Printer << ", "; Printer.callPrintStructurePre(PrintStructureKind::TupleElement); printTypeRepr(Elements[i], Printer, Opts); Printer.printStructurePost(PrintStructureKind::TupleElement); if (hasEllipsis() && getEllipsisIndex() == i) Printer << "..."; } Printer << ")"; }
void TypeRepr::print(ASTPrinter &Printer, const PrintOptions &Opts) const { // The type part of a NamedTypeRepr will get the callback. if (!isa<NamedTypeRepr>(this)) Printer.printTypePre(TypeLoc(const_cast<TypeRepr *>(this))); defer { if (!isa<NamedTypeRepr>(this)) Printer.printTypePost(TypeLoc(const_cast<TypeRepr *>(this))); }; switch (getKind()) { #define TYPEREPR(CLASS, PARENT) \ case TypeReprKind::CLASS: { \ auto Ty = static_cast<const CLASS##TypeRepr*>(this); \ return Ty->printImpl(Printer, Opts); \ } #include "swift/AST/TypeReprNodes.def" } llvm_unreachable("unknown kind!"); }
void DeclAttribute::print(ASTPrinter &Printer, const PrintOptions &Options, const Decl *D) const { if (!printImpl(Printer, Options, D)) return; // Nothing printed. if (isLongAttribute() && Options.PrintLongAttrsOnSeparateLines) Printer.printNewline(); else Printer << " "; }
void swift::ide::printHeaderInterface( StringRef Filename, ASTContext &Ctx, ASTPrinter &Printer, const PrintOptions &Options) { auto AdjustedOptions = Options; adjustPrintOptions(AdjustedOptions); auto &Importer = static_cast<ClangImporter &>(*Ctx.getClangModuleLoader()); auto &ClangSM = Importer.getClangASTContext().getSourceManager(); auto headerFilter = [&](ClangNode ClangN) -> bool { return true; // no need for filtering. }; SmallVector<Decl *, 32> ClangDecls; llvm::SmallPtrSet<Decl *, 32> SeenDecls; auto headerReceiver = [&](Decl *D) { if (SeenDecls.count(D) == 0) { SeenDecls.insert(D); ClangDecls.push_back(D); } }; Importer.lookupDeclsFromHeader(Filename, headerFilter, headerReceiver); // Sort imported declarations in source order. std::sort(ClangDecls.begin(), ClangDecls.end(), [&](Decl *LHS, Decl *RHS) -> bool { return ClangSM.isBeforeInTranslationUnit( LHS->getClangNode().getLocation(), RHS->getClangNode().getLocation()); }); ASTPrinter *PrinterToUse = &Printer; ClangCommentPrinter RegularCommentPrinter(Printer, Importer); if (Options.PrintRegularClangComments) PrinterToUse = &RegularCommentPrinter; for (auto *D : ClangDecls) { ASTPrinter &Printer = *PrinterToUse; if (!shouldPrint(D, AdjustedOptions)) { Printer.avoidPrintDeclPost(D); continue; } if (D->print(Printer, AdjustedOptions)) Printer << "\n"; } }
/// Print the short-form @available() attribute for an array of long-form /// AvailableAttrs that can be represented in the short form. /// For example, for: /// @available(OSX, introduced=10.10) /// @available(iOS, introduced=8.0) /// this will print: /// @available(OSX 10.10, iOS 8.0, *) static void printShortFormAvailable(ArrayRef<const DeclAttribute *> Attrs, ASTPrinter &Printer, const PrintOptions &Options) { assert(!Attrs.empty()); Printer << "@available("; for (auto *DA : Attrs) { auto *AvailAttr = cast<AvailableAttr>(DA); assert(AvailAttr->Introduced.hasValue()); Printer << platformString(AvailAttr->Platform) << " " << AvailAttr->Introduced.getValue().getAsString() << ", "; } Printer << "*)"; Printer.printNewline(); }
/// Print the short-form @available() attribute for an array of long-form /// AvailableAttrs that can be represented in the short form. /// For example, for: /// @available(OSX, introduced: 10.10) /// @available(iOS, introduced: 8.0) /// this will print: /// @available(OSX 10.10, iOS 8.0, *) static void printShortFormAvailable(ArrayRef<const DeclAttribute *> Attrs, ASTPrinter &Printer, const PrintOptions &Options) { assert(!Attrs.empty()); Printer << "@available("; auto FirstAvail = cast<AvailableAttr>(Attrs.front()); if (Attrs.size() == 1 && FirstAvail->isLanguageVersionSpecific()) { assert(FirstAvail->Introduced.hasValue()); Printer << "swift " << FirstAvail->Introduced.getValue().getAsString() << ")"; } else { for (auto *DA : Attrs) { auto *AvailAttr = cast<AvailableAttr>(DA); assert(AvailAttr->Introduced.hasValue()); Printer << platformString(AvailAttr->Platform) << " " << AvailAttr->Introduced.getValue().getAsString() << ", "; } Printer << "*)"; } Printer.printNewline(); }
bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options, const Decl *D) const { // Handle any attributes that are not printed at all before we make printer // callbacks. switch (getKind()) { case DAK_ObjC: if (Options.PrintForSIL && isImplicit()) return false; break; case DAK_RawDocComment: case DAK_ObjCBridged: case DAK_SynthesizedProtocol: case DAK_ShowInInterface: case DAK_Rethrows: case DAK_Infix: return false; default: break; } // Handle any decl-modifiers. // FIXME: Ideally we would handle decl modifiers as a special kind of // attribute, but for now it's simpler to treat them as a keyword in the // printer. switch (getKind()) { // Handle all of the SIMPLE_DECL_ATTRs. #define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS: #include "swift/AST/Attr.def" case DAK_Inline: case DAK_AccessControl: case DAK_ReferenceOwnership: case DAK_Effects: case DAK_Optimize: if (DeclAttribute::isDeclModifier(getKind())) { Printer.printKeyword(getAttrName()); } else { Printer.printSimpleAttr(getAttrName(), /*needAt=*/true); } return true; case DAK_SetterAccess: Printer.printKeyword(getAttrName()); Printer << "(set)"; return true; default: break; } Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); }; switch (getKind()) { case DAK_Semantics: Printer.printAttrName("@_semantics"); Printer << "(\"" << cast<SemanticsAttr>(this)->Value << "\")"; break; case DAK_Alignment: Printer.printAttrName("@_alignment"); Printer << "(" << cast<AlignmentAttr>(this)->getValue() << ")"; break; case DAK_SILGenName: Printer.printAttrName("@_silgen_name"); Printer << "(\"" << cast<SILGenNameAttr>(this)->Name << "\")"; break; case DAK_Available: { Printer.printAttrName("@available"); Printer << "("; auto Attr = cast<AvailableAttr>(this); if (Attr->isLanguageVersionSpecific()) Printer << "swift"; else Printer << Attr->platformString(); if (Attr->isUnconditionallyUnavailable()) Printer << ", unavailable"; else if (Attr->isUnconditionallyDeprecated()) Printer << ", deprecated"; if (Attr->Introduced) Printer << ", introduced: " << Attr->Introduced.getValue().getAsString(); if (Attr->Deprecated) Printer << ", deprecated: " << Attr->Deprecated.getValue().getAsString(); if (Attr->Obsoleted) Printer << ", obsoleted: " << Attr->Obsoleted.getValue().getAsString(); if (!Attr->Rename.empty()) Printer << ", renamed: \"" << Attr->Rename << "\""; // If there's no message, but this is specifically an imported // "unavailable in Swift" attribute, synthesize a message to look good in // the generated interface. if (!Attr->Message.empty()) Printer << ", message: \"" << Attr->Message << "\""; else if (Attr->getPlatformAgnosticAvailability() == PlatformAgnosticAvailabilityKind::UnavailableInSwift) Printer << ", message: \"Not available in Swift\""; Printer << ")"; break; } case DAK_CDecl: Printer << "@_cdecl(\"" << cast<CDeclAttr>(this)->Name << "\")"; break; case DAK_ObjC: { Printer.printAttrName("@objc"); llvm::SmallString<32> scratch; if (auto Name = cast<ObjCAttr>(this)->getName()) { if (!cast<ObjCAttr>(this)->isNameImplicit()) Printer << "(" << Name->getString(scratch) << ")"; } break; } case DAK_SwiftNativeObjCRuntimeBase: { auto *attr = cast<SwiftNativeObjCRuntimeBaseAttr>(this); Printer.printAttrName("@_swift_native_objc_runtime_base"); Printer << "(" << attr->BaseClassName.str() << ")"; break; } case DAK_Specialize: { Printer << "@" << getAttrName() << "("; auto *attr = cast<SpecializeAttr>(this); auto exported = attr->isExported() ? "true" : "false"; auto kind = attr->isPartialSpecialization() ? "partial" : "full"; Printer << "exported: "<< exported << ", "; Printer << "kind: " << kind << ", "; if (!attr->getRequirements().empty()) { Printer << "where "; } std::function<Type(Type)> GetInterfaceType; auto *FnDecl = dyn_cast_or_null<AbstractFunctionDecl>(D); if (!FnDecl || !FnDecl->getGenericEnvironment()) GetInterfaceType = [](Type Ty) -> Type { return Ty; }; else { // Use GenericEnvironment to produce user-friendly // names instead of something like t_0_0. auto *GenericEnv = FnDecl->getGenericEnvironment(); assert(GenericEnv); GetInterfaceType = [=](Type Ty) -> Type { return GenericEnv->getSugaredType(Ty); }; } interleave(attr->getRequirements(), [&](Requirement req) { auto FirstTy = GetInterfaceType(req.getFirstType()); if (req.getKind() != RequirementKind::Layout) { auto SecondTy = GetInterfaceType(req.getSecondType()); Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy); ReqWithDecls.print(Printer, Options); } else { Requirement ReqWithDecls(req.getKind(), FirstTy, req.getLayoutConstraint()); ReqWithDecls.print(Printer, Options); } }, [&] { Printer << ", "; }); Printer << ")"; break; } case DAK_Implements: { Printer.printAttrName("@_implements"); Printer << "("; auto *attr = cast<ImplementsAttr>(this); attr->getProtocolType().getType().print(Printer, Options); Printer << ", " << attr->getMemberName() << ")"; break; } case DAK_ObjCRuntimeName: { Printer.printAttrName("@objc"); Printer << "("; auto *attr = cast<ObjCRuntimeNameAttr>(this); Printer << "\"" << attr->Name << "\""; Printer << ")"; break; } case DAK_ClangImporterSynthesizedType: { Printer.printAttrName("@_clangImporterSynthesizedType"); auto *attr = cast<ClangImporterSynthesizedTypeAttr>(this); Printer << "(originalTypeName: \"" << attr->originalTypeName << "\", manglingForKind: \"" << attr->getManglingName() << "\")"; break; } case DAK_Count: llvm_unreachable("exceed declaration attribute kinds"); #define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS: #include "swift/AST/Attr.def" llvm_unreachable("handled above"); default: assert(DeclAttribute::isDeclModifier(getKind()) && "handled above"); } return true; }
void DeclAttribute::print(ASTPrinter &Printer, const PrintOptions &Options) const { switch (getKind()) { // Handle all of the SIMPLE_DECL_ATTRs. #define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS: #include "swift/AST/Attr.def" case DAK_Inline: case DAK_Accessibility: case DAK_Ownership: case DAK_Effects: if (!DeclAttribute::isDeclModifier(getKind())) Printer << "@"; Printer << getAttrName(); break; case DAK_Semantics: Printer << "@_semantics(\"" << cast<SemanticsAttr>(this)->Value << "\")"; break; case DAK_Alignment: Printer << "@_alignment(" << cast<AlignmentAttr>(this)->Value << ")"; break; case DAK_SILGenName: Printer << "@_silgen_name(\"" << cast<SILGenNameAttr>(this)->Name << "\")"; break; case DAK_Available: { Printer << "@available("; auto Attr = cast<AvailableAttr>(this); Printer << Attr->platformString(); if (Attr->isUnconditionallyUnavailable()) Printer << ", unavailable"; else if (Attr->isUnconditionallyDeprecated()) Printer << ", deprecated"; if (Attr->Introduced) Printer << ", introduced=" << Attr->Introduced.getValue().getAsString(); if (Attr->Deprecated) Printer << ", deprecated=" << Attr->Deprecated.getValue().getAsString(); if (Attr->Obsoleted) Printer << ", obsoleted=" << Attr->Obsoleted.getValue().getAsString(); // If there's no message, but this is specifically an imported // "unavailable in Swift" attribute, synthesize a message to look good in // the generated interface. if (!Attr->Message.empty()) Printer << ", message=\"" << Attr->Message << "\""; else if (Attr->getUnconditionalAvailability() == UnconditionalAvailabilityKind::UnavailableInSwift) Printer << ", message=\"Not available in Swift\""; Printer << ")"; break; } case DAK_AutoClosure: Printer << "@autoclosure"; if (cast<AutoClosureAttr>(this)->isEscaping()) Printer << "(escaping)"; break; case DAK_ObjC: { if (Options.PrintForSIL && isImplicit()) break; Printer << "@objc"; llvm::SmallString<32> scratch; if (auto Name = cast<ObjCAttr>(this)->getName()) { if (!cast<ObjCAttr>(this)->isNameImplicit()) Printer << "(" << Name->getString(scratch) << ")"; } break; } case DAK_SetterAccessibility: Printer << getAttrName() << "(set)"; break; case DAK_SwiftNativeObjCRuntimeBase: { auto *attr = cast<SwiftNativeObjCRuntimeBaseAttr>(this); Printer << "@_swift_native_objc_runtime_base(" << attr->BaseClassName.str() << ")"; break; } case DAK_RawDocComment: // Not printed. return; case DAK_ObjCBridged: // Not printed. return; case DAK_SynthesizedProtocol: // Not printed. return; case DAK_WarnUnusedResult: { Printer << "@warn_unused_result"; auto *attr = cast<WarnUnusedResultAttr>(this); bool printedParens = false; if (!attr->getMessage().empty()) { Printer << "(message=\"" << attr->getMessage() << "\""; printedParens = true; } if (!attr->getMutableVariant().empty()) { if (printedParens) Printer << ", "; else Printer << "("; Printer << "mutable_variant=\"" << attr->getMutableVariant() << "\""; printedParens = true; } if (printedParens) Printer << ")"; break; } case DAK_Count: llvm_unreachable("exceed declaration attribute kinds"); } if (isLongAttribute() && Options.PrintLongAttrsOnSeparateLines) Printer.printNewline(); else Printer << " "; }
bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options) const { // Handle any attributes that are not printed at all before we make printer // callbacks. switch (getKind()) { case DAK_ObjC: if (Options.PrintForSIL && isImplicit()) return false; break; case DAK_RawDocComment: case DAK_ObjCBridged: case DAK_SynthesizedProtocol: case DAK_ShowInInterface: case DAK_Rethrows: return false; default: break; } // Handle any decl-modifiers. // FIXME: Ideally we would handle decl modifiers as a special kind of // attribute, but for now it's simpler to treat them as a keyword in the // printer. switch (getKind()) { // Handle all of the SIMPLE_DECL_ATTRs. #define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS: #include "swift/AST/Attr.def" case DAK_Inline: case DAK_Accessibility: case DAK_Ownership: case DAK_Effects: if (DeclAttribute::isDeclModifier(getKind())) { Printer.printKeyword(getAttrName()); } else { Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); Printer.printAttrName(getAttrName(), /*needAt=*/true); Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); } return true; case DAK_SetterAccessibility: Printer.printKeyword(getAttrName()); Printer << "(set)"; return true; default: break; } Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); }; switch (getKind()) { case DAK_Semantics: Printer.printAttrName("@_semantics"); Printer << "(\"" << cast<SemanticsAttr>(this)->Value << "\")"; break; case DAK_Alignment: Printer.printAttrName("@_alignment"); Printer << "(" << cast<AlignmentAttr>(this)->Value << ")"; break; case DAK_SILGenName: Printer.printAttrName("@_silgen_name"); Printer << "(\"" << cast<SILGenNameAttr>(this)->Name << "\")"; break; case DAK_Available: { Printer.printAttrName("@available"); Printer << "("; auto Attr = cast<AvailableAttr>(this); Printer << Attr->platformString(); if (Attr->isUnconditionallyUnavailable()) Printer << ", unavailable"; else if (Attr->isUnconditionallyDeprecated()) Printer << ", deprecated"; if (Attr->Introduced) Printer << ", introduced: " << Attr->Introduced.getValue().getAsString(); if (Attr->Deprecated) Printer << ", deprecated: " << Attr->Deprecated.getValue().getAsString(); if (Attr->Obsoleted) Printer << ", obsoleted: " << Attr->Obsoleted.getValue().getAsString(); if (!Attr->Rename.empty()) Printer << ", renamed: \"" << Attr->Rename << "\""; // If there's no message, but this is specifically an imported // "unavailable in Swift" attribute, synthesize a message to look good in // the generated interface. if (!Attr->Message.empty()) Printer << ", message: \"" << Attr->Message << "\""; else if (Attr->getUnconditionalAvailability() == UnconditionalAvailabilityKind::UnavailableInSwift) Printer << ", message: \"Not available in Swift\""; Printer << ")"; break; } case DAK_AutoClosure: Printer.printAttrName("@autoclosure"); if (cast<AutoClosureAttr>(this)->isEscaping()) Printer << "(escaping)"; break; case DAK_CDecl: Printer << "@_cdecl(\"" << cast<CDeclAttr>(this)->Name << "\")"; break; case DAK_ObjC: { Printer.printAttrName("@objc"); llvm::SmallString<32> scratch; if (auto Name = cast<ObjCAttr>(this)->getName()) { if (!cast<ObjCAttr>(this)->isNameImplicit()) Printer << "(" << Name->getString(scratch) << ")"; } break; } case DAK_SwiftNativeObjCRuntimeBase: { auto *attr = cast<SwiftNativeObjCRuntimeBaseAttr>(this); Printer.printAttrName("@_swift_native_objc_runtime_base"); Printer << "(" << attr->BaseClassName.str() << ")"; break; } case DAK_Swift3Migration: { auto attr = cast<Swift3MigrationAttr>(this); Printer.printAttrName("@swift3_migration"); Printer << "("; bool printedAny = false; auto printSeparator = [&] { if (printedAny) Printer << ", "; else printedAny = true; }; if (attr->getRenamed()) { printSeparator(); Printer << "renamed: \"" << attr->getRenamed() << "\""; } if (!attr->getMessage().empty()) { printSeparator(); Printer << "message: \""; Printer << attr->getMessage(); Printer << "\""; } Printer << ")"; break; } case DAK_Specialize: { Printer << "@" << getAttrName() << "("; auto *attr = cast<SpecializeAttr>(this); interleave(attr->getTypeLocs(), [&](TypeLoc tyLoc){ tyLoc.getType().print(Printer, Options); }, [&]{ Printer << ", "; }); Printer << ")"; break; } case DAK_Count: llvm_unreachable("exceed declaration attribute kinds"); default: llvm_unreachable("handled before this switch"); } return true; }
void InOutTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { Printer.printKeyword("inout"); Printer << " "; printTypeRepr(Base, Printer, Opts); }
void SILBoxTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { // TODO Printer.printKeyword("sil_box"); }
bool Compiler::CompileShaderPrimary( const ShaderInput& inputDesc, const ShaderOutput& outputDesc, Reflection::ReflectionData* reflectionData) { /* Validate arguments */ ValidateArguments(inputDesc, outputDesc); /* ----- Pre-processing ----- */ timePoints_.preprocessor = Time::now(); std::unique_ptr<IncludeHandler> stdIncludeHandler; if (!inputDesc.includeHandler) stdIncludeHandler = std::unique_ptr<IncludeHandler>(new IncludeHandler()); auto includeHandler = (inputDesc.includeHandler != nullptr ? inputDesc.includeHandler : stdIncludeHandler.get()); std::unique_ptr<PreProcessor> preProcessor; if (IsLanguageHLSL(inputDesc.shaderVersion)) preProcessor = MakeUnique<PreProcessor>(*includeHandler, log_); else if (IsLanguageGLSL(inputDesc.shaderVersion)) preProcessor = MakeUnique<GLSLPreProcessor>(*includeHandler, log_); const bool writeLineMarksInPP = (!outputDesc.options.preprocessOnly || outputDesc.formatting.lineMarks); const bool writeLineMarkFilenamesInPP = (!outputDesc.options.preprocessOnly || IsLanguageHLSL(inputDesc.shaderVersion)); auto processedInput = preProcessor->Process( std::make_shared<SourceCode>(inputDesc.sourceCode), inputDesc.filename, writeLineMarksInPP, writeLineMarkFilenamesInPP, ((inputDesc.warnings & Warnings::PreProcessor) != 0) ); if (reflectionData) reflectionData->macros = preProcessor->ListDefinedMacroIdents(); if (!processedInput) return ReturnWithError(R_PreProcessingSourceFailed); if (outputDesc.options.preprocessOnly) { (*outputDesc.sourceCode) << processedInput->rdbuf(); return true; } /* ----- Parsing ----- */ timePoints_.parser = Time::now(); std::unique_ptr<IntrinsicAdept> intrinsicAdpet; ProgramPtr program; if (IsLanguageHLSL(inputDesc.shaderVersion)) { /* Establish intrinsic adept */ intrinsicAdpet = MakeUnique<HLSLIntrinsicAdept>(); /* Parse HLSL input code */ HLSLParser parser(log_); program = parser.ParseSource( std::make_shared<SourceCode>(std::move(processedInput)), outputDesc.nameMangling, inputDesc.shaderVersion, outputDesc.options.rowMajorAlignment, ((inputDesc.warnings & Warnings::Syntax) != 0) ); } else if (IsLanguageGLSL(inputDesc.shaderVersion)) { /* Establish intrinsic adept */ #if 0 intrinsicAdpet = MakeUnique<GLSLIntrinsicAdept>(); #else //!!! intrinsicAdpet = MakeUnique<HLSLIntrinsicAdept>(); #endif /* Parse GLSL input code */ GLSLParser parser(log_); program = parser.ParseSource( std::make_shared<SourceCode>(std::move(processedInput)), outputDesc.nameMangling, inputDesc.shaderVersion, ((inputDesc.warnings & Warnings::Syntax) != 0) ); } if (!program) return ReturnWithError(R_ParsingSourceFailed); /* ----- Context analysis ----- */ timePoints_.analyzer = Time::now(); bool analyzerResult = false; if (IsLanguageHLSL(inputDesc.shaderVersion)) { /* Analyse HLSL program */ HLSLAnalyzer analyzer(log_); analyzerResult = analyzer.DecorateAST(*program, inputDesc, outputDesc); } /* Print AST */ if (outputDesc.options.showAST) { ASTPrinter printer; printer.PrintAST(program.get()); } if (!analyzerResult) return ReturnWithError(R_AnalyzingSourceFailed); /* Optimize AST */ timePoints_.optimizer = Time::now(); if (outputDesc.options.optimize) { Optimizer optimizer; optimizer.Optimize(*program); } /* ----- Code generation ----- */ timePoints_.generation = Time::now(); bool generatorResult = false; if (IsLanguageGLSL(outputDesc.shaderVersion) || IsLanguageESSL(outputDesc.shaderVersion) || IsLanguageVKSL(outputDesc.shaderVersion)) { /* Generate GLSL output code */ GLSLGenerator generator(log_); generatorResult = generator.GenerateCode(*program, inputDesc, outputDesc, log_); } if (!generatorResult) return ReturnWithError(R_GeneratingOutputCodeFailed); /* ----- Code reflection ----- */ timePoints_.reflection = Time::now(); if (reflectionData) { ReflectionAnalyzer reflectAnalyzer(log_); reflectAnalyzer.Reflect( *program, inputDesc.shaderTarget, *reflectionData, ((inputDesc.warnings & Warnings::CodeReflection) != 0) ); } return true; }
void swift::ide::printSubmoduleInterface( Module *M, ArrayRef<StringRef> FullModuleName, Optional<StringRef> GroupName, ModuleTraversalOptions TraversalOptions, ASTPrinter &Printer, const PrintOptions &Options, const bool PrintSynthesizedExtensions) { auto AdjustedOptions = Options; adjustPrintOptions(AdjustedOptions); SmallVector<Decl *, 1> Decls; M->getDisplayDecls(Decls); auto &SwiftContext = M->getASTContext(); auto &Importer = static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader()); const clang::Module *InterestingClangModule = nullptr; SmallVector<ImportDecl *, 1> ImportDecls; llvm::DenseSet<const clang::Module *> ClangModulesForImports; SmallVector<Decl *, 1> SwiftDecls; llvm::DenseMap<const clang::Module *, SmallVector<std::pair<Decl *, clang::SourceLocation>, 1>> ClangDecls; // Drop top-level module name. FullModuleName = FullModuleName.slice(1); InterestingClangModule = M->findUnderlyingClangModule(); if (InterestingClangModule) { for (StringRef Name : FullModuleName) { InterestingClangModule = InterestingClangModule->findSubmodule(Name); if (!InterestingClangModule) return; } } else { assert(FullModuleName.empty()); } // If we're printing recursively, find all of the submodules to print. if (InterestingClangModule) { if (TraversalOptions) { SmallVector<const clang::Module *, 8> Worklist; SmallPtrSet<const clang::Module *, 8> Visited; Worklist.push_back(InterestingClangModule); Visited.insert(InterestingClangModule); while (!Worklist.empty()) { const clang::Module *CM = Worklist.pop_back_val(); if (!(TraversalOptions & ModuleTraversal::VisitHidden) && CM->IsExplicit) continue; ClangDecls.insert({ CM, {} }); // If we're supposed to visit submodules, add them now. if (TraversalOptions & ModuleTraversal::VisitSubmodules) { for (auto Sub = CM->submodule_begin(), SubEnd = CM->submodule_end(); Sub != SubEnd; ++Sub) { if (Visited.insert(*Sub).second) Worklist.push_back(*Sub); } } } } else { ClangDecls.insert({ InterestingClangModule, {} }); } } // Collect those submodules that are actually imported but have no import decls // in the module. llvm::SmallPtrSet<const clang::Module *, 16> NoImportSubModules; if (InterestingClangModule) { // Assume all submodules are missing. for (auto It =InterestingClangModule->submodule_begin(); It != InterestingClangModule->submodule_end(); It ++) { NoImportSubModules.insert(*It); } } // Separate the declarations that we are going to print into different // buckets. for (Decl *D : Decls) { // Skip declarations that are not accessible. if (auto *VD = dyn_cast<ValueDecl>(D)) { if (Options.AccessibilityFilter > Accessibility::Private && VD->hasAccessibility() && VD->getFormalAccess() < Options.AccessibilityFilter) continue; } auto ShouldPrintImport = [&](ImportDecl *ImportD) -> bool { if (!InterestingClangModule) return true; auto ClangMod = ImportD->getClangModule(); if (!ClangMod) return true; if (!ClangMod->isSubModule()) return true; if (ClangMod == InterestingClangModule) return false; // FIXME: const-ness on the clang API. return ClangMod->isSubModuleOf( const_cast<clang::Module*>(InterestingClangModule)); }; if (auto ID = dyn_cast<ImportDecl>(D)) { if (ShouldPrintImport(ID)) { if (ID->getClangModule()) // Erase those submodules that are not missing. NoImportSubModules.erase(ID->getClangModule()); if (ID->getImportKind() == ImportKind::Module) { // Make sure we don't print duplicate imports, due to getting imports // for both a clang module and its overlay. if (auto *ClangMod = getUnderlyingClangModuleForImport(ID)) { auto P = ClangModulesForImports.insert(ClangMod); bool IsNew = P.second; if (!IsNew) continue; } } ImportDecls.push_back(ID); } continue; } auto addToClangDecls = [&](Decl *D) { assert(D->hasClangNode()); auto CN = D->getClangNode(); clang::SourceLocation Loc = CN.getLocation(); auto *OwningModule = Importer.getClangOwningModule(CN); auto I = ClangDecls.find(OwningModule); if (I != ClangDecls.end()) { I->second.push_back({ D, Loc }); } }; if (D->hasClangNode()) { addToClangDecls(D); continue; } if (FullModuleName.empty()) { // If group name is given and the decl does not belong to the group, skip it. if (GroupName && (!D->getGroupName() || D->getGroupName().getValue() != GroupName.getValue())) continue; // Add Swift decls if we are printing the top-level module. SwiftDecls.push_back(D); } } // Create the missing import decls and add to the collector. for (auto *SM : NoImportSubModules) { ImportDecls.push_back(createImportDecl(M->getASTContext(), M, SM, {})); } auto &ClangSourceManager = Importer.getClangASTContext().getSourceManager(); // Sort imported declarations in source order *within a submodule*. for (auto &P : ClangDecls) { std::sort(P.second.begin(), P.second.end(), [&](std::pair<Decl *, clang::SourceLocation> LHS, std::pair<Decl *, clang::SourceLocation> RHS) -> bool { return ClangSourceManager.isBeforeInTranslationUnit(LHS.second, RHS.second); }); } // Sort Swift declarations so that we print them in a consistent order. std::sort(ImportDecls.begin(), ImportDecls.end(), [](ImportDecl *LHS, ImportDecl *RHS) -> bool { auto LHSPath = LHS->getFullAccessPath(); auto RHSPath = RHS->getFullAccessPath(); for (unsigned i = 0, e = std::min(LHSPath.size(), RHSPath.size()); i != e; i++) { if (int Ret = LHSPath[i].first.str().compare(RHSPath[i].first.str())) return Ret < 0; } return false; }); // If the group name is specified, we sort them according to their source order, // which is the order preserved by getTopLeveDecls. if (!GroupName) { std::sort(SwiftDecls.begin(), SwiftDecls.end(), [&](Decl *LHS, Decl *RHS) -> bool { auto *LHSValue = dyn_cast<ValueDecl>(LHS); auto *RHSValue = dyn_cast<ValueDecl>(RHS); if (LHSValue && RHSValue) { StringRef LHSName = LHSValue->getName().str(); StringRef RHSName = RHSValue->getName().str(); if (int Ret = LHSName.compare(RHSName)) return Ret < 0; // FIXME: this is not sufficient to establish a total order for overloaded // decls. return LHS->getKind() < RHS->getKind(); } return LHS->getKind() < RHS->getKind(); }); } ASTPrinter *PrinterToUse = &Printer; ClangCommentPrinter RegularCommentPrinter(Printer, Importer); if (Options.PrintRegularClangComments) PrinterToUse = &RegularCommentPrinter; auto PrintDecl = [&](Decl *D) -> bool { ASTPrinter &Printer = *PrinterToUse; if (!shouldPrint(D, AdjustedOptions)) { Printer.avoidPrintDeclPost(D); return false; } if (auto Ext = dyn_cast<ExtensionDecl>(D)) { // Clang extensions (categories) are always printed in source order. // Swift extensions are printed with their associated type unless it's // a cross-module extension. if (!Ext->hasClangNode()) { auto ExtendedNominal = Ext->getExtendedType()->getAnyNominal(); if (Ext->getModuleContext() == ExtendedNominal->getModuleContext()) return false; } } if (D->print(Printer, AdjustedOptions)) { Printer << "\n"; if (auto NTD = dyn_cast<NominalTypeDecl>(D)) { std::queue<NominalTypeDecl *> SubDecls{{NTD}}; while (!SubDecls.empty()) { auto NTD = SubDecls.front(); SubDecls.pop(); // Add sub-types of NTD. for (auto Sub : NTD->getMembers()) if (auto N = dyn_cast<NominalTypeDecl>(Sub)) SubDecls.push(N); // Print Ext and add sub-types of Ext. for (auto Ext : NTD->getExtensions()) { if (!shouldPrint(Ext, AdjustedOptions)) { Printer.avoidPrintDeclPost(Ext); continue; } if (Ext->hasClangNode()) continue; // will be printed in its source location, see above. Printer << "\n"; Ext->print(Printer, AdjustedOptions); Printer << "\n"; for (auto Sub : Ext->getMembers()) if (auto N = dyn_cast<NominalTypeDecl>(Sub)) SubDecls.push(N); } if (!PrintSynthesizedExtensions) continue; // Print synthesized extensions. llvm::SmallPtrSet<ExtensionDecl *, 10> ExtensionsFromConformances; findExtensionsFromConformingProtocols(D, ExtensionsFromConformances); AdjustedOptions.initArchetypeTransformerForSynthesizedExtensions(NTD); for (auto ET : ExtensionsFromConformances) { if (!shouldPrint(ET, AdjustedOptions)) continue; Printer << "\n"; Printer << "/// Synthesized extension from "; ET->getExtendedTypeLoc().getType().print(Printer, AdjustedOptions); Printer << "\n"; ET->print(Printer, AdjustedOptions); Printer << "\n"; } AdjustedOptions.clearArchetypeTransformerForSynthesizedExtensions(); } } return true; } return false; }; // Imports from the stdlib are internal details that don't need to be exposed. if (!M->isStdlibModule()) { for (auto *D : ImportDecls) PrintDecl(D); Printer << "\n"; } { using ModuleAndName = std::pair<const clang::Module *, std::string>; SmallVector<ModuleAndName, 8> ClangModules; for (auto P : ClangDecls) { ClangModules.push_back({ P.first, P.first->getFullModuleName() }); } // Sort modules by name. std::sort(ClangModules.begin(), ClangModules.end(), [](const ModuleAndName &LHS, const ModuleAndName &RHS) -> bool { return LHS.second < RHS.second; }); for (auto CM : ClangModules) { for (auto DeclAndLoc : ClangDecls[CM.first]) PrintDecl(DeclAndLoc.first); } } if (!(TraversalOptions & ModuleTraversal::SkipOverlay) || !InterestingClangModule) { for (auto *D : SwiftDecls) { if (PrintDecl(D)) Printer << "\n"; } } }