aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-08-17 19:34:38 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-08-17 19:34:38 +0000
commit631f6b779f4d248755ad71398d0f296653dd62cf (patch)
tree817597699dc876210d1681a258acaaca031345a9 /lib
parent7fd6ba58d980ec2bf312a80444948501dd27d020 (diff)
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTDiagnostic.cpp6
-rw-r--r--lib/AST/DeclCXX.cpp11
-rw-r--r--lib/AST/ExprConstant.cpp18
-rw-r--r--lib/Analysis/CFG.cpp12
-rw-r--r--lib/Basic/Targets.cpp4
-rw-r--r--lib/CodeGen/CGBlocks.cpp12
-rw-r--r--lib/CodeGen/CGBuiltin.cpp5
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp10
-rw-r--r--lib/CodeGen/CGStmt.cpp22
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp11
-rw-r--r--lib/Driver/ToolChains.cpp13
-rw-r--r--lib/Driver/ToolChains.h3
-rw-r--r--lib/Driver/Tools.cpp29
-rw-r--r--lib/Headers/avx512fintrin.h1
-rw-r--r--lib/Headers/avxintrin.h4
-rw-r--r--lib/Headers/cpuid.h8
-rw-r--r--lib/Headers/emmintrin.h9
-rw-r--r--lib/Headers/xmmintrin.h4
-rw-r--r--lib/Lex/Pragma.cpp4
-rw-r--r--lib/Parse/ParseExpr.cpp7
-rw-r--r--lib/Parse/ParseExprCXX.cpp65
-rw-r--r--lib/Sema/SemaChecking.cpp22
-rw-r--r--lib/Sema/SemaExprCXX.cpp34
-rw-r--r--lib/Sema/SemaLambda.cpp21
-rw-r--r--lib/Sema/SemaOverload.cpp6
-rw-r--r--lib/Sema/TreeTransform.h4
-rw-r--r--lib/Serialization/ASTReader.cpp2
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp13
-rw-r--r--lib/Serialization/ASTWriter.cpp18
29 files changed, 200 insertions, 178 deletions
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 22de8bc0dd050..0f5a8b5ae8926 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -917,6 +917,8 @@ class TemplateDiff {
/// template argument.
InternalIterator(const TemplateSpecializationType *TST)
: TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
+ if (!TST) return;
+
if (isEnd()) return;
// Set to first template argument. If not a parameter pack, done.
@@ -937,11 +939,13 @@ class TemplateDiff {
/// isEnd - Returns true if the iterator is one past the end.
bool isEnd() const {
+ assert(TST && "InternalIterator is invalid with a null TST.");
return Index >= TST->getNumArgs();
}
/// &operator++ - Increment the iterator to the next template argument.
InternalIterator &operator++() {
+ assert(TST && "InternalIterator is invalid with a null TST.");
if (isEnd()) {
return *this;
}
@@ -977,6 +981,7 @@ class TemplateDiff {
/// operator* - Returns the appropriate TemplateArgument.
reference operator*() const {
+ assert(TST && "InternalIterator is invalid with a null TST.");
assert(!isEnd() && "Index exceeds number of arguments.");
if (CurrentTA == EndTA)
return TST->getArg(Index);
@@ -986,6 +991,7 @@ class TemplateDiff {
/// operator-> - Allow access to the underlying TemplateArgument.
pointer operator->() const {
+ assert(TST && "InternalIterator is invalid with a null TST.");
return &operator*();
}
};
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index d069bfdc3dc28..81f94148d6ed3 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -807,6 +807,17 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().DefaultedDestructorIsDeleted = true;
}
+ // For an anonymous union member, our overload resolution will perform
+ // overload resolution for its members.
+ if (Field->isAnonymousStructOrUnion()) {
+ data().NeedOverloadResolutionForMoveConstructor |=
+ FieldRec->data().NeedOverloadResolutionForMoveConstructor;
+ data().NeedOverloadResolutionForMoveAssignment |=
+ FieldRec->data().NeedOverloadResolutionForMoveAssignment;
+ data().NeedOverloadResolutionForDestructor |=
+ FieldRec->data().NeedOverloadResolutionForDestructor;
+ }
+
// C++0x [class.ctor]p5:
// A default constructor is trivial [...] if:
// -- for all the non-static data members of its class that are of
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index a25a6c7e51358..df944e8f25f29 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -36,7 +36,6 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/ASTLambda.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
@@ -2126,22 +2125,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
// If this is a local variable, dig out its value.
if (Frame) {
Result = Frame->getTemporary(VD);
- if (!Result) {
- // Assume variables referenced within a lambda's call operator that were
- // not declared within the call operator are captures and during checking
- // of a potential constant expression, assume they are unknown constant
- // expressions.
- assert(isLambdaCallOperator(Frame->Callee) &&
- (VD->getDeclContext() != Frame->Callee || VD->isInitCapture()) &&
- "missing value for local variable");
- if (Info.checkingPotentialConstantExpression())
- return false;
- // FIXME: implement capture evaluation during constant expr evaluation.
- Info.FFDiag(E->getLocStart(),
- diag::note_unimplemented_constexpr_lambda_feature_ast)
- << "captures not currently allowed";
- return false;
- }
+ assert(Result && "missing value for local variable");
return true;
}
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index d7a9bdb3d82cd..a67f0910e15a7 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -3902,7 +3902,17 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const {
case CFGElement::AutomaticObjectDtor: {
const VarDecl *var = castAs<CFGAutomaticObjDtor>().getVarDecl();
QualType ty = var->getType();
- ty = ty.getNonReferenceType();
+
+ // FIXME: See CFGBuilder::addLocalScopeForVarDecl.
+ //
+ // Lifetime-extending constructs are handled here. This works for a single
+ // temporary in an initializer expression.
+ if (ty->isReferenceType()) {
+ if (const Expr *Init = var->getInit()) {
+ ty = getReferenceInitTemporaryType(astContext, Init);
+ }
+ }
+
while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) {
ty = arrayType->getElementType();
}
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index c3ca8c8af5d5c..7ec06bb17e3fd 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -7094,9 +7094,9 @@ class MipsTargetInfo : public TargetInfo {
if (ABI == "o32")
Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
else if (ABI == "n32")
- Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
+ Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
else if (ABI == "n64")
- Layout = "m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
+ Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128";
else
llvm_unreachable("Invalid ABI");
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 5a41f361d9acf..e3658ab9b7624 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -125,10 +125,15 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
llvm::Constant *init = llvm::ConstantStruct::getAnon(elements);
+ unsigned AddrSpace = 0;
+ if (C.getLangOpts().OpenCL)
+ AddrSpace = C.getTargetAddressSpace(LangAS::opencl_constant);
llvm::GlobalVariable *global =
new llvm::GlobalVariable(CGM.getModule(), init->getType(), true,
llvm::GlobalValue::InternalLinkage,
- init, "__block_descriptor_tmp");
+ init, "__block_descriptor_tmp", nullptr,
+ llvm::GlobalValue::NotThreadLocal,
+ AddrSpace);
return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType());
}
@@ -927,7 +932,10 @@ llvm::Type *CodeGenModule::getBlockDescriptorType() {
UnsignedLongTy, UnsignedLongTy, nullptr);
// Now form a pointer to that.
- BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType);
+ unsigned AddrSpace = 0;
+ if (getLangOpts().OpenCL)
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant);
+ BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
return BlockDescriptorType;
}
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index c74e53ea84e07..a5fc53113bdcf 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -2209,8 +2209,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT);
else
NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT);
- auto NewCall = Builder.CreateCall(CGM.CreateRuntimeFunction(FTy,
- E->getDirectCallee()->getName()), {NewArg});
+ auto NewName = std::string("__") + E->getDirectCallee()->getName().str();
+ auto NewCall =
+ Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg});
return RValue::get(Builder.CreateBitOrPointerCast(NewCall,
ConvertType(E->getType())));
}
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 5e9d73f082fc8..0607a5157a6fc 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -3637,6 +3637,16 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) {
// Emitting one decl is sufficient - debuggers can detect that this is an
// overloaded name & provide lookup for all the overloads.
const UsingShadowDecl &USD = **UD.shadow_begin();
+
+ // FIXME: Skip functions with undeduced auto return type for now since we
+ // don't currently have the plumbing for separate declarations & definitions
+ // of free functions and mismatched types (auto in the declaration, concrete
+ // return type in the definition)
+ if (const auto *FD = dyn_cast<FunctionDecl>(USD.getUnderlyingDecl()))
+ if (const auto *AT =
+ FD->getType()->getAs<FunctionProtoType>()->getContainedAutoType())
+ if (AT->getDeducedType().isNull())
+ return;
if (llvm::DINode *Target =
getDeclarationOrDefinition(USD.getUnderlyingDecl()))
DBuilder.createImportedDeclaration(
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 13c02f2181354..77879021f9af6 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -620,14 +620,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
RunCleanupsScope ThenScope(*this);
EmitStmt(S.getThen());
}
- {
- auto CurBlock = Builder.GetInsertBlock();
- EmitBranch(ContBlock);
- // Eliminate any empty blocks that may have been created by nested
- // control flow statements in the 'then' clause.
- if (CurBlock)
- SimplifyForwardingBlocks(CurBlock);
- }
+ EmitBranch(ContBlock);
// Emit the 'else' code if present.
if (const Stmt *Else = S.getElse()) {
@@ -643,12 +636,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
{
// There is no need to emit line number for an unconditional branch.
auto NL = ApplyDebugLocation::CreateEmpty(*this);
- auto CurBlock = Builder.GetInsertBlock();
EmitBranch(ContBlock);
- // Eliminate any empty blocks that may have been created by nested
- // control flow statements emitted in the 'else' clause.
- if (CurBlock)
- SimplifyForwardingBlocks(CurBlock);
}
}
@@ -1261,6 +1249,14 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
}
void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
+ // If there is no enclosing switch instance that we're aware of, then this
+ // default statement can be elided. This situation only happens when we've
+ // constant-folded the switch.
+ if (!SwitchInsn) {
+ EmitStmt(S.getSubStmt());
+ return;
+ }
+
llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
assert(DefaultBlock->empty() &&
"EmitDefaultStmt: Default block already defined?");
diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp
index b4dd1a930325f..b011a0f319e37 100644
--- a/lib/CodeGen/CoverageMappingGen.cpp
+++ b/lib/CodeGen/CoverageMappingGen.cpp
@@ -351,6 +351,9 @@ struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
gatherFileIDs(FileIDMapping);
emitSourceRegions();
+ if (MappingRegions.empty())
+ return;
+
CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
Writer.write(OS);
}
@@ -604,6 +607,9 @@ struct CounterCoverageMappingBuilder
emitExpansionRegions();
gatherSkippedRegions();
+ if (MappingRegions.empty())
+ return;
+
CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(),
MappingRegions);
Writer.write(OS);
@@ -620,6 +626,11 @@ struct CounterCoverageMappingBuilder
void VisitDecl(const Decl *D) {
Stmt *Body = D->getBody();
+
+ // Do not propagate region counts into system headers.
+ if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
+ return;
+
propagateCounts(getRegionCounter(Body), Body);
}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 4ecbf2bac3c3f..9bb7a59adc1c7 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -3281,6 +3281,19 @@ Tool *CloudABI::buildLinker() const {
return new tools::cloudabi::Linker(*this);
}
+bool CloudABI::isPIEDefault() const {
+ // Only enable PIE on architectures that support PC-relative
+ // addressing. PC-relative addressing is required, as the process
+ // startup code must be able to relocate itself.
+ switch (getTriple().getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::x86_64:
+ return true;
+ default:
+ return false;
+ }
+}
+
SanitizerMask CloudABI::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::SafeStack;
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 4e5c3f7f96a6c..369712fa934b9 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -634,8 +634,7 @@ public:
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
- bool isPIEDefault() const override { return true; }
-
+ bool isPIEDefault() const override;
SanitizerMask getSupportedSanitizers() const override;
SanitizerMask getDefaultSanitizers() const override;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index af70017edb056..31d4360184508 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -3258,7 +3258,7 @@ static bool shouldUseFramePointerForTarget(const ArgList &Args,
break;
}
- if (Triple.isOSLinux()) {
+ if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI) {
switch (Triple.getArch()) {
// Don't use a frame pointer on linux if optimizing for certain targets.
case llvm::Triple::mips64:
@@ -4568,8 +4568,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_gdwarf_4, options::OPT_gdwarf_5))
DwarfVersion = DwarfVersionNum(A->getSpelling());
- // Forward -gcodeview.
- // 'EmitCodeView might have been set by CL-compatibility argument parsing.
+ // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility
+ // argument parsing.
if (Args.hasArg(options::OPT_gcodeview) || EmitCodeView) {
// DwarfVersion remains at 0 if no explicit choice was made.
CmdArgs.push_back("-gcodeview");
@@ -5020,9 +5020,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
- // Forward flags for OpenMP
+ // Forward flags for OpenMP. We don't do this if the current action is an
+ // device offloading action.
+ //
+ // TODO: Allow OpenMP offload actions when they become available.
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
- options::OPT_fno_openmp, false)) {
+ options::OPT_fno_openmp, false) &&
+ JA.isDeviceOffloading(Action::OFK_None)) {
switch (getOpenMPRuntime(getToolChain(), Args)) {
case OMPRT_OMP:
case OMPRT_IOMP5:
@@ -6354,9 +6358,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong)));
}
- // Emit CodeView if -Z7 or -Zd are present.
+ // Emit CodeView if -Z7, -Zd, or -gline-tables-only are present.
if (Arg *DebugInfoArg =
- Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd)) {
+ Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd,
+ options::OPT_gline_tables_only)) {
*EmitCodeView = true;
if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7))
*DebugInfoKind = codegenoptions::LimitedDebugInfo;
@@ -7453,11 +7458,13 @@ void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// CloudABI only supports static linkage.
CmdArgs.push_back("-Bstatic");
-
- // CloudABI uses Position Independent Executables exclusively.
- CmdArgs.push_back("-pie");
CmdArgs.push_back("--no-dynamic-linker");
- CmdArgs.push_back("-zrelro");
+
+ // Provide PIE linker flags in case PIE is default for the architecture.
+ if (ToolChain.isPIEDefault()) {
+ CmdArgs.push_back("-pie");
+ CmdArgs.push_back("-zrelro");
+ }
CmdArgs.push_back("--eh-frame-hdr");
CmdArgs.push_back("--gc-sections");
diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h
index badc43650bab1..0bf6582345d4f 100644
--- a/lib/Headers/avx512fintrin.h
+++ b/lib/Headers/avx512fintrin.h
@@ -7484,7 +7484,6 @@ _mm512_mask_cvtsepi64_storeu_epi8 (void * __P, __mmask8 __M, __m512i __A)
static __inline__ __m256i __DEFAULT_FN_ATTRS
_mm512_cvtsepi64_epi32 (__m512i __A)
{
- __v8si __O;
return (__m256i) __builtin_ia32_pmovsqd512_mask ((__v8di) __A,
(__v8si) _mm256_undefined_si256 (),
(__mmask8) -1);
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
index 86bfdfb80c796..32e8546817b3a 100644
--- a/lib/Headers/avxintrin.h
+++ b/lib/Headers/avxintrin.h
@@ -2117,7 +2117,7 @@ _mm256_cvtps_pd(__m128 __a)
static __inline __m128i __DEFAULT_FN_ATTRS
_mm256_cvttpd_epi32(__m256d __a)
{
- return (__m128i)__builtin_convertvector((__v4df) __a, __v4si);
+ return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a);
}
static __inline __m128i __DEFAULT_FN_ATTRS
@@ -2129,7 +2129,7 @@ _mm256_cvtpd_epi32(__m256d __a)
static __inline __m256i __DEFAULT_FN_ATTRS
_mm256_cvttps_epi32(__m256 __a)
{
- return (__m256i)__builtin_convertvector((__v8sf) __a, __v8si);
+ return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a);
}
static __inline double __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/cpuid.h b/lib/Headers/cpuid.h
index 5da02e0e51521..400dcfacd552c 100644
--- a/lib/Headers/cpuid.h
+++ b/lib/Headers/cpuid.h
@@ -82,6 +82,7 @@
/* Features in %ecx for level 1 */
#define bit_SSE3 0x00000001
#define bit_PCLMULQDQ 0x00000002
+#define bit_PCLMUL bit_PCLMULQDQ /* for gcc compat */
#define bit_DTES64 0x00000004
#define bit_MONITOR 0x00000008
#define bit_DSCPL 0x00000010
@@ -98,15 +99,19 @@
#define bit_PCID 0x00020000
#define bit_DCA 0x00040000
#define bit_SSE41 0x00080000
+#define bit_SSE4_1 bit_SSE41 /* for gcc compat */
#define bit_SSE42 0x00100000
+#define bit_SSE4_2 bit_SSE42 /* for gcc compat */
#define bit_x2APIC 0x00200000
#define bit_MOVBE 0x00400000
#define bit_POPCNT 0x00800000
#define bit_TSCDeadline 0x01000000
#define bit_AESNI 0x02000000
+#define bit_AES bit_AESNI /* for gcc compat */
#define bit_XSAVE 0x04000000
#define bit_OSXSAVE 0x08000000
#define bit_AVX 0x10000000
+#define bit_F16C 0x20000000
#define bit_RDRND 0x40000000
/* Features in %edx for level 1 */
@@ -119,6 +124,7 @@
#define bit_PAE 0x00000040
#define bit_MCE 0x00000080
#define bit_CX8 0x00000100
+#define bit_CMPXCHG8B bit_CX8 /* for gcc compat */
#define bit_APIC 0x00000200
#define bit_SEP 0x00000800
#define bit_MTRR 0x00001000
@@ -133,7 +139,7 @@
#define bit_ACPI 0x00400000
#define bit_MMX 0x00800000
#define bit_FXSR 0x01000000
-#define bit_FXSAVE bit_FXSR /* for gcc compat */
+#define bit_FXSAVE bit_FXSR /* for gcc compat */
#define bit_SSE 0x02000000
#define bit_SSE2 0x04000000
#define bit_SS 0x08000000
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index c78d059f442bf..70d6d726110af 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -417,8 +417,7 @@ _mm_cvtsd_si32(__m128d __a)
static __inline__ __m128 __DEFAULT_FN_ATTRS
_mm_cvtsd_ss(__m128 __a, __m128d __b)
{
- __a[0] = __b[0];
- return __a;
+ return (__m128)__builtin_ia32_cvtsd2ss((__v4sf)__a, (__v2df)__b);
}
static __inline__ __m128d __DEFAULT_FN_ATTRS
@@ -444,7 +443,7 @@ _mm_cvttpd_epi32(__m128d __a)
static __inline__ int __DEFAULT_FN_ATTRS
_mm_cvttsd_si32(__m128d __a)
{
- return __a[0];
+ return __builtin_ia32_cvttsd2si((__v2df)__a);
}
static __inline__ __m64 __DEFAULT_FN_ATTRS
@@ -1707,7 +1706,7 @@ _mm_cvtsd_si64(__m128d __a)
static __inline__ long long __DEFAULT_FN_ATTRS
_mm_cvttsd_si64(__m128d __a)
{
- return __a[0];
+ return __builtin_ia32_cvttsd2si64((__v2df)__a);
}
#endif
@@ -1755,7 +1754,7 @@ _mm_cvtps_epi32(__m128 __a)
static __inline__ __m128i __DEFAULT_FN_ATTRS
_mm_cvttps_epi32(__m128 __a)
{
- return (__m128i)__builtin_convertvector((__v4sf)__a, __v4si);
+ return (__m128i)__builtin_ia32_cvttps2dq((__v4sf)__a);
}
/// \brief Returns a vector of [4 x i32] where the lowest element is the input
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index 3110e8babf946..99cddb0fac82b 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -1350,7 +1350,7 @@ _mm_cvt_ps2pi(__m128 __a)
static __inline__ int __DEFAULT_FN_ATTRS
_mm_cvttss_si32(__m128 __a)
{
- return __a[0];
+ return __builtin_ia32_cvttss2si((__v4sf)__a);
}
/// \brief Converts a float value contained in the lower 32 bits of a vector of
@@ -1386,7 +1386,7 @@ _mm_cvtt_ss2si(__m128 __a)
static __inline__ long long __DEFAULT_FN_ATTRS
_mm_cvttss_si64(__m128 __a)
{
- return __a[0];
+ return __builtin_ia32_cvttss2si64((__v4sf)__a);
}
/// \brief Converts two low-order float values in a 128-bit vector of
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 1819f4f06bc53..3bdd31b26ff8b 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -354,7 +354,9 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
/// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'.
///
void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
- if (isInPrimaryFile()) {
+ // Don't honor the 'once' when handling the primary source file, unless
+ // this is a prefix to a TU, which indicates we're generating a PCH file.
+ if (isInPrimaryFile() && TUKind != TU_Prefix) {
Diag(OnceTok, diag::pp_pragma_once_in_main_file);
return;
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 47d1326b79895..3e87a73aafe89 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -447,14 +447,15 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
OpToken.getKind(), LHS.get(), RHS.get());
- // In this case, ActOnBinOp performed the CorrectDelayedTyposInExpr check.
- if (!getLangOpts().CPlusPlus)
- continue;
} else {
LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
LHS.get(), TernaryMiddle.get(),
RHS.get());
}
+ // In this case, ActOnBinOp or ActOnConditionalOp performed the
+ // CorrectDelayedTyposInExpr check.
+ if (!getLangOpts().CPlusPlus)
+ continue;
}
// Ensure potential typos aren't left undiagnosed.
if (LHS.isInvalid()) {
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index b09d7dbc12fc3..85c1301fc9678 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1053,58 +1053,6 @@ bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
return false;
}
-static void
-tryConsumeMutableOrConstexprToken(Parser &P, SourceLocation &MutableLoc,
- SourceLocation &ConstexprLoc,
- SourceLocation &DeclEndLoc) {
- assert(MutableLoc.isInvalid());
- assert(ConstexprLoc.isInvalid());
- // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc
- // to the final of those locations. Emit an error if we have multiple
- // copies of those keywords and recover.
-
- while (true) {
- switch (P.getCurToken().getKind()) {
- case tok::kw_mutable: {
- if (MutableLoc.isValid()) {
- P.Diag(P.getCurToken().getLocation(),
- diag::err_lambda_decl_specifier_repeated)
- << 0 << FixItHint::CreateRemoval(P.getCurToken().getLocation());
- }
- MutableLoc = P.ConsumeToken();
- DeclEndLoc = MutableLoc;
- break /*switch*/;
- }
- case tok::kw_constexpr:
- if (ConstexprLoc.isValid()) {
- P.Diag(P.getCurToken().getLocation(),
- diag::err_lambda_decl_specifier_repeated)
- << 1 << FixItHint::CreateRemoval(P.getCurToken().getLocation());
- }
- ConstexprLoc = P.ConsumeToken();
- DeclEndLoc = ConstexprLoc;
- break /*switch*/;
- default:
- return;
- }
- }
-}
-
-static void
-addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc,
- DeclSpec &DS) {
- if (ConstexprLoc.isValid()) {
- P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus1z
- ? diag::ext_constexpr_on_lambda_cxx1z
- : diag::warn_cxx14_compat_constexpr_on_lambda);
- const char *PrevSpec = nullptr;
- unsigned DiagID = 0;
- DS.SetConstexprSpec(ConstexprLoc, PrevSpec, DiagID);
- assert(PrevSpec == nullptr && DiagID == 0 &&
- "Constexpr cannot have been set previously!");
- }
-}
-
/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
/// expression.
ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
@@ -1163,13 +1111,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// compatible with MSVC.
MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc);
- // Parse mutable-opt and/or constexpr-opt, and update the DeclEndLoc.
+ // Parse 'mutable'[opt].
SourceLocation MutableLoc;
- SourceLocation ConstexprLoc;
- tryConsumeMutableOrConstexprToken(*this, MutableLoc, ConstexprLoc,
- DeclEndLoc);
-
- addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS);
+ if (TryConsumeToken(tok::kw_mutable, MutableLoc))
+ DeclEndLoc = MutableLoc;
// Parse exception-specification[opt].
ExceptionSpecificationType ESpecType = EST_None;
@@ -1227,8 +1172,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
LParenLoc, FunLocalRangeEnd, D,
TrailingReturnType),
Attr, DeclEndLoc);
- } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,
- tok::kw_constexpr) ||
+ } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute) ||
(Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
// It's common to forget that one needs '()' before 'mutable', an attribute
// specifier, or the result type. Deal with this.
@@ -1238,7 +1182,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
case tok::arrow: TokKind = 1; break;
case tok::kw___attribute:
case tok::l_square: TokKind = 2; break;
- case tok::kw_constexpr: TokKind = 3; break;
default: llvm_unreachable("Unknown token kind");
}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 0c25e01787c12..b8e7ede2716c9 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -6523,6 +6523,12 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType,
if (!stackE)
return; // Nothing suspicious was found.
+ // Parameters are initalized in the calling scope, so taking the address
+ // of a parameter reference doesn't need a warning.
+ for (auto *DRE : refVars)
+ if (isa<ParmVarDecl>(DRE->getDecl()))
+ return;
+
SourceLocation diagLoc;
SourceRange diagRange;
if (refVars.empty()) {
@@ -6546,6 +6552,13 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType,
} else if (isa<AddrLabelExpr>(stackE)) { // address of label.
S.Diag(diagLoc, diag::warn_ret_addr_label) << diagRange;
} else { // local temporary.
+ // If there is an LValue->RValue conversion, then the value of the
+ // reference type is used, not the reference.
+ if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetValExp)) {
+ if (ICE->getCastKind() == CK_LValueToRValue) {
+ return;
+ }
+ }
S.Diag(diagLoc, diag::warn_ret_local_temp_addr_ref)
<< lhsType->isReferenceType() << diagRange;
}
@@ -7776,6 +7789,12 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
unsigned OriginalWidth = Value.getBitWidth();
unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context);
+ if (Value.isSigned() && Value.isNegative())
+ if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
+ if (UO->getOpcode() == UO_Minus)
+ if (isa<IntegerLiteral>(UO->getSubExpr()))
+ OriginalWidth = Value.getMinSignedBits();
+
if (OriginalWidth <= FieldWidth)
return false;
@@ -9372,7 +9391,8 @@ void Sema::CheckUnsequencedOperations(Expr *E) {
void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc,
bool IsConstexpr) {
CheckImplicitConversions(E, CheckLoc);
- CheckUnsequencedOperations(E);
+ if (!E->isInstantiationDependent())
+ CheckUnsequencedOperations(E);
if (!IsConstexpr && !E->isValueDependent())
CheckForIntOverflow(E);
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 2cd00f8218a67..b7a968e09d4d6 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -961,32 +961,26 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda(
QualType Sema::getCurrentThisType() {
DeclContext *DC = getFunctionLevelDeclContext();
QualType ThisTy = CXXThisTypeOverride;
+
if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) {
if (method && method->isInstance())
ThisTy = method->getThisType(Context);
}
- if (ThisTy.isNull()) {
- if (isGenericLambdaCallOperatorSpecialization(CurContext) &&
- CurContext->getParent()->getParent()->isRecord()) {
- // This is a generic lambda call operator that is being instantiated
- // within a default initializer - so use the enclosing class as 'this'.
- // There is no enclosing member function to retrieve the 'this' pointer
- // from.
- // FIXME: This looks wrong. If we're in a lambda within a lambda within a
- // default member initializer, we need to recurse up more parents to find
- // the right context. Looks like we should be walking up to the parent of
- // the closure type, checking whether that is itself a lambda, and if so,
- // recursing, until we reach a class or a function that isn't a lambda
- // call operator. And we should accumulate the constness of *this on the
- // way.
+ if (ThisTy.isNull() && isLambdaCallOperator(CurContext) &&
+ !ActiveTemplateInstantiations.empty()) {
- QualType ClassTy = Context.getTypeDeclType(
- cast<CXXRecordDecl>(CurContext->getParent()->getParent()));
- // There are no cv-qualifiers for 'this' within default initializers,
- // per [expr.prim.general]p4.
- ThisTy = Context.getPointerType(ClassTy);
- }
+ assert(isa<CXXRecordDecl>(DC) &&
+ "Trying to get 'this' type from static method?");
+
+ // This is a lambda call operator that is being instantiated as a default
+ // initializer. DC must point to the enclosing class type, so we can recover
+ // the 'this' type from it.
+
+ QualType ClassTy = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
+ // There are no cv-qualifiers for 'this' within default initializers,
+ // per [expr.prim.general]p4.
+ ThisTy = Context.getPointerType(ClassTy);
}
// If we are within a lambda's call operator, the cv-qualifiers of 'this'
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 1b8410d7f4b97..8a2bf929dfc0e 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -355,8 +355,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
SourceRange IntroducerRange,
TypeSourceInfo *MethodTypeInfo,
SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params,
- const bool IsConstexprSpecified) {
+ ArrayRef<ParmVarDecl *> Params) {
QualType MethodType = MethodTypeInfo->getType();
TemplateParameterList *TemplateParams =
getGenericLambdaTemplateParameterList(getCurLambda(), *this);
@@ -393,7 +392,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
MethodType, MethodTypeInfo,
SC_None,
/*isInline=*/true,
- IsConstexprSpecified,
+ /*isConstExpr=*/false,
EndLoc);
Method->setAccess(AS_public);
@@ -878,9 +877,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo,
KnownDependent, Intro.Default);
- CXXMethodDecl *Method =
- startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params,
- ParamInfo.getDeclSpec().isConstexprSpecified());
+ CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
+ MethodTyInfo, EndLoc, Params);
if (ExplicitParams)
CheckCXXDefaultArguments(Method);
@@ -1599,17 +1597,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
CaptureInits, ArrayIndexVars,
ArrayIndexStarts, EndLoc,
ContainsUnexpandedParameterPack);
- // If the lambda expression's call operator is not explicitly marked constexpr
- // and we are not in a dependent context, analyze the call operator to infer
- // its constexpr-ness, supressing diagnostics while doing so.
- if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() &&
- !CallOperator->isConstexpr() &&
- !Class->getDeclContext()->isDependentContext()) {
- TentativeAnalysisScope DiagnosticScopeGuard(*this);
- CallOperator->setConstexpr(
- CheckConstexprFunctionDecl(CallOperator) &&
- CheckConstexprFunctionBody(CallOperator, CallOperator->getBody()));
- }
if (!CurContext->isDependentContext()) {
switch (ExprEvalContexts.back().Context) {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index b025a397edca0..40d6e910f1fb3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5975,8 +5975,12 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
SmallVector<Expr *, 16> ConvertedArgs;
bool InitializationFailed = false;
+ // Ignore any variadic parameters. Converting them is pointless, since the
+ // user can't refer to them in the enable_if condition.
+ unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size());
+
// Convert the arguments.
- for (unsigned I = 0, E = Args.size(); I != E; ++I) {
+ for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) {
ExprResult R;
if (I == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) &&
!cast<CXXMethodDecl>(Function)->isStatic() &&
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 36859f61d3871..7224eef848dee 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -10222,9 +10222,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
Class, E->getIntroducerRange(), NewCallOpTSI,
E->getCallOperator()->getLocEnd(),
- NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
- E->getCallOperator()->isConstexpr());
-
+ NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams());
LSI->CallOperator = NewCallOperator;
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index b35bd7bd329b4..9d1554a826aaf 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -8637,6 +8637,7 @@ void ASTReader::FinishedDeserializing() {
auto Updates = std::move(PendingExceptionSpecUpdates);
PendingExceptionSpecUpdates.clear();
for (auto Update : Updates) {
+ ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
auto *FPT = Update.second->getType()->castAs<FunctionProtoType>();
auto ESI = FPT->getExtProtoInfo().ExceptionSpec;
if (auto *Listener = Context.getASTMutationListener())
@@ -8707,6 +8708,7 @@ ASTReader::ASTReader(
AllowConfigurationMismatch(AllowConfigurationMismatch),
ValidateSystemInputs(ValidateSystemInputs),
UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
+ ProcessingUpdateRecords(false),
CurrSwitchCaseStmts(&SwitchCaseStmts), NumSLocEntriesRead(0),
TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
NumMacrosRead(0), TotalNumMacros(0), NumIdentifierLookups(0),
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 4fd7aeb83ac1f..d38a701c04b5a 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -3484,6 +3484,7 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
// The declaration may have been modified by files later in the chain.
// If this is the case, read the record containing the updates from each file
// and pass it to ASTDeclReader to make the modifications.
+ ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
if (UpdI != DeclUpdateOffsets.end()) {
auto UpdateOffsets = std::move(UpdI->second);
@@ -3902,11 +3903,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
}
case UPD_DECL_MARKED_USED: {
- // FIXME: This doesn't send the right notifications if there are
- // ASTMutationListeners other than an ASTWriter.
-
// Maintain AST consistency: any later redeclarations are used too.
- D->setIsUsed();
+ D->markUsed(Reader.Context);
break;
}
@@ -3930,11 +3928,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
Exported = TD->getDefinition();
Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr;
if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
- // FIXME: This doesn't send the right notifications if there are
- // ASTMutationListeners other than an ASTWriter.
- Reader.getContext().mergeDefinitionIntoModule(
- cast<NamedDecl>(Exported), Owner,
- /*NotifyListeners*/ false);
+ Reader.getContext().mergeDefinitionIntoModule(cast<NamedDecl>(Exported),
+ Owner);
Reader.PendingMergedDefinitionsToDeduplicate.insert(
cast<NamedDecl>(Exported));
} else if (Owner && Owner->NameVisibility != Module::AllVisible) {
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index bb6a8ae8f6283..7589b0c5dd528 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -5637,6 +5637,7 @@ void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
}
void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(D->isCompleteDefinition());
assert(!WritingAST && "Already writing the AST!");
if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
@@ -5663,7 +5664,8 @@ static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
}
void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
- assert(DC->isLookupContext() &&
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
+ assert(DC->isLookupContext() &&
"Should not add lookup results to non-lookup contexts!");
// TU is handled elsewhere.
@@ -5697,6 +5699,7 @@ void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
}
void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(D->isImplicit());
// We're only interested in cases where a local declaration is added to an
@@ -5714,6 +5717,7 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
}
void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!DoneWritingDeclsAndTypes && "Already done writing updates!");
if (!Chain) return;
Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
@@ -5728,6 +5732,7 @@ void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
}
void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!Chain) return;
Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
@@ -5738,6 +5743,7 @@ void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
const FunctionDecl *Delete) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
assert(Delete && "Not given an operator delete");
if (!Chain) return;
@@ -5747,6 +5753,7 @@ void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
}
void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return; // Declaration not imported from PCH.
@@ -5756,6 +5763,7 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
}
void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -5764,6 +5772,7 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
}
void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -5776,6 +5785,7 @@ void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
}
void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -5786,6 +5796,7 @@ void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!IFD->isFromASTFile())
return; // Declaration not imported from PCH.
@@ -5796,6 +5807,7 @@ void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
}
void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
// If there is *any* declaration of the entity that's not from an AST file,
@@ -5809,6 +5821,7 @@ void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
}
void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -5818,6 +5831,7 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -5827,6 +5841,7 @@ void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
}
void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
assert(D->isHidden() && "expected a hidden declaration");
DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M));
@@ -5834,6 +5849,7 @@ void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
const RecordDecl *Record) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!Record->isFromASTFile())
return;