std::string MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args, types::ID InputType) const { std::string TripleStr = ToolChain::ComputeEffectiveClangTriple(Args, InputType); llvm::Triple Triple(TripleStr); VersionTuple MSVT = tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args, /*IsWindowsMSVC=*/true); if (MSVT.empty()) return TripleStr; MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0), MSVT.getSubminor().getValueOr(0)); if (Triple.getEnvironment() == llvm::Triple::MSVC) { StringRef ObjFmt = Triple.getEnvironmentName().split('-').second; if (ObjFmt.empty()) Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str()); else Triple.setEnvironmentName( (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str()); } return Triple.getTriple(); }
void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { FullCommentParts Parts(C, Traits); const DeclInfo *DI = C->getDeclInfo(); StringRef RootEndTag; if (DI) { switch (DI->getKind()) { case DeclInfo::OtherKind: RootEndTag = "</Other>"; Result << "<Other"; break; case DeclInfo::FunctionKind: RootEndTag = "</Function>"; Result << "<Function"; switch (DI->TemplateKind) { case DeclInfo::NotTemplate: break; case DeclInfo::Template: Result << " templateKind=\"template\""; break; case DeclInfo::TemplateSpecialization: Result << " templateKind=\"specialization\""; break; case DeclInfo::TemplatePartialSpecialization: llvm_unreachable("partial specializations of functions " "are not allowed in C++"); } if (DI->IsInstanceMethod) Result << " isInstanceMethod=\"1\""; if (DI->IsClassMethod) Result << " isClassMethod=\"1\""; break; case DeclInfo::ClassKind: RootEndTag = "</Class>"; Result << "<Class"; switch (DI->TemplateKind) { case DeclInfo::NotTemplate: break; case DeclInfo::Template: Result << " templateKind=\"template\""; break; case DeclInfo::TemplateSpecialization: Result << " templateKind=\"specialization\""; break; case DeclInfo::TemplatePartialSpecialization: Result << " templateKind=\"partialSpecialization\""; break; } break; case DeclInfo::VariableKind: RootEndTag = "</Variable>"; Result << "<Variable"; break; case DeclInfo::NamespaceKind: RootEndTag = "</Namespace>"; Result << "<Namespace"; break; case DeclInfo::TypedefKind: RootEndTag = "</Typedef>"; Result << "<Typedef"; break; case DeclInfo::EnumKind: RootEndTag = "</Enum>"; Result << "<Enum"; break; } { // Print line and column number. SourceLocation Loc = DI->CurrentDecl->getLocation(); std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); FileID FID = LocInfo.first; unsigned FileOffset = LocInfo.second; if (FID.isValid()) { if (const FileEntry *FE = SM.getFileEntryForID(FID)) { Result << " file=\""; appendToResultWithXMLEscaping(FE->getName()); Result << "\""; } Result << " line=\"" << SM.getLineNumber(FID, FileOffset) << "\" column=\"" << SM.getColumnNumber(FID, FileOffset) << "\""; } } // Finish the root tag. Result << ">"; bool FoundName = false; if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) { if (DeclarationName DeclName = ND->getDeclName()) { Result << "<Name>"; std::string Name = DeclName.getAsString(); appendToResultWithXMLEscaping(Name); FoundName = true; Result << "</Name>"; } } if (!FoundName) Result << "<Name><anonymous></Name>"; { // Print USR. SmallString<128> USR; generateUSRForDecl(DI->CommentDecl, USR); if (!USR.empty()) { Result << "<USR>"; appendToResultWithXMLEscaping(USR); Result << "</USR>"; } } } else { // No DeclInfo -- just emit some root tag and name tag. RootEndTag = "</Other>"; Result << "<Other><Name>unknown</Name>"; } if (Parts.Headerfile) { Result << "<Headerfile>"; visit(Parts.Headerfile); Result << "</Headerfile>"; } { // Pretty-print the declaration. Result << "<Declaration>"; SmallString<128> Declaration; getSourceTextOfDeclaration(DI, Declaration); formatTextOfDeclaration(DI, Declaration); appendToResultWithXMLEscaping(Declaration); Result << "</Declaration>"; } bool FirstParagraphIsBrief = false; if (Parts.Brief) { Result << "<Abstract>"; visit(Parts.Brief); Result << "</Abstract>"; } else if (Parts.FirstParagraph) { Result << "<Abstract>"; visit(Parts.FirstParagraph); Result << "</Abstract>"; FirstParagraphIsBrief = true; } if (Parts.TParams.size() != 0) { Result << "<TemplateParameters>"; for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i) visit(Parts.TParams[i]); Result << "</TemplateParameters>"; } if (Parts.Params.size() != 0) { Result << "<Parameters>"; for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i) visit(Parts.Params[i]); Result << "</Parameters>"; } if (Parts.Exceptions.size() != 0) { Result << "<Exceptions>"; for (unsigned i = 0, e = Parts.Exceptions.size(); i != e; ++i) visit(Parts.Exceptions[i]); Result << "</Exceptions>"; } if (Parts.Returns.size() != 0) { Result << "<ResultDiscussion>"; for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i) visit(Parts.Returns[i]); Result << "</ResultDiscussion>"; } if (DI->CommentDecl->hasAttrs()) { const AttrVec &Attrs = DI->CommentDecl->getAttrs(); for (unsigned i = 0, e = Attrs.size(); i != e; i++) { const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]); if (!AA) { if (const DeprecatedAttr *DA = dyn_cast<DeprecatedAttr>(Attrs[i])) { if (DA->getMessage().empty()) Result << "<Deprecated/>"; else { Result << "<Deprecated>"; appendToResultWithXMLEscaping(DA->getMessage()); Result << "</Deprecated>"; } } else if (const UnavailableAttr *UA = dyn_cast<UnavailableAttr>(Attrs[i])) { if (UA->getMessage().empty()) Result << "<Unavailable/>"; else { Result << "<Unavailable>"; appendToResultWithXMLEscaping(UA->getMessage()); Result << "</Unavailable>"; } } continue; } // 'availability' attribute. Result << "<Availability"; StringRef Distribution; if (AA->getPlatform()) { Distribution = AvailabilityAttr::getPrettyPlatformName( AA->getPlatform()->getName()); if (Distribution.empty()) Distribution = AA->getPlatform()->getName(); } Result << " distribution=\"" << Distribution << "\">"; VersionTuple IntroducedInVersion = AA->getIntroduced(); if (!IntroducedInVersion.empty()) { Result << "<IntroducedInVersion>" << IntroducedInVersion.getAsString() << "</IntroducedInVersion>"; } VersionTuple DeprecatedInVersion = AA->getDeprecated(); if (!DeprecatedInVersion.empty()) { Result << "<DeprecatedInVersion>" << DeprecatedInVersion.getAsString() << "</DeprecatedInVersion>"; } VersionTuple RemovedAfterVersion = AA->getObsoleted(); if (!RemovedAfterVersion.empty()) { Result << "<RemovedAfterVersion>" << RemovedAfterVersion.getAsString() << "</RemovedAfterVersion>"; } StringRef DeprecationSummary = AA->getMessage(); if (!DeprecationSummary.empty()) { Result << "<DeprecationSummary>"; appendToResultWithXMLEscaping(DeprecationSummary); Result << "</DeprecationSummary>"; } if (AA->getUnavailable()) Result << "<Unavailable/>"; Result << "</Availability>"; } } { bool StartTagEmitted = false; for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) { const Comment *C = Parts.MiscBlocks[i]; if (FirstParagraphIsBrief && C == Parts.FirstParagraph) continue; if (!StartTagEmitted) { Result << "<Discussion>"; StartTagEmitted = true; } visit(C); } if (StartTagEmitted) Result << "</Discussion>"; } Result << RootEndTag; }
/// \brief Determine the availability of the given declaration based on /// the target platform. /// /// When it returns an availability result other than \c AR_Available, /// if the \p Message parameter is non-NULL, it will be set to a /// string describing why the entity is unavailable. /// /// FIXME: Make these strings localizable, since they end up in /// diagnostics. static AvailabilityResult CheckAvailability(ASTContext &Context, const AvailabilityAttr *A, std::string *Message) { StringRef TargetPlatform = Context.getTargetInfo().getPlatformName(); StringRef PrettyPlatformName = AvailabilityAttr::getPrettyPlatformName(TargetPlatform); if (PrettyPlatformName.empty()) PrettyPlatformName = TargetPlatform; VersionTuple TargetMinVersion = Context.getTargetInfo().getPlatformMinVersion(); if (TargetMinVersion.empty()) return AR_Available; // Match the platform name. if (A->getPlatform()->getName() != TargetPlatform) return AR_Available; std::string HintMessage; if (!A->getMessage().empty()) { HintMessage = " - "; HintMessage += A->getMessage(); } // Make sure that this declaration has not been marked 'unavailable'. if (A->getUnavailable()) { if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "not available on " << PrettyPlatformName << HintMessage; } return AR_Unavailable; } // Make sure that this declaration has already been introduced. if (!A->getIntroduced().empty() && TargetMinVersion < A->getIntroduced()) { if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "introduced in " << PrettyPlatformName << ' ' << A->getIntroduced() << HintMessage; } return AR_NotYetIntroduced; } // Make sure that this declaration hasn't been obsoleted. if (!A->getObsoleted().empty() && TargetMinVersion >= A->getObsoleted()) { if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "obsoleted in " << PrettyPlatformName << ' ' << A->getObsoleted() << HintMessage; } return AR_Unavailable; } // Make sure that this declaration hasn't been deprecated. if (!A->getDeprecated().empty() && TargetMinVersion >= A->getDeprecated()) { if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "first deprecated in " << PrettyPlatformName << ' ' << A->getDeprecated() << HintMessage; } return AR_Deprecated; } return AR_Available; }