Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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());
}
Exemplo n.º 4
0
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!");
}
Exemplo n.º 5
0
void NamedTypeRepr::printImpl(ASTPrinter &Printer,
                              const PrintOptions &Opts) const {
  if (!Id.empty()) {
    Printer.printName(Id, PrintNameContext::TupleElement);
    Printer << ": ";
  }
  printTypeRepr(Ty, Printer, Opts);
}
Exemplo n.º 6
0
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 << ")";
}
Exemplo n.º 7
0
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 << " ";
  }
}
Exemplo n.º 8
0
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 << ")";
}
Exemplo n.º 9
0
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!");
}
Exemplo n.º 10
0
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 << " ";
}
Exemplo n.º 11
0
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";
  }
}
Exemplo n.º 12
0
/// 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();
}
Exemplo n.º 13
0
/// 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();
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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 << " ";
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
void InOutTypeRepr::printImpl(ASTPrinter &Printer,
                              const PrintOptions &Opts) const {
  Printer.printKeyword("inout");
  Printer << " ";
  printTypeRepr(Base, Printer, Opts);
}
Exemplo n.º 18
0
void SILBoxTypeRepr::printImpl(ASTPrinter &Printer,
                               const PrintOptions &Opts) const {
  // TODO
  Printer.printKeyword("sil_box");
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
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";
    }
  }
}