179 changes: 47 additions & 132 deletions clang/lib/AST/DeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;

Expand Down Expand Up @@ -49,18 +50,6 @@ namespace {

void PrintObjCTypeParams(ObjCTypeParamList *Params);

enum class AttrPrintLoc {
None = 0,
Left = 1,
Right = 2,
Any = Left | Right,

LLVM_MARK_AS_BITMASK_ENUM(/*DefaultValue=*/Any)
};

void prettyPrintAttributes(Decl *D, raw_ostream &out,
AttrPrintLoc loc = AttrPrintLoc::Any);

public:
DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
const ASTContext &Context, unsigned Indentation = 0,
Expand Down Expand Up @@ -129,11 +118,10 @@ namespace {
const TemplateParameterList *Params);
void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args,
const TemplateParameterList *Params);

inline void prettyPrintAttributes(Decl *D) {
prettyPrintAttributes(D, Out);
}

enum class AttrPosAsWritten { Default = 0, Left, Right };
void
prettyPrintAttributes(const Decl *D,
AttrPosAsWritten Pos = AttrPosAsWritten::Default);
void prettyPrintPragmas(Decl *D);
void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
};
Expand Down Expand Up @@ -250,87 +238,48 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
return Out;
}

// For CLANG_ATTR_LIST_CanPrintOnLeft macro.
#include "clang/Basic/AttrLeftSideCanPrintList.inc"
static DeclPrinter::AttrPosAsWritten getPosAsWritten(const Attr *A,
const Decl *D) {
SourceLocation ALoc = A->getLoc();
SourceLocation DLoc = D->getLocation();
const ASTContext &C = D->getASTContext();
if (ALoc.isInvalid() || DLoc.isInvalid())
return DeclPrinter::AttrPosAsWritten::Left;

// For CLANG_ATTR_LIST_PrintOnLeft macro.
#include "clang/Basic/AttrLeftSideMustPrintList.inc"
if (C.getSourceManager().isBeforeInTranslationUnit(ALoc, DLoc))
return DeclPrinter::AttrPosAsWritten::Left;

static bool canPrintOnLeftSide(attr::Kind kind) {
#ifdef CLANG_ATTR_LIST_CanPrintOnLeft
switch (kind) {
CLANG_ATTR_LIST_CanPrintOnLeft
return true;
default:
return false;
}
#else
return false;
#endif
}

static bool canPrintOnLeftSide(const Attr *A) {
if (A->isStandardAttributeSyntax())
return false;

return canPrintOnLeftSide(A->getKind());
return DeclPrinter::AttrPosAsWritten::Right;
}

static bool mustPrintOnLeftSide(attr::Kind kind) {
#ifdef CLANG_ATTR_LIST_PrintOnLeft
switch (kind) {
CLANG_ATTR_LIST_PrintOnLeft
return true;
default:
return false;
}
#else
return false;
#endif
}

static bool mustPrintOnLeftSide(const Attr *A) {
if (A->isDeclspecAttribute())
return true;

return mustPrintOnLeftSide(A->getKind());
}

void DeclPrinter::prettyPrintAttributes(Decl *D, llvm::raw_ostream &Out,
AttrPrintLoc Loc) {
void DeclPrinter::prettyPrintAttributes(const Decl *D,
AttrPosAsWritten Pos /*=Default*/) {
if (Policy.PolishForDeclaration)
return;

if (D->hasAttrs()) {
AttrVec &Attrs = D->getAttrs();
const AttrVec &Attrs = D->getAttrs();
for (auto *A : Attrs) {
if (A->isInherited() || A->isImplicit())
continue;

AttrPrintLoc AttrLoc = AttrPrintLoc::Right;
if (mustPrintOnLeftSide(A)) {
// If we must always print on left side (e.g. declspec), then mark as
// so.
AttrLoc = AttrPrintLoc::Left;
} else if (canPrintOnLeftSide(A)) {
// For functions with body defined we print the attributes on the left
// side so that GCC accept our dumps as well.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
FD && FD->isThisDeclarationADefinition())
// In case Decl is a function with a body, then attrs should be print
// on the left side.
AttrLoc = AttrPrintLoc::Left;

// In case it is a variable declaration with a ctor, then allow
// printing on the left side for readbility.
else if (const VarDecl *VD = dyn_cast<VarDecl>(D);
VD && VD->getInit() &&
VD->getInitStyle() == VarDecl::CallInit)
AttrLoc = AttrPrintLoc::Left;
switch (A->getKind()) {
#define ATTR(X)
#define PRAGMA_SPELLING_ATTR(X) case attr::X:
#include "clang/Basic/AttrList.inc"
break;
default:
AttrPosAsWritten APos = getPosAsWritten(A, D);
assert(APos != AttrPosAsWritten::Default &&
"Default not a valid for an attribute location");
if (Pos == AttrPosAsWritten::Default || Pos == APos) {
if (Pos != AttrPosAsWritten::Left)
Out << ' ';
A->printPretty(Out, Policy);
if (Pos == AttrPosAsWritten::Left)
Out << ' ';
}
break;
}
// Only print the side matches the user requested.
if ((Loc & AttrLoc) != AttrPrintLoc::None)
A->printPretty(Out, Policy);
}
}
}
Expand Down Expand Up @@ -691,8 +640,10 @@ static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy,

void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (!D->getDescribedFunctionTemplate() &&
!D->isFunctionTemplateSpecialization())
!D->isFunctionTemplateSpecialization()) {
prettyPrintPragmas(D);
prettyPrintAttributes(D, AttrPosAsWritten::Left);
}

if (D->isFunctionTemplateSpecialization())
Out << "template<> ";
Expand All @@ -702,22 +653,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
printTemplateParameters(D->getTemplateParameterList(I));
}

std::string LeftsideAttrs;
llvm::raw_string_ostream LSAS(LeftsideAttrs);

prettyPrintAttributes(D, LSAS, AttrPrintLoc::Left);

// prettyPrintAttributes print a space on left side of the attribute.
if (LeftsideAttrs[0] == ' ') {
// Skip the space prettyPrintAttributes generated.
LeftsideAttrs.erase(0, LeftsideAttrs.find_first_not_of(' '));

// Add a single space between the attribute and the Decl name.
LSAS << ' ';
}

Out << LeftsideAttrs;

CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
Expand Down Expand Up @@ -883,7 +818,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Ty.print(Out, Policy, Proto);
}

prettyPrintAttributes(D, Out, AttrPrintLoc::Right);
prettyPrintAttributes(D, AttrPosAsWritten::Right);

if (D->isPureVirtual())
Out << " = 0";
Expand Down Expand Up @@ -976,27 +911,12 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
void DeclPrinter::VisitVarDecl(VarDecl *D) {
prettyPrintPragmas(D);

prettyPrintAttributes(D, AttrPosAsWritten::Left);

if (const auto *Param = dyn_cast<ParmVarDecl>(D);
Param && Param->isExplicitObjectParameter())
Out << "this ";

std::string LeftSide;
llvm::raw_string_ostream LeftSideStream(LeftSide);

// Print attributes that should be placed on the left, such as __declspec.
prettyPrintAttributes(D, LeftSideStream, AttrPrintLoc::Left);

// prettyPrintAttributes print a space on left side of the attribute.
if (LeftSide[0] == ' ') {
// Skip the space prettyPrintAttributes generated.
LeftSide.erase(0, LeftSide.find_first_not_of(' '));

// Add a single space between the attribute and the Decl name.
LeftSideStream << ' ';
}

Out << LeftSide;

QualType T = D->getTypeSourceInfo()
? D->getTypeSourceInfo()->getType()
: D->getASTContext().getUnqualifiedObjCPointerType(D->getType());
Expand Down Expand Up @@ -1029,21 +949,16 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
}
}

StringRef Name;

Name = (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
D->getIdentifier())
? D->getIdentifier()->deuglifiedName()
: D->getName();

if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
!Policy.SuppressUnwrittenScope)
MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out);
printDeclType(T, Name);

// Print the attributes that should be placed right before the end of the
// decl.
prettyPrintAttributes(D, Out, AttrPrintLoc::Right);
printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
D->getIdentifier())
? D->getIdentifier()->deuglifiedName()
: D->getName());

prettyPrintAttributes(D, AttrPosAsWritten::Right);

Expr *Init = D->getInit();
if (!Policy.SuppressInitializers && Init) {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,9 @@ static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,
if (const auto *Ref = T->getAs<ReferenceType>())
T = Ref->getPointeeType();

if (T.getQualifiers().hasUnaligned())
return CharUnits::One();

// __alignof is defined to return the preferred alignment.
// Before 8, clang returned the preferred alignment for alignof and
// _Alignof as well.
Expand Down
31 changes: 31 additions & 0 deletions clang/lib/AST/Interp/Disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,34 @@ LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS,
F = F->Caller;
}
}

LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation,
unsigned Offset) const {
unsigned Indent = Indentation * 2;
OS.indent(Indent);
{
ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
OS << getName() << "\n";
}

unsigned I = 0;
for (const Record::Base &B : bases()) {
OS.indent(Indent) << "- Base " << I << ". Offset " << (Offset + B.Offset)
<< "\n";
B.R->dump(OS, Indentation + 1, Offset + B.Offset);
++I;
}

// FIXME: Virtual bases.

I = 0;
for (const Record::Field &F : fields()) {
OS.indent(Indent) << "- Field " << I << ": ";
{
ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true});
OS << F.Decl->getName();
}
OS << ". Offset " << (Offset + F.Offset) << "\n";
++I;
}
}
26 changes: 26 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,18 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
return true;
}

for (const auto &P : {LHS, RHS}) {
if (P.isZero())
continue;
if (const ValueDecl *VD = P.getDeclDesc()->asValueDecl();
VD && VD->isWeak()) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_pointer_weak_comparison)
<< P.toDiagnosticString(S.getCtx());
return false;
}
}

if (!Pointer::hasSameBase(LHS, RHS)) {
S.Stk.push<BoolT>(BoolT::from(Fn(ComparisonCategoryResult::Unordered)));
return true;
Expand Down Expand Up @@ -1333,6 +1345,11 @@ inline bool FinishInit(InterpState &S, CodePtr OpPC) {
return true;
}

inline bool Dump(InterpState &S, CodePtr OpPC) {
S.Stk.dump();
return true;
}

inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl,
const Pointer &Ptr) {
Pointer Base = Ptr;
Expand Down Expand Up @@ -1841,6 +1858,15 @@ inline bool This(InterpState &S, CodePtr OpPC) {
if (!CheckThis(S, OpPC, This))
return false;

// Ensure the This pointer has been cast to the correct base.
if (!This.isDummy()) {
assert(isa<CXXMethodDecl>(S.Current->getFunction()->getDecl()));
assert(This.getRecord());
assert(
This.getRecord()->getDecl() ==
cast<CXXMethodDecl>(S.Current->getFunction()->getDecl())->getParent());
}

S.Stk.push<Pointer>(This);
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/Interp/Opcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -723,3 +723,8 @@ def CheckNonNullArg : Opcode {
}

def Memcpy : Opcode;

//===----------------------------------------------------------------------===//
// Debugging.
//===----------------------------------------------------------------------===//
def Dump : Opcode;
4 changes: 4 additions & 0 deletions clang/lib/AST/Interp/Pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ void Pointer::initialize() const {
if (isStatic() && Base == 0)
return;

// Nothing to do for these.
if (Desc->getNumElems() == 0)
return;

InitMapPtr &IM = getInitMap();
if (!IM)
IM =
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/AST/Interp/Record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "Record.h"
#include "clang/AST/ASTContext.h"

using namespace clang;
using namespace clang::interp;
Expand All @@ -27,6 +28,14 @@ Record::Record(const RecordDecl *Decl, BaseList &&SrcBases,
VirtualBaseMap[V.Decl] = &V;
}

const std::string Record::getName() const {
std::string Ret;
llvm::raw_string_ostream OS(Ret);
Decl->getNameForDiagnostic(OS, Decl->getASTContext().getPrintingPolicy(),
/*Qualified=*/true);
return Ret;
}

const Record::Field *Record::getField(const FieldDecl *FD) const {
auto It = FieldMap.find(FD);
assert(It != FieldMap.end() && "Missing field");
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/AST/Interp/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Record final {
/// Returns the underlying declaration.
const RecordDecl *getDecl() const { return Decl; }
/// Returns the name of the underlying declaration.
const std::string getName() const { return Decl->getNameAsString(); }
const std::string getName() const;
/// Checks if the record is a union.
bool isUnion() const { return getDecl()->isUnion(); }
/// Returns the size of the record.
Expand Down Expand Up @@ -100,6 +100,10 @@ class Record final {
unsigned getNumVirtualBases() const { return VirtualBases.size(); }
const Base *getVirtualBase(unsigned I) const { return &VirtualBases[I]; }

void dump(llvm::raw_ostream &OS, unsigned Indentation = 0,
unsigned Offset = 0) const;
void dump() const { dump(llvm::errs()); }

private:
/// Constructor used by Program to create record descriptors.
Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields,
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/AST/StmtPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,11 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
}

void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
for (const auto *Attr : Node->getAttrs()) {
llvm::ArrayRef<const Attr *> Attrs = Node->getAttrs();
for (const auto *Attr : Attrs) {
Attr->printPretty(OS, Policy);
if (Attr != Attrs.back())
OS << ' ';
}

PrintStmt(Node->getSubStmt(), 0);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,7 @@ void StmtProfiler::VisitMSPropertySubscriptExpr(
void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
VisitExpr(S);
ID.AddBoolean(S->isImplicit());
ID.AddBoolean(S->isCapturedByCopyInLambdaWithExplicitObjectParameter());
}

void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,8 +1194,11 @@ void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
case NOUR_Constant: OS << " non_odr_use_constant"; break;
case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
}
if (Node->refersToEnclosingVariableOrCapture())
if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
OS << " dependent_capture";
else if (Node->refersToEnclosingVariableOrCapture())
OS << " refers_to_enclosing_variable_or_capture";

if (Node->isImmediateEscalating())
OS << " immediate-escalating";
}
Expand Down Expand Up @@ -1351,6 +1354,8 @@ void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
if (Node->isImplicit())
OS << " implicit";
if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
OS << " dependent_capture";
OS << " this";
}

Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17288,6 +17288,16 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Value *Op1 = EmitScalarExpr(E->getArg(1));
Value *Op2 = EmitScalarExpr(E->getArg(2));
Value *Op3 = EmitScalarExpr(E->getArg(3));
// rldimi is 64-bit instruction, expand the intrinsic before isel to
// leverage peephole and avoid legalization efforts.
if (BuiltinID == PPC::BI__builtin_ppc_rldimi &&
!getTarget().getTriple().isPPC64()) {
Function *F = CGM.getIntrinsic(Intrinsic::fshl, Op0->getType());
Op2 = Builder.CreateZExt(Op2, Int64Ty);
Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2});
return Builder.CreateOr(Builder.CreateAnd(Shift, Op3),
Builder.CreateAnd(Op1, Builder.CreateNot(Op3)));
}
return Builder.CreateCall(
CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi
? Intrinsic::ppc_rldimi
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,13 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
std::optional<std::string> ToolChain::getRuntimePath() const {
SmallString<128> P(D.ResourceDir);
llvm::sys::path::append(P, "lib");
return getTargetSubDirPath(P);
if (auto Ret = getTargetSubDirPath(P))
return Ret;
// Darwin does not use per-target runtime directory.
if (Triple.isOSDarwin())
return {};
llvm::sys::path::append(P, Triple.str());
return std::string(P);
}

std::optional<std::string> ToolChain::getStdlibPath() const {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
return "BuildingBuiltinDumpStructCall";
case CodeSynthesisContext::BuildingDeductionGuides:
return "BuildingDeductionGuides";
case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
return "TypeAliasTemplateInstantiation";
}
return "";
Expand Down
5 changes: 1 addition & 4 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,10 +720,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
if (LangOpts.CPlusPlus20) {
Builder.defineMacro("__cpp_aggregate_paren_init", "201902L");

// P0848 is implemented, but we're still waiting for other concepts
// issues to be addressed before bumping __cpp_concepts up to 202002L.
// Refer to the discussion of this at https://reviews.llvm.org/D128619.
Builder.defineMacro("__cpp_concepts", "201907L");
Builder.defineMacro("__cpp_concepts", "202002");
Builder.defineMacro("__cpp_conditional_explicit", "201806L");
Builder.defineMacro("__cpp_consteval", "202211L");
Builder.defineMacro("__cpp_constexpr_dynamic_alloc", "201907L");
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5232,7 +5232,6 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_ppc_fetch_and_andlp:
case PPC::BI__builtin_ppc_fetch_and_orlp:
case PPC::BI__builtin_ppc_fetch_and_swaplp:
case PPC::BI__builtin_ppc_rldimi:
return true;
}
return false;
Expand Down
55 changes: 40 additions & 15 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3442,10 +3442,11 @@ static bool ShouldLookupResultBeMultiVersionOverload(const LookupResult &R) {

ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
LookupResult &R, bool NeedsADL,
bool AcceptInvalidDecl) {
bool AcceptInvalidDecl,
bool NeedUnresolved) {
// If this is a single, fully-resolved result and we don't need ADL,
// just build an ordinary singleton decl ref.
if (!NeedsADL && R.isSingleResult() &&
if (!NeedUnresolved && !NeedsADL && R.isSingleResult() &&
!R.getAsSingle<FunctionTemplateDecl>() &&
!ShouldLookupResultBeMultiVersionOverload(R))
return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(),
Expand Down Expand Up @@ -18981,8 +18982,10 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
// Note that we skip the implicit instantiation of templates that are only
// used in unused default arguments or by recursive calls to themselves.
// This is formally non-conforming, but seems reasonable in practice.
bool NeedDefinition = !IsRecursiveCall && (OdrUse == OdrUseContext::Used ||
NeededForConstantEvaluation);
bool NeedDefinition =
!IsRecursiveCall &&
(OdrUse == OdrUseContext::Used ||
(NeededForConstantEvaluation && !Func->isPureVirtual()));

// C++14 [temp.expl.spec]p6:
// If a template [...] is explicitly specialized then that specialization
Expand Down Expand Up @@ -20719,20 +20722,42 @@ void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {
static void FixDependencyOfIdExpressionsInLambdaWithDependentObjectParameter(
Sema &SemaRef, ValueDecl *D, Expr *E) {
auto *ID = dyn_cast<DeclRefExpr>(E);
if (!ID || ID->isTypeDependent())
if (!ID || ID->isTypeDependent() || !ID->refersToEnclosingVariableOrCapture())
return;

// If any enclosing lambda with a dependent explicit object parameter either
// explicitly captures the variable by value, or has a capture default of '='
// and does not capture the variable by reference, then the type of the DRE
// is dependent on the type of that lambda's explicit object parameter.
auto IsDependent = [&]() {
const LambdaScopeInfo *LSI = SemaRef.getCurLambda();
if (!LSI)
return false;
if (!LSI->ExplicitObjectParameter ||
!LSI->ExplicitObjectParameter->getType()->isDependentType())
return false;
if (!LSI->CaptureMap.count(D))
return false;
const Capture &Cap = LSI->getCapture(D);
return !Cap.isCopyCapture();
for (auto *Scope : llvm::reverse(SemaRef.FunctionScopes)) {
auto *LSI = dyn_cast<sema::LambdaScopeInfo>(Scope);
if (!LSI)
continue;

if (LSI->Lambda && !LSI->Lambda->Encloses(SemaRef.CurContext) &&
LSI->AfterParameterList)
return false;

const auto *MD = LSI->CallOperator;
if (MD->getType().isNull())
continue;

const auto *Ty = cast<FunctionProtoType>(MD->getType());
if (!Ty || !MD->isExplicitObjectMemberFunction() ||
!Ty->getParamType(0)->isDependentType())
continue;

if (auto *C = LSI->CaptureMap.count(D) ? &LSI->getCapture(D) : nullptr) {
if (C->isCopyCapture())
return true;
continue;
}

if (LSI->ImpCaptureStyle == LambdaScopeInfo::ImpCap_LambdaByval)
return true;
}
return false;
}();

ID->setCapturedByCopyInLambdaWithExplicitObjectParameter(
Expand Down
99 changes: 77 additions & 22 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,26 +1415,42 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
}

ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
/// C++ 9.3.2: In the body of a non-static member function, the keyword this
/// is a non-lvalue expression whose value is the address of the object for
/// which the function is called.
// C++20 [expr.prim.this]p1:
// The keyword this names a pointer to the object for which an
// implicit object member function is invoked or a non-static
// data member's initializer is evaluated.
QualType ThisTy = getCurrentThisType();

if (ThisTy.isNull()) {
DeclContext *DC = getFunctionLevelDeclContext();
if (CheckCXXThisType(Loc, ThisTy))
return ExprError();

if (const auto *Method = dyn_cast<CXXMethodDecl>(DC);
Method && Method->isExplicitObjectMemberFunction()) {
return Diag(Loc, diag::err_invalid_this_use) << 1;
}
return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
}

if (isLambdaCallWithExplicitObjectParameter(CurContext))
return Diag(Loc, diag::err_invalid_this_use) << 1;
bool Sema::CheckCXXThisType(SourceLocation Loc, QualType Type) {
if (!Type.isNull())
return false;

return Diag(Loc, diag::err_invalid_this_use) << 0;
// C++20 [expr.prim.this]p3:
// If a declaration declares a member function or member function template
// of a class X, the expression this is a prvalue of type
// "pointer to cv-qualifier-seq X" wherever X is the current class between
// the optional cv-qualifier-seq and the end of the function-definition,
// member-declarator, or declarator. It shall not appear within the
// declaration of either a static member function or an explicit object
// member function of the current class (although its type and value
// category are defined within such member functions as they are within
// an implicit object member function).
DeclContext *DC = getFunctionLevelDeclContext();
if (const auto *Method = dyn_cast<CXXMethodDecl>(DC);
Method && Method->isExplicitObjectMemberFunction()) {
Diag(Loc, diag::err_invalid_this_use) << 1;
} else if (isLambdaCallWithExplicitObjectParameter(CurContext)) {
Diag(Loc, diag::err_invalid_this_use) << 1;
} else {
Diag(Loc, diag::err_invalid_this_use) << 0;
}

return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
return true;
}

Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
Expand All @@ -1446,6 +1462,42 @@ Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,

void Sema::MarkThisReferenced(CXXThisExpr *This) {
CheckCXXThisCapture(This->getExprLoc());
if (This->isTypeDependent())
return;

// Check if 'this' is captured by value in a lambda with a dependent explicit
// object parameter, and mark it as type-dependent as well if so.
auto IsDependent = [&]() {
for (auto *Scope : llvm::reverse(FunctionScopes)) {
auto *LSI = dyn_cast<sema::LambdaScopeInfo>(Scope);
if (!LSI)
continue;

if (LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
LSI->AfterParameterList)
return false;

// If this lambda captures 'this' by value, then 'this' is dependent iff
// this lambda has a dependent explicit object parameter. If we can't
// determine whether it does (e.g. because the CXXMethodDecl's type is
// null), assume it doesn't.
if (LSI->isCXXThisCaptured()) {
if (!LSI->getCXXThisCapture().isCopyCapture())
continue;

const auto *MD = LSI->CallOperator;
if (MD->getType().isNull())
return false;

const auto *Ty = cast<FunctionProtoType>(MD->getType());
return Ty && MD->isExplicitObjectMemberFunction() &&
Ty->getParamType(0)->isDependentType();
}
}
return false;
}();

This->setCapturedByCopyInLambdaWithExplicitObjectParameter(IsDependent);
}

bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
Expand Down Expand Up @@ -5566,8 +5618,8 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
}
}

static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
QualType RhsT, SourceLocation KeyLoc);
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs,
const TypeSourceInfo *Rhs, SourceLocation KeyLoc);

static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
SourceLocation KWLoc,
Expand All @@ -5583,8 +5635,8 @@ static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
// Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
// alongside the IsConstructible traits to avoid duplication.
if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary && Kind != BTT_ReferenceConstructsFromTemporary)
return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
Args[1]->getType(), RParenLoc);
return EvaluateBinaryTypeTrait(S, Kind, Args[0],
Args[1], RParenLoc);

switch (Kind) {
case clang::BTT_ReferenceBindsToTemporary:
Expand Down Expand Up @@ -5679,8 +5731,8 @@ static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
if (U->isReferenceType())
return false;

QualType TPtr = S.Context.getPointerType(S.BuiltinRemoveReference(T, UnaryTransformType::RemoveCVRef, {}));
QualType UPtr = S.Context.getPointerType(S.BuiltinRemoveReference(U, UnaryTransformType::RemoveCVRef, {}));
TypeSourceInfo *TPtr = S.Context.CreateTypeSourceInfo(S.Context.getPointerType(S.BuiltinRemoveReference(T, UnaryTransformType::RemoveCVRef, {})));
TypeSourceInfo *UPtr = S.Context.CreateTypeSourceInfo(S.Context.getPointerType(S.BuiltinRemoveReference(U, UnaryTransformType::RemoveCVRef, {})));
return EvaluateBinaryTypeTrait(S, TypeTrait::BTT_IsConvertibleTo, UPtr, TPtr, RParenLoc);
}

Expand Down Expand Up @@ -5814,8 +5866,11 @@ ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
}

static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
QualType RhsT, SourceLocation KeyLoc) {
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs,
const TypeSourceInfo *Rhs, SourceLocation KeyLoc) {
QualType LhsT = Lhs->getType();
QualType RhsT = Rhs->getType();

assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
"Cannot evaluate traits of dependent types");

Expand Down
42 changes: 30 additions & 12 deletions clang/lib/Sema/SemaExprMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ enum IMAKind {
/// The reference is a contextually-permitted abstract member reference.
IMA_Abstract,

/// Whether the context is static is dependent on the enclosing template (i.e.
/// in a dependent class scope explicit specialization).
IMA_Dependent,

/// The reference may be to an unresolved using declaration and the
/// context is not an instance method.
IMA_Unresolved_StaticOrExplicitContext,
Expand Down Expand Up @@ -91,10 +95,18 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,

DeclContext *DC = SemaRef.getFunctionLevelDeclContext();

bool isStaticOrExplicitContext =
SemaRef.CXXThisTypeOverride.isNull() &&
(!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic() ||
cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction());
bool couldInstantiateToStatic = false;
bool isStaticOrExplicitContext = SemaRef.CXXThisTypeOverride.isNull();

if (auto *MD = dyn_cast<CXXMethodDecl>(DC)) {
if (MD->isImplicitObjectMemberFunction()) {
isStaticOrExplicitContext = false;
// A dependent class scope function template explicit specialization
// that is neither declared 'static' nor with an explicit object
// parameter could instantiate to a static or non-static member function.
couldInstantiateToStatic = MD->getDependentSpecializationInfo();
}
}

if (R.isUnresolvableResult())
return isStaticOrExplicitContext ? IMA_Unresolved_StaticOrExplicitContext
Expand Down Expand Up @@ -123,6 +135,9 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
if (Classes.empty())
return IMA_Static;

if (couldInstantiateToStatic)
return IMA_Dependent;

// C++11 [expr.prim.general]p12:
// An id-expression that denotes a non-static data member or non-static
// member function of a class can only be used:
Expand Down Expand Up @@ -268,27 +283,30 @@ ExprResult Sema::BuildPossibleImplicitMemberExpr(
const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
UnresolvedLookupExpr *AsULE) {
switch (ClassifyImplicitMemberAccess(*this, R)) {
switch (IMAKind Classification = ClassifyImplicitMemberAccess(*this, R)) {
case IMA_Instance:
return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, S);

case IMA_Mixed:
case IMA_Mixed_Unrelated:
case IMA_Unresolved:
return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
S);

return BuildImplicitMemberExpr(
SS, TemplateKWLoc, R, TemplateArgs,
/*IsKnownInstance=*/Classification == IMA_Instance, S);
case IMA_Field_Uneval_Context:
Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
<< R.getLookupNameInfo().getName();
[[fallthrough]];
case IMA_Static:
case IMA_Abstract:
case IMA_Dependent:
case IMA_Mixed_StaticOrExplicitContext:
case IMA_Unresolved_StaticOrExplicitContext:
if (TemplateArgs || TemplateKWLoc.isValid())
return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
return AsULE ? AsULE : BuildDeclarationNameExpr(SS, R, false);
return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*RequiresADL=*/false,
TemplateArgs);
return AsULE ? AsULE
: BuildDeclarationNameExpr(
SS, R, /*NeedsADL=*/false, /*AcceptInvalidDecl=*/false,
/*NeedUnresolved=*/Classification == IMA_Dependent);

case IMA_Error_StaticOrExplicitContext:
case IMA_Error_Unrelated:
Expand Down
13 changes: 5 additions & 8 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,11 @@ bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,

bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
OpenACCClauseKind ClauseKind) {
switch (ClauseKind) {
// FIXME: For each clause as we implement them, we can add the
// 'legalization' list here.
default:
// Do nothing so we can go to the 'unimplemented' diagnostic instead.
return true;
}
llvm_unreachable("Invalid clause kind");
// FIXME: For each clause as we implement them, we can add the
// 'legalization' list here.

// Do nothing so we can go to the 'unimplemented' diagnostic instead.
return true;
}
} // namespace

Expand Down
10 changes: 4 additions & 6 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4494,15 +4494,13 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
AliasTemplate->getTemplateParameters()->getDepth());

LocalInstantiationScope Scope(*this);
InstantiatingTemplate Inst(*this, TemplateLoc, Template);
InstantiatingTemplate Inst(
*this, /*PointOfInstantiation=*/TemplateLoc,
/*Entity=*/AliasTemplate,
/*TemplateArgs=*/TemplateArgLists.getInnermost());
if (Inst.isInvalid())
return QualType();

InstantiatingTemplate InstTemplate(
*this, /*PointOfInstantiation=*/AliasTemplate->getBeginLoc(),
/*Template=*/AliasTemplate,
/*TemplateArgs=*/TemplateArgLists.getInnermost());

std::optional<ContextRAII> SavedContext;
if (!AliasTemplate->getDeclContext()->isFileContext())
SavedContext.emplace(*this, AliasTemplate->getDeclContext());
Expand Down
19 changes: 9 additions & 10 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,11 +737,11 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(

Sema::InstantiatingTemplate::InstantiatingTemplate(
Sema &SemaRef, SourceLocation PointOfInstantiation,
TypeAliasTemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
TypeAliasTemplateDecl *Entity, ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange)
: InstantiatingTemplate(
SemaRef, Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation,
PointOfInstantiation, InstantiationRange, /*Entity=*/Template,
SemaRef, CodeSynthesisContext::TypeAliasTemplateInstantiation,
PointOfInstantiation, InstantiationRange, /*Entity=*/Entity,
/*Template=*/nullptr, TemplateArgs) {}

Sema::InstantiatingTemplate::InstantiatingTemplate(
Expand Down Expand Up @@ -983,11 +983,6 @@ void Sema::PrintInstantiationStack() {
Diags.Report(Active->PointOfInstantiation,
diag::note_template_class_instantiation_here)
<< CTD << Active->InstantiationRange;
} else {
Diags.Report(Active->PointOfInstantiation,
diag::note_template_type_alias_instantiation_here)
<< cast<TypeAliasTemplateDecl>(D)
<< Active->InstantiationRange;
}
break;
}
Expand Down Expand Up @@ -1262,6 +1257,10 @@ void Sema::PrintInstantiationStack() {
diag::note_building_deduction_guide_here);
break;
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
Diags.Report(Active->PointOfInstantiation,
diag::note_template_type_alias_instantiation_here)
<< cast<TypeAliasTemplateDecl>(Active->Entity)
<< Active->InstantiationRange;
break;
}
}
Expand All @@ -1278,12 +1277,13 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
++Active)
{
switch (Active->Kind) {
case CodeSynthesisContext::TemplateInstantiation:
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
// An instantiation of an alias template may or may not be a SFINAE
// context, depending on what else is on the stack.
if (isa<TypeAliasTemplateDecl>(Active->Entity))
break;
[[fallthrough]];
case CodeSynthesisContext::TemplateInstantiation:
case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
case CodeSynthesisContext::ExceptionSpecInstantiation:
case CodeSynthesisContext::ConstraintsCheck:
Expand Down Expand Up @@ -1340,7 +1340,6 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
break;

case CodeSynthesisContext::Memoization:
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
break;
}

Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,8 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
: (TemplateArgs.begin() + TemplateArgs.getNumLevels() - 1 -
D->getTemplateDepth())
->Args);
if (InstTemplate.isInvalid())
return nullptr;

TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) {
Expand Down Expand Up @@ -5091,6 +5093,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
EnterExpressionEvaluationContext EvalContext(
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);

Qualifiers ThisTypeQuals;
CXXRecordDecl *ThisContext = nullptr;
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
ThisContext = Method->getParent();
ThisTypeQuals = Method->getMethodQualifiers();
}
CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals);

// Introduce a new scope where local variable instantiations will be
// recorded, unless we're actually a member function within a local
// class, in which case we need to merge our results with the parent
Expand Down
25 changes: 17 additions & 8 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -3307,12 +3307,13 @@ class TreeTransform {

/// Build a new C++ "this" expression.
///
/// By default, builds a new "this" expression without performing any
/// semantic analysis. Subclasses may override this routine to provide
/// different behavior.
/// By default, performs semantic analysis to build a new "this" expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
QualType ThisType,
bool isImplicit) {
if (getSema().CheckCXXThisType(ThisLoc, ThisType))
return ExprError();
return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
}

Expand Down Expand Up @@ -11177,8 +11178,8 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
}

if (!getDerived().AlwaysRebuild() &&
QualifierLoc == E->getQualifierLoc() &&
ND == E->getDecl() &&
!E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
Found == E->getFoundDecl() &&
NameInfo.getName() == E->getDecl()->getDeclName() &&
!E->hasExplicitTemplateArgs()) {
Expand Down Expand Up @@ -12641,9 +12642,17 @@ TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
//
// In other contexts, the type of `this` may be overrided
// for type deduction, so we need to recompute it.
QualType T = getSema().getCurLambda() ?
getDerived().TransformType(E->getType())
: getSema().getCurrentThisType();
//
// Always recompute the type if we're in the body of a lambda, and
// 'this' is dependent on a lambda's explicit object parameter.
QualType T = [&]() {
auto &S = getSema();
if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
return S.getCurrentThisType();
if (S.getCurLambda())
return getDerived().TransformType(E->getType());
return S.getCurrentThisType();
}();

if (!getDerived().AlwaysRebuild() && T == E->getType()) {
// Mark it referenced in the new context regardless.
Expand Down
21 changes: 6 additions & 15 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ namespace clang {
GlobalDeclID NamedDeclForTagDecl = 0;
IdentifierInfo *TypedefNameForLinkage = nullptr;

bool HasPendingBody = false;

///A flag to carry the information for a decl from the entity is
/// used. We use it to delay the marking of the canonical decl as used until
/// the entire declaration is deserialized and merged.
Expand Down Expand Up @@ -314,9 +312,6 @@ namespace clang {
static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
static void markIncompleteDeclChainImpl(...);

/// Determine whether this declaration has a pending body.
bool hasPendingBody() const { return HasPendingBody; }

void ReadFunctionDefinition(FunctionDecl *FD);
void Visit(Decl *D);

Expand Down Expand Up @@ -541,7 +536,6 @@ void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
}
// Store the offset of the body so we can lazily load it later.
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
HasPendingBody = true;
}

void ASTDeclReader::Visit(Decl *D) {
Expand Down Expand Up @@ -1164,7 +1158,6 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
// Load the body on-demand. Most clients won't care, because method
// definitions rarely show up in headers.
Reader.PendingBodies[MD] = GetCurrentCursorOffset();
HasPendingBody = true;
}
MD->setSelfDecl(readDeclAs<ImplicitParamDecl>());
MD->setCmdDecl(readDeclAs<ImplicitParamDecl>());
Expand Down Expand Up @@ -4156,8 +4149,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// AST consumer might need to know about, queue it.
// We don't pass it to the consumer immediately because we may be in recursive
// loading, and some declarations may still be initializing.
PotentiallyInterestingDecls.push_back(
InterestingDecl(D, Reader.hasPendingBody()));
PotentiallyInterestingDecls.push_back(D);

return D;
}
Expand All @@ -4179,10 +4171,10 @@ void ASTReader::PassInterestingDeclsToConsumer() {
EagerlyDeserializedDecls.clear();

while (!PotentiallyInterestingDecls.empty()) {
InterestingDecl D = PotentiallyInterestingDecls.front();
Decl *D = PotentiallyInterestingDecls.front();
PotentiallyInterestingDecls.pop_front();
if (isConsumerInterestedIn(getContext(), D.getDecl(), D.hasPendingBody()))
PassInterestingDeclToConsumer(D.getDecl());
if (isConsumerInterestedIn(getContext(), D, PendingBodies.count(D)))
PassInterestingDeclToConsumer(D);
}
}

Expand Down Expand Up @@ -4239,9 +4231,8 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
// We might have made this declaration interesting. If so, remember that
// we need to hand it off to the consumer.
if (!WasInteresting &&
isConsumerInterestedIn(getContext(), D, Reader.hasPendingBody())) {
PotentiallyInterestingDecls.push_back(
InterestingDecl(D, Reader.hasPendingBody()));
isConsumerInterestedIn(getContext(), D, PendingBodies.count(D))) {
PotentiallyInterestingDecls.push_back(D);
WasInteresting = true;
}
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,7 @@ void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
VisitExpr(E);
E->setLocation(readSourceLocation());
E->setImplicit(Record.readInt());
E->setCapturedByCopyInLambdaWithExplicitObjectParameter(Record.readInt());
}

void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,7 @@ void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
VisitExpr(E);
Record.AddSourceLocation(E->getLocation());
Record.push_back(E->isImplicit());
Record.push_back(E->isCapturedByCopyInLambdaWithExplicitObjectParameter());

Code = serialization::EXPR_CXX_THIS;
}
Expand Down
16 changes: 8 additions & 8 deletions clang/test/APINotes/retain-count-convention.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

#import <SimpleKit/SimpleKit.h>

// CHECK: void *getCFOwnedToUnowned(void) __attribute__((cf_returns_not_retained));
// CHECK: void *getCFUnownedToOwned(void) __attribute__((cf_returns_retained));
// CHECK: void *getCFOwnedToNone(void) __attribute__((cf_unknown_transfer));
// CHECK: id getObjCOwnedToUnowned(void) __attribute__((ns_returns_not_retained));
// CHECK: id getObjCUnownedToOwned(void) __attribute__((ns_returns_retained));
// CHECK: int indirectGetCFOwnedToUnowned(void * _Nullable *out __attribute__((cf_returns_not_retained)));
// CHECK: int indirectGetCFUnownedToOwned(void * _Nullable *out __attribute__((cf_returns_retained)));
// CHECK: __attribute__((cf_returns_not_retained)) void *getCFOwnedToUnowned(void);
// CHECK: __attribute__((cf_returns_retained)) void *getCFUnownedToOwned(void);
// CHECK: __attribute__((cf_unknown_transfer)) void *getCFOwnedToNone(void);
// CHECK: __attribute__((ns_returns_not_retained)) id getObjCOwnedToUnowned(void);
// CHECK: __attribute__((ns_returns_retained)) id getObjCUnownedToOwned(void);
// CHECK: int indirectGetCFOwnedToUnowned(__attribute__((cf_returns_not_retained)) void * _Nullable *out);
// CHECK: int indirectGetCFUnownedToOwned(__attribute__((cf_returns_retained)) void * _Nullable *out);
// CHECK: int indirectGetCFOwnedToNone(void * _Nullable *out);
// CHECK: int indirectGetCFNoneToOwned(void **out __attribute__((cf_returns_not_retained)));
// CHECK: int indirectGetCFNoneToOwned(__attribute__((cf_returns_not_retained)) void **out);

// CHECK-LABEL: @interface MethodTest
// CHECK: - (id)getOwnedToUnowned __attribute__((ns_returns_not_retained));
Expand Down
4 changes: 2 additions & 2 deletions clang/test/APINotes/versioned.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#import <VersionedKit/VersionedKit.h>

// CHECK-UNVERSIONED: void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));
// CHECK-VERSIONED: void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(a:b:)")));
// CHECK-VERSIONED:__attribute__((swift_name("moveTo(a:b:)"))) void moveToPointDUMP(double x, double y);

// CHECK-DUMP-LABEL: Dumping moveToPointDUMP
// CHECK-VERSIONED-DUMP: SwiftVersionedAdditionAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
Expand Down Expand Up @@ -65,7 +65,7 @@

// CHECK-DUMP-NOT: Dumping

// CHECK-UNVERSIONED: void acceptClosure(void (^block)(void) __attribute__((noescape)));
// CHECK-UNVERSIONED: void acceptClosure(__attribute__((noescape)) void (^block)(void));
// CHECK-VERSIONED: void acceptClosure(void (^block)(void));

// CHECK-UNVERSIONED: void privateFunc(void) __attribute__((swift_private));
Expand Down
4 changes: 4 additions & 0 deletions clang/test/AST/Interp/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,3 +566,7 @@ char melchizedek[2200000000];
typedef decltype(melchizedek[1] - melchizedek[0]) ptrdiff_t;
constexpr ptrdiff_t d1 = &melchizedek[0x7fffffff] - &melchizedek[0]; // ok
constexpr ptrdiff_t d3 = &melchizedek[0] - &melchizedek[0x80000000u]; // ok

/// GH#88018
const int SZA[] = {};
void testZeroSizedArrayAccess() { unsigned c = SZA[4]; }
2 changes: 2 additions & 0 deletions clang/test/AST/Interp/ms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@

/// Used to assert because the two parameters to _rotl do not have the same type.
static_assert(_rotl(0x01, 5) == 32);

static_assert(alignof(__unaligned int) == 1, "");
15 changes: 15 additions & 0 deletions clang/test/AST/Interp/weak.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s




/// FIXME: The new interpreter also emits the "address of weak declaration" note in the pointer-to-bool case.

[[gnu::weak]] extern int a;
int ha[(bool)&a]; // both-warning {{variable length arrays in C++ are a Clang extension}} \
// expected-note {{comparison against address of weak declaration}} \
// both-error {{variable length array declaration not allowed at file scope}}
int ha2[&a == nullptr]; // both-warning {{variable length arrays in C++ are a Clang extension}} \
// both-note {{comparison against address of weak declaration '&a' can only be performed at runtime}} \
// both-error {{variable length array declaration not allowed at file scope}}
2 changes: 1 addition & 1 deletion clang/test/AST/ast-print-method-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct DefMethodsWithoutBody {
// CHECK-NEXT: DefMethodsWithoutBody() = default;
~DefMethodsWithoutBody() = default;

// CHECK-NEXT: __attribute__((alias("X"))) void m1();
// CHECK-NEXT: void m1() __attribute__((alias("X")));
void m1() __attribute__((alias("X")));

// CHECK-NEXT: };
Expand Down
2 changes: 1 addition & 1 deletion clang/test/AST/ast-print-no-sanitize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ void should_not_crash_1() __attribute__((no_sanitize_memory));
[[clang::no_sanitize_memory]] void should_not_crash_2();

// CHECK: void should_not_crash_1() __attribute__((no_sanitize("memory")));
// CHECK: void should_not_crash_2() {{\[\[}}clang::no_sanitize("memory"){{\]\]}};
// CHECK: {{\[\[}}clang::no_sanitize("memory"){{\]\]}} void should_not_crash_2();
15 changes: 15 additions & 0 deletions clang/test/AST/attr-print-emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,18 @@ class C {
// CHECK: void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3)));
void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3)));
};

#define ANNOTATE_ATTR __attribute__((annotate("Annotated")))
ANNOTATE_ATTR int annotated_attr ANNOTATE_ATTR = 0;
// CHECK: __attribute__((annotate("Annotated"))) int annotated_attr __attribute__((annotate("Annotated"))) = 0;

// FIXME: We do not print the attribute as written after the type specifier.
int ANNOTATE_ATTR annotated_attr_fixme = 0;
// CHECK: __attribute__((annotate("Annotated"))) int annotated_attr_fixme = 0;

#define NONNULL_ATTR __attribute__((nonnull(1)))
ANNOTATE_ATTR NONNULL_ATTR void fn_non_null_annotated_attr(int *) __attribute__((annotate("AnnotatedRHS")));
// CHECK:__attribute__((annotate("Annotated"))) __attribute__((nonnull(1))) void fn_non_null_annotated_attr(int *) __attribute__((annotate("AnnotatedRHS")));

[[gnu::nonnull(1)]] [[gnu::always_inline]] void cxx11_attr(int*) ANNOTATE_ATTR;
// CHECK: {{\[\[}}gnu::nonnull(1)]] {{\[\[}}gnu::always_inline]] void cxx11_attr(int *) __attribute__((annotate("Annotated")));
2 changes: 1 addition & 1 deletion clang/test/Analysis/scopes-cfg-output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,7 @@ void test_cleanup_functions2(int m) {
// CHECK: [B1]
// CHECK-NEXT: 1: CFGScopeBegin(f)
// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], F)
// CHECK-NEXT: 3: __attribute__((cleanup(cleanup_F))) F f;
// CHECK-NEXT: 3: F f __attribute__((cleanup(cleanup_F)));
// CHECK-NEXT: 4: CleanupFunction (cleanup_F)
// CHECK-NEXT: 5: [B1.3].~F() (Implicit destructor)
// CHECK-NEXT: 6: CFGScopeEnd(f)
Expand Down
6 changes: 0 additions & 6 deletions clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-error.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ void test_trap(void) {
__tw(ia, ib, 0); //expected-error {{argument value 0 is outside the valid range [1, 31]}}
}

#ifdef __PPC64__
void test_builtin_ppc_rldimi() {
unsigned int shift;
unsigned long long mask;
Expand All @@ -33,7 +32,6 @@ void test_builtin_ppc_rldimi() {
res = __builtin_ppc_rldimi(ull, ull, 63, 0xFFFF000000000F00); // expected-error {{argument 3 value should represent a contiguous bit field}}
res = __builtin_ppc_rldimi(ull, ull, 64, 0xFFFF000000000000); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
}
#endif

void test_builtin_ppc_rlwimi() {
unsigned int shift;
Expand Down Expand Up @@ -86,10 +84,6 @@ void testalignx(const void *pointer, unsigned int alignment) {
}

#ifndef __PPC64__
unsigned long long testrldimi32() {
return __rldimi(ull, ui, 3, 0x7ffff8ULL); //expected-error {{this builtin is only available on 64-bit targets}}
}

long long testbpermd(long long bit_selector, long long source) {
return __bpermd(bit_selector, source); //expected-error {{this builtin is only available on 64-bit targets}}
}
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGen/ubsan-bitfield-conversion.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void foo1(int x) {
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
Expand All @@ -29,7 +29,7 @@ void foo2(int x) {
// CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 6
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 6
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
Expand All @@ -42,7 +42,7 @@ void foo3() {
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
Expand All @@ -55,7 +55,7 @@ void foo4(int x) {
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
73 changes: 73 additions & 0 deletions clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,76 @@ void test_temporary() {
//CHECK: %ref.tmp = alloca %struct.MaterializedTemporary, align 1
//CHECK: call void @_ZN21MaterializedTemporaryC1Ev(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}
//CHECK invoke void @_ZNH21MaterializedTemporary3fooEOS_(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}

namespace GH86399 {
volatile int a = 0;
struct function {
function& operator=(function const&) {
a = 1;
return *this;
}
};

void f() {
function list;

//CHECK-LABEL: define internal void @"_ZZN7GH863991f{{.*}}"(ptr %{{.*}})
//CHECK: call {{.*}} @_ZN7GH863998functionaSERKS0_
//CHECK-NEXT: ret void
[&list](this auto self) {
list = function{};
}();
}
}

namespace GH84163 {
// Just check that this doesn't crash (we were previously not instantiating
// everything that needs instantiating in here).
template <typename> struct S {};

void a() {
int x;
const auto l = [&x](this auto&) { S<decltype(x)> q; };
l();
}
}

namespace GH84425 {
// As above.
void do_thing(int x) {
auto second = [&](this auto const& self, int b) -> int {
if (x) return x;
else return self(x);
};

second(1);
}

void do_thing2(int x) {
auto second = [&](this auto const& self) {
if (true) return x;
else return x;
};

second();
}
}

namespace GH79754 {
// As above.
void f() {
int x;
[&x](this auto&&) {return x;}();
}
}

namespace GH70604 {
auto dothing(int num)
{
auto fun = [&num](this auto&& self) -> void {
auto copy = num;
};

fun();
}
}
16 changes: 8 additions & 8 deletions clang/test/CodeGenCXX/ubsan-bitfield-conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ void foo1(int x) {
// CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
c.a = x;
// CHECK: store i8 %{{.*}}
// CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
// CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
Expand All @@ -42,13 +42,13 @@ void foo2(int x) {
// CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 6
// CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 6
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
c.b = x;
// CHECK: store i8 %{{.*}}
// CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 6
// CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 6
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
Expand All @@ -61,14 +61,14 @@ void foo3() {
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
c.a++;
// CHECK: store i8 %{{.*}}
// CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
Expand All @@ -81,14 +81,14 @@ void foo4(int x) {
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
c.a += x;
// CHECK: store i8 %{{.*}}
// CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
// CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
// CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
// CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize !6
// CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
// CHECK-BITFIELD-CONVERSION: [[CONT]]:
// CHECK-NEXT: ret void
}
14 changes: 7 additions & 7 deletions clang/test/Driver/arm-compiler-rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,47 @@
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-GNUEABI
// ARM-GNUEABI: "{{.*[/\\]}}libclang_rt.builtins-arm.a"
// ARM-GNUEABI: "{{.*[/\\]}}libclang_rt.builtins.a"

// RUN: %clang -target arm-linux-gnueabi \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-GNUEABI-ABI
// ARM-GNUEABI-ABI: "{{.*[/\\]}}libclang_rt.builtins-armhf.a"
// ARM-GNUEABI-ABI: "{{.*[/\\]}}libclang_rt.builtins.a"

// RUN: %clang -target arm-linux-gnueabihf \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-GNUEABIHF
// ARM-GNUEABIHF: "{{.*[/\\]}}libclang_rt.builtins-armhf.a"
// ARM-GNUEABIHF: "{{.*[/\\]}}libclang_rt.builtins.a"

// RUN: %clang -target arm-linux-gnueabihf \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -mfloat-abi=soft -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-GNUEABIHF-ABI
// ARM-GNUEABIHF-ABI: "{{.*[/\\]}}libclang_rt.builtins-arm.a"
// ARM-GNUEABIHF-ABI: "{{.*[/\\]}}libclang_rt.builtins.a"

// RUN: %clang -target arm-windows-itanium \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-WINDOWS
// ARM-WINDOWS: "{{.*[/\\]}}clang_rt.builtins-arm.lib"
// ARM-WINDOWS: "{{.*[/\\]}}clang_rt.builtins.lib"

// RUN: %clang -target arm-linux-androideabi \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-ANDROID
// ARM-ANDROID: "{{.*[/\\]}}libclang_rt.builtins-arm-android.a"
// ARM-ANDROID: "{{.*[/\\]}}libclang_rt.builtins.a"

// RUN: not %clang --target=arm-linux-androideabi \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix ARM-ANDROIDHF
// ARM-ANDROIDHF: "{{.*[/\\]}}libclang_rt.builtins-armhf-android.a"
// ARM-ANDROIDHF: "{{.*[/\\]}}libclang_rt.builtins.a"

16 changes: 8 additions & 8 deletions clang/test/Driver/cl-link.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@
// ASAN: link.exe
// ASAN: "-debug"
// ASAN: "-incremental:no"
// ASAN: "{{[^"]*}}clang_rt.asan-i386.lib"
// ASAN: "-wholearchive:{{.*}}clang_rt.asan-i386.lib"
// ASAN: "{{[^"]*}}clang_rt.asan_cxx-i386.lib"
// ASAN: "-wholearchive:{{.*}}clang_rt.asan_cxx-i386.lib"
// ASAN: "{{[^"]*}}clang_rt.asan.lib"
// ASAN: "-wholearchive:{{.*}}clang_rt.asan.lib"
// ASAN: "{{[^"]*}}clang_rt.asan_cxx.lib"
// ASAN: "-wholearchive:{{.*}}clang_rt.asan_cxx.lib"
// ASAN: "{{.*}}cl-link{{.*}}.obj"

// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /MD /Tc%s -fuse-ld=link -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s
// ASAN-MD: link.exe
// ASAN-MD: "-debug"
// ASAN-MD: "-incremental:no"
// ASAN-MD: "{{.*}}clang_rt.asan_dynamic-i386.lib"
// ASAN-MD: "{{[^"]*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib"
// ASAN-MD: "{{.*}}clang_rt.asan_dynamic.lib"
// ASAN-MD: "{{[^"]*}}clang_rt.asan_dynamic_runtime_thunk.lib"
// ASAN-MD: "-include:___asan_seh_interceptor"
// ASAN-MD: "-wholearchive:{{.*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib"
// ASAN-MD: "-wholearchive:{{.*}}clang_rt.asan_dynamic_runtime_thunk.lib"
// ASAN-MD: "{{.*}}cl-link{{.*}}.obj"

// RUN: %clang_cl /LD -fuse-ld=link -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s
Expand All @@ -40,7 +40,7 @@
// ASAN-DLL: "-dll"
// ASAN-DLL: "-debug"
// ASAN-DLL: "-incremental:no"
// ASAN-DLL: "{{.*}}clang_rt.asan_dll_thunk-i386.lib"
// ASAN-DLL: "{{.*}}clang_rt.asan_dll_thunk.lib"
// ASAN-DLL: "{{.*}}cl-link{{.*}}.obj"

// RUN: %clang_cl /Zi /Tc%s -fuse-ld=link -### 2>&1 | FileCheck --check-prefix=DEBUG %s
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Driver/compiler-rt-unwind.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@
// RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \
// RUN: -shared-libgcc \
// RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT %s
// MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
// MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins.a"
// MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT-SAME: "-l:libunwind.dll.a"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \
// RUN: -static-libgcc \
// RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT %s
// MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
// MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins.a"
// MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT-SAME: "-l:libunwind.a"
//
// RUN: %clang -### %s 2>&1 \
Expand All @@ -114,5 +114,5 @@
// RUN: %clangxx -### %s 2>&1 \
// RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \
// RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT %s
// MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
// MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins.a"
// MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT-SAME: "-lunwind"
8 changes: 4 additions & 4 deletions clang/test/Driver/coverage-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
// RUN: | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s
//
// CHECK-FREEBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-freebsd{{/|\\\\}}libclang_rt.profile.a"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-netbsd --coverage -fuse-ld=ld \
Expand All @@ -42,7 +42,7 @@
// RUN: | FileCheck --check-prefix=CHECK-NETBSD-X86-64 %s

// CHECK-NETBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-NETBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}netbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-NETBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-netbsd{{/|\\\\}}libclang_rt.profile.a"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-openbsd --coverage -fuse-ld=ld \
Expand All @@ -51,7 +51,7 @@
// RUN: | FileCheck --check-prefix=CHECK-OPENBSD-X86-64 %s

// CHECK-OPENBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-OPENBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}openbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-OPENBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-openbsd{{/|\\\\}}libclang_rt.profile.a"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=arm-linux-androideabi --coverage -fuse-ld=ld \
Expand All @@ -60,4 +60,4 @@
// RUN: | FileCheck --check-prefix=CHECK-ANDROID-ARM %s
//
// CHECK-ANDROID-ARM: "{{(.*[^.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
// CHECK-ANDROID-ARM: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-arm-android.a"
// CHECK-ANDROID-ARM: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}arm-unknown-linux-android{{/|\\\\}}libclang_rt.profile.a"
2 changes: 1 addition & 1 deletion clang/test/Driver/cuda-external-tools.cu
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
// Check -Xcuda-ptxas with clang-cl
// RUN: %clang_cl -### -c -Xcuda-ptxas -foo1 \
// RUN: --offload-arch=sm_35 --cuda-path=%S/Inputs/CUDA/usr/local/cuda \
// RUN: -Xcuda-ptxas -foo2 %s 2>&1 \
// RUN: -Xcuda-ptxas -foo2 -- %s 2>&1 \
// RUN: | FileCheck -check-prefixes=CHECK,SM35,PTXAS-EXTRA %s

// MacOS spot-checks
Expand Down
16 changes: 8 additions & 8 deletions clang/test/Driver/instrprof-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
// RUN: | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s
//
// CHECK-FREEBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-freebsd{{/|\\\\}}libclang_rt.profile.a"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-netbsd -fprofile-instr-generate -fuse-ld=ld \
Expand All @@ -43,7 +43,7 @@
// RUN: | FileCheck --check-prefix=CHECK-NETBSD-X86-64 %s

// CHECK-NETBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-NETBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}netbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-NETBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-netbsd{{/|\\\\}}libclang_rt.profile.a"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-openbsd -fprofile-instr-generate -fuse-ld=ld \
Expand All @@ -52,7 +52,7 @@
// RUN: | FileCheck --check-prefix=CHECK-OPENBSD-X86-64 %s

// CHECK-OPENBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-OPENBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}openbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-OPENBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-openbsd{{/|\\\\}}libclang_rt.profile.a"

// RUN: %clang -### %s 2>&1 \
// RUN: -shared \
Expand All @@ -72,7 +72,7 @@
// RUN: | FileCheck --check-prefix=CHECK-LINUX-X86-64-SHARED %s
//
// CHECK-LINUX-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-LINUX-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{.*}}linux{{.*}}libclang_rt.profile.a" {{.*}} "-lc"
// CHECK-LINUX-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{.*}}x86_64-unknown-linux{{.*}}libclang_rt.profile.a" {{.*}} "-lc"
//
// RUN: %clang -### %s 2>&1 \
// RUN: -shared \
Expand All @@ -82,7 +82,7 @@
// RUN: | FileCheck --check-prefix=CHECK-FREEBSD-X86-64-SHARED %s
//
// CHECK-FREEBSD-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-FREEBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-FREEBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-freebsd{{/|\\\\}}libclang_rt.profile.a"
//
// RUN: %clang -### %s 2>&1 \
// RUN: -shared \
Expand All @@ -92,7 +92,7 @@
// RUN: | FileCheck --check-prefix=CHECK-NETBSD-X86-64-SHARED %s

// CHECK-NETBSD-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-NETBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}netbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-NETBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-netbsd{{/|\\\\}}libclang_rt.profile.a"

// RUN: %clang -### %s 2>&1 \
// RUN: -shared \
Expand All @@ -102,7 +102,7 @@
// RUN: | FileCheck --check-prefix=CHECK-OPENBSD-X86-64-SHARED %s

// CHECK-OPENBSD-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-OPENBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}openbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-OPENBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-openbsd{{/|\\\\}}libclang_rt.profile.a"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-apple-darwin14 -fprofile-instr-generate -fuse-ld=ld \
Expand Down Expand Up @@ -174,7 +174,7 @@
// RUN: | FileCheck --check-prefix=CHECK-MINGW-X86-64 %s
//
// CHECK-MINGW-X86-64: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-MINGW-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}windows{{/|\\\\}}libclang_rt.profile-x86_64.a"
// CHECK-MINGW-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-windows-gnu{{/|\\\\}}libclang_rt.profile.a"

// Test instrumented profiling dependent-lib flags
//
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Driver/linux-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@
// CHECK-LD-RT-ANDROID: "--eh-frame-hdr"
// CHECK-LD-RT-ANDROID: "-m" "armelf_linux_eabi"
// CHECK-LD-RT-ANDROID: "-dynamic-linker"
// CHECK-LD-RT-ANDROID: libclang_rt.builtins-arm-android.a"
// CHECK-LD-RT-ANDROID: libclang_rt.builtins.a"
// CHECK-LD-RT-ANDROID: "-lc"
// CHECK-LD-RT-ANDROID: libclang_rt.builtins-arm-android.a"
// CHECK-LD-RT-ANDROID: libclang_rt.builtins.a"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
Expand Down Expand Up @@ -264,7 +264,7 @@
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-STATIC %s
// CHECK-CLANG-ANDROID-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-CLANG-ANDROID-STATIC: "--start-group" "{{[^"]*}}{{/|\\\\}}libclang_rt.builtins-aarch64-android.a" "-l:libunwind.a" "-lc" "--end-group"
// CHECK-CLANG-ANDROID-STATIC: "--start-group" "{{[^"]*}}{{/|\\\\}}libclang_rt.builtins.a" "-l:libunwind.a" "-lc" "--end-group"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
Expand Down
16 changes: 8 additions & 8 deletions clang/test/Driver/mingw-sanitizers.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
//
// ASAN-ALL-NOT:"-l{{[^"]+"]}}"
// ASAN-ALL-NOT:"[[INPUT]]"
// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic-i386.dll.a"
// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic-x86_64.dll.a"
// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic.dll.a"
// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic.dll.a"
// ASAN-ALL: "-lcomponent"
// ASAN-ALL: "[[INPUT]]"
// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic-i386.dll.a"
// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-i386.a"
// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic.dll.a"
// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk.a"
// ASAN-I686: "--require-defined" "___asan_seh_interceptor"
// ASAN-I686: "--whole-archive" "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-i386.a" "--no-whole-archive"
// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic-x86_64.dll.a"
// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a"
// ASAN-I686: "--whole-archive" "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk.a" "--no-whole-archive"
// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic.dll.a"
// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk.a"
// ASAN-X86_64: "--require-defined" "__asan_seh_interceptor"
// ASAN-X86_64: "--whole-archive" "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a" "--no-whole-archive"
// ASAN-X86_64: "--whole-archive" "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk.a" "--no-whole-archive"

// RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=vptr
4 changes: 2 additions & 2 deletions clang/test/Driver/msp430-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@
// LIBS-COMPILER-RT-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtbegin_no_eh.o"
// LIBS-COMPILER-RT-POS: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430"
// LIBS-COMPILER-RT-POS: "-L{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430"
// LIBS-COMPILER-RT-POS: "{{[^"]*}}libclang_rt.builtins-msp430.a" "--start-group" "-lmul_none" "-lc" "{{[^"]*}}libclang_rt.builtins-msp430.a" "-lcrt" "-lnosys" "--end-group" "{{[^"]*}}libclang_rt.builtins-msp430.a"
// LIBS-COMPILER-RT-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtend_no_eh.o" "{{[^"]*}}libclang_rt.builtins-msp430.a"
// LIBS-COMPILER-RT-POS: "{{[^"]*}}libclang_rt.builtins.a" "--start-group" "-lmul_none" "-lc" "{{[^"]*}}libclang_rt.builtins.a" "-lcrt" "-lnosys" "--end-group" "{{[^"]*}}libclang_rt.builtins.a"
// LIBS-COMPILER-RT-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtend_no_eh.o" "{{[^"]*}}libclang_rt.builtins.a"
// LIBS-COMPILER-RT-NEG-NOT: crtbegin.o
// LIBS-COMPILER-RT-NEG-NOT: -lssp_nonshared
// LIBS-COMPILER-RT-NEG-NOT: -lssp
Expand Down
12 changes: 6 additions & 6 deletions clang/test/Driver/print-libgcc-file-name-clangrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-X8664 %s
// CHECK-CLANGRT-X8664: libclang_rt.builtins-x86_64.a
// CHECK-CLANGRT-X8664: libclang_rt.builtins.a

// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
// RUN: --target=i386-pc-linux \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-I386 %s
// CHECK-CLANGRT-I386: libclang_rt.builtins-i386.a
// CHECK-CLANGRT-I386: libclang_rt.builtins.a

// Check whether alternate arch values map to the correct library.
//
Expand All @@ -27,28 +27,28 @@
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARM %s
// CHECK-CLANGRT-ARM: libclang_rt.builtins-arm.a
// CHECK-CLANGRT-ARM: libclang_rt.builtins.a

// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
// RUN: --target=arm-linux-androideabi \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARM-ANDROID %s
// CHECK-CLANGRT-ARM-ANDROID: libclang_rt.builtins-arm-android.a
// CHECK-CLANGRT-ARM-ANDROID: libclang_rt.builtins.a

// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
// RUN: --target=arm-linux-gnueabihf \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARMHF %s
// CHECK-CLANGRT-ARMHF: libclang_rt.builtins-armhf.a
// CHECK-CLANGRT-ARMHF: libclang_rt.builtins.a

// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
// RUN: --target=arm-linux-gnueabi -mfloat-abi=hard \
// RUN: --sysroot=%S/Inputs/resource_dir_with_arch_subdir \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARM-ABI %s
// CHECK-CLANGRT-ARM-ABI: libclang_rt.builtins-armhf.a
// CHECK-CLANGRT-ARM-ABI: libclang_rt.builtins.a

// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name \
// RUN: --target=armv7m-none-eabi \
Expand Down
6 changes: 0 additions & 6 deletions clang/test/Driver/print-runtime-dir.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
// Default directory layout
// RUN: %clang -print-runtime-dir --target=x86_64-pc-windows-msvc \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: | FileCheck --check-prefix=PRINT-RUNTIME-DIR -DFILE=%S/Inputs/resource_dir %s
// PRINT-RUNTIME-DIR: [[FILE]]{{/|\\}}lib{{/|\\}}windows

// Per-target directory layout
// RUN: %clang -print-runtime-dir --target=x86_64-pc-windows-msvc \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Driver/riscv32-toolchain-extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
// C-RV32-BAREMETAL-ILP32-NOGCC: "-internal-isystem" "{{.*}}/riscv32-nogcc/bin/../riscv32-unknown-elf/include"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/bin/riscv32-unknown-elf-ld"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/bin/../riscv32-unknown-elf/lib/crt0.o"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/{{.*}}/lib/clang_rt.crtbegin-riscv32.o"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/{{.*}}/riscv32-unknown-unknown-elf/clang_rt.crtbegin.o"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/bin/../riscv32-unknown-elf/lib"
// C-RV32-BAREMETAL-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/{{.*}}/lib/libclang_rt.builtins-riscv32.a"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/{{.*}}/lib/clang_rt.crtend-riscv32.o"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/{{.*}}/riscv32-unknown-unknown-elf/libclang_rt.builtins.a"
// C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}/riscv32-nogcc/{{.*}}/riscv32-unknown-unknown-elf/clang_rt.crtend.o"
6 changes: 3 additions & 3 deletions clang/test/Driver/riscv32-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@
// RUN: --target=riscv32-unknown-elf --rtlib=compiler-rt --unwindlib=compiler-rt 2>&1 \
// RUN: | FileCheck -check-prefix=C-RV32-RTLIB-COMPILERRT-ILP32 %s
// C-RV32-RTLIB-COMPILERRT-ILP32: "{{.*}}crt0.o"
// C-RV32-RTLIB-COMPILERRT-ILP32: "{{.*}}clang_rt.crtbegin-riscv32.o"
// C-RV32-RTLIB-COMPILERRT-ILP32: "--start-group" "-lc" "-lgloss" "--end-group" "{{.*}}libclang_rt.builtins-riscv32.a"
// C-RV32-RTLIB-COMPILERRT-ILP32: "{{.*}}clang_rt.crtend-riscv32.o"
// C-RV32-RTLIB-COMPILERRT-ILP32: "{{.*}}clang_rt.crtbegin.o"
// C-RV32-RTLIB-COMPILERRT-ILP32: "--start-group" "-lc" "-lgloss" "--end-group" "{{.*}}libclang_rt.builtins.a"
// C-RV32-RTLIB-COMPILERRT-ILP32: "{{.*}}clang_rt.crtend.o"

// RUN: %clang -### %s --target=riscv32 \
// RUN: --gcc-toolchain=%S/Inputs/basic_riscv32_tree --sysroot= \
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Driver/riscv64-toolchain-extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
// C-RV64-BAREMETAL-LP64-NOGCC: "-internal-isystem" "{{.*}}/riscv64-nogcc/bin/../riscv64-unknown-elf/include"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/bin/riscv64-unknown-elf-ld"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/bin/../riscv64-unknown-elf/lib/crt0.o"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/{{.*}}/lib/clang_rt.crtbegin-riscv64.o"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/{{.*}}/riscv64-unknown-unknown-elf/clang_rt.crtbegin.o"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/bin/../riscv64-unknown-elf/lib"
// C-RV64-BAREMETAL-LP64-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/{{.*}}/lib/libclang_rt.builtins-riscv64.a"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/{{.*}}/lib/clang_rt.crtend-riscv64.o"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/{{.*}}/riscv64-unknown-unknown-elf/libclang_rt.builtins.a"
// C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}/riscv64-nogcc/{{.*}}/riscv64-unknown-unknown-elf/clang_rt.crtend.o"
6 changes: 3 additions & 3 deletions clang/test/Driver/riscv64-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@
// RUN: --target=riscv64-unknown-elf --rtlib=compiler-rt --unwindlib=compiler-rt 2>&1 \
// RUN: | FileCheck -check-prefix=C-RV64-RTLIB-COMPILERRT-LP64 %s
// C-RV64-RTLIB-COMPILERRT-LP64: "{{.*}}crt0.o"
// C-RV64-RTLIB-COMPILERRT-LP64: "{{.*}}clang_rt.crtbegin-riscv64.o"
// C-RV64-RTLIB-COMPILERRT-LP64: "--start-group" "-lc" "-lgloss" "--end-group" "{{.*}}libclang_rt.builtins-riscv64.a"
// C-RV64-RTLIB-COMPILERRT-LP64: "{{.*}}clang_rt.crtend-riscv64.o"
// C-RV64-RTLIB-COMPILERRT-LP64: "{{.*}}clang_rt.crtbegin.o"
// C-RV64-RTLIB-COMPILERRT-LP64: "--start-group" "-lc" "-lgloss" "--end-group" "{{.*}}libclang_rt.builtins.a"
// C-RV64-RTLIB-COMPILERRT-LP64: "{{.*}}clang_rt.crtend.o"

// RUN: %clang -### %s --target=riscv64 \
// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree --sysroot= \
Expand Down
30 changes: 15 additions & 15 deletions clang/test/Driver/sanitizer-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
// CHECK-ASAN-FREEBSD: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-ASAN-FREEBSD-NOT: "-lc"
// CHECK-ASAN-FREEBSD-NOT: libclang_rt.asan_cxx
// CHECK-ASAN-FREEBSD: freebsd{{/|\\+}}libclang_rt.asan-i386.a"
// CHECK-ASAN-FREEBSD: freebsd{{/|\\+}}libclang_rt.asan.a"
// CHECK-ASAN-FREEBSD-NOT: libclang_rt.asan_cxx
// CHECK-ASAN-FREEBSD-NOT: "--dynamic-list"
// CHECK-ASAN-FREEBSD: "--export-dynamic"
Expand All @@ -135,8 +135,8 @@
//
// CHECK-ASAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-ASAN-LINUX-CXX-NOT: "-lc"
// CHECK-ASAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan-i386.a" "--no-whole-archive"
// CHECK-ASAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan_cxx-i386.a" "--no-whole-archive"
// CHECK-ASAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive"
// CHECK-ASAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan_cxx.a" "--no-whole-archive"
// CHECK-ASAN-LINUX-CXX-NOT: "--dynamic-list"
// CHECK-ASAN-LINUX-CXX: "--export-dynamic"
// CHECK-ASAN-LINUX-CXX: stdc++
Expand All @@ -163,7 +163,7 @@
//
// CHECK-ASAN-ARM: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-ASAN-ARM-NOT: "-lc"
// CHECK-ASAN-ARM: libclang_rt.asan-arm.a"
// CHECK-ASAN-ARM: libclang_rt.asan.a"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=armv7l-linux-gnueabi -fuse-ld=ld -fsanitize=address \
Expand All @@ -172,7 +172,7 @@
//
// CHECK-ASAN-ARMv7: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-ASAN-ARMv7-NOT: "-lc"
// CHECK-ASAN-ARMv7: libclang_rt.asan-arm.a"
// CHECK-ASAN-ARMv7: libclang_rt.asan.a"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
Expand All @@ -184,7 +184,7 @@
// CHECK-ASAN-ANDROID-NOT: "-lc"
// CHECK-ASAN-ANDROID-NOT: "-lpthread"
// CHECK-ASAN-ANDROID-NOT: "-lresolv"
// CHECK-ASAN-ANDROID: libclang_rt.asan-arm-android.so"
// CHECK-ASAN-ANDROID: libclang_rt.asan.so"
// CHECK-ASAN-ANDROID-NOT: "-lpthread"
// CHECK-ASAN-ANDROID-NOT: "-lresolv"

Expand All @@ -195,7 +195,7 @@
// RUN: | FileCheck --check-prefix=CHECK-ASAN-ANDROID-STATICLIBASAN %s
//
// CHECK-ASAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
// CHECK-ASAN-ANDROID-STATICLIBASAN: libclang_rt.asan-arm-android.a"
// CHECK-ASAN-ANDROID-STATICLIBASAN: libclang_rt.asan.a"
// CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lpthread"
// CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lrt"
// CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lresolv"
Expand All @@ -210,7 +210,7 @@
// CHECK-UBSAN-ANDROID-NOT: "-lc"
// CHECK-UBSAN-ANDROID-NOT: "-lpthread"
// CHECK-UBSAN-ANDROID-NOT: "-lresolv"
// CHECK-UBSAN-ANDROID: libclang_rt.ubsan_standalone-arm-android.so"
// CHECK-UBSAN-ANDROID: libclang_rt.ubsan_standalone.so"
// CHECK-UBSAN-ANDROID-NOT: "-lpthread"
// CHECK-UBSAN-ANDROID-NOT: "-lresolv"

Expand All @@ -221,7 +221,7 @@
// RUN: | FileCheck --check-prefix=CHECK-UBSAN-ANDROID-STATICLIBASAN %s
//
// CHECK-UBSAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
// CHECK-UBSAN-ANDROID-STATICLIBASAN: libclang_rt.ubsan_standalone-arm-android.a"
// CHECK-UBSAN-ANDROID-STATICLIBASAN: libclang_rt.ubsan_standalone.a"
// CHECK-UBSAN-ANDROID-STATICLIBASAN-NOT: "-lpthread"
// CHECK-UBSAN-ANDROID-STATICLIBASAN-NOT: "-lrt"
// CHECK-UBSAN-ANDROID-STATICLIBASAN-NOT: "-lresolv"
Expand All @@ -237,7 +237,7 @@
// CHECK-ASAN-ANDROID-X86-NOT: "-lc"
// CHECK-ASAN-ANDROID-X86-NOT: "-lpthread"
// CHECK-ASAN-ANDROID-X86-NOT: "-lresolv"
// CHECK-ASAN-ANDROID-X86: libclang_rt.asan-i686-android.so"
// CHECK-ASAN-ANDROID-X86: libclang_rt.asan.so"
// CHECK-ASAN-ANDROID-X86-NOT: "-lpthread"
// CHECK-ASAN-ANDROID-X86-NOT: "-lresolv"
//
Expand All @@ -257,7 +257,7 @@
//
// CHECK-ASAN-ANDROID-SHARED: "{{(.*[^.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
// CHECK-ASAN-ANDROID-SHARED-NOT: "-lc"
// CHECK-ASAN-ANDROID-SHARED: libclang_rt.asan-arm-android.so"
// CHECK-ASAN-ANDROID-SHARED: libclang_rt.asan.so"
// CHECK-ASAN-ANDROID-SHARED-NOT: "-lpthread"
// CHECK-ASAN-ANDROID-SHARED-NOT: "-lresolv"

Expand Down Expand Up @@ -347,7 +347,7 @@
// CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan
// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx
// CHECK-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone-x32.a" "--no-whole-archive"
// CHECK-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive"
// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan
// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx
// CHECK-UBSAN-LINUX-NOT: "-lstdc++"
Expand Down Expand Up @@ -678,7 +678,7 @@
// RUN: --sysroot=%S/Inputs/basic_android_tree \
// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-DIAG-ANDROID %s
// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{.*}}ld{{(.exe)?}}"
// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{[^"]*}}libclang_rt.ubsan_standalone-aarch64-android.so"
// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{[^"]*}}libclang_rt.ubsan_standalone.so"
// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "--export-dynamic-symbol=__cfi_check"

// RUN: %clangxx -fsanitize=address -### %s 2>&1 \
Expand Down Expand Up @@ -929,7 +929,7 @@
// CHECK-SCUDO-ANDROID: "-pie"
// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
// CHECK-SCUDO-ANDROID-NOT: "-lresolv"
// CHECK-SCUDO-ANDROID: libclang_rt.scudo_standalone-arm-android.so"
// CHECK-SCUDO-ANDROID: libclang_rt.scudo_standalone.so"
// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
// CHECK-SCUDO-ANDROID-NOT: "-lresolv"

Expand All @@ -940,7 +940,7 @@
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID-STATIC %s
// CHECK-SCUDO-ANDROID-STATIC: "{{(.*[^.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
// CHECK-SCUDO-ANDROID-STATIC: "-pie"
// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-arm-android.a" "--no-whole-archive"
// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone.a" "--no-whole-archive"
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lpthread"
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lrt"
Expand Down
18 changes: 9 additions & 9 deletions clang/test/Driver/wasm-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,42 @@
// RUN: %clang -### --target=wasm32-unknown-unknown --sysroot=/foo %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK %s
// LINK: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C link command-line with optimization with unknown OS.

// RUN: %clang -### -O2 --target=wasm32-unknown-unknown --sysroot=/foo %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_OPT %s
// LINK_OPT: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C link command-line with known OS.

// RUN: %clang -### --target=wasm32-wasi --sysroot=/foo %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_KNOWN %s
// LINK_KNOWN: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// -shared should be passed through to `wasm-ld` and include crt1-reactor.o with a known OS.

// RUN: %clang -### -shared -mexec-model=reactor --target=wasm32-wasi --sysroot=/foo %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_KNOWN_SHARED %s
// LINK_KNOWN_SHARED: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_KNOWN_SHARED: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1-reactor.o" "--entry" "_initialize" "-shared" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_KNOWN_SHARED: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1-reactor.o" "--entry" "_initialize" "-shared" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// -shared should be passed through to `wasm-ld` and include crt1-reactor.o with an unknown OS.

// RUN: %clang -### -shared -mexec-model=reactor --target=wasm32-unknown-unknown --sysroot=/foo %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_UNKNOWN_SHARED %s
// LINK_UNKNOWN_SHARED: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_UNKNOWN_SHARED: wasm-ld{{.*}}" "crt1-reactor.o" "--entry" "_initialize" "-shared" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_UNKNOWN_SHARED: wasm-ld{{.*}}" "crt1-reactor.o" "--entry" "_initialize" "-shared" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C link command-line with optimization with known OS.

// RUN: %clang -### -O2 --target=wasm32-wasi --sysroot=/foo %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_OPT_KNOWN %s
// LINK_OPT_KNOWN: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C compile command-line with known OS.

Expand Down Expand Up @@ -180,12 +180,12 @@
// RUN: %clang -### %s --target=wasm32-unknown-unknown --sysroot=%s/no-sysroot-there -mexec-model=command 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-COMMAND %s
// CHECK-COMMAND: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// CHECK-COMMAND: wasm-ld{{.*}}" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// CHECK-COMMAND: wasm-ld{{.*}}" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// RUN: %clang -### %s --target=wasm32-unknown-unknown --sysroot=%s/no-sysroot-there -mexec-model=reactor 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-REACTOR %s
// CHECK-REACTOR: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// CHECK-REACTOR: wasm-ld{{.*}}" "crt1-reactor.o" "--entry" "_initialize" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// CHECK-REACTOR: wasm-ld{{.*}}" "crt1-reactor.o" "--entry" "_initialize" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// -fPIC implies +mutable-globals

Expand All @@ -204,7 +204,7 @@
// RUN: %clang -### -O2 --target=wasm32-wasip2 %s --sysroot /foo 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_WASIP2 %s
// LINK_WASIP2: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_WASIP2: wasm-component-ld{{.*}}" "-L/foo/lib/wasm32-wasip2" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_WASIP2: wasm-component-ld{{.*}}" "-L/foo/lib/wasm32-wasip2" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// Test that on `wasm32-wasip2` the `wasm-component-ld` programs is told where
// to find `wasm-ld` by default.
Expand Down
16 changes: 8 additions & 8 deletions clang/test/Driver/wasm-toolchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,48 @@
// RUN: %clangxx -### --target=wasm32-unknown-unknown --sysroot=/foo --stdlib=libc++ %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK %s
// LINK: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// RUN: %clangxx -### --target=wasm32-unknown-unknown --sysroot=/foo --stdlib=libstdc++ %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_STDCXX %s
// LINK_STDCXX: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_STDCXX: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_STDCXX: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C++ link command-line with optimization with unknown OS.

// RUN: %clangxx -### -O2 --target=wasm32-unknown-unknown --sysroot=/foo %s --stdlib=libc++ 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_OPT %s
// LINK_OPT: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// RUN: %clangxx -### -O2 --target=wasm32-unknown-unknown --sysroot=/foo %s --stdlib=libstdc++ 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_OPT_STDCXX %s
// LINK_OPT_STDCXX: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT_STDCXX: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_OPT_STDCXX: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C++ link command-line with known OS.

// RUN: %clangxx -### --target=wasm32-wasi --sysroot=/foo --stdlib=libc++ %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_KNOWN %s
// LINK_KNOWN: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// RUN: %clangxx -### --target=wasm32-wasi --sysroot=/foo --stdlib=libstdc++ %s 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_KNOWN_STDCXX %s
// LINK_KNOWN_STDCXX: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_KNOWN_STDCXX: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_KNOWN_STDCXX: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C++ link command-line with optimization with known OS.

// RUN: %clangxx -### -O2 --target=wasm32-wasi --sysroot=/foo %s --stdlib=libc++ 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_OPT_KNOWN %s
// LINK_OPT_KNOWN: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// RUN: %clangxx -### -O2 --target=wasm32-wasi --sysroot=/foo %s --stdlib=libstdc++ 2>&1 \
// RUN: | FileCheck -check-prefix=LINK_OPT_KNOWN_STDCXX %s
// LINK_OPT_KNOWN_STDCXX: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT_KNOWN_STDCXX: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// LINK_OPT_KNOWN_STDCXX: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"

// A basic C++ compile command-line with known OS.

Expand Down
Loading