19 changes: 6 additions & 13 deletions clang/include/clang/Basic/DiagnosticSerializationKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@ def err_fe_pch_malformed : Error<
"malformed or corrupted AST file: '%0'">, DefaultFatal;
def err_fe_pch_malformed_block : Error<
"malformed block record in PCH file: '%0'">, DefaultFatal;
def err_fe_pch_file_modified : Error<
"file '%0' has been modified since the precompiled header '%1' was built"
": %select{size|mtime|content}2 changed">,
DefaultFatal;
def err_fe_module_file_modified : Error<
"file '%0' has been modified since the module file '%1' was built"
": %select{size|mtime|content}2 changed">,
DefaultFatal;
def err_fe_ast_file_modified : Error<
"file '%0' has been modified since the AST file '%1' was built"
": %select{size|mtime|content}2 changed">,
"file '%0' has been modified since the "
"%select{precompiled header|module file|AST file}1 '%2' was built"
": %select{size|mtime|content}3 changed">,
DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
Expand Down Expand Up @@ -63,12 +56,12 @@ def err_pch_with_compiler_errors : Error<

def err_module_file_conflict : Error<
"module '%0' is defined in both '%1' and '%2'">, DefaultFatal;
def err_module_file_not_found : Error<
def err_ast_file_not_found : Error<
"%select{PCH|module|AST}0 file '%1' not found%select{|: %3}2">, DefaultFatal;
def err_module_file_out_of_date : Error<
def err_ast_file_out_of_date : Error<
"%select{PCH|module|AST}0 file '%1' is out of date and "
"needs to be rebuilt%select{|: %3}2">, DefaultFatal;
def err_module_file_invalid : Error<
def err_ast_file_invalid : Error<
"file '%1' is not a valid precompiled %select{PCH|module|AST}0 file">, DefaultFatal;
def note_module_file_imported_by : Note<
"imported by %select{|module '%2' in }1'%0'">;
Expand Down
47 changes: 32 additions & 15 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -340,36 +340,53 @@ def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">,
InternalDriverOpt,
HelpText<"Apply modifications and produces temporary files to migrate to "
"modern ObjC syntax">;

def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC literals">;
HelpText<"Enable migration to modern ObjC literals">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Literals">;
def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC subscripting">;
HelpText<"Enable migration to modern ObjC subscripting">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Subscripting">;
def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC property">;
HelpText<"Enable migration to modern ObjC property">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Property">;
def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC">;
HelpText<"Enable migration to modern ObjC">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_MigrateDecls">;
def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC readonly property">;
HelpText<"Enable migration to modern ObjC readonly property">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ReadonlyProperty">;
def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC readwrite property">;
HelpText<"Enable migration to modern ObjC readwrite property">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ReadwriteProperty">;
def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, Flags<[CC1Option]>,
HelpText<"Enable migration of setter/getter messages to property-dot syntax">;
HelpText<"Enable migration of setter/getter messages to property-dot syntax">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_PropertyDotSyntax">;
def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, Flags<[CC1Option]>,
HelpText<"Enable migration to property and method annotations">;
HelpText<"Enable migration to property and method annotations">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Annotation">;
def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, Flags<[CC1Option]>,
HelpText<"Enable migration to infer instancetype for method result type">;
HelpText<"Enable migration to infer instancetype for method result type">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Instancetype">;
def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, Flags<[CC1Option]>,
HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">;
HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_NsMacros">;
def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, Flags<[CC1Option]>,
HelpText<"Enable migration to add protocol conformance on classes">;
HelpText<"Enable migration to add protocol conformance on classes">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ProtocolConformance">;
def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, Flags<[CC1Option]>,
HelpText<"Make migration to 'atomic' properties">;
HelpText<"Make migration to 'atomic' properties">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_AtomicProperty">;
def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, Flags<[CC1Option]>,
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">;
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ReturnsInnerPointerProperty">;
def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">;
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty">;
def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">;
HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">,
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_DesignatedInitializer">;

def objcmt_whitelist_dir_path: Joined<["-"], "objcmt-whitelist-dir-path=">, Flags<[CC1Option]>,
HelpText<"Only modify files with a filename contained in the provided directory path">;
// The misspelt "white-list" [sic] alias is due for removal.
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Frontend/ASTUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,6 @@ class ASTUnit {
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
unsigned PrecompilePreambleAfterNParses = 0,
bool CacheCodeCompletionResults = false,
bool IncludeBriefCommentsInCodeCompletion = false,
bool UserFilesAreVolatile = false,
std::unique_ptr<ASTUnit> *ErrAST = nullptr);

Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1450,8 +1450,6 @@ class ASTReader
void Error(StringRef Msg) const;
void Error(unsigned DiagID, StringRef Arg1 = StringRef(),
StringRef Arg2 = StringRef(), StringRef Arg3 = StringRef()) const;
void Error(unsigned DiagID, StringRef Arg1, StringRef Arg2,
unsigned Select) const;
void Error(llvm::Error &&Err) const;

public:
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7677,7 +7677,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
}

unsigned i = 0;
for (auto *Field : RDecl->fields()) {
for (FieldDecl *Field : RDecl->fields()) {
if (!Field->isZeroLengthBitField(*this) && Field->isZeroSize(*this))
continue;
uint64_t offs = layout.getFieldOffset(i);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
std::make_pair(offs, Field));
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
Expand Down Expand Up @@ -1295,6 +1296,14 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
HWASanPass(SanitizerKind::HWAddress, false);
HWASanPass(SanitizerKind::KernelHWAddress, true);

if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
PB.registerOptimizerLastEPCallback(
[this](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
MPM.addPass(
DataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles));
});
}

if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts, LangOpts))
PB.registerPipelineStartEPCallback(
[Options](ModulePassManager &MPM,
Expand Down
52 changes: 28 additions & 24 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10748,8 +10748,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
case NEON::BI__builtin_neon_vld2q_lane_v: {
llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
Ops.push_back(Ops[1]);
Ops.erase(Ops.begin()+1);
std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Expand All @@ -10762,8 +10761,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
case NEON::BI__builtin_neon_vld3q_lane_v: {
llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
Ops.push_back(Ops[1]);
Ops.erase(Ops.begin()+1);
std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
Expand All @@ -10777,8 +10775,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
case NEON::BI__builtin_neon_vld4q_lane_v: {
llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
Ops.push_back(Ops[1]);
Ops.erase(Ops.begin()+1);
std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
Expand All @@ -10791,50 +10788,44 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
}
case NEON::BI__builtin_neon_vst2_v:
case NEON::BI__builtin_neon_vst2q_v: {
Ops.push_back(Ops[0]);
Ops.erase(Ops.begin());
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
Ops, "");
}
case NEON::BI__builtin_neon_vst2_lane_v:
case NEON::BI__builtin_neon_vst2q_lane_v: {
Ops.push_back(Ops[0]);
Ops.erase(Ops.begin());
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
Ops, "");
}
case NEON::BI__builtin_neon_vst3_v:
case NEON::BI__builtin_neon_vst3q_v: {
Ops.push_back(Ops[0]);
Ops.erase(Ops.begin());
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
Ops, "");
}
case NEON::BI__builtin_neon_vst3_lane_v:
case NEON::BI__builtin_neon_vst3q_lane_v: {
Ops.push_back(Ops[0]);
Ops.erase(Ops.begin());
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
Ops, "");
}
case NEON::BI__builtin_neon_vst4_v:
case NEON::BI__builtin_neon_vst4q_v: {
Ops.push_back(Ops[0]);
Ops.erase(Ops.begin());
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
Ops, "");
}
case NEON::BI__builtin_neon_vst4_lane_v:
case NEON::BI__builtin_neon_vst4q_lane_v: {
Ops.push_back(Ops[0]);
Ops.erase(Ops.begin());
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
Expand Down Expand Up @@ -14776,6 +14767,19 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
break;
#include "clang/Basic/BuiltinsPPC.def"
}
if (BuiltinID == PPC::BI__builtin_mma_lxvp ||
BuiltinID == PPC::BI__builtin_mma_stxvp) {
if (BuiltinID == PPC::BI__builtin_mma_lxvp) {
Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]);
} else {
Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy);
Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]);
}
Ops.pop_back();
llvm::Function *F = CGM.getIntrinsic(ID);
return Builder.CreateCall(F, Ops, "");
}
SmallVector<Value*, 4> CallOps;
if (Accumulate) {
Address Addr = EmitPointerWithAlignment(E->getArg(0));
Expand Down Expand Up @@ -16412,24 +16416,24 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow_in_catch);
return Builder.CreateCall(Callee);
}
case WebAssembly::BI__builtin_wasm_atomic_wait_i32: {
case WebAssembly::BI__builtin_wasm_memory_atomic_wait32: {
Value *Addr = EmitScalarExpr(E->getArg(0));
Value *Expected = EmitScalarExpr(E->getArg(1));
Value *Timeout = EmitScalarExpr(E->getArg(2));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i32);
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_wait32);
return Builder.CreateCall(Callee, {Addr, Expected, Timeout});
}
case WebAssembly::BI__builtin_wasm_atomic_wait_i64: {
case WebAssembly::BI__builtin_wasm_memory_atomic_wait64: {
Value *Addr = EmitScalarExpr(E->getArg(0));
Value *Expected = EmitScalarExpr(E->getArg(1));
Value *Timeout = EmitScalarExpr(E->getArg(2));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i64);
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_wait64);
return Builder.CreateCall(Callee, {Addr, Expected, Timeout});
}
case WebAssembly::BI__builtin_wasm_atomic_notify: {
case WebAssembly::BI__builtin_wasm_memory_atomic_notify: {
Value *Addr = EmitScalarExpr(E->getArg(0));
Value *Count = EmitScalarExpr(E->getArg(1));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_notify);
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_notify);
return Builder.CreateCall(Callee, {Addr, Count});
}
case WebAssembly::BI__builtin_wasm_trunc_s_i32_f32:
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/Frontend/ASTUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1520,8 +1520,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile,
std::unique_ptr<ASTUnit> *ErrAST) {
bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
assert(CI && "A CompilerInvocation is required");

std::unique_ptr<ASTUnit> OwnAST;
Expand All @@ -1544,8 +1543,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
AST->IncludeBriefCommentsInCodeCompletion
= IncludeBriefCommentsInCodeCompletion;
AST->IncludeBriefCommentsInCodeCompletion = false;

// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
Expand Down
129 changes: 62 additions & 67 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ CompilerInvocationBase::~CompilerInvocationBase() = default;
#include "clang/Driver/Options.inc"
#undef SIMPLE_ENUM_VALUE_TABLE

static llvm::Optional<bool> normalizeSimpleFlag(OptSpecifier Opt,
unsigned TableIndex,
const ArgList &Args,
DiagnosticsEngine &Diags) {
if (Args.hasArg(Opt))
return true;
return None;
}

template <typename T, T Value>
static llvm::Optional<T>
normalizeFlagToValue(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args,
DiagnosticsEngine &Diags) {
if (Args.hasArg(Opt))
return Value;
return None;
}

static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
unsigned TableIndex,
const ArgList &Args,
Expand All @@ -146,22 +164,26 @@ static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
return None;
}

static const char *denormalizeSimpleEnum(CompilerInvocation::StringAllocator SA,
unsigned TableIndex, unsigned Value) {
static void denormalizeSimpleEnum(SmallVectorImpl<const char *> &Args,
CompilerInvocation::StringAllocator SA,
unsigned TableIndex, unsigned Value) {
assert(TableIndex < SimpleEnumValueTablesSize);
const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
for (int I = 0, E = Table.Size; I != E; ++I)
if (Value == Table.Table[I].Value)
return Table.Table[I].Name;
for (int I = 0, E = Table.Size; I != E; ++I) {
if (Value == Table.Table[I].Value) {
Args.push_back(Table.Table[I].Name);
return;
}
}

llvm_unreachable("The simple enum value was not correctly defined in "
"the tablegen option description");
}

static const char *denormalizeString(CompilerInvocation::StringAllocator SA,
unsigned TableIndex,
const std::string &Value) {
return SA(Value);
static void denormalizeString(SmallVectorImpl<const char *> &Args,
CompilerInvocation::StringAllocator SA,
unsigned TableIndex, const std::string &Value) {
Args.push_back(SA(Value));
}

static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
Expand All @@ -173,6 +195,24 @@ static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
return llvm::Triple::normalize(Arg->getValue());
}

template <typename T, typename U>
static T mergeForwardValue(T KeyPath, U Value) {
return Value;
}

template <typename T, typename U> static T mergeMaskValue(T KeyPath, U Value) {
return KeyPath | Value;
}

template <typename T> static T extractForwardValue(T KeyPath) {
return KeyPath;
}

template <typename T, typename U, U Value>
static T extractMaskValue(T KeyPath) {
return KeyPath & Value;
}

//===----------------------------------------------------------------------===//
// Deserialization (from args)
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -2010,37 +2050,6 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ARCMTMigrateEmitARCErrors
= Args.hasArg(OPT_arcmt_migrate_emit_arc_errors);

if (Args.hasArg(OPT_objcmt_migrate_literals))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals;
if (Args.hasArg(OPT_objcmt_migrate_subscripting))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting;
if (Args.hasArg(OPT_objcmt_migrate_property_dot_syntax))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_PropertyDotSyntax;
if (Args.hasArg(OPT_objcmt_migrate_property))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property;
if (Args.hasArg(OPT_objcmt_migrate_readonly_property))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadonlyProperty;
if (Args.hasArg(OPT_objcmt_migrate_readwrite_property))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadwriteProperty;
if (Args.hasArg(OPT_objcmt_migrate_annotation))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Annotation;
if (Args.hasArg(OPT_objcmt_returns_innerpointer_property))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReturnsInnerPointerProperty;
if (Args.hasArg(OPT_objcmt_migrate_instancetype))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Instancetype;
if (Args.hasArg(OPT_objcmt_migrate_nsmacros))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsMacros;
if (Args.hasArg(OPT_objcmt_migrate_protocol_conformance))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ProtocolConformance;
if (Args.hasArg(OPT_objcmt_atomic_property))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty;
if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty;
if (Args.hasArg(OPT_objcmt_migrate_designated_init))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer;
if (Args.hasArg(OPT_objcmt_migrate_all))
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls;

Opts.ObjCMTWhiteListPath =
std::string(Args.getLastArgValue(OPT_objcmt_whitelist_dir_path));

Expand Down Expand Up @@ -3722,26 +3731,18 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,

bool CompilerInvocation::parseSimpleArgs(const ArgList &Args,
DiagnosticsEngine &Diags) {
#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \
ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \
METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \
KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \
this->KEYPATH = (Args.hasArg(OPT_##ID) && IS_POSITIVE) || (DEFAULT_VALUE);

#define OPTION_WITH_MARSHALLING_STRING( \
#define OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
TYPE, NORMALIZER, DENORMALIZER, TABLE_INDEX) \
TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
{ \
this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE); \
if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \
this->KEYPATH = static_cast<TYPE>(*MaybeValue); \
else \
this->KEYPATH = DEFAULT_VALUE; \
this->KEYPATH = MERGER(this->KEYPATH, static_cast<TYPE>(*MaybeValue)); \
}

#include "clang/Driver/Options.inc"
#undef OPTION_WITH_MARSHALLING_STRING
#undef OPTION_WITH_MARSHALLING_FLAG
#undef OPTION_WITH_MARSHALLING
return true;
}

Expand Down Expand Up @@ -3996,29 +3997,23 @@ std::string CompilerInvocation::getModuleHash() const {

void CompilerInvocation::generateCC1CommandLine(
SmallVectorImpl<const char *> &Args, StringAllocator SA) const {
#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \
ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \
METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \
KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \
if ((FLAGS) & options::CC1Option && \
(ALWAYS_EMIT || this->KEYPATH != (DEFAULT_VALUE))) \
Args.push_back(SPELLING);

#define OPTION_WITH_MARSHALLING_STRING( \
#define OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
NORMALIZER_RET_TY, NORMALIZER, DENORMALIZER, TABLE_INDEX) \
TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
if (((FLAGS) & options::CC1Option) && \
(ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) { \
(ALWAYS_EMIT || EXTRACTOR(this->KEYPATH) != (DEFAULT_VALUE))) { \
if (Option::KIND##Class == Option::FlagClass) { \
Args.push_back(SPELLING); \
} \
if (Option::KIND##Class == Option::SeparateClass) { \
Args.push_back(SPELLING); \
Args.push_back(DENORMALIZER(SA, TABLE_INDEX, this->KEYPATH)); \
DENORMALIZER(Args, SA, TABLE_INDEX, EXTRACTOR(this->KEYPATH)); \
} \
}

#include "clang/Driver/Options.inc"
#undef OPTION_WITH_MARSHALLING_STRING
#undef OPTION_WITH_MARSHALLING_FLAG
#undef OPTION_WITH_MARSHALLING
}

IntrusiveRefCntPtr<llvm::vfs::FileSystem>
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1593,7 +1593,8 @@ void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
if (!AL.isCXX11Attribute() && !AL.isC2xAttribute())
continue;
if (AL.getKind() == ParsedAttr::UnknownAttribute)
Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL;
Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
<< AL << AL.getRange();
else {
Diag(AL.getLoc(), DiagID) << AL;
AL.setInvalid();
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,8 @@ void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
} else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
DC = FN;
} else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
DC = cast<DeclContext>(TD->getTemplatedDecl());
if (isa<DeclContext>(TD->getTemplatedDecl()))
DC = cast<DeclContext>(TD->getTemplatedDecl());
}

EffectiveContext EC(DC);
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2055,7 +2055,8 @@ bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
// Check whether the attribute is valid on the current target.
if (!AL.existsInTarget(Context.getTargetInfo())) {
Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL;
Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
<< AL << AL.getRange();
AL.setInvalid();
return true;
}
Expand Down Expand Up @@ -7362,7 +7363,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
AL.isDeclspecAttribute()
? (unsigned)diag::warn_unhandled_ms_attribute_ignored
: (unsigned)diag::warn_unknown_attribute_ignored)
<< AL;
<< AL << AL.getRange();
return;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2612,7 +2612,7 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
Diag(AL.getLoc(), AL.getKind() == ParsedAttr::UnknownAttribute
? (unsigned)diag::warn_unknown_attribute_ignored
: (unsigned)diag::err_base_specifier_attribute)
<< AL;
<< AL << AL.getRange();
}

TypeSourceInfo *TInfo = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaStmtAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
S.Diag(A.getLoc(), A.isDeclspecAttribute()
? (unsigned)diag::warn_unhandled_ms_attribute_ignored
: (unsigned)diag::warn_unknown_attribute_ignored)
<< A;
<< A << A.getRange();
return nullptr;
case ParsedAttr::AT_FallThrough:
return handleFallThroughAttr(S, St, A, Range);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8091,7 +8091,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
if (attr.isCXX11Attribute() && TAL == TAL_DeclChunk)
state.getSema().Diag(attr.getLoc(),
diag::warn_unknown_attribute_ignored)
<< attr;
<< attr << attr.getRange();
break;

case ParsedAttr::IgnoredAttribute:
Expand Down
41 changes: 13 additions & 28 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1246,12 +1246,6 @@ void ASTReader::Error(unsigned DiagID, StringRef Arg1, StringRef Arg2,
Diag(DiagID) << Arg1 << Arg2 << Arg3;
}

void ASTReader::Error(unsigned DiagID, StringRef Arg1, StringRef Arg2,
unsigned Select) const {
if (!Diags.isDiagnosticInFlight())
Diag(DiagID) << Arg1 << Arg2 << Select;
}

void ASTReader::Error(llvm::Error &&Err) const {
Error(toString(std::move(Err)));
}
Expand Down Expand Up @@ -2395,37 +2389,28 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
auto FileChange = HasInputFileChanged();
// For an overridden file, there is nothing to validate.
if (!Overridden && FileChange != ModificationType::None) {
if (Complain) {
if (Complain && !Diags.isDiagnosticInFlight()) {
// Build a list of the PCH imports that got us here (in reverse).
SmallVector<ModuleFile *, 4> ImportStack(1, &F);
while (!ImportStack.back()->ImportedBy.empty())
ImportStack.push_back(ImportStack.back()->ImportedBy[0]);

// The top-level PCH is stale.
StringRef TopLevelPCHName(ImportStack.back()->FileName);
unsigned DiagnosticKind =
moduleKindForDiagnostic(ImportStack.back()->Kind);
if (DiagnosticKind == 0)
Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName,
(unsigned)FileChange);
else if (DiagnosticKind == 1)
Error(diag::err_fe_module_file_modified, Filename, TopLevelPCHName,
(unsigned)FileChange);
else
Error(diag::err_fe_ast_file_modified, Filename, TopLevelPCHName,
(unsigned)FileChange);
Diag(diag::err_fe_ast_file_modified)
<< Filename << moduleKindForDiagnostic(ImportStack.back()->Kind)
<< TopLevelPCHName << FileChange;

// Print the import stack.
if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) {
if (ImportStack.size() > 1) {
Diag(diag::note_pch_required_by)
<< Filename << ImportStack[0]->FileName;
for (unsigned I = 1; I < ImportStack.size(); ++I)
Diag(diag::note_pch_required_by)
<< ImportStack[I-1]->FileName << ImportStack[I]->FileName;
}

if (!Diags.isDiagnosticInFlight())
Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
}

IsOutOfDate = true;
Expand Down Expand Up @@ -4512,9 +4497,9 @@ ASTReader::ReadASTCore(StringRef FileName,
return Missing;

// Otherwise, return an error.
Diag(diag::err_module_file_not_found) << moduleKindForDiagnostic(Type)
<< FileName << !ErrorStr.empty()
<< ErrorStr;
Diag(diag::err_ast_file_not_found)
<< moduleKindForDiagnostic(Type) << FileName << !ErrorStr.empty()
<< ErrorStr;
return Failure;

case ModuleManager::OutOfDate:
Expand All @@ -4524,9 +4509,9 @@ ASTReader::ReadASTCore(StringRef FileName,
return OutOfDate;

// Otherwise, return an error.
Diag(diag::err_module_file_out_of_date) << moduleKindForDiagnostic(Type)
<< FileName << !ErrorStr.empty()
<< ErrorStr;
Diag(diag::err_ast_file_out_of_date)
<< moduleKindForDiagnostic(Type) << FileName << !ErrorStr.empty()
<< ErrorStr;
return Failure;
}

Expand All @@ -4547,7 +4532,7 @@ ASTReader::ReadASTCore(StringRef FileName,

// Sniff for the signature.
if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) {
Diag(diag::err_module_file_invalid)
Diag(diag::err_ast_file_invalid)
<< moduleKindForDiagnostic(Type) << FileName << std::move(Err);
return Failure;
}
Expand Down
14 changes: 0 additions & 14 deletions clang/test/CodeGen/O0-no-skipped-passes.c

This file was deleted.

159 changes: 159 additions & 0 deletions clang/test/CodeGen/builtins-ppc-mma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,3 +1036,162 @@ void test65(unsigned char *vqp, unsigned char *vpp, vector unsigned char vc, uns
__builtin_mma_pmxvbf16ger2nn(&vq, vc, vc, 0, 0, 0);
*((__vector_quad *)resp) = vq;
}

// CHECK-LABEL: @test66(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = bitcast <256 x i1>* [[VP2:%.*]] to i8*
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP1]], i8* [[TMP2]])
// CHECK-NEXT: ret void
//
void test66(const __vector_pair *vpp, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(0LL, vpp);
__builtin_mma_stxvp(vp, 0LL, vp2);
}

// CHECK-LABEL: @test67(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[TMP0]], i64 [[OFFSET:%.*]]
// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = bitcast <256 x i1>* [[VP2:%.*]] to i8*
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[TMP3]], i64 [[OFFSET]]
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP2]], i8* [[TMP4]])
// CHECK-NEXT: ret void
//
void test67(const __vector_pair *vpp, signed long long offset, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(offset, vpp);
__builtin_mma_stxvp(vp, offset, vp2);
}

// CHECK-LABEL: @test68(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[TMP0]], i64 18
// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = bitcast <256 x i1>* [[VP2:%.*]] to i8*
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[TMP3]], i64 18
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP2]], i8* [[TMP4]])
// CHECK-NEXT: ret void
//
void test68(const __vector_pair *vpp, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(18LL, vpp);
__builtin_mma_stxvp(vp, 18LL, vp2);
}

// CHECK-LABEL: @test69(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[TMP0]], i64 1
// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = bitcast <256 x i1>* [[VP2:%.*]] to i8*
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[TMP3]], i64 1
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP2]], i8* [[TMP4]])
// CHECK-NEXT: ret void
//
void test69(const __vector_pair *vpp, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(1LL, vpp);
__builtin_mma_stxvp(vp, 1LL, vp2);
}

// CHECK-LABEL: @test70(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[TMP0]], i64 42
// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = bitcast <256 x i1>* [[VP2:%.*]] to i8*
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[TMP3]], i64 42
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP2]], i8* [[TMP4]])
// CHECK-NEXT: ret void
//
void test70(const __vector_pair *vpp, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(42LL, vpp);
__builtin_mma_stxvp(vp, 42LL, vp2);
}

// CHECK-LABEL: @test71(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr <256 x i1>, <256 x i1>* [[VPP:%.*]], i64 128
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <256 x i1>* [[TMP0]] to i8*
// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr <256 x i1>, <256 x i1>* [[VP2:%.*]], i64 128
// CHECK-NEXT: [[TMP4:%.*]] = bitcast <256 x i1>* [[TMP3]] to i8*
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP2]], i8* [[TMP4]])
// CHECK-NEXT: ret void
//
void test71(const __vector_pair *vpp, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(32768LL, vpp);
__builtin_mma_stxvp(vp, 32768LL, vp2);
}

// CHECK-LABEL: @test72(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[TMP0]], i64 32799
// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = bitcast <256 x i1>* [[VP2:%.*]] to i8*
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[TMP3]], i64 32799
// CHECK-NEXT: tail call void @llvm.ppc.mma.stxvp(<256 x i1> [[TMP2]], i8* [[TMP4]])
// CHECK-NEXT: ret void
//
void test72(const __vector_pair *vpp, const __vector_pair *vp2) {
__vector_pair vp = __builtin_mma_lxvp(32799LL, vpp);
__builtin_mma_stxvp(vp, 32799LL, vp2);
}

// CHECK-LABEL: @test73(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[VQP:%.*]] to <512 x i1>*
// CHECK-NEXT: [[TMP1:%.*]] = load <512 x i1>, <512 x i1>* [[TMP0]], align 64, [[TBAA2:!tbaa !.*]]
// CHECK-NEXT: [[TMP2:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, i8* [[TMP2]], i64 8
// CHECK-NEXT: [[TMP4:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP3]])
// CHECK-NEXT: [[TMP5:%.*]] = tail call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> [[TMP1]], <256 x i1> [[TMP4]], <16 x i8> [[VC:%.*]], i32 0, i32 0)
// CHECK-NEXT: [[TMP6:%.*]] = bitcast i8* [[RESP:%.*]] to <512 x i1>*
// CHECK-NEXT: store <512 x i1> [[TMP5]], <512 x i1>* [[TMP6]], align 64, [[TBAA2]]
// CHECK-NEXT: ret void
//
void test73(unsigned char *vqp, const __vector_pair *vpp, vector unsigned char vc, unsigned char *resp) {
__vector_quad vq = *((__vector_quad *)vqp);
__vector_pair vp = __builtin_mma_lxvp(8LL, vpp);
__builtin_mma_pmxvf64gernn(&vq, vp, vc, 0, 0);
*((__vector_quad *)resp) = vq;
}

// CHECK-LABEL: @test74(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[VQP:%.*]] to <512 x i1>*
// CHECK-NEXT: [[TMP1:%.*]] = load <512 x i1>, <512 x i1>* [[TMP0]], align 64, [[TBAA2]]
// CHECK-NEXT: [[TMP2:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP3:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP2]])
// CHECK-NEXT: [[TMP4:%.*]] = tail call <512 x i1> @llvm.ppc.mma.xvf64gernp(<512 x i1> [[TMP1]], <256 x i1> [[TMP3]], <16 x i8> [[VC:%.*]])
// CHECK-NEXT: [[TMP5:%.*]] = bitcast i8* [[RESP:%.*]] to <512 x i1>*
// CHECK-NEXT: store <512 x i1> [[TMP4]], <512 x i1>* [[TMP5]], align 64, [[TBAA2]]
// CHECK-NEXT: ret void
//
void test74(unsigned char *vqp, const __vector_pair *vpp, vector unsigned char vc, unsigned char *resp) {
__vector_quad vq = *((__vector_quad *)vqp);
__vector_pair vp = __builtin_mma_lxvp(0LL, vpp);
__builtin_mma_xvf64gernp(&vq, vp, vc);
*((__vector_quad *)resp) = vq;
}

// CHECK-LABEL: @test75(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[VQP:%.*]] to <512 x i1>*
// CHECK-NEXT: [[TMP1:%.*]] = load <512 x i1>, <512 x i1>* [[TMP0]], align 64, [[TBAA2:!tbaa !.*]]
// CHECK-NEXT: [[TMP2:%.*]] = bitcast <256 x i1>* [[VPP:%.*]] to i8*
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, i8* [[TMP2]], i64 [[OFFS:%.*]]
// CHECK-NEXT: [[TMP4:%.*]] = tail call <256 x i1> @llvm.ppc.mma.lxvp(i8* [[TMP3]])
// CHECK-NEXT: [[TMP5:%.*]] = tail call <512 x i1> @llvm.ppc.mma.xvf64gernp(<512 x i1> [[TMP1]], <256 x i1> [[TMP4]], <16 x i8> [[VC:%.*]])
// CHECK-NEXT: [[TMP6:%.*]] = bitcast i8* [[RESP:%.*]] to <512 x i1>*
// CHECK-NEXT: store <512 x i1> [[TMP5]], <512 x i1>* [[TMP6]], align 64, [[TBAA2]]
// CHECK-NEXT: ret void
//
void test75(unsigned char *vqp, signed long long offs, const __vector_pair *vpp, vector unsigned char vc, unsigned char *resp) {
__vector_quad vq = *((__vector_quad *)vqp);
__vector_pair vp = __builtin_mma_lxvp(offs, vpp);
__builtin_mma_xvf64gernp(&vq, vp, vc);
*((__vector_quad *)resp) = vq;
}
24 changes: 12 additions & 12 deletions clang/test/CodeGen/builtins-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,22 @@ void rethrow_in_catch(void) {
// WEBASSEMBLY64: call void @llvm.wasm.rethrow.in.catch()
}

int atomic_wait_i32(int *addr, int expected, long long timeout) {
return __builtin_wasm_atomic_wait_i32(addr, expected, timeout);
// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
int memory_atomic_wait32(int *addr, int expected, long long timeout) {
return __builtin_wasm_memory_atomic_wait32(addr, expected, timeout);
// WEBASSEMBLY32: call i32 @llvm.wasm.memory.atomic.wait32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.memory.atomic.wait32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
}

int atomic_wait_i64(long long *addr, long long expected, long long timeout) {
return __builtin_wasm_atomic_wait_i64(addr, expected, timeout);
// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
int memory_atomic_wait64(long long *addr, long long expected, long long timeout) {
return __builtin_wasm_memory_atomic_wait64(addr, expected, timeout);
// WEBASSEMBLY32: call i32 @llvm.wasm.memory.atomic.wait64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.memory.atomic.wait64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
}

unsigned int atomic_notify(int *addr, unsigned int count) {
return __builtin_wasm_atomic_notify(addr, count);
// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
unsigned int memory_atomic_notify(int *addr, unsigned int count) {
return __builtin_wasm_memory_atomic_notify(addr, count);
// WEBASSEMBLY32: call i32 @llvm.wasm.memory.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
// WEBASSEMBLY64: call i32 @llvm.wasm.memory.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
}

int trunc_s_i32_f32(float f) {
Expand Down
27 changes: 27 additions & 0 deletions clang/test/CodeGen/no-skipped-passes-O0-opt-bisect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Test that no passes are skipped under NPM with -O0/opt-bisect
//
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fcoroutines-ts 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=address 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=hwaddress 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=memory 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=thread 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=local-bounds 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=dataflow 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize-coverage-trace-pc-guard 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -enable-npm-optnone -O0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fmemory-profile 2>&1 | FileCheck %s

// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fcoroutines-ts 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=address 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=hwaddress 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=memory 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=thread 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=local-bounds 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize=dataflow 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fsanitize-coverage-trace-pc-guard 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -mllvm -opt-bisect-limit=0 -fexperimental-new-pass-manager %s -fdebug-pass-manager -emit-llvm -o /dev/null -fmemory-profile 2>&1 | FileCheck %s

// CHECK-NOT: Skipping pass

int func(int a) { return a; }
6 changes: 0 additions & 6 deletions clang/test/CodeGenCXX/wasm-eh.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
// REQUIRES: webassembly-registered-target
// https://reviews.llvm.org/D79655 temporarily added a RUN line that was missing
// a -o flag and wrote to the source dir. The file it wrote was then interpreted
// as a test without RUN line, breaking bots. FIXME: Remove this rm line once
// it's been in the tree long enough to clean up everyone's build dirs.
// Removing this June 2020 should be fine.
// RUN: rm -f %S/wasm-eh.ll
// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s

Expand Down
31 changes: 23 additions & 8 deletions clang/test/CodeGenObjCXX/encode.mm
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=gnu++98 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++98 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX98 %s
// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20 %s

// CHECK: v17@0:8{vector<float, float, float>=}16
// CHECK: {vector<float, float, float>=}
Expand Down Expand Up @@ -87,7 +88,9 @@ @implementation RedBalloonHGXFormWrapper

typedef vector< float, fixed<4> > vector4f;

// CHECK: @_ZN11rdar93574002ggE = constant [49 x i8] c"{vector<float, rdar9357400::fixed<4, -1> >=[4f]}\00"
// FIXME: This difference is due to D76801. It was probably an unintentional change. Maybe we want to undo it?
// CHECKCXX98: @_ZN11rdar93574002ggE = constant [49 x i8] c"{vector<float, rdar9357400::fixed<4, -1> >=[4f]}\00"
// CHECKCXX20: @_ZN11rdar93574002ggE = constant [48 x i8] c"{vector<float, rdar9357400::fixed<4, -1>>=[4f]}\00"
extern const char gg[] = @encode(vector4f);
}

Expand Down Expand Up @@ -170,21 +173,21 @@ @implementation RedBalloonHGXFormWrapper


// PR10990
class CefBase {
struct CefBase {
virtual ~CefBase() {}
};
class CefBrowser : public virtual CefBase {};
class CefBrowserImpl : public CefBrowser {};
struct CefBrowser : public virtual CefBase {};
struct CefBrowserImpl : public CefBrowser {};
// CHECK: @g6 = constant [21 x i8] c"{CefBrowserImpl=^^?}\00"
extern const char g6[] = @encode(CefBrowserImpl);

// PR10990_2
class CefBase2 {
struct CefBase2 {
virtual ~CefBase2() {}
int i;
};
class CefBrowser2 : public virtual CefBase2 {};
class CefBrowserImpl2 : public CefBrowser2 {};
struct CefBrowser2 : public virtual CefBase2 {};
struct CefBrowserImpl2 : public CefBrowser2 {};
// CHECK: @g7 = constant [26 x i8] c"{CefBrowserImpl2=^^?^^?i}\00"
extern const char g7[] = @encode(CefBrowserImpl2);

Expand Down Expand Up @@ -245,3 +248,15 @@ @implementation N
// CHECK: @{{.*}} = private unnamed_addr constant [13 x i8] c"{N={S<N>=@}}\00"
return @encode(N);
}

#if __cplusplus >= 202002L
namespace PR48048 {
struct F {};
struct I {
int m;
[[no_unique_address]] F n;
};
// CHECKCXX20: @_ZN7PR480481xE = constant [6 x i8] c"{I=i}\00"
extern const char x[] = @encode(I);
}
#endif
14 changes: 14 additions & 0 deletions clang/test/Sema/ppc-mma-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,17 @@ void testVPOperators4(int v, void *ptr) {
__vector_pair vp2 = (__vector_pair)vpp; // expected-error {{used type '__vector_pair' where arithmetic or pointer type is required}}
}

void testBuiltinTypes1(const __vector_pair *vpp, const __vector_pair *vp2, float f) {
__vector_pair vp = __builtin_mma_lxvp(f, vpp); // expected-error {{passing 'float' to parameter of incompatible type 'long long'}}
__builtin_mma_stxvp(vp, 32799, vp2); // expected-error {{passing 'int' to parameter of incompatible type 'long long'}}
}

void testBuiltinTypes2(__vector_pair *vpp, const __vector_pair *vp2, unsigned char c) {
__vector_pair vp = __builtin_mma_lxvp(6LL, vpp); // expected-error {{passing '__vector_pair *' to parameter of incompatible type 'const __vector_pair *'}}
__builtin_mma_stxvp(vp, c, vp2); // expected-error {{passing 'unsigned char' to parameter of incompatible type 'long long'}}
}

void testBuiltinTypes3(vector int v, __vector_pair *vp2, signed long long ll, unsigned short s) {
__vector_pair vp = __builtin_mma_lxvp(ll, v); // expected-error {{passing '__vector int' (vector of 4 'int' values) to parameter of incompatible type 'const __vector_pair *'}}
__builtin_mma_stxvp(vp, ll, s); // expected-error {{passing 'unsigned short' to parameter of incompatible type 'const __vector_pair *'}}
}
13 changes: 13 additions & 0 deletions clang/test/SemaCXX/cxx14-access.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s

namespace NoCrashOnDelayedAccessCheck {
class Foo {
class Private; // expected-note {{declared private here}}
};

struct Bar {};

template <typename T>
Foo::Private Bar::ABC; // expected-error {{no member named 'ABC' in 'NoCrashOnDelayedAccessCheck::Bar'}} \
expected-error {{'Private' is a private member of}}
}
4 changes: 1 addition & 3 deletions clang/tools/libclang/Indexing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,7 @@ static CXErrorCode clang_indexSourceFile_Impl(
std::move(CInvok), CXXIdx->getPCHContainerOperations(), Diags,
IndexAction.get(), UPtr, Persistent, CXXIdx->getClangResourcesPath(),
OnlyLocalDecls, CaptureDiagnostics, PrecompilePreambleAfterNParses,
CacheCodeCompletionResults,
/*IncludeBriefCommentsInCodeCompletion=*/false,
/*UserFilesAreVolatile=*/true);
CacheCodeCompletionResults, /*UserFilesAreVolatile=*/true);
if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
printDiagsToStderr(UPtr);

Expand Down
26 changes: 18 additions & 8 deletions compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,17 @@ TEST(ScudoQuarantineTest, GlobalQuarantine) {
Str.output();
}

void *populateQuarantine(void *Param) {
struct PopulateQuarantineThread {
pthread_t Thread;
QuarantineT *Quarantine;
CacheT Cache;
Cache.init();
QuarantineT *Quarantine = reinterpret_cast<QuarantineT *>(Param);
};

void *populateQuarantine(void *Param) {
PopulateQuarantineThread *P = static_cast<PopulateQuarantineThread *>(Param);
P->Cache.init();
for (scudo::uptr I = 0; I < 128UL; I++)
Quarantine->put(&Cache, Cb, FakePtr, LargeBlockSize);
P->Quarantine->put(&P->Cache, Cb, FakePtr, LargeBlockSize);
return 0;
}

Expand All @@ -233,13 +238,18 @@ TEST(ScudoQuarantineTest, ThreadedGlobalQuarantine) {
Quarantine.init(MaxQuarantineSize, MaxCacheSize);

const scudo::uptr NumberOfThreads = 32U;
pthread_t T[NumberOfThreads];
for (scudo::uptr I = 0; I < NumberOfThreads; I++)
pthread_create(&T[I], 0, populateQuarantine, &Quarantine);
PopulateQuarantineThread T[NumberOfThreads];
for (scudo::uptr I = 0; I < NumberOfThreads; I++) {
T[I].Quarantine = &Quarantine;
pthread_create(&T[I].Thread, 0, populateQuarantine, &T[I]);
}
for (scudo::uptr I = 0; I < NumberOfThreads; I++)
pthread_join(T[I], 0);
pthread_join(T[I].Thread, 0);

scudo::ScopedString Str(1024);
Quarantine.getStats(&Str);
Str.output();

for (scudo::uptr I = 0; I < NumberOfThreads; I++)
Quarantine.drainAndRecycle(&T[I].Cache, Cb);
}
8 changes: 7 additions & 1 deletion flang/lib/Evaluate/fold-implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,13 @@ auto ApplyElementwise(FoldingContext &context,
if (rightExpr.Rank() > 0) {
if (std::optional<Shape> rightShape{GetShape(context, rightExpr)}) {
if (auto right{AsFlatArrayConstructor(rightExpr)}) {
CheckConformance(context.messages(), *leftShape, *rightShape);
if (CheckConformance(
context.messages(), *leftShape, *rightShape)) {
return MapOperation(context, std::move(f), *leftShape,
std::move(*left), std::move(*right));
} else {
return std::nullopt;
}
return MapOperation(context, std::move(f), *leftShape,
std::move(*left), std::move(*right));
}
Expand Down
21 changes: 12 additions & 9 deletions flang/lib/Evaluate/shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,8 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
return std::nullopt;
}

// Check conformance of the passed shapes. Only return true if we can verify
// that they conform
bool CheckConformance(parser::ContextualMessages &messages, const Shape &left,
const Shape &right, const char *leftIs, const char *rightIs) {
int n{GetRank(left)};
Expand All @@ -693,15 +695,16 @@ bool CheckConformance(parser::ContextualMessages &messages, const Shape &left,
return false;
} else {
for (int j{0}; j < n; ++j) {
if (auto leftDim{ToInt64(left[j])}) {
if (auto rightDim{ToInt64(right[j])}) {
if (*leftDim != *rightDim) {
messages.Say("Dimension %1$d of %2$s has extent %3$jd, "
"but %4$s has extent %5$jd"_err_en_US,
j + 1, leftIs, *leftDim, rightIs, *rightDim);
return false;
}
}
auto leftDim{ToInt64(left[j])};
auto rightDim{ToInt64(right[j])};
if (!leftDim || !rightDim) {
return false;
}
if (*leftDim != *rightDim) {
messages.Say("Dimension %1$d of %2$s has extent %3$jd, "
"but %4$s has extent %5$jd"_err_en_US,
j + 1, leftIs, *leftDim, rightIs, *rightDim);
return false;
}
}
}
Expand Down
41 changes: 41 additions & 0 deletions flang/test/Semantics/shape.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
! RUN: %S/test_errors.sh %s %t %f18
! Test comparisons that use the intrinsic SHAPE() as an operand
program testShape
contains
subroutine sub1(arrayDummy)
integer :: arrayDummy(:)
integer, allocatable :: arrayDeferred(:)
integer :: arrayLocal(2) = [88, 99]
if (all(shape(arrayDummy)==shape(8))) then
print *, "hello"
end if
if (all(shape(27)==shape(arrayDummy))) then
print *, "hello"
end if
if (all(64==shape(arrayDummy))) then
print *, "hello"
end if
if (all(shape(arrayDeferred)==shape(8))) then
print *, "hello"
end if
if (all(shape(27)==shape(arrayDeferred))) then
print *, "hello"
end if
if (all(64==shape(arrayDeferred))) then
print *, "hello"
end if
!ERROR: Dimension 1 of left operand has extent 1, but right operand has extent 0
!ERROR: Dimension 1 of left operand has extent 1, but right operand has extent 0
if (all(shape(arrayLocal)==shape(8))) then
print *, "hello"
end if
!ERROR: Dimension 1 of left operand has extent 0, but right operand has extent 1
!ERROR: Dimension 1 of left operand has extent 0, but right operand has extent 1
if (all(shape(27)==shape(arrayLocal))) then
print *, "hello"
end if
if (all(64==shape(arrayLocal))) then
print *, "hello"
end if
end subroutine sub1
end program testShape
1 change: 1 addition & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ set(files
support/fuchsia/xlocale.h
support/ibm/limits.h
support/ibm/locale_mgmt_aix.h
support/ibm/nanosleep.h
support/ibm/support.h
support/ibm/xlocale.h
support/musl/xlocale.h
Expand Down
4 changes: 4 additions & 0 deletions libcxx/include/__threading_support
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include <iosfwd>
#include <errno.h>

#ifdef __MVS__
# include <support/ibm/nanosleep.h>
#endif

#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
#pragma GCC system_header
#endif
Expand Down
38 changes: 38 additions & 0 deletions libcxx/include/support/ibm/nanosleep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
#define _LIBCPP_SUPPORT_IBM_NANOSLEEP_H

#include <unistd.h>

inline int nanosleep(const struct timespec* req, struct timespec* rem)
{
// The nanosleep() function is not available on z/OS. Therefore, we will call
// sleep() to sleep for whole seconds and usleep() to sleep for any remaining
// fraction of a second. Any remaining nanoseconds will round up to the next
// microsecond.

useconds_t __micro_sec = (rem->tv_nsec + 999) / 1000;
if (__micro_sec > 999999)
{
++rem->tv_sec;
__micro_sec -= 1000000;
}
while (rem->tv_sec)
rem->tv_sec = sleep(rem->tv_sec);
if (__micro_sec) {
rem->tv_nsec = __micro_sec * 1000;
return usleep(__micro_sec);
}
rem->tv_nsec = 0;
return 0;
}

#endif // _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
39 changes: 26 additions & 13 deletions libcxx/src/filesystem/filesystem_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ struct ErrorHandler {
using chrono::duration;
using chrono::duration_cast;

using TimeSpec = timespec;
using TimeSpec = struct timespec;
using TimeVal = struct timeval;
using StatT = struct stat;

template <class FileTimeT, class TimeT,
Expand Down Expand Up @@ -381,26 +382,38 @@ struct time_util : time_util_base<FileTimeT, TimeT> {
using fs_time = time_util<file_time_type, time_t, TimeSpec>;

#if defined(__APPLE__)
TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
#elif defined(__MVS__)
inline TimeSpec extract_mtime(StatT const& st) {
TimeSpec TS = {st.st_mtime, 0};
return TS;
}
inline TimeSpec extract_atime(StatT const& st) {
TimeSpec TS = {st.st_atime, 0};
return TS;
}
#else
TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
#endif

// allow the utimes implementation to compile even it we're not going
// to use it.

bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
error_code& ec) {
inline TimeVal make_timeval(TimeSpec const& ts) {
using namespace chrono;
auto Convert = [](long nsec) {
using int_type = decltype(std::declval< ::timeval>().tv_usec);
using int_type = decltype(std::declval<TimeVal>().tv_usec);
auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
return static_cast<int_type>(dur);
};
struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)},
{TS[1].tv_sec, Convert(TS[1].tv_nsec)}};
TimeVal TV = {};
TV.tv_sec = ts.tv_sec;
TV.tv_usec = Convert(ts.tv_nsec);
return TV;
}

inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
error_code& ec) {
TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
if (::utimes(p.c_str(), ConvertedTS) == -1) {
ec = capture_errno();
return true;
Expand Down
25 changes: 19 additions & 6 deletions libcxx/src/include/refstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@
#include <stdexcept>
#include <cstddef>
#include <cstring>
#ifdef __APPLE__
#include <dlfcn.h>
#include <mach-o/dyld.h>
#endif
#include "atomic_support.h"

// MacOS and iOS used to ship with libstdc++, and still support old applications
// linking against libstdc++. The libc++ and libstdc++ exceptions are supposed
// to be ABI compatible, such that they can be thrown from one library and caught
// in the other.
//
// For that reason, we must look for libstdc++ in the same process and if found,
// check the string stored in the exception object to see if it is the GCC empty
// string singleton before manipulating the reference count. This is done so that
// if an exception is created with a zero-length string in libstdc++, libc++abi
// won't try to delete the memory.
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \
defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
# define _LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE
# include <dlfcn.h>
# include <mach-o/dyld.h>
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

namespace __refstring_imp { namespace {
Expand All @@ -40,7 +53,7 @@ inline char * data_from_rep(_Rep_base *rep) noexcept {
return data + sizeof(*rep);
}

#if defined(__APPLE__)
#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE)
inline
const char* compute_gcc_empty_string_storage() _NOEXCEPT
{
Expand Down Expand Up @@ -115,7 +128,7 @@ __libcpp_refstring::~__libcpp_refstring() {

inline
bool __libcpp_refstring::__uses_refcount() const {
#ifdef __APPLE__
#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE)
return __imp_ != get_gcc_empty_string_storage();
#else
return true;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/utils/ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y bash curl

# Install various tools used by the build or the test suite
RUN apt-get update && apt-get install -y ninja-build python3 python3-sphinx git
RUN apt-get update && apt-get install -y ninja-build python3 python3-sphinx git gdb

# Install the most recently released LLVM
RUN apt-get update && apt-get install -y lsb-release wget software-properties-common
Expand Down
24 changes: 24 additions & 0 deletions lld/test/wasm/relocation-bad-tls.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
# RUN: not wasm-ld %t.o -o out.wasm 2>&1 | FileCheck %s

.globl _start
_start:
.functype _start () -> ()
i32.const foo@TLSREL
i32.const bar@TLSREL
end_function

.section .data,"",@
.globl foo
foo:
.int32 0
.size foo, 4

.section .bss,"",@
.globl bar
bar:
.int32 0
.size bar, 4

# CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against `foo` in non-TLS section: .data
# CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against `bar` in non-TLS section: .bss
41 changes: 33 additions & 8 deletions lld/test/wasm/tls.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@
tls1_addr:
.functype tls1_addr () -> (i32)
global.get __tls_base
i32.const tls1
i32.const tls1@TLSREL
i32.add
end_function

.globl tls2_addr
tls2_addr:
.functype tls2_addr () -> (i32)
global.get __tls_base
i32.const tls2
i32.const tls2@TLSREL
i32.add
end_function

.globl tls3_addr
tls3_addr:
.functype tls3_addr () -> (i32)
global.get __tls_base
i32.const tls3
i32.add
end_function

Expand Down Expand Up @@ -46,6 +54,13 @@ tls2:
.int32 1
.size tls2, 4

.section .tbss.tls3,"",@
.globl tls3
.p2align 2
tls3:
.int32 0
.size tls3, 4

.section .custom_section.target_features,"",@
.int8 2
.int8 43
Expand All @@ -68,7 +83,7 @@ tls2:
# CHECK-NEXT: Mutable: true
# CHECK-NEXT: InitExpr:
# CHECK-NEXT: Opcode: I32_CONST
# CHECK-NEXT: Value: 66576
# CHECK-NEXT: Value: 66592

# __tls_base
# CHECK-NEXT: - Index: 1
Expand All @@ -84,7 +99,7 @@ tls2:
# CHECK-NEXT: Mutable: false
# CHECK-NEXT: InitExpr:
# CHECK-NEXT: Opcode: I32_CONST
# CHECK-NEXT: Value: 8
# CHECK-NEXT: Value: 12

# __tls_align
# CHECK-NEXT: - Index: 3
Expand All @@ -100,14 +115,14 @@ tls2:
# Skip __wasm_call_ctors and __wasm_init_memory
# CHECK: - Index: 2
# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 20002401200041004108FC0800000B
# CHECK-NEXT: Body: 2000240120004100410CFC0800000B

# Expected body of __wasm_init_tls:
# local.get 0
# global.set 1
# local.get 0
# i32.const 0
# i32.const 8
# i32.const 12
# memory.init 1, 0
# end

Expand All @@ -125,16 +140,26 @@ tls2:
# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 2381808080004184808080006A0B

# Expected body of tls1_addr:
# Expected body of tls2_addr:
# global.get 1
# i32.const 4
# i32.add
# end

# CHECK-NEXT: - Index: 5
# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 2381808080004188808080006A0B

# Expected body of tls3_addr:
# global.get 1
# i32.const 4
# i32.add
# end

# CHECK-NEXT: - Index: 6
# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 2383808080000B

# Expected body of tls1_addr:
# Expected body of tls_align:
# global.get 3
# end
4 changes: 4 additions & 0 deletions lld/wasm/InputChunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void InputChunk::verifyRelocTargets() const {
case R_WASM_TABLE_INDEX_REL_SLEB:
case R_WASM_MEMORY_ADDR_SLEB:
case R_WASM_MEMORY_ADDR_REL_SLEB:
case R_WASM_MEMORY_ADDR_TLS_SLEB:
existingValue = static_cast<uint64_t>(decodeSLEB128(loc, &bytesRead));
break;
case R_WASM_TABLE_INDEX_SLEB64:
Expand All @@ -96,6 +97,7 @@ void InputChunk::verifyRelocTargets() const {
break;
case R_WASM_TABLE_INDEX_I64:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I64:
existingValue = read64le(loc);
break;
default:
Expand Down Expand Up @@ -158,6 +160,7 @@ void InputChunk::writeTo(uint8_t *buf) const {
case R_WASM_TABLE_INDEX_REL_SLEB:
case R_WASM_MEMORY_ADDR_SLEB:
case R_WASM_MEMORY_ADDR_REL_SLEB:
case R_WASM_MEMORY_ADDR_TLS_SLEB:
encodeSLEB128(static_cast<int32_t>(value), loc, 5);
break;
case R_WASM_TABLE_INDEX_SLEB64:
Expand All @@ -174,6 +177,7 @@ void InputChunk::writeTo(uint8_t *buf) const {
break;
case R_WASM_TABLE_INDEX_I64:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I64:
write64le(loc, value);
break;
default:
Expand Down
29 changes: 24 additions & 5 deletions lld/wasm/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "InputChunks.h"
#include "InputEvent.h"
#include "InputGlobal.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
Expand Down Expand Up @@ -123,6 +124,7 @@ uint64_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const {
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64:
return reloc.Addend;
case R_WASM_SECTION_OFFSET_I32:
return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend;
Expand Down Expand Up @@ -154,7 +156,8 @@ uint64_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
case R_WASM_MEMORY_ADDR_REL_SLEB:
case R_WASM_MEMORY_ADDR_REL_SLEB64:
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_I64: {
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_MEMORY_ADDR_TLS_SLEB: {
const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
if (sym.isUndefined())
return 0;
Expand All @@ -169,7 +172,8 @@ uint64_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
else
llvm_unreachable("unknown init expr opcode");
}
case R_WASM_FUNCTION_OFFSET_I32: {
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64: {
const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
InputFunction *f =
functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()];
Expand Down Expand Up @@ -227,10 +231,24 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc) const {
case R_WASM_MEMORY_ADDR_REL_SLEB:
case R_WASM_MEMORY_ADDR_REL_SLEB64:
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_MEMORY_ADDR_I64: {
if (isa<UndefinedData>(sym) || sym->isUndefWeak())
return 0;
auto D = cast<DefinedData>(sym);
// Treat non-TLS relocation against symbols that live in the TLS segment
// like TLS relocations. This beaviour exists to support older object
// files created before we introduced TLS relocations.
// TODO(sbc): Remove this legacy behaviour one day. This will break
// backward compat with old object files built with `-fPIC`.
if (D->segment && D->segment->outputSeg->name == ".tdata")
return D->getOutputSegmentOffset() + reloc.Addend;
return D->getVirtualAddress() + reloc.Addend;
}
case R_WASM_MEMORY_ADDR_TLS_SLEB:
if (isa<UndefinedData>(sym) || sym->isUndefWeak())
return 0;
return cast<DefinedData>(sym)->getVirtualAddress() + reloc.Addend;
// TLS relocations are relative to the start of the TLS output segment
return cast<DefinedData>(sym)->getOutputSegmentOffset() + reloc.Addend;
case R_WASM_TYPE_INDEX_LEB:
return typeMap[reloc.Index];
case R_WASM_FUNCTION_INDEX_LEB:
Expand All @@ -242,7 +260,8 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc) const {
return sym->getGOTIndex();
case R_WASM_EVENT_INDEX_LEB:
return getEventSymbol(reloc.Index)->getEventIndex();
case R_WASM_FUNCTION_OFFSET_I32: {
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64: {
auto *f = cast<DefinedFunction>(sym);
return f->function->outputOffset +
(f->function->getFunctionCodeOffset() + reloc.Addend);
Expand Down
13 changes: 10 additions & 3 deletions lld/wasm/OutputSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,20 @@ void DataSection::finalizeContents() {
std::count_if(segments.begin(), segments.end(),
[](OutputSegment *segment) { return !segment->isBss; });

#ifndef NDEBUG
unsigned activeCount = std::count_if(
segments.begin(), segments.end(), [](OutputSegment *segment) {
return (segment->initFlags & WASM_SEGMENT_IS_PASSIVE) == 0;
});
#endif

assert((!config->isPic || activeCount <= 1) &&
"Currenly only a single data segment is supported in PIC mode");

writeUleb128(os, segmentCount, "data segment count");
os.flush();
bodySize = dataSectionHeader.size();

assert((!config->isPic || segments.size() <= 1) &&
"Currenly only a single data segment is supported in PIC mode");

for (OutputSegment *segment : segments) {
if (segment->isBss)
continue;
Expand Down
11 changes: 11 additions & 0 deletions lld/wasm/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Relocations.h"

#include "InputChunks.h"
#include "OutputSegment.h"
#include "SyntheticSections.h"

using namespace llvm;
Expand Down Expand Up @@ -88,6 +89,16 @@ void scanRelocations(InputChunk *chunk) {
if (!isa<GlobalSymbol>(sym))
addGOTEntry(sym);
break;
case R_WASM_MEMORY_ADDR_TLS_SLEB:
if (auto *D = dyn_cast<DefinedData>(sym)) {
if (D->segment->outputSeg->name != ".tdata") {
error(toString(file) + ": relocation " +
relocTypeToString(reloc.Type) + " cannot be used against `" +
toString(*sym) +
"` in non-TLS section: " + D->segment->outputSeg->name);
}
}
break;
}

if (config->isPic) {
Expand Down
8 changes: 1 addition & 7 deletions lld/wasm/Symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,8 @@ DefinedFunction::DefinedFunction(StringRef name, uint32_t flags, InputFile *f,

uint64_t DefinedData::getVirtualAddress() const {
LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
if (segment) {
// For thread local data, the symbol location is relative to the start of
// the .tdata section, since they are used as offsets from __tls_base.
// Hence, we do not add in segment->outputSeg->startVA.
if (segment->outputSeg->name == ".tdata")
return segment->outputSegmentOffset + offset;
if (segment)
return segment->outputSeg->startVA + segment->outputSegmentOffset + offset;
}
return offset;
}

Expand Down
12 changes: 6 additions & 6 deletions lld/wasm/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,15 +749,15 @@ void Writer::assignIndexes() {
}

static StringRef getOutputDataSegmentName(StringRef name) {
// With PIC code we currently only support a single data segment since
// we only have a single __memory_base to use as our base address.
if (config->isPic)
return ".data";
// We only support one thread-local segment, so we must merge the segments
// despite --no-merge-data-segments.
// We also need to merge .tbss into .tdata so they share the same offsets.
if (name.startswith(".tdata") || name.startswith(".tbss"))
return ".tdata";
// With PIC code we currently only support a single data segment since
// we only have a single __memory_base to use as our base address.
if (config->isPic)
return ".data";
if (!config->mergeDataSegments)
return name;
if (name.startswith(".text."))
Expand Down Expand Up @@ -1199,10 +1199,10 @@ void Writer::run() {

if (!config->relocatable) {
// Create linker synthesized functions
if (config->sharedMemory)
createInitMemoryFunction();
if (config->isPic)
createApplyRelocationsFunction();
else if (config->sharedMemory)
createInitMemoryFunction();
createCallCtorsFunction();

// Create export wrappers for commands if needed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -837,18 +837,6 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
return std::string(result.GetString());
}

lldb::ProcessSP PlatformRemoteGDBServer::ConnectProcess(
llvm::StringRef connect_url, llvm::StringRef plugin_name,
lldb_private::Debugger &debugger, lldb_private::Target *target,
lldb_private::Status &error) {
if (!IsRemote() || !IsConnected()) {
error.SetErrorString("Not connected to remote gdb server");
return nullptr;
}
return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
error);
}

size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger,
Status &error) {
std::vector<std::string> connection_urls;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,6 @@ class PlatformRemoteGDBServer : public Platform, private UserIDResolver {

const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;

lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
llvm::StringRef plugin_name,
lldb_private::Debugger &debugger,
lldb_private::Target *target,
lldb_private::Status &error) override;

size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
lldb_private::Status &error) override;

Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Target/AssertFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
SymbolContext sym_ctx =
prev_frame_sp->GetSymbolContext(eSymbolContextEverything);

if (!sym_ctx.module_sp->GetFileSpec().FileEquals(location.module_spec))
if (!sym_ctx.module_sp ||
!sym_ctx.module_sp->GetFileSpec().FileEquals(location.module_spec))
continue;

ConstString func_name = sym_ctx.GetFunctionName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace std {
// Pretend to be a std::vector template we need to instantiate in LLDB
// when import-std-module is enabled.
template<typename T>
struct vector { class F; F *f; };
struct vector { class F; F *f = nullptr; };
// The definition of our forward declared nested class.
template<typename T> class vector<T>::F { int x; };
}
Expand Down
11 changes: 11 additions & 0 deletions lldb/test/Shell/Commands/command-process-connect.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# UNSUPPORTED: system-windows

# Synchronous
# RUN: %lldb -o 'platform select remote-gdb-server' -o 'process connect connect://localhost:4321' 2>&1 | FileCheck %s

# Asynchronous
# RUN: echo -e 'platform select remote-gdb-server\nprocess connect connect://localhost:4321' | %lldb 2>&1 | FileCheck %s

# CHECK: Platform: remote-gdb-server
# CHECK: Connected: no
# CHECK: error: Failed to connect port
4 changes: 2 additions & 2 deletions lldb/test/Shell/SymbolFile/PDB/udt-layout.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ RUN: %lldb -b -s %S/Inputs/UdtLayoutTest.script -- %t.exe | FileCheck %s
CHECK:(int) int C::abc = 123
CHECK:(List [16]) ls = {
CHECK: [15] = {
CHECK: Prev = 0x00000000
CHECK: Next = 0x00000000
CHECK: Prev = nullptr
CHECK: Next = nullptr
CHECK: Value = {
CHECK: B<0> = {
CHECK: A = {
Expand Down
61 changes: 0 additions & 61 deletions llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -714,67 +714,6 @@ if(NOT Python3_Interpreter_FOUND)
set(Python3_EXECUTABLE ${Python2_EXECUTABLE})
endif()

######
# LLVMBuild Integration
#
# We use llvm-build to generate all the data required by the CMake based
# build system in one swoop:
#
# - We generate a file (a CMake fragment) in the object root which contains
# all the definitions that are required by CMake.
#
# - We generate the library table used by llvm-config.
#
# - We generate the dependencies for the CMake fragment, so that we will
# automatically reconfigure ourselves.

set(LLVMBUILDTOOL "${LLVM_MAIN_SRC_DIR}/utils/llvm-build/llvm-build")
set(LLVMCONFIGLIBRARYDEPENDENCIESINC
"${LLVM_BINARY_DIR}/tools/llvm-config/LibraryDependencies.inc")
set(LLVMBUILDCMAKEFRAG
"${LLVM_BINARY_DIR}/LLVMBuild.cmake")

# Create the list of optional components that are enabled
if (LLVM_USE_INTEL_JITEVENTS)
set(LLVMOPTIONALCOMPONENTS IntelJITEvents)
endif (LLVM_USE_INTEL_JITEVENTS)
if (LLVM_USE_OPROFILE)
set(LLVMOPTIONALCOMPONENTS ${LLVMOPTIONALCOMPONENTS} OProfileJIT)
endif (LLVM_USE_OPROFILE)
if (LLVM_USE_PERF)
set(LLVMOPTIONALCOMPONENTS ${LLVMOPTIONALCOMPONENTS} PerfJITEvents)
endif (LLVM_USE_PERF)

message(STATUS "Constructing LLVMBuild project information")
execute_process(
COMMAND "${Python3_EXECUTABLE}" -B ${LLVMBUILDTOOL}
--native-target "${LLVM_NATIVE_ARCH}"
--enable-targets "${LLVM_TARGETS_TO_BUILD}"
--enable-optional-components "${LLVMOPTIONALCOMPONENTS}"
--write-library-table ${LLVMCONFIGLIBRARYDEPENDENCIESINC}
--write-cmake-fragment ${LLVMBUILDCMAKEFRAG}
OUTPUT_VARIABLE LLVMBUILDOUTPUT
ERROR_VARIABLE LLVMBUILDERRORS
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE LLVMBUILDRESULT)

# On Win32, CMake doesn't properly handle piping the default output/error
# streams into the GUI console. So, we explicitly catch and report them.
if( NOT "${LLVMBUILDOUTPUT}" STREQUAL "")
message(STATUS "llvm-build output: ${LLVMBUILDOUTPUT}")
endif()
if( NOT "${LLVMBUILDRESULT}" STREQUAL "0" )
message(FATAL_ERROR
"Unexpected failure executing llvm-build: ${LLVMBUILDERRORS}")
endif()

# Include the generated CMake fragment. This will define properties from the
# LLVMBuild files in a format which is easy to consume from CMake, and will add
# the dependencies so that CMake will reconfigure properly when the LLVMBuild
# files change.
include(${LLVMBUILDCMAKEFRAG})

######

# Configure all of the various header file fragments LLVM uses which depend on
Expand Down
23 changes: 0 additions & 23 deletions llvm/LLVMBuild.txt

This file was deleted.

20 changes: 0 additions & 20 deletions llvm/bindings/LLVMBuild.txt

This file was deleted.

2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_analysis
OCAML llvm_analysis
OCAMLDEP llvm
C analysis_ocaml
LLVM analysis)
LLVM Analysis)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/bitreader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_bitreader
OCAML llvm_bitreader
OCAMLDEP llvm
C bitreader_ocaml
LLVM bitreader)
LLVM BitReader)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/bitwriter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_bitwriter
OCAML llvm_bitwriter
OCAMLDEP llvm
C bitwriter_ocaml
LLVM bitwriter)
LLVM BitWriter)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/executionengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ add_ocaml_library(llvm_executionengine
OCAML llvm_executionengine
OCAMLDEP llvm llvm_target
C executionengine_ocaml
LLVM executionengine mcjit native
LLVM ExecutionEngine MCJIT native
PKG ctypes)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/irreader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_irreader
OCAML llvm_irreader
OCAMLDEP llvm
C irreader_ocaml
LLVM irreader)
LLVM IRReader)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/linker/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_linker
OCAML llvm_linker
OCAMLDEP llvm
C linker_ocaml
LLVM linker)
LLVM Linker)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_ocaml_library(llvm
OCAML llvm
C llvm_ocaml
LLVM core support)
LLVM Core Support)

configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/META.llvm.in"
Expand Down
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/target/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_target
OCAML llvm_target
OCAMLDEP llvm
C target_ocaml
LLVM target)
LLVM Target)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/transforms/scalar_opts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_scalar_opts
OCAML llvm_scalar_opts
OCAMLDEP llvm
C scalar_opts_ocaml
LLVM scalaropts)
LLVM Scalar)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/transforms/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_transform_utils
OCAML llvm_transform_utils
OCAMLDEP llvm
C transform_utils_ocaml
LLVM transformutils)
LLVM TransformUtils)
2 changes: 1 addition & 1 deletion llvm/bindings/ocaml/transforms/vectorize/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ add_ocaml_library(llvm_vectorize
OCAML llvm_vectorize
OCAMLDEP llvm
C vectorize_ocaml
LLVM vectorize)
LLVM Vectorize)
66 changes: 57 additions & 9 deletions llvm/cmake/modules/AddLLVM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,13 @@ function(llvm_add_library name)
endif()
endif()

if(ARG_STATIC)
set(libtype PUBLIC)
else()
# We can use PRIVATE since SO knows its dependent libs.
set(libtype PRIVATE)
endif()

if(ARG_MODULE AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS AND ARG_PLUGIN_TOOL AND (WIN32 OR CYGWIN))
# On DLL platforms symbols are imported from the tool by linking against it.
set(llvm_libs ${ARG_PLUGIN_TOOL})
Expand All @@ -630,19 +637,19 @@ function(llvm_add_library name)
endif()
else()
# Components have not been defined explicitly in CMake, so add the
# dependency information for this library as defined by LLVMBuild.
# dependency information for this library through their name, and let
# LLVMBuildResolveComponentsLink resolve the mapping.
#
# It would be nice to verify that we have the dependencies for this library
# name, but using get_property(... SET) doesn't suffice to determine if a
# property has been set to an empty value.
get_property(lib_deps GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_${name})
endif()
set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS})

if(ARG_STATIC)
set(libtype PUBLIC)
else()
# We can use PRIVATE since SO knows its dependent libs.
set(libtype PRIVATE)
# These two properties are internal properties only used to make sure the
# link step applied in LLVMBuildResolveComponentsLink uses the same
# properties as the target_link_libraries call below.
set_property(TARGET ${name} PROPERTY LLVM_LINK_LIBS ${ARG_LINK_LIBS})
set_property(TARGET ${name} PROPERTY LLVM_LIBTYPE ${libtype})
endif()

target_link_libraries(${name} ${libtype}
Expand Down Expand Up @@ -723,8 +730,49 @@ function(add_llvm_install_targets target)
endif()
endfunction()

# Define special targets that behave like a component group. They don't have any
# source attached but other components can add themselves to them. If the
# component supports is a Target and it supports JIT compilation, HAS_JIT must
# be passed. One can use ADD_TO_COMPONENT option from add_llvm_component_library
# to link extra component into an existing group.
function(add_llvm_component_group name)
cmake_parse_arguments(ARG "HAS_JIT" "" "LINK_COMPONENTS" ${ARGN})
add_custom_target(${name})
if(ARG_HAS_JIT)
set_property(TARGET ${name} PROPERTY COMPONENT_HAS_JIT ON)
endif()
if(ARG_LINK_COMPONENTS)
set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
endif()
endfunction()

# An LLVM component is a cmake target with the following cmake properties
# eventually set:
# - LLVM_COMPONENT_NAME: the name of the component, which can be the name of
# the associated library or the one specified through COMPONENT_NAME
# - LLVM_LINK_COMPONENTS: a list of component this component depends on
# - COMPONENT_HAS_JIT: (only for group component) whether this target group
# supports JIT compilation
# Additionnaly, the ADD_TO_COMPONENT <component> option make it possible to add this
# component to the LLVM_LINK_COMPONENTS of <component>.
function(add_llvm_component_library name)
add_llvm_library(${name} COMPONENT_LIB ${ARGN})
cmake_parse_arguments(ARG
""
"COMPONENT_NAME;ADD_TO_COMPONENT"
""
${ARGN})
add_llvm_library(${name} COMPONENT_LIB ${ARG_UNPARSED_ARGUMENTS})
string(REGEX REPLACE "^LLVM" "" component_name ${name})
set_property(TARGET ${name} PROPERTY LLVM_COMPONENT_NAME ${component_name})

if(ARG_COMPONENT_NAME)
set_property(GLOBAL PROPERTY LLVM_COMPONENT_NAME_${ARG_COMPONENT_NAME} ${component_name})
endif()

if(ARG_ADD_TO_COMPONENT)
set_property(TARGET ${ARG_ADD_TO_COMPONENT} APPEND PROPERTY LLVM_LINK_COMPONENTS ${component_name})
endif()

endfunction()

macro(add_llvm_library name)
Expand Down
107 changes: 107 additions & 0 deletions llvm/cmake/modules/LLVM-Build.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Generate C code in the file provided as OUTPUT that describes the properties
# of all components. This C code is suitable for inclusion in `llvm-config`
function(LLVMBuildGenerateCFragment)
cmake_parse_arguments(ARG "" "OUTPUT" "" ${ARGN})

# Write C header
#################
get_property(llvmbuild_components GLOBAL PROPERTY LLVM_COMPONENT_LIBS)
foreach(llvmbuild_component ${llvmbuild_components})
string(REGEX REPLACE "^LLVM" "" component_name ${llvmbuild_component})
list(APPEND all_component_libdeps ${component_name})
endforeach()
list(APPEND llvmbuild_components all)
list(APPEND llvmbuild_components all-targets)
list(APPEND llvmbuild_components Engine)
list(APPEND llvmbuild_components Native)
list(APPEND llvmbuild_components NativeCodeGen)
foreach(llvm_target_to_build ${LLVM_TARGETS_TO_BUILD})
list(APPEND llvmbuild_components ${llvm_target_to_build})
endforeach()

list(LENGTH llvmbuild_components llvmbuild_components_size)
file(WRITE ${ARG_OUTPUT}
"
struct AvailableComponent {
/// The name of the component.
const char *Name;

/// The name of the library for this component (or NULL).
const char *Library;

/// Whether the component is installed.
bool IsInstalled;

/// The list of libraries required when linking this component.
const char *RequiredLibraries[${llvmbuild_components_size}];
} AvailableComponents[${llvmbuild_components_size}] = {
")

foreach(llvmbuild_component ${llvmbuild_components})
if(llvmbuild_component STREQUAL "all")
unset(llvmbuild_libname)
set(llvmbuild_libdeps ${all_component_libdeps})
else()
get_property(llvmbuild_libname TARGET ${llvmbuild_component} PROPERTY LLVM_COMPONENT_NAME)
get_property(llvmbuild_libdeps TARGET ${llvmbuild_component} PROPERTY LLVM_LINK_COMPONENTS)
endif()
string(TOLOWER ${llvmbuild_component} llvmbuild_componentname)

if(NOT llvmbuild_libname)
set(llvmbuild_llvmlibname nullptr)
string(TOLOWER ${llvmbuild_component} llvmbuild_libname)
else()
set(llvmbuild_llvmlibname "\"LLVM${llvmbuild_libname}\"")
string(TOLOWER ${llvmbuild_libname} llvmbuild_libname)
endif()

set(llvmbuild_clibdeps "")
foreach(llvmbuild_libdep ${llvmbuild_libdeps})
get_property(llvmbuild_libdepname GLOBAL PROPERTY LLVM_COMPONENT_NAME_${llvmbuild_libdep})
if(NOT llvmbuild_libdepname)
string(TOLOWER ${llvmbuild_libdep} llvmbuild_clibdep)
else()
string(TOLOWER ${llvmbuild_libdepname} llvmbuild_clibdep)
endif()
list(APPEND llvmbuild_clibdeps ${llvmbuild_clibdep})
endforeach()

list(TRANSFORM llvmbuild_clibdeps PREPEND "\"")
list(TRANSFORM llvmbuild_clibdeps APPEND "\"")
list(JOIN llvmbuild_clibdeps ", " llvmbuild_clibdeps_joint)
list(APPEND llvmbuild_centries "{ \"${llvmbuild_libname}\", ${llvmbuild_llvmlibname}, true, {${llvmbuild_clibdeps_joint}} },\n")
endforeach()

list(SORT llvmbuild_centries)
foreach(llvmbuild_centry ${llvmbuild_centries})
file(APPEND ${ARG_OUTPUT} "${llvmbuild_centry}")
endforeach()
file(APPEND ${ARG_OUTPUT} "};")
endfunction()

# Resolve cross-component dependencies, for each available component.
function(LLVMBuildResolveComponentsLink)

# the native target may not be enabled when cross compiling
if(TARGET ${LLVM_NATIVE_ARCH})
get_property(llvm_has_jit_native TARGET ${LLVM_NATIVE_ARCH} PROPERTY LLVM_HAS_JIT)
else()
set(llvm_has_jit_native OFF)
endif()

if(llvm_has_jit_native)
set_property(TARGET Engine APPEND PROPERTY LLVM_LINK_COMPONENTS "MCJIT" "Native")
else()
set_property(TARGET Engine APPEND PROPERTY LLVM_LINK_COMPONENTS "Interpreter")
endif()

get_property(llvm_components GLOBAL PROPERTY LLVM_COMPONENT_LIBS)
foreach(llvm_component ${llvm_components})
get_property(link_components TARGET ${llvm_component} PROPERTY LLVM_LINK_COMPONENTS)
llvm_map_components_to_libnames(llvm_libs ${link_components})
if(llvm_libs)
get_property(libtype TARGET ${llvm_component} PROPERTY LLVM_LIBTYPE)
target_link_libraries(${llvm_component} ${libtype} ${llvm_libs})
endif()
endforeach()
endfunction()
22 changes: 19 additions & 3 deletions llvm/cmake/modules/LLVM-Config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function(is_llvm_target_library library return_var)
string(TOUPPER "${LLVM_TARGETS_TO_BUILD}" targets)
elseif(ARG_OMITTED_TARGETS)
set(omitted_targets ${LLVM_ALL_TARGETS})
list(REMOVE_ITEM omitted_targets "${LLVM_TARGETS_TO_BUILD}")
list(REMOVE_ITEM omitted_targets ${LLVM_TARGETS_TO_BUILD})
string(TOUPPER "${omitted_targets}" targets)
else()
string(TOUPPER "${LLVM_ALL_TARGETS}" targets)
Expand Down Expand Up @@ -253,6 +253,10 @@ function(llvm_map_components_to_libnames out_libs)
# Translate symbolic component names to real libraries:
llvm_expand_pseudo_components(link_components ${link_components})
foreach(c ${link_components})
get_property(c_rename GLOBAL PROPERTY LLVM_COMPONENT_NAME_${c})
if(c_rename)
set(c ${c_rename})
endif()
if( c STREQUAL "native" )
# already processed
elseif( c STREQUAL "backend" )
Expand Down Expand Up @@ -298,14 +302,26 @@ function(expand_topologically name required_libs visited_libs)
list(APPEND visited_libs ${name})
set(visited_libs ${visited_libs} PARENT_SCOPE)

get_property(lib_deps GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_${name})
#
get_property(libname GLOBAL PROPERTY LLVM_COMPONENT_NAME_${name})
if(libname)
set(cname LLVM${libname})
elseif(TARGET ${name})
set(cname ${name})
elseif(TARGET LLVM${name})
set(cname LLVM${name})
else()
message(FATAL_ERROR "unknown component ${name}")
endif()

get_property(lib_deps TARGET ${cname} PROPERTY LLVM_LINK_COMPONENTS)
foreach( lib_dep ${lib_deps} )
expand_topologically(${lib_dep} "${required_libs}" "${visited_libs}")
set(required_libs ${required_libs} PARENT_SCOPE)
set(visited_libs ${visited_libs} PARENT_SCOPE)
endforeach()

list(APPEND required_libs ${name})
list(APPEND required_libs ${cname})
set(required_libs ${required_libs} PARENT_SCOPE)
endif()
endfunction()
Expand Down
3 changes: 1 addition & 2 deletions llvm/docs/CodingStandards.rst
Original file line number Diff line number Diff line change
Expand Up @@ -748,8 +748,7 @@ Library Layering
^^^^^^^^^^^^^^^^

A directory of header files (for example ``include/llvm/Foo``) defines a
library (``Foo``). Dependencies between libraries are defined by the
``LLVMBuild.txt`` file in their implementation (``lib/Foo``). One library (both
library (``Foo``). One library (both
its headers and implementation) should only use things from the libraries
listed in its dependencies.

Expand Down
1 change: 0 additions & 1 deletion llvm/docs/CommandGuide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ Developer Tools
FileCheck
tblgen
lit
llvm-build
llvm-exegesis
llvm-pdbutil
llvm-locstats
79 changes: 0 additions & 79 deletions llvm/docs/CommandGuide/llvm-build.rst

This file was deleted.

5 changes: 0 additions & 5 deletions llvm/docs/GettingInvolved.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ Information about LLVM's development process.
:hidden:

Projects
LLVMBuild
HowToReleaseLLVM
Packaging
ReleaseProcess
Expand All @@ -78,10 +77,6 @@ Information about LLVM's development process.
tree) allow the project code to be located outside (or inside) the ``llvm/``
tree, while using LLVM header files and libraries.

:doc:`LLVMBuild`
Describes the LLVMBuild organization and files used by LLVM to specify
component descriptions.

:doc:`HowToReleaseLLVM`
This is a guide to preparing LLVM releases. Most developers can ignore it.

Expand Down
Loading