aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-02-05 18:04:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-02-05 18:05:05 +0000
commitecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (patch)
tree3a4038f3b7bafaeade9fd6146ea8021237616657 /clang/lib
parent6f8fc217eaa12bf657be1c6468ed9938d10168b3 (diff)
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp37
-rw-r--r--clang/lib/AST/ExprConstant.cpp17
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp7
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp73
-rw-r--r--clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp11
-rw-r--r--clang/lib/Basic/Targets/AArch64.cpp2
-rw-r--r--clang/lib/Basic/Targets/AArch64.h5
-rw-r--r--clang/lib/Basic/Targets/ARM.cpp23
-rw-r--r--clang/lib/Basic/Targets/ARM.h6
-rw-r--r--clang/lib/Basic/Targets/WebAssembly.cpp1
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp31
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp12
-rw-r--r--clang/lib/CodeGen/CGClass.cpp3
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp2
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp8
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp1
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp16
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp55
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h7
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp57
-rw-r--r--clang/lib/Driver/Action.cpp8
-rw-r--r--clang/lib/Driver/Driver.cpp264
-rw-r--r--clang/lib/Driver/ToolChain.cpp12
-rw-r--r--clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp4
-rw-r--r--clang/lib/Driver/ToolChains/AVR.cpp5
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp159
-rw-r--r--clang/lib/Driver/ToolChains/Clang.h15
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.cpp27
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.h3
-rw-r--r--clang/lib/Driver/ToolChains/Cuda.cpp4
-rw-r--r--clang/lib/Driver/ToolChains/XCore.cpp4
-rw-r--r--clang/lib/Format/BreakableToken.cpp35
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp12
-rw-r--r--clang/lib/Format/Format.cpp57
-rw-r--r--clang/lib/Format/FormatToken.h28
-rw-r--r--clang/lib/Format/NamespaceEndCommentsFixer.cpp4
-rw-r--r--clang/lib/Format/SortJavaScriptImports.cpp7
-rw-r--r--clang/lib/Format/TokenAnalyzer.cpp10
-rw-r--r--clang/lib/Format/TokenAnnotator.h5
-rw-r--r--clang/lib/Format/UnwrappedLineFormatter.cpp25
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp21
-rw-r--r--clang/lib/Format/UsingDeclarationsSorter.cpp10
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp31
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp4
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp8
-rw-r--r--clang/lib/Headers/arm_acle.h6
-rw-r--r--clang/lib/Headers/float.h21
-rw-r--r--clang/lib/Headers/limits.h2
-rw-r--r--clang/lib/Headers/opencl-c-base.h6
-rw-r--r--clang/lib/Headers/opencl-c.h86
-rw-r--r--clang/lib/Lex/Lexer.cpp5
-rw-r--r--clang/lib/Sema/OpenCLBuiltins.td14
-rw-r--r--clang/lib/Sema/Sema.cpp55
-rw-r--r--clang/lib/Sema/SemaCUDA.cpp2
-rw-r--r--clang/lib/Sema/SemaChecking.cpp2
-rw-r--r--clang/lib/Sema/SemaCoroutine.cpp12
-rw-r--r--clang/lib/Sema/SemaDecl.cpp13
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp23
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp7
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp19
-rw-r--r--clang/lib/Sema/SemaOverload.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp3
-rw-r--r--clang/lib/Sema/SemaType.cpp7
-rw-r--r--clang/lib/Sema/TreeTransform.h2
70 files changed, 1086 insertions, 362 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 8a780250b6d8..5fa2d46de89b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3370,8 +3370,9 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
/// lvalue reference to the specified type.
QualType
ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
- assert(getCanonicalType(T) != OverloadTy &&
- "Unresolved overloaded function type");
+ assert((!T->isPlaceholderType() ||
+ T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
+ "Unresolved placeholder type");
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
@@ -3409,6 +3410,10 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
/// getRValueReferenceType - Return the uniqued reference to the type for an
/// rvalue reference to the specified type.
QualType ASTContext::getRValueReferenceType(QualType T) const {
+ assert((!T->isPlaceholderType() ||
+ T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
+ "Unresolved placeholder type");
+
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -6099,7 +6104,8 @@ ASTContext::getNameForTemplate(TemplateName Name,
llvm_unreachable("bad template name kind!");
}
-TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
+TemplateName
+ASTContext::getCanonicalTemplateName(const TemplateName &Name) const {
switch (Name.getKind()) {
case TemplateName::QualifiedTemplate:
case TemplateName::Template: {
@@ -6141,13 +6147,14 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
llvm_unreachable("bad template name!");
}
-bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) {
- X = getCanonicalTemplateName(X);
- Y = getCanonicalTemplateName(Y);
- return X.getAsVoidPointer() == Y.getAsVoidPointer();
+bool ASTContext::hasSameTemplateName(const TemplateName &X,
+ const TemplateName &Y) const {
+ return getCanonicalTemplateName(X).getAsVoidPointer() ==
+ getCanonicalTemplateName(Y).getAsVoidPointer();
}
-bool ASTContext::isSameTemplateParameter(NamedDecl *X, NamedDecl *Y) {
+bool ASTContext::isSameTemplateParameter(const NamedDecl *X,
+ const NamedDecl *Y) {
if (X->getKind() != Y->getKind())
return false;
@@ -6198,8 +6205,8 @@ bool ASTContext::isSameTemplateParameter(NamedDecl *X, NamedDecl *Y) {
TY->getTemplateParameters());
}
-bool ASTContext::isSameTemplateParameterList(TemplateParameterList *X,
- TemplateParameterList *Y) {
+bool ASTContext::isSameTemplateParameterList(const TemplateParameterList *X,
+ const TemplateParameterList *Y) {
if (X->size() != Y->size())
return false;
@@ -6302,7 +6309,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,
return true;
}
-bool ASTContext::isSameEntity(NamedDecl *X, NamedDecl *Y) {
+bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) {
if (X == Y)
return true;
@@ -6409,6 +6416,8 @@ bool ASTContext::isSameEntity(NamedDecl *X, NamedDecl *Y) {
if (getLangOpts().CPlusPlus17 && XFPT && YFPT &&
(isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||
isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&
+ // FIXME: We could make isSameEntity const after we make
+ // hasSameFunctionTypeIgnoringExceptionSpec const.
hasSameFunctionTypeIgnoringExceptionSpec(XT, YT))
return true;
return false;
@@ -8286,6 +8295,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
*NotEncodedT = T;
return;
+ case Type::BitInt:
+ if (NotEncodedT)
+ *NotEncodedT = T;
+ return;
+
// We could see an undeduced auto type here during error recovery.
// Just ignore it.
case Type::Auto:
@@ -8293,7 +8307,6 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return;
case Type::Pipe:
- case Type::BitInt:
#define ABSTRACT_TYPE(KIND, BASE)
#define TYPE(KIND, BASE)
#define DEPENDENT_TYPE(KIND, BASE) \
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f9416e8e215d..9e4088f94015 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -983,6 +983,8 @@ namespace {
discardCleanups();
}
+ ASTContext &getCtx() const override { return Ctx; }
+
void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value,
EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
EvaluatingDecl = Base;
@@ -1116,8 +1118,6 @@ namespace {
Expr::EvalStatus &getEvalStatus() const override { return EvalStatus; }
- ASTContext &getCtx() const override { return Ctx; }
-
// If we have a prior diagnostic, it will be noting that the expression
// isn't a constant expression. This diagnostic is more important,
// unless we require this evaluation to produce a constant expression.
@@ -2216,6 +2216,19 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
// FIXME: Diagnostic!
return false;
+
+ // In CUDA/HIP device compilation, only device side variables have
+ // constant addresses.
+ if (Info.getCtx().getLangOpts().CUDA &&
+ Info.getCtx().getLangOpts().CUDAIsDevice &&
+ Info.getCtx().CUDAConstantEvalCtx.NoWrongSidedVars) {
+ if ((!Var->hasAttr<CUDADeviceAttr>() &&
+ !Var->hasAttr<CUDAConstantAttr>() &&
+ !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
+ !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
+ Var->hasAttr<HIPManagedAttr>())
+ return false;
+ }
}
if (const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
// __declspec(dllimport) must be handled very carefully:
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 61a30ead165e..709e05716a56 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1887,7 +1887,12 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
UnfilledBitsInLastUnit = 0;
LastBitfieldStorageUnitSize = 0;
- bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
+ llvm::Triple Target = Context.getTargetInfo().getTriple();
+ bool FieldPacked = (Packed && (!FieldClass || FieldClass->isPOD() ||
+ Context.getLangOpts().getClangABICompat() <=
+ LangOptions::ClangABI::Ver13 ||
+ Target.isPS4() || Target.isOSDarwin())) ||
+ D->hasAttr<PackedAttr>();
AlignRequirementKind AlignRequirement = AlignRequirementKind::None;
CharUnits FieldSize;
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 938f7338b640..eca58b313761 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -41,6 +41,21 @@ llvm::DenseMap<K, V> intersectDenseMaps(const llvm::DenseMap<K, V> &Map1,
return Result;
}
+/// Returns true if and only if `Val1` is equivalent to `Val2`.
+static bool equivalentValues(QualType Type, Value *Val1, Value *Val2,
+ Environment::ValueModel &Model) {
+ if (Val1 == Val2)
+ return true;
+
+ if (auto *IndVal1 = dyn_cast<IndirectionValue>(Val1)) {
+ auto *IndVal2 = cast<IndirectionValue>(Val2);
+ assert(IndVal1->getKind() == IndVal2->getKind());
+ return &IndVal1->getPointeeLoc() == &IndVal2->getPointeeLoc();
+ }
+
+ return Model.compareEquivalent(Type, *Val1, *Val2);
+}
+
Environment::Environment(DataflowAnalysisContext &DACtx,
const DeclContext &DeclCtx)
: Environment(DACtx) {
@@ -68,13 +83,40 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
}
}
-bool Environment::operator==(const Environment &Other) const {
+bool Environment::equivalentTo(const Environment &Other,
+ Environment::ValueModel &Model) const {
assert(DACtx == Other.DACtx);
- return DeclToLoc == Other.DeclToLoc && LocToVal == Other.LocToVal;
+
+ if (DeclToLoc != Other.DeclToLoc)
+ return false;
+
+ if (ExprToLoc != Other.ExprToLoc)
+ return false;
+
+ if (LocToVal.size() != Other.LocToVal.size())
+ return false;
+
+ for (auto &Entry : LocToVal) {
+ const StorageLocation *Loc = Entry.first;
+ assert(Loc != nullptr);
+
+ Value *Val = Entry.second;
+ assert(Val != nullptr);
+
+ auto It = Other.LocToVal.find(Loc);
+ if (It == Other.LocToVal.end())
+ return false;
+ assert(It->second != nullptr);
+
+ if (!equivalentValues(Loc->getType(), Val, It->second, Model))
+ return false;
+ }
+
+ return true;
}
LatticeJoinEffect Environment::join(const Environment &Other,
- Environment::Merger &Merger) {
+ Environment::ValueModel &Model) {
assert(DACtx == Other.DACtx);
auto Effect = LatticeJoinEffect::Unchanged;
@@ -89,8 +131,12 @@ LatticeJoinEffect Environment::join(const Environment &Other,
if (ExprToLocSizeBefore != ExprToLoc.size())
Effect = LatticeJoinEffect::Changed;
- llvm::DenseMap<const StorageLocation *, Value *> MergedLocToVal;
- for (auto &Entry : LocToVal) {
+ // Move `LocToVal` so that `Environment::ValueModel::merge` can safely assign
+ // values to storage locations while this code iterates over the current
+ // assignments.
+ llvm::DenseMap<const StorageLocation *, Value *> OldLocToVal =
+ std::move(LocToVal);
+ for (auto &Entry : OldLocToVal) {
const StorageLocation *Loc = Entry.first;
assert(Loc != nullptr);
@@ -102,20 +148,19 @@ LatticeJoinEffect Environment::join(const Environment &Other,
continue;
assert(It->second != nullptr);
- if (It->second == Val) {
- MergedLocToVal.insert({Loc, Val});
+ if (equivalentValues(Loc->getType(), Val, It->second, Model)) {
+ LocToVal.insert({Loc, Val});
continue;
}
- // FIXME: Consider destroying `MergedValue` immediately if `Merger::merge`
- // returns false to avoid storing unneeded values in `DACtx`.
+ // FIXME: Consider destroying `MergedValue` immediately if
+ // `ValueModel::merge` returns false to avoid storing unneeded values in
+ // `DACtx`.
if (Value *MergedVal = createValue(Loc->getType()))
- if (Merger.merge(Loc->getType(), *Val, *It->second, *MergedVal, *this))
- MergedLocToVal.insert({Loc, MergedVal});
+ if (Model.merge(Loc->getType(), *Val, *It->second, *MergedVal, *this))
+ LocToVal.insert({Loc, MergedVal});
}
- const unsigned LocToValSizeBefore = LocToVal.size();
- LocToVal = std::move(MergedLocToVal);
- if (LocToValSizeBefore != LocToVal.size())
+ if (OldLocToVal.size() != LocToVal.size())
Effect = LatticeJoinEffect::Changed;
return Effect;
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index aaf6a834f5b3..6b14b5ceaf69 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include <memory>
+#include <system_error>
#include <utility>
#include <vector>
@@ -26,7 +27,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Error.h"
namespace clang {
namespace dataflow {
@@ -190,7 +191,7 @@ TypeErasedDataflowAnalysisState transferBlock(
return State;
}
-std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>>
+llvm::Expected<std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>>>
runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx,
TypeErasedDataflowAnalysis &Analysis,
const Environment &InitEnv) {
@@ -216,8 +217,8 @@ runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx,
static constexpr uint32_t MaxIterations = 1 << 16;
while (const CFGBlock *Block = Worklist.dequeue()) {
if (++Iterations > MaxIterations) {
- llvm::errs() << "Maximum number of iterations reached, giving up.\n";
- break;
+ return llvm::createStringError(std::errc::timed_out,
+ "maximum number of iterations reached");
}
const llvm::Optional<TypeErasedDataflowAnalysisState> &OldBlockState =
@@ -228,7 +229,7 @@ runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx,
if (OldBlockState.hasValue() &&
Analysis.isEqualTypeErased(OldBlockState.getValue().Lattice,
NewBlockState.Lattice) &&
- OldBlockState->Env == NewBlockState.Env) {
+ OldBlockState->Env.equivalentTo(NewBlockState.Env, Analysis)) {
// The state of `Block` didn't change after transfer so there's no need to
// revisit its successors.
continue;
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 8e23cc4c421a..34bdb58dffc1 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -138,7 +138,7 @@ bool AArch64TargetInfo::setABI(const std::string &Name) {
return true;
}
-bool AArch64TargetInfo::validateBranchProtection(StringRef Spec,
+bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
BranchProtectionInfo &BPI,
StringRef &Err) const {
llvm::ARM::ParsedBranchProtection PBP;
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index ebddce0c1c73..9e22aeaff251 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -70,8 +70,9 @@ public:
StringRef getABI() const override;
bool setABI(const std::string &Name) override;
- bool validateBranchProtection(StringRef, BranchProtectionInfo &,
- StringRef &) const override;
+ bool validateBranchProtection(StringRef Spec, StringRef Arch,
+ BranchProtectionInfo &BPI,
+ StringRef &Err) const override;
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 478a0233398d..9c9d198e8f32 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -371,13 +371,34 @@ bool ARMTargetInfo::setABI(const std::string &Name) {
return false;
}
-bool ARMTargetInfo::validateBranchProtection(StringRef Spec,
+bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
+ llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
+
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ return false;
+
+ StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
+ auto a =
+ llvm::Triple(ArchFeature, getTriple().getVendorName(),
+ getTriple().getOSName(), getTriple().getEnvironmentName());
+
+ StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
+ llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
+ return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
+}
+
+bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
BranchProtectionInfo &BPI,
StringRef &Err) const {
llvm::ARM::ParsedBranchProtection PBP;
if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
return false;
+ if (!isBranchProtectionSupportedArch(Arch))
+ return false;
+
BPI.SignReturnAddr =
llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
.Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h
index f074dac57f9b..e85336b6e32f 100644
--- a/clang/lib/Basic/Targets/ARM.h
+++ b/clang/lib/Basic/Targets/ARM.h
@@ -126,8 +126,10 @@ public:
StringRef getABI() const override;
bool setABI(const std::string &Name) override;
- bool validateBranchProtection(StringRef, BranchProtectionInfo &,
- StringRef &) const override;
+ bool isBranchProtectionSupportedArch(StringRef Arch) const override;
+ bool validateBranchProtection(StringRef Spec, StringRef Arch,
+ BranchProtectionInfo &BPI,
+ StringRef &Err) const override;
// FIXME: This should be based on Arch attributes, not CPU names.
bool
diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp
index 4cba861f61d2..2309997eb77b 100644
--- a/clang/lib/Basic/Targets/WebAssembly.cpp
+++ b/clang/lib/Basic/Targets/WebAssembly.cpp
@@ -260,6 +260,7 @@ void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
if (!HasAtomics) {
Opts.POSIXThreads = false;
Opts.setThreadModel(LangOptions::ThreadModelKind::Single);
+ Opts.ThreadsafeStatics = false;
}
}
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 9ae5c870afc8..a4d330c0ba93 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -84,6 +84,7 @@
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include <memory>
@@ -1745,8 +1746,36 @@ void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
llvm::MemoryBufferRef Buf) {
if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
return;
- llvm::EmbedBitcodeInModule(
+ llvm::embedBitcodeInModule(
*M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
CGOpts.CmdArgs);
}
+
+void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
+ DiagnosticsEngine &Diags) {
+ if (CGOpts.OffloadObjects.empty())
+ return;
+
+ for (StringRef OffloadObject : CGOpts.OffloadObjects) {
+ if (OffloadObject.count(',') != 1) {
+ Diags.Report(Diags.getCustomDiagID(
+ DiagnosticsEngine::Error, "Invalid string pair for embedding '%0'"))
+ << OffloadObject;
+ return;
+ }
+ auto FilenameAndSection = OffloadObject.split(',');
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
+ llvm::MemoryBuffer::getFileOrSTDIN(std::get<0>(FilenameAndSection));
+ if (std::error_code EC = ObjectOrErr.getError()) {
+ auto DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "could not open '%0' for embedding");
+ Diags.Report(DiagID) << std::get<0>(FilenameAndSection);
+ return;
+ }
+
+ SmallString<128> SectionName(
+ {".llvm.offloading.", std::get<1>(FilenameAndSection)});
+ llvm::embedBufferInModule(*M, **ObjectOrErr, SectionName);
+ }
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 2b7862e618bd..d071c7a5b4a4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -9777,6 +9777,18 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, {Arg0, Arg1});
}
+ // Memory Operations (MOPS)
+ if (BuiltinID == AArch64::BI__builtin_arm_mops_memset_tag) {
+ Value *Dst = EmitScalarExpr(E->getArg(0));
+ Value *Val = EmitScalarExpr(E->getArg(1));
+ Value *Size = EmitScalarExpr(E->getArg(2));
+ Dst = Builder.CreatePointerCast(Dst, Int8PtrTy);
+ Val = Builder.CreateTrunc(Val, Int8Ty);
+ Size = Builder.CreateIntCast(Size, Int64Ty, false);
+ return Builder.CreateCall(
+ CGM.getIntrinsic(Intrinsic::aarch64_mops_memset_tag), {Dst, Val, Size});
+ }
+
// Memory Tagging Extensions (MTE) Intrinsics
Intrinsic::ID MTEIntrinsicID = Intrinsic::not_intrinsic;
switch (BuiltinID) {
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 520e119ada26..76b90924750c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -162,7 +162,8 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
CGM.getDynamicOffsetAlignment(base.getAlignment(),
memberPtrType->getClass()->getAsCXXRecordDecl(),
memberAlign);
- return Address(ptr, memberAlign);
+ return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()),
+ memberAlign);
}
CharUnits CodeGenModule::computeNonVirtualBaseClassOffset(
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 0fb7ec26a85e..bb5d18b74894 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -150,7 +150,7 @@ Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align,
Result = Address(
Builder.CreateBitCast(Result.getPointer(), VectorTy->getPointerTo()),
- Result.getAlignment());
+ VectorTy, Result.getAlignment());
}
return Result;
}
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 0968afd82064..73b05690537d 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1834,8 +1834,8 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,
// at the end of each iteration.
CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
- LValue elementLV =
- CGF.MakeAddrLValue(Address(element, elementAlign), elementType);
+ LValue elementLV = CGF.MakeAddrLValue(
+ Address(element, llvmElementType, elementAlign), elementType);
if (InnerLoop) {
// If the subexpression is an ArrayInitLoopExpr, share its cleanup.
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 0571c498c377..f06d21861740 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1108,10 +1108,10 @@ void CodeGenFunction::EmitNewArrayInitializer(
StoreAnyExprIntoOneUnit(*this, ILE->getInit(i),
ILE->getInit(i)->getType(), CurPtr,
AggValueSlot::DoesNotOverlap);
- CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getElementType(),
- CurPtr.getPointer(),
- Builder.getSize(1),
- "array.exp.next"),
+ CurPtr = Address(Builder.CreateInBoundsGEP(
+ CurPtr.getElementType(), CurPtr.getPointer(),
+ Builder.getSize(1), "array.exp.next"),
+ CurPtr.getElementType(),
StartAlign.alignmentAtOffset((i + 1) * ElementSize));
}
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index cf1f2e0eab92..ac4b4d1308ab 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -851,6 +851,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
}
llvm::Constant *ConstStructBuilder::Finalize(QualType Type) {
+ Type = Type.getNonReferenceType();
RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
llvm::Type *ValTy = CGM.getTypes().ConvertType(Type);
return Builder.build(ValTy, RD->hasFlexibleArrayMember());
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index e09ea5e01b1a..2d5511336851 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -1125,20 +1125,25 @@ void CGOpenMPRuntimeGPU::createOffloadEntry(llvm::Constant *ID,
llvm::GlobalValue::LinkageTypes) {
// TODO: Add support for global variables on the device after declare target
// support.
- if (!isa<llvm::Function>(Addr))
+ llvm::Function *Fn = dyn_cast<llvm::Function>(Addr);
+ if (!Fn)
return;
+
llvm::Module &M = CGM.getModule();
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
- // Get "nvvm.annotations" metadata node
+ // Get "nvvm.annotations" metadata node.
llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata("nvvm.annotations");
llvm::Metadata *MDVals[] = {
- llvm::ConstantAsMetadata::get(Addr), llvm::MDString::get(Ctx, "kernel"),
+ llvm::ConstantAsMetadata::get(Fn), llvm::MDString::get(Ctx, "kernel"),
llvm::ConstantAsMetadata::get(
llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 1))};
- // Append metadata to nvvm.annotations
+ // Append metadata to nvvm.annotations.
MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
+
+ // Add a function attribute for the kernel.
+ Fn->addFnAttr(llvm::Attribute::get(Ctx, "kernel"));
}
void CGOpenMPRuntimeGPU::emitTargetOutlinedFunction(
@@ -1198,7 +1203,8 @@ CGOpenMPRuntimeGPU::CGOpenMPRuntimeGPU(CodeGenModule &CGM)
llvm_unreachable("OpenMP can only handle device code.");
llvm::OpenMPIRBuilder &OMPBuilder = getOMPBuilder();
- if (CGM.getLangOpts().OpenMPTargetNewRuntime) {
+ if (CGM.getLangOpts().OpenMPTargetNewRuntime &&
+ !CGM.getLangOpts().OMPHostIRFile.empty()) {
OMPBuilder.createGlobalFlag(CGM.getLangOpts().OpenMPTargetDebug,
"__omp_rtl_debug_kind");
OMPBuilder.createGlobalFlag(CGM.getLangOpts().OpenMPTeamSubscription,
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 520483bc08b6..9e939bb545ad 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -385,7 +385,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
cast<OMPTargetTeamsDistributeSimdDirective>(*S));
break;
case Stmt::OMPInteropDirectiveClass:
- llvm_unreachable("Interop directive not supported yet.");
+ EmitOMPInteropDirective(cast<OMPInteropDirective>(*S));
break;
case Stmt::OMPDispatchDirectiveClass:
llvm_unreachable("Dispatch directive not supported yet.");
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 0db59dd2624c..39dd4c00765d 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -30,6 +30,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/AtomicOrdering.h"
using namespace clang;
@@ -6568,6 +6569,60 @@ void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
[](CodeGenFunction &) { return nullptr; });
}
+void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {
+ llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
+ llvm::Value *Device = nullptr;
+ if (const auto *C = S.getSingleClause<OMPDeviceClause>())
+ Device = EmitScalarExpr(C->getDevice());
+
+ llvm::Value *NumDependences = nullptr;
+ llvm::Value *DependenceAddress = nullptr;
+ if (const auto *DC = S.getSingleClause<OMPDependClause>()) {
+ OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(),
+ DC->getModifier());
+ Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end());
+ std::pair<llvm::Value *, Address> DependencePair =
+ CGM.getOpenMPRuntime().emitDependClause(*this, Dependencies,
+ DC->getBeginLoc());
+ NumDependences = DependencePair.first;
+ DependenceAddress = Builder.CreatePointerCast(
+ DependencePair.second.getPointer(), CGM.Int8PtrTy);
+ }
+
+ assert(!(S.hasClausesOfKind<OMPNowaitClause>() &&
+ !(S.getSingleClause<OMPInitClause>() ||
+ S.getSingleClause<OMPDestroyClause>() ||
+ S.getSingleClause<OMPUseClause>())) &&
+ "OMPNowaitClause clause is used separately in OMPInteropDirective.");
+
+ if (const auto *C = S.getSingleClause<OMPInitClause>()) {
+ llvm::Value *InteropvarPtr =
+ EmitLValue(C->getInteropVar()).getPointer(*this);
+ llvm::omp::OMPInteropType InteropType = llvm::omp::OMPInteropType::Unknown;
+ if (C->getIsTarget()) {
+ InteropType = llvm::omp::OMPInteropType::Target;
+ } else {
+ assert(C->getIsTargetSync() && "Expected interop-type target/targetsync");
+ InteropType = llvm::omp::OMPInteropType::TargetSync;
+ }
+ OMPBuilder.createOMPInteropInit(Builder, InteropvarPtr, InteropType, Device,
+ NumDependences, DependenceAddress,
+ S.hasClausesOfKind<OMPNowaitClause>());
+ } else if (const auto *C = S.getSingleClause<OMPDestroyClause>()) {
+ llvm::Value *InteropvarPtr =
+ EmitLValue(C->getInteropVar()).getPointer(*this);
+ OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
+ NumDependences, DependenceAddress,
+ S.hasClausesOfKind<OMPNowaitClause>());
+ } else if (const auto *C = S.getSingleClause<OMPUseClause>()) {
+ llvm::Value *InteropvarPtr =
+ EmitLValue(C->getInteropVar()).getPointer(*this);
+ OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
+ NumDependences, DependenceAddress,
+ S.hasClausesOfKind<OMPNowaitClause>());
+ }
+}
+
static void emitTargetTeamsDistributeParallelForRegion(
CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S,
PrePostActionTy &Action) {
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index b72b16cf2b5f..c2c508dedb09 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -1134,6 +1134,7 @@ void CodeGenAction::ExecuteAction() {
TheModule->setTargetTriple(TargetOpts.Triple);
}
+ EmbedObject(TheModule.get(), CodeGenOpts, Diagnostics);
EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile);
LLVMContext &Ctx = TheModule->getContext();
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 6db888dcec08..df99cd9a1b79 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3562,6 +3562,7 @@ public:
void EmitOMPTargetTeamsDistributeSimdDirective(
const OMPTargetTeamsDistributeSimdDirective &S);
void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S);
+ void EmitOMPInteropDirective(const OMPInteropDirective &S);
/// Emit device code for the target directive.
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d534cf182f5a..2346176a1562 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -731,6 +731,7 @@ void CodeGenModule::Release() {
"tag-stack-memory-buildattr", 1);
if (Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb ||
+ Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb ||
Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 ||
Arch == llvm::Triple::aarch64_be) {
getModule().addModuleFlag(llvm::Module::Error, "branch-target-enforcement",
@@ -742,11 +743,9 @@ void CodeGenModule::Release() {
getModule().addModuleFlag(llvm::Module::Error, "sign-return-address-all",
LangOpts.isSignReturnAddressScopeAll());
- if (Arch != llvm::Triple::thumb && Arch != llvm::Triple::thumbeb) {
- getModule().addModuleFlag(llvm::Module::Error,
- "sign-return-address-with-bkey",
- !LangOpts.isSignReturnAddressWithAKey());
- }
+ getModule().addModuleFlag(llvm::Module::Error,
+ "sign-return-address-with-bkey",
+ !LangOpts.isSignReturnAddressWithAKey());
}
if (!CodeGenOpts.MemoryProfileOutput.empty()) {
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index e803022508a4..1fcd5d4d808a 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -394,13 +394,6 @@ private:
llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames;
llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings;
- // An ordered map of canonical GlobalDecls paired with the cpu-index for
- // cpu-specific name manglings.
- llvm::MapVector<std::pair<GlobalDecl, unsigned>, StringRef>
- CPUSpecificMangledDeclNames;
- llvm::StringMap<std::pair<GlobalDecl, unsigned>, llvm::BumpPtrAllocator>
- CPUSpecificManglings;
-
/// Global annotations.
std::vector<llvm::Constant*> Annotations;
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index fb81169003fc..8a0150218a7a 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -5563,8 +5563,8 @@ public:
TargetInfo::BranchProtectionInfo BPI;
StringRef Error;
- (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
- BPI, Error);
+ (void)CGM.getTarget().validateBranchProtection(
+ Attr.BranchProtection, Attr.Architecture, BPI, Error);
assert(Error.empty());
auto *Fn = cast<llvm::Function>(GV);
@@ -6377,17 +6377,36 @@ public:
if (!Attr.BranchProtection.empty()) {
TargetInfo::BranchProtectionInfo BPI;
StringRef DiagMsg;
- (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
- BPI, DiagMsg);
-
- static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
- assert(static_cast<unsigned>(BPI.SignReturnAddr) <= 2 &&
- "Unexpected SignReturnAddressScopeKind");
- Fn->addFnAttr("sign-return-address",
- SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]);
+ StringRef Arch = Attr.Architecture.empty()
+ ? CGM.getTarget().getTargetOpts().CPU
+ : Attr.Architecture;
+ if (!CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
+ Arch, BPI, DiagMsg)) {
+ CGM.getDiags().Report(
+ D->getLocation(),
+ diag::warn_target_unsupported_branch_protection_attribute)
+ << Arch;
+ } else {
+ static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
+ assert(static_cast<unsigned>(BPI.SignReturnAddr) <= 2 &&
+ "Unexpected SignReturnAddressScopeKind");
+ Fn->addFnAttr(
+ "sign-return-address",
+ SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]);
- Fn->addFnAttr("branch-target-enforcement",
- BPI.BranchTargetEnforcement ? "true" : "false");
+ Fn->addFnAttr("branch-target-enforcement",
+ BPI.BranchTargetEnforcement ? "true" : "false");
+ }
+ } else if (CGM.getLangOpts().BranchTargetEnforcement ||
+ CGM.getLangOpts().hasSignReturnAddress()) {
+ // If the Branch Protection attribute is missing, validate the target
+ // Architecture attribute against Branch Protection command line
+ // settings.
+ if (!CGM.getTarget().isBranchProtectionSupportedArch(Attr.Architecture))
+ CGM.getDiags().Report(
+ D->getLocation(),
+ diag::warn_target_unsupported_branch_protection_attribute)
+ << Attr.Architecture;
}
}
@@ -8285,12 +8304,14 @@ public:
// Check if global/static variable is defined in address space
// 1~6 (__flash, __flash1, __flash2, __flash3, __flash4, __flash5)
// but not constant.
- LangAS AS = D->getType().getAddressSpace();
- if (isTargetAddressSpace(AS) && 1 <= toTargetAddressSpace(AS) &&
- toTargetAddressSpace(AS) <= 6 && !D->getType().isConstQualified())
- CGM.getDiags().Report(D->getLocation(),
- diag::err_verify_nonconst_addrspace)
- << "__flash*";
+ if (D) {
+ LangAS AS = D->getType().getAddressSpace();
+ if (isTargetAddressSpace(AS) && 1 <= toTargetAddressSpace(AS) &&
+ toTargetAddressSpace(AS) <= 6 && !D->getType().isConstQualified())
+ CGM.getDiags().Report(D->getLocation(),
+ diag::err_verify_nonconst_addrspace)
+ << "__flash*";
+ }
return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D);
}
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index e2d2f6c22de0..eb08bfe9cde5 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -43,6 +43,8 @@ const char *Action::getClassName(ActionClass AC) {
return "clang-offload-unbundler";
case OffloadWrapperJobClass:
return "clang-offload-wrapper";
+ case LinkerWrapperJobClass:
+ return "clang-linker-wrapper";
case StaticLibJobClass:
return "static-lib-linker";
}
@@ -418,6 +420,12 @@ OffloadWrapperJobAction::OffloadWrapperJobAction(ActionList &Inputs,
types::ID Type)
: JobAction(OffloadWrapperJobClass, Inputs, Type) {}
+void LinkerWrapperJobAction::anchor() {}
+
+LinkerWrapperJobAction::LinkerWrapperJobAction(ActionList &Inputs,
+ types::ID Type)
+ : JobAction(LinkerWrapperJobClass, Inputs, Type) {}
+
void StaticLibJobAction::anchor() {}
StaticLibJobAction::StaticLibJobAction(ActionList &Inputs, types::ID Type)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 2e4ebc10e9ba..3bfddeefc7b2 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -103,39 +103,58 @@ using namespace clang;
using namespace llvm::opt;
static llvm::Optional<llvm::Triple>
-getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
- if (Args.hasArg(options::OPT_offload_EQ)) {
- auto HIPOffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
+getOffloadTargetTriple(const Driver &D, const ArgList &Args) {
+ auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
+ // Offload compilation flow does not support multiple targets for now. We
+ // need the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too)
+ // to support multiple tool chains first.
+ switch (OffloadTargets.size()) {
+ default:
+ D.Diag(diag::err_drv_only_one_offload_target_supported);
+ return llvm::None;
+ case 0:
+ D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
+ return llvm::None;
+ case 1:
+ break;
+ }
+ return llvm::Triple(OffloadTargets[0]);
+}
- // HIP compilation flow does not support multiple targets for now. We need
- // the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too) to
- // support multiple tool chains first.
- switch (HIPOffloadTargets.size()) {
- default:
- D.Diag(diag::err_drv_only_one_offload_target_supported_in) << "HIP";
- return llvm::None;
- case 0:
- D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
- return llvm::None;
- case 1:
- break;
- }
- llvm::Triple TT(HIPOffloadTargets[0]);
- if (TT.getArch() == llvm::Triple::amdgcn &&
- TT.getVendor() == llvm::Triple::AMD &&
- TT.getOS() == llvm::Triple::AMDHSA)
- return TT;
- if (TT.getArch() == llvm::Triple::spirv64 &&
- TT.getVendor() == llvm::Triple::UnknownVendor &&
- TT.getOS() == llvm::Triple::UnknownOS)
+static llvm::Optional<llvm::Triple>
+getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args,
+ const llvm::Triple &HostTriple) {
+ if (!Args.hasArg(options::OPT_offload_EQ)) {
+ return llvm::Triple(HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda"
+ : "nvptx-nvidia-cuda");
+ }
+ auto TT = getOffloadTargetTriple(D, Args);
+ if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
+ TT->getArch() == llvm::Triple::spirv64)) {
+ if (Args.hasArg(options::OPT_emit_llvm))
return TT;
- D.Diag(diag::err_drv_invalid_or_unsupported_offload_target)
- << HIPOffloadTargets[0];
+ D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
return llvm::None;
}
-
- static const llvm::Triple T("amdgcn-amd-amdhsa"); // Default HIP triple.
- return T;
+ D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
+ return llvm::None;
+}
+static llvm::Optional<llvm::Triple>
+getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
+ if (!Args.hasArg(options::OPT_offload_EQ)) {
+ return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple.
+ }
+ auto TT = getOffloadTargetTriple(D, Args);
+ if (!TT)
+ return llvm::None;
+ if (TT->getArch() == llvm::Triple::amdgcn &&
+ TT->getVendor() == llvm::Triple::AMD &&
+ TT->getOS() == llvm::Triple::AMDHSA)
+ return TT;
+ if (TT->getArch() == llvm::Triple::spirv64)
+ return TT;
+ D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
+ return llvm::None;
}
// static
@@ -719,17 +738,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
if (IsCuda) {
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
const llvm::Triple &HostTriple = HostTC->getTriple();
- StringRef DeviceTripleStr;
auto OFK = Action::OFK_Cuda;
- DeviceTripleStr =
- HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda" : "nvptx-nvidia-cuda";
- llvm::Triple CudaTriple(DeviceTripleStr);
+ auto CudaTriple =
+ getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(), HostTriple);
+ if (!CudaTriple)
+ return;
// Use the CUDA and host triples as the key into the ToolChains map,
// because the device toolchain we create depends on both.
- auto &CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()];
+ auto &CudaTC = ToolChains[CudaTriple->str() + "/" + HostTriple.str()];
if (!CudaTC) {
CudaTC = std::make_unique<toolchains::CudaToolChain>(
- *this, CudaTriple, *HostTC, C.getInputArgs(), OFK);
+ *this, *CudaTriple, *HostTC, C.getInputArgs(), OFK);
}
C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
} else if (IsHIP) {
@@ -773,21 +792,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
if (HasValidOpenMPRuntime) {
llvm::StringMap<const char *> FoundNormalizedTriples;
for (const char *Val : OpenMPTargets->getValues()) {
- llvm::Triple TT(Val);
+ llvm::Triple TT(ToolChain::getOpenMPTriple(Val));
std::string NormalizedName = TT.normalize();
- // We want to expand the shortened versions of the triples passed in to
- // the values used for the bitcode libraries for convenience.
- if (TT.getVendor() == llvm::Triple::UnknownVendor ||
- TT.getOS() == llvm::Triple::UnknownOS) {
- if (TT.getArch() == llvm::Triple::nvptx)
- TT = llvm::Triple("nvptx-nvidia-cuda");
- else if (TT.getArch() == llvm::Triple::nvptx64)
- TT = llvm::Triple("nvptx64-nvidia-cuda");
- else if (TT.getArch() == llvm::Triple::amdgcn)
- TT = llvm::Triple("amdgcn-amd-amdhsa");
- }
-
// Make sure we don't have a duplicate triple.
auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
if (Duplicate != FoundNormalizedTriples.end()) {
@@ -3823,6 +3830,11 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Builder to be used to build offloading actions.
OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
+ // Offload kinds active for this compilation.
+ unsigned OffloadKinds = Action::OFK_None;
+ if (C.hasOffloadToolChain<Action::OFK_OpenMP>())
+ OffloadKinds |= Action::OFK_OpenMP;
+
// Construct the actions to perform.
HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
ActionList LinkerInputs;
@@ -3843,14 +3855,16 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Use the current host action in any of the offloading actions, if
// required.
- if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
- break;
+ if (!Args.hasArg(options::OPT_fopenmp_new_driver))
+ if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
+ break;
for (phases::ID Phase : PL) {
// Add any offload action the host action depends on.
- Current = OffloadBuilder.addDeviceDependencesToHostAction(
- Current, InputArg, Phase, PL.back(), FullPL);
+ if (!Args.hasArg(options::OPT_fopenmp_new_driver))
+ Current = OffloadBuilder.addDeviceDependencesToHostAction(
+ Current, InputArg, Phase, PL.back(), FullPL);
if (!Current)
break;
@@ -3883,6 +3897,11 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
break;
}
+ // Try to build the offloading actions and add the result as a dependency
+ // to the host.
+ if (Args.hasArg(options::OPT_fopenmp_new_driver))
+ Current = BuildOffloadingActions(C, Args, I, Current);
+
// FIXME: Should we include any prior module file outputs as inputs of
// later actions in the same command line?
@@ -3900,8 +3919,9 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Use the current host action in any of the offloading actions, if
// required.
- if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
- break;
+ if (!Args.hasArg(options::OPT_fopenmp_new_driver))
+ if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
+ break;
if (Current->getType() == types::TY_Nothing)
break;
@@ -3912,7 +3932,11 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Actions.push_back(Current);
// Add any top level actions generated for offloading.
- OffloadBuilder.appendTopLevelActions(Actions, Current, InputArg);
+ if (!Args.hasArg(options::OPT_fopenmp_new_driver))
+ OffloadBuilder.appendTopLevelActions(Actions, Current, InputArg);
+ else if (Current)
+ Current->propagateHostOffloadInfo(OffloadKinds,
+ /*BoundArch=*/nullptr);
}
// Add a link action if necessary.
@@ -3924,16 +3948,23 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
}
if (!LinkerInputs.empty()) {
- if (Action *Wrapper = OffloadBuilder.makeHostLinkAction())
- LinkerInputs.push_back(Wrapper);
+ if (!Args.hasArg(options::OPT_fopenmp_new_driver))
+ if (Action *Wrapper = OffloadBuilder.makeHostLinkAction())
+ LinkerInputs.push_back(Wrapper);
Action *LA;
// Check if this Linker Job should emit a static library.
if (ShouldEmitStaticLibrary(Args)) {
LA = C.MakeAction<StaticLibJobAction>(LinkerInputs, types::TY_Image);
+ } else if (Args.hasArg(options::OPT_fopenmp_new_driver) &&
+ OffloadKinds != Action::OFK_None) {
+ LA = C.MakeAction<LinkerWrapperJobAction>(LinkerInputs, types::TY_Image);
+ LA->propagateHostOffloadInfo(OffloadKinds,
+ /*BoundArch=*/nullptr);
} else {
LA = C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image);
}
- LA = OffloadBuilder.processHostLinkAction(LA);
+ if (!Args.hasArg(options::OPT_fopenmp_new_driver))
+ LA = OffloadBuilder.processHostLinkAction(LA);
Actions.push_back(LA);
}
@@ -4019,6 +4050,68 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Args.ClaimAllArgs(options::OPT_cuda_compile_host_device);
}
+Action *Driver::BuildOffloadingActions(Compilation &C,
+ llvm::opt::DerivedArgList &Args,
+ const InputTy &Input,
+ Action *HostAction) const {
+ if (!isa<CompileJobAction>(HostAction))
+ return HostAction;
+
+ SmallVector<const ToolChain *, 2> ToolChains;
+ ActionList DeviceActions;
+
+ types::ID InputType = Input.first;
+ const Arg *InputArg = Input.second;
+
+ auto OpenMPTCRange = C.getOffloadToolChains<Action::OFK_OpenMP>();
+ for (auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE; ++TI)
+ ToolChains.push_back(TI->second);
+
+ for (unsigned I = 0; I < ToolChains.size(); ++I)
+ DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType));
+
+ if (DeviceActions.empty())
+ return HostAction;
+
+ auto PL = types::getCompilationPhases(*this, Args, InputType);
+
+ for (phases::ID Phase : PL) {
+ if (Phase == phases::Link) {
+ assert(Phase == PL.back() && "linking must be final compilation step.");
+ break;
+ }
+
+ auto TC = ToolChains.begin();
+ for (Action *&A : DeviceActions) {
+ A = ConstructPhaseAction(C, Args, Phase, A, Action::OFK_OpenMP);
+
+ if (isa<CompileJobAction>(A)) {
+ HostAction->setCannotBeCollapsedWithNextDependentAction();
+ OffloadAction::HostDependence HDep(
+ *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
+ /*BourdArch=*/nullptr, Action::OFK_OpenMP);
+ OffloadAction::DeviceDependences DDep;
+ DDep.add(*A, **TC, /*BoundArch=*/nullptr, Action::OFK_OpenMP);
+ A = C.MakeAction<OffloadAction>(HDep, DDep);
+ }
+ ++TC;
+ }
+ }
+
+ OffloadAction::DeviceDependences DDeps;
+
+ auto TC = ToolChains.begin();
+ for (Action *A : DeviceActions) {
+ DDeps.add(*A, **TC, /*BoundArch=*/nullptr, Action::OFK_OpenMP);
+ TC++;
+ }
+
+ OffloadAction::HostDependence HDep(
+ *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
+ /*BoundArch=*/nullptr, DDeps);
+ return C.MakeAction<OffloadAction>(HDep, DDeps);
+}
+
Action *Driver::ConstructPhaseAction(
Compilation &C, const ArgList &Args, phases::ID Phase, Action *Input,
Action::OffloadKind TargetDeviceOffloadKind) const {
@@ -4110,6 +4203,12 @@ Action *Driver::ConstructPhaseAction(
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return C.MakeAction<BackendJobAction>(Input, Output);
}
+ if (isUsingLTO(/* IsOffload */ true) &&
+ TargetDeviceOffloadKind == Action::OFK_OpenMP) {
+ types::ID Output =
+ Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
+ return C.MakeAction<BackendJobAction>(Input, Output);
+ }
if (Args.hasArg(options::OPT_emit_llvm) ||
(TargetDeviceOffloadKind == Action::OFK_HIP &&
Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
@@ -4181,7 +4280,7 @@ void Driver::BuildJobs(Compilation &C) const {
ArchNames.insert(A->getValue());
// Set of (Action, canonical ToolChain triple) pairs we've built jobs for.
- std::map<std::pair<const Action *, std::string>, InputInfo> CachedResults;
+ std::map<std::pair<const Action *, std::string>, InputInfoList> CachedResults;
for (Action *A : C.getActions()) {
// If we are linking an image for multiple archs then the linker wants
// -arch_multiple and -final_output <final image name>. Unfortunately, this
@@ -4638,10 +4737,11 @@ static std::string GetTriplePlusArchString(const ToolChain *TC,
return TriplePlusArch;
}
-InputInfo Driver::BuildJobsForAction(
+InputInfoList Driver::BuildJobsForAction(
Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
- std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults,
+ std::map<std::pair<const Action *, std::string>, InputInfoList>
+ &CachedResults,
Action::OffloadKind TargetDeviceOffloadKind) const {
std::pair<const Action *, std::string> ActionTC = {
A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
@@ -4649,17 +4749,18 @@ InputInfo Driver::BuildJobsForAction(
if (CachedResult != CachedResults.end()) {
return CachedResult->second;
}
- InputInfo Result = BuildJobsForActionNoCache(
+ InputInfoList Result = BuildJobsForActionNoCache(
C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
CachedResults, TargetDeviceOffloadKind);
CachedResults[ActionTC] = Result;
return Result;
}
-InputInfo Driver::BuildJobsForActionNoCache(
+InputInfoList Driver::BuildJobsForActionNoCache(
Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
- std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults,
+ std::map<std::pair<const Action *, std::string>, InputInfoList>
+ &CachedResults,
Action::OffloadKind TargetDeviceOffloadKind) const {
llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
@@ -4697,7 +4798,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
// If there is a single device option, just generate the job for it.
if (OA->hasSingleDeviceDependence()) {
- InputInfo DevA;
+ InputInfoList DevA;
OA->doOnEachDeviceDependence([&](Action *DepA, const ToolChain *DepTC,
const char *DepBoundArch) {
DevA =
@@ -4715,7 +4816,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
OA->doOnEachDependence(
/*IsHostDependence=*/BuildingForOffloadDevice,
[&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) {
- OffloadDependencesInputInfo.push_back(BuildJobsForAction(
+ OffloadDependencesInputInfo.append(BuildJobsForAction(
C, DepA, DepTC, DepBoundArch, /*AtTopLevel=*/false,
/*MultipleArchs*/ !!DepBoundArch, LinkingOutput, CachedResults,
DepA->getOffloadingDeviceKind()));
@@ -4724,6 +4825,17 @@ InputInfo Driver::BuildJobsForActionNoCache(
A = BuildingForOffloadDevice
? OA->getSingleDeviceDependence(/*DoNotConsiderHostActions=*/true)
: OA->getHostDependence();
+
+ // We may have already built this action as a part of the offloading
+ // toolchain, return the cached input if so.
+ std::pair<const Action *, std::string> ActionTC = {
+ OA->getHostDependence(),
+ GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
+ if (CachedResults.find(ActionTC) != CachedResults.end()) {
+ InputInfoList Inputs = CachedResults[ActionTC];
+ Inputs.append(OffloadDependencesInputInfo);
+ return Inputs;
+ }
}
if (const InputAction *IA = dyn_cast<InputAction>(A)) {
@@ -4733,9 +4845,9 @@ InputInfo Driver::BuildJobsForActionNoCache(
Input.claim();
if (Input.getOption().matches(options::OPT_INPUT)) {
const char *Name = Input.getValue();
- return InputInfo(A, Name, /* _BaseInput = */ Name);
+ return {InputInfo(A, Name, /* _BaseInput = */ Name)};
}
- return InputInfo(A, &Input, /* _BaseInput = */ "");
+ return {InputInfo(A, &Input, /* _BaseInput = */ "")};
}
if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
@@ -4765,7 +4877,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
if (!T)
- return InputInfo();
+ return {InputInfo()};
if (BuildingForOffloadDevice &&
A->getOffloadingDeviceKind() == Action::OFK_OpenMP) {
@@ -4792,7 +4904,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
cast<OffloadAction>(OA)->doOnEachDependence(
/*IsHostDependence=*/BuildingForOffloadDevice,
[&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) {
- OffloadDependencesInputInfo.push_back(BuildJobsForAction(
+ OffloadDependencesInputInfo.append(BuildJobsForAction(
C, DepA, DepTC, DepBoundArch, /* AtTopLevel */ false,
/*MultipleArchs=*/!!DepBoundArch, LinkingOutput, CachedResults,
DepA->getOffloadingDeviceKind()));
@@ -4806,7 +4918,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
// FIXME: Clean this up.
bool SubJobAtTopLevel =
AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
- InputInfos.push_back(BuildJobsForAction(
+ InputInfos.append(BuildJobsForAction(
C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
CachedResults, A->getOffloadingDeviceKind()));
}
@@ -4890,8 +5002,8 @@ InputInfo Driver::BuildJobsForActionNoCache(
Arch = BoundArch;
CachedResults[{A, GetTriplePlusArchString(UI.DependentToolChain, Arch,
- UI.DependentOffloadKind)}] =
- CurI;
+ UI.DependentOffloadKind)}] = {
+ CurI};
}
// Now that we have all the results generated, select the one that should be
@@ -4900,9 +5012,9 @@ InputInfo Driver::BuildJobsForActionNoCache(
A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
assert(CachedResults.find(ActionTC) != CachedResults.end() &&
"Result does not exist??");
- Result = CachedResults[ActionTC];
+ Result = CachedResults[ActionTC].front();
} else if (JA->getType() == types::TY_Nothing)
- Result = InputInfo(A, BaseInput);
+ Result = {InputInfo(A, BaseInput)};
else {
// We only have to generate a prefix for the host if this is not a top-level
// action.
@@ -4955,7 +5067,7 @@ InputInfo Driver::BuildJobsForActionNoCache(
C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()),
LinkingOutput);
}
- return Result;
+ return {Result};
}
const char *Driver::getDefaultImageName() const {
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 5fef1fb2ee5a..d657d21bfcdb 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -327,6 +327,12 @@ Tool *ToolChain::getOffloadWrapper() const {
return OffloadWrapper.get();
}
+Tool *ToolChain::getLinkerWrapper() const {
+ if (!LinkerWrapper)
+ LinkerWrapper.reset(new tools::LinkerWrapper(*this, getLink()));
+ return LinkerWrapper.get();
+}
+
Tool *ToolChain::getTool(Action::ActionClass AC) const {
switch (AC) {
case Action::AssembleJobClass:
@@ -365,6 +371,8 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
case Action::OffloadWrapperJobClass:
return getOffloadWrapper();
+ case Action::LinkerWrapperJobClass:
+ return getLinkerWrapper();
}
llvm_unreachable("Invalid tool kind.");
@@ -1129,8 +1137,10 @@ llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
A->getOption().matches(options::OPT_Xopenmp_target);
if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
+ llvm::Triple TT(getOpenMPTriple(A->getValue(0)));
+
// Passing device args: -Xopenmp-target=<triple> -opt=val.
- if (A->getValue(0) == getTripleString())
+ if (TT.getTriple() == getTripleString())
Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
else
continue;
diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
index 6899f9360da5..d7cf41e4b660 100644
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -285,6 +285,10 @@ void AMDGPUOpenMPToolChain::addClangTargetOptions(
if (DriverArgs.hasArg(options::OPT_nogpulib))
return;
+ // Link the bitcode library late if we're using device LTO.
+ if (getDriver().isUsingLTO(/* IsOffload */ true))
+ return;
+
std::string BitcodeSuffix;
if (DriverArgs.hasFlag(options::OPT_fopenmp_target_new_runtime,
options::OPT_fno_openmp_target_new_runtime, true))
diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp
index a66cae8b4d6b..2cf16cf9fdb4 100644
--- a/clang/lib/Driver/ToolChains/AVR.cpp
+++ b/clang/lib/Driver/ToolChains/AVR.cpp
@@ -379,6 +379,11 @@ void AVRToolChain::addClangTargetOptions(
if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
options::OPT_fno_use_init_array, false))
CC1Args.push_back("-fno-use-init-array");
+ // Use `-fno-use-cxa-atexit` as default, since avr-libc does not support
+ // `__cxa_atexit()`.
+ if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit,
+ options::OPT_fno_use_cxa_atexit, false))
+ CC1Args.push_back("-fno-use-cxa-atexit");
}
Tool *AVRToolChain::buildLinker() const {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4386e395bc6c..7aac977209eb 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1627,7 +1627,7 @@ void RenderARMABI(const Driver &D, const llvm::Triple &Triple,
}
}
-static void CollectARMPACBTIOptions(const Driver &D, const ArgList &Args,
+static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool isAArch64) {
const Arg *A = isAArch64
? Args.getLastArg(options::OPT_msign_return_address_EQ,
@@ -1636,6 +1636,12 @@ static void CollectARMPACBTIOptions(const Driver &D, const ArgList &Args,
if (!A)
return;
+ const Driver &D = TC.getDriver();
+ const llvm::Triple &Triple = TC.getEffectiveTriple();
+ if (!(isAArch64 || (Triple.isArmT32() && Triple.isArmMClass())))
+ D.Diag(diag::warn_target_unsupported_branch_protection_option)
+ << Triple.getArchName();
+
StringRef Scope, Key;
bool IndirectBranches;
@@ -1713,8 +1719,7 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
// Enable/disable return address signing and indirect branch targets.
- CollectARMPACBTIOptions(getToolChain().getDriver(), Args, CmdArgs,
- false /*isAArch64*/);
+ CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, false /*isAArch64*/);
}
void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
@@ -1841,8 +1846,7 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
}
// Enable/disable return address signing and indirect branch targets.
- CollectARMPACBTIOptions(getToolChain().getDriver(), Args, CmdArgs,
- true /*isAArch64*/);
+ CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/);
// Handle -msve_vector_bits=<bits>
if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
@@ -4347,6 +4351,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
+ bool IsOpenMPHost = JA.isHostOffloading(Action::OFK_OpenMP);
bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(Action::OFK_None) ||
JA.isDeviceOffloading(Action::OFK_Host));
@@ -4365,6 +4370,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
IsHeaderModulePrecompile ? HeaderModuleInput : Inputs[0];
InputInfoList ModuleHeaderInputs;
+ InputInfoList OpenMPHostInputs;
const InputInfo *CudaDeviceInput = nullptr;
const InputInfo *OpenMPDeviceInput = nullptr;
for (const InputInfo &I : Inputs) {
@@ -4383,6 +4389,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CudaDeviceInput = &I;
} else if (IsOpenMPDevice && !OpenMPDeviceInput) {
OpenMPDeviceInput = &I;
+ } else if (IsOpenMPHost) {
+ OpenMPHostInputs.push_back(I);
} else {
llvm_unreachable("unexpectedly given multiple inputs");
}
@@ -4611,7 +4619,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (JA.getType() == types::TY_LLVM_BC)
CmdArgs.push_back("-emit-llvm-uselists");
- if (IsUsingLTO) {
+ if (IsUsingLTO && !Args.hasArg(options::OPT_fopenmp_new_driver)) {
// Only AMDGPU supports device-side LTO.
if (IsDeviceOffloadAction && !Triple.isAMDGPU()) {
D.Diag(diag::err_drv_unsupported_opt_for_target)
@@ -6262,7 +6270,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasFlag(
options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
!RawTriple.isOSAIX() && !RawTriple.isOSWindows() &&
- TC.getArch() != llvm::Triple::xcore &&
((RawTriple.getVendor() != llvm::Triple::MipsTechnologies) ||
RawTriple.hasEnvironment())) ||
KernelOrKext)
@@ -6890,6 +6897,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ // Host-side OpenMP offloading recieves the device object files and embeds it
+ // in a named section including the associated target triple and architecture.
+ if (IsOpenMPHost && !OpenMPHostInputs.empty()) {
+ auto InputFile = OpenMPHostInputs.begin();
+ auto OpenMPTCs = C.getOffloadToolChains<Action::OFK_OpenMP>();
+ for (auto TI = OpenMPTCs.first, TE = OpenMPTCs.second; TI != TE;
+ ++TI, ++InputFile) {
+ const ToolChain *TC = TI->second;
+ const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP);
+ StringRef File =
+ C.getArgs().MakeArgString(TC->getInputFilename(*InputFile));
+ StringRef InputName = Clang::getBaseInputStem(Args, Inputs);
+
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fembed-offload-object=" + File + "," + TC->getTripleString() + "." +
+ TCArgs.getLastArgValue(options::OPT_march_EQ) + "." + InputName));
+ }
+ }
+
if (Triple.isAMDGPU()) {
handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs);
@@ -8116,3 +8142,122 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
Args.MakeArgString(getToolChain().GetProgramPath(getShortName())),
CmdArgs, Inputs, Output));
}
+
+void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ ArgStringList CmdArgs;
+
+ if (getToolChain().getDriver().isUsingLTO(/* IsOffload */ true)) {
+ // Pass in target features for each toolchain.
+ auto OpenMPTCRange = C.getOffloadToolChains<Action::OFK_OpenMP>();
+ for (auto &I :
+ llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) {
+ const ToolChain *TC = I.second;
+ const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP);
+ ArgStringList FeatureArgs;
+ TC->addClangTargetOptions(TCArgs, FeatureArgs, Action::OFK_OpenMP);
+ auto FeatureIt = llvm::find(FeatureArgs, "-target-feature");
+ CmdArgs.push_back(Args.MakeArgString(
+ "-target-feature=" + TC->getTripleString() + "=" + *(FeatureIt + 1)));
+ }
+
+ // Pass in the bitcode library to be linked during LTO.
+ for (auto &I : llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) {
+ const ToolChain *TC = I.second;
+ const Driver &D = TC->getDriver();
+ const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP);
+ StringRef Arch = TCArgs.getLastArgValue(options::OPT_march_EQ);
+
+ std::string BitcodeSuffix;
+ if (TCArgs.hasFlag(options::OPT_fopenmp_target_new_runtime,
+ options::OPT_fno_openmp_target_new_runtime, true))
+ BitcodeSuffix += "new-";
+ if (TC->getTriple().isNVPTX())
+ BitcodeSuffix += "nvptx-";
+ else if (TC->getTriple().isAMDGPU())
+ BitcodeSuffix += "amdgpu-";
+ BitcodeSuffix += Arch;
+
+ ArgStringList BitcodeLibrary;
+ addOpenMPDeviceRTL(D, TCArgs, BitcodeLibrary, BitcodeSuffix,
+ TC->getTriple());
+
+ if (!BitcodeLibrary.empty())
+ CmdArgs.push_back(
+ Args.MakeArgString("-target-library=" + TC->getTripleString() +
+ "-" + Arch + "=" + BitcodeLibrary.back()));
+ }
+
+ // Pass in the optimization level to use for LTO.
+ if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+ StringRef OOpt;
+ if (A->getOption().matches(options::OPT_O4) ||
+ A->getOption().matches(options::OPT_Ofast))
+ OOpt = "3";
+ else if (A->getOption().matches(options::OPT_O)) {
+ OOpt = A->getValue();
+ if (OOpt == "g")
+ OOpt = "1";
+ else if (OOpt == "s" || OOpt == "z")
+ OOpt = "2";
+ } else if (A->getOption().matches(options::OPT_O0))
+ OOpt = "0";
+ if (!OOpt.empty())
+ CmdArgs.push_back(Args.MakeArgString(Twine("-opt-level=O") + OOpt));
+ }
+ }
+
+ // Construct the link job so we can wrap around it.
+ Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
+ const auto &LinkCommand = C.getJobs().getJobs().back();
+
+ CmdArgs.push_back("-host-triple");
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
+ if (Args.hasArg(options::OPT_v))
+ CmdArgs.push_back("-v");
+
+ // Add debug information if present.
+ if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
+ const Option &Opt = A->getOption();
+ if (Opt.matches(options::OPT_gN_Group)) {
+ if (Opt.matches(options::OPT_gline_directives_only) ||
+ Opt.matches(options::OPT_gline_tables_only))
+ CmdArgs.push_back("-gline-directives-only");
+ } else
+ CmdArgs.push_back("-g");
+ }
+
+ for (const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
+ CmdArgs.push_back(Args.MakeArgString("-ptxas-args=" + A));
+
+ // Forward remarks passes to the LLVM backend in the wrapper.
+ if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-pass-remarks=") + A->getValue()));
+ if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-pass-remarks-missed=") + A->getValue()));
+ if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-pass-remarks-analysis=") + A->getValue()));
+ if (Args.getLastArg(options::OPT_save_temps_EQ))
+ CmdArgs.push_back("-save-temps");
+
+ // Add the linker arguments to be forwarded by the wrapper.
+ CmdArgs.push_back("-linker-path");
+ CmdArgs.push_back(LinkCommand->getExecutable());
+ CmdArgs.push_back("--");
+ for (const char *LinkArg : LinkCommand->getArguments())
+ CmdArgs.push_back(LinkArg);
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath("clang-linker-wrapper"));
+
+ // Replace the executable and arguments of the link job with the
+ // wrapper.
+ LinkCommand->replaceExecutable(Exec);
+ LinkCommand->replaceArguments(CmdArgs);
+}
diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h
index 013cd2341e17..79407c9884d5 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -170,6 +170,21 @@ public:
const char *LinkingOutput) const override;
};
+/// Linker wrapper tool.
+class LLVM_LIBRARY_VISIBILITY LinkerWrapper final : public Tool {
+ const Tool *Linker;
+
+public:
+ LinkerWrapper(const ToolChain &TC, const Tool *Linker)
+ : Tool("Offload::Linker", "linker", TC), Linker(Linker) {}
+
+ bool hasIntegratedCPP() const override { return false; }
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
+
} // end namespace tools
} // end namespace driver
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 1d30090ca21c..6364cd133e0b 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -645,6 +645,22 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
/*IsLTO=*/true);
}
+void tools::addOpenMPRuntimeSpecificRPath(const ToolChain &TC,
+ const ArgList &Args,
+ ArgStringList &CmdArgs) {
+
+ if (Args.hasFlag(options::OPT_fopenmp_implicit_rpath,
+ options::OPT_fno_openmp_implicit_rpath, true)) {
+ // Default to clang lib / lib64 folder, i.e. the same location as device
+ // runtime
+ SmallString<256> DefaultLibPath =
+ llvm::sys::path::parent_path(TC.getDriver().Dir);
+ llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX);
+ CmdArgs.push_back("-rpath");
+ CmdArgs.push_back(Args.MakeArgString(DefaultLibPath));
+ }
+}
+
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
// Enable -frtlib-add-rpath by default for the case of VE.
@@ -702,6 +718,9 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
addArchSpecificRPath(TC, Args, CmdArgs);
+ if (RTKind == Driver::OMPRT_OMP)
+ addOpenMPRuntimeSpecificRPath(TC, Args, CmdArgs);
+
return true;
}
@@ -826,16 +845,16 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes())
StaticRuntimes.push_back("stats_client");
+ // Always link the static runtime regardless of DSO or executable.
+ if (SanArgs.needsAsanRt())
+ HelperStaticRuntimes.push_back("asan_static");
+
// Collect static runtimes.
if (Args.hasArg(options::OPT_shared)) {
// Don't link static runtimes into DSOs.
return;
}
- // Always link the static runtime for executable.
- if (SanArgs.needsAsanRt())
- HelperStaticRuntimes.push_back("asan_static");
-
// Each static runtime that has a DSO counterpart above is excluded below,
// but runtimes that exist only as static are not affected by needsSharedRt.
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 00291a3681c8..646fa76949b7 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -106,6 +106,9 @@ void AddAssemblerKPIC(const ToolChain &ToolChain,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
+void addOpenMPRuntimeSpecificRPath(const ToolChain &TC,
+ const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs);
void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
/// Returns true, if an OpenMP runtime has been added.
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 7324339efaa6..4a9f6d4c4e3e 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -744,6 +744,10 @@ void CudaToolChain::addClangTargetOptions(
return;
}
+ // Link the bitcode library late if we're using device LTO.
+ if (getDriver().isUsingLTO(/* IsOffload */ true))
+ return;
+
std::string BitcodeSuffix;
if (DriverArgs.hasFlag(options::OPT_fopenmp_target_new_runtime,
options::OPT_fno_openmp_target_new_runtime, true))
diff --git a/clang/lib/Driver/ToolChains/XCore.cpp b/clang/lib/Driver/ToolChains/XCore.cpp
index 7e74f6374050..29fa82aec0a9 100644
--- a/clang/lib/Driver/ToolChains/XCore.cpp
+++ b/clang/lib/Driver/ToolChains/XCore.cpp
@@ -130,6 +130,10 @@ void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
ArgStringList &CC1Args,
Action::OffloadKind) const {
CC1Args.push_back("-nostdsysteminc");
+ // Set `-fno-use-cxa-atexit` to default.
+ if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit,
+ options::OPT_fno_use_cxa_atexit, false))
+ CC1Args.push_back("-fno-use-cxa-atexit");
}
void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp
index 5d03c9811e1b..f68d802c1f95 100644
--- a/clang/lib/Format/BreakableToken.cpp
+++ b/clang/lib/Format/BreakableToken.cpp
@@ -254,8 +254,8 @@ unsigned
BreakableStringLiteral::getRemainingLength(unsigned LineIndex, unsigned Offset,
unsigned StartColumn) const {
return UnbreakableTailLength + Postfix.size() +
- encoding::columnWidthWithTabs(Line.substr(Offset, StringRef::npos),
- StartColumn, Style.TabWidth, Encoding);
+ encoding::columnWidthWithTabs(Line.substr(Offset), StartColumn,
+ Style.TabWidth, Encoding);
}
unsigned BreakableStringLiteral::getContentStartColumn(unsigned LineIndex,
@@ -539,31 +539,30 @@ unsigned BreakableBlockComment::getRangeLength(unsigned LineIndex,
unsigned Offset,
StringRef::size_type Length,
unsigned StartColumn) const {
+ return encoding::columnWidthWithTabs(
+ Content[LineIndex].substr(Offset, Length), StartColumn, Style.TabWidth,
+ Encoding);
+}
+
+unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex,
+ unsigned Offset,
+ unsigned StartColumn) const {
unsigned LineLength =
- encoding::columnWidthWithTabs(Content[LineIndex].substr(Offset, Length),
- StartColumn, Style.TabWidth, Encoding);
- // FIXME: This should go into getRemainingLength instead, but we currently
- // break tests when putting it there. Investigate how to fix those tests.
- // The last line gets a "*/" postfix.
+ UnbreakableTailLength +
+ getRangeLength(LineIndex, Offset, StringRef::npos, StartColumn);
if (LineIndex + 1 == Lines.size()) {
LineLength += 2;
// We never need a decoration when breaking just the trailing "*/" postfix.
- // Note that checking that Length == 0 is not enough, since Length could
- // also be StringRef::npos.
- if (Content[LineIndex].substr(Offset, StringRef::npos).empty()) {
- LineLength -= Decoration.size();
+ bool HasRemainingText = Offset < Content[LineIndex].size();
+ if (!HasRemainingText) {
+ bool HasDecoration = Lines[LineIndex].ltrim().startswith(Decoration);
+ if (HasDecoration)
+ LineLength -= Decoration.size();
}
}
return LineLength;
}
-unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex,
- unsigned Offset,
- unsigned StartColumn) const {
- return UnbreakableTailLength +
- getRangeLength(LineIndex, Offset, StringRef::npos, StartColumn);
-}
-
unsigned BreakableBlockComment::getContentStartColumn(unsigned LineIndex,
bool Break) const {
if (Break)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index b66584652bc8..45a4d23557f7 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1817,8 +1817,8 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
ContentStartsOnNewline || (NewCode->find('\n') != std::string::npos);
if (IsMultiline) {
// Break before further function parameters on all levels.
- for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
- State.Stack[i].BreakBeforeParameter = true;
+ for (ParenState &Paren : State.Stack)
+ Paren.BreakBeforeParameter = true;
}
return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter;
}
@@ -1826,8 +1826,8 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,
LineState &State) {
// Break before further function parameters on all levels.
- for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
- State.Stack[i].BreakBeforeParameter = true;
+ for (ParenState &Paren : State.Stack)
+ Paren.BreakBeforeParameter = true;
unsigned ColumnsUsed = State.Column;
// We can only affect layout of the first and the last line, so the penalty
@@ -2380,8 +2380,8 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
// the next parameter on all levels, so that the next parameter is clearly
// visible. Line comments already introduce a break.
if (Current.isNot(TT_LineComment)) {
- for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
- State.Stack[i].BreakBeforeParameter = true;
+ for (ParenState &Paren : State.Stack)
+ Paren.BreakBeforeParameter = true;
}
if (Current.is(TT_BlockComment))
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 04e2915e3af6..dd4755c2227e 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -44,6 +44,7 @@
#include <algorithm>
#include <memory>
#include <mutex>
+#include <numeric>
#include <string>
#include <unordered_map>
@@ -532,11 +533,9 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("Language", Style.Language);
if (IO.outputting()) {
- StringRef StylesArray[] = {"LLVM", "Google", "Chromium", "Mozilla",
- "WebKit", "GNU", "Microsoft"};
- ArrayRef<StringRef> Styles(StylesArray);
- for (size_t i = 0, e = Styles.size(); i < e; ++i) {
- StringRef StyleName(Styles[i]);
+ StringRef Styles[] = {"LLVM", "Google", "Chromium", "Mozilla",
+ "WebKit", "GNU", "Microsoft"};
+ for (StringRef StyleName : Styles) {
FormatStyle PredefinedStyle;
if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
Style == PredefinedStyle) {
@@ -1681,10 +1680,10 @@ std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
// configuration (which can only be at slot 0) after it.
FormatStyle::FormatStyleSet StyleSet;
bool LanguageFound = false;
- for (int i = Styles.size() - 1; i >= 0; --i) {
- if (Styles[i].Language != FormatStyle::LK_None)
- StyleSet.Add(Styles[i]);
- if (Styles[i].Language == Language)
+ for (const FormatStyle &Style : llvm::reverse(Styles)) {
+ if (Style.Language != FormatStyle::LK_None)
+ StyleSet.Add(Style);
+ if (Style.Language == Language)
LanguageFound = true;
}
if (!LanguageFound) {
@@ -1890,9 +1889,8 @@ public:
tooling::Replacements Result;
deriveLocalStyle(AnnotatedLines);
AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
- for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
- Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
- }
+ for (AnnotatedLine *Line : AnnotatedLines)
+ Annotator.calculateFormattingInformation(*Line);
Annotator.setCommentLineLevels(AnnotatedLines);
WhitespaceManager Whitespaces(
@@ -1962,10 +1960,10 @@ private:
deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
bool HasBinPackedFunction = false;
bool HasOnePerLineFunction = false;
- for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
- if (!AnnotatedLines[i]->First->Next)
+ for (AnnotatedLine *Line : AnnotatedLines) {
+ if (!Line->First->Next)
continue;
- FormatToken *Tok = AnnotatedLines[i]->First->Next;
+ FormatToken *Tok = Line->First->Next;
while (Tok->Next) {
if (Tok->is(PPK_BinPacked))
HasBinPackedFunction = true;
@@ -2524,9 +2522,8 @@ static void sortCppIncludes(const FormatStyle &Style,
if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
return;
SmallVector<unsigned, 16> Indices;
- for (unsigned i = 0, e = Includes.size(); i != e; ++i) {
- Indices.push_back(i);
- }
+ Indices.resize(Includes.size());
+ std::iota(Indices.begin(), Indices.end(), 0);
if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) {
llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
@@ -2678,6 +2675,15 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
if (!FormattingOff && !MergeWithNextLine) {
if (IncludeRegex.match(Line, &Matches)) {
StringRef IncludeName = Matches[2];
+ if (Line.contains("/*") && !Line.contains("*/")) {
+ // #include with a start of a block comment, but without the end.
+ // Need to keep all the lines until the end of the comment together.
+ // FIXME: This is somehow simplified check that probably does not work
+ // correctly if there are multiple comments on a line.
+ Pos = Code.find("*/", SearchFrom);
+ Line = Code.substr(
+ Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);
+ }
int Category = Categories.getIncludePriority(
IncludeName,
/*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
@@ -2718,7 +2724,7 @@ static unsigned findJavaImportGroup(const FormatStyle &Style,
unsigned LongestMatchIndex = UINT_MAX;
unsigned LongestMatchLength = 0;
for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
- std::string GroupPrefix = Style.JavaImportGroups[I];
+ const std::string &GroupPrefix = Style.JavaImportGroups[I];
if (ImportIdentifier.startswith(GroupPrefix) &&
GroupPrefix.length() > LongestMatchLength) {
LongestMatchIndex = I;
@@ -2743,13 +2749,16 @@ static void sortJavaImports(const FormatStyle &Style,
unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
return;
+
SmallVector<unsigned, 16> Indices;
+ Indices.resize(Imports.size());
+ std::iota(Indices.begin(), Indices.end(), 0);
+
SmallVector<unsigned, 16> JavaImportGroups;
- for (unsigned i = 0, e = Imports.size(); i != e; ++i) {
- Indices.push_back(i);
- JavaImportGroups.push_back(
- findJavaImportGroup(Style, Imports[i].Identifier));
- }
+ JavaImportGroups.reserve(Imports.size());
+ for (const JavaImportDirective &Import : Imports)
+ JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier));
+
bool StaticImportAfterNormalImport =
Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index a64329802ee3..f116a89ac644 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -123,6 +123,34 @@ namespace format {
TYPE(CSharpGenericTypeConstraintComma) \
TYPE(Unknown)
+/// Sorted operators that can follow a C variable.
+static const std::vector<clang::tok::TokenKind> COperatorsFollowingVar = [] {
+ std::vector<clang::tok::TokenKind> ReturnVal = {
+ tok::l_square, tok::r_square,
+ tok::l_paren, tok::r_paren,
+ tok::r_brace, tok::period,
+ tok::ellipsis, tok::ampamp,
+ tok::ampequal, tok::star,
+ tok::starequal, tok::plus,
+ tok::plusplus, tok::plusequal,
+ tok::minus, tok::arrow,
+ tok::minusminus, tok::minusequal,
+ tok::exclaim, tok::exclaimequal,
+ tok::slash, tok::slashequal,
+ tok::percent, tok::percentequal,
+ tok::less, tok::lessless,
+ tok::lessequal, tok::lesslessequal,
+ tok::greater, tok::greatergreater,
+ tok::greaterequal, tok::greatergreaterequal,
+ tok::caret, tok::caretequal,
+ tok::pipe, tok::pipepipe,
+ tok::pipeequal, tok::question,
+ tok::semi, tok::equal,
+ tok::equalequal, tok::comma};
+ assert(std::is_sorted(ReturnVal.begin(), ReturnVal.end()));
+ return ReturnVal;
+}();
+
/// Determines the semantic type of a syntactic token, e.g. whether "<" is a
/// template opener or binary operator.
enum TokenType : uint8_t {
diff --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/clang/lib/Format/NamespaceEndCommentsFixer.cpp
index 0c34c6126c21..9fb6c5142672 100644
--- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp
+++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -210,8 +210,8 @@ std::pair<tooling::Replacements, unsigned> NamespaceEndCommentsFixer::analyze(
// Spin through the lines and ensure we have balanced braces.
int Braces = 0;
- for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) {
- FormatToken *Tok = AnnotatedLines[I]->First;
+ for (AnnotatedLine *Line : AnnotatedLines) {
+ FormatToken *Tok = Line->First;
while (Tok) {
Braces += Tok->is(tok::l_brace) ? 1 : Tok->is(tok::r_brace) ? -1 : 0;
Tok = Tok->Next;
diff --git a/clang/lib/Format/SortJavaScriptImports.cpp b/clang/lib/Format/SortJavaScriptImports.cpp
index e4107525a7ff..71326163f45a 100644
--- a/clang/lib/Format/SortJavaScriptImports.cpp
+++ b/clang/lib/Format/SortJavaScriptImports.cpp
@@ -133,7 +133,10 @@ class JavaScriptImportSorter : public TokenAnalyzer {
public:
JavaScriptImportSorter(const Environment &Env, const FormatStyle &Style)
: TokenAnalyzer(Env, Style),
- FileContents(Env.getSourceManager().getBufferData(Env.getFileID())) {}
+ FileContents(Env.getSourceManager().getBufferData(Env.getFileID())) {
+ // FormatToken.Tok starts out in an uninitialized state.
+ invalidToken.Tok.startToken();
+ }
std::pair<tooling::Replacements, unsigned>
analyze(TokenAnnotator &Annotator,
@@ -232,7 +235,6 @@ private:
if (!Current || Current == LineEnd->Next) {
// Set the current token to an invalid token, so that further parsing on
// this line fails.
- invalidToken.Tok.setKind(tok::unknown);
Current = &invalidToken;
}
}
@@ -510,7 +512,6 @@ private:
while (Current->is(tok::identifier)) {
nextToken();
if (Current->is(tok::semi)) {
- nextToken();
return true;
}
if (!Current->is(tok::period))
diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp
index d0754e0c1112..2bd5a1fd6230 100644
--- a/clang/lib/Format/TokenAnalyzer.cpp
+++ b/clang/lib/Format/TokenAnalyzer.cpp
@@ -113,12 +113,13 @@ std::pair<tooling::Replacements, unsigned> TokenAnalyzer::process() {
assert(UnwrappedLines.rbegin()->empty());
unsigned Penalty = 0;
for (unsigned Run = 0, RunE = UnwrappedLines.size(); Run + 1 != RunE; ++Run) {
+ const auto &Lines = UnwrappedLines[Run];
LLVM_DEBUG(llvm::dbgs() << "Run " << Run << "...\n");
SmallVector<AnnotatedLine *, 16> AnnotatedLines;
TokenAnnotator Annotator(Style, Lex.getKeywords());
- for (unsigned i = 0, e = UnwrappedLines[Run].size(); i != e; ++i) {
- AnnotatedLines.push_back(new AnnotatedLine(UnwrappedLines[Run][i]));
+ for (const UnwrappedLine &Line : Lines) {
+ AnnotatedLines.push_back(new AnnotatedLine(Line));
Annotator.annotate(*AnnotatedLines.back());
}
@@ -130,9 +131,8 @@ std::pair<tooling::Replacements, unsigned> TokenAnalyzer::process() {
for (const tooling::Replacement &Fix : RunResult.first)
llvm::dbgs() << Fix.toString() << "\n";
});
- for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
- delete AnnotatedLines[i];
- }
+ for (AnnotatedLine *Line : AnnotatedLines)
+ delete Line;
Penalty += RunResult.second;
for (const auto &R : RunResult.first) {
diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h
index ecd9dbb0f864..96e03967ff60 100644
--- a/clang/lib/Format/TokenAnnotator.h
+++ b/clang/lib/Format/TokenAnnotator.h
@@ -66,9 +66,8 @@ public:
}
~AnnotatedLine() {
- for (unsigned i = 0, e = Children.size(); i != e; ++i) {
- delete Children[i];
- }
+ for (AnnotatedLine *Child : Children)
+ delete Child;
FormatToken *Current = First;
while (Current) {
Current->Children.clear();
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 0172a224335c..01c151fec132 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -100,10 +100,27 @@ private:
if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() ||
Style.isCSharp())
return 0;
- if (RootToken.isAccessSpecifier(false) ||
- RootToken.isObjCAccessSpecifier() ||
- (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
- RootToken.Next && RootToken.Next->is(tok::colon))) {
+
+ auto IsAccessModifier = [this, &RootToken]() {
+ if (RootToken.isAccessSpecifier(Style.isCpp()))
+ return true;
+ else if (RootToken.isObjCAccessSpecifier())
+ return true;
+ // Handle Qt signals.
+ else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
+ RootToken.Next && RootToken.Next->is(tok::colon)))
+ return true;
+ else if (RootToken.Next &&
+ RootToken.Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
+ RootToken.Next->Next && RootToken.Next->Next->is(tok::colon))
+ return true;
+ // Handle malformed access specifier e.g. 'private' without trailing ':'.
+ else if (!RootToken.Next && RootToken.isAccessSpecifier(false))
+ return true;
+ return false;
+ };
+
+ if (IsAccessModifier()) {
// The AccessModifierOffset may be overridden by IndentAccessModifiers,
// in which case we take a negative value of the IndentWidth to simulate
// the upper indent level.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 35be2fa3eb62..642679128409 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -687,9 +687,9 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
} while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty());
// Assume other blocks for all unclosed opening braces.
- for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
- if (LBraceStack[i]->is(BK_Unknown))
- LBraceStack[i]->setBlockKind(BK_Block);
+ for (FormatToken *LBrace : LBraceStack) {
+ if (LBrace->is(BK_Unknown))
+ LBrace->setBlockKind(BK_Block);
}
FormatTok = Tokens->setPosition(StoredPosition);
@@ -2708,14 +2708,25 @@ void UnwrappedLineParser::parseSwitch() {
}
void UnwrappedLineParser::parseAccessSpecifier() {
+ FormatToken *AccessSpecifierCandidate = FormatTok;
nextToken();
// Understand Qt's slots.
if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
nextToken();
// Otherwise, we don't know what it is, and we'd better keep the next token.
- if (FormatTok->Tok.is(tok::colon))
+ if (FormatTok->Tok.is(tok::colon)) {
nextToken();
- addUnwrappedLine();
+ addUnwrappedLine();
+ } else if (!FormatTok->Tok.is(tok::coloncolon) &&
+ !std::binary_search(COperatorsFollowingVar.begin(),
+ COperatorsFollowingVar.end(),
+ FormatTok->Tok.getKind())) {
+ // Not a variable name nor namespace name.
+ addUnwrappedLine();
+ } else if (AccessSpecifierCandidate) {
+ // Consider the access specifier to be a C identifier.
+ AccessSpecifierCandidate->Tok.setKind(tok::identifier);
+ }
}
void UnwrappedLineParser::parseConcept() {
diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp
index 5608a5a75953..bf5307260c0b 100644
--- a/clang/lib/Format/UsingDeclarationsSorter.cpp
+++ b/clang/lib/Format/UsingDeclarationsSorter.cpp
@@ -188,10 +188,10 @@ std::pair<tooling::Replacements, unsigned> UsingDeclarationsSorter::analyze(
AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
tooling::Replacements Fixes;
SmallVector<UsingDeclaration, 4> UsingDeclarations;
- for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) {
- const auto *FirstTok = AnnotatedLines[I]->First;
- if (AnnotatedLines[I]->InPPDirective ||
- !AnnotatedLines[I]->startsWith(tok::kw_using) || FirstTok->Finalized) {
+ for (const AnnotatedLine *Line : AnnotatedLines) {
+ const auto *FirstTok = Line->First;
+ if (Line->InPPDirective || !Line->startsWith(tok::kw_using) ||
+ FirstTok->Finalized) {
endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
continue;
}
@@ -204,7 +204,7 @@ std::pair<tooling::Replacements, unsigned> UsingDeclarationsSorter::analyze(
endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
continue;
}
- UsingDeclarations.push_back(UsingDeclaration(AnnotatedLines[I], Label));
+ UsingDeclarations.push_back(UsingDeclaration(Line, Label));
}
endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
return {Fixes, 0};
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 0d2e507ac587..4c130abd83c3 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -344,6 +344,10 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
return true;
+ // Lambda.
+ if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace))
+ return false;
+
// Continued function declaration
if (ScopeStart > Start + 1 &&
Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName))
@@ -352,8 +356,13 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
// Continued function call
if (ScopeStart > Start + 1 &&
Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
- Changes[ScopeStart - 1].Tok->is(tok::l_paren))
+ Changes[ScopeStart - 1].Tok->is(tok::l_paren) &&
+ Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) {
+ if (Changes[i].Tok->MatchingParen &&
+ Changes[i].Tok->MatchingParen->is(TT_LambdaLBrace))
+ return false;
return Style.BinPackArguments;
+ }
// Ternary operator
if (Changes[i].Tok->is(TT_ConditionalExpr))
@@ -372,8 +381,15 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if (ScopeStart > Start + 1 &&
Changes[ScopeStart - 2].Tok->isNot(tok::identifier) &&
Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
- Changes[i].Tok->isNot(tok::r_brace))
+ Changes[i].Tok->isNot(tok::r_brace)) {
+ for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) {
+ // Lambda.
+ if (OuterScopeStart > Start &&
+ Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace))
+ return false;
+ }
return true;
+ }
return false;
};
@@ -1014,7 +1030,7 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
// Now go through and fixup the spaces.
auto *CellIter = Cells.begin();
- for (auto i = 0U; i < CellDescs.CellCount; i++, ++CellIter) {
+ for (auto i = 0U; i < CellDescs.CellCount; ++i, ++CellIter) {
unsigned NetWidth = 0U;
if (isSplitCell(*CellIter))
NetWidth = getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
@@ -1331,8 +1347,13 @@ void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) {
void WhitespaceManager::appendNewlineText(std::string &Text,
unsigned Newlines) {
- for (unsigned i = 0; i < Newlines; ++i)
- Text.append(UseCRLF ? "\r\n" : "\n");
+ if (UseCRLF) {
+ Text.reserve(Text.size() + 2 * Newlines);
+ for (unsigned i = 0; i < Newlines; ++i)
+ Text.append("\r\n");
+ } else {
+ Text.append(Newlines, '\n');
+ }
}
void WhitespaceManager::appendEscapedNewlineText(
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 7f1ce3da7e7e..553a0b31c0ab 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3560,6 +3560,8 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "11.0", SA);
else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver12)
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "12.0", SA);
+ else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver13)
+ GenerateArg(Args, OPT_fclang_abi_compat_EQ, "13.0", SA);
if (Opts.getSignReturnAddressScope() ==
LangOptions::SignReturnAddressScopeKind::All)
@@ -4062,6 +4064,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.setClangABICompat(LangOptions::ClangABI::Ver11);
else if (Major <= 12)
Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
+ else if (Major <= 13)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver13);
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index a9023a7a1171..e259ab47c558 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -25,6 +25,7 @@
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
using namespace clang;
static bool MacroBodyEndsInBackslash(StringRef MacroBody) {
@@ -914,6 +915,13 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__LONG_WIDTH__", Twine(TI.getLongWidth()));
Builder.defineMacro("__LLONG_WIDTH__", Twine(TI.getLongLongWidth()));
+ size_t BitIntMaxWidth = TI.getMaxBitIntWidth();
+ assert(BitIntMaxWidth <= llvm::IntegerType::MAX_INT_BITS &&
+ "Target defined a max bit width larger than LLVM can support!");
+ assert(BitIntMaxWidth >= TI.getLongLongWidth() &&
+ "Target defined a max bit width smaller than the C standard allows!");
+ Builder.defineMacro("__BITINT_MAXWIDTH__", Twine(BitIntMaxWidth));
+
DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder);
DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder);
DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder);
diff --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index 45fac248dadb..1cfc1403276d 100644
--- a/clang/lib/Headers/arm_acle.h
+++ b/clang/lib/Headers/arm_acle.h
@@ -730,6 +730,12 @@ __arm_st64bv0(void *__addr, data512_t __value) {
#define __arm_mte_ptrdiff(__ptra, __ptrb) __builtin_arm_subp(__ptra, __ptrb)
#endif
+/* Memory Operations Intrinsics */
+#if __ARM_FEATURE_MOPS && __ARM_FEATURE_MEMORY_TAGGING
+#define __arm_mops_memset_tag(__tagged_address, __value, __size) \
+ __builtin_arm_mops_memset_tag(__tagged_address, __value, __size)
+#endif
+
/* Transactional Memory Extension (TME) Intrinsics */
#if __ARM_FEATURE_TME
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index ed610b24aa10..c6a6cc08462d 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -14,10 +14,11 @@
* additional definitions provided for Windows.
* For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx
*
- * Also fall back on Darwin to allow additional definitions and
+ * Also fall back on Darwin and AIX to allow additional definitions and
* implementation-defined values.
*/
-#if (defined(__APPLE__) || (defined(__MINGW32__) || defined(_MSC_VER))) && \
+#if (defined(__APPLE__) || defined(__MINGW32__) || defined(_MSC_VER) || \
+ defined(_AIX)) && \
__STDC_HOSTED__ && __has_include_next(<float.h>)
/* Prior to Apple's 10.7 SDK, float.h SDK header used to apply an extra level
@@ -37,7 +38,9 @@
# undef FLT_MANT_DIG
# undef DBL_MANT_DIG
# undef LDBL_MANT_DIG
-# if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
+# if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || \
+ __cplusplus >= 201103L || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
# undef DECIMAL_DIG
# endif
# undef FLT_DIG
@@ -64,7 +67,9 @@
# undef FLT_MIN
# undef DBL_MIN
# undef LDBL_MIN
-# if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
+# if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || \
+ __cplusplus >= 201703L || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
# undef FLT_TRUE_MIN
# undef DBL_TRUE_MIN
# undef LDBL_TRUE_MIN
@@ -87,7 +92,9 @@
#define DBL_MANT_DIG __DBL_MANT_DIG__
#define LDBL_MANT_DIG __LDBL_MANT_DIG__
-#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
+#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || \
+ __cplusplus >= 201103L || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
# define DECIMAL_DIG __DECIMAL_DIG__
#endif
@@ -123,7 +130,9 @@
#define DBL_MIN __DBL_MIN__
#define LDBL_MIN __LDBL_MIN__
-#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
+#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || \
+ __cplusplus >= 201703L || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
# define FLT_TRUE_MIN __FLT_DENORM_MIN__
# define DBL_TRUE_MIN __DBL_DENORM_MIN__
# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
diff --git a/clang/lib/Headers/limits.h b/clang/lib/Headers/limits.h
index c2d3a7cf4353..cfd23a219ee5 100644
--- a/clang/lib/Headers/limits.h
+++ b/clang/lib/Headers/limits.h
@@ -78,6 +78,8 @@
#define LONG_WIDTH __LONG_WIDTH__
#define ULLONG_WIDTH __LLONG_WIDTH__
#define LLONG_WIDTH __LLONG_WIDTH__
+
+#define BITINT_MAXWIDTH __BITINT_MAXWIDTH__
#endif
#ifdef __CHAR_UNSIGNED__ /* -funsigned-char */
diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h
index 06b78da63e69..ad276dc0f6aa 100644
--- a/clang/lib/Headers/opencl-c-base.h
+++ b/clang/lib/Headers/opencl-c-base.h
@@ -72,6 +72,12 @@
#endif // defined(__SPIR__)
#endif // (__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300)
+#if !defined(__opencl_c_generic_address_space)
+// Internal feature macro to provide named (global, local, private) address
+// space overloads for builtin functions that take a pointer argument.
+#define __opencl_c_named_address_space_builtins 1
+#endif // !defined(__opencl_c_generic_address_space)
+
// built-in scalar data types:
/**
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index 8fde2fa29899..059a2ec2371b 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -7285,7 +7285,9 @@ half4 __ovld fract(half4 x, half4 *iptr);
half8 __ovld fract(half8 x, half8 *iptr);
half16 __ovld fract(half16 x, half16 *iptr);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld fract(float x, __global float *iptr);
float2 __ovld fract(float2 x, __global float2 *iptr);
float3 __ovld fract(float3 x, __global float3 *iptr);
@@ -7344,7 +7346,7 @@ half4 __ovld fract(half4 x, __private half4 *iptr);
half8 __ovld fract(half8 x, __private half8 *iptr);
half16 __ovld fract(half16 x, __private half16 *iptr);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Extract mantissa and exponent from x. For each
@@ -7375,7 +7377,9 @@ half4 __ovld frexp(half4 x, int4 *exp);
half8 __ovld frexp(half8 x, int8 *exp);
half16 __ovld frexp(half16 x, int16 *exp);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld frexp(float x, __global int *exp);
float2 __ovld frexp(float2 x, __global int2 *exp);
float3 __ovld frexp(float3 x, __global int3 *exp);
@@ -7434,7 +7438,7 @@ half4 __ovld frexp(half4 x, __private int4 *exp);
half8 __ovld frexp(half8 x, __private int8 *exp);
half16 __ovld frexp(half16 x, __private int16 *exp);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Compute the value of the square root of x^2 + y^2
@@ -7582,7 +7586,9 @@ half4 __ovld lgamma_r(half4 x, int4 *signp);
half8 __ovld lgamma_r(half8 x, int8 *signp);
half16 __ovld lgamma_r(half16 x, int16 *signp);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld lgamma_r(float x, __global int *signp);
float2 __ovld lgamma_r(float2 x, __global int2 *signp);
float3 __ovld lgamma_r(float3 x, __global int3 *signp);
@@ -7641,7 +7647,7 @@ half4 __ovld lgamma_r(half4 x, __private int4 *signp);
half8 __ovld lgamma_r(half8 x, __private int8 *signp);
half16 __ovld lgamma_r(half16 x, __private int16 *signp);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Compute natural logarithm.
@@ -7888,7 +7894,9 @@ half4 __ovld modf(half4 x, half4 *iptr);
half8 __ovld modf(half8 x, half8 *iptr);
half16 __ovld modf(half16 x, half16 *iptr);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld modf(float x, __global float *iptr);
float2 __ovld modf(float2 x, __global float2 *iptr);
float3 __ovld modf(float3 x, __global float3 *iptr);
@@ -7947,7 +7955,7 @@ half4 __ovld modf(half4 x, __private half4 *iptr);
half8 __ovld modf(half8 x, __private half8 *iptr);
half16 __ovld modf(half16 x, __private half16 *iptr);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Returns a quiet NaN. The nancode may be placed
@@ -8147,9 +8155,10 @@ half3 __ovld remquo(half3 x, half3 y, int3 *quo);
half4 __ovld remquo(half4 x, half4 y, int4 *quo);
half8 __ovld remquo(half8 x, half8 y, int8 *quo);
half16 __ovld remquo(half16 x, half16 y, int16 *quo);
-
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld remquo(float x, float y, __global int *quo);
float2 __ovld remquo(float2 x, float2 y, __global int2 *quo);
float3 __ovld remquo(float3 x, float3 y, __global int3 *quo);
@@ -8208,7 +8217,7 @@ half4 __ovld remquo(half4 x, half4 y, __private int4 *quo);
half8 __ovld remquo(half8 x, half8 y, __private int8 *quo);
half16 __ovld remquo(half16 x, half16 y, __private int16 *quo);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Round to integral value (using round to nearest
* even rounding mode) in floating-point format.
@@ -8372,7 +8381,9 @@ half4 __ovld sincos(half4 x, half4 *cosval);
half8 __ovld sincos(half8 x, half8 *cosval);
half16 __ovld sincos(half16 x, half16 *cosval);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld sincos(float x, __global float *cosval);
float2 __ovld sincos(float2 x, __global float2 *cosval);
float3 __ovld sincos(float3 x, __global float3 *cosval);
@@ -8431,7 +8442,7 @@ half4 __ovld sincos(half4 x, __private half4 *cosval);
half8 __ovld sincos(half8 x, __private half8 *cosval);
half16 __ovld sincos(half16 x, __private half16 *cosval);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Compute hyperbolic sine.
@@ -11315,7 +11326,9 @@ half4 __ovld __purefn vload4(size_t offset, const half *p);
half8 __ovld __purefn vload8(size_t offset, const half *p);
half16 __ovld __purefn vload16(size_t offset, const half *p);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
char2 __ovld __purefn vload2(size_t offset, const __global char *p);
uchar2 __ovld __purefn vload2(size_t offset, const __global uchar *p);
short2 __ovld __purefn vload2(size_t offset, const __global short *p);
@@ -11490,7 +11503,7 @@ half4 __ovld __purefn vload4(size_t offset, const __private half *p);
half8 __ovld __purefn vload8(size_t offset, const __private half *p);
half16 __ovld __purefn vload16(size_t offset, const __private half *p);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
#if defined(__opencl_c_generic_address_space)
void __ovld vstore2(char2 data, size_t offset, char *p);
@@ -11553,7 +11566,9 @@ void __ovld vstore4(half4 data, size_t offset, half *p);
void __ovld vstore8(half8 data, size_t offset, half *p);
void __ovld vstore16(half16 data, size_t offset, half *p);
#endif //cl_khr_fp16
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
void __ovld vstore2(char2 data, size_t offset, __global char *p);
void __ovld vstore2(uchar2 data, size_t offset, __global uchar *p);
void __ovld vstore2(short2 data, size_t offset, __global short *p);
@@ -11726,7 +11741,7 @@ void __ovld vstore4(half4 data, size_t offset, __private half *p);
void __ovld vstore8(half8 data, size_t offset, __private half *p);
void __ovld vstore16(half16 data, size_t offset, __private half *p);
#endif //cl_khr_fp16
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Read sizeof (half) bytes of data from address
@@ -11739,11 +11754,13 @@ void __ovld vstore16(half16 data, size_t offset, __private half *p);
float __ovld __purefn vload_half(size_t offset, const __constant half *p);
#if defined(__opencl_c_generic_address_space)
float __ovld __purefn vload_half(size_t offset, const half *p);
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float __ovld __purefn vload_half(size_t offset, const __global half *p);
float __ovld __purefn vload_half(size_t offset, const __local half *p);
float __ovld __purefn vload_half(size_t offset, const __private half *p);
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* Read sizeof (halfn) bytes of data from address
@@ -11764,7 +11781,9 @@ float3 __ovld __purefn vload_half3(size_t offset, const half *p);
float4 __ovld __purefn vload_half4(size_t offset, const half *p);
float8 __ovld __purefn vload_half8(size_t offset, const half *p);
float16 __ovld __purefn vload_half16(size_t offset, const half *p);
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float2 __ovld __purefn vload_half2(size_t offset, const __global half *p);
float3 __ovld __purefn vload_half3(size_t offset, const __global half *p);
float4 __ovld __purefn vload_half4(size_t offset, const __global half *p);
@@ -11780,7 +11799,7 @@ float3 __ovld __purefn vload_half3(size_t offset, const __private half *p);
float4 __ovld __purefn vload_half4(size_t offset, const __private half *p);
float8 __ovld __purefn vload_half8(size_t offset, const __private half *p);
float16 __ovld __purefn vload_half16(size_t offset, const __private half *p);
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* The float value given by data is first
@@ -11806,7 +11825,9 @@ void __ovld vstore_half_rtz(double data, size_t offset, half *p);
void __ovld vstore_half_rtp(double data, size_t offset, half *p);
void __ovld vstore_half_rtn(double data, size_t offset, half *p);
#endif //cl_khr_fp64
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
void __ovld vstore_half(float data, size_t offset, __global half *p);
void __ovld vstore_half_rte(float data, size_t offset, __global half *p);
void __ovld vstore_half_rtz(float data, size_t offset, __global half *p);
@@ -11839,7 +11860,7 @@ void __ovld vstore_half_rtz(double data, size_t offset, __private half *p);
void __ovld vstore_half_rtp(double data, size_t offset, __private half *p);
void __ovld vstore_half_rtn(double data, size_t offset, __private half *p);
#endif //cl_khr_fp64
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* The floatn value given by data is converted to
@@ -11905,7 +11926,9 @@ void __ovld vstore_half4_rtn(double4 data, size_t offset, half *p);
void __ovld vstore_half8_rtn(double8 data, size_t offset, half *p);
void __ovld vstore_half16_rtn(double16 data, size_t offset, half *p);
#endif //cl_khr_fp64
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
void __ovld vstore_half2(float2 data, size_t offset, __global half *p);
void __ovld vstore_half3(float3 data, size_t offset, __global half *p);
void __ovld vstore_half4(float4 data, size_t offset, __global half *p);
@@ -12058,7 +12081,7 @@ void __ovld vstore_half4_rtn(double4 data, size_t offset, __private half *p);
void __ovld vstore_half8_rtn(double8 data, size_t offset, __private half *p);
void __ovld vstore_half16_rtn(double16 data, size_t offset, __private half *p);
#endif //cl_khr_fp64
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* For n = 1, 2, 4, 8 and 16 read sizeof (halfn)
@@ -12084,7 +12107,9 @@ float3 __ovld __purefn vloada_half3(size_t offset, const half *p);
float4 __ovld __purefn vloada_half4(size_t offset, const half *p);
float8 __ovld __purefn vloada_half8(size_t offset, const half *p);
float16 __ovld __purefn vloada_half16(size_t offset, const half *p);
-#else
+#endif //defined(__opencl_c_generic_address_space)
+
+#if defined(__opencl_c_named_address_space_builtins)
float2 __ovld __purefn vloada_half2(size_t offset, const __global half *p);
float3 __ovld __purefn vloada_half3(size_t offset, const __global half *p);
float4 __ovld __purefn vloada_half4(size_t offset, const __global half *p);
@@ -12100,7 +12125,7 @@ float3 __ovld __purefn vloada_half3(size_t offset, const __private half *p);
float4 __ovld __purefn vloada_half4(size_t offset, const __private half *p);
float8 __ovld __purefn vloada_half8(size_t offset, const __private half *p);
float16 __ovld __purefn vloada_half16(size_t offset, const __private half *p);
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
/**
* The floatn value given by data is converted to
@@ -12180,8 +12205,9 @@ void __ovld vstorea_half4_rtn(double4 data, size_t offset, half *p);
void __ovld vstorea_half8_rtn(double8 data, size_t offset, half *p);
void __ovld vstorea_half16_rtn(double16 data, size_t offset, half *p);
#endif //cl_khr_fp64
+#endif //defined(__opencl_c_generic_address_space)
-#else
+#if defined(__opencl_c_named_address_space_builtins)
void __ovld vstorea_half2(float2 data, size_t offset, __global half *p);
void __ovld vstorea_half3(float3 data, size_t offset, __global half *p);
void __ovld vstorea_half4(float4 data, size_t offset, __global half *p);
@@ -12363,7 +12389,7 @@ void __ovld vstorea_half4_rtn(double4 data,size_t offset, __private half *p);
void __ovld vstorea_half8_rtn(double8 data,size_t offset, __private half *p);
void __ovld vstorea_half16_rtn(double16 data,size_t offset, __private half *p);
#endif //cl_khr_fp64
-#endif //defined(__opencl_c_generic_address_space)
+#endif //defined(__opencl_c_named_address_space_builtins)
// OpenCL v1.1 s6.11.8, v1.2 s6.12.8, v2.0 s6.13.8 - Synchronization Functions
@@ -18513,6 +18539,8 @@ int __ovld arm_dot_acc_sat(char4 a, char4 b, int c);
// Disable any extensions we may have enabled previously.
#pragma OPENCL EXTENSION all : disable
+#undef __opencl_c_named_address_space_builtins
+
#undef __cnfn
#undef __ovld
#endif //_OPENCL_H_
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 89e89c7c1f17..a180bba365cf 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2378,8 +2378,9 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr,
bool &TokAtPhysicalStartOfLine) {
// If Line comments aren't explicitly enabled for this language, emit an
// extension warning.
- if (!LangOpts.LineComment && !isLexingRawMode()) {
- Diag(BufferPtr, diag::ext_line_comment);
+ if (!LangOpts.LineComment) {
+ if (!isLexingRawMode()) // There's no PP in raw mode, so can't emit diags.
+ Diag(BufferPtr, diag::ext_line_comment);
// Mark them enabled so we only emit one warning for this translation
// unit.
diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td
index df2f206041c1..cd704ba2df13 100644
--- a/clang/lib/Sema/OpenCLBuiltins.td
+++ b/clang/lib/Sema/OpenCLBuiltins.td
@@ -85,6 +85,8 @@ def FuncExtKhrMipmapImageWrites : FunctionExtension<"cl_khr_mipmap_imag
def FuncExtKhrGlMsaaSharing : FunctionExtension<"cl_khr_gl_msaa_sharing">;
def FuncExtKhrGlMsaaSharingReadWrite : FunctionExtension<"cl_khr_gl_msaa_sharing __opencl_c_read_write_images">;
+def FuncExtOpenCLCGenericAddressSpace : FunctionExtension<"__opencl_c_generic_address_space">;
+def FuncExtOpenCLCNamedAddressSpaceBuiltins : FunctionExtension<"__opencl_c_named_address_space_builtins">;
def FuncExtOpenCLCPipes : FunctionExtension<"__opencl_c_pipes">;
def FuncExtOpenCLCWGCollectiveFunctions : FunctionExtension<"__opencl_c_work_group_collective_functions">;
def FuncExtOpenCLCReadWriteImages : FunctionExtension<"__opencl_c_read_write_images">;
@@ -591,10 +593,10 @@ multiclass MathWithPointer<list<AddressSpace> addrspaces> {
}
}
-let MaxVersion = CL20 in {
+let Extension = FuncExtOpenCLCNamedAddressSpaceBuiltins in {
defm : MathWithPointer<[GlobalAS, LocalAS, PrivateAS]>;
}
-let MinVersion = CL20 in {
+let Extension = FuncExtOpenCLCGenericAddressSpace in {
defm : MathWithPointer<[GenericAS]>;
}
@@ -840,10 +842,10 @@ multiclass VloadVstore<list<AddressSpace> addrspaces, bit defStores> {
}
}
-let MaxVersion = CL20 in {
+let Extension = FuncExtOpenCLCNamedAddressSpaceBuiltins in {
defm : VloadVstore<[GlobalAS, LocalAS, PrivateAS], 1>;
}
-let MinVersion = CL20 in {
+let Extension = FuncExtOpenCLCGenericAddressSpace in {
defm : VloadVstore<[GenericAS], 1>;
}
// vload with constant address space is available regardless of version.
@@ -874,10 +876,10 @@ multiclass VloadVstoreHalf<list<AddressSpace> addrspaces, bit defStores> {
}
}
-let MaxVersion = CL20 in {
+let Extension = FuncExtOpenCLCNamedAddressSpaceBuiltins in {
defm : VloadVstoreHalf<[GlobalAS, LocalAS, PrivateAS], 1>;
}
-let MinVersion = CL20 in {
+let Extension = FuncExtOpenCLCGenericAddressSpace in {
defm : VloadVstoreHalf<[GenericAS], 1>;
}
// vload_half and vloada_half with constant address space are available regardless of version.
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 20b4a9a5d4e6..7b57c8da4e9c 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2554,39 +2554,38 @@ static bool IsCPUDispatchCPUSpecificMultiVersion(const Expr *E) {
bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
bool ForceComplain,
bool (*IsPlausibleResult)(QualType)) {
- if (isSFINAEContext()) {
- // If this is a SFINAE context, don't try anything that might trigger ADL
- // prematurely.
- return false;
- }
SourceLocation Loc = E.get()->getExprLoc();
SourceRange Range = E.get()->getSourceRange();
-
- QualType ZeroArgCallTy;
UnresolvedSet<4> Overloads;
- if (tryExprAsCall(*E.get(), ZeroArgCallTy, Overloads) &&
- !ZeroArgCallTy.isNull() &&
- (!IsPlausibleResult || IsPlausibleResult(ZeroArgCallTy))) {
- // At this point, we know E is potentially callable with 0
- // arguments and that it returns something of a reasonable type,
- // so we can emit a fixit and carry on pretending that E was
- // actually a CallExpr.
- SourceLocation ParenInsertionLoc = getLocForEndOfToken(Range.getEnd());
- bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get());
- Diag(Loc, PD) << /*zero-arg*/ 1 << IsMV << Range
- << (IsCallableWithAppend(E.get())
- ? FixItHint::CreateInsertion(ParenInsertionLoc, "()")
- : FixItHint());
- if (!IsMV)
- notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult);
- // FIXME: Try this before emitting the fixit, and suppress diagnostics
- // while doing so.
- E = BuildCallExpr(nullptr, E.get(), Range.getEnd(), None,
- Range.getEnd().getLocWithOffset(1));
- return true;
- }
+ // If this is a SFINAE context, don't try anything that might trigger ADL
+ // prematurely.
+ if (!isSFINAEContext()) {
+ QualType ZeroArgCallTy;
+ if (tryExprAsCall(*E.get(), ZeroArgCallTy, Overloads) &&
+ !ZeroArgCallTy.isNull() &&
+ (!IsPlausibleResult || IsPlausibleResult(ZeroArgCallTy))) {
+ // At this point, we know E is potentially callable with 0
+ // arguments and that it returns something of a reasonable type,
+ // so we can emit a fixit and carry on pretending that E was
+ // actually a CallExpr.
+ SourceLocation ParenInsertionLoc = getLocForEndOfToken(Range.getEnd());
+ bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get());
+ Diag(Loc, PD) << /*zero-arg*/ 1 << IsMV << Range
+ << (IsCallableWithAppend(E.get())
+ ? FixItHint::CreateInsertion(ParenInsertionLoc,
+ "()")
+ : FixItHint());
+ if (!IsMV)
+ notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult);
+ // FIXME: Try this before emitting the fixit, and suppress diagnostics
+ // while doing so.
+ E = BuildCallExpr(nullptr, E.get(), Range.getEnd(), None,
+ Range.getEnd().getLocWithOffset(1));
+ return true;
+ }
+ }
if (!ForceComplain) return false;
bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get());
diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp
index 59601c5ce79d..efa38554bc83 100644
--- a/clang/lib/Sema/SemaCUDA.cpp
+++ b/clang/lib/Sema/SemaCUDA.cpp
@@ -590,6 +590,8 @@ bool HasAllowedCUDADeviceStaticInitializer(Sema &S, VarDecl *VD,
};
auto IsConstantInit = [&](const Expr *Init) {
assert(Init);
+ ASTContext::CUDAConstantEvalContextRAII EvalCtx(S.Context,
+ /*NoWronSidedVars=*/true);
return Init->isConstantInitializer(S.Context,
VD->getType()->isReferenceType());
};
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c8fb36b8311a..dfbf4cdc89cb 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3987,7 +3987,7 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI,
}
if (!HasFeature) {
- std::string FeatureStrs = "";
+ std::string FeatureStrs;
for (StringRef OF : ReqOpFeatures) {
// If the feature is 64bit, alter the string so it will print better in
// the diagnostic.
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index e7e60b7e7daf..cd3ae62ebbe2 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -810,7 +810,7 @@ ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
checkSuspensionContext(*this, Loc, "co_await");
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult R = CheckPlaceholderExpr(E);
if (R.isInvalid()) return ExprError();
E = R.get();
@@ -828,7 +828,7 @@ ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *E,
if (!FSI)
return ExprError();
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult R = CheckPlaceholderExpr(E);
if (R.isInvalid())
return ExprError();
@@ -866,7 +866,7 @@ ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *E,
if (!Coroutine)
return ExprError();
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult R = CheckPlaceholderExpr(E);
if (R.isInvalid()) return ExprError();
E = R.get();
@@ -927,7 +927,7 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
if (!Coroutine)
return ExprError();
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult R = CheckPlaceholderExpr(E);
if (R.isInvalid()) return ExprError();
E = R.get();
@@ -970,8 +970,8 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
if (!FSI)
return StmtError();
- if (E && E->getType()->isPlaceholderType() &&
- !E->getType()->isSpecificPlaceholderType(BuiltinType::Overload)) {
+ if (E && E->hasPlaceholderType() &&
+ !E->hasPlaceholderType(BuiltinType::Overload)) {
ExprResult R = CheckPlaceholderExpr(E);
if (R.isInvalid()) return StmtError();
E = R.get();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3252671991b7..cbd9df4d6a7b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5703,6 +5703,13 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
return false;
}
+/// Returns true if the declaration is declared in a system header or from a
+/// system macro.
+static bool isFromSystemHeader(SourceManager &SM, const Decl *D) {
+ return SM.isInSystemHeader(D->getLocation()) ||
+ SM.isInSystemMacro(D->getLocation());
+}
+
void Sema::warnOnReservedIdentifier(const NamedDecl *D) {
// Avoid warning twice on the same identifier, and don't warn on redeclaration
// of system decl.
@@ -5710,9 +5717,10 @@ void Sema::warnOnReservedIdentifier(const NamedDecl *D) {
return;
ReservedIdentifierStatus Status = D->isReserved(getLangOpts());
if (Status != ReservedIdentifierStatus::NotReserved &&
- !Context.getSourceManager().isInSystemHeader(D->getLocation()))
+ !isFromSystemHeader(Context.getSourceManager(), D)) {
Diag(D->getLocation(), diag::warn_reserved_extern_symbol)
<< D << static_cast<int>(Status);
+ }
}
Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
@@ -14188,6 +14196,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
if (!FD->isGlobal())
return false;
+ if (!FD->isExternallyVisible())
+ return false;
+
// Don't warn about C++ member functions.
if (isa<CXXMethodDecl>(FD))
return false;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index f04236ab96c3..e76e7c608e0c 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3393,7 +3393,8 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
if (ParsedAttrs.BranchProtection.empty())
return false;
if (!Context.getTargetInfo().validateBranchProtection(
- ParsedAttrs.BranchProtection, BPI, DiagMsg)) {
+ ParsedAttrs.BranchProtection, ParsedAttrs.Architecture, BPI,
+ DiagMsg)) {
if (DiagMsg.empty())
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << "branch-protection" << Target;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7de43705c2b1..85553eccde83 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -497,7 +497,7 @@ SourceRange Sema::getExprRange(Expr *E) const {
/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
// Handle any placeholder expressions which made it here.
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
E = result.get();
@@ -621,7 +621,7 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
ExprResult Sema::DefaultLvalueConversion(Expr *E) {
// Handle any placeholder expressions which made it here.
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
E = result.get();
@@ -4685,7 +4685,7 @@ ExprResult
Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc,
Expr *idx, SourceLocation rbLoc) {
if (base && !base->getType().isNull() &&
- base->getType()->isSpecificPlaceholderType(BuiltinType::OMPArraySection))
+ base->hasPlaceholderType(BuiltinType::OMPArraySection))
return ActOnOMPArraySectionExpr(base, lbLoc, idx, SourceLocation(),
SourceLocation(), /*Length*/ nullptr,
/*Stride=*/nullptr, rbLoc);
@@ -4711,8 +4711,7 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc,
};
// The matrix subscript operator ([][])is considered a single operator.
// Separating the index expressions by parenthesis is not allowed.
- if (base->getType()->isSpecificPlaceholderType(
- BuiltinType::IncompleteMatrixIdx) &&
+ if (base->hasPlaceholderType(BuiltinType::IncompleteMatrixIdx) &&
!isa<MatrixSubscriptExpr>(base)) {
Diag(base->getExprLoc(), diag::err_matrix_separate_incomplete_index)
<< SourceRange(base->getBeginLoc(), rbLoc);
@@ -4944,9 +4943,8 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
SourceLocation ColonLocSecond,
Expr *Length, Expr *Stride,
SourceLocation RBLoc) {
- if (Base->getType()->isPlaceholderType() &&
- !Base->getType()->isSpecificPlaceholderType(
- BuiltinType::OMPArraySection)) {
+ if (Base->hasPlaceholderType() &&
+ !Base->hasPlaceholderType(BuiltinType::OMPArraySection)) {
ExprResult Result = CheckPlaceholderExpr(Base);
if (Result.isInvalid())
return ExprError();
@@ -5114,8 +5112,7 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
}
}
- if (!Base->getType()->isSpecificPlaceholderType(
- BuiltinType::OMPArraySection)) {
+ if (!Base->hasPlaceholderType(BuiltinType::OMPArraySection)) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(Base);
if (Result.isInvalid())
return ExprError();
@@ -5130,7 +5127,7 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
SourceLocation RParenLoc,
ArrayRef<Expr *> Dims,
ArrayRef<SourceRange> Brackets) {
- if (Base->getType()->isPlaceholderType()) {
+ if (Base->hasPlaceholderType()) {
ExprResult Result = CheckPlaceholderExpr(Base);
if (Result.isInvalid())
return ExprError();
@@ -5155,7 +5152,7 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
SmallVector<Expr *, 4> NewDims;
bool ErrorFound = false;
for (Expr *Dim : Dims) {
- if (Dim->getType()->isPlaceholderType()) {
+ if (Dim->hasPlaceholderType()) {
ExprResult Result = CheckPlaceholderExpr(Dim);
if (Result.isInvalid()) {
ErrorFound = true;
@@ -13653,7 +13650,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
if (OrigOp.get()->isTypeDependent())
return Context.DependentTy;
- assert(!OrigOp.get()->getType()->isPlaceholderType());
+ assert(!OrigOp.get()->hasPlaceholderType());
// Make sure to ignore parentheses in subsequent checks
Expr *op = OrigOp.get()->IgnoreParens();
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index b34b744d7312..7ce125f5ef82 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -564,7 +564,7 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation RParenLoc) {
bool WasEvaluated = false;
if (E && !E->isTypeDependent()) {
- if (E->getType()->isPlaceholderType()) {
+ if (E->hasPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
E = result.get();
@@ -5704,7 +5704,7 @@ ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET,
SourceLocation RParen) {
if (Queried->isTypeDependent()) {
// Delay type-checking for type-dependent expressions.
- } else if (Queried->getType()->isPlaceholderType()) {
+ } else if (Queried->hasPlaceholderType()) {
ExprResult PE = CheckPlaceholderExpr(Queried);
if (PE.isInvalid()) return ExprError();
return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
@@ -5720,8 +5720,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
ExprValueKind &VK,
SourceLocation Loc,
bool isIndirect) {
- assert(!LHS.get()->getType()->isPlaceholderType() &&
- !RHS.get()->getType()->isPlaceholderType() &&
+ assert(!LHS.get()->hasPlaceholderType() && !RHS.get()->hasPlaceholderType() &&
"placeholders should have been weeded out by now");
// The LHS undergoes lvalue conversions if this is ->*, and undergoes the
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ae91a6470471..a500ad4f0220 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5327,6 +5327,8 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
IntegerLiteral *Zero = IntegerLiteral::Create(
Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
+ IntegerLiteral *One = IntegerLiteral::Create(
+ Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
Expr *Dist;
if (Rel == BO_NE) {
// When using a != comparison, the increment can be +1 or -1. This can be
@@ -5381,18 +5383,25 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
if (Rel == BO_LE || Rel == BO_GE) {
// Add one to the range if the relational operator is inclusive.
- Range = AssertSuccess(Actions.BuildBinOp(
- nullptr, {}, BO_Add, Range,
- Actions.ActOnIntegerConstant(SourceLocation(), 1).get()));
+ Range =
+ AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
}
- // Divide by the absolute step amount.
+ // Divide by the absolute step amount. If the range is not a multiple of
+ // the step size, rounding-up the effective upper bound ensures that the
+ // last iteration is included.
+ // Note that the rounding-up may cause an overflow in a temporry that
+ // could be avoided, but would have occured in a C-style for-loop as well.
Expr *Divisor = BuildVarRef(NewStep);
if (Rel == BO_GE || Rel == BO_GT)
Divisor =
AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
+ Expr *DivisorMinusOne =
+ AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
+ Expr *RangeRoundUp = AssertSuccess(
+ Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
Dist = AssertSuccess(
- Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
+ Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
// If there is not at least one iteration, the range contains garbage. Fix
// to zero in this case.
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 483247aaa7c5..3fa192cedfa3 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -14320,7 +14320,8 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
FoundDecl = MemExpr->getFoundDecl();
Qualifier = MemExpr->getQualifier();
UnbridgedCasts.restore();
- } else if (auto *UnresExpr = dyn_cast<UnresolvedMemberExpr>(NakedMemExpr)) {
+ } else {
+ UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr);
Qualifier = UnresExpr->getQualifier();
QualType ObjectType = UnresExpr->getBaseType();
@@ -14433,9 +14434,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
}
MemExpr = cast<MemberExpr>(MemExprE->IgnoreParens());
- } else
- // Unimaged NakedMemExpr type.
- return ExprError();
+ }
QualType ResultType = Method->getReturnType();
ExprValueKind VK = Expr::getValueKindForType(ResultType);
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 7c6bb4c8a5f8..6de486be8f16 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1943,6 +1943,9 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
if (ExprInst.isInvalid())
return nullptr;
ExprResult TransExprRes = TransformExpr(E);
+ if (!TransExprRes.isInvalid() && !Trap.hasErrorOccurred() &&
+ TransExprRes.get()->hasPlaceholderType())
+ TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
TransExpr = createSubstDiag(SemaRef, Info, [&](llvm::raw_ostream &OS) {
E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 959f4903b030..ab47e9f03eaf 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2257,7 +2257,7 @@ QualType Sema::BuildBitIntType(bool IsUnsigned, Expr *BitWidth,
if (ICE.isInvalid())
return QualType();
- int64_t NumBits = Bits.getSExtValue();
+ size_t NumBits = Bits.getZExtValue();
if (!IsUnsigned && NumBits < 2) {
Diag(Loc, diag::err_bit_int_bad_size) << 0;
return QualType();
@@ -2268,9 +2268,10 @@ QualType Sema::BuildBitIntType(bool IsUnsigned, Expr *BitWidth,
return QualType();
}
- if (NumBits > llvm::IntegerType::MAX_INT_BITS) {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ if (NumBits > TI.getMaxBitIntWidth()) {
Diag(Loc, diag::err_bit_int_max_size)
- << IsUnsigned << llvm::IntegerType::MAX_INT_BITS;
+ << IsUnsigned << static_cast<uint64_t>(TI.getMaxBitIntWidth());
return QualType();
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index e43b3ca968eb..5c37fcaaea13 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12494,6 +12494,8 @@ TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req)
TransExpr = Req->getExprSubstitutionDiagnostic();
else {
ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
+ if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
+ TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
if (TransExprRes.isInvalid())
return nullptr;
TransExpr = TransExprRes.get();