aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp20
-rw-r--r--clang/lib/AST/Expr.cpp7
-rw-r--r--clang/lib/Basic/LangOptions.cpp8
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp23
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp18
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp38
-rw-r--r--clang/lib/Driver/ToolChains/Hexagon.cpp32
-rw-r--r--clang/lib/Driver/ToolChains/MinGW.cpp7
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp18
-rw-r--r--clang/lib/Headers/intrin.h3
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp11
-rw-r--r--clang/lib/Sema/SemaConcept.cpp17
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp9
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp19
16 files changed, 146 insertions, 91 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index e102a3ba508d..fdba204fbe7f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6066,9 +6066,11 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
NNS->getAsNamespaceAlias()->getNamespace()
->getOriginalNamespace());
+ // The difference between TypeSpec and TypeSpecWithTemplate is that the
+ // latter will have the 'template' keyword when printed.
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
- QualType T = getCanonicalType(QualType(NNS->getAsType(), 0));
+ const Type *T = getCanonicalType(NNS->getAsType());
// If we have some kind of dependent-named type (e.g., "typename T::type"),
// break it apart into its prefix and identifier, then reconsititute those
@@ -6078,14 +6080,16 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
// typedef typename T::type T1;
// typedef typename T1::type T2;
if (const auto *DNT = T->getAs<DependentNameType>())
- return NestedNameSpecifier::Create(*this, DNT->getQualifier(),
- const_cast<IdentifierInfo *>(DNT->getIdentifier()));
-
- // Otherwise, just canonicalize the type, and force it to be a TypeSpec.
- // FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the
- // first place?
+ return NestedNameSpecifier::Create(
+ *this, DNT->getQualifier(),
+ const_cast<IdentifierInfo *>(DNT->getIdentifier()));
+ if (const auto *DTST = T->getAs<DependentTemplateSpecializationType>())
+ return NestedNameSpecifier::Create(*this, DTST->getQualifier(), true,
+ const_cast<Type *>(T));
+
+ // TODO: Set 'Template' parameter to true for other template types.
return NestedNameSpecifier::Create(*this, nullptr, false,
- const_cast<Type *>(T.getTypePtr()));
+ const_cast<Type *>(T));
}
case NestedNameSpecifier::Global:
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index e8b4aaa2b81e..11f10d4695fc 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2233,8 +2233,11 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
};
switch (getIdentKind()) {
- case SourceLocExpr::File:
- return MakeStringLiteral(PLoc.getFilename());
+ case SourceLocExpr::File: {
+ SmallString<256> Path(PLoc.getFilename());
+ Ctx.getLangOpts().remapPathPrefix(Path);
+ return MakeStringLiteral(Path);
+ }
case SourceLocExpr::Function: {
const Decl *CurDecl = dyn_cast_or_null<Decl>(Context);
return MakeStringLiteral(
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index dc392d5352aa..bebf3178426f 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -11,6 +11,8 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Path.h"
using namespace clang;
@@ -48,6 +50,12 @@ VersionTuple LangOptions::getOpenCLVersionTuple() const {
return VersionTuple(Ver / 100, (Ver % 100) / 10);
}
+void LangOptions::remapPathPrefix(SmallString<256> &Path) const {
+ for (const auto &Entry : MacroPrefixMap)
+ if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second))
+ break;
+}
+
FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
FPOptions result(LO);
return result;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d9b2a5fe16be..1a02965b223e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -9732,6 +9732,29 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F);
}
+ if (BuiltinID == AArch64::BI__mulh || BuiltinID == AArch64::BI__umulh) {
+ llvm::Type *ResType = ConvertType(E->getType());
+ llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
+
+ bool IsSigned = BuiltinID == AArch64::BI__mulh;
+ Value *LHS =
+ Builder.CreateIntCast(EmitScalarExpr(E->getArg(0)), Int128Ty, IsSigned);
+ Value *RHS =
+ Builder.CreateIntCast(EmitScalarExpr(E->getArg(1)), Int128Ty, IsSigned);
+
+ Value *MulResult, *HigherBits;
+ if (IsSigned) {
+ MulResult = Builder.CreateNSWMul(LHS, RHS);
+ HigherBits = Builder.CreateAShr(MulResult, 64);
+ } else {
+ MulResult = Builder.CreateNUWMul(LHS, RHS);
+ HigherBits = Builder.CreateLShr(MulResult, 64);
+ }
+ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
+
+ return HigherBits;
+ }
+
// Handle MSVC intrinsics before argument evaluation to prevent double
// evaluation.
if (Optional<MSVCIntrin> MsvcIntId = translateAarch64ToMsvcIntrin(BuiltinID))
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index d43fb99550a8..553fedebfe56 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -555,7 +555,8 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
PrioritizedCXXGlobalInits.size());
PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
} else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
- getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR) {
+ getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR ||
+ D->hasAttr<SelectAnyAttr>()) {
// C++ [basic.start.init]p2:
// Definitions of explicitly specialized class template static data
// members have ordered initialization. Other class template static data
@@ -568,17 +569,18 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
// group with the global being initialized. On most platforms, this is a
// minor startup time optimization. In the MS C++ ABI, there are no guard
// variables, so this COMDAT key is required for correctness.
- AddGlobalCtor(Fn, 65535, COMDATKey);
- if (getTarget().getCXXABI().isMicrosoft() && COMDATKey) {
- // In The MS C++, MS add template static data member in the linker
- // drective.
- addUsedGlobal(COMDATKey);
- }
- } else if (D->hasAttr<SelectAnyAttr>()) {
+ //
// SelectAny globals will be comdat-folded. Put the initializer into a
// COMDAT group associated with the global, so the initializers get folded
// too.
+
AddGlobalCtor(Fn, 65535, COMDATKey);
+ if (COMDATKey && (getTriple().isOSBinFormatELF() ||
+ getTarget().getCXXABI().isMicrosoft())) {
+ // When COMDAT is used on ELF or in the MS C++ ABI, the key must be in
+ // llvm.used to prevent linker GC.
+ addUsedGlobal(COMDATKey);
+ }
} else {
I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash.
if (I == DelayedCXXInitPosition.end()) {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 9b40b88ea3c9..49a1396b58e3 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -186,7 +186,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
!getModule().getSourceFileName().empty()) {
std::string Path = getModule().getSourceFileName();
// Check if a path substitution is needed from the MacroPrefixMap.
- for (const auto &Entry : PPO.MacroPrefixMap)
+ for (const auto &Entry : LangOpts.MacroPrefixMap)
if (Path.rfind(Entry.first, 0) != std::string::npos) {
Path = Entry.second + Path.substr(Entry.first.size());
break;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1870bd81789c..4c8ba8cdcd29 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2637,7 +2637,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
llvm::DenormalMode DenormalFPMath = DefaultDenormalFPMath;
llvm::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math;
- StringRef FPContract = "on";
+ StringRef FPContract = "";
bool StrictFPModel = false;
@@ -2662,7 +2662,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
ReciprocalMath = false;
SignedZeros = true;
// -fno_fast_math restores default denormal and fpcontract handling
- FPContract = "on";
+ FPContract = "";
DenormalFPMath = llvm::DenormalMode::getIEEE();
// FIXME: The target may have picked a non-IEEE default mode here based on
@@ -2682,18 +2682,20 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
// ffp-model= is a Driver option, it is entirely rewritten into more
// granular options before being passed into cc1.
// Use the gcc option in the switch below.
- if (!FPModel.empty() && !FPModel.equals(Val))
+ if (!FPModel.empty() && !FPModel.equals(Val)) {
D.Diag(clang::diag::warn_drv_overriding_flag_option)
<< Args.MakeArgString("-ffp-model=" + FPModel)
<< Args.MakeArgString("-ffp-model=" + Val);
+ FPContract = "";
+ }
if (Val.equals("fast")) {
optID = options::OPT_ffast_math;
FPModel = Val;
- FPContract = Val;
+ FPContract = "fast";
} else if (Val.equals("precise")) {
optID = options::OPT_ffp_contract;
FPModel = Val;
- FPContract = "on";
+ FPContract = "fast";
PreciseFPModel = true;
} else if (Val.equals("strict")) {
StrictFPModel = true;
@@ -2779,11 +2781,9 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
case options::OPT_ffp_contract: {
StringRef Val = A->getValue();
if (PreciseFPModel) {
- // When -ffp-model=precise is seen on the command line,
- // the boolean PreciseFPModel is set to true which indicates
- // "the current option is actually PreciseFPModel". The optID
- // is changed to OPT_ffp_contract and FPContract is set to "on".
- // the argument Val string is "precise": it shouldn't be checked.
+ // -ffp-model=precise enables ffp-contract=fast as a side effect
+ // the FPContract value has already been set to a string literal
+ // and the Val string isn't a pertinent value.
;
} else if (Val.equals("fast") || Val.equals("on") || Val.equals("off"))
FPContract = Val;
@@ -2881,17 +2881,18 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
// -fno_fast_math restores default denormal and fpcontract handling
DenormalFPMath = DefaultDenormalFPMath;
DenormalFP32Math = llvm::DenormalMode::getIEEE();
- FPContract = "on";
+ FPContract = "";
break;
}
if (StrictFPModel) {
// If -ffp-model=strict has been specified on command line but
// subsequent options conflict then emit warning diagnostic.
- if (HonorINFs && HonorNaNs && !AssociativeMath && !ReciprocalMath &&
- SignedZeros && TrappingMath && RoundingFPMath &&
- DenormalFPMath == llvm::DenormalMode::getIEEE() &&
- DenormalFP32Math == llvm::DenormalMode::getIEEE() &&
- FPContract.equals("off"))
+ if (HonorINFs && HonorNaNs &&
+ !AssociativeMath && !ReciprocalMath &&
+ SignedZeros && TrappingMath && RoundingFPMath &&
+ (FPContract.equals("off") || FPContract.empty()) &&
+ DenormalFPMath == llvm::DenormalMode::getIEEE() &&
+ DenormalFP32Math == llvm::DenormalMode::getIEEE())
// OK: Current Arg doesn't conflict with -ffp-model=strict
;
else {
@@ -7690,8 +7691,11 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
assert(CurTC == nullptr && "Expected one dependence!");
CurTC = TC;
});
+ UB += C.addTempFile(
+ C.getArgs().MakeArgString(CurTC->getInputFilename(Inputs[I])));
+ } else {
+ UB += CurTC->getInputFilename(Inputs[I]);
}
- UB += CurTC->getInputFilename(Inputs[I]);
}
CmdArgs.push_back(TCArgs.MakeArgString(UB));
diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index 828bfdbb05a3..314d0efce441 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -588,21 +588,43 @@ void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs,
void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- if (DriverArgs.hasArg(options::OPT_nostdinc) ||
- DriverArgs.hasArg(options::OPT_nostdlibinc))
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
return;
+ const bool IsELF = !getTriple().isMusl() && !getTriple().isOSLinux();
+ const bool IsLinuxMusl = getTriple().isMusl() && getTriple().isOSLinux();
+
const Driver &D = getDriver();
- if (!D.SysRoot.empty()) {
+ SmallString<128> ResourceDirInclude(D.ResourceDir);
+ if (!IsELF) {
+ llvm::sys::path::append(ResourceDirInclude, "include");
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&
+ (!IsLinuxMusl || DriverArgs.hasArg(options::OPT_nostdlibinc)))
+ addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
+ }
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ const bool HasSysRoot = !D.SysRoot.empty();
+ if (HasSysRoot) {
SmallString<128> P(D.SysRoot);
- if (getTriple().isMusl())
+ if (IsLinuxMusl)
llvm::sys::path::append(P, "usr/include");
else
llvm::sys::path::append(P, "include");
+
addExternCSystemInclude(DriverArgs, CC1Args, P.str());
- return;
+ // LOCAL_INCLUDE_DIR
+ addSystemInclude(DriverArgs, CC1Args, P + "/usr/local/include");
+ // TOOL_INCLUDE_DIR
+ AddMultilibIncludeArgs(DriverArgs, CC1Args);
}
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && IsLinuxMusl)
+ addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
+
+ if (HasSysRoot)
+ return;
std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
D.PrefixDirs);
addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 20efbdc237a8..7ba729f36bd8 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -136,10 +136,13 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
llvm_unreachable("Unsupported target architecture.");
}
- if (Args.hasArg(options::OPT_mwindows)) {
+ Arg *SubsysArg =
+ Args.getLastArg(options::OPT_mwindows, options::OPT_mconsole);
+ if (SubsysArg && SubsysArg->getOption().matches(options::OPT_mwindows)) {
CmdArgs.push_back("--subsystem");
CmdArgs.push_back("windows");
- } else if (Args.hasArg(options::OPT_mconsole)) {
+ } else if (SubsysArg &&
+ SubsysArg->getOption().matches(options::OPT_mconsole)) {
CmdArgs.push_back("--subsystem");
CmdArgs.push_back("console");
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 33e5f3e99c45..7025028bc94a 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3528,6 +3528,9 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Args, OPT_fexperimental_relative_cxx_abi_vtables, SA);
else
GenerateArg(Args, OPT_fno_experimental_relative_cxx_abi_vtables, SA);
+
+ for (const auto &MP : Opts.MacroPrefixMap)
+ GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA);
}
bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@@ -4037,6 +4040,12 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
options::OPT_fno_experimental_relative_cxx_abi_vtables,
TargetCXXABI::usesRelativeVTables(T));
+ for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
+ auto Split = StringRef(A).split('=');
+ Opts.MacroPrefixMap.insert(
+ {std::string(Split.first), std::string(Split.second)});
+ }
+
return Diags.getNumErrors() == NumErrorsBefore;
}
@@ -4109,9 +4118,6 @@ static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA);
- for (const auto &MP : Opts.MacroPrefixMap)
- GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA);
-
if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
GenerateArg(Args, OPT_preamble_bytes_EQ,
Twine(Opts.PrecompiledPreambleBytes.first) + "," +
@@ -4180,12 +4186,6 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
- for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
- auto Split = StringRef(A).split('=');
- Opts.MacroPrefixMap.insert(
- {std::string(Split.first), std::string(Split.second)});
- }
-
if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
StringRef Value(A->getValue());
size_t Comma = Value.find(',');
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index ff8eb8fca268..34ec79d6acbc 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -574,6 +574,9 @@ void _WriteStatusReg(int, __int64);
unsigned short __cdecl _byteswap_ushort(unsigned short val);
unsigned long __cdecl _byteswap_ulong (unsigned long val);
unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val);
+
+__int64 __mulh(__int64 __a, __int64 __b);
+unsigned __int64 __umulh(unsigned __int64 __a, unsigned __int64 __b);
#endif
/*----------------------------------------------------------------------------*\
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 8728ac9e2166..d8ad9d845e7a 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1453,15 +1453,6 @@ static bool isTargetEnvironment(const TargetInfo &TI,
return TI.getTriple().getEnvironment() == Env.getEnvironment();
}
-static void remapMacroPath(
- SmallString<256> &Path,
- const std::map<std::string, std::string, std::greater<std::string>>
- &MacroPrefixMap) {
- for (const auto &Entry : MacroPrefixMap)
- if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second))
- break;
-}
-
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
/// as a builtin macro, handle it and return the next token as 'Tok'.
void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
@@ -1543,7 +1534,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else {
FN += PLoc.getFilename();
}
- remapMacroPath(FN, PPOpts->MacroPrefixMap);
+ getLangOpts().remapPathPrefix(FN);
Lexer::Stringify(FN);
OS << '"' << FN << '"';
}
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index f2c70d0a56ef..931c9e3e2738 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -742,22 +742,15 @@ Optional<NormalizedConstraint>
NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
ArrayRef<const Expr *> E) {
assert(E.size() != 0);
- auto First = fromConstraintExpr(S, D, E[0]);
- if (E.size() == 1)
- return First;
- auto Second = fromConstraintExpr(S, D, E[1]);
- if (!Second)
+ auto Conjunction = fromConstraintExpr(S, D, E[0]);
+ if (!Conjunction)
return None;
- llvm::Optional<NormalizedConstraint> Conjunction;
- Conjunction.emplace(S.Context, std::move(*First), std::move(*Second),
- CCK_Conjunction);
- for (unsigned I = 2; I < E.size(); ++I) {
+ for (unsigned I = 1; I < E.size(); ++I) {
auto Next = fromConstraintExpr(S, D, E[I]);
if (!Next)
- return llvm::Optional<NormalizedConstraint>{};
- NormalizedConstraint NewConjunction(S.Context, std::move(*Conjunction),
+ return None;
+ *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction),
std::move(*Next), CCK_Conjunction);
- *Conjunction = std::move(NewConjunction);
}
return Conjunction;
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 83c97626ff7e..da4f4f862095 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -12472,6 +12472,8 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
return false;
}
+ const NestedNameSpecifier *CNNS =
+ Context.getCanonicalNestedNameSpecifier(Qual);
for (LookupResult::iterator I = Prev.begin(), E = Prev.end(); I != E; ++I) {
NamedDecl *D = *I;
@@ -12497,8 +12499,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
// using decls differ if they name different scopes (but note that
// template instantiation can cause this check to trigger when it
// didn't before instantiation).
- if (Context.getCanonicalNestedNameSpecifier(Qual) !=
- Context.getCanonicalNestedNameSpecifier(DQual))
+ if (CNNS != Context.getCanonicalNestedNameSpecifier(DQual))
continue;
Diag(NameLoc, diag::err_using_decl_redeclaration) << SS.getRange();
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 175388198324..5d26f2d2c11a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1079,7 +1079,7 @@ NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
return Param;
// Check the template argument itself.
- if (CheckTemplateArgument(Param, DefaultTInfo)) {
+ if (CheckTemplateArgument(DefaultTInfo)) {
Param->setInvalidDecl();
return Param;
}
@@ -5042,7 +5042,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
}
}
- if (CheckTemplateArgument(Param, TSI))
+ if (CheckTemplateArgument(TSI))
return true;
// Add the converted template type argument.
@@ -5661,7 +5661,7 @@ bool Sema::CheckTemplateArgumentList(
TemplateArgumentListInfo NewArgs = TemplateArgs;
// Make sure we get the template parameter list from the most
- // recentdeclaration, since that is the only one that has is guaranteed to
+ // recent declaration, since that is the only one that is guaranteed to
// have all the default template argument information.
TemplateParameterList *Params =
cast<TemplateDecl>(Template->getMostRecentDecl())
@@ -6208,8 +6208,7 @@ bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
///
/// This routine implements the semantics of C++ [temp.arg.type]. It
/// returns true if an error occurred, and false otherwise.
-bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
- TypeSourceInfo *ArgInfo) {
+bool Sema::CheckTemplateArgument(TypeSourceInfo *ArgInfo) {
assert(ArgInfo && "invalid TypeSourceInfo");
QualType Arg = ArgInfo->getType();
SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index f18f77d3442a..74889aa3ca88 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1934,25 +1934,23 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
return Req;
Sema::SFINAETrap Trap(SemaRef);
- TemplateDeductionInfo Info(Req->getExpr()->getBeginLoc());
llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
TransExpr;
if (Req->isExprSubstitutionFailure())
TransExpr = Req->getExprSubstitutionDiagnostic();
else {
- Sema::InstantiatingTemplate ExprInst(SemaRef, Req->getExpr()->getBeginLoc(),
- Req, Info,
- Req->getExpr()->getSourceRange());
+ Expr *E = Req->getExpr();
+ TemplateDeductionInfo Info(E->getBeginLoc());
+ Sema::InstantiatingTemplate ExprInst(SemaRef, E->getBeginLoc(), Req, Info,
+ E->getSourceRange());
if (ExprInst.isInvalid())
return nullptr;
- ExprResult TransExprRes = TransformExpr(Req->getExpr());
+ ExprResult TransExprRes = TransformExpr(E);
if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
- TransExpr = createSubstDiag(SemaRef, Info,
- [&] (llvm::raw_ostream& OS) {
- Req->getExpr()->printPretty(OS, nullptr,
- SemaRef.getPrintingPolicy());
- });
+ TransExpr = createSubstDiag(SemaRef, Info, [&](llvm::raw_ostream &OS) {
+ E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
+ });
else
TransExpr = TransExprRes.get();
}
@@ -1966,6 +1964,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
else if (RetReq.isTypeConstraint()) {
TemplateParameterList *OrigTPL =
RetReq.getTypeConstraintTemplateParameterList();
+ TemplateDeductionInfo Info(OrigTPL->getTemplateLoc());
Sema::InstantiatingTemplate TPLInst(SemaRef, OrigTPL->getTemplateLoc(),
Req, Info, OrigTPL->getSourceRange());
if (TPLInst.isInvalid())