diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-07-05 14:23:59 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-07-05 14:23:59 +0000 |
commit | c192b3dcffd5e672a2b2e1730e2440febb4fb192 (patch) | |
tree | ac719b5984165053bf83d71142e4d96b609b9784 /lib | |
parent | 2e645aa5697838f16ec570eb07c2bee7e13d0e0b (diff) | |
download | src-c192b3dcffd5e672a2b2e1730e2440febb4fb192.tar.gz src-c192b3dcffd5e672a2b2e1730e2440febb4fb192.zip |
Vendor import of clang trunk r241361:vendor/clang/clang-trunk-r241361
Notes
Notes:
svn path=/vendor/clang/dist/; revision=285165
svn path=/vendor/clang/clang-trunk-r241361/; revision=285166; tag=vendor/clang/clang-trunk-r241361
Diffstat (limited to 'lib')
232 files changed, 10700 insertions, 5864 deletions
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 8c2e0f4de808..b61a421ce415 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -355,8 +355,8 @@ public: bool TraverseObjCMessageExpr(ObjCMessageExpr *E) { // Do depth first; we want to rewrite the subexpressions first so that if // we have to move expressions we will move them already rewritten. - for (Stmt::child_range range = E->children(); range; ++range) - if (!TraverseStmt(*range)) + for (Stmt *SubStmt : E->children()) + if (!TraverseStmt(SubStmt)) return false; return WalkUpFromObjCMessageExpr(E); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 049eebd82b66..5a91f074c4e1 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1786,6 +1786,17 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { return TypeInfo(Width, Align, AlignIsRequired); } +unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const { + unsigned SimdAlign = getTargetInfo().getSimdDefaultAlign(); + // Target ppc64 with QPX: simd default alignment for pointer to double is 32. + if ((getTargetInfo().getTriple().getArch() == llvm::Triple::ppc64 || + getTargetInfo().getTriple().getArch() == llvm::Triple::ppc64le) && + getTargetInfo().getABI() == "elfv1-qpx" && + T->isSpecificBuiltinType(BuiltinType::Double)) + SimdAlign = 256; + return SimdAlign; +} + /// toCharUnitsFromBits - Convert a size in bits to a size in characters. CharUnits ASTContext::toCharUnitsFromBits(int64_t BitSize) const { return CharUnits::fromQuantity(BitSize / getCharWidth()); @@ -1866,6 +1877,16 @@ CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T) const { return toCharUnitsFromBits(getAlignOfGlobalVar(T)); } +CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const { + CharUnits Offset = CharUnits::Zero(); + const ASTRecordLayout *Layout = &getASTRecordLayout(RD); + while (const CXXRecordDecl *Base = Layout->getBaseSharingVBPtr()) { + Offset += Layout->getBaseClassOffset(Base); + Layout = &getASTRecordLayout(Base); + } + return Offset; +} + /// DeepCollectObjCIvars - /// This routine first collects all declared, but not synthesized, ivars in /// super class and then collects all ivars, including those synthesized for diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 60cbb0601138..90da4167197a 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -981,6 +981,10 @@ void ASTDumper::dumpDecl(const Decl *D) { OS << " in " << M->getFullModuleName(); else if (Module *M = D->getLocalOwningModule()) OS << " in (local) " << M->getFullModuleName(); + if (auto *ND = dyn_cast<NamedDecl>(D)) + for (Module *M : D->getASTContext().getModulesWithMergedDefinition( + const_cast<NamedDecl *>(ND))) + dumpChild([=] { OS << "also in " << M->getFullModuleName(); }); if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) if (ND->isHidden()) OS << " hidden"; @@ -1595,8 +1599,8 @@ void ASTDumper::dumpStmt(const Stmt *S) { ConstStmtVisitor<ASTDumper>::Visit(S); - for (Stmt::const_child_range CI = S->children(); CI; ++CI) - dumpStmt(*CI); + for (const Stmt *SubStmt : S->children()) + dumpStmt(SubStmt); }); } @@ -1825,6 +1829,9 @@ void ASTDumper::VisitUnaryExprOrTypeTraitExpr( case UETT_VecStep: OS << " vec_step"; break; + case UETT_OpenMPRequiredSimdAlign: + OS << " __builtin_omp_required_simd_align"; + break; } if (Node->isArgumentType()) dumpType(Node->getArgumentType()); diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 70bd16ffdd5d..d20451d1badc 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -236,6 +236,7 @@ void Decl::setLexicalDeclContext(DeclContext *DC) { } else { getMultipleDC()->LexicalDC = DC; } + Hidden = cast<Decl>(DC)->Hidden; } void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index c3ce47600972..d33093b8b5e1 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -954,9 +954,8 @@ void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx, if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Oneway) Out << "oneway "; if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_CSNullability) { - if (auto nullability = AttributedType::stripOuterNullability(T)) { - Out << getNullabilitySpelling(*nullability).substr(2) << ' '; - } + if (auto nullability = AttributedType::stripOuterNullability(T)) + Out << getNullabilitySpelling(*nullability, true) << ' '; } Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy); @@ -1207,7 +1206,7 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { Out << (first ? ' ' : ',') << "null_resettable"; } else { Out << (first ? ' ' : ',') - << getNullabilitySpelling(*nullability).substr(2); + << getNullabilitySpelling(*nullability, true); } first = false; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 36f4139f8352..87f9ffba78e3 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -3154,10 +3154,10 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, } // Recurse to children. - for (const_child_range SubStmts = children(); SubStmts; ++SubStmts) - if (const Stmt *S = *SubStmts) - if (cast<Expr>(S)->HasSideEffects(Ctx, IncludePossibleEffects)) - return true; + for (const Stmt *SubStmt : children()) + if (SubStmt && + cast<Expr>(SubStmt)->HasSideEffects(Ctx, IncludePossibleEffects)) + return true; return false; } diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 8e472f174140..ed749cc56f1e 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -7251,6 +7251,13 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( return false; return Success(Sizeof, E); } + case UETT_OpenMPRequiredSimdAlign: + assert(E->isArgumentType()); + return Success( + Info.Ctx.toCharUnitsFromBits( + Info.Ctx.getOpenMPDefaultSimdAlign(E->getArgumentType())) + .getQuantity(), + E); } llvm_unreachable("unknown expr/type trait"); diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp index 730842a28f6a..1c82c355134e 100644 --- a/lib/AST/ExternalASTSource.cpp +++ b/lib/AST/ExternalASTSource.cpp @@ -22,6 +22,16 @@ using namespace clang; ExternalASTSource::~ExternalASTSource() { } +llvm::Optional<ExternalASTSource::ASTSourceDescriptor> +ExternalASTSource::getSourceDescriptor(unsigned ID) { + return None; +} + +ExternalASTSource::ASTSourceDescriptor +ExternalASTSource::getSourceDescriptor(const Module &M) { + return ASTSourceDescriptor(); +} + void ExternalASTSource::FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length, SmallVectorImpl<Decl *> &Decls) {} diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index e5a31f879b76..0134c090d67e 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -3018,13 +3018,21 @@ recurse: case UETT_AlignOf: Out << 'a'; break; - case UETT_VecStep: + case UETT_VecStep: { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot yet mangle vec_step expression"); Diags.Report(DiagID); return; } + case UETT_OpenMPRequiredSimdAlign: + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, + "cannot yet mangle __builtin_omp_required_simd_align expression"); + Diags.Report(DiagID); + return; + } if (SAE->isArgumentType()) { Out << 't'; mangleType(SAE->getArgumentType()); diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 29a95a5103ce..48a8fa541a69 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -115,6 +115,9 @@ public: void mangleCXXVBTable(const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath, raw_ostream &Out) override; + void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD, + const CXXRecordDecl *DstRD, + raw_ostream &Out) override; void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, uint32_t NumEntries, raw_ostream &Out) override; void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, @@ -499,6 +502,9 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, FieldOffset /= getASTContext().getCharWidth(); VBTableOffset = 0; + + if (IM == MSInheritanceAttr::Keyword_virtual_inheritance) + FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity(); } else { FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1; @@ -567,6 +573,10 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, mangleName(MD); mangleFunctionEncoding(MD, /*ShouldMangle=*/true); } + + if (VBTableOffset == 0 && + IM == MSInheritanceAttr::Keyword_virtual_inheritance) + NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity(); } else { // Null single inheritance member functions are encoded as a simple nullptr. if (IM == MSInheritanceAttr::Keyword_single_inheritance) { @@ -579,7 +589,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, } if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM)) - mangleNumber(NVOffset); + mangleNumber(static_cast<uint32_t>(NVOffset)); if (MSInheritanceAttr::hasVBPtrOffsetField(IM)) mangleNumber(VBPtrOffset); if (MSInheritanceAttr::hasVBTableOffsetField(IM)) @@ -1205,11 +1215,23 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, return; } if (MPT->isMemberDataPointer()) { - mangleMemberDataPointer(RD, nullptr); - return; + if (isa<ClassTemplateDecl>(TD)) { + mangleMemberDataPointer(RD, nullptr); + return; + } + // nullptr data pointers are always represented with a single field + // which is initialized with either 0 or -1. Why -1? Well, we need to + // distinguish the case where the data member is at offset zero in the + // record. + // However, we are free to use 0 *if* we would use multiple fields for + // non-nullptr member pointers. + if (!RD->nullFieldOffsetIsZero()) { + mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false); + return; + } } } - Out << "$0A@"; + mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false); break; } case TemplateArgument::Expression: @@ -2395,6 +2417,15 @@ void MicrosoftMangleContextImpl::mangleCXXCatchHandlerType(QualType T, Mangler.getStream() << '.' << Flags; } +void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap( + const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) { + MicrosoftCXXNameMangler Mangler(*this, Out); + Mangler.getStream() << "\01??_K"; + Mangler.mangleName(SrcRD); + Mangler.getStream() << "$C"; + Mangler.mangleName(DstRD); +} + void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp index 2749100e14a2..a9b10ed451c0 100644 --- a/lib/AST/NSAPI.cpp +++ b/lib/AST/NSAPI.cpp @@ -30,7 +30,8 @@ IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const { "NSNumber", "NSMutableSet", "NSCountedSet", - "NSMutableOrderedSet" + "NSMutableOrderedSet", + "NSValue" }; if (!ClassIds[K]) diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp index a991302a2540..d7d5f9c69205 100644 --- a/lib/AST/ParentMap.cpp +++ b/lib/AST/ParentMap.cpp @@ -36,8 +36,8 @@ static void BuildParentMap(MapTy& M, Stmt* S, // If we are rebuilding the map, clear out any existing state. if (M[POE->getSyntacticForm()]) - for (Stmt::child_range I = S->children(); I; ++I) - M[*I] = nullptr; + for (Stmt *SubStmt : S->children()) + M[SubStmt] = nullptr; M[POE->getSyntacticForm()] = S; BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent); @@ -82,10 +82,10 @@ static void BuildParentMap(MapTy& M, Stmt* S, break; } default: - for (Stmt::child_range I = S->children(); I; ++I) { - if (*I) { - M[*I] = S; - BuildParentMap(M, *I, OVMode); + for (Stmt *SubStmt : S->children()) { + if (SubStmt) { + M[SubStmt] = S; + BuildParentMap(M, SubStmt, OVMode); } } break; diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 6f4a89fee39c..c0aab4c4db7d 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -1579,6 +1579,30 @@ OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) { return new (Mem) OMPFlushClause(N); } +OMPDependClause * +OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + OpenMPDependClauseKind DepKind, SourceLocation DepLoc, + SourceLocation ColonLoc, ArrayRef<Expr *> VL) { + void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause), + llvm::alignOf<Expr *>()) + + sizeof(Expr *) * VL.size()); + OMPDependClause *Clause = + new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size()); + Clause->setVarRefs(VL); + Clause->setDependencyKind(DepKind); + Clause->setDependencyLoc(DepLoc); + Clause->setColonLoc(ColonLoc); + return Clause; +} + +OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) { + void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause), + llvm::alignOf<Expr *>()) + + sizeof(Expr *) * N); + return new (Mem) OMPDependClause(N); +} + const OMPClause * OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const { auto &&I = getClausesOfKind(K); @@ -2062,6 +2086,46 @@ OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C, return new (Mem) OMPTaskgroupDirective(); } +OMPCancellationPointDirective *OMPCancellationPointDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + OpenMPDirectiveKind CancelRegion) { + unsigned Size = llvm::RoundUpToAlignment( + sizeof(OMPCancellationPointDirective), llvm::alignOf<Stmt *>()); + void *Mem = C.Allocate(Size); + OMPCancellationPointDirective *Dir = + new (Mem) OMPCancellationPointDirective(StartLoc, EndLoc); + Dir->setCancelRegion(CancelRegion); + return Dir; +} + +OMPCancellationPointDirective * +OMPCancellationPointDirective::CreateEmpty(const ASTContext &C, EmptyShell) { + unsigned Size = llvm::RoundUpToAlignment( + sizeof(OMPCancellationPointDirective), llvm::alignOf<Stmt *>()); + void *Mem = C.Allocate(Size); + return new (Mem) OMPCancellationPointDirective(); +} + +OMPCancelDirective * +OMPCancelDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + OpenMPDirectiveKind CancelRegion) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective), + llvm::alignOf<Stmt *>()); + void *Mem = C.Allocate(Size); + OMPCancelDirective *Dir = new (Mem) OMPCancelDirective(StartLoc, EndLoc); + Dir->setCancelRegion(CancelRegion); + return Dir; +} + +OMPCancelDirective *OMPCancelDirective::CreateEmpty(const ASTContext &C, + EmptyShell) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective), + llvm::alignOf<Stmt *>()); + void *Mem = C.Allocate(Size); + return new (Mem) OMPCancelDirective(); +} + OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp index 1ccba04d9f5b..732756fbec9a 100644 --- a/lib/AST/StmtIterator.cpp +++ b/lib/AST/StmtIterator.cpp @@ -93,12 +93,12 @@ bool StmtIteratorBase::HandleDecl(Decl* D) { } StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge) - : stmt(nullptr), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { + : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) { NextDecl(false); } StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t) - : stmt(nullptr), DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) { + : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) { RawVAPtr |= reinterpret_cast<uintptr_t>(t); } diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 658e3dfdeed4..79600773f567 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -799,6 +799,17 @@ void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) { OS << ")"; } } + +void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) { + if (!Node->varlist_empty()) { + OS << "depend("; + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), + Node->getDependencyKind()) + << " :"; + VisitOMPClauseList(Node, ' '); + OS << ")"; + } +} } //===----------------------------------------------------------------------===// @@ -940,6 +951,18 @@ void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPCancellationPointDirective( + OMPCancellationPointDirective *Node) { + Indent() << "#pragma omp cancellation point " + << getOpenMPDirectiveName(Node->getCancelRegion()); + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { + Indent() << "#pragma omp cancel " + << getOpenMPDirectiveName(Node->getCancelRegion()); + PrintOMPExecutableDirective(Node); +} //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// @@ -1206,6 +1229,9 @@ void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ case UETT_VecStep: OS << "vec_step"; break; + case UETT_OpenMPRequiredSimdAlign: + OS << "__builtin_omp_required_simd_align"; + break; } if (Node->isArgumentType()) { OS << '('; diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 23f8d0c8be7a..da996920c420 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -69,9 +69,9 @@ namespace { void StmtProfiler::VisitStmt(const Stmt *S) { ID.AddInteger(S->getStmtClass()); - for (Stmt::const_child_range C = S->children(); C; ++C) { - if (*C) - Visit(*C); + for (const Stmt *SubStmt : S->children()) { + if (SubStmt) + Visit(SubStmt); else ID.AddInteger(0); } @@ -425,6 +425,9 @@ OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) { void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) { VisitOMPClauseList(C); } +void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) { + VisitOMPClauseList(C); +} } void @@ -534,6 +537,15 @@ void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPCancellationPointDirective( + const OMPCancellationPointDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 3ac117194099..541bd1ebdf88 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -364,6 +364,11 @@ bool Type::isStructureType() const { return RT->getDecl()->isStruct(); return false; } +bool Type::isObjCBoxableRecordType() const { + if (const RecordType *RT = getAs<RecordType>()) + return RT->getDecl()->hasAttr<ObjCBoxableAttr>(); + return false; +} bool Type::isInterfaceType() const { if (const RecordType *RT = getAs<RecordType>()) return RT->getDecl()->isInterface(); diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index ebe09d85495e..9938170c321a 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -1147,11 +1147,11 @@ void TypePrinter::printAttributedBefore(const AttributedType *T, T->getAttrKind() == AttributedType::attr_nullable || T->getAttrKind() == AttributedType::attr_null_unspecified) { if (T->getAttrKind() == AttributedType::attr_nonnull) - OS << " __nonnull"; + OS << " _Nonnull"; else if (T->getAttrKind() == AttributedType::attr_nullable) - OS << " __nullable"; + OS << " _Nullable"; else if (T->getAttrKind() == AttributedType::attr_null_unspecified) - OS << " __null_unspecified"; + OS << " _Null_unspecified"; else llvm_unreachable("unhandled nullability"); spaceBeforePlaceHolder(OS); @@ -1186,11 +1186,11 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, T->getAttrKind() == AttributedType::attr_nullable || T->getAttrKind() == AttributedType::attr_null_unspecified) { if (T->getAttrKind() == AttributedType::attr_nonnull) - OS << " __nonnull"; + OS << " _Nonnull"; else if (T->getAttrKind() == AttributedType::attr_nullable) - OS << " __nullable"; + OS << " _Nullable"; else if (T->getAttrKind() == AttributedType::attr_null_unspecified) - OS << " __null_unspecified"; + OS << " _Null_unspecified"; else llvm_unreachable("unhandled nullability"); diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp index 2c482e38dc08..b6ef8226a9a9 100644 --- a/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -114,9 +114,9 @@ DynTypedMatcher DynTypedMatcher::constructVariadic( assert(InnerMatchers.size() > 0 && "Array must not be empty."); assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(), [&InnerMatchers](const DynTypedMatcher &M) { - return InnerMatchers[0].SupportedKind.isSame(M.SupportedKind); + return InnerMatchers[0].canConvertTo(M.SupportedKind); }) && - "SupportedKind must match!"); + "SupportedKind must be convertible to a common type!"); auto SupportedKind = InnerMatchers[0].SupportedKind; // We must relax the restrict kind here. diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index 59c204d370a6..72713dda03c7 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -240,6 +240,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(innerType); REGISTER_MATCHER(integerLiteral); REGISTER_MATCHER(isArrow); + REGISTER_MATCHER(isCatchAll); REGISTER_MATCHER(isConst); REGISTER_MATCHER(isConstQualified); REGISTER_MATCHER(isDefinition); diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp index 4e623c8d6c39..d7fb7e95d758 100644 --- a/lib/Analysis/AnalysisDeclContext.cpp +++ b/lib/Analysis/AnalysisDeclContext.cpp @@ -472,9 +472,9 @@ public: : BEVals(bevals), BC(bc) {} void VisitStmt(Stmt *S) { - for (Stmt::child_range I = S->children(); I; ++I) - if (Stmt *child = *I) - Visit(child); + for (Stmt *Child : S->children()) + if (Child) + Visit(Child); } void VisitDeclRefExpr(DeclRefExpr *DR) { diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 19b3f5a47654..54d15bd232a1 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -270,9 +270,8 @@ reverse_children::reverse_children(Stmt *S) { } // Default case for all other statements. - for (Stmt::child_range I = S->children(); I; ++I) { - childrenBuf.push_back(*I); - } + for (Stmt *SubStmt : S->children()) + childrenBuf.push_back(SubStmt); // This needs to be done *after* childrenBuf has been populated. children = childrenBuf; @@ -3641,11 +3640,11 @@ CFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E, // bottom-up, this means we visit them in their natural order, which // reverses them in the CFG. CFGBlock *B = Block; - for (Stmt::child_range I = E->children(); I; ++I) { - if (Stmt *Child = *I) + for (Stmt *Child : E->children()) + if (Child) if (CFGBlock *R = VisitForTemporaryDtors(Child, false, Context)) B = R; - } + return B; } diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp index 91a8492eaa54..d06603469dd0 100644 --- a/lib/Analysis/CallGraph.cpp +++ b/lib/Analysis/CallGraph.cpp @@ -83,9 +83,9 @@ public: } void VisitChildren(Stmt *S) { - for (Stmt::child_range I = S->children(); I; ++I) - if (*I) - static_cast<CGBuilder*>(this)->Visit(*I); + for (Stmt *SubStmt : S->children()) + if (SubStmt) + this->Visit(SubStmt); } }; diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp index 0ab158036d84..5e0a9a0d73c8 100644 --- a/lib/Analysis/LiveVariables.cpp +++ b/lib/Analysis/LiveVariables.cpp @@ -322,11 +322,10 @@ void TransferFunctions::Visit(Stmt *S) { return; } } - - for (Stmt::child_iterator it = S->child_begin(), ei = S->child_end(); - it != ei; ++it) { - if (Stmt *child = *it) - AddLiveStmt(val.liveStmts, LV.SSetFact, child); + + for (Stmt *Child : S->children()) { + if (Child) + AddLiveStmt(val.liveStmts, LV.SSetFact, Child); } } diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp index b8d3ec18016a..f0976bce9720 100644 --- a/lib/Analysis/PrintfFormatString.cpp +++ b/lib/Analysis/PrintfFormatString.cpp @@ -49,6 +49,24 @@ static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, return false; } +static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS, + const char *FlagBeg, const char *E, bool Warn) { + StringRef Flag(FlagBeg, E - FlagBeg); + // Currently there is only one flag. + if (Flag == "tt") { + FS.setHasObjCTechnicalTerm(FlagBeg); + return false; + } + // Handle either the case of no flag or an invalid flag. + if (Warn) { + if (Flag == "") + H.HandleEmptyObjCModifierFlag(FlagBeg, E - FlagBeg); + else + H.HandleInvalidObjCModifierFlag(FlagBeg, E - FlagBeg); + } + return true; +} + static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, @@ -168,6 +186,38 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, return true; } + // Look for the Objective-C modifier flags, if any. + // We parse these here, even if they don't apply to + // the conversion specifier, and then emit an error + // later if the conversion specifier isn't '@'. This + // enables better recovery, and we don't know if + // these flags are applicable until later. + const char *ObjCModifierFlagsStart = nullptr, + *ObjCModifierFlagsEnd = nullptr; + if (*I == '[') { + ObjCModifierFlagsStart = I; + ++I; + auto flagStart = I; + for (;; ++I) { + ObjCModifierFlagsEnd = I; + if (I == E) { + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); + return true; + } + // Did we find the closing ']'? + if (*I == ']') { + if (ParseObjCFlags(H, FS, flagStart, I, Warn)) + return true; + ++I; + break; + } + // There are no separators defined yet for multiple + // Objective-C modifier flags. When those are + // defined, this is the place to check. + } + } + if (*I == '\0') { // Detect spurious null characters, which are likely errors. H.HandleNullChar(I); @@ -240,6 +290,18 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (Target.getTriple().isOSMSVCRT()) k = ConversionSpecifier::ZArg; } + + // Check to see if we used the Objective-C modifier flags with + // a conversion specifier other than '@'. + if (k != ConversionSpecifier::ObjCObjArg && + k != ConversionSpecifier::InvalidSpecifier && + ObjCModifierFlagsStart) { + H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart, + ObjCModifierFlagsEnd + 1, + conversionPosition); + return true; + } + PrintfConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) diff --git a/lib/Analysis/PseudoConstantAnalysis.cpp b/lib/Analysis/PseudoConstantAnalysis.cpp index 3f96ca877f19..5b917a7a27f5 100644 --- a/lib/Analysis/PseudoConstantAnalysis.cpp +++ b/lib/Analysis/PseudoConstantAnalysis.cpp @@ -220,8 +220,8 @@ void PseudoConstantAnalysis::RunAnalysis() { } // switch (head->getStmtClass()) // Add all substatements to the worklist - for (Stmt::const_child_range I = Head->children(); I; ++I) - if (*I) - WorkList.push_back(*I); + for (const Stmt *SubStmt : Head->children()) + if (SubStmt) + WorkList.push_back(SubStmt); } // while (!WorkList.empty()) } diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 7f5a15dab6b2..f89caf7b248f 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -24,6 +24,27 @@ using namespace clang; +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + DiagNullabilityKind nullability) { + StringRef string; + switch (nullability.first) { + case NullabilityKind::NonNull: + string = nullability.second ? "'nonnull'" : "'_Nonnull'"; + break; + + case NullabilityKind::Nullable: + string = nullability.second ? "'nullable'" : "'_Nullable'"; + break; + + case NullabilityKind::Unspecified: + string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'"; + break; + } + + DB.AddString(string); + return DB; +} + static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, StringRef Modifier, StringRef Argument, ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index b29500810003..36fba994f1e7 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -71,8 +71,6 @@ IdentifierIterator *IdentifierInfoLookup::getIdentifiers() { return new EmptyLookupIterator(); } -ExternalIdentifierLookup::~ExternalIdentifierLookup() {} - IdentifierTable::IdentifierTable(const LangOptions &LangOpts, IdentifierInfoLookup* externalLookup) : HashTable(8192), // Start with space for 8K identifiers. @@ -647,16 +645,17 @@ const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) { llvm_unreachable("Invalid OverloadedOperatorKind!"); } -StringRef clang::getNullabilitySpelling(NullabilityKind kind) { +StringRef clang::getNullabilitySpelling(NullabilityKind kind, + bool isContextSensitive) { switch (kind) { case NullabilityKind::NonNull: - return "__nonnull"; + return isContextSensitive ? "nonnull" : "_Nonnull"; case NullabilityKind::Nullable: - return "__nullable"; + return isContextSensitive ? "nullable" : "_Nullable"; case NullabilityKind::Unspecified: - return "__null_unspecified"; + return isContextSensitive ? "null_unspecified" : "_Null_unspecified"; } llvm_unreachable("Unknown nullability kind."); } diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 7308665bd2d8..1a48a6c6a8d1 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -27,7 +27,7 @@ using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), - Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID), + Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID), IsMissingRequirement(false), IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), IsInferred(false), InferSubmodules(false), diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index b2798b7f0fd3..b7407f60e6d1 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -91,6 +91,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_SCHEDULE_unknown); + case OMPC_depend: + return llvm::StringSwitch<OpenMPDependClauseKind>(Str) +#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DEPEND_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -154,6 +159,15 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, return #Name; #include "clang/Basic/OpenMPKinds.def" } + case OMPC_depend: + switch (Type) { + case OMPC_DEPEND_unknown: + return "unknown"; +#define OPENMP_DEPEND_KIND(Name) \ + case OMPC_DEPEND_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } llvm_unreachable("Invalid OpenMP 'schedule' clause type"); case OMPC_unknown: case OMPC_threadprivate: @@ -333,6 +347,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, case OMPD_barrier: case OMPD_taskwait: case OMPD_taskgroup: + case OMPD_cancellation_point: + case OMPD_cancel: case OMPD_ordered: break; } diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 330258b025b5..856ad50d3782 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -50,6 +50,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; MaxVectorAlign = 0; + SimdDefaultAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 076b04bf342c..8f2bca051b67 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -759,6 +759,7 @@ public: HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false), HasBPERMD(false), HasExtDiv(false) { BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); + SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; } @@ -2215,6 +2216,7 @@ public: Names = AddlRegNames; NumNames = llvm::array_lengthof(AddlRegNames); } + bool validateCpuSupports(StringRef Name) const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -2249,7 +2251,9 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; StringRef getABI() const override { - if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) + if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F) + return "avx512"; + else if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) return "avx"; else if (getTriple().getArch() == llvm::Triple::x86 && MMX3DNowLevel == NoMMX3DNow) @@ -2725,7 +2729,11 @@ void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) { - Features[Name] = Enabled; + // This is a bit of a hack to deal with the sse4 target feature when used + // as part of the target attribute. We handle sse4 correctly everywhere + // else. See below for more information on how we handle the sse4 options. + if (Name != "sse4") + Features[Name] = Enabled; if (Name == "mmx") { setMMXLevel(Features, MMX, Enabled); @@ -2776,6 +2784,15 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, } else if (Name == "sha") { if (Enabled) setSSELevel(Features, SSE2, Enabled); + } else if (Name == "sse4") { + // We can get here via the __target__ attribute since that's not controlled + // via the -msse4/-mno-sse4 command line alias. Handle this the same way + // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if + // disabled. + if (Enabled) + setSSELevel(Features, SSE42, Enabled); + else + setSSELevel(Features, SSE41, Enabled); } } @@ -2972,6 +2989,9 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, Features.erase(it); else if (SSELevel > NoSSE) MMX3DNowLevel = std::max(MMX3DNowLevel, MMX); + + SimdDefaultAlign = + (getABI() == "avx512") ? 512 : (getABI() == "avx") ? 256 : 128; return true; } @@ -3336,6 +3356,33 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Default(false); } +// We can't use a generic validation scheme for the features accepted here +// versus subtarget features accepted in the target attribute because the +// bitfield structure that's initialized in the runtime only supports the +// below currently rather than the full range of subtarget features. (See +// X86TargetInfo::hasFeature for a somewhat comprehensive list). +bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { + return llvm::StringSwitch<bool>(FeatureStr) + .Case("cmov", true) + .Case("mmx", true) + .Case("popcnt", true) + .Case("sse", true) + .Case("sse2", true) + .Case("sse3", true) + .Case("sse4.1", true) + .Case("sse4.2", true) + .Case("avx", true) + .Case("avx2", true) + .Case("sse4a", true) + .Case("fma4", true) + .Case("xop", true) + .Case("fma", true) + .Case("avx512f", true) + .Case("bmi", true) + .Case("bmi2", true) + .Default(false); +} + bool X86TargetInfo::validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const { @@ -3949,8 +3996,14 @@ class ARMTargetInfo : public TargetInfo { FP_Neon } FPMath; + unsigned ArchISA; + unsigned ArchKind; + unsigned ArchProfile; + unsigned ArchVersion; + unsigned FPU : 5; + unsigned ShouldUseInlineAtomic : 1; unsigned IsAAPCS : 1; unsigned IsThumb : 1; unsigned HWDiv : 2; @@ -3972,37 +4025,6 @@ class ARMTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; - static bool shouldUseInlineAtomic(const llvm::Triple &T) { - StringRef ArchName = T.getArchName(); - if (T.getArch() == llvm::Triple::arm || - T.getArch() == llvm::Triple::armeb) { - StringRef VersionStr; - if (ArchName.startswith("armv")) - VersionStr = ArchName.substr(4, 1); - else if (ArchName.startswith("armebv")) - VersionStr = ArchName.substr(6, 1); - else - return false; - unsigned Version; - if (VersionStr.getAsInteger(10, Version)) - return false; - return Version >= 6; - } - assert(T.getArch() == llvm::Triple::thumb || - T.getArch() == llvm::Triple::thumbeb); - StringRef VersionStr; - if (ArchName.startswith("thumbv")) - VersionStr = ArchName.substr(6, 1); - else if (ArchName.startswith("thumbebv")) - VersionStr = ArchName.substr(8, 1); - else - return false; - unsigned Version; - if (VersionStr.getAsInteger(10, Version)) - return false; - return Version >= 7; - } - void setABIAAPCS() { IsAAPCS = true; @@ -4101,6 +4123,27 @@ class ARMTargetInfo : public TargetInfo { // FIXME: Override "preferred align" for double and long long. } + void setArchInfo(StringRef ArchName) { + ArchISA = llvm::ARMTargetParser::parseArchISA(ArchName); + ArchKind = llvm::ARMTargetParser::parseArch(ArchName); + ArchProfile = llvm::ARMTargetParser::parseArchProfile(ArchName); + ArchVersion = llvm::ARMTargetParser::parseArchVersion(ArchName); + } + + void setAtomic() { + // Cortex M does not support 8 byte atomics, while general Thumb2 does. + if (ArchProfile == llvm::ARM::PK_M) { + MaxAtomicPromoteWidth = 32; + if (ShouldUseInlineAtomic) + MaxAtomicInlineWidth = 32; + } + else { + MaxAtomicPromoteWidth = 64; + if (ShouldUseInlineAtomic) + MaxAtomicInlineWidth = 64; + } + } + public: ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian) : TargetInfo(Triple), CPU("arm1136j-s"), FPMath(FP_Default), @@ -4116,12 +4159,27 @@ public: break; } + // if subArch is not specified Arc Info is based on the default CPU + if (Triple.getSubArch() == llvm::Triple::SubArchType::NoSubArch) { + unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(CPU); + setArchInfo(llvm::ARMTargetParser::getArchName(ArchKind)); + ShouldUseInlineAtomic = false; + } + else { + setArchInfo(Triple.getArchName()); + // FIXME: Should't this be updated also when calling setCPU() ? + // Doing so currently causes regressions + ShouldUseInlineAtomic = (ArchISA == llvm::ARM::IK_ARM && ArchVersion >= 6) || + (ArchISA == llvm::ARM::IK_THUMB && ArchVersion >= 7); + } + // {} in inline assembly are neon specifiers, not assembly variant // specifiers. NoAsmVariants = true; - // FIXME: Should we just treat this as a feature? - IsThumb = getTriple().getArchName().startswith("thumb"); + // FIXME: Should't this be updated also when calling setCPU() ? + // Doing so currently causes regressions + IsThumb = (ArchISA == llvm::ARM::IK_THUMB); // FIXME: This duplicates code from the driver that sets the -target-abi // option - this code is used if -target-abi isn't passed and should @@ -4166,10 +4224,7 @@ public: // ARM targets default to using the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::GenericARM); - // ARM has atomics up to 8 bytes - MaxAtomicPromoteWidth = 64; - if (shouldUseInlineAtomic(getTriple())) - MaxAtomicInlineWidth = 64; + setAtomic(); // Do force alignment of members that follow zero length bitfields. If // the alignment of the zero-length bitfield is greater than the member @@ -4177,7 +4232,9 @@ public: // zero length bitfield. UseZeroLengthBitfieldAlignment = true; } + StringRef getABI() const override { return ABI; } + bool setABI(const std::string &Name) override { ABI = Name; @@ -4198,11 +4255,6 @@ public: // FIXME: This should be based on Arch attributes, not CPU names. void getDefaultFeatures(llvm::StringMap<bool> &Features) const override { - StringRef ArchName = getTriple().getArchName(); - unsigned ArchKind = llvm::ARMTargetParser::parseArch(ArchName); - bool IsV8 = (ArchKind == llvm::ARM::AK_ARMV8A || - ArchKind == llvm::ARM::AK_ARMV8_1A); - if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") Features["vfp2"] = true; else if (CPU == "cortex-a8" || CPU == "cortex-a9") { @@ -4227,7 +4279,7 @@ public: Features["hwdiv-arm"] = true; Features["crc"] = true; Features["crypto"] = true; - } else if (CPU == "cortex-r5" || CPU == "cortex-r7" || IsV8) { + } else if (CPU == "cortex-r5" || CPU == "cortex-r7" || ArchVersion == 8) { Features["hwdiv"] = true; Features["hwdiv-arm"] = true; } else if (CPU == "cortex-m3" || CPU == "cortex-m4" || CPU == "cortex-m7" || @@ -4244,6 +4296,9 @@ public: SoftFloat = SoftFloatABI = false; HWDiv = 0; + // This does not diagnose illegal cases like having both + // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". + uint32_t HW_FP_remove = 0; for (const auto &Feature : Features) { if (Feature == "+soft-float") { SoftFloat = true; @@ -4251,19 +4306,19 @@ public: SoftFloatABI = true; } else if (Feature == "+vfp2") { FPU |= VFP2FPU; - HW_FP = HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP | HW_FP_DP; } else if (Feature == "+vfp3") { FPU |= VFP3FPU; - HW_FP = HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP | HW_FP_DP; } else if (Feature == "+vfp4") { FPU |= VFP4FPU; - HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP; + HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP; } else if (Feature == "+fp-armv8") { FPU |= FPARMV8; - HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP; + HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP; } else if (Feature == "+neon") { FPU |= NeonFPU; - HW_FP = HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP | HW_FP_DP; } else if (Feature == "+hwdiv") { HWDiv |= HWDivThumb; } else if (Feature == "+hwdiv-arm") { @@ -4273,9 +4328,10 @@ public: } else if (Feature == "+crypto") { Crypto = 1; } else if (Feature == "+fp-only-sp") { - HW_FP &= ~HW_FP_DP; + HW_FP_remove |= HW_FP_DP | HW_FP_HP; } } + HW_FP &= ~HW_FP_remove; if (!(FPU & NeonFPU) && FPMath == FP_Neon) { Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; @@ -4306,26 +4362,14 @@ public: .Case("hwdiv-arm", HWDiv & HWDivARM) .Default(false); } - const char *getCPUDefineSuffix(StringRef Name) const { - if(Name == "generic") { - auto subarch = getTriple().getSubArch(); - switch (subarch) { - case llvm::Triple::SubArchType::ARMSubArch_v8_1a: - return "8_1A"; - default: - break; - } - } - - unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name); - if (ArchKind == llvm::ARM::AK_INVALID) - return ""; - + const char *getCPUAttr() const { + const char *CPUAttr; // For most sub-arches, the build attribute CPU name is enough. // For Cortex variants, it's slightly different. switch(ArchKind) { default: - return llvm::ARMTargetParser::getCPUAttr(ArchKind); + CPUAttr = llvm::ARMTargetParser::getCPUAttr(ArchKind); + return CPUAttr ? CPUAttr : "" ; case llvm::ARM::AK_ARMV6M: case llvm::ARM::AK_ARMV6SM: return "6M"; @@ -4345,23 +4389,8 @@ public: return "8_1A"; } } - const char *getCPUProfile(StringRef Name) const { - if(Name == "generic") { - auto subarch = getTriple().getSubArch(); - switch (subarch) { - case llvm::Triple::SubArchType::ARMSubArch_v8_1a: - return "A"; - default: - break; - } - } - - unsigned CPUArch = llvm::ARMTargetParser::parseCPUArch(Name); - if (CPUArch == llvm::ARM::AK_INVALID) - return ""; - - StringRef ArchName = llvm::ARMTargetParser::getArchName(CPUArch); - switch(llvm::ARMTargetParser::parseArchProfile(ArchName)) { + const char *getCPUProfile() const { + switch(ArchProfile) { case llvm::ARM::PK_A: return "A"; case llvm::ARM::PK_R: @@ -4373,35 +4402,26 @@ public: } } bool setCPU(const std::string &Name) override { - if (!getCPUDefineSuffix(Name)) + unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name); + if (ArchKind == llvm::ARM::AK_INVALID) return false; - - // Cortex M does not support 8 byte atomics, while general Thumb2 does. - StringRef Profile = getCPUProfile(Name); - if (Profile == "M" && MaxAtomicInlineWidth) { - MaxAtomicPromoteWidth = 32; - MaxAtomicInlineWidth = 32; - } - + setArchInfo(llvm::ARMTargetParser::getArchName(ArchKind)); + setAtomic(); CPU = Name; return true; } bool setFPMath(StringRef Name) override; - bool supportsThumb(StringRef ArchName, StringRef CPUArch, - unsigned CPUArchVer) const { - return CPUArchVer >= 7 || (CPUArch.find('T') != StringRef::npos) || - (CPUArch.find('M') != StringRef::npos); - } - bool supportsThumb2(StringRef ArchName, StringRef CPUArch, - unsigned CPUArchVer) const { - // We check both CPUArchVer and ArchName because when only triple is - // specified, the default CPU is arm1136j-s. - return ArchName.endswith("v6t2") || ArchName.endswith("v7") || - ArchName.endswith("v8.1a") || - ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7; + bool supportsThumb(StringRef CPUAttr) const { + return CPUAttr.count('T') || ArchVersion >= 6; + } + bool supportsThumb2(StringRef CPUAttr) const { + return CPUAttr.equals("6T2") || ArchVersion >= 7; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { + StringRef CPUAttr = getCPUAttr(); + StringRef CPUProfile = getCPUProfile(); + // Target identification. Builder.defineMacro("__arm"); Builder.defineMacro("__arm__"); @@ -4409,19 +4429,12 @@ public: // Target properties. Builder.defineMacro("__REGISTER_PREFIX__", ""); - StringRef CPUArch = getCPUDefineSuffix(CPU); - unsigned int CPUArchVer; - if (CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer)) - llvm_unreachable("Invalid char for architecture version number"); - Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__"); + Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__"); // ACLE 6.4.1 ARM/Thumb instruction set architecture - StringRef CPUProfile = getCPUProfile(CPU); - StringRef ArchName = getTriple().getArchName(); - // __ARM_ARCH is defined as an integer value indicating the current ARM ISA - Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1)); - if (CPUArch[0] >= '8') { + Builder.defineMacro("__ARM_ARCH", std::to_string(ArchVersion)); + if (ArchVersion >= 8) { Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN"); Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING"); } @@ -4435,9 +4448,9 @@ public: // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original // Thumb ISA (including v6-M). It is set to 2 if the core supports the // Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture. - if (supportsThumb2(ArchName, CPUArch, CPUArchVer)) + if (supportsThumb2(CPUAttr)) Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2"); - else if (supportsThumb(ArchName, CPUArch, CPUArchVer)) + else if (supportsThumb(CPUAttr)) Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1"); // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit @@ -4462,7 +4475,7 @@ public: // FIXME: It's more complicated than this and we don't really support // interworking. // Windows on ARM does not "support" interworking - if (5 <= CPUArchVer && CPUArchVer <= 8 && !getTriple().isOSWindows()) + if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows()) Builder.defineMacro("__THUMB_INTERWORK__"); if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { @@ -4485,7 +4498,7 @@ public: if (IsThumb) { Builder.defineMacro("__THUMBEL__"); Builder.defineMacro("__thumb__"); - if (supportsThumb2(ArchName, CPUArch, CPUArchVer)) + if (supportsThumb2(CPUAttr)) Builder.defineMacro("__thumb2__"); } if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb)) @@ -4508,7 +4521,7 @@ public: // the VFP define, hence the soft float and arch check. This is subtly // different from gcc, we follow the intent which was that it should be set // when Neon instructions are actually available. - if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7) { + if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { Builder.defineMacro("__ARM_NEON"); Builder.defineMacro("__ARM_NEON__"); } @@ -4525,18 +4538,18 @@ public: if (Crypto) Builder.defineMacro("__ARM_FEATURE_CRYPTO"); - if (CPUArchVer >= 6 && CPUArch != "6M") { + if (ArchVersion >= 6 && CPUAttr != "6M") { Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } - bool is5EOrAbove = (CPUArchVer >= 6 || - (CPUArchVer == 5 && - CPUArch.find('E') != StringRef::npos)); - bool is32Bit = (!IsThumb || supportsThumb2(ArchName, CPUArch, CPUArchVer)); - if (is5EOrAbove && is32Bit && (CPUProfile != "M" || CPUArch == "7EM")) + bool is5EOrAbove = (ArchVersion >= 6 || + (ArchVersion == 5 && CPUAttr.count('E'))); + // FIXME: We are not getting all 32-bit ARM architectures + bool is32Bit = (!IsThumb || supportsThumb2(CPUAttr)); + if (is5EOrAbove && is32Bit && (CPUProfile != "M" || CPUAttr == "7EM")) Builder.defineMacro("__ARM_FEATURE_DSP"); } void getTargetBuiltins(const Builtin::Info *&Records, diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp index 8a882e13f7a5..a36102cf0f5a 100644 --- a/lib/Basic/VirtualFileSystem.cpp +++ b/lib/Basic/VirtualFileSystem.cpp @@ -324,20 +324,6 @@ directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, // VFSFromYAML implementation //===-----------------------------------------------------------------------===/ -// Allow DenseMap<StringRef, ...>. This is useful below because we know all the -// strings are literals and will outlive the map, and there is no reason to -// store them. -namespace llvm { - template<> - struct DenseMapInfo<StringRef> { - // This assumes that "" will never be a valid key. - static inline StringRef getEmptyKey() { return StringRef(""); } - static inline StringRef getTombstoneKey() { return StringRef(); } - static unsigned getHashValue(StringRef Val) { return HashString(Val); } - static bool isEqual(StringRef LHS, StringRef RHS) { return LHS == RHS; } - }; -} - namespace { enum EntryKind { diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index f5edea7810ab..0bccad0570da 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -536,7 +536,6 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath; Options.StackAlignmentOverride = CodeGenOpts.StackAlignment; - Options.TrapFuncName = CodeGenOpts.TrapFuncName; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.FunctionSections = CodeGenOpts.FunctionSections; Options.DataSections = CodeGenOpts.DataSections; @@ -604,7 +603,10 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, if (!TM) TM.reset(CreateTargetMachine(UsesCodeGen)); - if (UsesCodeGen && !TM) return; + if (UsesCodeGen && !TM) + return; + if (TM) + TheModule->setDataLayout(*TM->getDataLayout()); CreatePasses(); switch (Action) { diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index a14daac596f5..2ec909b9aac5 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -82,9 +82,9 @@ static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, /// Utility to insert an atomic instruction based on Instrinsic::ID /// and the expression node. -static RValue EmitBinaryAtomic(CodeGenFunction &CGF, - llvm::AtomicRMWInst::BinOp Kind, - const CallExpr *E) { +static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF, + llvm::AtomicRMWInst::BinOp Kind, + const CallExpr *E) { QualType T = E->getType(); assert(E->getArg(0)->getType()->isPointerType()); assert(CGF.getContext().hasSameUnqualifiedType(T, @@ -108,8 +108,13 @@ static RValue EmitBinaryAtomic(CodeGenFunction &CGF, llvm::Value *Result = CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], llvm::SequentiallyConsistent); - Result = EmitFromInt(CGF, Result, T, ValueType); - return RValue::get(Result); + return EmitFromInt(CGF, Result, T, ValueType); +} + +static RValue EmitBinaryAtomic(CodeGenFunction &CGF, + llvm::AtomicRMWInst::BinOp Kind, + const CallExpr *E) { + return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); } /// Utility to insert an atomic instruction based Instrinsic::ID and @@ -151,6 +156,47 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, return RValue::get(Result); } +/// @brief Utility to insert an atomic cmpxchg instruction. +/// +/// @param CGF The current codegen function. +/// @param E Builtin call expression to convert to cmpxchg. +/// arg0 - address to operate on +/// arg1 - value to compare with +/// arg2 - new value +/// @param ReturnBool Specifies whether to return success flag of +/// cmpxchg result or the old value. +/// +/// @returns result of cmpxchg, according to ReturnBool +static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E, + bool ReturnBool) { + QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType(); + llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); + unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); + + llvm::IntegerType *IntType = llvm::IntegerType::get( + CGF.getLLVMContext(), CGF.getContext().getTypeSize(T)); + llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); + + Value *Args[3]; + Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); + Args[1] = CGF.EmitScalarExpr(E->getArg(1)); + llvm::Type *ValueType = Args[1]->getType(); + Args[1] = EmitToInt(CGF, Args[1], T, IntType); + Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); + + Value *Pair = CGF.Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], + llvm::SequentiallyConsistent, + llvm::SequentiallyConsistent); + if (ReturnBool) + // Extract boolean success flag and zext it to int. + return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1), + CGF.ConvertType(E->getType())); + else + // Extract old value and emit it using the same type as compare value. + return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T, + ValueType); +} + /// EmitFAbs - Emit a call to @llvm.fabs(). static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) { Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); @@ -497,14 +543,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *F = CGM.getIntrinsic(Intrinsic::clear_cache); return RValue::get(Builder.CreateCall(F, {Begin, End})); } - case Builtin::BI__builtin_trap: { - Value *F = CGM.getIntrinsic(Intrinsic::trap); - return RValue::get(Builder.CreateCall(F, {})); - } - case Builtin::BI__debugbreak: { - Value *F = CGM.getIntrinsic(Intrinsic::debugtrap); - return RValue::get(Builder.CreateCall(F, {})); - } + case Builtin::BI__builtin_trap: + return RValue::get(EmitTrapCall(Intrinsic::trap)); + case Builtin::BI__debugbreak: + return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); case Builtin::BI__builtin_unreachable: { if (SanOpts.has(SanitizerKind::Unreachable)) { SanitizerScope SanScope(this); @@ -1057,58 +1099,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__sync_val_compare_and_swap_2: case Builtin::BI__sync_val_compare_and_swap_4: case Builtin::BI__sync_val_compare_and_swap_8: - case Builtin::BI__sync_val_compare_and_swap_16: { - QualType T = E->getType(); - llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); - unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); - - llvm::IntegerType *IntType = - llvm::IntegerType::get(getLLVMContext(), - getContext().getTypeSize(T)); - llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); - - Value *Args[3]; - Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); - Args[1] = EmitScalarExpr(E->getArg(1)); - llvm::Type *ValueType = Args[1]->getType(); - Args[1] = EmitToInt(*this, Args[1], T, IntType); - Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); - - Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], - llvm::SequentiallyConsistent, - llvm::SequentiallyConsistent); - Result = Builder.CreateExtractValue(Result, 0); - Result = EmitFromInt(*this, Result, T, ValueType); - return RValue::get(Result); - } + case Builtin::BI__sync_val_compare_and_swap_16: + return RValue::get(MakeAtomicCmpXchgValue(*this, E, false)); case Builtin::BI__sync_bool_compare_and_swap_1: case Builtin::BI__sync_bool_compare_and_swap_2: case Builtin::BI__sync_bool_compare_and_swap_4: case Builtin::BI__sync_bool_compare_and_swap_8: - case Builtin::BI__sync_bool_compare_and_swap_16: { - QualType T = E->getArg(1)->getType(); - llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); - unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); - - llvm::IntegerType *IntType = - llvm::IntegerType::get(getLLVMContext(), - getContext().getTypeSize(T)); - llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); - - Value *Args[3]; - Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); - Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType); - Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); - - Value *Pair = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], - llvm::SequentiallyConsistent, - llvm::SequentiallyConsistent); - Value *Result = Builder.CreateExtractValue(Pair, 1); - // zext bool to int. - Result = Builder.CreateZExt(Result, ConvertType(E->getType())); - return RValue::get(Result); - } + case Builtin::BI__sync_bool_compare_and_swap_16: + return RValue::get(MakeAtomicCmpXchgValue(*this, E, true)); case Builtin::BI__sync_swap_1: case Builtin::BI__sync_swap_2: @@ -1880,6 +1879,9 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, return EmitAMDGPUBuiltinExpr(BuiltinID, E); case llvm::Triple::systemz: return EmitSystemZBuiltinExpr(BuiltinID, E); + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + return EmitNVPTXBuiltinExpr(BuiltinID, E); default: return nullptr; } @@ -3339,6 +3341,42 @@ static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF, return Builder.CreateCall(F, { Metadata, ArgValue }); } +/// Return true if BuiltinID is an overloaded Neon intrinsic with an extra +/// argument that specifies the vector type. +static bool HasExtraNeonArgument(unsigned BuiltinID) { + switch (BuiltinID) { + default: break; + case NEON::BI__builtin_neon_vget_lane_i8: + case NEON::BI__builtin_neon_vget_lane_i16: + case NEON::BI__builtin_neon_vget_lane_i32: + case NEON::BI__builtin_neon_vget_lane_i64: + case NEON::BI__builtin_neon_vget_lane_f32: + case NEON::BI__builtin_neon_vgetq_lane_i8: + case NEON::BI__builtin_neon_vgetq_lane_i16: + case NEON::BI__builtin_neon_vgetq_lane_i32: + case NEON::BI__builtin_neon_vgetq_lane_i64: + case NEON::BI__builtin_neon_vgetq_lane_f32: + case NEON::BI__builtin_neon_vset_lane_i8: + case NEON::BI__builtin_neon_vset_lane_i16: + case NEON::BI__builtin_neon_vset_lane_i32: + case NEON::BI__builtin_neon_vset_lane_i64: + case NEON::BI__builtin_neon_vset_lane_f32: + case NEON::BI__builtin_neon_vsetq_lane_i8: + case NEON::BI__builtin_neon_vsetq_lane_i16: + case NEON::BI__builtin_neon_vsetq_lane_i32: + case NEON::BI__builtin_neon_vsetq_lane_i64: + case NEON::BI__builtin_neon_vsetq_lane_f32: + case NEON::BI__builtin_neon_vsha1h_u32: + case NEON::BI__builtin_neon_vsha1cq_u32: + case NEON::BI__builtin_neon_vsha1pq_u32: + case NEON::BI__builtin_neon_vsha1mq_u32: + case ARM::BI_MoveToCoprocessor: + case ARM::BI_MoveToCoprocessor2: + return false; + } + return true; +} + Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (auto Hint = GetValueForARMHint(BuiltinID)) @@ -3591,7 +3629,9 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, SmallVector<Value*, 4> Ops; llvm::Value *Align = nullptr; - for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { + bool HasExtraArg = HasExtraNeonArgument(BuiltinID); + unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0); + for (unsigned i = 0, e = NumArgs; i != e; i++) { if (i == 0) { switch (BuiltinID) { case NEON::BI__builtin_neon_vld1_v: @@ -3666,8 +3706,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, switch (BuiltinID) { default: break; - // vget_lane and vset_lane are not overloaded and do not have an extra - // argument that specifies the vector type. + case NEON::BI__builtin_neon_vget_lane_i8: case NEON::BI__builtin_neon_vget_lane_i16: case NEON::BI__builtin_neon_vget_lane_i32: @@ -3678,8 +3717,8 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vgetq_lane_i32: case NEON::BI__builtin_neon_vgetq_lane_i64: case NEON::BI__builtin_neon_vgetq_lane_f32: - return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), - "vget_lane"); + return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); + case NEON::BI__builtin_neon_vset_lane_i8: case NEON::BI__builtin_neon_vset_lane_i16: case NEON::BI__builtin_neon_vset_lane_i32: @@ -3690,29 +3729,34 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vsetq_lane_i32: case NEON::BI__builtin_neon_vsetq_lane_i64: case NEON::BI__builtin_neon_vsetq_lane_f32: - Ops.push_back(EmitScalarExpr(E->getArg(2))); return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); - // Non-polymorphic crypto instructions also not overloaded case NEON::BI__builtin_neon_vsha1h_u32: - Ops.push_back(EmitScalarExpr(E->getArg(0))); return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, "vsha1h"); case NEON::BI__builtin_neon_vsha1cq_u32: - Ops.push_back(EmitScalarExpr(E->getArg(2))); return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, "vsha1h"); case NEON::BI__builtin_neon_vsha1pq_u32: - Ops.push_back(EmitScalarExpr(E->getArg(2))); return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, "vsha1h"); case NEON::BI__builtin_neon_vsha1mq_u32: - Ops.push_back(EmitScalarExpr(E->getArg(2))); return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, "vsha1h"); + + // The ARM _MoveToCoprocessor builtins put the input register value as + // the first argument, but the LLVM intrinsic expects it as the third one. + case ARM::BI_MoveToCoprocessor: + case ARM::BI_MoveToCoprocessor2: { + Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ? + Intrinsic::arm_mcr : Intrinsic::arm_mcr2); + return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], + Ops[3], Ops[4], Ops[5]}); + } } // Get the last argument, which specifies the vector type. + assert(HasExtraArg); llvm::APSInt Result; const Expr *Arg = E->getArg(E->getNumArgs()-1); if (!Arg->isIntegerConstantExpr(Result, getContext())) @@ -6053,6 +6097,83 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, switch (BuiltinID) { default: return nullptr; + case X86::BI__builtin_cpu_supports: { + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); + + // TODO: When/if this becomes more than x86 specific then use a TargetInfo + // based mapping. + // Processor features and mapping to processor feature value. + enum X86Features { + CMOV = 0, + MMX, + POPCNT, + SSE, + SSE2, + SSE3, + SSSE3, + SSE4_1, + SSE4_2, + AVX, + AVX2, + SSE4_A, + FMA4, + XOP, + FMA, + AVX512F, + BMI, + BMI2, + MAX + }; + + X86Features Feature = StringSwitch<X86Features>(FeatureStr) + .Case("cmov", X86Features::CMOV) + .Case("mmx", X86Features::MMX) + .Case("popcnt", X86Features::POPCNT) + .Case("sse", X86Features::SSE) + .Case("sse2", X86Features::SSE2) + .Case("sse3", X86Features::SSE3) + .Case("sse4.1", X86Features::SSE4_1) + .Case("sse4.2", X86Features::SSE4_2) + .Case("avx", X86Features::AVX) + .Case("avx2", X86Features::AVX2) + .Case("sse4a", X86Features::SSE4_A) + .Case("fma4", X86Features::FMA4) + .Case("xop", X86Features::XOP) + .Case("fma", X86Features::FMA) + .Case("avx512f", X86Features::AVX512F) + .Case("bmi", X86Features::BMI) + .Case("bmi2", X86Features::BMI2) + .Default(X86Features::MAX); + assert(Feature != X86Features::MAX && "Invalid feature!"); + + // Matching the struct layout from the compiler-rt/libgcc structure that is + // filled in: + // unsigned int __cpu_vendor; + // unsigned int __cpu_type; + // unsigned int __cpu_subtype; + // unsigned int __cpu_features[1]; + llvm::Type *STy = llvm::StructType::get( + Int32Ty, Int32Ty, Int32Ty, llvm::ArrayType::get(Int32Ty, 1), nullptr); + + // Grab the global __cpu_model. + llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); + + // Grab the first (0th) element from the field __cpu_features off of the + // global in the struct STy. + Value *Idxs[] = { + ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, 3), + ConstantInt::get(Int32Ty, 0) + }; + Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); + Value *Features = Builder.CreateLoad(CpuFeatures); + + // Check the value of the bit corresponding to the feature requested. + Value *Bitset = Builder.CreateAnd( + Features, llvm::ConstantInt::get(Int32Ty, 1 << Feature)); + return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0)); + } case X86::BI_mm_prefetch: { Value *Address = EmitScalarExpr(E->getArg(0)); Value *RW = ConstantInt::get(Int32Ty, 0); @@ -6512,6 +6633,13 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, llvm::Function *F = CGM.getIntrinsic(ID); return Builder.CreateCall(F, Ops, ""); } + case PPC::BI__builtin_vsx_xvrspip: + case PPC::BI__builtin_vsx_xvrdpip: + llvm::Type *ResultType = ConvertType(E->getType()); + Value *X = EmitScalarExpr(E->getArg(0)); + ID = Intrinsic::ceil; + llvm::Function *F = CGM.getIntrinsic(ID, ResultType); + return Builder.CreateCall(F, X); } } @@ -6859,3 +6987,72 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, return nullptr; } } + +Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, + const CallExpr *E) { + switch (BuiltinID) { + case NVPTX::BI__nvvm_atom_add_gen_i: + case NVPTX::BI__nvvm_atom_add_gen_l: + case NVPTX::BI__nvvm_atom_add_gen_ll: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E); + + case NVPTX::BI__nvvm_atom_sub_gen_i: + case NVPTX::BI__nvvm_atom_sub_gen_l: + case NVPTX::BI__nvvm_atom_sub_gen_ll: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E); + + case NVPTX::BI__nvvm_atom_and_gen_i: + case NVPTX::BI__nvvm_atom_and_gen_l: + case NVPTX::BI__nvvm_atom_and_gen_ll: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E); + + case NVPTX::BI__nvvm_atom_or_gen_i: + case NVPTX::BI__nvvm_atom_or_gen_l: + case NVPTX::BI__nvvm_atom_or_gen_ll: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E); + + case NVPTX::BI__nvvm_atom_xor_gen_i: + case NVPTX::BI__nvvm_atom_xor_gen_l: + case NVPTX::BI__nvvm_atom_xor_gen_ll: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E); + + case NVPTX::BI__nvvm_atom_xchg_gen_i: + case NVPTX::BI__nvvm_atom_xchg_gen_l: + case NVPTX::BI__nvvm_atom_xchg_gen_ll: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E); + + case NVPTX::BI__nvvm_atom_max_gen_i: + case NVPTX::BI__nvvm_atom_max_gen_l: + case NVPTX::BI__nvvm_atom_max_gen_ll: + case NVPTX::BI__nvvm_atom_max_gen_ui: + case NVPTX::BI__nvvm_atom_max_gen_ul: + case NVPTX::BI__nvvm_atom_max_gen_ull: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E); + + case NVPTX::BI__nvvm_atom_min_gen_i: + case NVPTX::BI__nvvm_atom_min_gen_l: + case NVPTX::BI__nvvm_atom_min_gen_ll: + case NVPTX::BI__nvvm_atom_min_gen_ui: + case NVPTX::BI__nvvm_atom_min_gen_ul: + case NVPTX::BI__nvvm_atom_min_gen_ull: + return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E); + + case NVPTX::BI__nvvm_atom_cas_gen_i: + case NVPTX::BI__nvvm_atom_cas_gen_l: + case NVPTX::BI__nvvm_atom_cas_gen_ll: + return MakeAtomicCmpXchgValue(*this, E, true); + + case NVPTX::BI__nvvm_atom_add_gen_f: { + Value *Ptr = EmitScalarExpr(E->getArg(0)); + Value *Val = EmitScalarExpr(E->getArg(1)); + // atomicrmw only deals with integer arguments so we need to use + // LLVM's nvvm_atomic_load_add_f32 intrinsic for that. + Value *FnALAF32 = + CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType()); + return Builder.CreateCall(FnALAF32, {Ptr, Val}); + } + + default: + return nullptr; + } +} diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp index cb7e6dfca1c5..dc16616df9c5 100644 --- a/lib/CodeGen/CGCXXABI.cpp +++ b/lib/CodeGen/CGCXXABI.cpp @@ -130,10 +130,9 @@ CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { return GetBogusMemberPointer(QualType(MPT, 0)); } -llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { - return GetBogusMemberPointer( - CGM.getContext().getMemberPointerType(MD->getType(), - MD->getParent()->getTypeForDecl())); +llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { + return GetBogusMemberPointer(CGM.getContext().getMemberPointerType( + MD->getType(), MD->getParent()->getTypeForDecl())); } llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index b6b4ee6850ac..436b96a615ef 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -172,7 +172,7 @@ public: virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); /// Create a member pointer for the given method. - virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); + virtual llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD); /// Create a member pointer for the given field. virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 58ef171df0d7..0535c05da5d5 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -32,7 +32,6 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/Transforms/Utils/Local.h" -#include <sstream> using namespace clang; using namespace CodeGen; @@ -1453,6 +1452,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, // Attributes that should go on the call site only. if (!CodeGenOpts.SimplifyLibCalls) FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin); + if (!CodeGenOpts.TrapFuncName.empty()) + FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName); } else { // Attributes that should go on the function, but not the call site. if (!CodeGenOpts.DisableFPElim) { @@ -1493,12 +1494,16 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, // avoid putting features in the target-features set if we know it'll be // one of the default features in the backend, e.g. corei7-avx and +avx or // figure out non-explicit dependencies. - std::vector<std::string> Features(getTarget().getTargetOpts().Features); + // Canonicalize the existing features in a new feature map. + // TODO: Migrate the existing backends to keep the map around rather than + // the vector. + llvm::StringMap<bool> FeatureMap; + for (auto F : getTarget().getTargetOpts().Features) { + const char *Name = F.c_str(); + bool Enabled = Name[0] == '+'; + getTarget().setFeatureEnabled(FeatureMap, Name + 1, Enabled); + } - // TODO: The target attribute complicates this further by allowing multiple - // additional features to be tacked on to the feature string for a - // particular function. For now we simply append to the set of features and - // let backend resolution fix them up. const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl); if (FD) { if (const TargetAttr *TD = FD->getAttr<TargetAttr>()) { @@ -1507,7 +1512,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, FeaturesStr.split(AttrFeatures, ","); // Grab the various features and prepend a "+" to turn on the feature to - // the backend and add them to our existing set of Features. + // the backend and add them to our existing set of features. for (auto &Feature : AttrFeatures) { // While we're here iterating check for a different target cpu. if (Feature.startswith("arch=")) @@ -1521,24 +1526,28 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, // attributes on the function. ; else if (Feature.startswith("mno-")) - Features.push_back("-" + Feature.split("-").second.str()); + getTarget().setFeatureEnabled(FeatureMap, Feature.split("-").second, + false); else - Features.push_back("+" + Feature.str()); - } + getTarget().setFeatureEnabled(FeatureMap, Feature, true); + } } } + // Produce the canonical string for this set of features. + std::vector<std::string> Features; + for (llvm::StringMap<bool>::const_iterator it = FeatureMap.begin(), + ie = FeatureMap.end(); + it != ie; ++it) + Features.push_back((it->second ? "+" : "-") + it->first().str()); + // Now add the target-cpu and target-features to the function. if (TargetCPU != "") FuncAttrs.addAttribute("target-cpu", TargetCPU); if (!Features.empty()) { - std::stringstream TargetFeatures; - std::copy(Features.begin(), Features.end(), - std::ostream_iterator<std::string>(TargetFeatures, ",")); - - // The drop_back gets rid of the trailing space. + std::sort(Features.begin(), Features.end()); FuncAttrs.addAttribute("target-features", - StringRef(TargetFeatures.str()).drop_back(1)); + llvm::join(Features.begin(), Features.end(), ",")); } } diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 1d2b7875d8f7..62df9820a6c3 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -29,13 +29,12 @@ using namespace clang; using namespace CodeGen; -static CharUnits -ComputeNonVirtualBaseClassOffset(ASTContext &Context, - const CXXRecordDecl *DerivedClass, - CastExpr::path_const_iterator Start, - CastExpr::path_const_iterator End) { +CharUnits CodeGenModule::computeNonVirtualBaseClassOffset( + const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, + CastExpr::path_const_iterator End) { CharUnits Offset = CharUnits::Zero(); + const ASTContext &Context = getContext(); const CXXRecordDecl *RD = DerivedClass; for (CastExpr::path_const_iterator I = Start; I != End; ++I) { @@ -64,8 +63,7 @@ CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, assert(PathBegin != PathEnd && "Base path should not be empty!"); CharUnits Offset = - ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, - PathBegin, PathEnd); + computeNonVirtualBaseClassOffset(ClassDecl, PathBegin, PathEnd); if (Offset.isZero()) return nullptr; @@ -158,9 +156,8 @@ llvm::Value *CodeGenFunction::GetAddressOfBaseClass( // Compute the static offset of the ultimate destination within its // allocating subobject (the virtual base, if there is one, or else // the "complete" object that we see). - CharUnits NonVirtualOffset = - ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, - Start, PathEnd); + CharUnits NonVirtualOffset = CGM.computeNonVirtualBaseClassOffset( + VBase ? VBase : Derived, Start, PathEnd); // If there's a virtual step, we can sometimes "devirtualize" it. // For now, that's limited to when the derived type is final. @@ -1342,6 +1339,11 @@ FieldHasTrivialDestructorBody(ASTContext &Context, return true; CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); + + // The destructor for an implicit anonymous union member is never invoked. + if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) + return false; + return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); } diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index a20e39f3fc00..8c4b4b3d0617 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -27,6 +27,8 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Constants.h" @@ -1179,12 +1181,13 @@ void CGDebugInfo::CollectCXXMemberFunctions( // the member being added to type units by LLVM, while still allowing it // to be emitted into the type declaration/reference inside the compile // unit. + // Ditto 'nodebug' methods, for consistency with CodeGenFunction.cpp. // FIXME: Handle Using(Shadow?)Decls here to create // DW_TAG_imported_declarations inside the class for base decls brought into // derived classes. GDB doesn't seem to notice/leverage these when I tried // it, so I'm not rushing to fix this. (GCC seems to produce them, if // referenced) - if (!Method || Method->isImplicit()) + if (!Method || Method->isImplicit() || Method->hasAttr<NoDebugAttr>()) continue; if (Method->getType()->getAs<FunctionProtoType>()->getContainedAutoType()) @@ -1279,7 +1282,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, // Member function pointers have special support for building them, though // this is currently unsupported in LLVM CodeGen. else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->isInstance()) - V = CGM.getCXXABI().EmitMemberPointer(MD); + V = CGM.getCXXABI().EmitMemberFunctionPointer(MD); else if (const auto *FD = dyn_cast<FunctionDecl>(D)) V = CGM.GetAddrOfFunction(FD); // Member data pointers have special handling too to compute the fixed @@ -1660,6 +1663,47 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, return CreateTypeDefinition(Ty, Unit); } +llvm::DIModule * +CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod) { + auto it = ModuleRefCache.find(Mod.Signature); + if (it != ModuleRefCache.end()) + return it->second; + + // Macro definitions that were defined with "-D" on the command line. + SmallString<128> ConfigMacros; + { + llvm::raw_svector_ostream OS(ConfigMacros); + const auto &PPOpts = CGM.getPreprocessorOpts(); + unsigned I = 0; + // Translate the macro definitions back into a commmand line. + for (auto &M : PPOpts.Macros) { + if (++I > 1) + OS << " "; + const std::string &Macro = M.first; + bool Undef = M.second; + OS << "\"-" << (Undef ? 'U' : 'D'); + for (char c : Macro) + switch (c) { + case '\\' : OS << "\\\\"; break; + case '"' : OS << "\\\""; break; + default: OS << c; + } + OS << '\"'; + } + } + llvm::DIBuilder DIB(CGM.getModule()); + auto *CU = DIB.createCompileUnit( + TheCU->getSourceLanguage(), internString(Mod.ModuleName), + internString(Mod.Path), TheCU->getProducer(), true, StringRef(), 0, + internString(Mod.ASTFile), llvm::DIBuilder::FullDebug, Mod.Signature); + llvm::DIModule *ModuleRef = + DIB.createModule(CU, Mod.ModuleName, ConfigMacros, internString(Mod.Path), + internString(CGM.getHeaderSearchOpts().Sysroot)); + DIB.finalize(); + ModuleRefCache.insert(std::make_pair(Mod.Signature, ModuleRef)); + return ModuleRef; +} + llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIFile *Unit) { ObjCInterfaceDecl *ID = Ty->getDecl(); @@ -3303,6 +3347,15 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { getLineNumber(USD.getLocation())); } +void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) { + auto *Reader = CGM.getContext().getExternalSource(); + auto Info = Reader->getSourceDescriptor(*ID.getImportedModule()); + DBuilder.createImportedDeclaration( + getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())), + getOrCreateModuleRef(Info), + getLineNumber(ID.getLocation())); +} + llvm::DIImportedEntity * CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 8509e0770db6..10d3b0d9ab02 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -83,6 +83,9 @@ class CGDebugInfo { /// which may change. llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache; + /// \brief Cache of references to AST files such as PCHs or modules. + llvm::DenseMap<uint64_t, llvm::DIModule *> ModuleRefCache; + /// \brief list of interfaces we want to keep even if orphaned. std::vector<void *> RetainedTypes; @@ -289,6 +292,9 @@ public: /// \brief Emit C++ using declaration. void EmitUsingDecl(const UsingDecl &UD); + /// \brief Emit an @import declaration. + void EmitImportDecl(const ImportDecl &ID); + /// \brief Emit C++ namespace alias. llvm::DIImportedEntity *EmitNamespaceAlias(const NamespaceAliasDecl &NA); @@ -344,6 +350,10 @@ private: /// necessary. llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg); + /// \brief Get a reference to a clang module. + llvm::DIModule * + getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod); + /// \brief Get the type from the cache or create a new /// partial type if necessary. llvm::DIType *getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile *F); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 07dbce4252fe..839c2e474ca3 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -579,9 +579,9 @@ static bool isAccessedBy(const VarDecl &var, const Stmt *s) { } } - for (Stmt::const_child_range children = s->children(); children; ++children) - // children might be null; as in missing decl or conditional of an if-stmt. - if ((*children) && isAccessedBy(var, *children)) + for (const Stmt *SubStmt : s->children()) + // SubStmt might be null; as in missing decl or conditional of an if-stmt. + if (SubStmt && isAccessedBy(var, SubStmt)) return true; return false; @@ -1074,8 +1074,8 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) { return false; } - for (Stmt::const_child_range children = e->children(); children; ++children) - if (isCapturedBy(var, cast<Expr>(*children))) + for (const Stmt *SubStmt : e->children()) + if (isCapturedBy(var, cast<Expr>(SubStmt))) return true; return false; diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 1a76afaf1158..175763c4e815 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2403,8 +2403,7 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) { TrapBB = createBasicBlock("trap"); Builder.CreateCondBr(Checked, Cont, TrapBB); EmitBlock(TrapBB); - llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap); - llvm::CallInst *TrapCall = Builder.CreateCall(F, {}); + llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); TrapCall->setDoesNotReturn(); TrapCall->setDoesNotThrow(); Builder.CreateUnreachable(); @@ -2415,6 +2414,18 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) { EmitBlock(Cont); } +llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) { + llvm::CallInst *TrapCall = + Builder.CreateCall(CGM.getIntrinsic(IntrID), {}); + + if (!CGM.getCodeGenOpts().TrapFuncName.empty()) + TrapCall->addAttribute(llvm::AttributeSet::FunctionIndex, + "trap-func-name", + CGM.getCodeGenOpts().TrapFuncName); + + return TrapCall; +} + /// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an /// array to pointer, return the array subexpression. static const Expr *isSimpleArrayDecayOperand(const Expr *E) { diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index f0f706d7b957..c7adccaeeaea 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -1548,7 +1548,8 @@ namespace { // The size of an element, multiplied by the number of elements. llvm::Value *Size = llvm::ConstantInt::get(SizeTy, ElementTypeSize.getQuantity()); - Size = CGF.Builder.CreateMul(Size, NumElements); + if (NumElements) + Size = CGF.Builder.CreateMul(Size, NumElements); // Plus the size of the cookie if applicable. if (!CookieSize.isZero()) { diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index acfb9b6dbb25..a15c151d6f9d 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -1452,7 +1452,7 @@ CodeGenModule::getMemberPointerConstant(const UnaryOperator *uo) { // A member function pointer. if (const CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(decl)) - return getCXXABI().EmitMemberPointer(method); + return getCXXABI().EmitMemberFunctionPointer(method); // Otherwise, a member data pointer. uint64_t fieldOffset = getContext().getFieldOffset(decl); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 330a0dffb244..c73f1189314e 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -16,6 +16,7 @@ #include "CGDebugInfo.h" #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/RecordLayout.h" @@ -2037,6 +2038,13 @@ ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( return size; } + } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) { + auto Alignment = + CGF.getContext() + .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( + E->getTypeOfArgument()->getPointeeType())) + .getQuantity(); + return llvm::ConstantInt::get(CGF.SizeTy, Alignment); } // If this isn't sizeof(vla), the result must be constant; use the constant diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 9981fccb3e9d..747326e4c5bc 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -55,13 +55,15 @@ llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) /// EmitObjCBoxedExpr - This routine generates code to call /// the appropriate expression boxing method. This will either be -/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:]. +/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:], +/// or [NSValue valueWithBytes:objCType:]. /// llvm::Value * CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { // Generate the correct selector for this literal's concrete type. // Get the method. const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod(); + const Expr *SubExpr = E->getSubExpr(); assert(BoxingMethod && "BoxingMethod is null"); assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method"); Selector Sel = BoxingMethod->getSelector(); @@ -74,7 +76,35 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl); CallArgList Args; - EmitCallArgs(Args, BoxingMethod, E->arg_begin(), E->arg_end()); + const ParmVarDecl *ArgDecl = *BoxingMethod->param_begin(); + QualType ArgQT = ArgDecl->getType().getUnqualifiedType(); + + // ObjCBoxedExpr supports boxing of structs and unions + // via [NSValue valueWithBytes:objCType:] + const QualType ValueType(SubExpr->getType().getCanonicalType()); + if (ValueType->isObjCBoxableRecordType()) { + // Emit CodeGen for first parameter + // and cast value to correct type + llvm::Value *Temporary = CreateMemTemp(SubExpr->getType()); + EmitAnyExprToMem(SubExpr, Temporary, Qualifiers(), /*isInit*/ true); + llvm::Value *BitCast = Builder.CreateBitCast(Temporary, + ConvertType(ArgQT)); + Args.add(RValue::get(BitCast), ArgQT); + + // Create char array to store type encoding + std::string Str; + getContext().getObjCEncodingForType(ValueType, Str); + llvm::GlobalVariable *GV = CGM.GetAddrOfConstantCString(Str); + + // Cast type encoding to correct type + const ParmVarDecl *EncodingDecl = BoxingMethod->parameters()[1]; + QualType EncodingQT = EncodingDecl->getType().getUnqualifiedType(); + llvm::Value *Cast = Builder.CreateBitCast(GV, ConvertType(EncodingQT)); + + Args.add(RValue::get(Cast), EncodingQT); + } else { + Args.add(EmitAnyExpr(SubExpr), ArgQT); + } RValue result = Runtime.GenerateMessageSend( *this, ReturnValueSlot(), BoxingMethod->getReturnType(), Sel, Receiver, diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 3161af36c23e..534d148209ba 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -45,14 +45,14 @@ public: CGOpenMPRegionInfo(const CapturedStmt &CS, const CGOpenMPRegionKind RegionKind, - const RegionCodeGenTy &CodeGen) + const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind) : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind), - CodeGen(CodeGen) {} + CodeGen(CodeGen), Kind(Kind) {} CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind, - const RegionCodeGenTy &CodeGen) - : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), - CodeGen(CodeGen) {} + const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind) + : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen), + Kind(Kind) {} /// \brief Get a variable or parameter for storing global thread id /// inside OpenMP construct. @@ -67,6 +67,8 @@ public: CGOpenMPRegionKind getRegionKind() const { return RegionKind; } + OpenMPDirectiveKind getDirectiveKind() const { return Kind; } + static bool classof(const CGCapturedStmtInfo *Info) { return Info->getKind() == CR_OpenMP; } @@ -74,14 +76,16 @@ public: protected: CGOpenMPRegionKind RegionKind; const RegionCodeGenTy &CodeGen; + OpenMPDirectiveKind Kind; }; /// \brief API for captured statement code generation in OpenMP constructs. class CGOpenMPOutlinedRegionInfo : public CGOpenMPRegionInfo { public: CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar, - const RegionCodeGenTy &CodeGen) - : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen), + const RegionCodeGenTy &CodeGen, + OpenMPDirectiveKind Kind) + : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind), ThreadIDVar(ThreadIDVar) { assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region."); } @@ -109,8 +113,9 @@ class CGOpenMPTaskOutlinedRegionInfo : public CGOpenMPRegionInfo { public: CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar, - const RegionCodeGenTy &CodeGen) - : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen), + const RegionCodeGenTy &CodeGen, + OpenMPDirectiveKind Kind) + : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind), ThreadIDVar(ThreadIDVar) { assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region."); } @@ -141,8 +146,9 @@ private: class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo { public: CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI, - const RegionCodeGenTy &CodeGen) - : CGOpenMPRegionInfo(InlinedRegion, CodeGen), OldCSI(OldCSI), + const RegionCodeGenTy &CodeGen, + OpenMPDirectiveKind Kind) + : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind), OldCSI(OldCSI), OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {} // \brief Retrieve the value of the context parameter. llvm::Value *getContextValue() const override { @@ -207,11 +213,12 @@ public: /// \param CodeGen Code generation sequence for combined directives. Includes /// a list of functions used for code generation of implicitly inlined /// regions. - InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen) + InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen, + OpenMPDirectiveKind Kind) : CGF(CGF) { // Start emission for the construct. CGF.CapturedStmtInfo = - new CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen); + new CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen, Kind); } ~InlinedOpenMPRegionRAII() { // Restore original CapturedStmtInfo only if we're done with code emission. @@ -273,29 +280,28 @@ void CGOpenMPRuntime::clear() { InternalVars.clear(); } -llvm::Value * -CGOpenMPRuntime::emitParallelOutlinedFunction(const OMPExecutableDirective &D, - const VarDecl *ThreadIDVar, - const RegionCodeGenTy &CodeGen) { +llvm::Value *CGOpenMPRuntime::emitParallelOutlinedFunction( + const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, + OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) { assert(ThreadIDVar->getType()->isPointerType() && "thread id variable must be of type kmp_int32 *"); const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt()); CodeGenFunction CGF(CGM, true); - CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen); - CGF.CapturedStmtInfo = &CGInfo; + CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind); + CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo); return CGF.GenerateCapturedStmtFunction(*CS); } -llvm::Value * -CGOpenMPRuntime::emitTaskOutlinedFunction(const OMPExecutableDirective &D, - const VarDecl *ThreadIDVar, - const RegionCodeGenTy &CodeGen) { +llvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction( + const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, + OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) { assert(!ThreadIDVar->getType()->isPointerType() && "thread id variable must be of type kmp_int32 for tasks"); auto *CS = cast<CapturedStmt>(D.getAssociatedStmt()); CodeGenFunction CGF(CGM, true); - CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen); - CGF.CapturedStmtInfo = &CGInfo; + CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, + InnermostKind); + CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo); return CGF.GenerateCapturedStmtFunction(*CS); } @@ -530,6 +536,14 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) { RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier"); break; } + case OMPRTL__kmpc_barrier: { + // Build void __kmpc_cancel_barrier(ident_t *loc, kmp_int32 global_tid); + llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; + llvm::FunctionType *FnTy = + llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); + RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier"); + break; + } case OMPRTL__kmpc_for_static_fini: { // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid); llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; @@ -781,6 +795,40 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) { RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind"); break; } + case OMPRTL__kmpc_omp_task_with_deps: { + // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid, + // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list, + // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list); + llvm::Type *TypeParams[] = { + getIdentTyPointerTy(), CGM.Int32Ty, CGM.VoidPtrTy, CGM.Int32Ty, + CGM.VoidPtrTy, CGM.Int32Ty, CGM.VoidPtrTy}; + llvm::FunctionType *FnTy = + llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false); + RTLFn = + CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_with_deps"); + break; + } + case OMPRTL__kmpc_omp_wait_deps: { + // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid, + // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias, + // kmp_depend_info_t *noalias_dep_list); + llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, + CGM.Int32Ty, CGM.VoidPtrTy, + CGM.Int32Ty, CGM.VoidPtrTy}; + llvm::FunctionType *FnTy = + llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false); + RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps"); + break; + } + case OMPRTL__kmpc_cancellationpoint: { + // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32 + // global_tid, kmp_int32 cncl_kind) + llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy}; + llvm::FunctionType *FnTy = + llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false); + RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint"); + break; + } } return RTLFn; } @@ -1212,11 +1260,12 @@ void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF, CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>( NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_critical), llvm::makeArrayRef(Args)); - emitInlinedDirective(CGF, CriticalOpGen); + emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen); } } static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond, + OpenMPDirectiveKind Kind, const RegionCodeGenTy &BodyOpGen) { llvm::Value *CallBool = CGF.EmitScalarConversion( IfCond, @@ -1228,7 +1277,7 @@ static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond, // Generate the branch (If-stmt) CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock); CGF.EmitBlock(ThenBlock); - CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, BodyOpGen); + CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, Kind, BodyOpGen); // Emit the rest of bblocks/branches CGF.EmitBranch(ContBlock); CGF.EmitBlock(ContBlock, true); @@ -1247,7 +1296,7 @@ void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF, CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_master), Args); typedef CallEndCleanup<std::extent<decltype(Args)>::value> MasterCallEndCleanup; - emitIfStmt(CGF, IsMaster, [&](CodeGenFunction &CGF) -> void { + emitIfStmt(CGF, IsMaster, OMPD_master, [&](CodeGenFunction &CGF) -> void { CodeGenFunction::RunCleanupsScope Scope(CGF); CGF.EHStack.pushCleanup<MasterCallEndCleanup>( NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_master), @@ -1280,7 +1329,7 @@ void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF, CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>( NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_taskgroup), llvm::makeArrayRef(Args)); - emitInlinedDirective(CGF, TaskgroupOpGen); + emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen); } } @@ -1376,7 +1425,7 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_single), Args); typedef CallEndCleanup<std::extent<decltype(Args)>::value> SingleCallEndCleanup; - emitIfStmt(CGF, IsSingle, [&](CodeGenFunction &CGF) -> void { + emitIfStmt(CGF, IsSingle, OMPD_single, [&](CodeGenFunction &CGF) -> void { CodeGenFunction::RunCleanupsScope Scope(CGF); CGF.EHStack.pushCleanup<SingleCallEndCleanup>( NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_single), @@ -1444,13 +1493,15 @@ void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF, CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>( NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_ordered), llvm::makeArrayRef(Args)); - emitInlinedDirective(CGF, OrderedOpGen); + emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen); } } void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPDirectiveKind Kind) { + OpenMPDirectiveKind Kind, + bool CheckForCancel) { // Build call __kmpc_cancel_barrier(loc, thread_id); + // Build call __kmpc_barrier(loc, thread_id); OpenMPLocationFlags Flags = OMP_IDENT_KMPC; if (Kind == OMPD_for) { Flags = @@ -1466,15 +1517,34 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, } else { Flags = static_cast<OpenMPLocationFlags>(Flags | OMP_IDENT_BARRIER_IMPL); } - // Build call __kmpc_cancel_barrier(loc, thread_id); - // Replace __kmpc_barrier() function by __kmpc_cancel_barrier() because this - // one provides the same functionality and adds initial support for - // cancellation constructs introduced in OpenMP 4.0. __kmpc_cancel_barrier() - // is provided default by the runtime library so it safe to make such - // replacement. + // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc, + // thread_id); llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags), getThreadID(CGF, Loc)}; - CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args); + if (auto *OMPRegionInfo = + dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { + auto CancelDestination = + CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); + if (CancelDestination.isValid()) { + auto *Result = CGF.EmitRuntimeCall( + createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args); + if (CheckForCancel) { + // if (__kmpc_cancel_barrier()) { + // exit from construct; + // } + auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); + auto *ContBB = CGF.createBasicBlock(".cancel.continue"); + auto *Cmp = CGF.Builder.CreateIsNotNull(Result); + CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); + CGF.EmitBlock(ExitBB); + // exit from construct; + CGF.EmitBranchThroughCleanup(CancelDestination); + CGF.EmitBlock(ContBB, /*IsFinished=*/true); + } + return; + } + } + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_barrier), Args); } /// \brief Schedule types for 'omp for' loops (these enumerators are taken from @@ -2009,11 +2079,12 @@ void CGOpenMPRuntime::emitTaskCall( CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final, llvm::Value *TaskFunction, QualType SharedsTy, llvm::Value *Shareds, - const Expr *IfCond, const ArrayRef<const Expr *> PrivateVars, - const ArrayRef<const Expr *> PrivateCopies, - const ArrayRef<const Expr *> FirstprivateVars, - const ArrayRef<const Expr *> FirstprivateCopies, - const ArrayRef<const Expr *> FirstprivateInits) { + const Expr *IfCond, ArrayRef<const Expr *> PrivateVars, + ArrayRef<const Expr *> PrivateCopies, + ArrayRef<const Expr *> FirstprivateVars, + ArrayRef<const Expr *> FirstprivateCopies, + ArrayRef<const Expr *> FirstprivateInits, + ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences) { auto &C = CGM.getContext(); llvm::SmallVector<PrivateDataTy, 8> Privates; // Aggregate privates and sort them by the alignment. @@ -2169,12 +2240,11 @@ void CGOpenMPRuntime::emitTaskCall( }); (void)InitScope.Privatize(); // Emit initialization for single element. - auto *OldCapturedStmtInfo = CGF.CapturedStmtInfo; - CGF.CapturedStmtInfo = &CapturesInfo; + CodeGenFunction::CGCapturedStmtRAII CapInfoRAII( + CGF, &CapturesInfo); CGF.EmitAnyExprToMem(Init, DestElement, Init->getType().getQualifiers(), /*IsInitializer=*/false); - CGF.CapturedStmtInfo = OldCapturedStmtInfo; }); } } else { @@ -2183,11 +2253,9 @@ void CGOpenMPRuntime::emitTaskCall( return SharedRefLValue.getAddress(); }); (void)InitScope.Privatize(); - auto *OldCapturedStmtInfo = CGF.CapturedStmtInfo; - CGF.CapturedStmtInfo = &CapturesInfo; + CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo); CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false); - CGF.CapturedStmtInfo = OldCapturedStmtInfo; } } else { CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false); @@ -2209,35 +2277,139 @@ void CGOpenMPRuntime::emitTaskCall( CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( DestructorFn, KmpRoutineEntryPtrTy), Destructor); + + // Process list of dependences. + llvm::Value *DependInfo = nullptr; + unsigned DependencesNumber = Dependences.size(); + if (!Dependences.empty()) { + // Dependence kind for RTL. + enum RTLDependenceKindTy { DepIn = 1, DepOut = 2, DepInOut = 3 }; + enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags }; + RecordDecl *KmpDependInfoRD; + QualType FlagsTy = C.getIntTypeForBitwidth( + C.toBits(C.getTypeSizeInChars(C.BoolTy)), /*Signed=*/false); + llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy); + if (KmpDependInfoTy.isNull()) { + KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info"); + KmpDependInfoRD->startDefinition(); + addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType()); + addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType()); + addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy); + KmpDependInfoRD->completeDefinition(); + KmpDependInfoTy = C.getRecordType(KmpDependInfoRD); + } else { + KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl()); + } + // Define type kmp_depend_info[<Dependences.size()>]; + QualType KmpDependInfoArrayTy = C.getConstantArrayType( + KmpDependInfoTy, llvm::APInt(/*numBits=*/64, Dependences.size()), + ArrayType::Normal, /*IndexTypeQuals=*/0); + // kmp_depend_info[<Dependences.size()>] deps; + DependInfo = CGF.CreateMemTemp(KmpDependInfoArrayTy); + for (unsigned i = 0; i < DependencesNumber; ++i) { + auto Addr = CGF.EmitLValue(Dependences[i].second); + auto *Size = llvm::ConstantInt::get( + CGF.SizeTy, + C.getTypeSizeInChars(Dependences[i].second->getType()).getQuantity()); + auto Base = CGF.MakeNaturalAlignAddrLValue( + CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, DependInfo, i), + KmpDependInfoTy); + // deps[i].base_addr = &<Dependences[i].second>; + auto BaseAddrLVal = CGF.EmitLValueForField( + Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr)); + CGF.EmitStoreOfScalar( + CGF.Builder.CreatePtrToInt(Addr.getAddress(), CGF.IntPtrTy), + BaseAddrLVal); + // deps[i].len = sizeof(<Dependences[i].second>); + auto LenLVal = CGF.EmitLValueForField( + Base, *std::next(KmpDependInfoRD->field_begin(), Len)); + CGF.EmitStoreOfScalar(Size, LenLVal); + // deps[i].flags = <Dependences[i].first>; + RTLDependenceKindTy DepKind; + switch (Dependences[i].first) { + case OMPC_DEPEND_in: + DepKind = DepIn; + break; + case OMPC_DEPEND_out: + DepKind = DepOut; + break; + case OMPC_DEPEND_inout: + DepKind = DepInOut; + break; + case OMPC_DEPEND_unknown: + llvm_unreachable("Unknown task dependence type"); + } + auto FlagsLVal = CGF.EmitLValueForField( + Base, *std::next(KmpDependInfoRD->field_begin(), Flags)); + CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind), + FlagsLVal); + } + DependInfo = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + CGF.Builder.CreateStructGEP(/*Ty=*/nullptr, DependInfo, 0), + CGF.VoidPtrTy); + } + // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc() // libcall. // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t // *new_task); + // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid, + // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list, + // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence + // list is not empty auto *ThreadID = getThreadID(CGF, Loc); - llvm::Value *TaskArgs[] = {emitUpdateLocation(CGF, Loc), ThreadID, NewTask}; - auto &&ThenCodeGen = [this, &TaskArgs](CodeGenFunction &CGF) { + auto *UpLoc = emitUpdateLocation(CGF, Loc); + llvm::Value *TaskArgs[] = {UpLoc, ThreadID, NewTask}; + llvm::Value *DepTaskArgs[] = { + UpLoc, + ThreadID, + NewTask, + DependInfo ? CGF.Builder.getInt32(DependencesNumber) : nullptr, + DependInfo, + DependInfo ? CGF.Builder.getInt32(0) : nullptr, + DependInfo ? llvm::ConstantPointerNull::get(CGF.VoidPtrTy) : nullptr}; + auto &&ThenCodeGen = [this, DependInfo, &TaskArgs, + &DepTaskArgs](CodeGenFunction &CGF) { // TODO: add check for untied tasks. - CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs); + CGF.EmitRuntimeCall( + createRuntimeFunction(DependInfo ? OMPRTL__kmpc_omp_task_with_deps + : OMPRTL__kmpc_omp_task), + DependInfo ? makeArrayRef(DepTaskArgs) : makeArrayRef(TaskArgs)); }; typedef CallEndCleanup<std::extent<decltype(TaskArgs)>::value> IfCallEndCleanup; - auto &&ElseCodeGen = - [this, &TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry]( - CodeGenFunction &CGF) { - CodeGenFunction::RunCleanupsScope LocalScope(CGF); - CGF.EmitRuntimeCall( - createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0), TaskArgs); - // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid, - // kmp_task_t *new_task); - CGF.EHStack.pushCleanup<IfCallEndCleanup>( - NormalAndEHCleanup, - createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0), - llvm::makeArrayRef(TaskArgs)); - - // Call proxy_task_entry(gtid, new_task); - llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy}; - CGF.EmitCallOrInvoke(TaskEntry, OutlinedFnArgs); - }; + llvm::Value *DepWaitTaskArgs[] = { + UpLoc, + ThreadID, + DependInfo ? CGF.Builder.getInt32(DependencesNumber) : nullptr, + DependInfo, + DependInfo ? CGF.Builder.getInt32(0) : nullptr, + DependInfo ? llvm::ConstantPointerNull::get(CGF.VoidPtrTy) : nullptr}; + auto &&ElseCodeGen = [this, &TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry, + DependInfo, &DepWaitTaskArgs](CodeGenFunction &CGF) { + CodeGenFunction::RunCleanupsScope LocalScope(CGF); + // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid, + // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 + // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info + // is specified. + if (DependInfo) + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps), + DepWaitTaskArgs); + // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid, + // kmp_task_t *new_task); + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0), + TaskArgs); + // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid, + // kmp_task_t *new_task); + CGF.EHStack.pushCleanup<IfCallEndCleanup>( + NormalAndEHCleanup, + createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0), + llvm::makeArrayRef(TaskArgs)); + + // Call proxy_task_entry(gtid, new_task); + llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy}; + CGF.EmitCallOrInvoke(TaskEntry, OutlinedFnArgs); + }; if (IfCond) { emitOMPIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen); } else { @@ -2545,8 +2717,60 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, } void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF, + OpenMPDirectiveKind InnerKind, const RegionCodeGenTy &CodeGen) { - InlinedOpenMPRegionRAII Region(CGF, CodeGen); + InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind); CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr); } +void CGOpenMPRuntime::emitCancellationPointCall( + CodeGenFunction &CGF, SourceLocation Loc, + OpenMPDirectiveKind CancelRegion) { + // Build call kmp_int32 OMPRTL__kmpc_cancellationpoint(ident_t *loc, kmp_int32 + // global_tid, kmp_int32 cncl_kind); + enum { + CancelNoreq = 0, + CancelParallel = 1, + CancelLoop = 2, + CancelSections = 3, + CancelTaskgroup = 4 + } CancelKind = CancelNoreq; + if (CancelRegion == OMPD_parallel) + CancelKind = CancelParallel; + else if (CancelRegion == OMPD_for) + CancelKind = CancelLoop; + else if (CancelRegion == OMPD_sections) + CancelKind = CancelSections; + else { + assert(CancelRegion == OMPD_taskgroup); + CancelKind = CancelTaskgroup; + } + if (auto *OMPRegionInfo = + dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { + auto CancelDest = + CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); + if (CancelDest.isValid()) { + llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), + getThreadID(CGF, Loc), + CGF.Builder.getInt32(CancelKind)}; + // Ignore return result until untied tasks are supported. + auto *Result = CGF.EmitRuntimeCall( + createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args); + // if (__kmpc_cancellationpoint()) { + // __kmpc_cancel_barrier(); + // exit from construct; + // } + auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); + auto *ContBB = CGF.createBasicBlock(".cancel.continue"); + auto *Cmp = CGF.Builder.CreateIsNotNull(Result); + CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); + CGF.EmitBlock(ExitBB); + // __kmpc_cancel_barrier(); + emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false); + // exit from construct; + CGF.EmitBranchThroughCleanup(CancelDest); + CGF.EmitBlock(ContBB, /*IsFinished=*/true); + } + } +} + diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h index d1efde25d096..76bb3ae35931 100644 --- a/lib/CodeGen/CGOpenMPRuntime.h +++ b/lib/CodeGen/CGOpenMPRuntime.h @@ -68,6 +68,8 @@ private: // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 // global_tid); OMPRTL__kmpc_cancel_barrier, + // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid); + OMPRTL__kmpc_barrier, // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid); OMPRTL__kmpc_for_static_fini, // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32 @@ -138,6 +140,17 @@ private: // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, // int proc_bind); OMPRTL__kmpc_push_proc_bind, + // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 + // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t + // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list); + OMPRTL__kmpc_omp_task_with_deps, + // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 + // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 + // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); + OMPRTL__kmpc_omp_wait_deps, + // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32 + // global_tid, kmp_int32 cncl_kind); + OMPRTL__kmpc_cancellationpoint, }; /// \brief Values for bit flags used in the ident_t to describe the fields. @@ -249,6 +262,16 @@ private: /// deconstructors of firstprivate C++ objects */ /// } kmp_task_t; QualType KmpTaskTQTy; + /// \brief Type typedef struct kmp_depend_info { + /// kmp_intptr_t base_addr; + /// size_t len; + /// struct { + /// bool in:1; + /// bool out:1; + /// } flags; + /// } kmp_depend_info_t; + QualType KmpDependInfoTy; + /// \brief Build type kmp_routine_entry_t (if not built yet). void emitKmpRoutineEntryT(QualType KmpInt32Ty); @@ -341,22 +364,25 @@ public: /// kmp_int32 BoundID, struct context_vars*). /// \param D OpenMP directive. /// \param ThreadIDVar Variable for thread id in the current OpenMP region. + /// \param InnermostKind Kind of innermost directive (for simple directives it + /// is a directive itself, for combined - its innermost directive). /// \param CodeGen Code generation sequence for the \a D directive. - virtual llvm::Value * - emitParallelOutlinedFunction(const OMPExecutableDirective &D, - const VarDecl *ThreadIDVar, - const RegionCodeGenTy &CodeGen); + virtual llvm::Value *emitParallelOutlinedFunction( + const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, + OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); /// \brief Emits outlined function for the OpenMP task directive \a D. This /// outlined function has type void(*)(kmp_int32 ThreadID, kmp_int32 /// PartID, struct context_vars*). /// \param D OpenMP directive. /// \param ThreadIDVar Variable for thread id in the current OpenMP region. + /// \param InnermostKind Kind of innermost directive (for simple directives it + /// is a directive itself, for combined - its innermost directive). /// \param CodeGen Code generation sequence for the \a D directive. /// - virtual llvm::Value *emitTaskOutlinedFunction(const OMPExecutableDirective &D, - const VarDecl *ThreadIDVar, - const RegionCodeGenTy &CodeGen); + virtual llvm::Value *emitTaskOutlinedFunction( + const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, + OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); /// \brief Cleans up references to the objects in finished function. /// @@ -423,9 +449,12 @@ public: /// \brief Emit an implicit/explicit barrier for OpenMP threads. /// \param Kind Directive for which this implicit barrier call must be /// generated. Must be OMPD_barrier for explicit barrier generation. + /// \param CheckForCancel true if check for possible cancellation must be + /// performed, false otherwise. /// virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPDirectiveKind Kind); + OpenMPDirectiveKind Kind, + bool CheckForCancel = true); /// \brief Check if the specified \a ScheduleKind is static non-chunked. /// This kind of worksharing directive is emitted without outer loop. @@ -580,7 +609,7 @@ public: /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32 /// /*part_id*/, captured_struct */*__context*/); /// \param SharedsTy A type which contains references the shared variables. - /// \param Shareds Context with the list of shared variables from the \a + /// \param Shareds Context with the list of shared variables from the \p /// TaskFunction. /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr /// otherwise. @@ -595,21 +624,26 @@ public: /// \param FirstprivateInits List of references to auto generated variables /// used for initialization of a single array element. Used if firstprivate /// variable is of array type. - virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, - const OMPExecutableDirective &D, bool Tied, - llvm::PointerIntPair<llvm::Value *, 1, bool> Final, - llvm::Value *TaskFunction, QualType SharedsTy, - llvm::Value *Shareds, const Expr *IfCond, - const ArrayRef<const Expr *> PrivateVars, - const ArrayRef<const Expr *> PrivateCopies, - const ArrayRef<const Expr *> FirstprivateVars, - const ArrayRef<const Expr *> FirstprivateCopies, - const ArrayRef<const Expr *> FirstprivateInits); + /// \param Dependences List of dependences for the 'task' construct, including + /// original expression and dependency type. + virtual void emitTaskCall( + CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, + bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final, + llvm::Value *TaskFunction, QualType SharedsTy, llvm::Value *Shareds, + const Expr *IfCond, ArrayRef<const Expr *> PrivateVars, + ArrayRef<const Expr *> PrivateCopies, + ArrayRef<const Expr *> FirstprivateVars, + ArrayRef<const Expr *> FirstprivateCopies, + ArrayRef<const Expr *> FirstprivateInits, + ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences); /// \brief Emit code for the directive that does not require outlining. /// + /// \param InnermostKind Kind of innermost directive (for simple directives it + /// is a directive itself, for combined - its innermost directive). /// \param CodeGen Code generation sequence for the \a D directive. virtual void emitInlinedDirective(CodeGenFunction &CGF, + OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen); /// \brief Emit a code for reduction clause. Next code should be emitted for /// reduction: @@ -656,6 +690,14 @@ public: /// \brief Emit code for 'taskwait' directive. virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc); + + /// \brief Emit code for 'cancellation point' construct. + /// \param CancelRegion Region kind for which the cancellation point must be + /// emitted. + /// + virtual void emitCancellationPointCall(CodeGenFunction &CGF, + SourceLocation Loc, + OpenMPDirectiveKind CancelRegion); }; } // namespace CodeGen diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 9286f0358926..a12f29534bfe 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -240,6 +240,12 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPTeamsDirectiveClass: EmitOMPTeamsDirective(cast<OMPTeamsDirective>(*S)); break; + case Stmt::OMPCancellationPointDirectiveClass: + EmitOMPCancellationPointDirective(cast<OMPCancellationPointDirective>(*S)); + break; + case Stmt::OMPCancelDirectiveClass: + EmitOMPCancelDirective(cast<OMPCancelDirective>(*S)); + break; } } @@ -2149,7 +2155,7 @@ CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) { // Emit the CapturedDecl CodeGenFunction CGF(CGM, true); - CGF.CapturedStmtInfo = new CGCapturedStmtInfo(S, K); + CGCapturedStmtRAII CapInfoRAII(CGF, new CGCapturedStmtInfo(S, K)); llvm::Function *F = CGF.GenerateCapturedStmtFunction(S); delete CGF.CapturedStmtInfo; diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 5e94d56feb5f..b021c1275318 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -451,11 +451,12 @@ void CodeGenFunction::EmitOMPReductionClauseFinal( static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, + OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) { auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CapturedStruct = CGF.GenerateCapturedStmtArgument(*CS); auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction( - S, *CS->getCapturedDecl()->param_begin(), CodeGen); + S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); if (auto C = S.getSingleClause(OMPC_num_threads)) { CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); auto NumThreadsClause = cast<OMPNumThreadsClause>(C); @@ -502,10 +503,11 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), OMPD_unknown); }; - emitCommonOMPParallelDirective(*this, S, CodeGen); + emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen); } -void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D) { +void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, + JumpDest LoopExit) { RunCleanupsScope BodyScope(*this); // Update counters values on current iteration. for (auto I : D.updates()) { @@ -521,7 +523,7 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D) { // On a continue in the body, jump to the end. auto Continue = getJumpDestInCurrentScope("omp.body.continue"); - BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue)); + BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); // Emit loop body. EmitStmt(D.getBody()); // The end (updates/cleanups). @@ -649,8 +651,10 @@ static void emitAlignedClause(CodeGenFunction &CGF, // If no optional parameter is specified, implementation-defined default // alignments for SIMD instructions on the target platforms are assumed. Alignment = - CGF.CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment( - E->getType()); + CGF.getContext() + .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( + E->getType()->getPointeeType())) + .getQuantity(); } assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && "alignment is not power of 2"); @@ -825,10 +829,10 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { CGF.EmitOMPReductionClauseInit(S, LoopScope); HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); (void)LoopScope.Privatize(); - CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), - S.getCond(), S.getInc(), + CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), + S.getInc(), [&S](CodeGenFunction &CGF) { - CGF.EmitOMPLoopBody(S); + CGF.EmitOMPLoopBody(S, JumpDest()); CGF.EmitStopPoint(&S); }, [](CodeGenFunction &) {}); @@ -845,7 +849,7 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { CGF.EmitBlock(ContBlock, true); } }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); } void CodeGenFunction::EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind, @@ -977,19 +981,17 @@ void CodeGenFunction::EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind, } SourceLocation Loc = S.getLocStart(); - EmitOMPInnerLoop( - S, LoopScope.requiresCleanups(), S.getCond(), - S.getInc(), - [&S](CodeGenFunction &CGF) { - CGF.EmitOMPLoopBody(S); - CGF.EmitStopPoint(&S); - }, - [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) { - if (Ordered) { - CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd( - CGF, Loc, IVSize, IVSigned); - } - }); + EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(), + [&S, LoopExit](CodeGenFunction &CGF) { + CGF.EmitOMPLoopBody(S, LoopExit); + CGF.EmitStopPoint(&S); + }, + [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) { + if (Ordered) { + CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd( + CGF, Loc, IVSize, IVSigned); + } + }); EmitBlock(Continue.getBlock()); BreakContinueStack.pop_back(); @@ -1138,6 +1140,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { RT.emitForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned, Ordered, IL.getAddress(), LB.getAddress(), UB.getAddress(), ST.getAddress()); + auto LoopExit = getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); // UB = min(UB, GlobalUB); EmitIgnoredExpr(S.getEnsureUpperBound()); // IV = LB; @@ -1145,11 +1148,12 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { // while (idx <= UB) { BODY; ++idx; } EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(), - [&S](CodeGenFunction &CGF) { - CGF.EmitOMPLoopBody(S); + [&S, LoopExit](CodeGenFunction &CGF) { + CGF.EmitOMPLoopBody(S, LoopExit); CGF.EmitStopPoint(&S); }, [](CodeGenFunction &) {}); + EmitBlock(LoopExit.getBlock()); // Tell the runtime we are done. RT.emitForStaticFinish(*this, S.getLocStart()); } else { @@ -1183,7 +1187,7 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { HasLastprivates = CGF.EmitOMPWorksharingLoop(S); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen); // Emit an implicit barrier at the end. if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { @@ -1197,7 +1201,7 @@ void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { HasLastprivates = CGF.EmitOMPWorksharingLoop(S); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); // Emit an implicit barrier at the end. if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { @@ -1214,8 +1218,8 @@ static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, return LVal; } -static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, - const OMPExecutableDirective &S) { +OpenMPDirectiveKind +CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt(); auto *CS = dyn_cast<CompoundStmt>(Stmt); if (CS && CS->size() > 1) { @@ -1263,12 +1267,13 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB, CS->size()); unsigned CaseNumber = 0; - for (auto C = CS->children(); C; ++C, ++CaseNumber) { + for (auto *SubStmt : CS->children()) { auto CaseBB = CGF.createBasicBlock(".omp.sections.case"); CGF.EmitBlock(CaseBB); SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB); - CGF.EmitStmt(*C); + CGF.EmitStmt(SubStmt); CGF.EmitBranch(ExitBB); + ++CaseNumber; } CGF.EmitBlock(ExitBB, /*IsFinished=*/true); }; @@ -1311,15 +1316,15 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, CGF.EmitLoadOfScalar(IL, S.getLocStart()))); }; - CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen); // Emit barrier for lastprivates only if 'sections' directive has 'nowait' // clause. Otherwise the barrier will be generated by the codegen for the // directive. if (HasLastprivates && S.getSingleClause(OMPC_nowait)) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_unknown); + CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), + OMPD_unknown); } return OMPD_sections; } @@ -1340,11 +1345,10 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, (void)SingleScope.Privatize(); CGF.EmitStmt(Stmt); - CGF.EnsureInsertPoint(); }; - CGF.CGM.getOpenMPRuntime().emitSingleRegion(CGF, CodeGen, S.getLocStart(), - llvm::None, llvm::None, - llvm::None, llvm::None); + CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), + llvm::None, llvm::None, llvm::None, + llvm::None); // Emit barrier for firstprivates, lastprivates or reductions only if // 'sections' directive has 'nowait' clause. Otherwise the barrier will be // generated by the codegen for the directive. @@ -1352,15 +1356,14 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, S.getSingleClause(OMPC_nowait)) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_unknown); + CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown); } return OMPD_single; } void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { LexicalScope Scope(*this, S.getSourceRange()); - OpenMPDirectiveKind EmittedAs = emitSections(*this, S); + OpenMPDirectiveKind EmittedAs = EmitSections(S); // Emit an implicit barrier at the end. if (!S.getSingleClause(OMPC_nowait)) { CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), EmittedAs); @@ -1373,7 +1376,7 @@ void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EnsureInsertPoint(); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen); } void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { @@ -1453,7 +1456,7 @@ void CodeGenFunction::EmitOMPParallelForDirective( CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), OMPD_parallel); }; - emitCommonOMPParallelDirective(*this, S, CodeGen); + emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen); } void CodeGenFunction::EmitOMPParallelForSimdDirective( @@ -1470,7 +1473,7 @@ void CodeGenFunction::EmitOMPParallelForSimdDirective( CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), OMPD_parallel); }; - emitCommonOMPParallelDirective(*this, S, CodeGen); + emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen); } void CodeGenFunction::EmitOMPParallelSectionsDirective( @@ -1479,12 +1482,12 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective( // directives: 'parallel' with 'sections' directive. LexicalScope Scope(*this, S.getSourceRange()); auto &&CodeGen = [&S](CodeGenFunction &CGF) { - (void)emitSections(CGF, S); + (void)CGF.EmitSections(S); // Emit implicit barrier at the end of parallel region. CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), OMPD_parallel); }; - emitCommonOMPParallelDirective(*this, S, CodeGen); + emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen); } void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { @@ -1531,6 +1534,15 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { ++IRef, ++IElemInitRef; } } + // Build list of dependences. + llvm::SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 8> + Dependences; + for (auto &&I = S.getClausesOfKind(OMPC_depend); I; ++I) { + auto *C = cast<OMPDependClause>(*I); + for (auto *IRef : C->varlists()) { + Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef)); + } + } auto &&CodeGen = [PartId, &S, &PrivateVars, &FirstprivateVars]( CodeGenFunction &CGF) { // Set proper addresses for generated private copies. @@ -1575,8 +1587,8 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { } CGF.EmitStmt(CS->getCapturedStmt()); }; - auto OutlinedFn = - CGM.getOpenMPRuntime().emitTaskOutlinedFunction(S, *I, CodeGen); + auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( + S, *I, OMPD_task, CodeGen); // Check if we should emit tied or untied task. bool Tied = !S.getSingleClause(OMPC_untied); // Check if the task is final @@ -1602,7 +1614,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { CGM.getOpenMPRuntime().emitTaskCall( *this, S.getLocStart(), S, Tied, Final, OutlinedFn, SharedsTy, CapturedStruct, IfCond, PrivateVars, PrivateCopies, FirstprivateVars, - FirstprivateCopies, FirstprivateInits); + FirstprivateCopies, FirstprivateInits, Dependences); } void CodeGenFunction::EmitOMPTaskyieldDirective( @@ -2041,6 +2053,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_nowait: case OMPC_untied: case OMPC_threadprivate: + case OMPC_depend: case OMPC_mergeable: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } @@ -2077,7 +2090,7 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { S.getV(), S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(), S.getLocStart()); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen); } void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) { @@ -2087,3 +2100,23 @@ void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) { void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) { llvm_unreachable("CodeGen for 'omp teams' is not supported yet."); } + +void CodeGenFunction::EmitOMPCancellationPointDirective( + const OMPCancellationPointDirective &S) { + CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(), + S.getCancelRegion()); +} + +void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) { + llvm_unreachable("CodeGen for 'omp cancel' is not supported yet."); +} + +CodeGenFunction::JumpDest +CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { + if (Kind == OMPD_parallel || Kind == OMPD_task) + return ReturnBlock; + else if (Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections) + return BreakContinueStack.empty() ? JumpDest() + : BreakContinueStack.back().BreakBlock; + return JumpDest(); +} diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 17db40138296..969629fb5845 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -123,8 +123,8 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF, // no-op thunk for the regular definition) call va_start/va_end. // There's a bit of per-call overhead for this solution, but it's // better for codesize if the definition is long. -void CodeGenFunction::GenerateVarArgsThunk( - llvm::Function *Fn, +llvm::Function * +CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); @@ -184,6 +184,8 @@ void CodeGenFunction::GenerateVarArgsThunk( } } } + + return Fn; } void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD, @@ -378,9 +380,6 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, // Set the right linkage. CGM.setFunctionLinkage(GD, Fn); - if (CGM.supportsCOMDAT() && Fn->isWeakForLinker()) - Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName())); - // Set the right visibility. const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); setThunkVisibility(CGM, MD, Thunk, Fn); @@ -450,17 +449,19 @@ void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, // expensive/sucky at the moment, so don't generate the thunk unless // we have to. // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly. - if (!UseAvailableExternallyLinkage) { - CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk); - CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD, - !Thunk.Return.isEmpty()); - } + if (UseAvailableExternallyLinkage) + return; + ThunkFn = + CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk); } else { // Normal thunk body generation. CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk); - CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD, - !Thunk.Return.isEmpty()); } + + CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD, + !Thunk.Return.isEmpty()); + if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker()) + ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName())); } void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD, @@ -702,7 +703,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { llvm::Function::InternalLinkage; return llvm::GlobalVariable::ExternalLinkage; - + case TSK_ImplicitInstantiation: return !Context.getLangOpts().AppleKext ? llvm::GlobalVariable::LinkOnceODRLinkage : diff --git a/lib/CodeGen/CodeGenABITypes.cpp b/lib/CodeGen/CodeGenABITypes.cpp index 12189ae1aea9..755e8aa628ce 100644 --- a/lib/CodeGen/CodeGenABITypes.cpp +++ b/lib/CodeGen/CodeGenABITypes.cpp @@ -20,6 +20,8 @@ #include "CodeGenModule.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/PreprocessorOptions.h" using namespace clang; using namespace CodeGen; @@ -29,7 +31,10 @@ CodeGenABITypes::CodeGenABITypes(ASTContext &C, const llvm::DataLayout &TD, CoverageSourceInfo *CoverageInfo) : CGO(new CodeGenOptions), - CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD, C.getDiagnostics(), + HSO(new HeaderSearchOptions), + PPO(new PreprocessorOptions), + CGM(new CodeGen::CodeGenModule(C, *HSO, *PPO, *CGO, + M, TD, C.getDiagnostics(), CoverageInfo)) { } diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index 54e6b73b3020..0e7b6d8a71d4 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -57,6 +57,8 @@ namespace clang { public: BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, + const HeaderSearchOptions &HeaderSearchOpts, + const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, const TargetOptions &TargetOpts, const LangOptions &LangOpts, bool TimePasses, @@ -66,7 +68,8 @@ namespace clang { : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS), Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"), - Gen(CreateLLVMCodeGen(Diags, InFile, CodeGenOpts, C, CoverageInfo)), + Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, + CodeGenOpts, C, CoverageInfo)), LinkModule(LinkModule) { llvm::TimePassesIsEnabled = TimePasses; } @@ -667,7 +670,8 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::unique_ptr<PPCallbacks>(CoverageInfo)); } std::unique_ptr<BackendConsumer> Result(new BackendConsumer( - BA, CI.getDiagnostics(), CI.getCodeGenOpts(), CI.getTargetOpts(), + BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModuleToUse, OS, *VMContext, CoverageInfo)); BEConsumer = Result.get(); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index bece41e9ecb2..1fca466e9244 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -930,8 +930,9 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return), "missing_return", EmitCheckSourceLocation(FD->getLocation()), None); - } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) - Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap), {}); + } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) { + EmitTrapCall(llvm::Intrinsic::trap); + } Builder.CreateUnreachable(); Builder.ClearInsertionPoint(); } @@ -970,8 +971,8 @@ bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { IgnoreCaseStmts = true; // Scan subexpressions for verboten labels. - for (Stmt::const_child_range I = S->children(); I; ++I) - if (ContainsLabel(*I, IgnoreCaseStmts)) + for (const Stmt *SubStmt : S->children()) + if (ContainsLabel(SubStmt, IgnoreCaseStmts)) return true; return false; @@ -994,8 +995,8 @@ bool CodeGenFunction::containsBreak(const Stmt *S) { return true; // Scan subexpressions for verboten breaks. - for (Stmt::const_child_range I = S->children(); I; ++I) - if (containsBreak(*I)) + for (const Stmt *SubStmt : S->children()) + if (containsBreak(SubStmt)) return true; return false; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 45475d1af1c4..a74c474232c8 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -233,6 +233,20 @@ public: }; CGCapturedStmtInfo *CapturedStmtInfo; + /// \brief RAII for correct setting/restoring of CapturedStmtInfo. + class CGCapturedStmtRAII { + private: + CodeGenFunction &CGF; + CGCapturedStmtInfo *PrevCapturedStmtInfo; + public: + CGCapturedStmtRAII(CodeGenFunction &CGF, + CGCapturedStmtInfo *NewCapturedStmtInfo) + : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo) { + CGF.CapturedStmtInfo = NewCapturedStmtInfo; + } + ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; } + }; + /// BoundsChecking - Emit run-time bounds checks. Higher values mean /// potentially higher performance penalties. unsigned char BoundsChecking; @@ -283,12 +297,12 @@ public: /// Header for data within LifetimeExtendedCleanupStack. struct LifetimeExtendedCleanupHeader { /// The size of the following cleanup object. - unsigned Size : 29; + unsigned Size; /// The kind of cleanup to push: a value from the CleanupKind enumeration. - unsigned Kind : 3; + CleanupKind Kind; - size_t getSize() const { return size_t(Size); } - CleanupKind getKind() const { return static_cast<CleanupKind>(Kind); } + size_t getSize() const { return Size; } + CleanupKind getKind() const { return Kind; } }; /// i32s containing the indexes of the cleanup destinations. @@ -388,6 +402,8 @@ public: LifetimeExtendedCleanupStack.resize( LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size); + static_assert(sizeof(Header) % llvm::AlignOf<T>::Alignment == 0, + "Cleanup will be allocated on misaligned address"); char *Buffer = &LifetimeExtendedCleanupStack[OldSize]; new (Buffer) LifetimeExtendedCleanupHeader(Header); new (Buffer + sizeof(Header)) T(A...); @@ -1280,8 +1296,9 @@ public: void GenerateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk); - void GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, - GlobalDecl GD, const ThunkInfo &Thunk); + llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn, + const CGFunctionInfo &FnInfo, + GlobalDecl GD, const ThunkInfo &Thunk); void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args); @@ -2185,6 +2202,9 @@ public: void EmitOMPAtomicDirective(const OMPAtomicDirective &S); void EmitOMPTargetDirective(const OMPTargetDirective &S); void EmitOMPTeamsDirective(const OMPTeamsDirective &S); + void + EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S); + void EmitOMPCancelDirective(const OMPCancelDirective &S); /// \brief Emit inner loop of the worksharing/simd construct. /// @@ -2202,10 +2222,12 @@ public: const llvm::function_ref<void(CodeGenFunction &)> &BodyGen, const llvm::function_ref<void(CodeGenFunction &)> &PostIncGen); + JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind); + private: /// Helpers for the OpenMP loop directives. - void EmitOMPLoopBody(const OMPLoopDirective &D); + void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit); void EmitOMPSimdInit(const OMPLoopDirective &D); void EmitOMPSimdFinal(const OMPLoopDirective &D); /// \brief Emit code for the worksharing loop-based directive. @@ -2217,6 +2239,8 @@ private: OMPPrivateScope &LoopScope, bool Ordered, llvm::Value *LB, llvm::Value *UB, llvm::Value *ST, llvm::Value *IL, llvm::Value *Chunk); + /// \brief Emit code for sections directive. + OpenMPDirectiveKind EmitSections(const OMPExecutableDirective &S); public: @@ -2586,6 +2610,7 @@ public: llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); @@ -2852,6 +2877,10 @@ public: /// conditional branch to it, for the -ftrapv checks. void EmitTrapCheck(llvm::Value *Checked); + /// \brief Emit a call to trap or debugtrap and attach function attribute + /// "trap-func-name" if specified. + llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID); + /// \brief Create a check for a function parameter that may potentially be /// declared as non-null. void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 2dd5414795e7..b905bd2b36bf 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -74,16 +74,19 @@ static CGCXXABI *createCXXABI(CodeGenModule &CGM) { llvm_unreachable("invalid C++ ABI kind"); } -CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, - llvm::Module &M, const llvm::DataLayout &TD, +CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, + const CodeGenOptions &CGO, llvm::Module &M, + const llvm::DataLayout &TD, DiagnosticsEngine &diags, CoverageSourceInfo *CoverageInfo) - : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M), - Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()), - ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(nullptr), - TheTargetCodeGenInfo(nullptr), Types(*this), VTables(*this), - ObjCRuntime(nullptr), OpenCLRuntime(nullptr), OpenMPRuntime(nullptr), - CUDARuntime(nullptr), DebugInfo(nullptr), ARCData(nullptr), + : Context(C), LangOpts(C.getLangOpts()), HeaderSearchOpts(HSO), + PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags), + TheDataLayout(TD), Target(C.getTargetInfo()), ABI(createCXXABI(*this)), + VMContext(M.getContext()), TBAA(nullptr), TheTargetCodeGenInfo(nullptr), + Types(*this), VTables(*this), ObjCRuntime(nullptr), + OpenCLRuntime(nullptr), OpenMPRuntime(nullptr), CUDARuntime(nullptr), + DebugInfo(nullptr), ARCData(nullptr), NoObjCARCExceptionsMetadata(nullptr), RRData(nullptr), PGOReader(nullptr), CFConstantStringClassRef(nullptr), ConstantStringClassRef(nullptr), NSConstantStringType(nullptr), NSConcreteGlobalBlock(nullptr), @@ -145,8 +148,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, llvm::IndexedInstrProfReader::create(CodeGenOpts.InstrProfileInput); if (std::error_code EC = ReaderOrErr.getError()) { unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "Could not read profile: %0"); - getDiags().Report(DiagID) << EC.message(); + "Could not read profile %0: %1"); + getDiags().Report(DiagID) << CodeGenOpts.InstrProfileInput + << EC.message(); } else PGOReader = std::move(ReaderOrErr.get()); } @@ -1424,7 +1428,7 @@ namespace { return false; } unsigned BuiltinID = FD->getBuiltinID(); - if (!BuiltinID) + if (!BuiltinID || !BI.isLibFunction(BuiltinID)) return true; StringRef BuiltinName = BI.GetName(BuiltinID); if (BuiltinName.startswith("__builtin_") && @@ -3358,6 +3362,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { Owner->getTopLevelModule()->Name == getLangOpts().CurrentModule) break; } + if (CGDebugInfo *DI = getModuleDebugInfo()) + DI->EmitImportDecl(*Import); ImportedModules.insert(Import->getImportedModule()); break; diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 8e671fa7878c..9a295feaffa4 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -69,6 +69,8 @@ class ValueDecl; class VarDecl; class LangOptions; class CodeGenOptions; +class HeaderSearchOptions; +class PreprocessorOptions; class DiagnosticsEngine; class AnnotateAttr; class CXXDestructorDecl; @@ -278,6 +280,8 @@ public: private: ASTContext &Context; const LangOptions &LangOpts; + const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info. + const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. const CodeGenOptions &CodeGenOpts; llvm::Module &TheModule; DiagnosticsEngine &Diags; @@ -488,7 +492,10 @@ private: std::unique_ptr<CoverageMappingModuleGen> CoverageMapping; public: - CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, + CodeGenModule(ASTContext &C, + const HeaderSearchOptions &headersearchopts, + const PreprocessorOptions &ppopts, + const CodeGenOptions &CodeGenOpts, llvm::Module &M, const llvm::DataLayout &TD, DiagnosticsEngine &Diags, CoverageSourceInfo *CoverageInfo = nullptr); @@ -600,6 +607,10 @@ public: ASTContext &getContext() const { return Context; } const LangOptions &getLangOpts() const { return LangOpts; } + const HeaderSearchOptions &getHeaderSearchOpts() + const { return HeaderSearchOpts; } + const PreprocessorOptions &getPreprocessorOpts() + const { return PreprocessorOpts; } const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } llvm::Module &getModule() const { return TheModule; } DiagnosticsEngine &getDiags() const { return Diags; } @@ -732,6 +743,11 @@ public: /// Get a reference to the target of VD. llvm::Constant *GetWeakRefReference(const ValueDecl *VD); + CharUnits + computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, + CastExpr::path_const_iterator Start, + CastExpr::path_const_iterator End); + /// Returns the offset from a derived class to a class. Returns null if the /// offset is 0. llvm::Constant * diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp index f182a469b3a4..8dffefc871f2 100644 --- a/lib/CodeGen/CodeGenPGO.cpp +++ b/lib/CodeGen/CodeGenPGO.cpp @@ -275,10 +275,9 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> { void VisitStmt(const Stmt *S) { RecordStmtCount(S); - for (Stmt::const_child_range I = S->children(); I; ++I) { - if (*I) - this->Visit(*I); - } + for (const Stmt *Child : S->children()) + if (Child) + this->Visit(Child); } void VisitFunctionDecl(const FunctionDecl *D) { diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index e0f926cabd71..a4a8654eb36b 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -154,14 +154,16 @@ isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT, static bool isSafeToConvert(QualType T, CodeGenTypes &CGT, llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) { - T = T.getCanonicalType(); - + // Strip off atomic type sugar. + if (const auto *AT = T->getAs<AtomicType>()) + T = AT->getValueType(); + // If this is a record, check it. - if (const RecordType *RT = dyn_cast<RecordType>(T)) + if (const auto *RT = T->getAs<RecordType>()) return isSafeToConvert(RT->getDecl(), CGT, AlreadyChecked); - + // If this is an array, check the elements, which are embedded inline. - if (const ArrayType *AT = dyn_cast<ArrayType>(T)) + if (const auto *AT = CGT.getContext().getAsArrayType(T)) return isSafeToConvert(AT->getElementType(), CGT, AlreadyChecked); // Otherwise, there is no concern about transforming this. We only care about diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp index 9ad5d14edfdc..eca91590e602 100644 --- a/lib/CodeGen/CoverageMappingGen.cpp +++ b/lib/CodeGen/CoverageMappingGen.cpp @@ -475,7 +475,8 @@ struct CounterCoverageMappingBuilder /// files, this adjusts our current region stack and creates the file regions /// for the exited file. void handleFileExit(SourceLocation NewLoc) { - if (SM.isWrittenInSameFile(MostRecentLocation, NewLoc)) + if (NewLoc.isInvalid() || + SM.isWrittenInSameFile(MostRecentLocation, NewLoc)) return; // If NewLoc is not in a file that contains MostRecentLocation, walk up to @@ -581,10 +582,9 @@ struct CounterCoverageMappingBuilder void VisitStmt(const Stmt *S) { if (!S->getLocStart().isInvalid()) extendRegion(S); - for (Stmt::const_child_range I = S->children(); I; ++I) { - if (*I) - this->Visit(*I); - } + for (const Stmt *Child : S->children()) + if (Child) + this->Visit(Child); handleFileExit(getEnd(S)); } @@ -931,7 +931,8 @@ void CoverageMappingModuleGen::addFunctionMappingRecord( if (!FunctionRecordTy) { llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty, Int64Ty}; FunctionRecordTy = - llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes)); + llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes), + /*isPacked=*/true); } llvm::Constant *FunctionRecordVals[] = { diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 3f5ad5db01b5..fa86e52ec804 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -94,7 +94,7 @@ public: llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override; - llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD) override; + llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override; llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset) override; llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override; @@ -219,7 +219,7 @@ public: bool ReturnAdjustment) override { // Allow inlining of thunks by emitting them with available_externally // linkage together with vtables when needed. - if (ForVTable) + if (ForVTable && !Thunk->hasLocalLinkage()) Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); } @@ -656,7 +656,8 @@ ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()); } -llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { +llvm::Constant * +ItaniumCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { return BuildMemberPointer(MD, CharUnits::Zero()); } diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 679516bfa89a..d149df63c9e4 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -247,6 +247,50 @@ public: getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD, llvm::GlobalVariable::LinkageTypes Linkage); + llvm::GlobalVariable * + getAddrOfVirtualDisplacementMap(const CXXRecordDecl *SrcRD, + const CXXRecordDecl *DstRD) { + SmallString<256> OutName; + llvm::raw_svector_ostream Out(OutName); + getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out); + Out.flush(); + StringRef MangledName = OutName.str(); + + if (auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName)) + return VDispMap; + + MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext(); + unsigned NumEntries = 1 + SrcRD->getNumVBases(); + SmallVector<llvm::Constant *, 4> Map(NumEntries, + llvm::UndefValue::get(CGM.IntTy)); + Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0); + bool AnyDifferent = false; + for (const auto &I : SrcRD->vbases()) { + const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl(); + if (!DstRD->isVirtuallyDerivedFrom(VBase)) + continue; + + unsigned SrcVBIndex = VTContext.getVBTableIndex(SrcRD, VBase); + unsigned DstVBIndex = VTContext.getVBTableIndex(DstRD, VBase); + Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4); + AnyDifferent |= SrcVBIndex != DstVBIndex; + } + // This map would be useless, don't use it. + if (!AnyDifferent) + return nullptr; + + llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size()); + llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map); + llvm::GlobalValue::LinkageTypes Linkage = + SrcRD->isExternallyVisible() && DstRD->isExternallyVisible() + ? llvm::GlobalValue::LinkOnceODRLinkage + : llvm::GlobalValue::InternalLinkage; + auto *VDispMap = new llvm::GlobalVariable( + CGM.getModule(), VDispMapTy, /*Constant=*/true, Linkage, + /*Initializer=*/Init, MangledName); + return VDispMap; + } + void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD, llvm::GlobalVariable *GV) const; @@ -502,10 +546,6 @@ private: CharUnits NonVirtualBaseAdjustment, unsigned VBTableIndex); - llvm::Constant *BuildMemberPointer(const CXXRecordDecl *RD, - const CXXMethodDecl *MD, - CharUnits NonVirtualBaseAdjustment); - bool MemberPointerConstantIsNull(const MemberPointerType *MPT, llvm::Constant *MP); @@ -545,7 +585,7 @@ public: llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset) override; - llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD) override; + llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override; llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override; llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, @@ -563,6 +603,12 @@ public: llvm::Value *Base, llvm::Value *MemPtr, const MemberPointerType *MPT) override; + llvm::Value *EmitNonNullMemberPointerConversion( + const MemberPointerType *SrcTy, const MemberPointerType *DstTy, + CastKind CK, CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, llvm::Value *Src, + CGBuilderTy &Builder); + llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src) override; @@ -570,6 +616,11 @@ public: llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, llvm::Constant *Src) override; + llvm::Constant *EmitMemberPointerConversion( + const MemberPointerType *SrcTy, const MemberPointerType *DstTy, + CastKind CK, CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, llvm::Constant *Src); + llvm::Value * EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, llvm::Value *&This, llvm::Value *MemPtr, @@ -2457,7 +2508,7 @@ MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) { CharUnits Offs = CharUnits::Zero(); - if (VBTableIndex && RD->getNumVBases()) + if (VBTableIndex) Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset(); fields.push_back(llvm::ConstantInt::get(CGM.IntTy, Offs.getQuantity())); } @@ -2473,43 +2524,76 @@ llvm::Constant * MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset) { const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); + if (RD->getMSInheritanceModel() == + MSInheritanceAttr::Keyword_virtual_inheritance) + offset -= getContext().getOffsetOfBaseWithVBPtr(RD); llvm::Constant *FirstField = llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD, CharUnits::Zero(), /*VBTableIndex=*/0); } -llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { - return BuildMemberPointer(MD->getParent(), MD, CharUnits::Zero()); -} - llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP, QualType MPType) { - const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); + const MemberPointerType *DstTy = MPType->castAs<MemberPointerType>(); const ValueDecl *MPD = MP.getMemberPointerDecl(); if (!MPD) - return EmitNullMemberPointer(MPT); + return EmitNullMemberPointer(DstTy); - CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); + ASTContext &Ctx = getContext(); + ArrayRef<const CXXRecordDecl *> MemberPointerPath = MP.getMemberPointerPath(); - // FIXME PR15713: Support virtual inheritance paths. + llvm::Constant *C; + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) { + C = EmitMemberFunctionPointer(MD); + } else { + CharUnits FieldOffset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(MPD)); + C = EmitMemberDataPointer(DstTy, FieldOffset); + } - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) - return BuildMemberPointer(MPT->getMostRecentCXXRecordDecl(), MD, - ThisAdjustment); + if (!MemberPointerPath.empty()) { + const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext()); + const Type *SrcRecTy = Ctx.getTypeDeclType(SrcRD).getTypePtr(); + const MemberPointerType *SrcTy = + Ctx.getMemberPointerType(DstTy->getPointeeType(), SrcRecTy) + ->castAs<MemberPointerType>(); + + bool DerivedMember = MP.isMemberPointerToDerivedMember(); + SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath; + const CXXRecordDecl *PrevRD = SrcRD; + for (const CXXRecordDecl *PathElem : MemberPointerPath) { + const CXXRecordDecl *Base = nullptr; + const CXXRecordDecl *Derived = nullptr; + if (DerivedMember) { + Base = PathElem; + Derived = PrevRD; + } else { + Base = PrevRD; + Derived = PathElem; + } + for (const CXXBaseSpecifier &BS : Derived->bases()) + if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == + Base->getCanonicalDecl()) + DerivedToBasePath.push_back(&BS); + PrevRD = PathElem; + } + assert(DerivedToBasePath.size() == MemberPointerPath.size()); - CharUnits FieldOffset = - getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); - return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); + CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer + : CK_BaseToDerivedMemberPointer; + C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(), + DerivedToBasePath.end(), C); + } + return C; } llvm::Constant * -MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD, - const CXXMethodDecl *MD, - CharUnits NonVirtualBaseAdjustment) { +MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { assert(MD->isInstance() && "Member function must not be static!"); + MD = MD->getCanonicalDecl(); - RD = RD->getMostRecentDecl(); + CharUnits NonVirtualBaseAdjustment = CharUnits::Zero(); + const CXXRecordDecl *RD = MD->getParent()->getMostRecentDecl(); CodeGenTypes &Types = CGM.getTypes(); unsigned VBTableIndex = 0; @@ -2527,20 +2611,24 @@ MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD, Ty = CGM.PtrDiffTy; } FirstField = CGM.GetAddrOfFunction(MD, Ty); - FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); } else { auto &VTableContext = CGM.getMicrosoftVTableContext(); MicrosoftVTableContext::MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD); - llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML); - FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy); + FirstField = EmitVirtualMemPtrThunk(MD, ML); // Include the vfptr adjustment if the method is in a non-primary vftable. NonVirtualBaseAdjustment += ML.VFPtrOffset; if (ML.VBase) VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4; } + if (VBTableIndex == 0 && + RD->getMSInheritanceModel() == + MSInheritanceAttr::Keyword_virtual_inheritance) + NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD); + // The rest of the fields are common with data member pointers. + FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD, NonVirtualBaseAdjustment, VBTableIndex); } @@ -2798,11 +2886,6 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress( return Builder.CreateBitCast(Addr, PType); } -static MSInheritanceAttr::Spelling -getInheritanceFromMemptr(const MemberPointerType *MPT) { - return MPT->getMostRecentCXXRecordDecl()->getMSInheritanceModel(); -} - llvm::Value * MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, @@ -2854,12 +2937,37 @@ MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB); CGF.EmitBlock(ConvertBB); + llvm::Value *Dst = EmitNonNullMemberPointerConversion( + SrcTy, DstTy, E->getCastKind(), E->path_begin(), E->path_end(), Src, + Builder); + + Builder.CreateBr(ContinueBB); + + // In the continuation, choose between DstNull and Dst. + CGF.EmitBlock(ContinueBB); + llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted"); + Phi->addIncoming(DstNull, OriginalBB); + Phi->addIncoming(Dst, ConvertBB); + return Phi; +} + +llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( + const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, llvm::Value *Src, + CGBuilderTy &Builder) { + const CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl(); + const CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl(); + MSInheritanceAttr::Spelling SrcInheritance = SrcRD->getMSInheritanceModel(); + MSInheritanceAttr::Spelling DstInheritance = DstRD->getMSInheritanceModel(); + bool IsFunc = SrcTy->isMemberFunctionPointer(); + bool IsConstant = isa<llvm::Constant>(Src); + // Decompose src. llvm::Value *FirstField = Src; - llvm::Value *NonVirtualBaseAdjustment = nullptr; - llvm::Value *VirtualBaseAdjustmentOffset = nullptr; - llvm::Value *VBPtrOffset = nullptr; - MSInheritanceAttr::Spelling SrcInheritance = SrcRD->getMSInheritanceModel(); + llvm::Value *NonVirtualBaseAdjustment = getZeroInt(); + llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt(); + llvm::Value *VBPtrOffset = getZeroInt(); if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) { // We need to extract values. unsigned I = 0; @@ -2872,59 +2980,138 @@ MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++); } + bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer); + const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy; + const CXXRecordDecl *DerivedClass = DerivedTy->getMostRecentCXXRecordDecl(); + // For data pointers, we adjust the field offset directly. For functions, we // have a separate field. - llvm::Constant *Adj = getMemberPointerAdjustment(E); - if (Adj) { - Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); - llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField; - bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - if (!NVAdjustField) // If this field didn't exist in src, it's zero. - NVAdjustField = getZeroInt(); - if (isDerivedToBase) - NVAdjustField = Builder.CreateNSWSub(NVAdjustField, Adj, "adj"); - else - NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, Adj, "adj"); + llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField; + + // The virtual inheritance model has a quirk: the virtual base table is always + // referenced when dereferencing a member pointer even if the member pointer + // is non-virtual. This is accounted for by adjusting the non-virtual offset + // to point backwards to the top of the MDC from the first VBase. Undo this + // adjustment to normalize the member pointer. + llvm::Value *SrcVBIndexEqZero = + Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt()); + if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) { + if (int64_t SrcOffsetToFirstVBase = + getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) { + llvm::Value *UndoSrcAdjustment = Builder.CreateSelect( + SrcVBIndexEqZero, + llvm::ConstantInt::get(CGM.IntTy, SrcOffsetToFirstVBase), + getZeroInt()); + NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment); + } } - // FIXME PR15713: Support conversions through virtually derived classes. + // A non-zero vbindex implies that we are dealing with a source member in a + // floating virtual base in addition to some non-virtual offset. If the + // vbindex is zero, we are dealing with a source that exists in a non-virtual, + // fixed, base. The difference between these two cases is that the vbindex + + // nvoffset *always* point to the member regardless of what context they are + // evaluated in so long as the vbindex is adjusted. A member inside a fixed + // base requires explicit nv adjustment. + llvm::Constant *BaseClassOffset = llvm::ConstantInt::get( + CGM.IntTy, + CGM.computeNonVirtualBaseClassOffset(DerivedClass, PathBegin, PathEnd) + .getQuantity()); + + llvm::Value *NVDisp; + if (IsDerivedToBase) + NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset, "adj"); + else + NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset, "adj"); + + NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt()); + + // Update the vbindex to an appropriate value in the destination because + // SrcRD's vbtable might not be a strict prefix of the one in DstRD. + llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero; + if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) && + MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) { + if (llvm::GlobalVariable *VDispMap = + getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) { + llvm::Value *VBIndex = Builder.CreateExactUDiv( + VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.IntTy, 4)); + if (IsConstant) { + llvm::Constant *Mapping = VDispMap->getInitializer(); + VirtualBaseAdjustmentOffset = + Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex)); + } else { + llvm::Value *Idxs[] = {getZeroInt(), VBIndex}; + VirtualBaseAdjustmentOffset = + Builder.CreateLoad(Builder.CreateInBoundsGEP(VDispMap, Idxs)); + } + + DstVBIndexEqZero = + Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt()); + } + } + + // Set the VBPtrOffset to zero if the vbindex is zero. Otherwise, initialize + // it to the offset of the vbptr. + if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) { + llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get( + CGM.IntTy, + getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity()); + VBPtrOffset = + Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset); + } + + // Likewise, apply a similar adjustment so that dereferencing the member + // pointer correctly accounts for the distance between the start of the first + // virtual base and the top of the MDC. + if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) { + if (int64_t DstOffsetToFirstVBase = + getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) { + llvm::Value *DoDstAdjustment = Builder.CreateSelect( + DstVBIndexEqZero, + llvm::ConstantInt::get(CGM.IntTy, DstOffsetToFirstVBase), + getZeroInt()); + NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment); + } + } // Recompose dst from the null struct and the adjusted fields from src. - MSInheritanceAttr::Spelling DstInheritance = DstRD->getMSInheritanceModel(); llvm::Value *Dst; if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) { Dst = FirstField; } else { - Dst = llvm::UndefValue::get(DstNull->getType()); + Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy)); unsigned Idx = 0; Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++); if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance)) - Dst = Builder.CreateInsertValue( - Dst, getValueOrZeroInt(NonVirtualBaseAdjustment), Idx++); + Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++); if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) - Dst = Builder.CreateInsertValue( - Dst, getValueOrZeroInt(VBPtrOffset), Idx++); + Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++); if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance)) - Dst = Builder.CreateInsertValue( - Dst, getValueOrZeroInt(VirtualBaseAdjustmentOffset), Idx++); + Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++); } - Builder.CreateBr(ContinueBB); - - // In the continuation, choose between DstNull and Dst. - CGF.EmitBlock(ContinueBB); - llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted"); - Phi->addIncoming(DstNull, OriginalBB); - Phi->addIncoming(Dst, ConvertBB); - return Phi; + return Dst; } llvm::Constant * MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E, llvm::Constant *Src) { const MemberPointerType *SrcTy = - E->getSubExpr()->getType()->castAs<MemberPointerType>(); + E->getSubExpr()->getType()->castAs<MemberPointerType>(); const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); + CastKind CK = E->getCastKind(); + + return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->path_begin(), + E->path_end(), Src); +} + +llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion( + const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, llvm::Constant *Src) { + assert(CK == CK_DerivedToBaseMemberPointer || + CK == CK_BaseToDerivedMemberPointer || + CK == CK_ReinterpretMemberPointer); // If src is null, emit a new null for dst. We can't return src because dst // might have a new representation. if (MemberPointerConstantIsNull(SrcTy, Src)) @@ -2933,61 +3120,14 @@ MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E, // We don't need to do anything for reinterpret_casts of non-null member // pointers. We should only get here when the two type representations have // the same size. - if (E->getCastKind() == CK_ReinterpretMemberPointer) + if (CK == CK_ReinterpretMemberPointer) return Src; - MSInheritanceAttr::Spelling SrcInheritance = getInheritanceFromMemptr(SrcTy); - MSInheritanceAttr::Spelling DstInheritance = getInheritanceFromMemptr(DstTy); - - // Decompose src. - llvm::Constant *FirstField = Src; - llvm::Constant *NonVirtualBaseAdjustment = nullptr; - llvm::Constant *VirtualBaseAdjustmentOffset = nullptr; - llvm::Constant *VBPtrOffset = nullptr; - bool IsFunc = SrcTy->isMemberFunctionPointer(); - if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) { - // We need to extract values. - unsigned I = 0; - FirstField = Src->getAggregateElement(I++); - if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance)) - NonVirtualBaseAdjustment = Src->getAggregateElement(I++); - if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance)) - VBPtrOffset = Src->getAggregateElement(I++); - if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) - VirtualBaseAdjustmentOffset = Src->getAggregateElement(I++); - } - - // For data pointers, we adjust the field offset directly. For functions, we - // have a separate field. - llvm::Constant *Adj = getMemberPointerAdjustment(E); - if (Adj) { - Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); - llvm::Constant *&NVAdjustField = - IsFunc ? NonVirtualBaseAdjustment : FirstField; - bool IsDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - if (!NVAdjustField) // If this field didn't exist in src, it's zero. - NVAdjustField = getZeroInt(); - if (IsDerivedToBase) - NVAdjustField = llvm::ConstantExpr::getNSWSub(NVAdjustField, Adj); - else - NVAdjustField = llvm::ConstantExpr::getNSWAdd(NVAdjustField, Adj); - } - - // FIXME PR15713: Support conversions through virtually derived classes. + CGBuilderTy Builder(CGM.getLLVMContext()); + auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion( + SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder)); - // Recompose dst from the null struct and the adjusted fields from src. - if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) - return FirstField; - - llvm::SmallVector<llvm::Constant *, 4> Fields; - Fields.push_back(FirstField); - if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance)) - Fields.push_back(getConstantOrZeroInt(NonVirtualBaseAdjustment)); - if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) - Fields.push_back(getConstantOrZeroInt(VBPtrOffset)); - if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance)) - Fields.push_back(getConstantOrZeroInt(VirtualBaseAdjustmentOffset)); - return llvm::ConstantStruct::getAnon(Fields); + return Dst; } llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer( @@ -3592,6 +3732,8 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD, ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.getModule()); ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>( FnInfo.getEffectiveCallingConvention())); + if (ThunkFn->isWeakForLinker()) + ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName())); bool IsCopy = CT == Ctor_CopyingClosure; // Start codegen. diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 25e57401fd57..def56a963126 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -32,6 +32,8 @@ namespace { DiagnosticsEngine &Diags; std::unique_ptr<const llvm::DataLayout> TD; ASTContext *Ctx; + const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info. + const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. const CodeGenOptions CodeGenOpts; // Intentionally copied in. unsigned HandlingTopLevelDecls; @@ -56,12 +58,15 @@ namespace { SmallVector<CXXMethodDecl *, 8> DeferredInlineMethodDefinitions; public: - CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName, - const CodeGenOptions &CGO, llvm::LLVMContext& C, + CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string &ModuleName, + const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, const CodeGenOptions &CGO, + llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo = nullptr) - : Diags(diags), Ctx(nullptr), CodeGenOpts(CGO), HandlingTopLevelDecls(0), - CoverageInfo(CoverageInfo), - M(new llvm::Module(ModuleName, C)) {} + : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO), + PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0), + CoverageInfo(CoverageInfo), + M(new llvm::Module(ModuleName, C)) {} ~CodeGeneratorImpl() override { // There should normally not be any leftover inline method definitions. @@ -97,7 +102,10 @@ namespace { M->setDataLayout(Ctx->getTargetInfo().getTargetDescription()); TD.reset( new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription())); - Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD, + Builder.reset(new CodeGen::CodeGenModule(Context, + HeaderSearchOpts, + PreprocessorOpts, + CodeGenOpts, *M, *TD, Diags, CoverageInfo)); for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i) @@ -236,10 +244,11 @@ namespace { void CodeGenerator::anchor() { } -CodeGenerator *clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, - const std::string& ModuleName, - const CodeGenOptions &CGO, - llvm::LLVMContext& C, - CoverageSourceInfo *CoverageInfo) { - return new CodeGeneratorImpl(Diags, ModuleName, CGO, C, CoverageInfo); +CodeGenerator *clang::CreateLLVMCodeGen( + DiagnosticsEngine &Diags, const std::string &ModuleName, + const HeaderSearchOptions &HeaderSearchOpts, + const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO, + llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) { + return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts, + PreprocessorOpts, CGO, C, CoverageInfo); } diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index e77c1242e70b..e5ba200e1c57 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -1391,6 +1391,26 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( namespace { +/// The AVX ABI level for X86 targets. +enum class X86AVXABILevel { + None, + AVX, + AVX512 +}; + +/// \p returns the size in bits of the largest (native) vector for \p AVXLevel. +static unsigned getNativeVectorSizeForAVXABI(X86AVXABILevel AVXLevel) { + switch (AVXLevel) { + case X86AVXABILevel::AVX512: + return 512; + case X86AVXABILevel::AVX: + return 256; + case X86AVXABILevel::None: + return 128; + } + llvm_unreachable("Unknown AVXLevel"); +} + /// X86_64ABIInfo - The X86_64 ABI information. class X86_64ABIInfo : public ABIInfo { enum Class { @@ -1496,13 +1516,14 @@ class X86_64ABIInfo : public ABIInfo { return !getTarget().getTriple().isOSDarwin(); } + X86AVXABILevel AVXLevel; // Some ABIs (e.g. X32 ABI and Native Client OS) use 32 bit pointers on // 64-bit hardware. bool Has64BitPointers; public: - X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : - ABIInfo(CGT), + X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) : + ABIInfo(CGT), AVXLevel(AVXLevel), Has64BitPointers(CGT.getDataLayout().getPointerSize(0) == 8) { } @@ -1527,10 +1548,6 @@ public: bool has64BitPointers() const { return Has64BitPointers; } - - bool hasAVX() const { - return getTarget().getABI() == "avx"; - } }; /// WinX86_64ABIInfo - The Windows X86_64 ABI information. @@ -1561,8 +1578,8 @@ public: class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { public: - X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) - : TargetCodeGenInfo(new X86_64ABIInfo(CGT)) {} + X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) + : TargetCodeGenInfo(new X86_64ABIInfo(CGT, AVXLevel)) {} const X86_64ABIInfo &getABIInfo() const { return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo()); @@ -1628,16 +1645,12 @@ public: ('T' << 24); return llvm::ConstantInt::get(CGM.Int32Ty, Sig); } - - unsigned getOpenMPSimdDefaultAlignment(QualType) const override { - return getABIInfo().hasAVX() ? 32 : 16; - } }; class PS4TargetCodeGenInfo : public X86_64TargetCodeGenInfo { public: - PS4TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) - : X86_64TargetCodeGenInfo(CGT) {} + PS4TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) + : X86_64TargetCodeGenInfo(CGT, AVXLevel) {} void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const override { @@ -1703,11 +1716,10 @@ void WinX86_32TargetCodeGenInfo::setTargetAttributes(const Decl *D, } class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo { - bool hasAVX() const { return getABIInfo().getTarget().getABI() == "avx"; } - public: - WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) - : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)) {} + WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, + X86AVXABILevel AVXLevel) + : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override; @@ -1737,10 +1749,6 @@ public: llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } - - unsigned getOpenMPSimdDefaultAlignment(QualType) const override { - return hasAVX() ? 32 : 16; - } }; void WinX86_64TargetCodeGenInfo::setTargetAttributes(const Decl *D, @@ -1928,7 +1936,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, // split. if (OffsetBase && OffsetBase != 64) Hi = Lo; - } else if (Size == 128 || (hasAVX() && isNamedArg && Size == 256)) { + } else if (Size == 128 || + (isNamedArg && Size <= getNativeVectorSizeForAVXABI(AVXLevel))) { // Arguments of 256-bits are split into four eightbyte chunks. The // least significant one belongs to class SSE and all the others to class // SSEUP. The original Lo and Hi design considers that types can't be @@ -1940,6 +1949,9 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, // Note that per 3.5.7 of AMD64-ABI, 256-bit args are only passed in // registers if they are "named", i.e. not part of the "..." of a // variadic function. + // + // Similarly, per 3.2.3. of the AVX512 draft, 512-bits ("named") args are + // split into eight eightbyte chunks, one SSE and seven SSEUP. Lo = SSE; Hi = SSEUp; } @@ -2150,7 +2162,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { bool X86_64ABIInfo::IsIllegalVectorType(QualType Ty) const { if (const VectorType *VecTy = Ty->getAs<VectorType>()) { uint64_t Size = getContext().getTypeSize(VecTy); - unsigned LargestVector = hasAVX() ? 256 : 128; + unsigned LargestVector = getNativeVectorSizeForAVXABI(AVXLevel); if (Size <= 64 || Size > LargestVector) return true; } @@ -2475,13 +2487,16 @@ GetX86_64ByValArgumentPair(llvm::Type *Lo, llvm::Type *Hi, // of the second element because it might make us access off the end of the // struct. if (HiStart != 8) { - // There are only two sorts of types the ABI generation code can produce for - // the low part of a pair that aren't 8 bytes in size: float or i8/i16/i32. + // There are usually two sorts of types the ABI generation code can produce + // for the low part of a pair that aren't 8 bytes in size: float or + // i8/i16/i32. This can also include pointers when they are 32-bit (X32 and + // NaCl). // Promote these to a larger type. if (Lo->isFloatTy()) Lo = llvm::Type::getDoubleTy(Lo->getContext()); else { - assert(Lo->isIntegerTy() && "Invalid/unknown lo type"); + assert((Lo->isIntegerTy() || Lo->isPointerTy()) + && "Invalid/unknown lo type"); Lo = llvm::Type::getInt64Ty(Lo->getContext()); } } @@ -3145,10 +3160,6 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override; - - unsigned getOpenMPSimdDefaultAlignment(QualType) const override { - return 16; // Natural alignment for Altivec vectors. - } }; } @@ -3388,13 +3399,11 @@ public: }; class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo { - bool HasQPX; public: PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT, PPC64_SVR4_ABIInfo::ABIKind Kind, bool HasQPX) - : TargetCodeGenInfo(new PPC64_SVR4_ABIInfo(CGT, Kind, HasQPX)), - HasQPX(HasQPX) {} + : TargetCodeGenInfo(new PPC64_SVR4_ABIInfo(CGT, Kind, HasQPX)) {} int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { // This is recovered from gcc output. @@ -3403,15 +3412,6 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override; - - unsigned getOpenMPSimdDefaultAlignment(QualType QT) const override { - if (HasQPX) - if (const PointerType *PT = QT->getAs<PointerType>()) - if (PT->getPointeeType()->isSpecificBuiltinType(BuiltinType::Double)) - return 32; // Natural alignment for QPX doubles. - - return 16; // Natural alignment for Altivec and VSX vectors. - } }; class PPC64TargetCodeGenInfo : public DefaultTargetCodeGenInfo { @@ -3425,10 +3425,6 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override; - - unsigned getOpenMPSimdDefaultAlignment(QualType) const override { - return 16; // Natural alignment for Altivec vectors. - } }; } @@ -7194,13 +7190,21 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { } case llvm::Triple::x86_64: { + StringRef ABI = getTarget().getABI(); + X86AVXABILevel AVXLevel = (ABI == "avx512" ? X86AVXABILevel::AVX512 : + ABI == "avx" ? X86AVXABILevel::AVX : + X86AVXABILevel::None); + switch (Triple.getOS()) { case llvm::Triple::Win32: - return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types)); + return *(TheTargetCodeGenInfo = + new WinX86_64TargetCodeGenInfo(Types, AVXLevel)); case llvm::Triple::PS4: - return *(TheTargetCodeGenInfo = new PS4TargetCodeGenInfo(Types)); + return *(TheTargetCodeGenInfo = + new PS4TargetCodeGenInfo(Types, AVXLevel)); default: - return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types)); + return *(TheTargetCodeGenInfo = + new X86_64TargetCodeGenInfo(Types, AVXLevel)); } } case llvm::Triple::hexagon: diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h index bf63265f0283..95275d5d42ee 100644 --- a/lib/CodeGen/TargetInfo.h +++ b/lib/CodeGen/TargetInfo.h @@ -218,13 +218,6 @@ public: virtual void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, llvm::SmallString<32> &Opt) const {} - - /// Gets the target-specific default alignment used when an 'aligned' clause - /// is used with a 'simd' OpenMP directive without specifying a specific - /// alignment. - virtual unsigned getOpenMPSimdDefaultAlignment(QualType Type) const { - return 0; - } }; } diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 412840b6ea6e..fa0430e211b9 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -10,6 +10,7 @@ add_clang_library(clangDriver Driver.cpp DriverOptions.cpp Job.cpp + MinGWToolChain.cpp Multilib.cpp MSVCToolChain.cpp Phases.cpp diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 2bcbd5cf943c..101d1fcc832a 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -192,18 +192,14 @@ static bool InputsOk(const Command &C, return !ActionFailed(&C.getSource(), FailingCommands); } -void Compilation::ExecuteJob(const Job &J, - FailingCommandList &FailingCommands) const { - if (const Command *C = dyn_cast<Command>(&J)) { - if (!InputsOk(*C, FailingCommands)) - return; +void Compilation::ExecuteJobs(const JobList &Jobs, + FailingCommandList &FailingCommands) const { + for (const auto &Job : Jobs) { + if (!InputsOk(Job, FailingCommands)) + continue; const Command *FailingCommand = nullptr; - if (int Res = ExecuteCommand(*C, FailingCommand)) + if (int Res = ExecuteCommand(Job, FailingCommand)) FailingCommands.push_back(std::make_pair(Res, FailingCommand)); - } else { - const JobList *Jobs = cast<JobList>(&J); - for (const auto &Job : *Jobs) - ExecuteJob(Job, FailingCommands); } } diff --git a/lib/Driver/CrossWindowsToolChain.cpp b/lib/Driver/CrossWindowsToolChain.cpp index 82456e76c75a..ffb1469df21d 100644 --- a/lib/Driver/CrossWindowsToolChain.cpp +++ b/lib/Driver/CrossWindowsToolChain.cpp @@ -108,10 +108,9 @@ AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs, } Tool *CrossWindowsToolChain::buildLinker() const { - return new tools::CrossWindows::Link(*this); + return new tools::CrossWindows::Linker(*this); } Tool *CrossWindowsToolChain::buildAssembler() const { - return new tools::CrossWindows::Assemble(*this); + return new tools::CrossWindows::Assembler(*this); } - diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 0f3ebef2cf2f..b9dc35d6219a 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -58,7 +58,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, CCCUsePCH(true), SuppressMissingInputWarning(false) { Name = llvm::sys::path::filename(ClangExecutable); - Dir = llvm::sys::path::parent_path(ClangExecutable); + Dir = llvm::sys::path::parent_path(ClangExecutable); // Compute the path to the resource directory. StringRef ClangResourceDir(CLANG_RESOURCE_DIR); @@ -81,23 +81,23 @@ Driver::~Driver() { void Driver::ParseDriverMode(ArrayRef<const char *> Args) { const std::string OptName = - getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); + getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); - for (size_t I = 0, E = Args.size(); I != E; ++I) { + for (const char *ArgPtr : Args) { // Ingore nullptrs, they are response file's EOL markers - if (Args[I] == nullptr) + if (ArgPtr == nullptr) continue; - const StringRef Arg = Args[I]; + const StringRef Arg = ArgPtr; if (!Arg.startswith(OptName)) continue; const StringRef Value = Arg.drop_front(OptName.size()); const unsigned M = llvm::StringSwitch<unsigned>(Value) - .Case("gcc", GCCMode) - .Case("g++", GXXMode) - .Case("cpp", CPPMode) - .Case("cl", CLMode) - .Default(~0U); + .Case("gcc", GCCMode) + .Case("g++", GXXMode) + .Case("cpp", CPPMode) + .Case("cl", CLMode) + .Default(~0U); if (M != ~0U) Mode = static_cast<DriverMode>(M); @@ -106,42 +106,39 @@ void Driver::ParseDriverMode(ArrayRef<const char *> Args) { } } -InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) { +InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) { llvm::PrettyStackTraceString CrashInfo("Command line argument parsing"); unsigned IncludedFlagsBitmask; unsigned ExcludedFlagsBitmask; std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = - getIncludeExcludeOptionFlagMasks(); + getIncludeExcludeOptionFlagMasks(); unsigned MissingArgIndex, MissingArgCount; - InputArgList *Args = getOpts().ParseArgs(ArgStrings.begin(), ArgStrings.end(), - MissingArgIndex, MissingArgCount, - IncludedFlagsBitmask, - ExcludedFlagsBitmask); + InputArgList Args = + getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount, + IncludedFlagsBitmask, ExcludedFlagsBitmask); // Check for missing argument error. if (MissingArgCount) Diag(clang::diag::err_drv_missing_argument) - << Args->getArgString(MissingArgIndex) << MissingArgCount; + << Args.getArgString(MissingArgIndex) << MissingArgCount; // Check for unsupported options. - for (const Arg *A : *Args) { + for (const Arg *A : Args) { if (A->getOption().hasFlag(options::Unsupported)) { - Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args); + Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(Args); continue; } // Warn about -mcpu= without an argument. - if (A->getOption().matches(options::OPT_mcpu_EQ) && - A->containsValue("")) { - Diag(clang::diag::warn_drv_empty_joined_argument) << - A->getAsString(*Args); + if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue("")) { + Diag(clang::diag::warn_drv_empty_joined_argument) << A->getAsString(Args); } } - for (const Arg *A : Args->filtered(options::OPT_UNKNOWN)) - Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args); + for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) + Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args); return Args; } @@ -149,14 +146,13 @@ InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) { // Determine which compilation mode we are in. We look for options which // affect the phase, starting with the earliest phases, and record which // option we used to determine the final phase. -phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, Arg **FinalPhaseArg) -const { +phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, + Arg **FinalPhaseArg) const { Arg *PhaseArg = nullptr; phases::ID FinalPhase; // -{E,EP,P,M,MM} only run the preprocessor. - if (CCCIsCPP() || - (PhaseArg = DAL.getLastArg(options::OPT_E)) || + if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) { @@ -192,7 +188,7 @@ const { return FinalPhase; } -static Arg* MakeInputArg(DerivedArgList &Args, OptTable *Opts, +static Arg *MakeInputArg(DerivedArgList &Args, OptTable *Opts, StringRef Value) { Arg *A = new Arg(Opts->getOption(options::OPT_INPUT), Value, Args.getBaseArgs().MakeIndex(Value), Value.data()); @@ -219,10 +215,9 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_Xlinker__no_demangle)); // Add the remaining values as Xlinker arguments. - for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) - if (StringRef(A->getValue(i)) != "--no-demangle") - DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker), - A->getValue(i)); + for (const StringRef Val : A->getValues()) + if (Val != "--no-demangle") + DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker), Val); continue; } @@ -250,15 +245,13 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { // Rewrite unless -nostdlib is present. if (!HasNostdlib && Value == "stdc++") { - DAL->AddFlagArg(A, Opts->getOption( - options::OPT_Z_reserved_lib_stdcxx)); + DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_stdcxx)); continue; } // Rewrite unconditionally. if (Value == "cc_kext") { - DAL->AddFlagArg(A, Opts->getOption( - options::OPT_Z_reserved_lib_cckext)); + DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_cckext)); continue; } } @@ -266,16 +259,16 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { // Pick up inputs via the -- option. if (A->getOption().matches(options::OPT__DASH_DASH)) { A->claim(); - for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) - DAL->append(MakeInputArg(*DAL, Opts, A->getValue(i))); + for (const StringRef Val : A->getValues()) + DAL->append(MakeInputArg(*DAL, Opts, Val)); continue; } DAL->append(A); } - // Add a default value of -mlinker-version=, if one was given and the user - // didn't specify one. +// Add a default value of -mlinker-version=, if one was given and the user +// didn't specify one. #if defined(HOST_LINK_VERSION) if (!Args.hasArg(options::OPT_mlinker_version_EQ) && strlen(HOST_LINK_VERSION) > 0) { @@ -297,8 +290,8 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { if (char *env = ::getenv("COMPILER_PATH")) { StringRef CompilerPath = env; while (!CompilerPath.empty()) { - std::pair<StringRef, StringRef> Split - = CompilerPath.split(llvm::sys::EnvPathSeparator); + std::pair<StringRef, StringRef> Split = + CompilerPath.split(llvm::sys::EnvPathSeparator); PrefixDirs.push_back(Split.first); CompilerPath = Split.second; } @@ -311,15 +304,15 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // FIXME: What are we going to do with -V and -b? // FIXME: This stuff needs to go into the Compilation, not the driver. - bool CCCPrintActions; + bool CCCPrintPhases; - InputArgList *Args = ParseArgStrings(ArgList.slice(1)); + InputArgList Args = ParseArgStrings(ArgList.slice(1)); // -no-canonical-prefixes is used very early in main. - Args->ClaimAllArgs(options::OPT_no_canonical_prefixes); + Args.ClaimAllArgs(options::OPT_no_canonical_prefixes); // Ignore -pipe. - Args->ClaimAllArgs(options::OPT_pipe); + Args.ClaimAllArgs(options::OPT_pipe); // Extract -ccc args. // @@ -327,12 +320,12 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // should be outside in the client; the parts that aren't should have proper // options, either by introducing new ones or by overloading gcc ones like -V // or -b. - CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases); - CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings); - if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name)) + CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases); + CCCPrintBindings = Args.hasArg(options::OPT_ccc_print_bindings); + if (const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name)) CCCGenericGCCName = A->getValue(); - CCCUsePCH = Args->hasFlag(options::OPT_ccc_pch_is_pch, - options::OPT_ccc_pch_is_pth); + CCCUsePCH = + Args.hasFlag(options::OPT_ccc_pch_is_pch, options::OPT_ccc_pch_is_pth); // FIXME: DefaultTargetTriple is used by the target-prefixed calls to as/ld // and getToolChain is const. if (IsCLMode()) { @@ -342,39 +335,42 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { T.setEnvironment(llvm::Triple::MSVC); DefaultTargetTriple = T.str(); } - if (const Arg *A = Args->getLastArg(options::OPT_target)) + if (const Arg *A = Args.getLastArg(options::OPT_target)) DefaultTargetTriple = A->getValue(); - if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir)) + if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir)) Dir = InstalledDir = A->getValue(); - for (const Arg *A : Args->filtered(options::OPT_B)) { + for (const Arg *A : Args.filtered(options::OPT_B)) { A->claim(); PrefixDirs.push_back(A->getValue(0)); } - if (const Arg *A = Args->getLastArg(options::OPT__sysroot_EQ)) + if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) SysRoot = A->getValue(); - if (const Arg *A = Args->getLastArg(options::OPT__dyld_prefix_EQ)) + if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ)) DyldPrefix = A->getValue(); - if (Args->hasArg(options::OPT_nostdlib)) + if (Args.hasArg(options::OPT_nostdlib)) UseStdLib = false; - if (const Arg *A = Args->getLastArg(options::OPT_resource_dir)) + if (const Arg *A = Args.getLastArg(options::OPT_resource_dir)) ResourceDir = A->getValue(); - if (const Arg *A = Args->getLastArg(options::OPT_save_temps_EQ)) { + if (const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) { SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue()) .Case("cwd", SaveTempsCwd) .Case("obj", SaveTempsObj) .Default(SaveTempsCwd); } + std::unique_ptr<llvm::opt::InputArgList> UArgs = + llvm::make_unique<InputArgList>(std::move(Args)); + // Perform the default argument translations. - DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args); + DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs); // Owned by the host. - const ToolChain &TC = getToolChain(*Args); + const ToolChain &TC = getToolChain(*UArgs); // The compilation takes ownership of Args. - Compilation *C = new Compilation(*this, TC, Args, TranslatedArgs); + Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs); if (!HandleImmediateArgs(*C)) return C; @@ -386,13 +382,13 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // Construct the list of abstract actions to perform for this compilation. On // MachO targets this uses the driver-driver and universal actions. if (TC.getTriple().isOSBinFormatMachO()) - BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(), - Inputs, C->getActions()); + BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(), Inputs, + C->getActions()); else BuildActions(C->getDefaultToolChain(), C->getArgs(), Inputs, C->getActions()); - if (CCCPrintActions) { + if (CCCPrintPhases) { PrintActions(*C); return C; } @@ -419,8 +415,8 @@ void Driver::generateCompilationDiagnostics(Compilation &C, PrintVersion(C, llvm::errs()); Diag(clang::diag::note_drv_command_failed_diag_msg) - << "PLEASE submit a bug report to " BUG_REPORT_URL " and include the " - "crash backtrace, preprocessed source, and associated run script."; + << "PLEASE submit a bug report to " BUG_REPORT_URL " and include the " + "crash backtrace, preprocessed source, and associated run script."; // Suppress driver output and emit preprocessor output to temp file. Mode = CPPMode; @@ -445,12 +441,12 @@ void Driver::generateCompilationDiagnostics(Compilation &C, // Ignore input from stdin or any inputs that cannot be preprocessed. // Check type first as not all linker inputs have a value. - if (types::getPreprocessedType(it->first) == types::TY_INVALID) { + if (types::getPreprocessedType(it->first) == types::TY_INVALID) { IgnoreInput = true; } else if (!strcmp(it->second->getValue(), "-")) { Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s) - ignoring input from stdin" - "."; + << "Error generating preprocessed source(s) - " + "ignoring input from stdin."; IgnoreInput = true; } @@ -464,7 +460,8 @@ void Driver::generateCompilationDiagnostics(Compilation &C, if (Inputs.empty()) { Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s) - no preprocessable inputs."; + << "Error generating preprocessed source(s) - " + "no preprocessable inputs."; return; } @@ -479,8 +476,8 @@ void Driver::generateCompilationDiagnostics(Compilation &C, } if (ArchNames.size() > 1) { Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s) - cannot generate " - "preprocessed source with multiple -arch options."; + << "Error generating preprocessed source(s) - cannot generate " + "preprocessed source with multiple -arch options."; return; } @@ -497,13 +494,13 @@ void Driver::generateCompilationDiagnostics(Compilation &C, // If there were errors building the compilation, quit now. if (Trap.hasErrorOccurred()) { Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s)."; + << "Error generating preprocessed source(s)."; return; } // Generate preprocessed output. SmallVector<std::pair<int, const Command *>, 4> FailingCommands; - C.ExecuteJob(C.getJobs(), FailingCommands); + C.ExecuteJobs(C.getJobs(), FailingCommands); // If any of the preprocessing commands failed, clean up and exit. if (!FailingCommands.empty()) { @@ -511,14 +508,14 @@ void Driver::generateCompilationDiagnostics(Compilation &C, C.CleanupFileList(C.getTempFiles(), true); Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s)."; + << "Error generating preprocessed source(s)."; return; } const ArgStringList &TempFiles = C.getTempFiles(); if (TempFiles.empty()) { Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s)."; + << "Error generating preprocessed source(s)."; return; } @@ -563,31 +560,22 @@ void Driver::generateCompilationDiagnostics(Compilation &C, << "\n\n********************"; } -void Driver::setUpResponseFiles(Compilation &C, Job &J) { - if (JobList *Jobs = dyn_cast<JobList>(&J)) { - for (auto &Job : *Jobs) - setUpResponseFiles(C, Job); - return; - } - - Command *CurCommand = dyn_cast<Command>(&J); - if (!CurCommand) - return; - +void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) { // Since argumentsFitWithinSystemLimits() may underestimate system's capacity // if the tool does not support response files, there is a chance/ that things // will just work without a response file, so we silently just skip it. - if (CurCommand->getCreator().getResponseFilesSupport() == Tool::RF_None || - llvm::sys::argumentsFitWithinSystemLimits(CurCommand->getArguments())) + if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None || + llvm::sys::argumentsFitWithinSystemLimits(Cmd.getArguments())) return; std::string TmpName = GetTemporaryPath("response", "txt"); - CurCommand->setResponseFile(C.addTempFile(C.getArgs().MakeArgString( - TmpName.c_str()))); + Cmd.setResponseFile( + C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str()))); } -int Driver::ExecuteCompilation(Compilation &C, - SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) { +int Driver::ExecuteCompilation( + Compilation &C, + SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) { // Just print if -### was present. if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { C.getJobs().Print(llvm::errs(), "\n", true); @@ -599,9 +587,10 @@ int Driver::ExecuteCompilation(Compilation &C, return 1; // Set up response file names for each command, if necessary - setUpResponseFiles(C, C.getJobs()); + for (auto &Job : C.getJobs()) + setUpResponseFiles(C, Job); - C.ExecuteJob(C.getJobs(), FailingCommands); + C.ExecuteJobs(C.getJobs(), FailingCommands); // Remove temp files. C.CleanupFileList(C.getTempFiles()); @@ -612,10 +601,9 @@ int Driver::ExecuteCompilation(Compilation &C, // Otherwise, remove result files and print extra information about abnormal // failures. - for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it = - FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) { - int Res = it->first; - const Command *FailingCommand = it->second; + for (const auto &CmdPair : FailingCommands) { + int Res = CmdPair.first; + const Command *FailingCommand = CmdPair.second; // Remove result files if we're not saving temps. if (!isSaveTempsEnabled()) { @@ -640,10 +628,10 @@ int Driver::ExecuteCompilation(Compilation &C, // FIXME: See FIXME above regarding result code interpretation. if (Res < 0) Diag(clang::diag::err_drv_command_signalled) - << FailingTool.getShortName(); + << FailingTool.getShortName(); else - Diag(clang::diag::err_drv_command_failed) - << FailingTool.getShortName() << Res; + Diag(clang::diag::err_drv_command_failed) << FailingTool.getShortName() + << Res; } } return 0; @@ -653,7 +641,7 @@ void Driver::PrintHelp(bool ShowHidden) const { unsigned IncludedFlagsBitmask; unsigned ExcludedFlagsBitmask; std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = - getIncludeExcludeOptionFlagMasks(); + getIncludeExcludeOptionFlagMasks(); ExcludedFlagsBitmask |= options::NoDriverOption; if (!ShowHidden) @@ -684,8 +672,8 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { /// option. static void PrintDiagnosticCategories(raw_ostream &OS) { // Skip the empty category. - for (unsigned i = 1, max = DiagnosticIDs::getNumberOfCategories(); - i != max; ++i) + for (unsigned i = 1, max = DiagnosticIDs::getNumberOfCategories(); i != max; + ++i) OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n'; } @@ -739,25 +727,26 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; - for (ToolChain::path_list::const_iterator it = TC.getProgramPaths().begin(), - ie = TC.getProgramPaths().end(); it != ie; ++it) { - if (it != TC.getProgramPaths().begin()) + bool separator = false; + for (const std::string &Path : TC.getProgramPaths()) { + if (separator) llvm::outs() << ':'; - llvm::outs() << *it; + llvm::outs() << Path; + separator = true; } llvm::outs() << "\n"; llvm::outs() << "libraries: =" << ResourceDir; StringRef sysroot = C.getSysRoot(); - for (ToolChain::path_list::const_iterator it = TC.getFilePaths().begin(), - ie = TC.getFilePaths().end(); it != ie; ++it) { + for (const std::string &Path : TC.getFilePaths()) { + // Always print a separator. ResourceDir was the first item shown. llvm::outs() << ':'; - const char *path = it->c_str(); - if (path[0] == '=') - llvm::outs() << sysroot << path + 1; + // Interpretation of leading '=' is needed only for NetBSD. + if (Path[0] == '=') + llvm::outs() << sysroot << Path.substr(1); else - llvm::outs() << path; + llvm::outs() << Path; } llvm::outs() << "\n"; return false; @@ -781,23 +770,17 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { } if (C.getArgs().hasArg(options::OPT_print_multi_lib)) { - const MultilibSet &Multilibs = TC.getMultilibs(); - - for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end(); - I != E; ++I) { - llvm::outs() << *I << "\n"; - } + for (const Multilib &Multilib : TC.getMultilibs()) + llvm::outs() << Multilib << "\n"; return false; } if (C.getArgs().hasArg(options::OPT_print_multi_directory)) { - const MultilibSet &Multilibs = TC.getMultilibs(); - for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end(); - I != E; ++I) { - if (I->gccSuffix().empty()) + for (const Multilib &Multilib : TC.getMultilibs()) { + if (Multilib.gccSuffix().empty()) llvm::outs() << ".\n"; else { - StringRef Suffix(I->gccSuffix()); + StringRef Suffix(Multilib.gccSuffix()); assert(Suffix.front() == '/'); llvm::outs() << Suffix.substr(1) << "\n"; } @@ -819,7 +802,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { // and latest-occuring action. Traversal is in pre-order, visiting the // inputs to each action before printing the action itself. static unsigned PrintActions1(const Compilation &C, Action *A, - std::map<Action*, unsigned> &Ids) { + std::map<Action *, unsigned> &Ids) { if (Ids.count(A)) // A was already visited. return Ids[A]; @@ -830,15 +813,13 @@ static unsigned PrintActions1(const Compilation &C, Action *A, if (InputAction *IA = dyn_cast<InputAction>(A)) { os << "\"" << IA->getInputArg().getValue() << "\""; } else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) { - os << '"' << BIA->getArchName() << '"' - << ", {" << PrintActions1(C, *BIA->begin(), Ids) << "}"; + os << '"' << BIA->getArchName() << '"' << ", {" + << PrintActions1(C, *BIA->begin(), Ids) << "}"; } else { - os << "{"; - for (Action::iterator it = A->begin(), ie = A->end(); it != ie;) { - os << PrintActions1(C, *it, Ids); - ++it; - if (it != ie) - os << ", "; + const char *Prefix = "{"; + for (Action *PreRequisite : *A) { + os << Prefix << PrintActions1(C, PreRequisite, Ids); + Prefix = ", "; } os << "}"; } @@ -854,17 +835,15 @@ static unsigned PrintActions1(const Compilation &C, Action *A, // Print the action graphs in a compilation C. // For example "clang -c file1.c file2.c" is composed of two subgraphs. void Driver::PrintActions(const Compilation &C) const { - std::map<Action*, unsigned> Ids; - for (ActionList::const_iterator it = C.getActions().begin(), - ie = C.getActions().end(); it != ie; ++it) - PrintActions1(C, *it, Ids); + std::map<Action *, unsigned> Ids; + for (Action *A : C.getActions()) + PrintActions1(C, A, Ids); } /// \brief Check whether the given input tree contains any compilation or /// assembly actions. static bool ContainsCompileOrAssembleAction(const Action *A) { - if (isa<CompileJobAction>(A) || - isa<BackendJobAction>(A) || + if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) || isa<AssembleJobAction>(A)) return true; @@ -875,8 +854,7 @@ static bool ContainsCompileOrAssembleAction(const Action *A) { return false; } -void Driver::BuildUniversalActions(const ToolChain &TC, - DerivedArgList &Args, +void Driver::BuildUniversalActions(const ToolChain &TC, DerivedArgList &Args, const InputList &BAInputs, ActionList &Actions) const { llvm::PrettyStackTraceString CrashInfo("Building universal build actions"); @@ -889,10 +867,9 @@ void Driver::BuildUniversalActions(const ToolChain &TC, // Validate the option here; we don't save the type here because its // particular spelling may participate in other driver choices. llvm::Triple::ArchType Arch = - tools::darwin::getArchTypeForMachOArchName(A->getValue()); + tools::darwin::getArchTypeForMachOArchName(A->getValue()); if (Arch == llvm::Triple::UnknownArch) { - Diag(clang::diag::err_drv_invalid_arch_name) - << A->getAsString(Args); + Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args); continue; } @@ -923,7 +900,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC, if (Archs.size() > 1 && !types::canLipoType(Act->getType())) Diag(clang::diag::err_drv_invalid_output_with_multiple_archs) - << types::getTypeName(Act->getType()); + << types::getTypeName(Act->getType()); ActionList Inputs; for (unsigned i = 0, e = Archs.size(); i != e; ++i) { @@ -1013,10 +990,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, options::OPT__SLASH_TP)) { InputTypeArg = TCTP; InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) - ? types::TY_C : types::TY_CXX; + ? types::TY_C + : types::TY_CXX; - arg_iterator it = Args.filtered_begin(options::OPT__SLASH_TC, - options::OPT__SLASH_TP); + arg_iterator it = + Args.filtered_begin(options::OPT__SLASH_TC, options::OPT__SLASH_TP); const arg_iterator ie = Args.filtered_end(); Arg *Previous = *it++; bool ShowNote = false; @@ -1078,7 +1056,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (Ty != OldTy) Diag(clang::diag::warn_drv_treating_input_as_cxx) - << getTypeName(OldTy) << getTypeName(Ty); + << getTypeName(OldTy) << getTypeName(Ty); } } @@ -1180,7 +1158,7 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, !llvm::sys::path::is_separator(V.back())) { // Check whether /Fo tries to name an output file for multiple inputs. Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources) - << A->getSpelling() << V; + << A->getSpelling() << V; Args.eraseArg(options::OPT__SLASH_Fo); } } @@ -1192,7 +1170,7 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, !llvm::sys::path::is_separator(V.back())) { // Check whether /Fa tries to name an asm file for multiple inputs. Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources) - << A->getSpelling() << V; + << A->getSpelling() << V; Args.eraseArg(options::OPT__SLASH_Fa); } } @@ -1232,30 +1210,27 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, // by a command-line argument with a corresponding Arg. if (CCCIsCPP()) Diag(clang::diag::warn_drv_input_file_unused_by_cpp) - << InputArg->getAsString(Args) - << getPhaseName(InitialPhase); + << InputArg->getAsString(Args) << getPhaseName(InitialPhase); // Special case '-E' warning on a previously preprocessed file to make // more sense. else if (InitialPhase == phases::Compile && FinalPhase == phases::Preprocess && getPreprocessedType(InputType) == types::TY_INVALID) Diag(clang::diag::warn_drv_preprocessed_input_file_unused) - << InputArg->getAsString(Args) - << !!FinalPhaseArg - << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : ""); + << InputArg->getAsString(Args) << !!FinalPhaseArg + << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : ""); else Diag(clang::diag::warn_drv_input_file_unused) - << InputArg->getAsString(Args) - << getPhaseName(InitialPhase) - << !!FinalPhaseArg - << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : ""); + << InputArg->getAsString(Args) << getPhaseName(InitialPhase) + << !!FinalPhaseArg + << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : ""); continue; } // Build the pipeline for this file. std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType)); - for (SmallVectorImpl<phases::ID>::iterator - i = PL.begin(), e = PL.end(); i != e; ++i) { + for (SmallVectorImpl<phases::ID>::iterator i = PL.begin(), e = PL.end(); + i != e; ++i) { phases::ID Phase = *i; // We are done if this step is past what the user requested. @@ -1308,7 +1283,8 @@ Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args, llvm::PrettyStackTraceString CrashInfo("Constructing phase actions"); // Build the appropriate action. switch (Phase) { - case phases::Link: llvm_unreachable("link action invalid here."); + case phases::Link: + llvm_unreachable("link action invalid here."); case phases::Preprocess: { types::ID OutputTy; // -{M, MM} alter the output type. @@ -1364,12 +1340,12 @@ Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args, case phases::Backend: { if (IsUsingLTO(Args)) { types::ID Output = - Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; + Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; return llvm::make_unique<BackendJobAction>(std::move(Input), Output); } if (Args.hasArg(options::OPT_emit_llvm)) { types::ID Output = - Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC; + Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC; return llvm::make_unique<BackendJobAction>(std::move(Input), Output); } return llvm::make_unique<BackendJobAction>(std::move(Input), @@ -1430,11 +1406,10 @@ void Driver::BuildJobs(Compilation &C) const { InputInfo II; BuildJobsForAction(C, A, &C.getDefaultToolChain(), - /*BoundArch*/nullptr, + /*BoundArch*/ nullptr, /*AtTopLevel*/ true, /*MultipleArchs*/ ArchNames.size() > 1, - /*LinkingOutput*/ LinkingOutput, - II); + /*LinkingOutput*/ LinkingOutput, II); } // If the user passed -Qunused-arguments or there were errors, don't warn @@ -1444,10 +1419,10 @@ void Driver::BuildJobs(Compilation &C) const { return; // Claim -### here. - (void) C.getArgs().hasArg(options::OPT__HASH_HASH_HASH); + (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH); // Claim --driver-mode, it was handled earlier. - (void) C.getArgs().hasArg(options::OPT_driver_mode); + (void)C.getArgs().hasArg(options::OPT_driver_mode); for (Arg *A : C.getArgs()) { // FIXME: It would be nice to be able to send the argument to the @@ -1475,7 +1450,7 @@ void Driver::BuildJobs(Compilation &C) const { } Diag(clang::diag::warn_drv_unused_argument) - << A->getAsString(C.getArgs()); + << A->getAsString(C.getArgs()); } } } @@ -1489,13 +1464,12 @@ static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, // bottom up, so what we are actually looking for is an assembler job with a // compiler input. - if (TC->useIntegratedAs() && - !SaveTemps && + if (TC->useIntegratedAs() && !SaveTemps && !C.getArgs().hasArg(options::OPT_via_file_asm) && !C.getArgs().hasArg(options::OPT__SLASH_FA) && !C.getArgs().hasArg(options::OPT__SLASH_Fa) && - isa<AssembleJobAction>(JA) && - Inputs->size() == 1 && isa<BackendJobAction>(*Inputs->begin())) { + isa<AssembleJobAction>(JA) && Inputs->size() == 1 && + isa<BackendJobAction>(*Inputs->begin())) { // A BackendJob is always preceded by a CompileJob, and without // -save-temps they will always get combined together, so instead of // checking the backend tool, check if the tool for the CompileJob @@ -1536,8 +1510,7 @@ static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, // (irrelevant since we don't support combine yet). if (Inputs->size() == 1 && isa<PreprocessJobAction>(*Inputs->begin()) && !C.getArgs().hasArg(options::OPT_no_integrated_cpp) && - !C.getArgs().hasArg(options::OPT_traditional_cpp) && - !SaveTemps && + !C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps && !C.getArgs().hasArg(options::OPT_rewrite_objc) && ToolForJob->hasIntegratedCPP()) Inputs = &(*Inputs)[0]->getInputs(); @@ -1545,12 +1518,9 @@ static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, return ToolForJob; } -void Driver::BuildJobsForAction(Compilation &C, - const Action *A, - const ToolChain *TC, - const char *BoundArch, - bool AtTopLevel, - bool MultipleArchs, +void Driver::BuildJobsForAction(Compilation &C, const Action *A, + const ToolChain *TC, const char *BoundArch, + bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, InputInfo &Result) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); @@ -1578,8 +1548,8 @@ void Driver::BuildJobsForAction(Compilation &C, else TC = &C.getDefaultToolChain(); - BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(), - AtTopLevel, MultipleArchs, LinkingOutput, Result); + BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(), AtTopLevel, + MultipleArchs, LinkingOutput, Result); return; } @@ -1647,7 +1617,8 @@ const char *Driver::getDefaultImageName() const { /// does not provide a filename, then use BaseName, and use the extension /// suitable for FileType. static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, - StringRef BaseName, types::ID FileType) { + StringRef BaseName, + types::ID FileType) { SmallString<128> Filename = ArgValue; if (ArgValue.empty()) { @@ -1674,16 +1645,13 @@ static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, return Args.MakeArgString(Filename.c_str()); } -const char *Driver::GetNamedOutputPath(Compilation &C, - const JobAction &JA, +const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, - const char *BoundArch, - bool AtTopLevel, + const char *BoundArch, bool AtTopLevel, bool MultipleArchs) const { llvm::PrettyStackTraceString CrashInfo("Computing output path"); // Output to a user requested destination? - if (AtTopLevel && !isa<DsymutilJobAction>(JA) && - !isa<VerifyJobAction>(JA)) { + if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) { if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) return C.addResultFile(FinalOutput->getValue(), &JA); } @@ -1695,8 +1663,9 @@ const char *Driver::GetNamedOutputPath(Compilation &C, StringRef NameArg; if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi)) NameArg = A->getValue(); - return C.addResultFile(MakeCLOutputFilename(C.getArgs(), NameArg, BaseName, - types::TY_PP_C), &JA); + return C.addResultFile( + MakeCLOutputFilename(C.getArgs(), NameArg, BaseName, types::TY_PP_C), + &JA); } // Default to writing to stdout? @@ -1711,19 +1680,19 @@ const char *Driver::GetNamedOutputPath(Compilation &C, // Use /Fa and the input filename to determine the asm file name. StringRef BaseName = llvm::sys::path::filename(BaseInput); StringRef FaValue = C.getArgs().getLastArgValue(options::OPT__SLASH_Fa); - return C.addResultFile(MakeCLOutputFilename(C.getArgs(), FaValue, BaseName, - JA.getType()), &JA); + return C.addResultFile( + MakeCLOutputFilename(C.getArgs(), FaValue, BaseName, JA.getType()), + &JA); } // Output to a temporary file? if ((!AtTopLevel && !isSaveTempsEnabled() && - !C.getArgs().hasArg(options::OPT__SLASH_Fo)) || + !C.getArgs().hasArg(options::OPT__SLASH_Fo)) || CCGenDiagnostics) { StringRef Name = llvm::sys::path::filename(BaseInput); std::pair<StringRef, StringRef> Split = Name.split('.'); - std::string TmpName = - GetTemporaryPath(Split.first, - types::getTypeTempSuffix(JA.getType(), IsCLMode())); + std::string TmpName = GetTemporaryPath( + Split.first, types::getTypeTempSuffix(JA.getType(), IsCLMode())); return C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str())); } @@ -1742,22 +1711,27 @@ const char *Driver::GetNamedOutputPath(Compilation &C, if (JA.getType() == types::TY_Object && C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) { // The /Fo or /o flag decides the object filename. - StringRef Val = C.getArgs().getLastArg(options::OPT__SLASH_Fo, - options::OPT__SLASH_o)->getValue(); - NamedOutput = MakeCLOutputFilename(C.getArgs(), Val, BaseName, - types::TY_Object); + StringRef Val = + C.getArgs() + .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o) + ->getValue(); + NamedOutput = + MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Object); } else if (JA.getType() == types::TY_Image && - C.getArgs().hasArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)) { + C.getArgs().hasArg(options::OPT__SLASH_Fe, + options::OPT__SLASH_o)) { // The /Fe or /o flag names the linked file. - StringRef Val = C.getArgs().getLastArg(options::OPT__SLASH_Fe, - options::OPT__SLASH_o)->getValue(); - NamedOutput = MakeCLOutputFilename(C.getArgs(), Val, BaseName, - types::TY_Image); + StringRef Val = + C.getArgs() + .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o) + ->getValue(); + NamedOutput = + MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Image); } else if (JA.getType() == types::TY_Image) { if (IsCLMode()) { // clang-cl uses BaseName for the executable name. - NamedOutput = MakeCLOutputFilename(C.getArgs(), "", BaseName, - types::TY_Image); + NamedOutput = + MakeCLOutputFilename(C.getArgs(), "", BaseName, types::TY_Image); } else if (MultipleArchs && BoundArch) { SmallString<128> Output(getDefaultImageName()); Output += "-"; @@ -1811,9 +1785,8 @@ const char *Driver::GetNamedOutputPath(Compilation &C, if (SameFile) { StringRef Name = llvm::sys::path::filename(BaseInput); std::pair<StringRef, StringRef> Split = Name.split('.'); - std::string TmpName = - GetTemporaryPath(Split.first, - types::getTypeTempSuffix(JA.getType(), IsCLMode())); + std::string TmpName = GetTemporaryPath( + Split.first, types::getTypeTempSuffix(JA.getType(), IsCLMode())); return C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str())); } } @@ -1834,14 +1807,10 @@ const char *Driver::GetNamedOutputPath(Compilation &C, std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const { // Respect a limited subset of the '-Bprefix' functionality in GCC by // attempting to use this prefix when looking for file paths. - for (Driver::prefix_list::const_iterator it = PrefixDirs.begin(), - ie = PrefixDirs.end(); it != ie; ++it) { - std::string Dir(*it); + for (const std::string &Dir : PrefixDirs) { if (Dir.empty()) continue; - if (Dir[0] == '=') - Dir = SysRoot + Dir.substr(1); - SmallString<128> P(Dir); + SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir); llvm::sys::path::append(P, Name); if (llvm::sys::fs::exists(Twine(P))) return P.str(); @@ -1852,15 +1821,10 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const { if (llvm::sys::fs::exists(Twine(P))) return P.str(); - const ToolChain::path_list &List = TC.getFilePaths(); - for (ToolChain::path_list::const_iterator - it = List.begin(), ie = List.end(); it != ie; ++it) { - std::string Dir(*it); + for (const std::string &Dir : TC.getFilePaths()) { if (Dir.empty()) continue; - if (Dir[0] == '=') - Dir = SysRoot + Dir.substr(1); - SmallString<128> P(Dir); + SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir); llvm::sys::path::append(P, Name); if (llvm::sys::fs::exists(Twine(P))) return P.str(); @@ -1869,9 +1833,9 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const { return Name; } -void -Driver::generatePrefixedToolNames(const char *Tool, const ToolChain &TC, - SmallVectorImpl<std::string> &Names) const { +void Driver::generatePrefixedToolNames( + const char *Tool, const ToolChain &TC, + SmallVectorImpl<std::string> &Names) const { // FIXME: Needs a better variable than DefaultTargetTriple Names.emplace_back(DefaultTargetTriple + "-" + Tool); Names.emplace_back(Tool); @@ -1923,8 +1887,8 @@ std::string Driver::GetProgramPath(const char *Name, return Name; } -std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix) - const { +std::string Driver::GetTemporaryPath(StringRef Prefix, + const char *Suffix) const { SmallString<128> Path; std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path); if (EC) { @@ -1998,7 +1962,7 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, if (Target.getEnvironment() == llvm::Triple::GNUX32) Target.setEnvironment(llvm::Triple::GNU); } else if (A->getOption().matches(options::OPT_mx32) && - Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { + Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { AT = llvm::Triple::x86_64; Target.setEnvironment(llvm::Triple::GNUX32); } else if (A->getOption().matches(options::OPT_m32)) { @@ -2006,7 +1970,7 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, if (Target.getEnvironment() == llvm::Triple::GNUX32) Target.setEnvironment(llvm::Triple::GNU); } else if (A->getOption().matches(options::OPT_m16) && - Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { + Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { AT = llvm::Triple::x86; Target.setEnvironment(llvm::Triple::CODE16); } @@ -2075,12 +2039,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, TC = new toolchains::Generic_GCC(*this, Target, Args); break; case llvm::Triple::GNU: - // FIXME: We need a MinGW toolchain. Use the default Generic_GCC - // toolchain for now as the default case would below otherwise. - if (Target.isOSBinFormatELF()) - TC = new toolchains::Generic_ELF(*this, Target, Args); - else - TC = new toolchains::Generic_GCC(*this, Target, Args); + TC = new toolchains::MinGW(*this, Target, Args); break; case llvm::Triple::Itanium: TC = new toolchains::CrossWindowsToolChain(*this, Target, Args); @@ -2116,8 +2075,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, bool Driver::ShouldUseClangCompiler(const JobAction &JA) const { // Say "no" if there is not exactly one input of a type clang understands. - if (JA.size() != 1 || - !types::isAcceptedByClang((*JA.begin())->getType())) + if (JA.size() != 1 || !types::isAcceptedByClang((*JA.begin())->getType())) return false; // And say "no" if this is not a kind of action clang understands. @@ -2143,21 +2101,21 @@ bool Driver::GetReleaseVersion(const char *Str, unsigned &Major, return false; char *End; - Major = (unsigned) strtol(Str, &End, 10); + Major = (unsigned)strtol(Str, &End, 10); if (*Str != '\0' && *End == '\0') return true; if (*End != '.') return false; - Str = End+1; - Minor = (unsigned) strtol(Str, &End, 10); + Str = End + 1; + Minor = (unsigned)strtol(Str, &End, 10); if (*Str != '\0' && *End == '\0') return true; if (*End != '.') return false; - Str = End+1; - Micro = (unsigned) strtol(Str, &End, 10); + Str = End + 1; + Micro = (unsigned)strtol(Str, &End, 10); if (*Str != '\0' && *End == '\0') return true; if (Str == End) diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp index 6d18a41cad08..ac18e1eb56a1 100644 --- a/lib/Driver/Job.cpp +++ b/lib/Driver/Job.cpp @@ -25,14 +25,10 @@ using llvm::raw_ostream; using llvm::StringRef; using llvm::ArrayRef; -Job::~Job() {} - -Command::Command(const Action &_Source, const Tool &_Creator, - const char *_Executable, - const ArgStringList &_Arguments) - : Job(CommandClass), Source(_Source), Creator(_Creator), - Executable(_Executable), Arguments(_Arguments), - ResponseFile(nullptr) {} +Command::Command(const Action &Source, const Tool &Creator, + const char *Executable, const ArgStringList &Arguments) + : Source(Source), Creator(Creator), Executable(Executable), + Arguments(Arguments), ResponseFile(nullptr) {} static int skipArgs(const char *Flag, bool HaveCrashVFS) { // These flags are all of the form -Flag <Arg> and are treated as two @@ -295,8 +291,6 @@ int FallbackCommand::Execute(const StringRef **Redirects, std::string *ErrMsg, return SecondaryStatus; } -JobList::JobList() : Job(JobListClass) {} - void JobList::Print(raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo) const { for (const auto &Job : *this) diff --git a/lib/Driver/MSVCToolChain.cpp b/lib/Driver/MSVCToolChain.cpp index 72161213db05..f20f58a119f4 100644 --- a/lib/Driver/MSVCToolChain.cpp +++ b/lib/Driver/MSVCToolChain.cpp @@ -53,12 +53,12 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple, } Tool *MSVCToolChain::buildLinker() const { - return new tools::visualstudio::Link(*this); + return new tools::visualstudio::Linker(*this); } Tool *MSVCToolChain::buildAssembler() const { if (getTriple().isOSBinFormatMachO()) - return new tools::darwin::Assemble(*this); + return new tools::darwin::Assembler(*this); getDriver().Diag(clang::diag::err_no_external_assembler); return nullptr; } diff --git a/lib/Driver/MinGWToolChain.cpp b/lib/Driver/MinGWToolChain.cpp new file mode 100644 index 000000000000..606508da6964 --- /dev/null +++ b/lib/Driver/MinGWToolChain.cpp @@ -0,0 +1,143 @@ +//===--- MinGWToolChain.cpp - MinGWToolChain Implementation +//-----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ToolChains.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace clang::diag; +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : ToolChain(D, Triple, Args) { + getProgramPaths().push_back(getDriver().getInstalledDir()); + + if (getDriver().SysRoot.size()) + Base = getDriver().SysRoot; + else if (llvm::ErrorOr<std::string> GPPName = + llvm::sys::findProgramByName("gcc")) + Base = llvm::sys::path::parent_path( + llvm::sys::path::parent_path(GPPName.get())); + else + Base = llvm::sys::path::parent_path(getDriver().getInstalledDir()); + Base += llvm::sys::path::get_separator(); + llvm::SmallString<1024> LibDir(Base); + llvm::sys::path::append(LibDir, "lib", "gcc"); + LibDir += llvm::sys::path::get_separator(); + + // First look for mingw-w64. + Arch = getTriple().getArchName(); + Arch += "-w64-mingw32"; + std::error_code EC; + llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC); + if (!EC) { + GccLibDir = MingW64Entry->path(); + } else { + // If mingw-w64 not found, try looking for mingw.org. + Arch = "mingw32"; + llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC); + if (!EC) + GccLibDir = MingwOrgEntry->path(); + } + Arch += llvm::sys::path::get_separator(); + // GccLibDir must precede Base/lib so that the + // correct crtbegin.o ,cetend.o would be found. + getFilePaths().push_back(GccLibDir); + getFilePaths().push_back(Base + "lib"); + getFilePaths().push_back(Base + Arch + "lib"); +} + +bool MinGW::IsIntegratedAssemblerDefault() const { return true; } + +Tool *MinGW::getTool(Action::ActionClass AC) const { + switch (AC) { + case Action::PreprocessJobClass: + if (!Preprocessor) + Preprocessor.reset(new tools::gcc::Preprocessor(*this)); + return Preprocessor.get(); + case Action::CompileJobClass: + if (!Compiler) + Compiler.reset(new tools::gcc::Compiler(*this)); + return Compiler.get(); + default: + return ToolChain::getTool(AC); + } +} + +Tool *MinGW::buildAssembler() const { + return new tools::MinGW::Assembler(*this); +} + +Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); } + +bool MinGW::IsUnwindTablesDefault() const { + return getArch() == llvm::Triple::x86_64; +} + +bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; } + +bool MinGW::isPIEDefault() const { return false; } + +bool MinGW::isPICDefaultForced() const { + return getArch() == llvm::Triple::x86_64; +} + +bool MinGW::UseSEHExceptions() const { + return getArch() == llvm::Triple::x86_64; +} + +void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<1024> P(getDriver().ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P.str()); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + llvm::SmallString<1024> IncludeDir(GccLibDir); + llvm::sys::path::append(IncludeDir, "include"); + addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); + IncludeDir += "-fixed"; + addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); + addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include"); + addSystemInclude(DriverArgs, CC1Args, Base + "include"); +} + +void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + llvm::SmallString<1024> IncludeDir; + for (bool MingW64 : {true, false}) { + if (MingW64) + IncludeDir = Base + Arch; + else + IncludeDir = GccLibDir; + llvm::sys::path::append(IncludeDir, "include", "c++"); + addSystemInclude(DriverArgs, CC1Args, IncludeDir.str()); + IncludeDir += llvm::sys::path::get_separator(); + addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + Arch); + addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + "backward"); + } +} diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 14c37025eb39..3043481c7132 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// #include "clang/Driver/SanitizerArgs.h" +#include "Tools.h" #include "clang/Basic/Sanitizers.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -26,6 +27,7 @@ using namespace llvm::opt; enum : SanitizerMask { NeedsUbsanRt = Undefined | Integer | CFI, + NeedsUbsanCxxRt = Vptr | CFI, NotAllowedWithTrap = Vptr, RequiresPIE = Memory | DataFlow, NeedsUnwindTables = Address | Thread | Memory | DataFlow, @@ -194,7 +196,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerMask DiagnosedKinds = 0; // All Kinds we have diagnosed up to now. // Used to deduplicate diagnostics. SanitizerMask Kinds = 0; - SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); + const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); const Driver &D = TC.getDriver(); @@ -282,6 +284,21 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto"; } + // Report error if there are non-trapping sanitizers that require + // c++abi-specific parts of UBSan runtime, and they are not provided by the + // toolchain. We don't have a good way to check the latter, so we just + // check if the toolchan supports vptr. + if (~Supported & Vptr) { + if (SanitizerMask KindsToDiagnose = + Kinds & ~TrappingKinds & NeedsUbsanCxxRt) { + SanitizerSet S; + S.Mask = KindsToDiagnose; + D.Diag(diag::err_drv_unsupported_opt_for_target) + << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str(); + Kinds &= ~KindsToDiagnose; + } + } + // Warn about incompatible groups of sanitizers. std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = { std::make_pair(Address, Thread), std::make_pair(Address, Memory), @@ -517,8 +534,9 @@ static std::string toString(const clang::SanitizerSet &Sanitizers) { return Res; } -void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const { +void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + types::ID InputType) const { if (Sanitizers.empty()) return; CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers))); @@ -565,6 +583,17 @@ void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args, // affect compilation. if (Sanitizers.has(Memory) || Sanitizers.has(Address)) CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new")); + + if (TC.getTriple().isOSWindows() && needsUbsanRt()) { + // Instruct the code generator to embed linker directives in the object file + // that cause the required runtime libraries to be linked. + CmdArgs.push_back(Args.MakeArgString( + "--dependent-lib=" + tools::getCompilerRT(TC, "ubsan_standalone"))); + if (types::isCXX(InputType)) + CmdArgs.push_back( + Args.MakeArgString("--dependent-lib=" + + tools::getCompilerRT(TC, "ubsan_standalone_cxx"))); + } } SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 987e063039ca..df74b41b0225 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -39,9 +39,8 @@ using namespace clang::driver::toolchains; using namespace clang; using namespace llvm::opt; -MachO::MachO(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) - : ToolChain(D, Triple, Args) { +MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : ToolChain(D, Triple, Args) { // We expect 'as', 'ld', etc. to be adjacent to our install dir. getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().getInstalledDir() != getDriver().Dir) @@ -62,9 +61,7 @@ types::ID MachO::LookupTypeForExtension(const char *Ext) const { return Ty; } -bool MachO::HasNativeLLVMSupport() const { - return true; -} +bool MachO::HasNativeLLVMSupport() const { return true; } /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { @@ -90,20 +87,20 @@ bool Darwin::hasBlocksRuntime() const { // other assumptions. Maybe MachO should consider standardising // their nomenclature. static const char *ArmMachOArchName(StringRef Arch) { - return llvm::StringSwitch<const char*>(Arch) - .Case("armv6k", "armv6") - .Case("armv6m", "armv6m") - .Case("armv5tej", "armv5") - .Case("xscale", "xscale") - .Case("armv4t", "armv4t") - .Case("armv7", "armv7") - .Cases("armv7a", "armv7-a", "armv7") - .Cases("armv7r", "armv7-r", "armv7") - .Cases("armv7em", "armv7e-m", "armv7em") - .Cases("armv7k", "armv7-k", "armv7k") - .Cases("armv7m", "armv7-m", "armv7m") - .Cases("armv7s", "armv7-s", "armv7s") - .Default(nullptr); + return llvm::StringSwitch<const char *>(Arch) + .Case("armv6k", "armv6") + .Case("armv6m", "armv6m") + .Case("armv5tej", "armv5") + .Case("xscale", "xscale") + .Case("armv4t", "armv4t") + .Case("armv7", "armv7") + .Cases("armv7a", "armv7-a", "armv7") + .Cases("armv7r", "armv7-r", "armv7") + .Cases("armv7em", "armv7e-m", "armv7em") + .Cases("armv7k", "armv7-k", "armv7k") + .Cases("armv7m", "armv7-m", "armv7m") + .Cases("armv7s", "armv7-s", "armv7s") + .Default(nullptr); } static const char *ArmMachOArchNameCPU(StringRef CPU) { @@ -159,15 +156,12 @@ StringRef MachO::getMachOArchName(const ArgList &Args) const { } } -Darwin::~Darwin() { -} - -MachO::~MachO() { -} +Darwin::~Darwin() {} +MachO::~MachO() {} std::string MachO::ComputeEffectiveClangTriple(const ArgList &Args, - types::ID InputType) const { + types::ID InputType) const { llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); return Triple.getTriple(); @@ -211,18 +205,15 @@ Tool *MachO::getTool(Action::ActionClass AC) const { } } -Tool *MachO::buildLinker() const { - return new tools::darwin::Link(*this); -} +Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); } Tool *MachO::buildAssembler() const { - return new tools::darwin::Assemble(*this); + return new tools::darwin::Assembler(*this); } -DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple, +DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Darwin(D, Triple, Args) { -} + : Darwin(D, Triple, Args) {} void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { // For iOS, 64-bit, promote certain warnings to errors. @@ -308,7 +299,7 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, } void Darwin::addProfileRTLibs(const ArgList &Args, - ArgStringList &CmdArgs) const { + ArgStringList &CmdArgs) const { if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, false) || Args.hasArg(options::OPT_fprofile_generate) || @@ -337,10 +328,11 @@ void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, } assert(isTargetMacOS() || isTargetIOSSimulator()); StringRef OS = isTargetMacOS() ? "osx" : "iossim"; - AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.") + Sanitizer + "_" + - OS + "_dynamic.dylib").str(), - /*AlwaysLink*/ true, /*IsEmbedded*/ false, - /*AddRPath*/ true); + AddLinkRuntimeLib( + Args, CmdArgs, + (Twine("libclang_rt.") + Sanitizer + "_" + OS + "_dynamic.dylib").str(), + /*AlwaysLink*/ true, /*IsEmbedded*/ false, + /*AddRPath*/ true); if (GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) { // Add explicit dependcy on -lc++abi, as -lc++ doesn't re-export @@ -357,7 +349,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, break; default: getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform) - << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin"; + << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin"; return; } @@ -372,12 +364,10 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, // cares. This is useful in situations where someone wants to statically link // something like libstdc++, and needs its runtime support routines. if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { - getDriver().Diag(diag::err_drv_unsupported_opt) - << A->getAsString(Args); + getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args); return; } - const SanitizerArgs &Sanitize = getSanitizerArgs(); if (Sanitize.needsAsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); @@ -443,7 +433,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) && StringRef(env) != "/") { Args.append(Args.MakeSeparateArg( - nullptr, Opts.getOption(options::OPT_isysroot), env)); + nullptr, Opts.getOption(options::OPT_isysroot), env)); } } } @@ -453,8 +443,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { if (OSXVersion && iOSVersion) { getDriver().Diag(diag::err_drv_argument_not_allowed_with) - << OSXVersion->getAsString(Args) - << iOSVersion->getAsString(Args); + << OSXVersion->getAsString(Args) << iOSVersion->getAsString(Args); iOSVersion = nullptr; } else if (!OSXVersion && !iOSVersion) { // If no deployment target was specified on the command line, check for @@ -466,16 +455,31 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) iOSTarget = env; - // If no '-miphoneos-version-min' specified on the command line and - // IPHONEOS_DEPLOYMENT_TARGET is not defined, see if we can set the default - // based on -isysroot. - if (iOSTarget.empty()) { + // If there is no command-line argument to specify the Target version and + // no environment variable defined, see if we can set the default based + // on -isysroot. + if (iOSTarget.empty() && OSXTarget.empty() && + Args.hasArg(options::OPT_isysroot)) { if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { - StringRef first, second; StringRef isysroot = A->getValue(); - std::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS")); - if (second != "") - iOSTarget = second.substr(0,3); + // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk + size_t BeginSDK = isysroot.rfind("SDKs/"); + size_t EndSDK = isysroot.rfind(".sdk"); + if (BeginSDK != StringRef::npos && EndSDK != StringRef::npos) { + StringRef SDK = isysroot.slice(BeginSDK + 5, EndSDK); + // Slice the version number out. + // Version number is between the first and the last number. + size_t StartVer = SDK.find_first_of("0123456789"); + size_t EndVer = SDK.find_last_of("0123456789"); + if (StartVer != StringRef::npos && EndVer > StartVer) { + StringRef Version = SDK.slice(StartVer, EndVer + 1); + if (SDK.startswith("iPhoneOS") || + SDK.startswith("iPhoneSimulator")) + iOSTarget = Version; + else if (SDK.startswith("MacOSX")) + OSXTarget = Version; + } + } } } @@ -535,18 +539,18 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { bool HadExtra; if (Platform == MacOS) { assert(!iOSVersion && "Unknown target platform!"); - if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, - Micro, HadExtra) || HadExtra || - Major != 10 || Minor >= 100 || Micro >= 100) + if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro, + HadExtra) || + HadExtra || Major != 10 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) - << OSXVersion->getAsString(Args); + << OSXVersion->getAsString(Args); } else if (Platform == IPhoneOS) { assert(iOSVersion && "Unknown target platform!"); - if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, - Micro, HadExtra) || HadExtra || - Major >= 10 || Minor >= 100 || Micro >= 100) + if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro, + HadExtra) || + HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) - << iOSVersion->getAsString(Args); + << iOSVersion->getAsString(Args); } else llvm_unreachable("unknown kind of Darwin platform"); @@ -646,10 +650,11 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, // Skip this argument unless the architecture matches either the toolchain // triple arch, or the arch being bound. llvm::Triple::ArchType XarchArch = - tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); - if (!(XarchArch == getArch() || - (BoundArch && XarchArch == - tools::darwin::getArchTypeForMachOArchName(BoundArch)))) + tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); + if (!(XarchArch == getArch() || + (BoundArch && + XarchArch == + tools::darwin::getArchTypeForMachOArchName(BoundArch)))) continue; Arg *OriginalArg = A; @@ -667,11 +672,11 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, // like -O4 are going to slip through. if (!XarchArg || Index > Prev + 1) { getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) - << A->getAsString(Args); + << A->getAsString(Args); continue; } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) - << A->getAsString(Args); + << A->getAsString(Args); continue; } @@ -685,11 +690,9 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, // "input arguments". if (A->getOption().hasFlag(options::LinkerInput)) { // Convert the argument into individual Zlinker_input_args. - for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { - DAL->AddSeparateArg(OriginalArg, - Opts.getOption(options::OPT_Zlinker_input), - A->getValue(i)); - + for (const char *Value : A->getValues()) { + DAL->AddSeparateArg( + OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); } continue; } @@ -698,7 +701,7 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, // Sob. These is strictly gcc compatible for the time being. Apple // gcc translates options twice, which means that self-expanding // options add duplicates. - switch ((options::ID) A->getOption().getID()) { + switch ((options::ID)A->getOption().getID()) { default: DAL->append(A); break; @@ -710,20 +713,19 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, break; case options::OPT_dependency_file: - DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), - A->getValue()); + DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue()); break; case options::OPT_gfull: DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); - DAL->AddFlagArg(A, - Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); + DAL->AddFlagArg( + A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); break; case options::OPT_gused: DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); - DAL->AddFlagArg(A, - Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); + DAL->AddFlagArg( + A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); break; case options::OPT_shared: @@ -744,8 +746,8 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, break; case options::OPT_Wno_nonportable_cfstrings: - DAL->AddFlagArg(A, - Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); + DAL->AddFlagArg( + A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); break; case options::OPT_fpascal_strings: @@ -861,7 +863,6 @@ void MachO::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true); } - DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, const char *BoundArch) const { // First get the generic Apple args, before moving onto Darwin-specific ones. @@ -882,7 +883,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, // but we can't check the deployment target in the translation code until // it is set here. if (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0)) { - for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { + for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie;) { Arg *A = *it; ++it; if (A->getOption().getID() != options::OPT_mkernel && @@ -914,8 +915,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, where = "iOS 5.0"; if (where != StringRef()) { - getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) - << where; + getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where; } } @@ -938,13 +938,9 @@ bool Darwin::UseSjLjExceptions() const { getTriple().getArch() == llvm::Triple::thumb); } -bool MachO::isPICDefault() const { - return true; -} +bool MachO::isPICDefault() const { return true; } -bool MachO::isPIEDefault() const { - return false; -} +bool MachO::isPIEDefault() const { return false; } bool MachO::isPICDefaultForced() const { return (getArch() == llvm::Triple::x86_64 || @@ -1058,25 +1054,23 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args, } } -bool Darwin::SupportsObjCGC() const { - return isTargetMacOS(); -} +bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); } void Darwin::CheckObjCARC() const { - if (isTargetIOSBased()|| (isTargetMacOS() && !isMacosxVersionLT(10, 6))) + if (isTargetIOSBased() || (isTargetMacOS() && !isMacosxVersionLT(10, 6))) return; getDriver().Diag(diag::err_arc_unsupported_on_toolchain); } SanitizerMask Darwin::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); - if (isTargetMacOS() || isTargetIOSSimulator()) { - // ASan and UBSan are available on Mac OS and on iOS simulator. + if (isTargetMacOS() || isTargetIOSSimulator()) Res |= SanitizerKind::Address; - Res |= SanitizerKind::Vptr; - } - if (isTargetMacOS()) + if (isTargetMacOS()) { + if (!isMacosxVersionLT(10, 9)) + Res |= SanitizerKind::Vptr; Res |= SanitizerKind::SafeStack; + } return Res; } @@ -1089,17 +1083,15 @@ SanitizerMask Darwin::getSupportedSanitizers() const { /// This is the primary means of forming GCCVersion objects. /*static*/ Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) { - const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; + const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; std::pair<StringRef, StringRef> First = VersionText.split('.'); std::pair<StringRef, StringRef> Second = First.second.split('.'); - GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" }; - if (First.first.getAsInteger(10, GoodVersion.Major) || - GoodVersion.Major < 0) + GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; + if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0) return BadVersion; GoodVersion.MajorStr = First.first.str(); - if (Second.first.getAsInteger(10, GoodVersion.Minor) || - GoodVersion.Minor < 0) + if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0) return BadVersion; GoodVersion.MinorStr = Second.first.str(); @@ -1176,12 +1168,11 @@ static llvm::StringRef getGCCToolchainDir(const ArgList &Args) { /// should instead pull the target out of the driver. This is currently /// necessary because the driver doesn't store the final version of the target /// triple. -void -Generic_GCC::GCCInstallationDetector::init( +void Generic_GCC::GCCInstallationDetector::init( const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args) { - llvm::Triple BiarchVariantTriple = - TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant() - : TargetTriple.get32BitArchVariant(); + llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit() + ? TargetTriple.get64BitArchVariant() + : TargetTriple.get32BitArchVariant(); // The library directories which may contain GCC installations. SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; // The compatible GCC triples for this particular architecture. @@ -1219,25 +1210,22 @@ Generic_GCC::GCCInstallationDetector::init( // Loop over the various components which exist and select the best GCC // installation available. GCC installs are ranked by version number. Version = GCCVersion::Parse("0.0.0"); - for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) { - if (!llvm::sys::fs::exists(Prefixes[i])) + for (const std::string &Prefix : Prefixes) { + if (!llvm::sys::fs::exists(Prefix)) continue; - for (unsigned j = 0, je = CandidateLibDirs.size(); j < je; ++j) { - const std::string LibDir = Prefixes[i] + CandidateLibDirs[j].str(); + for (const StringRef Suffix : CandidateLibDirs) { + const std::string LibDir = Prefix + Suffix.str(); if (!llvm::sys::fs::exists(LibDir)) continue; - for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k) - ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, - CandidateTripleAliases[k]); + for (const StringRef Candidate : CandidateTripleAliases) + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate); } - for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) { - const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str(); + for (const StringRef Suffix : CandidateBiarchLibDirs) { + const std::string LibDir = Prefix + Suffix.str(); if (!llvm::sys::fs::exists(LibDir)) continue; - for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke; - ++k) - ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, - CandidateBiarchTripleAliases[k], + for (const StringRef Candidate : CandidateBiarchTripleAliases) + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, /*NeedsBiarchSuffix=*/ true); } } @@ -1274,91 +1262,82 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const { // Declare a bunch of static data sets that we'll select between below. These // are specifically designed to always refer to string literals to avoid any // lifetime or initialization issues. - static const char *const AArch64LibDirs[] = { "/lib64", "/lib" }; - static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu", - "aarch64-linux-gnu", - "aarch64-linux-android", - "aarch64-redhat-linux" }; - static const char *const AArch64beLibDirs[] = { "/lib" }; - static const char *const AArch64beTriples[] = { "aarch64_be-none-linux-gnu", - "aarch64_be-linux-gnu" }; - - static const char *const ARMLibDirs[] = { "/lib" }; - static const char *const ARMTriples[] = { "arm-linux-gnueabi", - "arm-linux-androideabi" }; - static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf", - "armv7hl-redhat-linux-gnueabi" }; - static const char *const ARMebLibDirs[] = { "/lib" }; - static const char *const ARMebTriples[] = { "armeb-linux-gnueabi", - "armeb-linux-androideabi" }; - static const char *const ARMebHFTriples[] = { "armeb-linux-gnueabihf", - "armebv7hl-redhat-linux-gnueabi" }; - - static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; + static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; + static const char *const AArch64Triples[] = { + "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android", + "aarch64-redhat-linux"}; + static const char *const AArch64beLibDirs[] = {"/lib"}; + static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", + "aarch64_be-linux-gnu"}; + + static const char *const ARMLibDirs[] = {"/lib"}; + static const char *const ARMTriples[] = {"arm-linux-gnueabi", + "arm-linux-androideabi"}; + static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf", + "armv7hl-redhat-linux-gnueabi"}; + static const char *const ARMebLibDirs[] = {"/lib"}; + static const char *const ARMebTriples[] = {"armeb-linux-gnueabi", + "armeb-linux-androideabi"}; + static const char *const ARMebHFTriples[] = { + "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"}; + + static const char *const X86_64LibDirs[] = {"/lib64", "/lib"}; static const char *const X86_64Triples[] = { - "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu", - "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux", - "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", - "x86_64-linux-android", "x86_64-unknown-linux" - }; - static const char *const X32LibDirs[] = { "/libx32" }; - static const char *const X86LibDirs[] = { "/lib32", "/lib" }; + "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", + "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E", + "x86_64-redhat-linux", "x86_64-suse-linux", + "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", + "x86_64-slackware-linux", "x86_64-linux-android", + "x86_64-unknown-linux"}; + static const char *const X32LibDirs[] = {"/libx32"}; + static const char *const X86LibDirs[] = {"/lib32", "/lib"}; static const char *const X86Triples[] = { - "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu", - "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux", - "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux", - "i686-montavista-linux", "i686-linux-android", "i586-linux-gnu" - }; - - static const char *const MIPSLibDirs[] = { "/lib" }; - static const char *const MIPSTriples[] = { "mips-linux-gnu", - "mips-mti-linux-gnu", - "mips-img-linux-gnu" }; - static const char *const MIPSELLibDirs[] = { "/lib" }; - static const char *const MIPSELTriples[] = { "mipsel-linux-gnu", - "mipsel-linux-android", - "mips-img-linux-gnu" }; - - static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" }; - static const char *const MIPS64Triples[] = { "mips64-linux-gnu", - "mips-mti-linux-gnu", - "mips-img-linux-gnu", - "mips64-linux-gnuabi64" }; - static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" }; - static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu", - "mips-mti-linux-gnu", - "mips-img-linux-gnu", - "mips64el-linux-android", - "mips64el-linux-gnuabi64" }; - - static const char *const PPCLibDirs[] = { "/lib32", "/lib" }; + "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", + "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux", + "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux", + "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android", + "i586-linux-gnu"}; + + static const char *const MIPSLibDirs[] = {"/lib"}; + static const char *const MIPSTriples[] = { + "mips-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu"}; + static const char *const MIPSELLibDirs[] = {"/lib"}; + static const char *const MIPSELTriples[] = { + "mipsel-linux-gnu", "mipsel-linux-android", "mips-img-linux-gnu"}; + + static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; + static const char *const MIPS64Triples[] = { + "mips64-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu", + "mips64-linux-gnuabi64"}; + static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"}; + static const char *const MIPS64ELTriples[] = { + "mips64el-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu", + "mips64el-linux-android", "mips64el-linux-gnuabi64"}; + + static const char *const PPCLibDirs[] = {"/lib32", "/lib"}; static const char *const PPCTriples[] = { - "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", - "powerpc-suse-linux", "powerpc-montavista-linuxspe" - }; - static const char *const PPC64LibDirs[] = { "/lib64", "/lib" }; - static const char *const PPC64Triples[] = { "powerpc64-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64-suse-linux", - "ppc64-redhat-linux" }; - static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" }; - static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "powerpc64le-suse-linux", - "ppc64le-redhat-linux" }; - - static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" }; - static const char *const SPARCv8Triples[] = { "sparc-linux-gnu", - "sparcv8-linux-gnu" }; - static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" }; - static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu", - "sparcv9-linux-gnu" }; - - static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; + "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", + "powerpc-suse-linux", "powerpc-montavista-linuxspe"}; + static const char *const PPC64LibDirs[] = {"/lib64", "/lib"}; + static const char *const PPC64Triples[] = { + "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu", + "powerpc64-suse-linux", "ppc64-redhat-linux"}; + static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"}; + static const char *const PPC64LETriples[] = { + "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", + "powerpc64le-suse-linux", "ppc64le-redhat-linux"}; + + static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"}; + static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", + "sparcv8-linux-gnu"}; + static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"}; + static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu", + "sparcv9-linux-gnu"}; + + static const char *const SystemZLibDirs[] = {"/lib64", "/lib"}; static const char *const SystemZTriples[] = { - "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", - "s390x-suse-linux", "s390x-redhat-linux" - }; + "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", + "s390x-suse-linux", "s390x-redhat-linux"}; using std::begin; using std::end; @@ -1526,14 +1505,12 @@ static bool isMipsEL(llvm::Triple::ArchType Arch) { } static bool isMips16(const ArgList &Args) { - Arg *A = Args.getLastArg(options::OPT_mips16, - options::OPT_mno_mips16); + Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16); return A && A->getOption().matches(options::OPT_mips16); } static bool isMicroMips(const ArgList &Args) { - Arg *A = Args.getLastArg(options::OPT_mmicromips, - options::OPT_mno_micromips); + Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips); return A && A->getOption().matches(options::OPT_mmicromips); } @@ -1554,8 +1531,7 @@ static Multilib makeMultilib(StringRef commonSuffix) { } static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, - const ArgList &Args, - DetectedMultilibs &Result) { + const ArgList &Args, DetectedMultilibs &Result) { // Some MIPS toolchains put libraries and object files compiled // using different options in to the sub-directoris which names // reflects the flags used for compilation. For example sysroot @@ -1587,181 +1563,182 @@ static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, MultilibSet FSFMipsMultilibs; { auto MArchMips32 = makeMultilib("/mips32") - .flag("+m32").flag("-m64").flag("-mmicromips").flag("+march=mips32"); + .flag("+m32") + .flag("-m64") + .flag("-mmicromips") + .flag("+march=mips32"); auto MArchMicroMips = makeMultilib("/micromips") - .flag("+m32").flag("-m64").flag("+mmicromips"); + .flag("+m32") + .flag("-m64") + .flag("+mmicromips"); auto MArchMips64r2 = makeMultilib("/mips64r2") - .flag("-m32").flag("+m64").flag("+march=mips64r2"); + .flag("-m32") + .flag("+m64") + .flag("+march=mips64r2"); - auto MArchMips64 = makeMultilib("/mips64") - .flag("-m32").flag("+m64").flag("-march=mips64r2"); + auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag( + "-march=mips64r2"); auto MArchDefault = makeMultilib("") - .flag("+m32").flag("-m64").flag("-mmicromips").flag("+march=mips32r2"); - - auto Mips16 = makeMultilib("/mips16") - .flag("+mips16"); - - auto UCLibc = makeMultilib("/uclibc") - .flag("+muclibc"); - - auto MAbi64 = makeMultilib("/64") - .flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); - - auto BigEndian = makeMultilib("") - .flag("+EB").flag("-EL"); - - auto LittleEndian = makeMultilib("/el") - .flag("+EL").flag("-EB"); - - auto SoftFloat = makeMultilib("/sof") - .flag("+msoft-float"); - - auto Nan2008 = makeMultilib("/nan2008") - .flag("+mnan=2008"); - - FSFMipsMultilibs = MultilibSet() - .Either(MArchMips32, MArchMicroMips, - MArchMips64r2, MArchMips64, MArchDefault) - .Maybe(UCLibc) - .Maybe(Mips16) - .FilterOut("/mips64/mips16") - .FilterOut("/mips64r2/mips16") - .FilterOut("/micromips/mips16") - .Maybe(MAbi64) - .FilterOut("/micromips/64") - .FilterOut("/mips32/64") - .FilterOut("^/64") - .FilterOut("/mips16/64") - .Either(BigEndian, LittleEndian) - .Maybe(SoftFloat) - .Maybe(Nan2008) - .FilterOut(".*sof/nan2008") - .FilterOut(NonExistent) - .setIncludeDirsCallback([]( - StringRef InstallDir, StringRef TripleStr, const Multilib &M) { - std::vector<std::string> Dirs; - Dirs.push_back((InstallDir + "/include").str()); - std::string SysRootInc = InstallDir.str() + "/../../../../sysroot"; - if (StringRef(M.includeSuffix()).startswith("/uclibc")) - Dirs.push_back(SysRootInc + "/uclibc/usr/include"); - else - Dirs.push_back(SysRootInc + "/usr/include"); - return Dirs; - }); + .flag("+m32") + .flag("-m64") + .flag("-mmicromips") + .flag("+march=mips32r2"); + + auto Mips16 = makeMultilib("/mips16").flag("+mips16"); + + auto UCLibc = makeMultilib("/uclibc").flag("+muclibc"); + + auto MAbi64 = + makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); + + auto BigEndian = makeMultilib("").flag("+EB").flag("-EL"); + + auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB"); + + auto SoftFloat = makeMultilib("/sof").flag("+msoft-float"); + + auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008"); + + FSFMipsMultilibs = + MultilibSet() + .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64, + MArchDefault) + .Maybe(UCLibc) + .Maybe(Mips16) + .FilterOut("/mips64/mips16") + .FilterOut("/mips64r2/mips16") + .FilterOut("/micromips/mips16") + .Maybe(MAbi64) + .FilterOut("/micromips/64") + .FilterOut("/mips32/64") + .FilterOut("^/64") + .FilterOut("/mips16/64") + .Either(BigEndian, LittleEndian) + .Maybe(SoftFloat) + .Maybe(Nan2008) + .FilterOut(".*sof/nan2008") + .FilterOut(NonExistent) + .setIncludeDirsCallback([](StringRef InstallDir, + StringRef TripleStr, const Multilib &M) { + std::vector<std::string> Dirs; + Dirs.push_back((InstallDir + "/include").str()); + std::string SysRootInc = + InstallDir.str() + "/../../../../sysroot"; + if (StringRef(M.includeSuffix()).startswith("/uclibc")) + Dirs.push_back(SysRootInc + "/uclibc/usr/include"); + else + Dirs.push_back(SysRootInc + "/usr/include"); + return Dirs; + }); } // Check for Code Sourcery toolchain multilibs MultilibSet CSMipsMultilibs; { - auto MArchMips16 = makeMultilib("/mips16") - .flag("+m32").flag("+mips16"); + auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16"); - auto MArchMicroMips = makeMultilib("/micromips") - .flag("+m32").flag("+mmicromips"); + auto MArchMicroMips = + makeMultilib("/micromips").flag("+m32").flag("+mmicromips"); - auto MArchDefault = makeMultilib("") - .flag("-mips16").flag("-mmicromips"); + auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips"); - auto UCLibc = makeMultilib("/uclibc") - .flag("+muclibc"); + auto UCLibc = makeMultilib("/uclibc").flag("+muclibc"); - auto SoftFloat = makeMultilib("/soft-float") - .flag("+msoft-float"); + auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float"); - auto Nan2008 = makeMultilib("/nan2008") - .flag("+mnan=2008"); + auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008"); - auto DefaultFloat = makeMultilib("") - .flag("-msoft-float").flag("-mnan=2008"); + auto DefaultFloat = + makeMultilib("").flag("-msoft-float").flag("-mnan=2008"); - auto BigEndian = makeMultilib("") - .flag("+EB").flag("-EL"); + auto BigEndian = makeMultilib("").flag("+EB").flag("-EL"); - auto LittleEndian = makeMultilib("/el") - .flag("+EL").flag("-EB"); + auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB"); // Note that this one's osSuffix is "" auto MAbi64 = makeMultilib("") - .gccSuffix("/64") - .includeSuffix("/64") - .flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); - - CSMipsMultilibs = MultilibSet() - .Either(MArchMips16, MArchMicroMips, MArchDefault) - .Maybe(UCLibc) - .Either(SoftFloat, Nan2008, DefaultFloat) - .FilterOut("/micromips/nan2008") - .FilterOut("/mips16/nan2008") - .Either(BigEndian, LittleEndian) - .Maybe(MAbi64) - .FilterOut("/mips16.*/64") - .FilterOut("/micromips.*/64") - .FilterOut(NonExistent) - .setIncludeDirsCallback([]( - StringRef InstallDir, StringRef TripleStr, const Multilib &M) { - std::vector<std::string> Dirs; - Dirs.push_back((InstallDir + "/include").str()); - std::string SysRootInc = - InstallDir.str() + "/../../../../" + TripleStr.str(); - if (StringRef(M.includeSuffix()).startswith("/uclibc")) - Dirs.push_back(SysRootInc + "/libc/uclibc/usr/include"); - else - Dirs.push_back(SysRootInc + "/libc/usr/include"); - return Dirs; - }); - } - - MultilibSet AndroidMipsMultilibs = MultilibSet() - .Maybe(Multilib("/mips-r2").flag("+march=mips32r2")) - .Maybe(Multilib("/mips-r6").flag("+march=mips32r6")) - .FilterOut(NonExistent); + .gccSuffix("/64") + .includeSuffix("/64") + .flag("+mabi=n64") + .flag("-mabi=n32") + .flag("-m32"); + + CSMipsMultilibs = + MultilibSet() + .Either(MArchMips16, MArchMicroMips, MArchDefault) + .Maybe(UCLibc) + .Either(SoftFloat, Nan2008, DefaultFloat) + .FilterOut("/micromips/nan2008") + .FilterOut("/mips16/nan2008") + .Either(BigEndian, LittleEndian) + .Maybe(MAbi64) + .FilterOut("/mips16.*/64") + .FilterOut("/micromips.*/64") + .FilterOut(NonExistent) + .setIncludeDirsCallback([](StringRef InstallDir, + StringRef TripleStr, const Multilib &M) { + std::vector<std::string> Dirs; + Dirs.push_back((InstallDir + "/include").str()); + std::string SysRootInc = + InstallDir.str() + "/../../../../" + TripleStr.str(); + if (StringRef(M.includeSuffix()).startswith("/uclibc")) + Dirs.push_back(SysRootInc + "/libc/uclibc/usr/include"); + else + Dirs.push_back(SysRootInc + "/libc/usr/include"); + return Dirs; + }); + } + + MultilibSet AndroidMipsMultilibs = + MultilibSet() + .Maybe(Multilib("/mips-r2").flag("+march=mips32r2")) + .Maybe(Multilib("/mips-r6").flag("+march=mips32r6")) + .FilterOut(NonExistent); MultilibSet DebianMipsMultilibs; { - Multilib MAbiN32 = Multilib() - .gccSuffix("/n32") - .includeSuffix("/n32") - .flag("+mabi=n32"); + Multilib MAbiN32 = + Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32"); Multilib M64 = Multilib() - .gccSuffix("/64") - .includeSuffix("/64") - .flag("+m64").flag("-m32").flag("-mabi=n32"); + .gccSuffix("/64") + .includeSuffix("/64") + .flag("+m64") + .flag("-m32") + .flag("-mabi=n32"); - Multilib M32 = Multilib() - .flag("-m64").flag("+m32").flag("-mabi=n32"); + Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32"); - DebianMipsMultilibs = MultilibSet() - .Either(M32, M64, MAbiN32) - .FilterOut(NonExistent); + DebianMipsMultilibs = + MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent); } MultilibSet ImgMultilibs; { - auto Mips64r6 = makeMultilib("/mips64r6") - .flag("+m64").flag("-m32"); + auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32"); - auto LittleEndian = makeMultilib("/el") - .flag("+EL").flag("-EB"); + auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB"); - auto MAbi64 = makeMultilib("/64") - .flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); + auto MAbi64 = + makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); - ImgMultilibs = MultilibSet() - .Maybe(Mips64r6) - .Maybe(MAbi64) - .Maybe(LittleEndian) - .FilterOut(NonExistent) - .setIncludeDirsCallback([]( - StringRef InstallDir, StringRef TripleStr, const Multilib &M) { - std::vector<std::string> Dirs; - Dirs.push_back((InstallDir + "/include").str()); - Dirs.push_back((InstallDir + "/../../../../sysroot/usr/include").str()); - return Dirs; - }); + ImgMultilibs = + MultilibSet() + .Maybe(Mips64r6) + .Maybe(MAbi64) + .Maybe(LittleEndian) + .FilterOut(NonExistent) + .setIncludeDirsCallback([](StringRef InstallDir, + StringRef TripleStr, const Multilib &M) { + std::vector<std::string> Dirs; + Dirs.push_back((InstallDir + "/include").str()); + Dirs.push_back( + (InstallDir + "/../../../../sysroot/usr/include").str()); + return Dirs; + }); } StringRef CPUName; @@ -1816,8 +1793,8 @@ static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, // Sort candidates. Toolchain that best meets the directories goes first. // Then select the first toolchains matches command line flags. - MultilibSet *candidates[] = { &DebianMipsMultilibs, &FSFMipsMultilibs, - &CSMipsMultilibs }; + MultilibSet *candidates[] = {&DebianMipsMultilibs, &FSFMipsMultilibs, + &CSMipsMultilibs}; std::sort( std::begin(candidates), std::end(candidates), [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); }); @@ -1859,17 +1836,23 @@ static bool findBiarchMultilibs(const llvm::Triple &TargetTriple, Multilib Default; Multilib Alt64 = Multilib() - .gccSuffix("/64") - .includeSuffix("/64") - .flag("-m32").flag("+m64").flag("-mx32"); + .gccSuffix("/64") + .includeSuffix("/64") + .flag("-m32") + .flag("+m64") + .flag("-mx32"); Multilib Alt32 = Multilib() - .gccSuffix("/32") - .includeSuffix("/32") - .flag("+m32").flag("-m64").flag("-mx32"); + .gccSuffix("/32") + .includeSuffix("/32") + .flag("+m32") + .flag("-m64") + .flag("-mx32"); Multilib Altx32 = Multilib() - .gccSuffix("/x32") - .includeSuffix("/x32") - .flag("-m32").flag("-m64").flag("+mx32"); + .gccSuffix("/x32") + .includeSuffix("/x32") + .flag("-m32") + .flag("-m64") + .flag("+mx32"); FilterNonExistent NonExistent(Path); @@ -1916,8 +1899,7 @@ static bool findBiarchMultilibs(const llvm::Triple &TargetTriple, if (!Result.Multilibs.select(Flags, Result.SelectedMultilib)) return false; - if (Result.SelectedMultilib == Alt64 || - Result.SelectedMultilib == Alt32 || + if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32 || Result.SelectedMultilib == Altx32) Result.BiarchSibling = Default; @@ -1933,27 +1915,26 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( // check for. We also record what is necessary to walk from each back // up to the lib directory. const std::string LibSuffixes[] = { - "/gcc/" + CandidateTriple.str(), - // Debian puts cross-compilers in gcc-cross - "/gcc-cross/" + CandidateTriple.str(), - "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), - - // The Freescale PPC SDK has the gcc libraries in - // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. - "/" + CandidateTriple.str(), - - // Ubuntu has a strange mis-matched pair of triples that this happens to - // match. - // FIXME: It may be worthwhile to generalize this and look for a second - // triple. - "/i386-linux-gnu/gcc/" + CandidateTriple.str() - }; + "/gcc/" + CandidateTriple.str(), + // Debian puts cross-compilers in gcc-cross + "/gcc-cross/" + CandidateTriple.str(), + "/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), + + // The Freescale PPC SDK has the gcc libraries in + // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. + "/" + CandidateTriple.str(), + + // Ubuntu has a strange mis-matched pair of triples that this happens to + // match. + // FIXME: It may be worthwhile to generalize this and look for a second + // triple. + "/i386-linux-gnu/gcc/" + CandidateTriple.str()}; const std::string InstallSuffixes[] = { - "/../../..", // gcc/ - "/../../..", // gcc-cross/ - "/../../../..", // <triple>/gcc/ - "/../..", // <triple>/ - "/../../../.." // i386-linux-gnu/gcc/<triple>/ + "/../../..", // gcc/ + "/../../..", // gcc-cross/ + "/../../../..", // <triple>/gcc/ + "/../..", // <triple>/ + "/../../../.." // i386-linux-gnu/gcc/<triple>/ }; // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. const unsigned NumLibSuffixes = @@ -2000,26 +1981,25 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( } } -Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple, +Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : ToolChain(D, Triple, Args), GCCInstallation() { + : ToolChain(D, Triple, Args), GCCInstallation() { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().getInstalledDir() != getDriver().Dir) getProgramPaths().push_back(getDriver().Dir); } -Generic_GCC::~Generic_GCC() { -} +Generic_GCC::~Generic_GCC() {} Tool *Generic_GCC::getTool(Action::ActionClass AC) const { switch (AC) { case Action::PreprocessJobClass: if (!Preprocess) - Preprocess.reset(new tools::gcc::Preprocess(*this)); + Preprocess.reset(new tools::gcc::Preprocessor(*this)); return Preprocess.get(); case Action::CompileJobClass: if (!Compile) - Compile.reset(new tools::gcc::Compile(*this)); + Compile.reset(new tools::gcc::Compiler(*this)); return Compile.get(); default: return ToolChain::getTool(AC); @@ -2027,12 +2007,10 @@ Tool *Generic_GCC::getTool(Action::ActionClass AC) const { } Tool *Generic_GCC::buildAssembler() const { - return new tools::gnutools::Assemble(*this); + return new tools::gnutools::Assembler(*this); } -Tool *Generic_GCC::buildLinker() const { - return new tools::gcc::Link(*this); -} +Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); } void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { // Print the information about how we detected the GCC installation. @@ -2044,15 +2022,13 @@ bool Generic_GCC::IsUnwindTablesDefault() const { } bool Generic_GCC::isPICDefault() const { - return false; + return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows(); } -bool Generic_GCC::isPIEDefault() const { - return false; -} +bool Generic_GCC::isPIEDefault() const { return false; } bool Generic_GCC::isPICDefaultForced() const { - return false; + return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows(); } bool Generic_GCC::IsIntegratedAssemblerDefault() const { @@ -2092,8 +2068,7 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, getTriple().getOS() == llvm::Triple::NaCl; if (DriverArgs.hasFlag(options::OPT_fuse_init_array, - options::OPT_fno_use_init_array, - UseInitArrayDefault)) + options::OPT_fno_use_init_array, UseInitArrayDefault)) CC1Args.push_back("-fuse-init-array"); } @@ -2119,18 +2094,15 @@ std::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir, return InstallRelDir; } -const char *Hexagon_TC::GetSmallDataThreshold(const ArgList &Args) -{ +const char *Hexagon_TC::GetSmallDataThreshold(const ArgList &Args) { Arg *A; - A = Args.getLastArg(options::OPT_G, - options::OPT_G_EQ, + A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ, options::OPT_msmall_data_threshold_EQ); if (A) return A->getValue(); - A = Args.getLastArg(options::OPT_shared, - options::OPT_fpic, + A = Args.getLastArg(options::OPT_shared, options::OPT_fpic, options::OPT_fPIC); if (A) return "0"; @@ -2138,26 +2110,22 @@ const char *Hexagon_TC::GetSmallDataThreshold(const ArgList &Args) return 0; } -bool Hexagon_TC::UsesG0(const char* smallDataThreshold) -{ +bool Hexagon_TC::UsesG0(const char *smallDataThreshold) { return smallDataThreshold && smallDataThreshold[0] == '0'; } -static void GetHexagonLibraryPaths( - const ArgList &Args, - const std::string &Ver, - const std::string &MarchString, - const std::string &InstalledDir, - ToolChain::path_list *LibPaths) -{ +static void GetHexagonLibraryPaths(const ArgList &Args, const std::string &Ver, + const std::string &MarchString, + const std::string &InstalledDir, + ToolChain::path_list *LibPaths) { bool buildingLib = Args.hasArg(options::OPT_shared); //---------------------------------------------------------------------------- // -L Args //---------------------------------------------------------------------------- - for (const Arg *A : Args.filtered(options::OPT_L)) - for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) - LibPaths->push_back(A->getValue(i)); + for (Arg *A : Args.filtered(options::OPT_L)) + for (const char *Value : A->getValues()) + LibPaths->push_back(Value); //---------------------------------------------------------------------------- // Other standard paths @@ -2191,7 +2159,7 @@ static void GetHexagonLibraryPaths( Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Linux(D, Triple, Args) { + : Linux(D, Triple, Args) { const std::string InstalledDir(getDriver().getInstalledDir()); const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir, Args); @@ -2204,7 +2172,7 @@ Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, // Determine version of GCC libraries and headers to use. const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); std::error_code ec; - GCCVersion MaxVersion= GCCVersion::Parse("0.0.0"); + GCCVersion MaxVersion = GCCVersion::Parse("0.0.0"); for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de; !ec && di != de; di = di.increment(ec)) { GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path())); @@ -2213,30 +2181,25 @@ Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple &Triple, } GCCLibAndIncVersion = MaxVersion; - ToolChain::path_list *LibPaths= &getFilePaths(); + ToolChain::path_list *LibPaths = &getFilePaths(); // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets // 'elf' OS type, so the Linux paths are not appropriate. When we actually // support 'linux' we'll need to fix this up LibPaths->clear(); - GetHexagonLibraryPaths( - Args, - GetGCCLibAndIncVersion(), - GetTargetCPU(Args), - InstalledDir, - LibPaths); + GetHexagonLibraryPaths(Args, GetGCCLibAndIncVersion(), GetTargetCPU(Args), + InstalledDir, LibPaths); } -Hexagon_TC::~Hexagon_TC() { -} +Hexagon_TC::~Hexagon_TC() {} Tool *Hexagon_TC::buildAssembler() const { - return new tools::hexagon::Assemble(*this); + return new tools::hexagon::Assembler(*this); } Tool *Hexagon_TC::buildLinker() const { - return new tools::hexagon::Link(*this); + return new tools::hexagon::Linker(*this); } void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, @@ -2280,8 +2243,7 @@ Hexagon_TC::GetCXXStdlibType(const ArgList &Args) const { StringRef Value = A->getValue(); if (Value != "libstdc++") { - getDriver().Diag(diag::err_drv_invalid_stdlib_name) - << A->getAsString(Args); + getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); } return ToolChain::CST_Libstdcxx; @@ -2310,8 +2272,7 @@ static int getHexagonVersion(const ArgList &Args) { return 4; } -StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) -{ +StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) { int V = getHexagonVersion(Args); // FIXME: We don't support versions < 4. We should error on them. switch (V) { @@ -2334,13 +2295,13 @@ StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args) /// NaCl Toolchain NaCl_TC::NaCl_TC(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { + : Generic_ELF(D, Triple, Args) { // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the // default paths, and must instead only use the paths provided // with this toolchain based on architecture. - path_list& file_paths = getFilePaths(); - path_list& prog_paths = getProgramPaths(); + path_list &file_paths = getFilePaths(); + path_list &prog_paths = getProgramPaths(); file_paths.clear(); prog_paths.clear(); @@ -2354,30 +2315,30 @@ NaCl_TC::NaCl_TC(const Driver &D, const llvm::Triple &Triple, // Path for toolchain libraries (libgcc.a, ...) std::string ToolPath(getDriver().ResourceDir + "/lib/"); - switch(Triple.getArch()) { - case llvm::Triple::x86: { - file_paths.push_back(FilePath + "x86_64-nacl/lib32"); - file_paths.push_back(FilePath + "x86_64-nacl/usr/lib32"); - prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); - file_paths.push_back(ToolPath + "i686-nacl"); - break; - } - case llvm::Triple::x86_64: { - file_paths.push_back(FilePath + "x86_64-nacl/lib"); - file_paths.push_back(FilePath + "x86_64-nacl/usr/lib"); - prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); - file_paths.push_back(ToolPath + "x86_64-nacl"); - break; - } - case llvm::Triple::arm: { - file_paths.push_back(FilePath + "arm-nacl/lib"); - file_paths.push_back(FilePath + "arm-nacl/usr/lib"); - prog_paths.push_back(ProgPath + "arm-nacl/bin"); - file_paths.push_back(ToolPath + "arm-nacl"); - break; - } - default: - break; + switch (Triple.getArch()) { + case llvm::Triple::x86: { + file_paths.push_back(FilePath + "x86_64-nacl/lib32"); + file_paths.push_back(FilePath + "x86_64-nacl/usr/lib32"); + prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); + file_paths.push_back(ToolPath + "i686-nacl"); + break; + } + case llvm::Triple::x86_64: { + file_paths.push_back(FilePath + "x86_64-nacl/lib"); + file_paths.push_back(FilePath + "x86_64-nacl/usr/lib"); + prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); + file_paths.push_back(ToolPath + "x86_64-nacl"); + break; + } + case llvm::Triple::arm: { + file_paths.push_back(FilePath + "arm-nacl/lib"); + file_paths.push_back(FilePath + "arm-nacl/usr/lib"); + prog_paths.push_back(ProgPath + "arm-nacl/bin"); + file_paths.push_back(ToolPath + "arm-nacl"); + break; + } + default: + break; } // Use provided linker, not system linker @@ -2401,13 +2362,17 @@ void NaCl_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs, return; SmallString<128> P(D.Dir + "/../"); - if (getTriple().getArch() == llvm::Triple::arm) { + switch (getTriple().getArch()) { + case llvm::Triple::arm: llvm::sys::path::append(P, "arm-nacl/usr/include"); - } else if (getTriple().getArch() == llvm::Triple::x86) { + break; + case llvm::Triple::x86: llvm::sys::path::append(P, "x86_64-nacl/usr/include"); - } else if (getTriple().getArch() == llvm::Triple::x86_64) { + break; + case llvm::Triple::x86_64: llvm::sys::path::append(P, "x86_64-nacl/usr/include"); - } else { + break; + default: return; } @@ -2437,18 +2402,22 @@ void NaCl_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, // if the value is libc++, and emits an error for other values. GetCXXStdlibType(DriverArgs); - if (getTriple().getArch() == llvm::Triple::arm) { - SmallString<128> P(D.Dir + "/../"); + SmallString<128> P(D.Dir + "/../"); + switch (getTriple().getArch()) { + case llvm::Triple::arm: llvm::sys::path::append(P, "arm-nacl/include/c++/v1"); addSystemInclude(DriverArgs, CC1Args, P.str()); - } else if (getTriple().getArch() == llvm::Triple::x86) { - SmallString<128> P(D.Dir + "/../"); + break; + case llvm::Triple::x86: llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1"); addSystemInclude(DriverArgs, CC1Args, P.str()); - } else if (getTriple().getArch() == llvm::Triple::x86_64) { - SmallString<128> P(D.Dir + "/../"); + break; + case llvm::Triple::x86_64: llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1"); addSystemInclude(DriverArgs, CC1Args, P.str()); + break; + default: + break; } } @@ -2457,15 +2426,14 @@ ToolChain::CXXStdlibType NaCl_TC::GetCXXStdlibType(const ArgList &Args) const { StringRef Value = A->getValue(); if (Value == "libc++") return ToolChain::CST_Libcxx; - getDriver().Diag(diag::err_drv_invalid_stdlib_name) - << A->getAsString(Args); + getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); } return ToolChain::CST_Libcxx; } -std::string NaCl_TC::ComputeEffectiveClangTriple( - const ArgList &Args, types::ID InputType) const { +std::string NaCl_TC::ComputeEffectiveClangTriple(const ArgList &Args, + types::ID InputType) const { llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType)); if (TheTriple.getArch() == llvm::Triple::arm && TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment) @@ -2474,13 +2442,13 @@ std::string NaCl_TC::ComputeEffectiveClangTriple( } Tool *NaCl_TC::buildLinker() const { - return new tools::nacltools::Link(*this); + return new tools::nacltools::Linker(*this); } Tool *NaCl_TC::buildAssembler() const { if (getTriple().getArch() == llvm::Triple::arm) - return new tools::nacltools::AssembleARM(*this); - return new tools::gnutools::Assemble(*this); + return new tools::nacltools::AssemblerARM(*this); + return new tools::gnutools::Assembler(*this); } // End NaCl @@ -2488,9 +2456,9 @@ Tool *NaCl_TC::buildAssembler() const { /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. /// Currently does not support anything else but compilation. -TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, +TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : ToolChain(D, Triple, Args) { + : ToolChain(D, Triple, Args) { // Path mangling to find libexec std::string Path(getDriver().Dir); @@ -2498,24 +2466,15 @@ TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple& Triple, getProgramPaths().push_back(Path); } -TCEToolChain::~TCEToolChain() { -} +TCEToolChain::~TCEToolChain() {} -bool TCEToolChain::IsMathErrnoDefault() const { - return true; -} +bool TCEToolChain::IsMathErrnoDefault() const { return true; } -bool TCEToolChain::isPICDefault() const { - return false; -} +bool TCEToolChain::isPICDefault() const { return false; } -bool TCEToolChain::isPIEDefault() const { - return false; -} +bool TCEToolChain::isPIEDefault() const { return false; } -bool TCEToolChain::isPICDefaultForced() const { - return false; -} +bool TCEToolChain::isPICDefaultForced() const { return false; } // CloudABI - CloudABI tool chain which can call ld(1) directly. @@ -2545,42 +2504,40 @@ void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args, CmdArgs.push_back("-lunwind"); } -Tool *CloudABI::buildLinker() const { return new tools::cloudabi::Link(*this); } +Tool *CloudABI::buildLinker() const { + return new tools::cloudabi::Linker(*this); +} /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. -OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { +OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); } Tool *OpenBSD::buildAssembler() const { - return new tools::openbsd::Assemble(*this); + return new tools::openbsd::Assembler(*this); } -Tool *OpenBSD::buildLinker() const { - return new tools::openbsd::Link(*this); -} +Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); } /// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. -Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { +Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : Generic_ELF(D, Triple, Args) { getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); } Tool *Bitrig::buildAssembler() const { - return new tools::bitrig::Assemble(*this); + return new tools::bitrig::Assembler(*this); } -Tool *Bitrig::buildLinker() const { - return new tools::bitrig::Link(*this); -} +Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); } -ToolChain::CXXStdlibType -Bitrig::GetCXXStdlibType(const ArgList &Args) const { +ToolChain::CXXStdlibType Bitrig::GetCXXStdlibType(const ArgList &Args) const { if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { StringRef Value = A->getValue(); if (Value == "libstdc++") @@ -2588,8 +2545,7 @@ Bitrig::GetCXXStdlibType(const ArgList &Args) const { if (Value == "libc++") return ToolChain::CST_Libcxx; - getDriver().Diag(diag::err_drv_invalid_stdlib_name) - << A->getAsString(Args); + getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); } return ToolChain::CST_Libcxx; } @@ -2615,11 +2571,11 @@ void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, if (Triple.startswith("amd64")) addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" + - Triple.substr(5)); + Triple.substr(5)); else - addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/usr/include/c++/stdc++/" + - Triple); + addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + + "/usr/include/c++/stdc++/" + + Triple); break; } } @@ -2640,8 +2596,9 @@ void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. -FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { +FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall // back to '/usr/lib' if it doesn't exist. @@ -2653,8 +2610,7 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); } -ToolChain::CXXStdlibType -FreeBSD::GetCXXStdlibType(const ArgList &Args) const { +ToolChain::CXXStdlibType FreeBSD::GetCXXStdlibType(const ArgList &Args) const { if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { StringRef Value = A->getValue(); if (Value == "libstdc++") @@ -2662,10 +2618,9 @@ FreeBSD::GetCXXStdlibType(const ArgList &Args) const { if (Value == "libc++") return ToolChain::CST_Libcxx; - getDriver().Diag(diag::err_drv_invalid_stdlib_name) - << A->getAsString(Args); + getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); } - if (getTriple().getOSMajorVersion() >= 10) + if (getTriple().getOSMajorVersion() >= 10) return ToolChain::CST_Libcxx; return ToolChain::CST_Libstdcxx; } @@ -2691,12 +2646,10 @@ void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } Tool *FreeBSD::buildAssembler() const { - return new tools::freebsd::Assemble(*this); + return new tools::freebsd::Assembler(*this); } -Tool *FreeBSD::buildLinker() const { - return new tools::freebsd::Link(*this); -} +Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); } bool FreeBSD::UseSjLjExceptions() const { // FreeBSD uses SjLj exceptions on ARM oabi. @@ -2712,13 +2665,9 @@ bool FreeBSD::UseSjLjExceptions() const { } } -bool FreeBSD::HasNativeLLVMSupport() const { - return true; -} +bool FreeBSD::HasNativeLLVMSupport() const { return true; } -bool FreeBSD::isPIEDefault() const { - return getSanitizerArgs().requiresPIE(); -} +bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } SanitizerMask FreeBSD::getSupportedSanitizers() const { const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; @@ -2740,8 +2689,8 @@ SanitizerMask FreeBSD::getSupportedSanitizers() const { /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. -NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { +NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : Generic_ELF(D, Triple, Args) { if (getDriver().UseStdLib) { // When targeting a 32-bit platform, try the special directory used on @@ -2793,15 +2742,12 @@ NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) } Tool *NetBSD::buildAssembler() const { - return new tools::netbsd::Assemble(*this); + return new tools::netbsd::Assembler(*this); } -Tool *NetBSD::buildLinker() const { - return new tools::netbsd::Link(*this); -} +Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); } -ToolChain::CXXStdlibType -NetBSD::GetCXXStdlibType(const ArgList &Args) const { +ToolChain::CXXStdlibType NetBSD::GetCXXStdlibType(const ArgList &Args) const { if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { StringRef Value = A->getValue(); if (Value == "libstdc++") @@ -2809,8 +2755,7 @@ NetBSD::GetCXXStdlibType(const ArgList &Args) const { if (Value == "libc++") return ToolChain::CST_Libcxx; - getDriver().Diag(diag::err_drv_invalid_stdlib_name) - << A->getAsString(Args); + getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); } unsigned Major, Minor, Micro; @@ -2857,25 +2802,23 @@ void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, /// Minix - Minix tool chain which can call as(1) and ld(1) directly. -Minix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { +Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : Generic_ELF(D, Triple, Args) { getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); } Tool *Minix::buildAssembler() const { - return new tools::minix::Assemble(*this); + return new tools::minix::Assembler(*this); } -Tool *Minix::buildLinker() const { - return new tools::minix::Link(*this); -} +Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); } /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. -Solaris::Solaris(const Driver &D, const llvm::Triple& Triple, +Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Generic_GCC(D, Triple, Args) { + : Generic_GCC(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().getInstalledDir() != getDriver().Dir) @@ -2886,16 +2829,17 @@ Solaris::Solaris(const Driver &D, const llvm::Triple& Triple, } Tool *Solaris::buildAssembler() const { - return new tools::solaris::Assemble(*this); + return new tools::solaris::Assembler(*this); } -Tool *Solaris::buildLinker() const { - return new tools::solaris::Link(*this); -} +Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); } /// Distribution (very bare-bones at the moment). enum Distro { + // NB: Releases of a particular Linux distro should be kept together + // in this enum, because some tests are done by integer comparison against + // the first and last known member in the family, e.g. IsRedHat(). ArchLinux, DebianLenny, DebianSqueeze, @@ -2931,9 +2875,7 @@ static bool IsRedhat(enum Distro Distro) { return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL7); } -static bool IsOpenSUSE(enum Distro Distro) { - return Distro == OpenSUSE; -} +static bool IsOpenSUSE(enum Distro Distro) { return Distro == OpenSUSE; } static bool IsDebian(enum Distro Distro) { return Distro >= DebianLenny && Distro <= DebianStretch; @@ -2951,25 +2893,25 @@ static Distro DetectDistro(llvm::Triple::ArchType Arch) { SmallVector<StringRef, 16> Lines; Data.split(Lines, "\n"); Distro Version = UnknownDistro; - for (unsigned i = 0, s = Lines.size(); i != s; ++i) - if (Version == UnknownDistro && Lines[i].startswith("DISTRIB_CODENAME=")) - Version = llvm::StringSwitch<Distro>(Lines[i].substr(17)) - .Case("hardy", UbuntuHardy) - .Case("intrepid", UbuntuIntrepid) - .Case("jaunty", UbuntuJaunty) - .Case("karmic", UbuntuKarmic) - .Case("lucid", UbuntuLucid) - .Case("maverick", UbuntuMaverick) - .Case("natty", UbuntuNatty) - .Case("oneiric", UbuntuOneiric) - .Case("precise", UbuntuPrecise) - .Case("quantal", UbuntuQuantal) - .Case("raring", UbuntuRaring) - .Case("saucy", UbuntuSaucy) - .Case("trusty", UbuntuTrusty) - .Case("utopic", UbuntuUtopic) - .Case("vivid", UbuntuVivid) - .Default(UnknownDistro); + for (const StringRef Line : Lines) + if (Version == UnknownDistro && Line.startswith("DISTRIB_CODENAME=")) + Version = llvm::StringSwitch<Distro>(Line.substr(17)) + .Case("hardy", UbuntuHardy) + .Case("intrepid", UbuntuIntrepid) + .Case("jaunty", UbuntuJaunty) + .Case("karmic", UbuntuKarmic) + .Case("lucid", UbuntuLucid) + .Case("maverick", UbuntuMaverick) + .Case("natty", UbuntuNatty) + .Case("oneiric", UbuntuOneiric) + .Case("precise", UbuntuPrecise) + .Case("quantal", UbuntuQuantal) + .Case("raring", UbuntuRaring) + .Case("saucy", UbuntuSaucy) + .Case("trusty", UbuntuTrusty) + .Case("utopic", UbuntuUtopic) + .Case("vivid", UbuntuVivid) + .Default(UnknownDistro); return Version; } @@ -2999,9 +2941,9 @@ static Distro DetectDistro(llvm::Triple::ArchType Arch) { return DebianLenny; else if (Data.startswith("squeeze/sid") || Data[0] == '6') return DebianSqueeze; - else if (Data.startswith("wheezy/sid") || Data[0] == '7') + else if (Data.startswith("wheezy/sid") || Data[0] == '7') return DebianWheezy; - else if (Data.startswith("jessie/sid") || Data[0] == '8') + else if (Data.startswith("jessie/sid") || Data[0] == '8') return DebianJessie; else if (Data.startswith("stretch/sid") || Data[0] == '9') return DebianStretch; @@ -3028,100 +2970,105 @@ static Distro DetectDistro(llvm::Triple::ArchType Arch) { /// so we provide a rough mapping here. static std::string getMultiarchTriple(const llvm::Triple &TargetTriple, StringRef SysRoot) { + llvm::Triple::EnvironmentType TargetEnvironment = TargetTriple.getEnvironment(); + // For most architectures, just use whatever we have rather than trying to be // clever. switch (TargetTriple.getArch()) { default: - return TargetTriple.str(); + break; - // We use the existence of '/lib/<triple>' as a directory to detect some - // common linux triples that don't quite match the Clang triple for both - // 32-bit and 64-bit targets. Multiarch fixes its install triples to these - // regardless of what the actual target triple is. + // We use the existence of '/lib/<triple>' as a directory to detect some + // common linux triples that don't quite match the Clang triple for both + // 32-bit and 64-bit targets. Multiarch fixes its install triples to these + // regardless of what the actual target triple is. case llvm::Triple::arm: case llvm::Triple::thumb: - if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { + if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf")) return "arm-linux-gnueabihf"; } else { if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi")) return "arm-linux-gnueabi"; } - return TargetTriple.str(); + break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: - if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { + if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabihf")) return "armeb-linux-gnueabihf"; } else { if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabi")) return "armeb-linux-gnueabi"; } - return TargetTriple.str(); + break; case llvm::Triple::x86: if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu")) return "i386-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::x86_64: // We don't want this for x32, otherwise it will match x86_64 libs - if (TargetTriple.getEnvironment() != llvm::Triple::GNUX32 && + if (TargetEnvironment != llvm::Triple::GNUX32 && llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu")) return "x86_64-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::aarch64: if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu")) return "aarch64-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::aarch64_be: if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64_be-linux-gnu")) return "aarch64_be-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::mips: if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu")) return "mips-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::mipsel: if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu")) return "mipsel-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::mips64: if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnu")) return "mips64-linux-gnu"; if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnuabi64")) return "mips64-linux-gnuabi64"; - return TargetTriple.str(); + break; case llvm::Triple::mips64el: if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnu")) return "mips64el-linux-gnu"; if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnuabi64")) return "mips64el-linux-gnuabi64"; - return TargetTriple.str(); + break; case llvm::Triple::ppc: if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe")) return "powerpc-linux-gnuspe"; if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu")) return "powerpc-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::ppc64: if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) return "powerpc64-linux-gnu"; + break; case llvm::Triple::ppc64le: if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu")) return "powerpc64le-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::sparc: if (llvm::sys::fs::exists(SysRoot + "/lib/sparc-linux-gnu")) return "sparc-linux-gnu"; - return TargetTriple.str(); + break; case llvm::Triple::sparcv9: if (llvm::sys::fs::exists(SysRoot + "/lib/sparc64-linux-gnu")) return "sparc64-linux-gnu"; - return TargetTriple.str(); + break; } + return TargetTriple.str(); } static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { - if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); + if (llvm::sys::fs::exists(Path)) + Paths.push_back(Path.str()); } static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { @@ -3155,7 +3102,7 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { } Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { + : Generic_ELF(D, Triple, Args) { GCCInstallation.init(D, Triple, Args); Multilibs = GCCInstallation.getMultilibs(); llvm::Triple::ArchType Arch = Triple.getArch(); @@ -3171,7 +3118,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // FIXME: This seems unlikely to be Linux-specific. ToolChain::path_list &PPaths = getProgramPaths(); PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + - GCCInstallation.getTriple().str() + "/bin").str()); + GCCInstallation.getTriple().str() + "/bin") + .str()); Linker = GetLinkerPath(); @@ -3235,8 +3183,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // Sourcery CodeBench MIPS toolchain holds some libraries under // a biarch-like suffix of the GCC installation. - addPathIfExists((GCCInstallation.getInstallPath() + - Multilib.gccSuffix()), + addPathIfExists((GCCInstallation.getInstallPath() + Multilib.gccSuffix()), Paths); // GCC cross compiling toolchains will install target libraries which ship @@ -3258,7 +3205,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // Note that this matches the GCC behavior. See the below comment for where // Clang diverges from GCC's behavior. addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir + - Multilib.osSuffix(), + Multilib.osSuffix(), Paths); // If the GCC installation we found is inside of the sysroot, we want to @@ -3295,13 +3242,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // installations with strange symlinks. if (GCCInstallation.isValid()) { addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + - "/../../" + OSLibDir, Paths); + "/../../" + OSLibDir, + Paths); // Add the 'other' biarch variant path Multilib BiarchSibling; if (GCCInstallation.getBiarchSibling(BiarchSibling)) { - addPathIfExists(GCCInstallation.getInstallPath() + - BiarchSibling.gccSuffix(), Paths); + addPathIfExists( + GCCInstallation.getInstallPath() + BiarchSibling.gccSuffix(), Paths); } // See comments above on the multilib variant for details of why this is @@ -3309,8 +3257,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) const std::string &LibPath = GCCInstallation.getParentLibPath(); const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); const Multilib &Multilib = GCCInstallation.getMultilib(); - addPathIfExists(LibPath + "/../" + GCCTriple.str() + - "/lib" + Multilib.osSuffix(), Paths); + addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib" + + Multilib.osSuffix(), + Paths); // See comments above on the multilib variant for details of why this is // only included from within the sysroot. @@ -3330,16 +3279,12 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) addPathIfExists(SysRoot + "/usr/lib", Paths); } -bool Linux::HasNativeLLVMSupport() const { - return true; -} +bool Linux::HasNativeLLVMSupport() const { return true; } -Tool *Linux::buildLinker() const { - return new tools::gnutools::Link(*this); -} +Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); } Tool *Linux::buildAssembler() const { - return new tools::gnutools::Assemble(*this); + return new tools::gnutools::Assembler(*this); } std::string Linux::computeSysRoot() const { @@ -3357,8 +3302,9 @@ std::string Linux::computeSysRoot() const { const StringRef TripleStr = GCCInstallation.getTriple().str(); const Multilib &Multilib = GCCInstallation.getMultilib(); - std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" + - Multilib.osSuffix()).str(); + std::string Path = + (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix()) + .str(); if (llvm::sys::fs::exists(Path)) return Path; @@ -3421,91 +3367,91 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, // Implement generic Debian multiarch support. const StringRef X86_64MultiarchIncludeDirs[] = { - "/usr/include/x86_64-linux-gnu", + "/usr/include/x86_64-linux-gnu", - // FIXME: These are older forms of multiarch. It's not clear that they're - // in use in any released version of Debian, so we should consider - // removing them. - "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64" - }; + // FIXME: These are older forms of multiarch. It's not clear that they're + // in use in any released version of Debian, so we should consider + // removing them. + "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; const StringRef X86MultiarchIncludeDirs[] = { - "/usr/include/i386-linux-gnu", + "/usr/include/i386-linux-gnu", - // FIXME: These are older forms of multiarch. It's not clear that they're - // in use in any released version of Debian, so we should consider - // removing them. - "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", - "/usr/include/i486-linux-gnu" - }; + // FIXME: These are older forms of multiarch. It's not clear that they're + // in use in any released version of Debian, so we should consider + // removing them. + "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", + "/usr/include/i486-linux-gnu"}; const StringRef AArch64MultiarchIncludeDirs[] = { - "/usr/include/aarch64-linux-gnu" - }; + "/usr/include/aarch64-linux-gnu"}; const StringRef ARMMultiarchIncludeDirs[] = { - "/usr/include/arm-linux-gnueabi" - }; + "/usr/include/arm-linux-gnueabi"}; const StringRef ARMHFMultiarchIncludeDirs[] = { - "/usr/include/arm-linux-gnueabihf" - }; - const StringRef MIPSMultiarchIncludeDirs[] = { - "/usr/include/mips-linux-gnu" - }; + "/usr/include/arm-linux-gnueabihf"}; + const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; const StringRef MIPSELMultiarchIncludeDirs[] = { - "/usr/include/mipsel-linux-gnu" - }; + "/usr/include/mipsel-linux-gnu"}; const StringRef MIPS64MultiarchIncludeDirs[] = { - "/usr/include/mips64-linux-gnu", - "/usr/include/mips64-linux-gnuabi64" - }; + "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"}; const StringRef MIPS64ELMultiarchIncludeDirs[] = { - "/usr/include/mips64el-linux-gnu", - "/usr/include/mips64el-linux-gnuabi64" - }; + "/usr/include/mips64el-linux-gnu", + "/usr/include/mips64el-linux-gnuabi64"}; const StringRef PPCMultiarchIncludeDirs[] = { - "/usr/include/powerpc-linux-gnu" - }; + "/usr/include/powerpc-linux-gnu"}; const StringRef PPC64MultiarchIncludeDirs[] = { - "/usr/include/powerpc64-linux-gnu" - }; + "/usr/include/powerpc64-linux-gnu"}; const StringRef PPC64LEMultiarchIncludeDirs[] = { - "/usr/include/powerpc64le-linux-gnu" - }; + "/usr/include/powerpc64le-linux-gnu"}; const StringRef SparcMultiarchIncludeDirs[] = { - "/usr/include/sparc-linux-gnu" - }; + "/usr/include/sparc-linux-gnu"}; const StringRef Sparc64MultiarchIncludeDirs[] = { - "/usr/include/sparc64-linux-gnu" - }; + "/usr/include/sparc64-linux-gnu"}; ArrayRef<StringRef> MultiarchIncludeDirs; - if (getTriple().getArch() == llvm::Triple::x86_64) { + switch (getTriple().getArch()) { + case llvm::Triple::x86_64: MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::x86) { + break; + case llvm::Triple::x86: MultiarchIncludeDirs = X86MultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::aarch64 || - getTriple().getArch() == llvm::Triple::aarch64_be) { + break; + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::arm) { + break; + case llvm::Triple::arm: if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; else MultiarchIncludeDirs = ARMMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::mips) { + break; + case llvm::Triple::mips: MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::mipsel) { + break; + case llvm::Triple::mipsel: MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::mips64) { + break; + case llvm::Triple::mips64: MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::mips64el) { + break; + case llvm::Triple::mips64el: MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::ppc) { + break; + case llvm::Triple::ppc: MultiarchIncludeDirs = PPCMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::ppc64) { + break; + case llvm::Triple::ppc64: MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::ppc64le) { + break; + case llvm::Triple::ppc64le: MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::sparc) { + break; + case llvm::Triple::sparc: MultiarchIncludeDirs = SparcMultiarchIncludeDirs; - } else if (getTriple().getArch() == llvm::Triple::sparcv9) { + break; + case llvm::Triple::sparcv9: MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs; + break; + default: + break; } for (StringRef Dir : MultiarchIncludeDirs) { if (llvm::sys::fs::exists(SysRoot + Dir)) { @@ -3526,13 +3472,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, } /// \brief Helper to add the variant paths of a libstdc++ installation. -/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, - StringRef GCCTriple, - StringRef GCCMultiarchTriple, - StringRef TargetMultiarchTriple, - Twine IncludeSuffix, - const ArgList &DriverArgs, - ArgStringList &CC1Args) { +/*static*/ bool Linux::addLibStdCXXIncludePaths( + Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple, + StringRef TargetMultiarchTriple, Twine IncludeSuffix, + const ArgList &DriverArgs, ArgStringList &CC1Args) { if (!llvm::sys::fs::exists(Base + Suffix)) return false; @@ -3570,15 +3513,15 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, // Check if libc++ has been enabled and provide its include paths if so. if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) { const std::string LibCXXIncludePathCandidates[] = { - // The primary location is within the Clang installation. - // FIXME: We shouldn't hard code 'v1' here to make Clang future proof to - // newer ABI versions. - getDriver().Dir + "/../include/c++/v1", - - // We also check the system as for a long time this is the only place Clang looked. - // FIXME: We should really remove this. It doesn't make any sense. - getDriver().SysRoot + "/usr/include/c++/v1" - }; + // The primary location is within the Clang installation. + // FIXME: We shouldn't hard code 'v1' here to make Clang future proof to + // newer ABI versions. + getDriver().Dir + "/../include/c++/v1", + + // We also check the system as for a long time this is the only place + // Clang looked. + // FIXME: We should really remove this. It doesn't make any sense. + getDriver().SysRoot + "/usr/include/c++/v1"}; for (const auto &IncludePath : LibCXXIncludePathCandidates) { if (!llvm::sys::fs::exists(IncludePath)) continue; @@ -3609,24 +3552,24 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, // The primary search for libstdc++ supports multiarch variants. if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", - "/c++/" + Version.Text, TripleStr, GCCMultiarchTriple, - TargetMultiarchTriple, + "/c++/" + Version.Text, TripleStr, + GCCMultiarchTriple, TargetMultiarchTriple, Multilib.includeSuffix(), DriverArgs, CC1Args)) return; // Otherwise, fall back on a bunch of options which don't use multiarch // layouts for simplicity. const std::string LibStdCXXIncludePathCandidates[] = { - // Gentoo is weird and places its headers inside the GCC install, so if the - // first attempt to find the headers fails, try these patterns. - InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + - Version.MinorStr, - InstallDir.str() + "/include/g++-v" + Version.MajorStr, - // Android standalone toolchain has C++ headers in yet another place. - LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, - // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, - // without a subdirectory corresponding to the gcc version. - LibDir.str() + "/../include/c++", + // Gentoo is weird and places its headers inside the GCC install, + // so if the first attempt to find the headers fails, try these patterns. + InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + + Version.MinorStr, + InstallDir.str() + "/include/g++-v" + Version.MajorStr, + // Android standalone toolchain has C++ headers in yet another place. + LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, + // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, + // without a subdirectory corresponding to the gcc version. + LibDir.str() + "/../include/c++", }; for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { @@ -3638,15 +3581,15 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } } -bool Linux::isPIEDefault() const { - return getSanitizerArgs().requiresPIE(); -} +bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } SanitizerMask Linux::getSupportedSanitizers() const { const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || getTriple().getArch() == llvm::Triple::mips64el; + const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 || + getTriple().getArch() == llvm::Triple::ppc64le; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; Res |= SanitizerKind::KernelAddress; @@ -3654,9 +3597,10 @@ SanitizerMask Linux::getSupportedSanitizers() const { if (IsX86_64 || IsMIPS64) { Res |= SanitizerKind::DataFlow; Res |= SanitizerKind::Leak; - Res |= SanitizerKind::Memory; Res |= SanitizerKind::Thread; } + if (IsX86_64 || IsMIPS64 || IsPowerPC64) + Res |= SanitizerKind::Memory; if (IsX86 || IsX86_64) { Res |= SanitizerKind::Function; Res |= SanitizerKind::SafeStack; @@ -3666,8 +3610,9 @@ SanitizerMask Linux::getSupportedSanitizers() const { /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. -DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { +DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { // Path mangling to find libexec getProgramPaths().push_back(getDriver().getInstalledDir()); @@ -3683,47 +3628,34 @@ DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList } Tool *DragonFly::buildAssembler() const { - return new tools::dragonfly::Assemble(*this); + return new tools::dragonfly::Assembler(*this); } Tool *DragonFly::buildLinker() const { - return new tools::dragonfly::Link(*this); + return new tools::dragonfly::Linker(*this); } - /// XCore tool chain -XCore::XCore(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) : ToolChain(D, Triple, Args) { +XCore::XCore(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : ToolChain(D, Triple, Args) { // ProgramPaths are found via 'PATH' environment variable. } Tool *XCore::buildAssembler() const { - return new tools::XCore::Assemble(*this); + return new tools::XCore::Assembler(*this); } -Tool *XCore::buildLinker() const { - return new tools::XCore::Link(*this); -} +Tool *XCore::buildLinker() const { return new tools::XCore::Linker(*this); } -bool XCore::isPICDefault() const { - return false; -} +bool XCore::isPICDefault() const { return false; } -bool XCore::isPIEDefault() const { - return false; -} +bool XCore::isPIEDefault() const { return false; } -bool XCore::isPICDefaultForced() const { - return false; -} +bool XCore::isPICDefaultForced() const { return false; } -bool XCore::SupportsProfiling() const { - return false; -} +bool XCore::SupportsProfiling() const { return false; } -bool XCore::hasBlocksRuntime() const { - return false; -} +bool XCore::hasBlocksRuntime() const { return false; } void XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { @@ -3732,7 +3664,7 @@ void XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs, return; if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) { SmallVector<StringRef, 4> Dirs; - const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); ArrayRef<StringRef> DirVec(Dirs); addSystemIncludes(DriverArgs, CC1Args, DirVec); @@ -3752,7 +3684,7 @@ void XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, return; if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) { SmallVector<StringRef, 4> Dirs; - const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'}; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); ArrayRef<StringRef> DirVec(Dirs); addSystemIncludes(DriverArgs, CC1Args, DirVec); @@ -3770,11 +3702,11 @@ Tool *SHAVEToolChain::SelectTool(const JobAction &JA) const { switch (JA.getKind()) { case Action::CompileJobClass: if (!Compiler) - Compiler.reset(new tools::SHAVE::Compile(*this)); + Compiler.reset(new tools::SHAVE::Compiler(*this)); return Compiler.get(); case Action::AssembleJobClass: if (!Assembler) - Assembler.reset(new tools::SHAVE::Assemble(*this)); + Assembler.reset(new tools::SHAVE::Assembler(*this)); return Assembler.get(); default: return ToolChain::getTool(JA.getKind()); @@ -3782,7 +3714,7 @@ Tool *SHAVEToolChain::SelectTool(const JobAction &JA) const { } SHAVEToolChain::SHAVEToolChain(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) + const ArgList &Args) : Generic_GCC(D, Triple, Args) {} SHAVEToolChain::~SHAVEToolChain() {} diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index a48bb5fa5948..629f90ac79f8 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -101,7 +101,7 @@ protected: public: GCCInstallationDetector() : IsValid(false) {} void init(const Driver &D, const llvm::Triple &TargetTriple, - const llvm::opt::ArgList &Args); + const llvm::opt::ArgList &Args); /// \brief Check whether we detected a valid GCC install. bool isValid() const { return IsValid; } @@ -179,8 +179,8 @@ protected: /// @} private: - mutable std::unique_ptr<tools::gcc::Preprocess> Preprocess; - mutable std::unique_ptr<tools::gcc::Compile> Compile; + mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess; + mutable std::unique_ptr<tools::gcc::Compiler> Compile; }; class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { @@ -188,6 +188,7 @@ protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; Tool *getTool(Action::ActionClass AC) const override; + private: mutable std::unique_ptr<tools::darwin::Lipo> Lipo; mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; @@ -195,7 +196,7 @@ private: public: MachO(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args); + const llvm::opt::ArgList &Args); ~MachO() override; /// @name MachO specific toolchain API @@ -205,7 +206,6 @@ public: /// example, Apple treats different ARM variations as distinct architectures. StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; - /// Add the linker arguments to link the ARC runtime library. virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {} @@ -214,30 +214,24 @@ public: virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - virtual void - addStartObjectFileArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const {} + virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + } virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {} /// On some iOS platforms, kernel and kernel modules were built statically. Is /// this such a target? - virtual bool isKernelStatic() const { - return false; - } + virtual bool isKernelStatic() const { return false; } /// Is the target either iOS or an iOS simulator? - bool isTargetIOSBased() const { - return false; - } + bool isTargetIOSBased() const { return false; } void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, - StringRef DarwinLibName, - bool AlwaysLink = false, - bool IsEmbedded = false, - bool AddRPath = false) const; + StringRef DarwinLibName, bool AlwaysLink = false, + bool IsEmbedded = false, bool AddRPath = false) const; /// Add any profiling runtime libraries that are needed. This is essentially a /// MachO specific version of addProfileRT in Tools.cpp. @@ -271,22 +265,16 @@ public: return true; } - bool IsMathErrnoDefault() const override { - return false; - } + bool IsMathErrnoDefault() const override { return false; } - bool IsEncodeExtendedBlockSignatureDefault() const override { - return true; - } + bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } bool IsObjCNonFragileABIDefault() const override { // Non-fragile ABI is default for everything but i386. return getTriple().getArch() != llvm::Triple::x86; } - bool UseObjCMixedDispatch() const override { - return true; - } + bool UseObjCMixedDispatch() const override { return true; } bool IsUnwindTablesDefault() const override; @@ -300,20 +288,16 @@ public: bool SupportsProfiling() const override; - bool SupportsObjCGC() const override { - return false; - } + bool SupportsObjCGC() const override { return false; } bool UseDwarfDebugFlags() const override; - bool UseSjLjExceptions() const override { - return false; - } + bool UseSjLjExceptions() const override { return false; } /// } }; - /// Darwin - The base Darwin tool chain. +/// Darwin - The base Darwin tool chain. class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { public: /// Whether the information on the target has been initialized. @@ -323,11 +307,7 @@ public: // the argument translation business. mutable bool TargetInitialized; - enum DarwinPlatformKind { - MacOS, - IPhoneOS, - IPhoneOSSimulator - }; + enum DarwinPlatformKind { MacOS, IPhoneOS, IPhoneOSSimulator }; mutable DarwinPlatformKind TargetPlatform; @@ -348,14 +328,12 @@ public: /// @name Apple Specific Toolchain Implementation /// { - void - addMinVersionArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; - - void - addStartObjectFileArgs(const llvm::opt::ArgList &Args, + void addMinVersionArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; + void addStartObjectFileArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + bool isKernelStatic() const override { return !isTargetIPhoneOS() || isIPhoneOSVersionLT(6, 0); } @@ -411,12 +389,13 @@ protected: return TargetVersion; } - bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { + bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, + unsigned V2 = 0) const { assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); return TargetVersion < VersionTuple(V0, V1, V2); } - bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { + bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { assert(isTargetMacOS() && "Unexpected call for non OS X target!"); return TargetVersion < VersionTuple(V0, V1, V2); } @@ -476,23 +455,19 @@ public: /// @name Apple ToolChain Implementation /// { - void - AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; + void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; - void - AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; - void - AddCCKextLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; + void AddCCKextLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; - void - AddLinkARCArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; + void AddLinkARCArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; /// } private: @@ -503,6 +478,7 @@ private: class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { virtual void anchor(); + public: Generic_ELF(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args) @@ -521,8 +497,8 @@ public: bool IsMathErrnoDefault() const override { return false; } bool IsObjCNonFragileABIDefault() const override { return true; } - CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) - const override { + CXXStdlibType + GetCXXStdlibType(const llvm::opt::ArgList &Args) const override { return ToolChain::CST_Libcxx; } void AddClangCXXStdlibIncludeArgs( @@ -543,12 +519,43 @@ public: const llvm::opt::ArgList &Args); bool IsIntegratedAssemblerDefault() const override { return true; } + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; - }; +class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain { +public: + MinGW(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + bool IsIntegratedAssemblerDefault() const override; + bool IsUnwindTablesDefault() const override; + bool isPICDefault() const override; + bool isPIEDefault() const override; + bool isPICDefaultForced() const override; + bool UseSEHExceptions() const; + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + +protected: + Tool *getTool(Action::ActionClass AC) const override; + Tool *buildLinker() const override; + Tool *buildAssembler() const override; + +private: + std::string Base; + std::string GccLibDir; + std::string Arch; + mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor; + mutable std::unique_ptr<tools::gcc::Compiler> Compiler; +}; class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF { public: @@ -577,13 +584,13 @@ public: bool IsObjCNonFragileABIDefault() const override { return true; } CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { - return 1; + return 1; } protected: @@ -601,13 +608,14 @@ public: bool IsObjCNonFragileABIDefault() const override { return true; } CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; bool UseSjLjExceptions() const override; bool isPIEDefault() const override; SanitizerMask getSupportedSanitizers() const override; + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; @@ -623,12 +631,10 @@ public: CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; - bool IsUnwindTablesDefault() const override { - return true; - } + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + bool IsUnwindTablesDefault() const override { return true; } protected: Tool *buildAssembler() const override; @@ -667,9 +673,9 @@ public: void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; bool isPIEDefault() const override; SanitizerMask getSupportedSanitizers() const override; @@ -706,9 +712,9 @@ public: void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; } @@ -720,7 +726,7 @@ public: static const char *GetSmallDataThreshold(const llvm::opt::ArgList &Args); - static bool UsesG0(const char* smallDataThreshold); + static bool UsesG0(const char *smallDataThreshold); }; class LLVM_LIBRARY_VISIBILITY NaCl_TC : public Generic_ELF { @@ -731,19 +737,16 @@ public: void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; - CXXStdlibType - GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; - void - AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; - bool - IsIntegratedAssemblerDefault() const override { return false; } + bool IsIntegratedAssemblerDefault() const override { return false; } // Get the path to the file containing NaCl's ARM macros. It lives in NaCl_TC // because the AssembleARM tool needs a const char * that it can pass around @@ -790,9 +793,9 @@ public: void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - void - AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; bool getWindowsSDKDir(std::string &path, int &major, int &minor) const; bool getWindowsSDKLibraryPath(std::string &path) const; @@ -829,12 +832,12 @@ public: return 0; } - void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) - const override; - void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) - const override; + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; @@ -846,22 +849,26 @@ protected: class LLVM_LIBRARY_VISIBILITY XCore : public ToolChain { public: XCore(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args); + const llvm::opt::ArgList &Args); + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; + public: bool isPICDefault() const override; bool isPIEDefault() const override; bool isPICDefaultForced() const override; bool SupportsProfiling() const override; bool hasBlocksRuntime() const override; - void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; }; @@ -872,7 +879,7 @@ public: class LLVM_LIBRARY_VISIBILITY SHAVEToolChain : public Generic_GCC { public: SHAVEToolChain(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args); + const llvm::opt::ArgList &Args); ~SHAVEToolChain() override; virtual Tool *SelectTool(const JobAction &JA) const override; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 2367914cc0b4..a2955dbb9e77 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -84,10 +84,10 @@ static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) { // In gcc, only ARM checks this, but it seems reasonable to check universally. if (Args.hasArg(options::OPT_static)) - if (const Arg *A = Args.getLastArg(options::OPT_dynamic, - options::OPT_mdynamic_no_pic)) - D.Diag(diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-static"; + if (const Arg *A = + Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic)) + D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) + << "-static"; } // Add backslashes to escape spaces and other backslashes. @@ -95,9 +95,10 @@ static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) { // the -dwarf-debug-flags option. static void EscapeSpacesAndBackslashes(const char *Arg, SmallVectorImpl<char> &Res) { - for ( ; *Arg; ++Arg) { + for (; *Arg; ++Arg) { switch (*Arg) { - default: break; + default: + break; case ' ': case '\\': Res.push_back('\\'); @@ -109,8 +110,7 @@ static void EscapeSpacesAndBackslashes(const char *Arg, // Quote target names for inclusion in GNU Make dependency files. // Only the characters '$', '#', ' ', '\t' are quoted. -static void QuoteTarget(StringRef Target, - SmallVectorImpl<char> &Res) { +static void QuoteTarget(StringRef Target, SmallVectorImpl<char> &Res) { for (unsigned i = 0, e = Target.size(); i != e; ++i) { switch (Target[i]) { case ' ': @@ -136,10 +136,8 @@ static void QuoteTarget(StringRef Target, } } -static void addDirectoryList(const ArgList &Args, - ArgStringList &CmdArgs, - const char *ArgName, - const char *EnvVar) { +static void addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs, + const char *ArgName, const char *EnvVar) { const char *DirList = ::getenv(EnvVar); bool CombinedArg = false; @@ -165,7 +163,8 @@ static void addDirectoryList(const ArgList &Args, } } else { if (CombinedArg) { - CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim))); + CmdArgs.push_back( + Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim))); } else { CmdArgs.push_back(ArgName); CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim))); @@ -191,9 +190,8 @@ static void addDirectoryList(const ArgList &Args, } } -static void AddLinkerInputs(const ToolChain &TC, - const InputInfoList &Inputs, const ArgList &Args, - ArgStringList &CmdArgs) { +static void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, + const ArgList &Args, ArgStringList &CmdArgs) { const Driver &D = TC.getDriver(); // Add extra linker input arguments which are not treated as inputs @@ -205,10 +203,8 @@ static void AddLinkerInputs(const ToolChain &TC, // Don't try to pass LLVM inputs unless we have native support. if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || - II.getType() == types::TY_LLVM_BC || - II.getType() == types::TY_LTO_BC) - D.Diag(diag::err_drv_no_linker_llvm_support) - << TC.getTripleString(); + II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) + D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString(); } // Add filenames immediately. @@ -230,7 +226,7 @@ static void AddLinkerInputs(const ToolChain &TC, A.claim(); A.render(Args, CmdArgs); } else { - A.renderAsInput(Args, CmdArgs); + A.renderAsInput(Args, CmdArgs); } } @@ -259,14 +255,11 @@ static bool forwardToGCC(const Option &O) { // Don't forward inputs from the original command line. They are added from // InputInfoList. return O.getKind() != Option::InputClass && - !O.hasFlag(options::DriverOption) && - !O.hasFlag(options::LinkerInput); + !O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput); } -void Clang::AddPreprocessingOptions(Compilation &C, - const JobAction &JA, - const Driver &D, - const ArgList &Args, +void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, + const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, const InputInfo &Output, const InputInfoList &Inputs) const { @@ -333,7 +326,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, if (Args.hasArg(options::OPT_MG)) { if (!A || A->getOption().matches(options::OPT_MD) || - A->getOption().matches(options::OPT_MMD)) + A->getOption().matches(options::OPT_MMD)) D.Diag(diag::err_drv_mg_requires_m_or_mm); CmdArgs.push_back("-MG"); } @@ -351,7 +344,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, QuoteTarget(A->getValue(), Quoted); CmdArgs.push_back(Args.MakeArgString(Quoted)); - // -MT flag - no change + // -MT flag - no change } else { A->render(Args, CmdArgs); } @@ -408,8 +401,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, continue; } else { // Ignore the PCH if not first on command line and emit warning. - D.Diag(diag::warn_drv_pch_not_first_include) - << P << A->getAsString(Args); + D.Diag(diag::warn_drv_pch_not_first_include) << P + << A->getAsString(Args); } } } @@ -511,8 +504,8 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) { // Handle -mhwdiv=. static void getARMHWDivFeatures(const Driver &D, const Arg *A, - const ArgList &Args, - std::vector<const char *> &Features) { + const ArgList &Args, + std::vector<const char *> &Features) { StringRef HWDiv = A->getValue(); if (HWDiv == "arm") { Features.push_back("+hwdiv-arm"); @@ -556,9 +549,9 @@ static bool isARMMProfile(const llvm::Triple &Triple) { StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args, const llvm::Triple &Triple) { StringRef FloatABI; - if (Arg *A = Args.getLastArg(options::OPT_msoft_float, - options::OPT_mhard_float, - options::OPT_mfloat_abi_EQ)) { + if (Arg *A = + Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, + options::OPT_mfloat_abi_EQ)) { if (A->getOption().matches(options::OPT_msoft_float)) FloatABI = "soft"; else if (A->getOption().matches(options::OPT_mhard_float)) @@ -566,8 +559,7 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args, else { FloatABI = A->getValue(); if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") { - D.Diag(diag::err_drv_invalid_mfloat_abi) - << A->getAsString(Args); + D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); FloatABI = "soft"; } } @@ -595,7 +587,7 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args, break; case llvm::Triple::FreeBSD: - switch(Triple.getEnvironment()) { + switch (Triple.getEnvironment()) { case llvm::Triple::GNUEABIHF: FloatABI = "hard"; break; @@ -607,7 +599,7 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args, break; default: - switch(Triple.getEnvironment()) { + switch (Triple.getEnvironment()) { case llvm::Triple::GNUEABIHF: FloatABI = "hard"; break; @@ -715,8 +707,7 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, } } -void Clang::AddARMTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs, +void Clang::AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs, bool KernelOrKext) const { const Driver &D = getToolChain().getDriver(); // Get the effective triple, which takes into account the deployment target. @@ -734,8 +725,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args, // The backend is hardwired to assume AAPCS for M-class processors, ensure // the frontend matches that. if (Triple.getEnvironment() == llvm::Triple::EABI || - Triple.getOS() == llvm::Triple::UnknownOS || - isARMMProfile(Triple)) { + Triple.getOS() == llvm::Triple::UnknownOS || isARMMProfile(Triple)) { ABIName = "aapcs"; } else { ABIName = "apcs-gnu"; @@ -745,7 +735,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args, ABIName = "aapcs"; } else { // Select the default based on the platform. - switch(Triple.getEnvironment()) { + switch (Triple.getEnvironment()) { case llvm::Triple::Android: case llvm::Triple::GNUEABI: case llvm::Triple::GNUEABIHF: @@ -827,8 +817,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args, } if (!Args.hasFlag(options::OPT_mimplicit_float, - options::OPT_mno_implicit_float, - true)) + options::OPT_mno_implicit_float, true)) CmdArgs.push_back("-no-implicit-float"); // llvm does not support reserving registers in general. There is support @@ -932,10 +921,8 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, // Get CPU and ABI names. They are not independent // so we have to calculate them together. -void mips::getMipsCPUAndABI(const ArgList &Args, - const llvm::Triple &Triple, - StringRef &CPUName, - StringRef &ABIName) { +void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple, + StringRef &CPUName, StringRef &ABIName) { const char *DefMips32CPU = "mips32r2"; const char *DefMips64CPU = "mips64r2"; @@ -951,8 +938,7 @@ void mips::getMipsCPUAndABI(const ArgList &Args, if (Triple.getOS() == llvm::Triple::OpenBSD) DefMips64CPU = "mips3"; - if (Arg *A = Args.getLastArg(options::OPT_march_EQ, - options::OPT_mcpu_EQ)) + if (Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ)) CPUName = A->getValue(); if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { @@ -960,9 +946,9 @@ void mips::getMipsCPUAndABI(const ArgList &Args, // Convert a GNU style Mips ABI name to the name // accepted by LLVM Mips backend. ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName) - .Case("32", "o32") - .Case("64", "n64") - .Default(ABIName); + .Case("32", "o32") + .Case("64", "n64") + .Default(ABIName); } // Setup default CPU and ABI names. @@ -993,9 +979,9 @@ void mips::getMipsCPUAndABI(const ArgList &Args, if (CPUName.empty()) { // Deduce CPU name from ABI name. CPUName = llvm::StringSwitch<const char *>(ABIName) - .Cases("o32", "eabi", DefMips32CPU) - .Cases("n32", "n64", DefMips64CPU) - .Default(""); + .Cases("o32", "eabi", DefMips32CPU) + .Cases("n32", "n64", DefMips64CPU) + .Default(""); } // FIXME: Warn on inconsistent use of -march and -mabi. @@ -1004,18 +990,18 @@ void mips::getMipsCPUAndABI(const ArgList &Args, // Convert ABI name to the GNU tools acceptable variant. static StringRef getGnuCompatibleMipsABIName(StringRef ABI) { return llvm::StringSwitch<llvm::StringRef>(ABI) - .Case("o32", "32") - .Case("n64", "64") - .Default(ABI); + .Case("o32", "32") + .Case("n64", "64") + .Default(ABI); } // Select the MIPS float ABI as determined by -msoft-float, -mhard-float, // and -mfloat-abi=. static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) { StringRef FloatABI; - if (Arg *A = Args.getLastArg(options::OPT_msoft_float, - options::OPT_mhard_float, - options::OPT_mfloat_abi_EQ)) { + if (Arg *A = + Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, + options::OPT_mfloat_abi_EQ)) { if (A->getOption().matches(options::OPT_msoft_float)) FloatABI = "soft"; else if (A->getOption().matches(options::OPT_mhard_float)) @@ -1143,8 +1129,7 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, CmdArgs.push_back("-msoft-float"); CmdArgs.push_back("-mfloat-abi"); CmdArgs.push_back("soft"); - } - else { + } else { // Floating point operations and argument passing are hard. assert(FloatABI == "hard" && "Invalid float abi!"); CmdArgs.push_back("-mfloat-abi"); @@ -1196,51 +1181,51 @@ static std::string getPPCTargetCPU(const ArgList &Args) { } return llvm::StringSwitch<const char *>(CPUName) - .Case("common", "generic") - .Case("440", "440") - .Case("440fp", "440") - .Case("450", "450") - .Case("601", "601") - .Case("602", "602") - .Case("603", "603") - .Case("603e", "603e") - .Case("603ev", "603ev") - .Case("604", "604") - .Case("604e", "604e") - .Case("620", "620") - .Case("630", "pwr3") - .Case("G3", "g3") - .Case("7400", "7400") - .Case("G4", "g4") - .Case("7450", "7450") - .Case("G4+", "g4+") - .Case("750", "750") - .Case("970", "970") - .Case("G5", "g5") - .Case("a2", "a2") - .Case("a2q", "a2q") - .Case("e500mc", "e500mc") - .Case("e5500", "e5500") - .Case("power3", "pwr3") - .Case("power4", "pwr4") - .Case("power5", "pwr5") - .Case("power5x", "pwr5x") - .Case("power6", "pwr6") - .Case("power6x", "pwr6x") - .Case("power7", "pwr7") - .Case("power8", "pwr8") - .Case("pwr3", "pwr3") - .Case("pwr4", "pwr4") - .Case("pwr5", "pwr5") - .Case("pwr5x", "pwr5x") - .Case("pwr6", "pwr6") - .Case("pwr6x", "pwr6x") - .Case("pwr7", "pwr7") - .Case("pwr8", "pwr8") - .Case("powerpc", "ppc") - .Case("powerpc64", "ppc64") - .Case("powerpc64le", "ppc64le") - .Default(""); + .Case("common", "generic") + .Case("440", "440") + .Case("440fp", "440") + .Case("450", "450") + .Case("601", "601") + .Case("602", "602") + .Case("603", "603") + .Case("603e", "603e") + .Case("603ev", "603ev") + .Case("604", "604") + .Case("604e", "604e") + .Case("620", "620") + .Case("630", "pwr3") + .Case("G3", "g3") + .Case("7400", "7400") + .Case("G4", "g4") + .Case("7450", "7450") + .Case("G4+", "g4+") + .Case("750", "750") + .Case("970", "970") + .Case("G5", "g5") + .Case("a2", "a2") + .Case("a2q", "a2q") + .Case("e500mc", "e500mc") + .Case("e5500", "e5500") + .Case("power3", "pwr3") + .Case("power4", "pwr4") + .Case("power5", "pwr5") + .Case("power5x", "pwr5x") + .Case("power6", "pwr6") + .Case("power6x", "pwr6x") + .Case("power7", "pwr7") + .Case("power8", "pwr8") + .Case("pwr3", "pwr3") + .Case("pwr4", "pwr4") + .Case("pwr5", "pwr5") + .Case("pwr5x", "pwr5x") + .Case("pwr6", "pwr6") + .Case("pwr6x", "pwr6x") + .Case("pwr7", "pwr7") + .Case("pwr8", "pwr8") + .Case("powerpc", "ppc") + .Case("powerpc64", "ppc64") + .Case("powerpc64le", "ppc64le") + .Default(""); } return ""; @@ -1282,7 +1267,7 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { ABIName = A->getValue(); } else if (getToolChain().getTriple().isOSLinux()) - switch(getToolChain().getArch()) { + switch (getToolChain().getArch()) { case llvm::Triple::ppc64: { // When targeting a processor that supports QPX, or if QPX is // specifically enabled, default to using the ABI that supports QPX (so @@ -1304,7 +1289,7 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, break; default: break; - } + } if (ABIName) { CmdArgs.push_back("-target-abi"); @@ -1322,20 +1307,20 @@ static std::string getR600TargetGPU(const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { const char *GPUName = A->getValue(); return llvm::StringSwitch<const char *>(GPUName) - .Cases("rv630", "rv635", "r600") - .Cases("rv610", "rv620", "rs780", "rs880") - .Case("rv740", "rv770") - .Case("palm", "cedar") - .Cases("sumo", "sumo2", "sumo") - .Case("hemlock", "cypress") - .Case("aruba", "cayman") - .Default(GPUName); + .Cases("rv630", "rv635", "r600") + .Cases("rv610", "rv620", "rs780", "rs880") + .Case("rv740", "rv770") + .Case("palm", "cedar") + .Cases("sumo", "sumo2", "sumo") + .Case("hemlock", "cypress") + .Case("aruba", "cayman") + .Default(GPUName); } return ""; } void Clang::AddSparcTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { + ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); std::string Triple = getToolChain().ComputeEffectiveClangTriple(Args); @@ -1352,8 +1337,8 @@ void Clang::AddSparcTargetArgs(const ArgList &Args, // currently does not support Sparc soft-float, at all, display an // error if it's requested. if (SoftFloatABI) { - D.Diag(diag::err_drv_unsupported_opt_for_target) - << "-msoft-float" << Triple; + D.Diag(diag::err_drv_unsupported_opt_for_target) << "-msoft-float" + << Triple; } } @@ -1366,16 +1351,14 @@ static const char *getSystemZTargetCPU(const ArgList &Args) { static void getSystemZTargetFeatures(const ArgList &Args, std::vector<const char *> &Features) { // -m(no-)htm overrides use of the transactional-execution facility. - if (Arg *A = Args.getLastArg(options::OPT_mhtm, - options::OPT_mno_htm)) { + if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) { if (A->getOption().matches(options::OPT_mhtm)) Features.push_back("+transactional-execution"); else Features.push_back("-transactional-execution"); } // -m(no-)vx overrides use of the vector facility. - if (Arg *A = Args.getLastArg(options::OPT_mvx, - options::OPT_mno_vx)) { + if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) { if (A->getOption().matches(options::OPT_mvx)) Features.push_back("+vector"); else @@ -1403,6 +1386,28 @@ static const char *getX86TargetCPU(const ArgList &Args, return Args.MakeArgString(CPU); } + if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { + // Mapping built by referring to X86TargetInfo::getDefaultFeatures(). + StringRef Arch = A->getValue(); + const char *CPU; + if (Triple.getArch() == llvm::Triple::x86) { + CPU = llvm::StringSwitch<const char *>(Arch) + .Case("IA32", "i386") + .Case("SSE", "pentium3") + .Case("SSE2", "pentium4") + .Case("AVX", "sandybridge") + .Case("AVX2", "haswell") + .Default(nullptr); + } else { + CPU = llvm::StringSwitch<const char *>(Arch) + .Case("AVX", "sandybridge") + .Case("AVX2", "haswell") + .Default(nullptr); + } + if (CPU) + return CPU; + } + // Select the default CPU if none was given (or detection failed). if (Triple.getArch() != llvm::Triple::x86_64 && @@ -1446,7 +1451,7 @@ static const char *getX86TargetCPU(const ArgList &Args, } static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) { - switch(T.getArch()) { + switch (T.getArch()) { default: return ""; @@ -1517,7 +1522,8 @@ static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, // as gold requires -plugin to come before any -plugin-opt that -Wl might // forward. CmdArgs.push_back("-plugin"); - std::string Plugin = ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so"; + std::string Plugin = + ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so"; CmdArgs.push_back(Args.MakeArgString(Plugin)); // Try to pass driver level flags relevant to LTO code generation down to @@ -1534,7 +1540,7 @@ static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, /// parsing the refinement step. Otherwise, return true and set the Position /// of the refinement step in the input string. static bool getRefinementStep(const StringRef &In, const Driver &D, - const Arg &A, size_t &Position) { + const Arg &A, size_t &Position) { const char RefinementStepToken = ':'; Position = In.find(RefinementStepToken); if (Position != StringRef::npos) { @@ -1597,14 +1603,14 @@ static void ParseMRecip(const Driver &D, const ArgList &Args, // and pass through. llvm::StringMap<bool> OptionStrings; - OptionStrings.insert(std::make_pair("divd", false)); - OptionStrings.insert(std::make_pair("divf", false)); - OptionStrings.insert(std::make_pair("vec-divd", false)); - OptionStrings.insert(std::make_pair("vec-divf", false)); - OptionStrings.insert(std::make_pair("sqrtd", false)); - OptionStrings.insert(std::make_pair("sqrtf", false)); - OptionStrings.insert(std::make_pair("vec-sqrtd", false)); - OptionStrings.insert(std::make_pair("vec-sqrtf", false)); + OptionStrings.insert(std::make_pair("divd", false)); + OptionStrings.insert(std::make_pair("divf", false)); + OptionStrings.insert(std::make_pair("vec-divd", false)); + OptionStrings.insert(std::make_pair("vec-divf", false)); + OptionStrings.insert(std::make_pair("sqrtd", false)); + OptionStrings.insert(std::make_pair("sqrtf", false)); + OptionStrings.insert(std::make_pair("vec-sqrtd", false)); + OptionStrings.insert(std::make_pair("vec-sqrtf", false)); for (unsigned i = 0; i != NumOptions; ++i) { StringRef Val = A->getValue(i); @@ -1636,7 +1642,7 @@ static void ParseMRecip(const Driver &D, const ArgList &Args, return; } } - + if (OptionIter->second == true) { // Duplicate option specified. D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val; @@ -1669,8 +1675,8 @@ static void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, llvm::StringMap<bool> HostFeatures; if (llvm::sys::getHostCPUFeatures(HostFeatures)) for (auto &F : HostFeatures) - Features.push_back(Args.MakeArgString((F.second ? "+" : "-") + - F.first())); + Features.push_back( + Args.MakeArgString((F.second ? "+" : "-") + F.first())); } } @@ -1739,9 +1745,7 @@ static void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - if (!Args.hasFlag(options::OPT_mred_zone, - options::OPT_mno_red_zone, - true) || + if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || Args.hasArg(options::OPT_mkernel) || Args.hasArg(options::OPT_fapple_kext)) CmdArgs.push_back("-disable-red-zone"); @@ -1750,10 +1754,9 @@ void Clang::AddX86TargetArgs(const ArgList &Args, // that to be overridden with -mno-soft-float. bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) || Args.hasArg(options::OPT_fapple_kext)); - if (Arg *A = Args.getLastArg(options::OPT_msoft_float, - options::OPT_mno_soft_float, - options::OPT_mimplicit_float, - options::OPT_mno_implicit_float)) { + if (Arg *A = Args.getLastArg( + options::OPT_msoft_float, options::OPT_mno_soft_float, + options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) { const Option &O = A->getOption(); NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) || O.matches(options::OPT_msoft_float)); @@ -1778,21 +1781,21 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args, CmdArgs.push_back("-mqdsp6-compat"); CmdArgs.push_back("-Wreturn-type"); - if (const char* v = toolchains::Hexagon_TC::GetSmallDataThreshold(Args)) { - std::string SmallDataThreshold="-hexagon-small-data-threshold="; + if (const char *v = toolchains::Hexagon_TC::GetSmallDataThreshold(Args)) { + std::string SmallDataThreshold = "-hexagon-small-data-threshold="; SmallDataThreshold += v; - CmdArgs.push_back ("-mllvm"); + CmdArgs.push_back("-mllvm"); CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold)); } if (!Args.hasArg(options::OPT_fno_short_enums)) CmdArgs.push_back("-fshort-enums"); if (Args.getLastArg(options::OPT_mieee_rnd_near)) { - CmdArgs.push_back ("-mllvm"); - CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near"); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-enable-hexagon-ieee-rnd-near"); } - CmdArgs.push_back ("-mllvm"); - CmdArgs.push_back ("-machine-sink-split=0"); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-machine-sink-split=0"); } // Decode AArch64 features from string like +[no]featureA+[no]featureB+... @@ -1801,8 +1804,8 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, SmallVector<StringRef, 8> Split; text.split(Split, StringRef("+"), -1, false); - for (unsigned I = 0, E = Split.size(); I != E; ++I) { - const char *result = llvm::StringSwitch<const char *>(Split[I]) + for (const StringRef Feature : Split) { + const char *result = llvm::StringSwitch<const char *>(Feature) .Case("fp", "+fp-armv8") .Case("simd", "+neon") .Case("crc", "+crc") @@ -1814,7 +1817,7 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, .Default(nullptr); if (result) Features.push_back(result); - else if (Split[I] == "neon" || Split[I] == "noneon") + else if (Feature == "neon" || Feature == "noneon") D.Diag(diag::err_drv_no_neon_modifier); else return false; @@ -1828,7 +1831,8 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, std::vector<const char *> &Features) { std::pair<StringRef, StringRef> Split = Mcpu.split("+"); CPU = Split.first; - if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57" || CPU == "cortex-a72") { + if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57" || + CPU == "cortex-a72") { Features.push_back("+neon"); Features.push_back("+crc"); Features.push_back("+crypto"); @@ -1851,12 +1855,9 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, std::string MarchLowerCase = March.lower(); std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+"); - if (Split.first == "armv8-a" || - Split.first == "armv8a") { + if (Split.first == "armv8-a" || Split.first == "armv8a") { // ok, no additional features. - } else if ( - Split.first == "armv8.1-a" || - Split.first == "armv8.1a" ) { + } else if (Split.first == "armv8.1-a" || Split.first == "armv8.1a") { Features.push_back("+v8.1a"); } else { return false; @@ -1941,8 +1942,7 @@ static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args, } // En/disable crc - if (Arg *A = Args.getLastArg(options::OPT_mcrc, - options::OPT_mnocrc)) { + if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) { if (A->getOption().matches(options::OPT_mcrc)) Features.push_back("+crc"); else @@ -2023,7 +2023,7 @@ shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime, if (!Triple.isMacOSX()) return false; - return (!Triple.isMacOSXVersionLT(10,5) && + return (!Triple.isMacOSXVersionLT(10, 5) && (Triple.getArch() == llvm::Triple::x86_64 || Triple.getArch() == llvm::Triple::arm)); } @@ -2069,8 +2069,7 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, // is not necessarily sensible, but follows GCC. if (types::isObjC(InputType) && Args.hasFlag(options::OPT_fobjc_exceptions, - options::OPT_fno_objc_exceptions, - true)) { + options::OPT_fno_objc_exceptions, true)) { CmdArgs.push_back("-fobjc-exceptions"); EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple); @@ -2113,8 +2112,7 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back("-fexceptions"); } -static bool ShouldDisableAutolink(const ArgList &Args, - const ToolChain &TC) { +static bool ShouldDisableAutolink(const ArgList &Args, const ToolChain &TC) { bool Default = true; if (TC.getTriple().isOSDarwin()) { // The native darwin assembler doesn't support the linker_option directives, @@ -2127,9 +2125,9 @@ static bool ShouldDisableAutolink(const ArgList &Args, static bool ShouldDisableDwarfDirectory(const ArgList &Args, const ToolChain &TC) { - bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm, - options::OPT_fno_dwarf_directory_asm, - TC.useIntegratedAs()); + bool UseDwarfDirectory = + Args.hasFlag(options::OPT_fdwarf_directory_asm, + options::OPT_fno_dwarf_directory_asm, TC.useIntegratedAs()); return !UseDwarfDirectory; } @@ -2164,79 +2162,78 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) { } return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all, - RelaxDefault); + RelaxDefault); } static void CollectArgsForIntegratedAssembler(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs, const Driver &D) { - if (UseRelaxAll(C, Args)) - CmdArgs.push_back("-mrelax-all"); - - // When passing -I arguments to the assembler we sometimes need to - // unconditionally take the next argument. For example, when parsing - // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the - // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo' - // arg after parsing the '-I' arg. - bool TakeNextArg = false; - - // When using an integrated assembler, translate -Wa, and -Xassembler - // options. - bool CompressDebugSections = false; - for (const Arg *A : - Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { - A->claim(); + if (UseRelaxAll(C, Args)) + CmdArgs.push_back("-mrelax-all"); + + // When passing -I arguments to the assembler we sometimes need to + // unconditionally take the next argument. For example, when parsing + // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the + // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo' + // arg after parsing the '-I' arg. + bool TakeNextArg = false; + + // When using an integrated assembler, translate -Wa, and -Xassembler + // options. + bool CompressDebugSections = false; + for (const Arg *A : + Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { + A->claim(); - for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { - StringRef Value = A->getValue(i); + for (const StringRef Value : A->getValues()) { if (TakeNextArg) { CmdArgs.push_back(Value.data()); TakeNextArg = false; continue; } - if (Value == "-force_cpusubtype_ALL") { - // Do nothing, this is the default and we don't support anything else. - } else if (Value == "-L") { - CmdArgs.push_back("-msave-temp-labels"); - } else if (Value == "--fatal-warnings") { - CmdArgs.push_back("-massembler-fatal-warnings"); - } else if (Value == "--noexecstack") { - CmdArgs.push_back("-mnoexecstack"); - } else if (Value == "-compress-debug-sections" || - Value == "--compress-debug-sections") { - CompressDebugSections = true; - } else if (Value == "-nocompress-debug-sections" || - Value == "--nocompress-debug-sections") { - CompressDebugSections = false; - } else if (Value.startswith("-I")) { - CmdArgs.push_back(Value.data()); - // We need to consume the next argument if the current arg is a plain - // -I. The next arg will be the include directory. - if (Value == "-I") - TakeNextArg = true; - } else if (Value.startswith("-gdwarf-")) { - CmdArgs.push_back(Value.data()); - } else { - D.Diag(diag::err_drv_unsupported_option_argument) + if (Value == "-force_cpusubtype_ALL") { + // Do nothing, this is the default and we don't support anything else. + } else if (Value == "-L") { + CmdArgs.push_back("-msave-temp-labels"); + } else if (Value == "--fatal-warnings") { + CmdArgs.push_back("-massembler-fatal-warnings"); + } else if (Value == "--noexecstack") { + CmdArgs.push_back("-mnoexecstack"); + } else if (Value == "-compress-debug-sections" || + Value == "--compress-debug-sections") { + CompressDebugSections = true; + } else if (Value == "-nocompress-debug-sections" || + Value == "--nocompress-debug-sections") { + CompressDebugSections = false; + } else if (Value.startswith("-I")) { + CmdArgs.push_back(Value.data()); + // We need to consume the next argument if the current arg is a plain + // -I. The next arg will be the include directory. + if (Value == "-I") + TakeNextArg = true; + } else if (Value.startswith("-gdwarf-")) { + CmdArgs.push_back(Value.data()); + } else { + D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; - } } } - if (CompressDebugSections) { - if (llvm::zlib::isAvailable()) - CmdArgs.push_back("-compress-debug-sections"); - else - D.Diag(diag::warn_debug_compression_unavailable); - } + } + if (CompressDebugSections) { + if (llvm::zlib::isAvailable()) + CmdArgs.push_back("-compress-debug-sections"); + else + D.Diag(diag::warn_debug_compression_unavailable); + } } // Until ARM libraries are build separately, we have them all in one library static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) { - // FIXME: handle 64-bit if (TC.getTriple().isOSWindows() && - !TC.getTriple().isWindowsItaniumEnvironment()) + !TC.getTriple().isWindowsItaniumEnvironment() && + TC.getArch() == llvm::Triple::x86) return "i386"; if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) return "arm"; @@ -2254,8 +2251,8 @@ static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) { return Res; } -static SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component, - bool Shared = false) { +SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component, + bool Shared) { const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android ? "-android" : ""; @@ -2334,15 +2331,15 @@ static OpenMPRuntimeKind getOpenMPRuntime(const ToolChain &TC, RuntimeName = A->getValue(); auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName) - .Case("libomp", OMPRT_OMP) - .Case("libgomp", OMPRT_GOMP) - .Case("libiomp5", OMPRT_IOMP5) - .Default(OMPRT_Unknown); + .Case("libomp", OMPRT_OMP) + .Case("libgomp", OMPRT_GOMP) + .Case("libiomp5", OMPRT_IOMP5) + .Default(OMPRT_Unknown); if (RT == OMPRT_Unknown) { if (A) TC.getDriver().Diag(diag::err_drv_unsupported_option_argument) - << A->getOption().getName() << A->getValue(); + << A->getOption().getName() << A->getValue(); else // FIXME: We could use a nicer diagnostic here. TC.getDriver().Diag(diag::err_drv_unsupported_opt) << "-fopenmp"; @@ -2537,8 +2534,7 @@ static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) { } } -static const char *SplitDebugName(const ArgList &Args, - const InputInfo &Input) { +static const char *SplitDebugName(const ArgList &Args, const InputInfo &Input) { Arg *FinalOutput = Args.getLastArg(options::OPT_o); if (FinalOutput && Args.hasArg(options::OPT_c)) { SmallString<128> T(FinalOutput->getValue()); @@ -2555,10 +2551,9 @@ static const char *SplitDebugName(const ArgList &Args, } } -static void SplitDebugInfo(const ToolChain &TC, Compilation &C, - const Tool &T, const JobAction &JA, - const ArgList &Args, const InputInfo &Output, - const char *OutFile) { +static void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, + const JobAction &JA, const ArgList &Args, + const InputInfo &Output, const char *OutFile) { ArgStringList ExtractArgs; ExtractArgs.push_back("--extract-dwo"); @@ -2570,8 +2565,7 @@ static void SplitDebugInfo(const ToolChain &TC, Compilation &C, ExtractArgs.push_back(Output.getFilename()); ExtractArgs.push_back(OutFile); - const char *Exec = - Args.MakeArgString(TC.GetProgramPath("objcopy")); + const char *Exec = Args.MakeArgString(TC.GetProgramPath("objcopy")); // First extract the dwo sections. C.addCommand(llvm::make_unique<Command>(JA, T, Exec, ExtractArgs)); @@ -2635,7 +2629,7 @@ static VersionTuple getMSCompatibilityVersion(unsigned Version) { return VersionTuple(Version / 100, Version % 100); unsigned Build = 0, Factor = 1; - for ( ; Version > 10000; Version = Version / 10, Factor = Factor * 10) + for (; Version > 10000; Version = Version / 10, Factor = Factor * 10) Build = Build + (Version % 10) * Factor; return VersionTuple(Version / 100, Version % 100, Build); } @@ -2672,7 +2666,7 @@ static void appendUserToPath(SmallVectorImpl<char> &Result) { } } - // Fallback to user id. +// Fallback to user id. #ifdef LLVM_ON_UNIX std::string UID = llvm::utostr(getuid()); #else @@ -2692,7 +2686,7 @@ VersionTuple visualstudio::getMSVCVersion(const Driver *D, Args.hasArg(options::OPT_fms_compatibility_version)) { const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version); const Arg *MSCompatibilityVersion = - Args.getLastArg(options::OPT_fms_compatibility_version); + Args.getLastArg(options::OPT_fms_compatibility_version); if (MSCVersion && MSCompatibilityVersion) { if (D) @@ -2730,12 +2724,10 @@ VersionTuple visualstudio::getMSVCVersion(const Driver *D, } void Clang::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { - bool KernelOrKext = Args.hasArg(options::OPT_mkernel, - options::OPT_fapple_kext); + const InputInfo &Output, const InputInfoList &Inputs, + const ArgList &Args, const char *LinkingOutput) const { + bool KernelOrKext = + Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -2775,7 +2767,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Select the appropriate action. RewriteKind rewriteKind = RK_None; - + if (isa<AnalyzeJobAction>(JA)) { assert(JA.getType() == types::TY_Plist && "Invalid output type."); CmdArgs.push_back("-analyze"); @@ -2796,7 +2788,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D); // Also ignore explicit -force_cpusubtype_ALL option. - (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); + (void)Args.hasArg(options::OPT_force__cpusubtype__ALL); } else if (isa<PrecompileJobAction>(JA)) { // Use PCH if the user requested it. bool UsePCH = D.CCCUsePCH; @@ -2834,8 +2826,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-rewrite-objc"); rewriteKind = RK_Fragile; } else { - assert(JA.getType() == types::TY_PP_Asm && - "Unexpected output type!"); + assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!"); } // Preserve use-list order by default when emitting bitcode, so that @@ -2852,7 +2843,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!C.isForDiagnostics()) CmdArgs.push_back("-disable-free"); - // Disable the verification pass in -asserts builds. +// Disable the verification pass in -asserts builds. #ifdef NDEBUG CmdArgs.push_back("-disable-llvm-verifier"); #endif @@ -2885,9 +2876,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple) CmdArgs.push_back("-analyzer-checker=osx"); - + CmdArgs.push_back("-analyzer-checker=deadcode"); - + if (types::isCXX(Input.getType())) CmdArgs.push_back("-analyzer-checker=cplusplus"); @@ -2896,7 +2887,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, "-analyzer-checker=security.insecureAPI.UncheckedReturn"); CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw"); CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets"); - CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp"); + CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp"); CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp"); CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork"); } @@ -2980,10 +2971,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // used. If the last argument is any flavor of the '-fno-...' arguments, // both PIC and PIE are disabled. Any PIE option implicitly enables PIC // at the same level. - Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, - options::OPT_fpic, options::OPT_fno_pic, - options::OPT_fPIE, options::OPT_fno_PIE, - options::OPT_fpie, options::OPT_fno_pie); + Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, + options::OPT_fpic, options::OPT_fno_pic, + options::OPT_fPIE, options::OPT_fno_PIE, + options::OPT_fpie, options::OPT_fno_pie); // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness // is forced, then neither PIC nor PIE flags will have no effect. if (!getToolChain().isPICDefaultForced()) { @@ -2992,10 +2983,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); - PIC = PIE || O.matches(options::OPT_fPIC) || - O.matches(options::OPT_fpic); - IsPICLevelTwo = O.matches(options::OPT_fPIE) || - O.matches(options::OPT_fPIC); + PIC = + PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic); + IsPICLevelTwo = + O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC); } else { PIE = PIC = false; } @@ -3022,7 +3013,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // uses it, and it isn't even valid on any OS but Darwin. if (!getToolChain().getTriple().isOSDarwin()) D.Diag(diag::err_drv_unsupported_opt_for_target) - << A->getSpelling() << getToolChain().getTriple().str(); + << A->getSpelling() << getToolChain().getTriple().str(); // FIXME: Warn when this flag trumps some other PIC or PIE flag. @@ -3092,7 +3083,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_freg_struct_return)) { if (getToolChain().getArch() != llvm::Triple::x86) { D.Diag(diag::err_drv_unsupported_opt_for_target) - << A->getSpelling() << getToolChain().getTriple().str(); + << A->getSpelling() << getToolChain().getTriple().str(); } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) { CmdArgs.push_back("-fpcc-struct-return"); } else { @@ -3113,8 +3104,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, bool OFastEnabled = isOptimizationLevelFast(Args); // If -Ofast is the optimization level, then -fstrict-aliasing should be // enabled. This alias option is being used to simplify the hasFlag logic. - OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast : - options::OPT_fstrict_aliasing; + OptSpecifier StrictAliasingAliasOption = + OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing; // We turn strict aliasing off by default if we're in CL mode, since MSVC // doesn't do any TBAA. bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode(); @@ -3137,30 +3128,28 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // If -Ofast is the optimization level, then -ffast-math should be enabled. // This alias option is being used to simplify the getLastArg logic. - OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast : - options::OPT_ffast_math; - + OptSpecifier FastMathAliasOption = + OFastEnabled ? options::OPT_Ofast : options::OPT_ffast_math; + // Handle various floating point optimization flags, mapping them to the // appropriate LLVM code generation flags. The pattern for all of these is to // default off the codegen optimizations, and if any flag enables them and no // flag disables them after the flag enabling them, enable the codegen // optimization. This is complicated by several "umbrella" flags. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_ffinite_math_only, - options::OPT_fno_finite_math_only, - options::OPT_fhonor_infinities, - options::OPT_fno_honor_infinities)) + if (Arg *A = Args.getLastArg( + options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_ffinite_math_only, + options::OPT_fno_finite_math_only, options::OPT_fhonor_infinities, + options::OPT_fno_honor_infinities)) if (A->getOption().getID() != options::OPT_fno_fast_math && A->getOption().getID() != options::OPT_fno_finite_math_only && A->getOption().getID() != options::OPT_fhonor_infinities) CmdArgs.push_back("-menable-no-infs"); - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_ffinite_math_only, - options::OPT_fno_finite_math_only, - options::OPT_fhonor_nans, - options::OPT_fno_honor_nans)) + if (Arg *A = Args.getLastArg( + options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_ffinite_math_only, + options::OPT_fno_finite_math_only, options::OPT_fhonor_nans, + options::OPT_fno_honor_nans)) if (A->getOption().getID() != options::OPT_fno_fast_math && A->getOption().getID() != options::OPT_fno_finite_math_only && A->getOption().getID() != options::OPT_fhonor_nans) @@ -3168,10 +3157,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes. bool MathErrno = getToolChain().IsMathErrnoDefault(); - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_fmath_errno, - options::OPT_fno_math_errno)) { + if (Arg *A = + Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_fmath_errno, + options::OPT_fno_math_errno)) { // Turning on -ffast_math (with either flag) removes the need for MathErrno. // However, turning *off* -ffast_math merely restores the toolchain default // (which may be false). @@ -3190,45 +3179,41 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // entire set of LLVM optimizations, so collect them through all the flag // madness. bool AssociativeMath = false; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_funsafe_math_optimizations, - options::OPT_fno_unsafe_math_optimizations, - options::OPT_fassociative_math, - options::OPT_fno_associative_math)) + if (Arg *A = Args.getLastArg( + options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, + options::OPT_fno_unsafe_math_optimizations, + options::OPT_fassociative_math, options::OPT_fno_associative_math)) if (A->getOption().getID() != options::OPT_fno_fast_math && A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && A->getOption().getID() != options::OPT_fno_associative_math) AssociativeMath = true; bool ReciprocalMath = false; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_funsafe_math_optimizations, - options::OPT_fno_unsafe_math_optimizations, - options::OPT_freciprocal_math, - options::OPT_fno_reciprocal_math)) + if (Arg *A = Args.getLastArg( + options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, + options::OPT_fno_unsafe_math_optimizations, + options::OPT_freciprocal_math, options::OPT_fno_reciprocal_math)) if (A->getOption().getID() != options::OPT_fno_fast_math && A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && A->getOption().getID() != options::OPT_fno_reciprocal_math) ReciprocalMath = true; bool SignedZeros = true; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_funsafe_math_optimizations, - options::OPT_fno_unsafe_math_optimizations, - options::OPT_fsigned_zeros, - options::OPT_fno_signed_zeros)) + if (Arg *A = Args.getLastArg( + options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, + options::OPT_fno_unsafe_math_optimizations, + options::OPT_fsigned_zeros, options::OPT_fno_signed_zeros)) if (A->getOption().getID() != options::OPT_fno_fast_math && A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && A->getOption().getID() != options::OPT_fsigned_zeros) SignedZeros = false; bool TrappingMath = true; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, - options::OPT_fno_fast_math, - options::OPT_funsafe_math_optimizations, - options::OPT_fno_unsafe_math_optimizations, - options::OPT_ftrapping_math, - options::OPT_fno_trapping_math)) + if (Arg *A = Args.getLastArg( + options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, + options::OPT_fno_unsafe_math_optimizations, + options::OPT_ftrapping_math, options::OPT_fno_trapping_math)) if (A->getOption().getID() != options::OPT_fno_fast_math && A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations && A->getOption().getID() != options::OPT_ftrapping_math) @@ -3243,7 +3228,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (ReciprocalMath) CmdArgs.push_back("-freciprocal-math"); - // Validate and pass through -fp-contract option. + // Validate and pass through -fp-contract option. if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffp_contract)) { @@ -3253,7 +3238,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val)); } else { D.Diag(diag::err_drv_unsupported_option_argument) - << A->getOption().getName() << Val; + << A->getOption().getName() << Val; } } else if (A->getOption().matches(options::OPT_ffast_math) || (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) { @@ -3261,7 +3246,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); } } - + ParseMRecip(getToolChain().getDriver(), Args, CmdArgs); // We separately look for the '-ffast-math' and '-ffinite-math-only' flags, @@ -3271,8 +3256,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // and deserialization, etc. if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math)) - if (!A->getOption().matches(options::OPT_fno_fast_math)) - CmdArgs.push_back("-ffast-math"); + if (!A->getOption().matches(options::OPT_fno_fast_math)) + CmdArgs.push_back("-ffast-math"); if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math)) if (A->getOption().matches(options::OPT_ffinite_math_only)) @@ -3335,7 +3320,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } // FIXME: Handle -mtune=. - (void) Args.hasArg(options::OPT_mtune_EQ); + (void)Args.hasArg(options::OPT_mtune_EQ); if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) { CmdArgs.push_back("-mcode-model"); @@ -3358,7 +3343,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, getTargetFeatures(D, Triple, Args, CmdArgs, false); // Add target specific flags. - switch(getToolChain().getArch()) { + switch (getToolChain().getArch()) { default: break; @@ -3421,13 +3406,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, types::ID InputType = Input.getType(); if (!Args.hasArg(options::OPT_fallow_unsupported)) { Arg *Unsupported; - if (types::isCXX(InputType) && - getToolChain().getTriple().isOSDarwin() && + if (types::isCXX(InputType) && getToolChain().getTriple().isOSDarwin() && getToolChain().getArch() == llvm::Triple::x86) { if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) || (Unsupported = Args.getLastArg(options::OPT_mkernel))) D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386) - << Unsupported->getOption().getName(); + << Unsupported->getOption().getName(); } } @@ -3435,16 +3419,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_H); if (D.CCPrintHeaders && !D.CCGenDiagnostics) { CmdArgs.push_back("-header-include-file"); - CmdArgs.push_back(D.CCPrintHeadersFilename ? - D.CCPrintHeadersFilename : "-"); + CmdArgs.push_back(D.CCPrintHeadersFilename ? D.CCPrintHeadersFilename + : "-"); } Args.AddLastArg(CmdArgs, options::OPT_P); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); if (D.CCLogDiagnostics && !D.CCGenDiagnostics) { CmdArgs.push_back("-diagnostic-log-file"); - CmdArgs.push_back(D.CCLogDiagnosticsFilename ? - D.CCLogDiagnosticsFilename : "-"); + CmdArgs.push_back(D.CCLogDiagnosticsFilename ? D.CCLogDiagnosticsFilename + : "-"); } // Use the last option from "-g" group. "-gline-tables-only" and "-gdwarf-x" @@ -3525,8 +3509,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-ffunction-sections"); } - if (Args.hasFlag(options::OPT_fdata_sections, - options::OPT_fno_data_sections, UseSeparateSections)) { + if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections, + UseSeparateSections)) { CmdArgs.push_back("-fdata-sections"); } @@ -3541,7 +3525,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, (Args.hasArg(options::OPT_fprofile_instr_use) || Args.hasArg(options::OPT_fprofile_instr_use_EQ))) D.Diag(diag::err_drv_argument_not_allowed_with) - << "-fprofile-instr-generate" << "-fprofile-instr-use"; + << "-fprofile-instr-generate" + << "-fprofile-instr-use"; if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_generate_EQ)) A->render(Args, CmdArgs); @@ -3565,7 +3550,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, !(Args.hasArg(options::OPT_fprofile_instr_generate) || Args.hasArg(options::OPT_fprofile_instr_generate_EQ))) D.Diag(diag::err_drv_argument_only_allowed_with) - << "-fcoverage-mapping" << "-fprofile-instr-generate"; + << "-fcoverage-mapping" + << "-fprofile-instr-generate"; if (Args.hasArg(options::OPT_fcoverage_mapping)) CmdArgs.push_back("-fcoverage-mapping"); @@ -3597,7 +3583,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-nobuiltininc"); } else { if (Args.hasArg(options::OPT_nostdlibinc)) - CmdArgs.push_back("-nostdsysteminc"); + CmdArgs.push_back("-nostdsysteminc"); Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); } @@ -3641,8 +3627,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) { if (ARCMTEnabled) { - D.Diag(diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-ccc-arcmt-migrate"; + D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) + << "-ccc-arcmt-migrate"; } CmdArgs.push_back("-mt-migrate-directory"); CmdArgs.push_back(A->getValue()); @@ -3745,8 +3731,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // eventually we want to do all the standard defaulting here instead of // splitting it between the driver and clang -cc1. if (!types::isCXX(InputType)) - Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, - "-std=", /*Joined=*/true); + Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=", + /*Joined=*/true); else if (IsWindowsMSVC) ImplyVCPPCXXVer = true; @@ -3835,7 +3821,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value } - if (Args.hasArg(options::OPT_relocatable_pch)) CmdArgs.push_back("-relocatable-pch"); @@ -3917,8 +3902,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug); Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); // AltiVec language extensions aren't relevant for assembling. - if (!isa<PreprocessJobAction>(JA) || - Output.getType() != types::TY_PP_Asm) + if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) Args.AddLastArg(CmdArgs, options::OPT_faltivec); Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); @@ -3943,7 +3927,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs(); - Sanitize.addArgs(Args, CmdArgs); + Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType); // Report an error for -faltivec on anything other than PowerPC. if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) { @@ -3980,8 +3964,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fno-strict-overflow implies -fwrapv if it isn't disabled, but // -fstrict-overflow won't turn off an explicitly enabled -fwrapv. - if (Arg *A = Args.getLastArg(options::OPT_fwrapv, - options::OPT_fno_wrapv)) { + if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) { if (A->getOption().matches(options::OPT_fwrapv)) CmdArgs.push_back("-fwrapv"); } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow, @@ -4001,7 +3984,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_pthread); - // -stack-protector=0 is default. unsigned StackProtectorLevel = 0; if (getToolChain().getSanitizerArgs().needsSafeStackRt()) { @@ -4010,19 +3992,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.ClaimAllArgs(options::OPT_fstack_protector_strong); Args.ClaimAllArgs(options::OPT_fstack_protector); } else if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, - options::OPT_fstack_protector_all, - options::OPT_fstack_protector_strong, - options::OPT_fstack_protector)) { + options::OPT_fstack_protector_all, + options::OPT_fstack_protector_strong, + options::OPT_fstack_protector)) { if (A->getOption().matches(options::OPT_fstack_protector)) { - StackProtectorLevel = std::max<unsigned>(LangOptions::SSPOn, - getToolChain().GetDefaultStackProtectorLevel(KernelOrKext)); + StackProtectorLevel = std::max<unsigned>( + LangOptions::SSPOn, + getToolChain().GetDefaultStackProtectorLevel(KernelOrKext)); } else if (A->getOption().matches(options::OPT_fstack_protector_strong)) StackProtectorLevel = LangOptions::SSPStrong; else if (A->getOption().matches(options::OPT_fstack_protector_all)) StackProtectorLevel = LangOptions::SSPReq; } else { StackProtectorLevel = - getToolChain().GetDefaultStackProtectorLevel(KernelOrKext); + getToolChain().GetDefaultStackProtectorLevel(KernelOrKext); } if (StackProtectorLevel) { CmdArgs.push_back("-stack-protector"); @@ -4049,7 +4032,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-force-align-stack"); } if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign, - false)) { + false)) { CmdArgs.push_back(Args.MakeArgString("-mstackrealign")); } @@ -4126,12 +4109,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fblocks=0 is default. if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks, getToolChain().IsBlocksDefault()) || - (Args.hasArg(options::OPT_fgnu_runtime) && - Args.hasArg(options::OPT_fobjc_nonfragile_abi) && - !Args.hasArg(options::OPT_fno_blocks))) { + (Args.hasArg(options::OPT_fgnu_runtime) && + Args.hasArg(options::OPT_fobjc_nonfragile_abi) && + !Args.hasArg(options::OPT_fno_blocks))) { CmdArgs.push_back("-fblocks"); - if (!Args.hasArg(options::OPT_fgnu_runtime) && + if (!Args.hasArg(options::OPT_fgnu_runtime) && !getToolChain().hasBlocksRuntime()) CmdArgs.push_back("-fblocks-runtime-optional"); } @@ -4141,9 +4124,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // C++/Objective-C++ programs. bool HaveModules = false; if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) { - bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules, - options::OPT_fno_cxx_modules, - true); + bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules, + options::OPT_fno_cxx_modules, true); if (AllowedInCXX || !types::isCXX(InputType)) { CmdArgs.push_back("-fmodules"); HaveModules = true; @@ -4160,16 +4142,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fmodules-decluse checks that modules used are declared so (off by // default). if (Args.hasFlag(options::OPT_fmodules_decluse, - options::OPT_fno_modules_decluse, - false)) { + options::OPT_fno_modules_decluse, false)) { CmdArgs.push_back("-fmodules-decluse"); } // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that // all #included headers are part of modules. if (Args.hasFlag(options::OPT_fmodules_strict_decluse, - options::OPT_fno_modules_strict_decluse, - false)) { + options::OPT_fno_modules_strict_decluse, false)) { CmdArgs.push_back("-fmodules-strict-decluse"); } @@ -4264,14 +4244,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -faccess-control is default. if (Args.hasFlag(options::OPT_fno_access_control, - options::OPT_faccess_control, - false)) + options::OPT_faccess_control, false)) CmdArgs.push_back("-fno-access-control"); // -felide-constructors is the default. if (Args.hasFlag(options::OPT_fno_elide_constructors, - options::OPT_felide_constructors, - false)) + options::OPT_felide_constructors, false)) CmdArgs.push_back("-fno-elide-constructors"); ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode(); @@ -4282,10 +4260,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fno-rtti"); // -fshort-enums=0 is default for all architectures except Hexagon. - if (Args.hasFlag(options::OPT_fshort_enums, - options::OPT_fno_short_enums, - getToolChain().getArch() == - llvm::Triple::hexagon)) + if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums, + getToolChain().getArch() == llvm::Triple::hexagon)) CmdArgs.push_back("-fshort-enums"); // -fsigned-char is default. @@ -4304,8 +4280,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, !IsWindowsCygnus && !IsWindowsGNU && - getToolChain().getArch() != llvm::Triple::hexagon && - getToolChain().getArch() != llvm::Triple::xcore) || + getToolChain().getArch() != llvm::Triple::hexagon && + getToolChain().getArch() != llvm::Triple::xcore) || KernelOrKext) CmdArgs.push_back("-fno-use-cxa-atexit"); @@ -4320,11 +4296,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fuse-line-directives"); // -fms-compatibility=0 is default. - if (Args.hasFlag(options::OPT_fms_compatibility, + if (Args.hasFlag(options::OPT_fms_compatibility, options::OPT_fno_ms_compatibility, - (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions, - options::OPT_fno_ms_extensions, - true)))) + (IsWindowsMSVC && + Args.hasFlag(options::OPT_fms_extensions, + options::OPT_fno_ms_extensions, true)))) CmdArgs.push_back("-fms-compatibility"); // -fms-compatibility-version=18.00 is default. @@ -4366,8 +4342,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_gnu_keywords)) A->render(Args, CmdArgs); - if (Args.hasFlag(options::OPT_fgnu89_inline, - options::OPT_fno_gnu89_inline, + if (Args.hasFlag(options::OPT_fgnu89_inline, options::OPT_fno_gnu89_inline, false)) CmdArgs.push_back("-fgnu89-inline"); @@ -4387,7 +4362,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch, options::OPT_fno_objc_legacy_dispatch, objcRuntime.isLegacyDispatchDefaultForArch( - getToolChain().getArch()))) { + getToolChain().getArch()))) { if (getToolChain().UseObjCMixedDispatch()) CmdArgs.push_back("-fobjc-dispatch-method=mixed"); else @@ -4404,12 +4379,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, objcRuntime.getKind() == ObjCRuntime::FragileMacOSX && objcRuntime.isNeXTFamily()) CmdArgs.push_back("-fobjc-subscripting-legacy-runtime"); - + // -fencode-extended-block-signature=1 is default. if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) { CmdArgs.push_back("-fencode-extended-block-signature"); } - + // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc. // NOTE: This logic is duplicated in ToolChains.cpp. bool ARC = isObjCAutoRefCount(Args); @@ -4448,14 +4423,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, GCArg = Args.getLastArg(options::OPT_fobjc_gc); if (GCArg) { if (ARC) { - D.Diag(diag::err_drv_objc_gc_arr) - << GCArg->getAsString(Args); + D.Diag(diag::err_drv_objc_gc_arr) << GCArg->getAsString(Args); } else if (getToolChain().SupportsObjCGC()) { GCArg->render(Args, CmdArgs); } else { // FIXME: We should move this to a hard error. - D.Diag(diag::warn_drv_objc_gc_unsupported) - << GCArg->getAsString(Args); + D.Diag(diag::warn_drv_objc_gc_unsupported) << GCArg->getAsString(Args); } } @@ -4465,8 +4438,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Handle GCC-style exception args. if (!C.getDriver().IsCLMode()) - addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, - objcRuntime, CmdArgs); + addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, objcRuntime, + CmdArgs); if (getToolChain().UseSjLjExceptions()) CmdArgs.push_back("-fsjlj-exceptions"); @@ -4498,8 +4471,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fno-pascal-strings is default, only pass non-default. if (Args.hasFlag(options::OPT_fpascal_strings, - options::OPT_fno_pascal_strings, - false)) + options::OPT_fno_pascal_strings, false)) CmdArgs.push_back("-fpascal-strings"); // Honor -fpack-struct= and -fpack-struct, if given. Note that @@ -4543,28 +4515,27 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fsigned_bitfields, options::OPT_funsigned_bitfields)) D.Diag(diag::warn_drv_clang_unsupported) - << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args); + << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args); // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope. - if (!Args.hasFlag(options::OPT_ffor_scope, - options::OPT_fno_for_scope)) + if (!Args.hasFlag(options::OPT_ffor_scope, options::OPT_fno_for_scope)) D.Diag(diag::err_drv_clang_unsupported) - << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args); + << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args); // -finput_charset=UTF-8 is default. Reject others - if (Arg *inputCharset = Args.getLastArg( - options::OPT_finput_charset_EQ)) { - StringRef value = inputCharset->getValue(); - if (value != "UTF-8") - D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) << value; + if (Arg *inputCharset = Args.getLastArg(options::OPT_finput_charset_EQ)) { + StringRef value = inputCharset->getValue(); + if (value != "UTF-8") + D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) + << value; } // -fexec_charset=UTF-8 is default. Reject others - if (Arg *execCharset = Args.getLastArg( - options::OPT_fexec_charset_EQ)) { - StringRef value = execCharset->getValue(); - if (value != "UTF-8") - D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args) << value; + if (Arg *execCharset = Args.getLastArg(options::OPT_fexec_charset_EQ)) { + StringRef value = execCharset->getValue(); + if (value != "UTF-8") + D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args) + << value; } // -fcaret-diagnostics is default. @@ -4583,22 +4554,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fdiagnostics-show-option"); if (const Arg *A = - Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { + Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { CmdArgs.push_back("-fdiagnostics-show-category"); CmdArgs.push_back(A->getValue()); } - if (const Arg *A = - Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) { + if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) { CmdArgs.push_back("-fdiagnostics-format"); CmdArgs.push_back(A->getValue()); } if (Arg *A = Args.getLastArg( - options::OPT_fdiagnostics_show_note_include_stack, - options::OPT_fno_diagnostics_show_note_include_stack)) { + options::OPT_fdiagnostics_show_note_include_stack, + options::OPT_fno_diagnostics_show_note_include_stack)) { if (A->getOption().matches( - options::OPT_fdiagnostics_show_note_include_stack)) + options::OPT_fdiagnostics_show_note_include_stack)) CmdArgs.push_back("-fdiagnostics-show-note-include-stack"); else CmdArgs.push_back("-fno-diagnostics-show-note-include-stack"); @@ -4636,7 +4606,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, ShowColors = Colors_Auto; else getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) - << ("-fdiagnostics-color=" + value).str(); + << ("-fdiagnostics-color=" + value).str(); } } if (ShowColors == Colors_On || @@ -4650,8 +4620,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_show_source_location)) CmdArgs.push_back("-fno-show-source-location"); - if (!Args.hasFlag(options::OPT_fshow_column, - options::OPT_fno_show_column, + if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column, true)) CmdArgs.push_back("-fno-show-column"); @@ -4659,7 +4628,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_spell_checking)) CmdArgs.push_back("-fno-spell-checking"); - // -fno-asm-blocks is default. if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks, false)) @@ -4674,16 +4642,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // selected. For optimization levels that want vectorization we use the alias // option to simplify the hasFlag logic. bool EnableVec = shouldEnableVectorizerAtOLevel(Args, false); - OptSpecifier VectorizeAliasOption = EnableVec ? options::OPT_O_Group : - options::OPT_fvectorize; + OptSpecifier VectorizeAliasOption = + EnableVec ? options::OPT_O_Group : options::OPT_fvectorize; if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption, options::OPT_fno_vectorize, EnableVec)) CmdArgs.push_back("-vectorize-loops"); // -fslp-vectorize is enabled based on the optimization level selected. bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, true); - OptSpecifier SLPVectAliasOption = EnableSLPVec ? options::OPT_O_Group : - options::OPT_fslp_vectorize; + OptSpecifier SLPVectAliasOption = + EnableSLPVec ? options::OPT_O_Group : options::OPT_fslp_vectorize; if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption, options::OPT_fno_slp_vectorize, EnableSLPVec)) CmdArgs.push_back("-vectorize-slp"); @@ -4718,16 +4686,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_apple_pragma_pack, false)) CmdArgs.push_back("-fapple-pragma-pack"); - // le32-specific flags: + // le32-specific flags: // -fno-math-builtin: clang should not convert math builtins to intrinsics // by default. if (getToolChain().getArch() == llvm::Triple::le32) { CmdArgs.push_back("-fno-math-builtin"); } - // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM. - // - // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941. +// Default to -fno-builtin-str{cat,cpy} on Darwin for ARM. +// +// FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941. #if 0 if (getToolChain().getTriple().isOSDarwin() && (getToolChain().getArch() == llvm::Triple::arm || @@ -4759,7 +4727,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_dM); Args.AddLastArg(CmdArgs, options::OPT_dD); - + // Handle serialized diagnostics. if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) { CmdArgs.push_back("-serialize-diagnostic-file"); @@ -4828,9 +4796,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, SmallString<256> Flags; Flags += Exec; - for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { + for (const char *OriginalArg : OriginalArgs) { SmallString<128> EscapedArg; - EscapeSpacesAndBackslashes(OriginalArgs[i], EscapedArg); + EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); Flags += " "; Flags += EscapedArg; } @@ -4841,9 +4809,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Add the split debug info name to the command lines here so we // can propagate it to the backend. bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) && - getToolChain().getTriple().isOSLinux() && - (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) || - isa<BackendJobAction>(JA)); + getToolChain().getTriple().isOSLinux() && + (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) || + isa<BackendJobAction>(JA)); const char *SplitDwarfOut; if (SplitDwarf) { CmdArgs.push_back("-split-dwarf-file"); @@ -4863,7 +4831,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } - // Handle the debug info splitting at object creation time if we're // creating an object. // TODO: Currently only works on linux with newer objcopy. @@ -4872,8 +4839,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_pg)) if (Args.hasArg(options::OPT_fomit_frame_pointer)) - D.Diag(diag::err_drv_argument_not_allowed_with) - << "-fomit-frame-pointer" << A->getAsString(Args); + D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer" + << A->getAsString(Args); // Claim some arguments which clang supports automatically. @@ -4898,9 +4865,9 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, ArgStringList &cmdArgs, RewriteKind rewriteKind) const { // Look for the controlling runtime option. - Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime, - options::OPT_fgnu_runtime, - options::OPT_fobjc_runtime_EQ); + Arg *runtimeArg = + args.getLastArg(options::OPT_fnext_runtime, options::OPT_fgnu_runtime, + options::OPT_fobjc_runtime_EQ); // Just forward -fobjc-runtime= to the frontend. This supercedes // options about fragility. @@ -4910,7 +4877,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, StringRef value = runtimeArg->getValue(); if (runtime.tryParse(value)) { getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime) - << value; + << value; } runtimeArg->render(args, cmdArgs); @@ -4933,26 +4900,25 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, else if (value == "3") objcABIVersion = 3; else - getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) - << value; + getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) << value; } else { // Otherwise, determine if we are using the non-fragile ABI. - bool nonFragileABIIsDefault = - (rewriteKind == RK_NonFragile || - (rewriteKind == RK_None && - getToolChain().IsObjCNonFragileABIDefault())); + bool nonFragileABIIsDefault = + (rewriteKind == RK_NonFragile || + (rewriteKind == RK_None && + getToolChain().IsObjCNonFragileABIDefault())); if (args.hasFlag(options::OPT_fobjc_nonfragile_abi, options::OPT_fno_objc_nonfragile_abi, nonFragileABIIsDefault)) { - // Determine the non-fragile ABI version to use. +// Determine the non-fragile ABI version to use. #ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO unsigned nonFragileABIVersion = 1; #else unsigned nonFragileABIVersion = 2; #endif - if (Arg *abiArg = args.getLastArg( - options::OPT_fobjc_nonfragile_abi_version_EQ)) { + if (Arg *abiArg = + args.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ)) { StringRef value = abiArg->getValue(); if (value == "1") nonFragileABIVersion = 1; @@ -4960,7 +4926,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, nonFragileABIVersion = 2; else getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) - << value; + << value; } objcABIVersion = 1 + nonFragileABIVersion; @@ -4989,30 +4955,30 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, break; } - // -fnext-runtime + // -fnext-runtime } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) { // On Darwin, make this use the default behavior for the toolchain. if (getToolChain().getTriple().isOSDarwin()) { runtime = getToolChain().getDefaultObjCRuntime(isNonFragile); - // Otherwise, build for a generic macosx port. + // Otherwise, build for a generic macosx port. } else { runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple()); } - // -fgnu-runtime + // -fgnu-runtime } else { assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime)); // Legacy behaviour is to target the gnustep runtime if we are i // non-fragile mode or the GCC runtime in fragile mode. if (isNonFragile) - runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6)); + runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1, 6)); else runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple()); } - cmdArgs.push_back(args.MakeArgString( - "-fobjc-runtime=" + runtime.getAsString())); + cmdArgs.push_back( + args.MakeArgString("-fobjc-runtime=" + runtime.getAsString())); return runtime; } @@ -5039,14 +5005,22 @@ struct EHFlags { /// The default is /EHs-c-, meaning cleanups are disabled. static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) { EHFlags EH; - std::vector<std::string> EHArgs = Args.getAllArgValues(options::OPT__SLASH_EH); + std::vector<std::string> EHArgs = + Args.getAllArgValues(options::OPT__SLASH_EH); for (auto EHVal : EHArgs) { for (size_t I = 0, E = EHVal.size(); I != E; ++I) { switch (EHVal[I]) { - case 'a': EH.Asynch = maybeConsumeDash(EHVal, I); continue; - case 'c': EH.NoExceptC = maybeConsumeDash(EHVal, I); continue; - case 's': EH.Synch = maybeConsumeDash(EHVal, I); continue; - default: break; + case 'a': + EH.Asynch = maybeConsumeDash(EHVal, I); + continue; + case 'c': + EH.NoExceptC = maybeConsumeDash(EHVal, I); + continue; + case 's': + EH.Synch = maybeConsumeDash(EHVal, I); + continue; + default: + break; } D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal; break; @@ -5066,33 +5040,33 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const { if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) RTOptionID = A->getOption().getID(); - switch(RTOptionID) { - case options::OPT__SLASH_MD: - if (Args.hasArg(options::OPT__SLASH_LDd)) - CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); - CmdArgs.push_back("-D_DLL"); - CmdArgs.push_back("--dependent-lib=msvcrt"); - break; - case options::OPT__SLASH_MDd: + switch (RTOptionID) { + case options::OPT__SLASH_MD: + if (Args.hasArg(options::OPT__SLASH_LDd)) CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); - CmdArgs.push_back("-D_DLL"); - CmdArgs.push_back("--dependent-lib=msvcrtd"); - break; - case options::OPT__SLASH_MT: - if (Args.hasArg(options::OPT__SLASH_LDd)) - CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); - CmdArgs.push_back("--dependent-lib=libcmt"); - break; - case options::OPT__SLASH_MTd: + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-D_DLL"); + CmdArgs.push_back("--dependent-lib=msvcrt"); + break; + case options::OPT__SLASH_MDd: + CmdArgs.push_back("-D_DEBUG"); + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-D_DLL"); + CmdArgs.push_back("--dependent-lib=msvcrtd"); + break; + case options::OPT__SLASH_MT: + if (Args.hasArg(options::OPT__SLASH_LDd)) CmdArgs.push_back("-D_DEBUG"); - CmdArgs.push_back("-D_MT"); - CmdArgs.push_back("--dependent-lib=libcmtd"); - break; - default: - llvm_unreachable("Unexpected option ID."); + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("--dependent-lib=libcmt"); + break; + case options::OPT__SLASH_MTd: + CmdArgs.push_back("-D_DEBUG"); + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("--dependent-lib=libcmtd"); + break; + default: + llvm_unreachable("Unexpected option ID."); } // This provides POSIX compatibility (maps 'open' to '_open'), which most @@ -5176,9 +5150,9 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const { } } -visualstudio::Compile *Clang::getCLFallback() const { +visualstudio::Compiler *Clang::getCLFallback() const { if (!CLFallback) - CLFallback.reset(new visualstudio::Compile(getToolChain())); + CLFallback.reset(new visualstudio::Compiler(getToolChain())); return CLFallback.get(); } @@ -5194,8 +5168,7 @@ void ClangAs::AddMIPSTargetArgs(const ArgList &Args, } void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, + const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { ArgStringList CmdArgs; @@ -5217,8 +5190,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, // Add the "effective" target triple. CmdArgs.push_back("-triple"); - std::string TripleStr = - getToolChain().ComputeEffectiveClangTriple(Args, Input.getType()); + std::string TripleStr = + getToolChain().ComputeEffectiveClangTriple(Args, Input.getType()); CmdArgs.push_back(Args.MakeArgString(TripleStr)); // Set the output mode, we currently only expect to be used as a real @@ -5244,7 +5217,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, getTargetFeatures(D, Triple, Args, CmdArgs, true); // Ignore explicit -force_cpusubtype_ALL option. - (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); + (void)Args.hasArg(options::OPT_force__cpusubtype__ALL); + + // Pass along any -I options so we get proper .include search paths. + Args.AddAllArgs(CmdArgs, options::OPT_I_Group); // Determine the original source input. const Action *SourceAction = &JA; @@ -5288,9 +5264,9 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, SmallString<256> Flags; const char *Exec = getToolChain().getDriver().getClangProgramPath(); Flags += Exec; - for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) { + for (const char *OriginalArg : OriginalArgs) { SmallString<128> EscapedArg; - EscapeSpacesAndBackslashes(OriginalArgs[i], EscapedArg); + EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); Flags += " "; Flags += EscapedArg; } @@ -5301,7 +5277,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, // FIXME: Add -static support, once we have it. // Add target specific flags. - switch(getToolChain().getArch()) { + switch (getToolChain().getArch()) { default: break; @@ -5349,8 +5325,7 @@ void GnuTool::anchor() {} void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, + const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -5382,7 +5357,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getTriple().isOSDarwin()) { CmdArgs.push_back("-arch"); CmdArgs.push_back( - Args.MakeArgString(getToolChain().getDefaultUniversalArchName())); + Args.MakeArgString(getToolChain().getDefaultUniversalArchName())); } // Try to force gcc to match the tool chain we want, if we recognize @@ -5405,8 +5380,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsyntax-only"); } - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); // Only pass -x if gcc will understand it; otherwise hope gcc // understands the suffix correctly. The main use case this would go @@ -5421,13 +5395,12 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) D.Diag(diag::err_drv_no_linker_llvm_support) - << getToolChain().getTripleString(); + << getToolChain().getTripleString(); else if (II.getType() == types::TY_AST) - D.Diag(diag::err_drv_no_ast_support) - << getToolChain().getTripleString(); + D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString(); else if (II.getType() == types::TY_ModuleFile) D.Diag(diag::err_drv_no_module_support) - << getToolChain().getTripleString(); + << getToolChain().getTripleString(); if (types::canTypeBeUserSpecified(II.getType())) { CmdArgs.push_back("-x"); @@ -5459,18 +5432,17 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, } else GCCName = "gcc"; - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA, - ArgStringList &CmdArgs) const { +void gcc::Preprocessor::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const { CmdArgs.push_back("-E"); } -void gcc::Compile::RenderExtraToolArgs(const JobAction &JA, - ArgStringList &CmdArgs) const { +void gcc::Compiler::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); switch (JA.getType()) { @@ -5492,21 +5464,19 @@ void gcc::Compile::RenderExtraToolArgs(const JobAction &JA, } } -void gcc::Link::RenderExtraToolArgs(const JobAction &JA, - ArgStringList &CmdArgs) const { +void gcc::Linker::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const { // The types are (hopefully) good enough. } // Hexagon tools start. -void hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA, - ArgStringList &CmdArgs) const { - -} -void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const {} +void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); const Driver &D = getToolChain().getDriver(); @@ -5526,11 +5496,10 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsyntax-only"); } - if (const char* v = toolchains::Hexagon_TC::GetSmallDataThreshold(Args)) + if (const char *v = toolchains::Hexagon_TC::GetSmallDataThreshold(Args)) CmdArgs.push_back(Args.MakeArgString(std::string("-G") + v)); - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); // Only pass -x if gcc will understand it; otherwise hope gcc // understands the suffix correctly. The main use case this would go @@ -5545,18 +5514,19 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC) D.Diag(clang::diag::err_drv_no_linker_llvm_support) - << getToolChain().getTripleString(); + << getToolChain().getTripleString(); else if (II.getType() == types::TY_AST) D.Diag(clang::diag::err_drv_no_ast_support) - << getToolChain().getTripleString(); + << getToolChain().getTripleString(); else if (II.getType() == types::TY_ModuleFile) D.Diag(diag::err_drv_no_module_support) - << getToolChain().getTripleString(); + << getToolChain().getTripleString(); if (II.isFilename()) CmdArgs.push_back(II.getFilename()); else - // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ? + // Don't render as input, we need gcc to do the translations. + // FIXME: Pranav: What is this ? II.getInputArg().render(Args, CmdArgs); } @@ -5565,22 +5535,21 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void hexagon::Link::RenderExtraToolArgs(const JobAction &JA, - ArgStringList &CmdArgs) const { +void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const { // The types are (hopefully) good enough. } static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, - const toolchains::Hexagon_TC& ToolChain, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - ArgStringList &CmdArgs, - const char *LinkingOutput) { + const toolchains::Hexagon_TC &ToolChain, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + ArgStringList &CmdArgs, + const char *LinkingOutput) { const Driver &D = ToolChain.getDriver(); - //---------------------------------------------------------------------------- // //---------------------------------------------------------------------------- @@ -5624,7 +5593,7 @@ static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, if (buildPIE && !buildingLib) CmdArgs.push_back("-pie"); - if (const char* v = toolchains::Hexagon_TC::GetSmallDataThreshold(Args)) { + if (const char *v = toolchains::Hexagon_TC::GetSmallDataThreshold(Args)) { CmdArgs.push_back(Args.MakeArgString(std::string("-G") + v)); useG0 = toolchains::Hexagon_TC::UsesG0(v); } @@ -5640,15 +5609,14 @@ static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, const std::string MarchG0Suffix = MarchSuffix + G0Suffix; const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir, Args) + "/"; - const std::string StartFilesDir = RootDir - + "hexagon/lib" - + (useG0 ? MarchG0Suffix : MarchSuffix); + const std::string StartFilesDir = + RootDir + "hexagon/lib" + (useG0 ? MarchG0Suffix : MarchSuffix); //---------------------------------------------------------------------------- // moslib //---------------------------------------------------------------------------- std::vector<std::string> oslibs; - bool hasStandalone= false; + bool hasStandalone = false; for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) { A->claim(); @@ -5668,7 +5636,7 @@ static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, if (!buildingLib) { if (hasStandalone) { CmdArgs.push_back( - Args.MakeArgString(StartFilesDir + "/crt0_standalone.o")); + Args.MakeArgString(StartFilesDir + "/crt0_standalone.o")); } CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o")); } @@ -5706,9 +5674,8 @@ static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, CmdArgs.push_back("--start-group"); if (!buildingLib) { - for(std::vector<std::string>::iterator i = oslibs.begin(), - e = oslibs.end(); i != e; ++i) - CmdArgs.push_back(Args.MakeArgString("-l" + *i)); + for (const std::string &Lib : oslibs) + CmdArgs.push_back(Args.MakeArgString("-l" + Lib)); CmdArgs.push_back("-lc"); } CmdArgs.push_back("-lgcc"); @@ -5725,14 +5692,14 @@ static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, } } -void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { - const toolchains::Hexagon_TC& ToolChain = - static_cast<const toolchains::Hexagon_TC&>(getToolChain()); + const toolchains::Hexagon_TC &ToolChain = + static_cast<const toolchains::Hexagon_TC &>(getToolChain()); ArgStringList CmdArgs; constructHexagonLinkArgs(C, JA, ToolChain, Output, Inputs, Args, CmdArgs, @@ -5764,7 +5731,7 @@ const std::string arm::getARMArch(const ArgList &Args, const char *Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch); // If there is no valid architecture suffix for this CPU we don't know how // to handle it, so return no architecture. - if (strcmp(Suffix,"") == 0) + if (strcmp(Suffix, "") == 0) MArch = ""; else MArch = std::string("arm") + Suffix; @@ -5793,7 +5760,7 @@ const char *arm::getARMCPUForMArch(const ArgList &Args, /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. std::string arm::getARMTargetCPU(const ArgList &Args, - const llvm::Triple &Triple) { + const llvm::Triple &Triple) { // FIXME: Warn on inconsistent use of -mcpu and -march. // If we have -mcpu=, use that. if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { @@ -5822,7 +5789,7 @@ const char *arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch) { return llvm::ARMTargetParser::getSubArch(ArchKind); } -void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, +void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple) { if (Args.hasArg(options::OPT_r)) return; @@ -5866,14 +5833,14 @@ bool mips::isUCLibc(const ArgList &Args) { bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) { if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ)) return llvm::StringSwitch<bool>(NaNArg->getValue()) - .Case("2008", true) - .Case("legacy", false) - .Default(false); + .Case("2008", true) + .Case("legacy", false) + .Default(false); // NaN2008 is the default for MIPS32r6/MIPS64r6. return llvm::StringSwitch<bool>(getCPUName(Args, Triple)) - .Cases("mips32r6", "mips64r6", true) - .Default(false); + .Cases("mips32r6", "mips64r6", true) + .Default(false); return false; } @@ -5893,10 +5860,10 @@ bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, return false; return llvm::StringSwitch<bool>(CPUName) - .Cases("mips2", "mips3", "mips4", "mips5", true) - .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true) - .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true) - .Default(false); + .Cases("mips2", "mips3", "mips4", "mips5", true) + .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true) + .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true) + .Default(false); } bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple, @@ -5927,25 +5894,25 @@ llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) { // translation. return llvm::StringSwitch<llvm::Triple::ArchType>(Str) - .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc) - .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc) - .Case("ppc64", llvm::Triple::ppc64) - .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) - .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", - llvm::Triple::x86) - .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) - // This is derived from the driver driver. - .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) - .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm) - .Cases("armv7s", "xscale", llvm::Triple::arm) - .Case("arm64", llvm::Triple::aarch64) - .Case("r600", llvm::Triple::r600) - .Case("amdgcn", llvm::Triple::amdgcn) - .Case("nvptx", llvm::Triple::nvptx) - .Case("nvptx64", llvm::Triple::nvptx64) - .Case("amdil", llvm::Triple::amdil) - .Case("spir", llvm::Triple::spir) - .Default(llvm::Triple::UnknownArch); + .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc) + .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc) + .Case("ppc64", llvm::Triple::ppc64) + .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) + .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", + llvm::Triple::x86) + .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) + // This is derived from the driver driver. + .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) + .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm) + .Cases("armv7s", "xscale", llvm::Triple::arm) + .Case("arm64", llvm::Triple::aarch64) + .Case("r600", llvm::Triple::r600) + .Case("amdgcn", llvm::Triple::amdgcn) + .Case("nvptx", llvm::Triple::nvptx) + .Case("nvptx64", llvm::Triple::nvptx64) + .Case("amdil", llvm::Triple::amdil) + .Case("spir", llvm::Triple::spir) + .Default(llvm::Triple::UnknownArch); } void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) { @@ -5989,11 +5956,11 @@ const char *Clang::getDependencyFileName(const ArgList &Args, return Args.MakeArgString(Res + ".d"); } -void cloudabi::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const ToolChain &ToolChain = getToolChain(); const Driver &D = ToolChain.getDriver(); ArgStringList CmdArgs; @@ -6059,11 +6026,11 @@ void cloudabi::Link::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; assert(Inputs.size() == 1 && "Unexpected number of inputs."); @@ -6112,8 +6079,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, Args.hasArg(options::OPT_static))) CmdArgs.push_back("-static"); - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); assert(Output.isFilename() && "Unexpected lipo output."); CmdArgs.push_back("-o"); @@ -6124,8 +6090,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, // asm_final spec is empty. - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("as")); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } @@ -6144,7 +6109,7 @@ void darwin::MachOTool::AddMachOArch(const ArgList &Args, CmdArgs.push_back("-force_cpusubtype_ALL"); } -bool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const { +bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const { // We only need to generate a temp path for LTO if we aren't compiling object // files. When compiling source files, we run 'dsymutil' after linking. We // don't run 'dsymutil' when compiling object files. @@ -6155,21 +6120,19 @@ bool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const { return false; } -void darwin::Link::AddLinkArgs(Compilation &C, - const ArgList &Args, - ArgStringList &CmdArgs, - const InputInfoList &Inputs) const { +void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, + ArgStringList &CmdArgs, + const InputInfoList &Inputs) const { const Driver &D = getToolChain().getDriver(); const toolchains::MachO &MachOTC = getMachOToolChain(); - unsigned Version[3] = { 0, 0, 0 }; + unsigned Version[3] = {0, 0, 0}; if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { bool HadExtra; - if (!Driver::GetReleaseVersion(A->getValue(), Version[0], - Version[1], Version[2], HadExtra) || + if (!Driver::GetReleaseVersion(A->getValue(), Version[0], Version[1], + Version[2], HadExtra) || HadExtra) - D.Diag(diag::err_drv_invalid_version_number) - << A->getAsString(Args); + D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args); } // Newer linkers support -demangle. Pass it if supported and not disabled by @@ -6191,7 +6154,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, // dsymutil step. if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) { const char *TmpPath = C.getArgs().MakeArgString( - D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object))); + D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object))); C.addTempFile(TmpPath); CmdArgs.push_back("-object_path_lto"); CmdArgs.push_back(TmpPath); @@ -6219,8 +6182,8 @@ void darwin::Link::AddLinkArgs(Compilation &C, if ((A = Args.getLastArg(options::OPT_compatibility__version)) || (A = Args.getLastArg(options::OPT_current__version)) || (A = Args.getLastArg(options::OPT_install__name))) - D.Diag(diag::err_drv_argument_only_allowed_with) - << A->getAsString(Args) << "-dynamiclib"; + D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) + << "-dynamiclib"; Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); @@ -6235,8 +6198,8 @@ void darwin::Link::AddLinkArgs(Compilation &C, (A = Args.getLastArg(options::OPT_force__flat__namespace)) || (A = Args.getLastArg(options::OPT_keep__private__externs)) || (A = Args.getLastArg(options::OPT_private__bundle))) - D.Diag(diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-dynamiclib"; + D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) + << "-dynamiclib"; Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, "-dylib_compatibility_version"); @@ -6274,9 +6237,9 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); - if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, - options::OPT_fno_pie, - options::OPT_fno_PIE)) { + if (const Arg *A = + Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, + options::OPT_fno_pie, options::OPT_fno_PIE)) { if (A->getOption().matches(options::OPT_fpie) || A->getOption().matches(options::OPT_fPIE)) CmdArgs.push_back("-pie"); @@ -6335,11 +6298,11 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddLastArg(CmdArgs, options::OPT_Mach); } -void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { assert(Output.getType() == types::TY_Image && "Invalid linker output type."); // If the number of arguments surpasses the system limits, we will encode the @@ -6359,7 +6322,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, for (const auto &Arg : Args) Arg->claim(); const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("touch")); + Args.MakeArgString(getToolChain().GetProgramPath("touch")); CmdArgs.push_back(Output.getFilename()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); return; @@ -6437,8 +6400,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, InputFileList.push_back(II.getFilename()); } - if (isObjCRuntimeLinked(Args) && - !Args.hasArg(options::OPT_nostdlib) && + if (isObjCRuntimeLinked(Args) && !Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { // We use arclite library for both ARC and subscripting support. getMachOToolChain().AddLinkARCArgs(Args, CmdArgs); @@ -6496,10 +6458,9 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, } } - const char *Exec = - Args.MakeArgString(getToolChain().GetLinkerPath()); + const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); std::unique_ptr<Command> Cmd = - llvm::make_unique<Command>(JA, *this, Exec, CmdArgs); + llvm::make_unique<Command>(JA, *this, Exec, CmdArgs); Cmd->setInputFileList(std::move(InputFileList)); C.addCommand(std::move(Cmd)); } @@ -6542,7 +6503,7 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Input.getFilename()); const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); + Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } @@ -6565,11 +6526,11 @@ void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Input.getFilename()); const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); + Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA, +void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -6577,8 +6538,7 @@ void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA, claimNoWarnArgs(Args); ArgStringList CmdArgs; - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -6590,11 +6550,11 @@ void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { // FIXME: Find a real GCC, don't hard-code versions here std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/"; const llvm::Triple &T = getToolChain().getTriple(); @@ -6690,16 +6650,15 @@ void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA, addProfileRT(getToolChain(), Args, CmdArgs); - const char *Exec = - Args.MakeArgString(getToolChain().GetLinkerPath()); + const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; bool NeedsKPIC = false; @@ -6753,8 +6712,7 @@ void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, if (NeedsKPIC) addAssemblerKPIC(Args, CmdArgs); - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -6762,16 +6720,15 @@ void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, for (const auto &II : Inputs) CmdArgs.push_back(II.getFilename()); - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("as")); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -6822,25 +6779,25 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { - if (Args.hasArg(options::OPT_pg)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("gcrt0.o"))); + if (Args.hasArg(options::OPT_pg)) + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crt0.o"))); - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbegin.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crt0.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); } else { - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbeginS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); } } std::string Triple = getToolChain().getTripleString(); if (Triple.substr(0, 6) == "x86_64") Triple.replace(0, 6, "amd64"); - CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + - "/4.2.1")); + CmdArgs.push_back( + Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1")); Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); @@ -6856,7 +6813,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, !Args.hasArg(options::OPT_nodefaultlibs)) { if (D.CCCIsCXX()) { getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); - if (Args.hasArg(options::OPT_pg)) + if (Args.hasArg(options::OPT_pg)) CmdArgs.push_back("-lm_p"); else CmdArgs.push_back("-lm"); @@ -6867,18 +6824,17 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lgcc"); if (Args.hasArg(options::OPT_pthread)) { - if (!Args.hasArg(options::OPT_shared) && - Args.hasArg(options::OPT_pg)) - CmdArgs.push_back("-lpthread_p"); + if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg)) + CmdArgs.push_back("-lpthread_p"); else - CmdArgs.push_back("-lpthread"); + CmdArgs.push_back("-lpthread"); } if (!Args.hasArg(options::OPT_shared)) { if (Args.hasArg(options::OPT_pg)) - CmdArgs.push_back("-lc_p"); + CmdArgs.push_back("-lc_p"); else - CmdArgs.push_back("-lc"); + CmdArgs.push_back("-lc"); } CmdArgs.push_back("-lgcc"); @@ -6887,28 +6843,26 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtend.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtendS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); } - const char *Exec = - Args.MakeArgString(getToolChain().GetLinkerPath()); + const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void bitrig::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -6920,11 +6874,11 @@ void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void bitrig::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -6960,16 +6914,16 @@ void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { if (Args.hasArg(options::OPT_pg)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("gcrt0.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crt0.o"))); - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbegin.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crt0.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); } else { - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbeginS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); } } @@ -6990,8 +6944,7 @@ void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, } if (Args.hasArg(options::OPT_pthread)) { - if (!Args.hasArg(options::OPT_shared) && - Args.hasArg(options::OPT_pg)) + if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg)) CmdArgs.push_back("-lpthread_p"); else CmdArgs.push_back("-lpthread"); @@ -7024,23 +6977,22 @@ void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtend.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtendS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); } - const char *Exec = - Args.MakeArgString(getToolChain().GetLinkerPath()); + const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -7085,7 +7037,7 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-mfpu=softvfp"); } - switch(getToolChain().getTriple().getEnvironment()) { + switch (getToolChain().getTriple().getEnvironment()) { case llvm::Triple::GNUEABIHF: case llvm::Triple::GNUEABI: case llvm::Triple::EABI: @@ -7106,8 +7058,7 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, addAssemblerKPIC(Args, CmdArgs); } - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -7119,11 +7070,11 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const toolchains::FreeBSD &ToolChain = static_cast<const toolchains::FreeBSD &>(getToolChain()); const Driver &D = ToolChain.getDriver(); @@ -7298,12 +7249,11 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, addProfileRT(ToolChain, Args, CmdArgs); - const char *Exec = - Args.MakeArgString(getToolChain().GetLinkerPath()); + const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, +void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -7363,11 +7313,10 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, break; default: - break; + break; } - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -7379,11 +7328,11 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -7430,7 +7379,8 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: - arm::appendEBLinkFlags(Args, CmdArgs, + arm::appendEBLinkFlags( + Args, CmdArgs, llvm::Triple(getToolChain().ComputeEffectiveClangTriple(Args))); CmdArgs.push_back("-m"); switch (getToolChain().getTriple().getEnvironment()) { @@ -7455,14 +7405,14 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("elf32btsmip"); else CmdArgs.push_back("elf32ltsmip"); - } else if (mips::hasMipsAbiArg(Args, "64")) { - CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) - CmdArgs.push_back("elf64btsmip"); - else - CmdArgs.push_back("elf64ltsmip"); - } - break; + } else if (mips::hasMipsAbiArg(Args, "64")) { + CmdArgs.push_back("-m"); + if (getToolChain().getArch() == llvm::Triple::mips64) + CmdArgs.push_back("elf64btsmip"); + else + CmdArgs.push_back("elf64ltsmip"); + } + break; case llvm::Triple::ppc: CmdArgs.push_back("-m"); CmdArgs.push_back("elf32ppc_nbsd"); @@ -7498,17 +7448,17 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crt0.o"))); - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crti.o"))); - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbegin.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crt0.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); } else { - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crti.o"))); - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbeginS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); } } @@ -7526,7 +7476,7 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 49) || Major == 0) { - switch(getToolChain().getArch()) { + switch (getToolChain().getArch()) { case llvm::Triple::aarch64: case llvm::Triple::arm: case llvm::Triple::armeb: @@ -7574,13 +7524,12 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( - "crtend.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); else - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( - "crtendS.o"))); - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( - "crtn.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } addProfileRT(getToolChain(), Args, CmdArgs); @@ -7589,11 +7538,11 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -7668,8 +7617,8 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, // march from being picked in the absence of a cpu flag. Arg *A; if ((A = Args.getLastArg(options::OPT_mcpu_EQ)) && - StringRef(A->getValue()).lower() == "krait") - CmdArgs.push_back("-march=armv7-a"); + StringRef(A->getValue()).lower() == "krait") + CmdArgs.push_back("-march=armv7-a"); else Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ); @@ -7733,8 +7682,8 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of // -mno-mips16 is actually -no-mips16. - if (Arg *A = Args.getLastArg(options::OPT_mips16, - options::OPT_mno_mips16)) { + if (Arg *A = + Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) { if (A->getOption().matches(options::OPT_mips16)) { A->claim(); A->render(Args, CmdArgs); @@ -7780,8 +7729,7 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, if (NeedsKPIC) addAssemblerKPIC(Args, CmdArgs); - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -7909,7 +7857,8 @@ static void AddRunTimeLibs(const ToolChain &TC, const Driver &D, switch (RLT) { case ToolChain::RLT_CompilerRT: switch (TC.getTriple().getOS()) { - default: llvm_unreachable("unsupported OS"); + default: + llvm_unreachable("unsupported OS"); case llvm::Triple::Win32: case llvm::Triple::Linux: addClangRT(TC, Args, CmdArgs); @@ -7970,11 +7919,11 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { } } -void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const toolchains::Linux &ToolChain = static_cast<const toolchains::Linux &>(getToolChain()); const Driver &D = ToolChain.getDriver(); @@ -8048,7 +7997,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, !Args.hasArg(options::OPT_nostartfiles)) { if (!isAndroid) { const char *crt1 = nullptr; - if (!Args.hasArg(options::OPT_shared)){ + if (!Args.hasArg(options::OPT_shared)) { if (Args.hasArg(options::OPT_pg)) crt1 = "gcrt1.o"; else if (IsPIE) @@ -8096,11 +8045,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. addProfileRT(getToolChain(), Args, CmdArgs); - if (D.CCCIsCXX() && - !Args.hasArg(options::OPT_nostdlib) && + if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && - !Args.hasArg(options::OPT_static); + !Args.hasArg(options::OPT_static); if (OnlyLibstdcxxStatic) CmdArgs.push_back("-Bstatic"); ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); @@ -8181,37 +8129,35 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, llvm::make_unique<Command>(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); } - // NaCl ARM assembly (inline or standalone) can be written with a set of macros // for the various SFI requirements like register masking. The assembly tool // inserts the file containing the macros as an input into all the assembly // jobs. -void nacltools::AssembleARM::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { - const toolchains::NaCl_TC& ToolChain = - static_cast<const toolchains::NaCl_TC&>(getToolChain()); +void nacltools::AssemblerARM::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const toolchains::NaCl_TC &ToolChain = + static_cast<const toolchains::NaCl_TC &>(getToolChain()); InputInfo NaClMacros(ToolChain.GetNaClArmMacrosPath(), types::TY_PP_Asm, "nacl-arm-macros.s"); InputInfoList NewInputs; NewInputs.push_back(NaClMacros); NewInputs.append(Inputs.begin(), Inputs.end()); - gnutools::Assemble::ConstructJob(C, JA, Output, NewInputs, Args, - LinkingOutput); + gnutools::Assembler::ConstructJob(C, JA, Output, NewInputs, Args, + LinkingOutput); } - -// This is quite similar to gnutools::link::ConstructJob with changes that +// This is quite similar to gnutools::Linker::ConstructJob with changes that // we use static by default, do not yet support sanitizers or LTO, and a few // others. Eventually we can support more of that and hopefully migrate back -// to gnutools::link. -void nacltools::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +// to gnutools::Linker. +void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const toolchains::NaCl_TC &ToolChain = static_cast<const toolchains::NaCl_TC &>(getToolChain()); @@ -8293,11 +8239,10 @@ void nacltools::Link::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); - if (D.CCCIsCXX() && - !Args.hasArg(options::OPT_nostdlib) && + if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { - bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && - !IsStatic; + bool OnlyLibstdcxxStatic = + Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic; if (OnlyLibstdcxxStatic) CmdArgs.push_back("-Bstatic"); ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); @@ -8314,8 +8259,7 @@ void nacltools::Link::ConstructJob(Compilation &C, const JobAction &JA, // NaCl's libc++ currently requires libpthread, so just always include it // in the group for C++. if (Args.hasArg(options::OPT_pthread) || - Args.hasArg(options::OPT_pthreads) || - D.CCCIsCXX()) { + Args.hasArg(options::OPT_pthreads) || D.CCCIsCXX()) { CmdArgs.push_back("-lpthread"); } @@ -8341,16 +8285,15 @@ void nacltools::Link::ConstructJob(Compilation &C, const JobAction &JA, } } - C.addCommand(llvm::make_unique<Command>(JA, *this, - ToolChain.Linker.c_str(), CmdArgs)); + C.addCommand( + llvm::make_unique<Command>(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); } - -void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -8366,11 +8309,11 @@ void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -8383,10 +8326,11 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); - CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } Args.AddAllArgs(CmdArgs, options::OPT_L); @@ -8413,7 +8357,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lCompilerRT-Generic"); CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib"); CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); + Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); } const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); @@ -8424,11 +8368,11 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, // For now, DragonFly Assemble does just about the same as for // FreeBSD, but this may change soon. -void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -8449,11 +8393,11 @@ void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; bool UseGCC47 = llvm::sys::fs::exists("/usr/lib/gcc47"); @@ -8494,25 +8438,24 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { if (Args.hasArg(options::OPT_pg)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("gcrt1.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o"))); else { if (Args.hasArg(options::OPT_pie)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("Scrt1.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crt1.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); } } - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crti.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbeginS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtbegin.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); } Args.AddAllArgs(CmdArgs, options::OPT_L); @@ -8581,13 +8524,12 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtendS.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); else - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtend.o"))); - CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtn.o"))); + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } addProfileRT(getToolChain(), Args, CmdArgs); @@ -8616,18 +8558,18 @@ static std::string FindVisualStudioExecutable(const ToolChain &TC, return Exe; } -void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; const ToolChain &TC = getToolChain(); assert((Output.isFilename() || Output.isNothing()) && "invalid output"); if (Output.isFilename()) - CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + - Output.getFilename())); + CmdArgs.push_back( + Args.MakeArgString(std::string("-out:") + Output.getFilename())); if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles) && !C.getDriver().IsCLMode()) @@ -8671,16 +8613,14 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_g_Group)) CmdArgs.push_back("-debug"); - bool DLL = Args.hasArg(options::OPT__SLASH_LD, - options::OPT__SLASH_LDd, + bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd, options::OPT_shared); if (DLL) { CmdArgs.push_back(Args.MakeArgString("-dll")); SmallString<128> ImplibName(Output.getFilename()); llvm::sys::path::replace_extension(ImplibName, "lib"); - CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + - ImplibName)); + CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName)); } if (TC.getSanitizerArgs().needsAsanRt()) { @@ -8688,8 +8628,7 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-incremental:no")); if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) { static const char *CompilerRTComponents[] = { - "asan_dynamic", - "asan_dynamic_runtime_thunk", + "asan_dynamic", "asan_dynamic_runtime_thunk", }; for (const auto &Component : CompilerRTComponents) CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component))); @@ -8697,11 +8636,11 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, // to ensure proper SEH handling. CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor")); } else if (DLL) { - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk"))); + CmdArgs.push_back( + Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk"))); } else { static const char *CompilerRTComponents[] = { - "asan", - "asan_cxx", + "asan", "asan_cxx", }; for (const auto &Component : CompilerRTComponents) CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component))); @@ -8760,21 +8699,21 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput)); } -std::unique_ptr<Command> visualstudio::Compile::GetCommand( +std::unique_ptr<Command> visualstudio::Compiler::GetCommand( Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { ArgStringList CmdArgs; CmdArgs.push_back("/nologo"); - CmdArgs.push_back("/c"); // Compile only. + CmdArgs.push_back("/c"); // Compile only. CmdArgs.push_back("/W0"); // No warnings. // The goal is to be able to invoke this tool correctly based on @@ -8832,7 +8771,6 @@ std::unique_ptr<Command> visualstudio::Compile::GetCommand( options::OPT__SLASH_MT, options::OPT__SLASH_MTd)) A->render(Args, CmdArgs); - // Input filename. assert(Inputs.size() == 1); const InputInfo &II = Inputs[0]; @@ -8845,8 +8783,8 @@ std::unique_ptr<Command> visualstudio::Compile::GetCommand( // Output filename. assert(Output.getType() == types::TY_Object); - const char *Fo = Args.MakeArgString(std::string("/Fo") + - Output.getFilename()); + const char *Fo = + Args.MakeArgString(std::string("/Fo") + Output.getFilename()); CmdArgs.push_back(Fo); const Driver &D = getToolChain().getDriver(); @@ -8856,15 +8794,220 @@ std::unique_ptr<Command> visualstudio::Compile::GetCommand( CmdArgs); } +/// MinGW Tools +void MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + claimNoWarnArgs(Args); + ArgStringList CmdArgs; + + if (getToolChain().getArch() == llvm::Triple::x86) { + CmdArgs.push_back("--32"); + } else if (getToolChain().getArch() == llvm::Triple::x86_64) { + CmdArgs.push_back("--64"); + } + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + for (const auto &II : Inputs) + CmdArgs.push_back(II.getFilename()); + + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); + C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); + + if (Args.hasArg(options::OPT_gsplit_dwarf)) + SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, + SplitDebugName(Args, Inputs[0])); +} + +void MinGW::Linker::AddLibGCC(const ArgList &Args, + ArgStringList &CmdArgs) const { + if (Args.hasArg(options::OPT_mthreads)) + CmdArgs.push_back("-lmingwthrd"); + CmdArgs.push_back("-lmingw32"); + if (Args.hasArg(options::OPT_shared) || + Args.hasArg(options::OPT_shared_libgcc) || + !Args.hasArg(options::OPT_static_libgcc)) { + CmdArgs.push_back("-lgcc_s"); + CmdArgs.push_back("-lgcc"); + } else { + CmdArgs.push_back("-lgcc"); + CmdArgs.push_back("-lgcc_eh"); + } + CmdArgs.push_back("-lmoldname"); + CmdArgs.push_back("-lmingwex"); + CmdArgs.push_back("-lmsvcrt"); +} + +void MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &TC = getToolChain(); + const Driver &D = TC.getDriver(); + // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(); + + ArgStringList CmdArgs; + + // Silence warning for "clang -g foo.o -o foo" + Args.ClaimAllArgs(options::OPT_g_Group); + // and "clang -emit-llvm foo.o -o foo" + Args.ClaimAllArgs(options::OPT_emit_llvm); + // and for "clang -w foo.o -o foo". Other warning options are already + // handled somewhere else. + Args.ClaimAllArgs(options::OPT_w); + + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + + if (Args.hasArg(options::OPT_s)) + CmdArgs.push_back("-s"); + + CmdArgs.push_back("-m"); + if (TC.getArch() == llvm::Triple::x86) + CmdArgs.push_back("i386pe"); + if (TC.getArch() == llvm::Triple::x86_64) + CmdArgs.push_back("i386pep"); + + if (Args.hasArg(options::OPT_mwindows)) { + CmdArgs.push_back("--subsystem"); + CmdArgs.push_back("windows"); + } else if (Args.hasArg(options::OPT_mconsole)) { + CmdArgs.push_back("--subsystem"); + CmdArgs.push_back("console"); + } + + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("-Bstatic"); + else { + if (Args.hasArg(options::OPT_mdll)) + CmdArgs.push_back("--dll"); + else if (Args.hasArg(options::OPT_shared)) + CmdArgs.push_back("--shared"); + CmdArgs.push_back("-Bdynamic"); + if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-e"); + if (TC.getArch() == llvm::Triple::x86) + CmdArgs.push_back("_DllMainCRTStartup@12"); + else + CmdArgs.push_back("DllMainCRTStartup"); + CmdArgs.push_back("--enable-auto-image-base"); + } + } + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + Args.AddAllArgs(CmdArgs, options::OPT_e); + // FIXME: add -N, -n flags + Args.AddLastArg(CmdArgs, options::OPT_r); + Args.AddLastArg(CmdArgs, options::OPT_s); + Args.AddLastArg(CmdArgs, options::OPT_t); + Args.AddAllArgs(CmdArgs, options::OPT_u_Group); + Args.AddLastArg(CmdArgs, options::OPT_Z_Flag); + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) { + if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) { + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o"))); + } else { + if (Args.hasArg(options::OPT_municode)) + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o"))); + else + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o"))); + } + if (Args.hasArg(options::OPT_pg)) + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o"))); + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o"))); + } + + Args.AddAllArgs(CmdArgs, options::OPT_L); + const ToolChain::path_list Paths = TC.getFilePaths(); + for (const auto &Path : Paths) + CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path)); + + AddLinkerInputs(TC, Inputs, Args, CmdArgs); + + // TODO: Add ASan stuff here + + // TODO: Add profile stuff here + + if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nodefaultlibs)) { + bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && + !Args.hasArg(options::OPT_static); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bstatic"); + TC.AddCXXStdlibLibArgs(Args, CmdArgs); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bdynamic"); + } + + if (!Args.hasArg(options::OPT_nostdlib)) { + if (!Args.hasArg(options::OPT_nodefaultlibs)) { + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("--start-group"); + + if (Args.hasArg(options::OPT_fstack_protector) || + Args.hasArg(options::OPT_fstack_protector_strong) || + Args.hasArg(options::OPT_fstack_protector_all)) { + CmdArgs.push_back("-lssp_nonshared"); + CmdArgs.push_back("-lssp"); + } + if (Args.hasArg(options::OPT_fopenmp)) + CmdArgs.push_back("-lgomp"); + + AddLibGCC(Args, CmdArgs); + + if (Args.hasArg(options::OPT_pg)) + CmdArgs.push_back("-lgmon"); + + // FIXME: what to do about pthreads library? + // Currently required for OpenMP and posix-threading libgcc, + // does not exists in mingw.org. + //CmdArgs.push_back("-lpthread"); + + // add system libraries + if (Args.hasArg(options::OPT_mwindows)) { + CmdArgs.push_back("-lgdi32"); + CmdArgs.push_back("-lcomdlg32"); + } + CmdArgs.push_back("-ladvapi32"); + CmdArgs.push_back("-lshell32"); + CmdArgs.push_back("-luser32"); + CmdArgs.push_back("-lkernel32"); + + if (Args.hasArg(options::OPT_static)) + CmdArgs.push_back("--end-group"); + else + AddLibGCC(Args, CmdArgs); + } + + if (!Args.hasArg(options::OPT_nostartfiles)) { + // Add crtfastmath.o if available and fast math is enabled. + TC.AddFastMathRuntimeIfAvailable(Args, CmdArgs); + + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); + } + } + const char *Exec = Args.MakeArgString(TC.GetProgramPath("ld")); + C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); +} /// XCore Tools // We pass assemble and link construction to the xcc tool. -void XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -8884,8 +9027,7 @@ void XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fverbose-asm"); - Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, - options::OPT_Xassembler); + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); for (const auto &II : Inputs) CmdArgs.push_back(II.getFilename()); @@ -8894,11 +9036,11 @@ void XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void XCore::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; if (Output.isFilename()) { @@ -8920,11 +9062,11 @@ void XCore::Link::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void CrossWindows::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void CrossWindows::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { claimNoWarnArgs(Args); const auto &TC = static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain()); @@ -8932,7 +9074,8 @@ void CrossWindows::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec; switch (TC.getArch()) { - default: llvm_unreachable("unsupported architecture"); + default: + llvm_unreachable("unsupported architecture"); case llvm::Triple::arm: case llvm::Triple::thumb: break; @@ -8958,11 +9101,11 @@ void CrossWindows::Assemble::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void CrossWindows::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const auto &TC = static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain()); const llvm::Triple &T = TC.getTriple(); @@ -8991,7 +9134,8 @@ void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-m"); switch (TC.getArch()) { - default: llvm_unreachable("unsupported architecture"); + default: + llvm_unreachable("unsupported architecture"); case llvm::Triple::arm: case llvm::Triple::thumb: // FIXME: this is incorrect for WinCE @@ -9008,7 +9152,8 @@ void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_shared)) { switch (T.getArch()) { - default: llvm_unreachable("unsupported architecture"); + default: + llvm_unreachable("unsupported architecture"); case llvm::Triple::arm: case llvm::Triple::thumb: case llvm::Triple::x86_64: @@ -9098,11 +9243,11 @@ void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } -void tools::SHAVE::Compile::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; @@ -9143,12 +9288,11 @@ void tools::SHAVE::Compile::ConstructJob(Compilation &C, const JobAction &JA, llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), CmdArgs)); } -void tools::SHAVE::Assemble::ConstructJob(Compilation &C, - const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { +void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; assert(Inputs.size() == 1); diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 753f542622fe..52ab731cbc46 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -32,11 +32,14 @@ namespace toolchains { namespace tools { namespace visualstudio { - class Compile; +class Compiler; } using llvm::opt::ArgStringList; +SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component, + bool Shared = false); + /// \brief Clang compiler tool. class LLVM_LIBRARY_VISIBILITY Clang : public Tool { public: @@ -86,11 +89,14 @@ using llvm::opt::ArgStringList; void AddClangCLArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - visualstudio::Compile *getCLFallback() const; + visualstudio::Compiler *getCLFallback() const; - mutable std::unique_ptr<visualstudio::Compile> CLFallback; + mutable std::unique_ptr<visualstudio::Compiler> CLFallback; public: + // CAUTION! The first constructor argument ("clang") is not arbitrary, + // as it is for other tools. Some operations on a Tool actually test + // whether that tool is Clang based on the Tool's Name as a string. Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC, RF_Full) {} bool hasGoodDiagnostics() const override { return true; } @@ -124,7 +130,7 @@ using llvm::opt::ArgStringList; /// \brief Base class for all GNU tools that provide the same behavior when /// it comes to response files support - class GnuTool : public Tool { + class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool { virtual void anchor(); public: @@ -148,14 +154,14 @@ namespace gcc { /// RenderExtraToolArgs - Render any arguments necessary to force /// the particular tool mode. virtual void - RenderExtraToolArgs(const JobAction &JA, - llvm::opt::ArgStringList &CmdArgs) const = 0; + RenderExtraToolArgs(const JobAction &JA, + llvm::opt::ArgStringList &CmdArgs) const = 0; }; - class LLVM_LIBRARY_VISIBILITY Preprocess : public Common { + class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common { public: - Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", - "gcc preprocessor", TC) {} + Preprocessor(const ToolChain &TC) + : Common("gcc::Preprocessor", "gcc preprocessor", TC) {} bool hasGoodDiagnostics() const override { return true; } bool hasIntegratedCPP() const override { return false; } @@ -164,10 +170,10 @@ namespace gcc { llvm::opt::ArgStringList &CmdArgs) const override; }; - class LLVM_LIBRARY_VISIBILITY Compile : public Common { + class LLVM_LIBRARY_VISIBILITY Compiler : public Common { public: - Compile(const ToolChain &TC) : Common("gcc::Compile", - "gcc frontend", TC) {} + Compiler(const ToolChain &TC) + : Common("gcc::Compiler", "gcc frontend", TC) {} bool hasGoodDiagnostics() const override { return true; } bool hasIntegratedCPP() const override { return true; } @@ -176,10 +182,10 @@ namespace gcc { llvm::opt::ArgStringList &CmdArgs) const override; }; - class LLVM_LIBRARY_VISIBILITY Link : public Common { + class LLVM_LIBRARY_VISIBILITY Linker : public Common { public: - Link(const ToolChain &TC) : Common("gcc::Link", - "linker (via gcc)", TC) {} + Linker(const ToolChain &TC) + : Common("gcc::Linker", "linker (via gcc)", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -190,14 +196,15 @@ namespace gcc { } // end namespace gcc namespace hexagon { - // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile and Compile. - // We simply use "clang -cc1" for those actions. - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("hexagon::Assemble", - "hexagon-as", TC) {} +// For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile +// and Compile. +// We simply use "clang -cc1" for those actions. +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("hexagon::Assembler", "hexagon-as", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } void RenderExtraToolArgs(const JobAction &JA, llvm::opt::ArgStringList &CmdArgs) const; @@ -205,14 +212,13 @@ namespace hexagon { const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; - }; +}; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("hexagon::Link", - "hexagon-ld", TC) {} +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("hexagon::Linker", "hexagon-ld", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } virtual void RenderExtraToolArgs(const JobAction &JA, @@ -258,11 +264,11 @@ namespace ppc { bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value); } - /// cloudabi -- Directly call GNU Binutils linker +/// cloudabi -- Directly call GNU Binutils linker namespace cloudabi { -class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { public: - Link(const ToolChain &TC) : GnuTool("cloudabi::Link", "linker", TC) {} + Linker(const ToolChain &TC) : GnuTool("cloudabi::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -289,19 +295,19 @@ namespace darwin { } public: - MachOTool( - const char *Name, const char *ShortName, const ToolChain &TC, - ResponseFileSupport ResponseSupport = RF_None, - llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8, - const char *ResponseFlag = "@") - : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding, - ResponseFlag) {} + MachOTool( + const char *Name, const char *ShortName, const ToolChain &TC, + ResponseFileSupport ResponseSupport = RF_None, + llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8, + const char *ResponseFlag = "@") + : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding, + ResponseFlag) {} }; - class LLVM_LIBRARY_VISIBILITY Assemble : public MachOTool { + class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { public: - Assemble(const ToolChain &TC) : MachOTool("darwin::Assemble", - "assembler", TC) {} + Assembler(const ToolChain &TC) + : MachOTool("darwin::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -311,16 +317,16 @@ namespace darwin { const char *LinkingOutput) const override; }; - class LLVM_LIBRARY_VISIBILITY Link : public MachOTool { + class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { bool NeedsTempPath(const InputInfoList &Inputs) const; void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfoList &Inputs) const; public: - Link(const ToolChain &TC) : MachOTool("darwin::Link", "linker", TC, - RF_FileList, llvm::sys::WEM_UTF8, - "-filelist") {} + Linker(const ToolChain &TC) + : MachOTool("darwin::Linker", "linker", TC, RF_FileList, + llvm::sys::WEM_UTF8, "-filelist") {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -373,27 +379,26 @@ namespace darwin { } - /// openbsd -- Directly call GNU Binutils assembler and linker +/// openbsd -- Directly call GNU Binutils assembler and linker namespace openbsd { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("openbsd::Assemble", "assembler", - TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("openbsd::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("openbsd::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("openbsd::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -402,26 +407,26 @@ namespace openbsd { }; } // end namespace openbsd - /// bitrig -- Directly call GNU Binutils assembler and linker +/// bitrig -- Directly call GNU Binutils assembler and linker namespace bitrig { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("bitrig::Assemble", "assembler", - TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("bitrig::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("bitrig::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("bitrig::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -430,26 +435,26 @@ namespace bitrig { }; } // end namespace bitrig - /// freebsd -- Directly call GNU Binutils assembler and linker +/// freebsd -- Directly call GNU Binutils assembler and linker namespace freebsd { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("freebsd::Assemble", "assembler", - TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("freebsd::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("freebsd::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("freebsd::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -458,29 +463,28 @@ namespace freebsd { }; } // end namespace freebsd - /// netbsd -- Directly call GNU Binutils assembler and linker +/// netbsd -- Directly call GNU Binutils assembler and linker namespace netbsd { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { - public: - Assemble(const ToolChain &TC) - : GnuTool("netbsd::Assemble", "assembler", TC) {} +public: + Assembler(const ToolChain &TC) + : GnuTool("netbsd::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { - public: - Link(const ToolChain &TC) - : GnuTool("netbsd::Link", "linker", TC) {} +public: + Linker(const ToolChain &TC) : GnuTool("netbsd::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -489,26 +493,25 @@ namespace netbsd { }; } // end namespace netbsd - /// Directly call GNU Binutils' assembler and linker. +/// Directly call GNU Binutils' assembler and linker. namespace gnutools { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("GNU::Assemble", "assembler", TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("GNU::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, @@ -516,22 +519,21 @@ namespace gnutools { const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; }; -} + } -namespace nacltools { - class LLVM_LIBRARY_VISIBILITY AssembleARM : public gnutools::Assemble { + namespace nacltools { + class LLVM_LIBRARY_VISIBILITY AssemblerARM : public gnutools::Assembler { public: - AssembleARM(const ToolChain &TC) : gnutools::Assemble(TC) {} + AssemblerARM(const ToolChain &TC) : gnutools::Assembler(TC) {} void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, + const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; }; - class LLVM_LIBRARY_VISIBILITY Link : public Tool { + class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Link(const ToolChain &TC) : Tool("NaCl::Link", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("NaCl::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -544,27 +546,26 @@ namespace nacltools { }; } - /// minix -- Directly call GNU Binutils assembler and linker +/// minix -- Directly call GNU Binutils assembler and linker namespace minix { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("minix::Assemble", "assembler", - TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("minix::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("minix::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("minix::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, @@ -574,26 +575,26 @@ namespace minix { }; } // end namespace minix - /// solaris -- Directly call Solaris assembler and linker +/// solaris -- Directly call Solaris assembler and linker namespace solaris { - class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { - public: - Assemble(const ToolChain &TC) : Tool("solaris::Assemble", "assembler", - TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { +public: + Assembler(const ToolChain &TC) + : Tool("solaris::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public Tool { - public: - Link(const ToolChain &TC) : Tool("solaris::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("solaris::Linker", "linker", TC) {} - bool hasIntegratedCPP() const override { return false; } - bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -602,26 +603,26 @@ namespace solaris { }; } // end namespace solaris - /// dragonfly -- Directly call GNU Binutils assembler and linker +/// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { - class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool { - public: - Assemble(const ToolChain &TC) : GnuTool("dragonfly::Assemble", "assembler", - TC) {} +class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +public: + Assembler(const ToolChain &TC) + : GnuTool("dragonfly::Assembler", "assembler", TC) {} - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return false; } - void ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &TCArgs, - const char *LinkingOutput) const override; - }; - class LLVM_LIBRARY_VISIBILITY Link : public GnuTool { - public: - Link(const ToolChain &TC) : GnuTool("dragonfly::Link", "linker", TC) {} + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; |