aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp682
1 files changed, 203 insertions, 479 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 23c99d45a7..379e2aefb4 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1,9 +1,8 @@
//===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -62,7 +61,7 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType) {
namespace {
-class TypeNameValidatorCCC : public CorrectionCandidateCallback {
+class TypeNameValidatorCCC final : public CorrectionCandidateCallback {
public:
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass = false,
bool AllowTemplates = false,
@@ -106,6 +105,10 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
return !WantClassName && candidate.isKeyword();
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<TypeNameValidatorCCC>(*this);
+ }
+
private:
bool AllowInvalidDecl;
bool WantClassName;
@@ -368,11 +371,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
if (CorrectedII) {
- TypoCorrection Correction =
- CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS,
- llvm::make_unique<TypeNameValidatorCCC>(
- true, isClassName, AllowDeducedTemplate),
- CTK_ErrorRecovery);
+ TypeNameValidatorCCC CCC(/*AllowInvalid=*/true, isClassName,
+ AllowDeducedTemplate);
+ TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), Kind,
+ S, SS, CCC, CTK_ErrorRecovery);
IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
TemplateTy Template;
bool MemberOfUnknownSpecialization;
@@ -665,11 +667,12 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
// There may have been a typo in the name of the type. Look up typo
// results, in case we have something that we can suggest.
+ TypeNameValidatorCCC CCC(/*AllowInvalid=*/false, /*WantClass=*/false,
+ /*AllowTemplates=*/IsTemplateName,
+ /*AllowNonTemplates=*/!IsTemplateName);
if (TypoCorrection Corrected =
CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS,
- llvm::make_unique<TypeNameValidatorCCC>(
- false, false, IsTemplateName, !IsTemplateName),
- CTK_ErrorRecovery)) {
+ CCC, CTK_ErrorRecovery)) {
// FIXME: Support error recovery for the template-name case.
bool CanRecover = !IsTemplateName;
if (Corrected.isKeyword()) {
@@ -844,8 +847,7 @@ static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS,
Sema::NameClassification
Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
SourceLocation NameLoc, const Token &NextToken,
- bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC) {
+ bool IsAddressOfOperand, CorrectionCandidateCallback *CCC) {
DeclarationNameInfo NameInfo(Name, NameLoc);
ObjCMethodDecl *CurMethod = getCurMethodDecl();
@@ -927,10 +929,9 @@ Corrected:
// close to this name.
if (!SecondTry && CCC) {
SecondTry = true;
- if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
- Result.getLookupKind(), S,
- &SS, std::move(CCC),
- CTK_ErrorRecovery)) {
+ if (TypoCorrection Corrected =
+ CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S,
+ &SS, *CCC, CTK_ErrorRecovery)) {
unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
unsigned QualifiedDiag = diag::err_no_member_suggest;
@@ -1018,7 +1019,8 @@ Corrected:
case LookupResult::Ambiguous:
if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
- hasAnyAcceptableTemplateNames(Result)) {
+ hasAnyAcceptableTemplateNames(Result, /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/false)) {
// C++ [temp.local]p3:
// A lookup that finds an injected-class-name (10.2) can result in an
// ambiguity in certain cases (for example, if it is found in more than
@@ -1042,7 +1044,9 @@ Corrected:
}
if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
- (IsFilteredTemplateName || hasAnyAcceptableTemplateNames(Result))) {
+ (IsFilteredTemplateName ||
+ hasAnyAcceptableTemplateNames(Result, /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/false))) {
// C++ [temp.names]p3:
// After name lookup (3.4) finds that a name is a template-name or that
// an operator-function-id or a literal- operator-id refers to a set of
@@ -1061,15 +1065,16 @@ Corrected:
Template = Context.getOverloadedTemplateName(Result.begin(),
Result.end());
} else {
- TemplateDecl *TD
- = cast<TemplateDecl>((*Result.begin())->getUnderlyingDecl());
+ auto *TD = cast<TemplateDecl>(getAsTemplateNameDecl(
+ *Result.begin(), /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/false));
IsFunctionTemplate = isa<FunctionTemplateDecl>(TD);
IsVarTemplate = isa<VarTemplateDecl>(TD);
if (SS.isSet() && !SS.isInvalid())
- Template = Context.getQualifiedTemplateName(SS.getScopeRep(),
- /*TemplateKeyword=*/false,
- TD);
+ Template =
+ Context.getQualifiedTemplateName(SS.getScopeRep(),
+ /*TemplateKeyword=*/false, TD);
else
Template = TemplateName(TD);
}
@@ -1399,11 +1404,6 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
}
}
-void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
- if (IdResolver.tryAddTopLevelDecl(D, Name) && TUScope)
- TUScope->AddDecl(D);
-}
-
bool Sema::isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S,
bool AllowInlineNamespace) {
return IdResolver.isDeclInScope(D, Ctx, S, AllowInlineNamespace);
@@ -1461,12 +1461,17 @@ bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) {
Module *NewM = New->getOwningModule();
Module *OldM = Old->getOwningModule();
+
+ if (NewM && NewM->Kind == Module::PrivateModuleFragment)
+ NewM = NewM->Parent;
+ if (OldM && OldM->Kind == Module::PrivateModuleFragment)
+ OldM = OldM->Parent;
+
if (NewM == OldM)
return false;
- // FIXME: Check proclaimed-ownership-declarations here too.
- bool NewIsModuleInterface = NewM && NewM->Kind == Module::ModuleInterfaceUnit;
- bool OldIsModuleInterface = OldM && OldM->Kind == Module::ModuleInterfaceUnit;
+ bool NewIsModuleInterface = NewM && NewM->isModulePurview();
+ bool OldIsModuleInterface = OldM && OldM->isModulePurview();
if (NewIsModuleInterface || OldIsModuleInterface) {
// C++ Modules TS [basic.def.odr] 6.2/6.7 [sic]:
// if a declaration of D [...] appears in the purview of a module, all
@@ -1862,10 +1867,10 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
if (!IDecl && DoTypoCorrection) {
// Perform typo correction at the given location, but only if we
// find an Objective-C class name.
- if (TypoCorrection C = CorrectTypo(
- DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, nullptr,
- llvm::make_unique<DeclFilterCCC<ObjCInterfaceDecl>>(),
- CTK_ErrorRecovery)) {
+ DeclFilterCCC<ObjCInterfaceDecl> CCC{};
+ if (TypoCorrection C =
+ CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName,
+ TUScope, nullptr, CCC, CTK_ErrorRecovery)) {
diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id);
IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>();
Id = IDecl->getIdentifier();
@@ -1927,10 +1932,13 @@ static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S,
Context.setObjCSuperType(Context.getTagDeclType(TD));
}
-static StringRef getHeaderName(ASTContext::GetBuiltinTypeError Error) {
+static StringRef getHeaderName(Builtin::Context &BuiltinInfo, unsigned ID,
+ ASTContext::GetBuiltinTypeError Error) {
switch (Error) {
case ASTContext::GE_None:
return "";
+ case ASTContext::GE_Missing_type:
+ return BuiltinInfo.getHeaderName(ID);
case ASTContext::GE_Missing_stdio:
return "stdio.h";
case ASTContext::GE_Missing_setjmp:
@@ -1955,7 +1963,8 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
if (Error) {
if (ForRedeclaration)
Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
- << getHeaderName(Error) << Context.BuiltinInfo.getName(ID);
+ << getHeaderName(Context.BuiltinInfo, ID, Error)
+ << Context.BuiltinInfo.getName(ID);
return nullptr;
}
@@ -2427,13 +2436,11 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
InheritableAttr *NewAttr = nullptr;
unsigned AttrSpellingListIndex = Attr->getSpellingListIndex();
if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr))
- NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
- AA->isImplicit(), AA->getIntroduced(),
- AA->getDeprecated(),
- AA->getObsoleted(), AA->getUnavailable(),
- AA->getMessage(), AA->getStrict(),
- AA->getReplacement(), AMK,
- AttrSpellingListIndex);
+ NewAttr = S.mergeAvailabilityAttr(
+ D, AA->getRange(), AA->getPlatform(), AA->isImplicit(),
+ AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(),
+ AA->getUnavailable(), AA->getMessage(), AA->getStrict(),
+ AA->getReplacement(), AMK, AA->getPriority(), AttrSpellingListIndex);
else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))
NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
AttrSpellingListIndex);
@@ -2489,6 +2496,10 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
UA->getGuid());
+ else if (const auto *SLHA = dyn_cast<SpeculativeLoadHardeningAttr>(Attr))
+ NewAttr = S.mergeSpeculativeLoadHardeningAttr(D, *SLHA);
+ else if (const auto *SLHA = dyn_cast<NoSpeculativeLoadHardeningAttr>(Attr))
+ NewAttr = S.mergeNoSpeculativeLoadHardeningAttr(D, *SLHA);
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
@@ -2926,7 +2937,8 @@ static bool hasIdenticalPassObjectSizeAttrs(const FunctionDecl *A,
const auto *AttrB = B->getAttr<PassObjectSizeAttr>();
if (AttrA == AttrB)
return true;
- return AttrA && AttrB && AttrA->getType() == AttrB->getType();
+ return AttrA && AttrB && AttrA->getType() == AttrB->getType() &&
+ AttrA->isDynamic() == AttrB->isDynamic();
};
return std::equal(A->param_begin(), A->param_end(), B->param_begin(), AttrEq);
@@ -3126,6 +3138,15 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
// there but not here.
NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
RequiresAdjustment = true;
+ } else if (New->getBuiltinID()) {
+ // Calling Conventions on a Builtin aren't really useful and setting a
+ // default calling convention and cdecl'ing some builtin redeclarations is
+ // common, so warn and ignore the calling convention on the redeclaration.
+ Diag(New->getLocation(), diag::warn_cconv_ignored)
+ << FunctionType::getNameForCallConv(NewTypeInfo.getCC())
+ << (int)CallingConventionIgnoredReason::BuiltinFunction;
+ NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
+ RequiresAdjustment = true;
} else {
// Calling conventions aren't compatible, so complain.
bool FirstCCExplicit = getCallingConvAttributedType(First->getType());
@@ -4796,6 +4817,18 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
Invalid = true;
}
+ // C++ [dcl.dcl]p3:
+ // [If there are no declarators], and except for the declaration of an
+ // unnamed bit-field, the decl-specifier-seq shall introduce one or more
+ // names into the program
+ // C++ [class.mem]p2:
+ // each such member-declaration shall either declare at least one member
+ // name of the class or declare at least one unnamed bit-field
+ //
+ // For C this is an error even for a named struct, and is diagnosed elsewhere.
+ if (getLangOpts().CPlusPlus && Record->field_empty())
+ Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange();
+
// Mock up a declarator.
Declarator Dc(DS, DeclaratorContext::MemberContext);
TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
@@ -5082,7 +5115,7 @@ static bool hasSimilarParameters(ASTContext &Context,
QualType DefParamTy = Definition->getParamDecl(Idx)->getType();
// The parameter types are identical
- if (Context.hasSameType(DefParamTy, DeclParamTy))
+ if (Context.hasSameUnqualifiedType(DefParamTy, DeclParamTy))
continue;
QualType DeclParamBaseTy = getCoreType(DeclParamTy);
@@ -5955,10 +5988,24 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
}
if (const InheritableAttr *Attr = getDLLAttr(&ND)) {
+ auto *VD = dyn_cast<VarDecl>(&ND);
+ bool IsAnonymousNS = false;
+ bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+ if (VD) {
+ const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(VD->getDeclContext());
+ while (NS && !IsAnonymousNS) {
+ IsAnonymousNS = NS->isAnonymousNamespace();
+ NS = dyn_cast<NamespaceDecl>(NS->getParent());
+ }
+ }
// dll attributes require external linkage. Static locals may have external
// linkage but still cannot be explicitly imported or exported.
- auto *VD = dyn_cast<VarDecl>(&ND);
- if (!ND.isExternallyVisible() || (VD && VD->isStaticLocal())) {
+ // In Microsoft mode, a variable defined in anonymous namespace must have
+ // external linkage in order to be exported.
+ bool AnonNSInMicrosoftMode = IsAnonymousNS && IsMicrosoft;
+ if ((ND.isExternallyVisible() && AnonNSInMicrosoftMode) ||
+ (!AnonNSInMicrosoftMode &&
+ (!ND.isExternallyVisible() || (VD && VD->isStaticLocal())))) {
S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
<< &ND << Attr;
ND.setInvalidDecl();
@@ -6187,7 +6234,8 @@ static bool isIncompleteDeclExternC(Sema &S, const T *D) {
static bool shouldConsiderLinkage(const VarDecl *VD) {
const DeclContext *DC = VD->getDeclContext()->getRedeclContext();
- if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC))
+ if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC))
return VD->hasExternalStorage();
if (DC->isFileContext())
return true;
@@ -6199,7 +6247,7 @@ static bool shouldConsiderLinkage(const VarDecl *VD) {
static bool shouldConsiderLinkage(const FunctionDecl *FD) {
const DeclContext *DC = FD->getDeclContext()->getRedeclContext();
if (DC->isFileContext() || DC->isFunctionOrMethod() ||
- isa<OMPDeclareReductionDecl>(DC))
+ isa<OMPDeclareReductionDecl>(DC) || isa<OMPDeclareMapperDecl>(DC))
return true;
if (DC->isRecord())
return false;
@@ -7654,7 +7702,7 @@ namespace {
// Callback to only accept typo corrections that have a non-zero edit distance.
// Also only accept corrections that have the same parent decl.
-class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
+class DifferentNameValidatorCCC final : public CorrectionCandidateCallback {
public:
DifferentNameValidatorCCC(ASTContext &Context, FunctionDecl *TypoFD,
CXXRecordDecl *Parent)
@@ -7686,6 +7734,10 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<DifferentNameValidatorCCC>(*this);
+ }
+
private:
ASTContext &Context;
FunctionDecl *OriginalFD;
@@ -7733,6 +7785,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
assert(!Prev.isAmbiguous() &&
"Cannot have an ambiguity in previous-declaration lookup");
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
+ DifferentNameValidatorCCC CCC(SemaRef.Context, NewFD,
+ MD ? MD->getParent() : nullptr);
if (!Prev.empty()) {
for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
Func != FuncEnd; ++Func) {
@@ -7749,10 +7803,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
// If the qualified name lookup yielded nothing, try typo correction
} else if ((Correction = SemaRef.CorrectTypo(
Prev.getLookupNameInfo(), Prev.getLookupKind(), S,
- &ExtraArgs.D.getCXXScopeSpec(),
- llvm::make_unique<DifferentNameValidatorCCC>(
- SemaRef.Context, NewFD, MD ? MD->getParent() : nullptr),
- Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) {
+ &ExtraArgs.D.getCXXScopeSpec(), CCC, Sema::CTK_ErrorRecovery,
+ IsLocalFriend ? nullptr : NewDC))) {
// Set up everything for the call to ActOnFunctionDeclarator
ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(),
ExtraArgs.D.getIdentifierLoc());
@@ -8044,8 +8096,7 @@ static bool isOpenCLSizeDependentType(ASTContext &C, QualType Ty) {
QualType DesugaredTy = Ty;
do {
ArrayRef<StringRef> Names(SizeTypeNames);
- auto Match =
- std::find(Names.begin(), Names.end(), DesugaredTy.getAsString());
+ auto Match = llvm::find(Names, DesugaredTy.getAsString());
if (Names.end() != Match)
return true;
@@ -8620,8 +8671,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Complain about the 'static' specifier if it's on an out-of-line
// member function definition.
+
+ // MSVC permits the use of a 'static' storage specifier on an out-of-line
+ // member function template declaration, warn about this.
Diag(D.getDeclSpec().getStorageClassSpecLoc(),
- diag::err_static_out_of_line)
+ NewFD->getDescribedFunctionTemplate() && getLangOpts().MSVCCompat
+ ? diag::ext_static_out_of_line : diag::err_static_out_of_line)
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
}
@@ -9031,8 +9086,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// nothing will diagnose that error later.
if (isFriend &&
(D.getCXXScopeSpec().getScopeRep()->isDependent() ||
- (!Previous.empty() && (TemplateParamLists.size() ||
- CurContext->isDependentContext())))) {
+ (!Previous.empty() && CurContext->isDependentContext()))) {
// ignore these
} else {
// The user tried to provide an out-of-line definition for a
@@ -9137,13 +9191,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (getLangOpts().CUDA) {
IdentifierInfo *II = NewFD->getIdentifier();
- if (II &&
- II->isStr(getLangOpts().HIP ? "hipConfigureCall"
- : "cudaConfigureCall") &&
+ if (II && II->isStr(getCudaConfigureFuncName()) &&
!NewFD->isInvalidDecl() &&
NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
if (!R->getAs<FunctionType>()->getReturnType()->isScalarType())
- Diag(NewFD->getLocation(), diag::err_config_scalar_return);
+ Diag(NewFD->getLocation(), diag::err_config_scalar_return)
+ << getCudaConfigureFuncName();
Context.setcudaConfigureCallDecl(NewFD);
}
@@ -9575,9 +9628,7 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD,
/// Returns true if there was an error, false otherwise.
static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD,
MultiVersionKind MVType,
- const TargetAttr *TA,
- const CPUDispatchAttr *CPUDisp,
- const CPUSpecificAttr *CPUSpec) {
+ const TargetAttr *TA) {
assert(MVType != MultiVersionKind::None &&
"Function lacks multiversion attribute");
@@ -9884,8 +9935,7 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
// multiversioning, this isn't an error condition.
if (MVType == MultiVersionKind::None)
return false;
- return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA, NewCPUDisp,
- NewCPUSpec);
+ return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA);
}
FunctionDecl *OldFD = OldDecl->getAsFunction();
@@ -10017,7 +10067,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
if (!getLangOpts().CPlusPlus14 && MD && MD->isConstexpr() &&
!MD->isStatic() && !isa<CXXConstructorDecl>(MD) &&
- !MD->getTypeQualifiers().hasConst()) {
+ !MD->getMethodQualifiers().hasConst()) {
CXXMethodDecl *OldMD = nullptr;
if (OldDecl)
OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl->getAsFunction());
@@ -10808,7 +10858,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
DeclarationName Name, QualType Type,
TypeSourceInfo *TSI,
SourceRange Range, bool DirectInit,
- Expr *&Init) {
+ Expr *Init) {
bool IsInitCapture = !VDecl;
assert((!VDecl || !VDecl->isInitCapture()) &&
"init captures are expected to be deduced prior to initialization");
@@ -10924,8 +10974,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
<< (DeduceInit->getType().isNull() ? TSI->getType()
: DeduceInit->getType())
<< DeduceInit->getSourceRange();
- } else
- Init = DeduceInit;
+ }
// Warn if we deduced 'id'. 'auto' usually implies type-safety, but using
// 'id' instead of a specific object type prevents most of our usual
@@ -10942,7 +10991,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
}
bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
- Expr *&Init) {
+ Expr *Init) {
QualType DeducedType = deduceVarTypeFromInitializer(
VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
VDecl->getSourceRange(), DirectInit, Init);
@@ -11244,6 +11293,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
<< Culprit->getSourceRange();
}
}
+
+ if (auto *E = dyn_cast<ExprWithCleanups>(Init))
+ if (auto *BE = dyn_cast<BlockExpr>(E->getSubExpr()->IgnoreParens()))
+ if (VDecl->hasLocalStorage())
+ BE->getBlockDecl()->setCanAvoidCopyToHeap();
} else if (VDecl->isStaticDataMember() && !VDecl->isInline() &&
VDecl->getLexicalDeclContext()->isRecord()) {
// This is an in-class initialization for a static data member, e.g.,
@@ -11358,6 +11412,14 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
!isTemplateInstantiation(VDecl->getTemplateSpecializationKind()))
Diag(VDecl->getLocation(), diag::warn_extern_init);
+ // In Microsoft C++ mode, a const variable defined in namespace scope has
+ // external linkage by default if the variable is declared with
+ // __declspec(dllexport).
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ getLangOpts().CPlusPlus && VDecl->getType().isConstQualified() &&
+ VDecl->hasAttr<DLLExportAttr>() && VDecl->getDefinition())
+ VDecl->setStorageClass(SC_Extern);
+
// C99 6.7.8p4. All file scoped initializers need to be constant.
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl())
CheckForConstantInitializer(Init, DclT);
@@ -11448,9 +11510,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
return;
}
- Expr *TmpInit = nullptr;
if (Type->isUndeducedType() &&
- DeduceVariableDeclarationType(Var, false, TmpInit))
+ DeduceVariableDeclarationType(Var, false, nullptr))
return;
// C++11 [class.static.data]p3: A static data member can be declared with
@@ -11627,7 +11688,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
setFunctionHasBranchProtectedScope();
}
}
-
+ // In OpenCL, we can't initialize objects in the __local address space,
+ // even implicitly, so don't synthesize an implicit initializer.
+ if (getLangOpts().OpenCL &&
+ Var->getType().getAddressSpace() == LangAS::opencl_local)
+ return;
// C++03 [dcl.init]p9:
// If no initializer is specified for an object, and the
// object is of (possibly cv-qualified) non-POD class type (or
@@ -11723,7 +11788,6 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
D.SetIdentifier(Ident, IdentLoc);
D.takeAttributes(Attrs, AttrEnd);
- ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/ false),
IdentLoc);
Decl *Var = ActOnDeclarator(S, D);
@@ -12538,9 +12602,13 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
// - otherwise, it's an error
if (T->isArrayType()) {
if (!T.isConstQualified()) {
- DelayedDiagnostics.add(
- sema::DelayedDiagnostic::makeForbiddenType(
- NameLoc, diag::err_arc_array_param_no_ownership, T, false));
+ if (DelayedDiagnostics.shouldDelayDiagnostics())
+ DelayedDiagnostics.add(
+ sema::DelayedDiagnostic::makeForbiddenType(
+ NameLoc, diag::err_arc_array_param_no_ownership, T, false));
+ else
+ Diag(NameLoc, diag::err_arc_array_param_no_ownership)
+ << TSInfo->getTypeLoc().getSourceRange();
}
lifetime = Qualifiers::OCL_ExplicitNone;
} else {
@@ -13092,6 +13160,35 @@ private:
bool IsLambda = false;
};
+static void diagnoseImplicitlyRetainedSelf(Sema &S) {
+ llvm::DenseMap<const BlockDecl *, bool> EscapeInfo;
+
+ auto IsOrNestedInEscapingBlock = [&](const BlockDecl *BD) {
+ if (EscapeInfo.count(BD))
+ return EscapeInfo[BD];
+
+ bool R = false;
+ const BlockDecl *CurBD = BD;
+
+ do {
+ R = !CurBD->doesNotEscape();
+ if (R)
+ break;
+ CurBD = CurBD->getParent()->getInnermostBlockDecl();
+ } while (CurBD);
+
+ return EscapeInfo[BD] = R;
+ };
+
+ // If the location where 'self' is implicitly retained is inside a escaping
+ // block, emit a diagnostic.
+ for (const std::pair<SourceLocation, const BlockDecl *> &P :
+ S.ImplicitlyRetainedSelfLocs)
+ if (IsOrNestedInEscapingBlock(P.second))
+ S.Diag(P.first, diag::warn_implicitly_retains_self)
+ << FixItHint::CreateInsertion(P.first, "self->");
+}
+
Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
bool IsInstantiation) {
FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr;
@@ -13099,7 +13196,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr;
- if (getLangOpts().CoroutinesTS && getCurFunction()->isCoroutine())
+ if (getLangOpts().Coroutines && getCurFunction()->isCoroutine())
CheckCompletedCoroutineBody(FD, Body);
// Do not call PopExpressionEvaluationContext() if it is a lambda because one
@@ -13156,7 +13253,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// MSVC permits the use of pure specifier (=0) on function definition,
// defined at class scope, warn about this non-standard construct.
- if (getLangOpts().MicrosoftExt && FD->isPure() && FD->isCanonicalDecl())
+ if (getLangOpts().MicrosoftExt && FD->isPure() && !FD->isOutOfLine())
Diag(FD->getLocation(), diag::ext_pure_function_definition);
if (!FD->isInvalidDecl()) {
@@ -13256,8 +13353,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
assert(MD == getCurMethodDecl() && "Method parsing confused");
MD->setBody(Body);
if (!MD->isInvalidDecl()) {
- if (!MD->hasSkippedBody())
- DiagnoseUnusedParameters(MD->parameters());
DiagnoseSizeOfParametersAndReturnValue(MD->parameters(),
MD->getReturnType(), MD);
@@ -13303,6 +13398,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
diag::warn_objc_secondary_init_missing_init_call);
getCurFunction()->ObjCWarnForNoInitDelegation = false;
}
+
+ diagnoseImplicitlyRetainedSelf(*this);
} else {
// Parsing the function declaration failed in some way. Pop the fake scope
// we pushed on.
@@ -13484,10 +13581,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
// function declaration is going to be treated as an error.
if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) {
TypoCorrection Corrected;
- if (S &&
- (Corrected = CorrectTypo(
- DeclarationNameInfo(&II, Loc), LookupOrdinaryName, S, nullptr,
- llvm::make_unique<DeclFilterCCC<FunctionDecl>>(), CTK_NonError)))
+ DeclFilterCCC<FunctionDecl> CCC{};
+ if (S && (Corrected =
+ CorrectTypo(DeclarationNameInfo(&II, Loc), LookupOrdinaryName,
+ S, nullptr, CCC, CTK_NonError)))
diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion),
/*ErrorRecovery*/false);
}
@@ -13576,6 +13673,13 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
FD->getLocation()));
}
+ // Handle automatically recognized callbacks.
+ SmallVector<int, 4> Encoding;
+ if (!FD->hasAttr<CallbackAttr>() &&
+ Context.BuiltinInfo.performsCallback(BuiltinID, Encoding))
+ FD->addAttr(CallbackAttr::CreateImplicit(
+ Context, Encoding.data(), Encoding.size(), FD->getLocation()));
+
// Mark const if we don't care about errno and that is the only thing
// preventing the function from being const. This allows IRgen to use LLVM
// intrinsics for such functions.
@@ -14743,8 +14847,7 @@ CreateNewDecl:
// If this is an undefined enum, warn.
if (TUK != TUK_Definition && !Invalid) {
TagDecl *Def;
- if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC) &&
- cast<EnumDecl>(New)->isFixed()) {
+ if (IsFixed && cast<EnumDecl>(New)->isFixed()) {
// C++0x: 7.2p2: opaque-enum-declaration.
// Conflicts are diagnosed above. Do nothing.
}
@@ -15897,6 +16000,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Record->setHasObjectMember(true);
if (Record && FDTTy->getDecl()->hasVolatileMember())
Record->setHasVolatileMember(true);
+ if (Record && Record->isUnion() &&
+ FD->getType().isNonTrivialPrimitiveCType(Context))
+ Diag(FD->getLocation(),
+ diag::err_nontrivial_primitive_type_in_union);
} else if (FDTy->isObjCObjectType()) {
/// A field cannot be an Objective-c object
Diag(FD->getLocation(), diag::err_statically_allocated_object)
@@ -15904,7 +16011,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
} else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
- Record && !ObjCFieldLifetimeErrReported && Record->isUnion()) {
+ Record && !ObjCFieldLifetimeErrReported && Record->isUnion() &&
+ !getLangOpts().CPlusPlus) {
// It's an error in ARC or Weak if a field has lifetime.
// We don't want to report this in a system header, though,
// so we just make the field unavailable.
@@ -16907,390 +17015,6 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
return New;
}
-static void checkModuleImportContext(Sema &S, Module *M,
- SourceLocation ImportLoc, DeclContext *DC,
- bool FromInclude = false) {
- SourceLocation ExternCLoc;
-
- if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
- switch (LSD->getLanguage()) {
- case LinkageSpecDecl::lang_c:
- if (ExternCLoc.isInvalid())
- ExternCLoc = LSD->getBeginLoc();
- break;
- case LinkageSpecDecl::lang_cxx:
- break;
- }
- DC = LSD->getParent();
- }
-
- while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
- DC = DC->getParent();
-
- if (!isa<TranslationUnitDecl>(DC)) {
- S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M))
- ? diag::ext_module_import_not_at_top_level_noop
- : diag::err_module_import_not_at_top_level_fatal)
- << M->getFullModuleName() << DC;
- S.Diag(cast<Decl>(DC)->getBeginLoc(),
- diag::note_module_import_not_at_top_level)
- << DC;
- } else if (!M->IsExternC && ExternCLoc.isValid()) {
- S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)
- << M->getFullModuleName();
- S.Diag(ExternCLoc, diag::note_extern_c_begins_here);
- }
-}
-
-Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
- SourceLocation ModuleLoc,
- ModuleDeclKind MDK,
- ModuleIdPath Path) {
- assert(getLangOpts().ModulesTS &&
- "should only have module decl in modules TS");
-
- // A module implementation unit requires that we are not compiling a module
- // of any kind. A module interface unit requires that we are not compiling a
- // module map.
- switch (getLangOpts().getCompilingModule()) {
- case LangOptions::CMK_None:
- // It's OK to compile a module interface as a normal translation unit.
- break;
-
- case LangOptions::CMK_ModuleInterface:
- if (MDK != ModuleDeclKind::Implementation)
- break;
-
- // We were asked to compile a module interface unit but this is a module
- // implementation unit. That indicates the 'export' is missing.
- Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
- << FixItHint::CreateInsertion(ModuleLoc, "export ");
- MDK = ModuleDeclKind::Interface;
- break;
-
- case LangOptions::CMK_ModuleMap:
- Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
- return nullptr;
-
- case LangOptions::CMK_HeaderModule:
- Diag(ModuleLoc, diag::err_module_decl_in_header_module);
- return nullptr;
- }
-
- assert(ModuleScopes.size() == 1 && "expected to be at global module scope");
-
- // FIXME: Most of this work should be done by the preprocessor rather than
- // here, in order to support macro import.
-
- // Only one module-declaration is permitted per source file.
- if (ModuleScopes.back().Module->Kind == Module::ModuleInterfaceUnit) {
- Diag(ModuleLoc, diag::err_module_redeclaration);
- Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
- diag::note_prev_module_declaration);
- return nullptr;
- }
-
- // Flatten the dots in a module name. Unlike Clang's hierarchical module map
- // modules, the dots here are just another character that can appear in a
- // module name.
- std::string ModuleName;
- for (auto &Piece : Path) {
- if (!ModuleName.empty())
- ModuleName += ".";
- ModuleName += Piece.first->getName();
- }
-
- // If a module name was explicitly specified on the command line, it must be
- // correct.
- if (!getLangOpts().CurrentModule.empty() &&
- getLangOpts().CurrentModule != ModuleName) {
- Diag(Path.front().second, diag::err_current_module_name_mismatch)
- << SourceRange(Path.front().second, Path.back().second)
- << getLangOpts().CurrentModule;
- return nullptr;
- }
- const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
-
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- Module *Mod;
-
- switch (MDK) {
- case ModuleDeclKind::Interface: {
- // We can't have parsed or imported a definition of this module or parsed a
- // module map defining it already.
- if (auto *M = Map.findModule(ModuleName)) {
- Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
- if (M->DefinitionLoc.isValid())
- Diag(M->DefinitionLoc, diag::note_prev_module_definition);
- else if (const auto *FE = M->getASTFile())
- Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
- << FE->getName();
- Mod = M;
- break;
- }
-
- // Create a Module for the module that we're defining.
- Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
- ModuleScopes.front().Module);
- assert(Mod && "module creation should not fail");
- break;
- }
-
- case ModuleDeclKind::Partition:
- // FIXME: Check we are in a submodule of the named module.
- return nullptr;
-
- case ModuleDeclKind::Implementation:
- std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
- PP.getIdentifierInfo(ModuleName), Path[0].second);
- Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc},
- Module::AllVisible,
- /*IsIncludeDirective=*/false);
- if (!Mod) {
- Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
- // Create an empty module interface unit for error recovery.
- Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
- ModuleScopes.front().Module);
- }
- break;
- }
-
- // Switch from the global module to the named module.
- ModuleScopes.back().Module = Mod;
- ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation;
- VisibleModules.setVisible(Mod, ModuleLoc);
-
- // From now on, we have an owning module for all declarations we see.
- // However, those declarations are module-private unless explicitly
- // exported.
- auto *TU = Context.getTranslationUnitDecl();
- TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
- TU->setLocalOwningModule(Mod);
-
- // FIXME: Create a ModuleDecl.
- return nullptr;
-}
-
-DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
- SourceLocation ImportLoc,
- ModuleIdPath Path) {
- // Flatten the module path for a Modules TS module name.
- std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
- if (getLangOpts().ModulesTS) {
- std::string ModuleName;
- for (auto &Piece : Path) {
- if (!ModuleName.empty())
- ModuleName += ".";
- ModuleName += Piece.first->getName();
- }
- ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second};
- Path = ModuleIdPath(ModuleNameLoc);
- }
-
- Module *Mod =
- getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
- /*IsIncludeDirective=*/false);
- if (!Mod)
- return true;
-
- VisibleModules.setVisible(Mod, ImportLoc);
-
- checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
-
- // FIXME: we should support importing a submodule within a different submodule
- // of the same top-level module. Until we do, make it an error rather than
- // silently ignoring the import.
- // Import-from-implementation is valid in the Modules TS. FIXME: Should we
- // warn on a redundant import of the current module?
- if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
- (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS))
- Diag(ImportLoc, getLangOpts().isCompilingModule()
- ? diag::err_module_self_import
- : diag::err_module_import_in_implementation)
- << Mod->getFullModuleName() << getLangOpts().CurrentModule;
-
- SmallVector<SourceLocation, 2> IdentifierLocs;
- Module *ModCheck = Mod;
- for (unsigned I = 0, N = Path.size(); I != N; ++I) {
- // If we've run out of module parents, just drop the remaining identifiers.
- // We need the length to be consistent.
- if (!ModCheck)
- break;
- ModCheck = ModCheck->Parent;
-
- IdentifierLocs.push_back(Path[I].second);
- }
-
- ImportDecl *Import = ImportDecl::Create(Context, CurContext, StartLoc,
- Mod, IdentifierLocs);
- if (!ModuleScopes.empty())
- Context.addModuleInitializer(ModuleScopes.back().Module, Import);
- CurContext->addDecl(Import);
-
- // Re-export the module if needed.
- if (Import->isExported() &&
- !ModuleScopes.empty() && ModuleScopes.back().ModuleInterface)
- getCurrentModule()->Exports.emplace_back(Mod, false);
-
- return Import;
-}
-
-void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
- checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
- BuildModuleInclude(DirectiveLoc, Mod);
-}
-
-void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
- // Determine whether we're in the #include buffer for a module. The #includes
- // in that buffer do not qualify as module imports; they're just an
- // implementation detail of us building the module.
- //
- // FIXME: Should we even get ActOnModuleInclude calls for those?
- bool IsInModuleIncludes =
- TUKind == TU_Module &&
- getSourceManager().isWrittenInMainFile(DirectiveLoc);
-
- bool ShouldAddImport = !IsInModuleIncludes;
-
- // If this module import was due to an inclusion directive, create an
- // implicit import declaration to capture it in the AST.
- if (ShouldAddImport) {
- TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
- ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
- DirectiveLoc, Mod,
- DirectiveLoc);
- if (!ModuleScopes.empty())
- Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
- TU->addDecl(ImportD);
- Consumer.HandleImplicitImportDecl(ImportD);
- }
-
- getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc);
- VisibleModules.setVisible(Mod, DirectiveLoc);
-}
-
-void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
- checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
-
- ModuleScopes.push_back({});
- ModuleScopes.back().Module = Mod;
- if (getLangOpts().ModulesLocalVisibility)
- ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
-
- VisibleModules.setVisible(Mod, DirectiveLoc);
-
- // The enclosing context is now part of this module.
- // FIXME: Consider creating a child DeclContext to hold the entities
- // lexically within the module.
- if (getLangOpts().trackLocalOwningModule()) {
- for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
- cast<Decl>(DC)->setModuleOwnershipKind(
- getLangOpts().ModulesLocalVisibility
- ? Decl::ModuleOwnershipKind::VisibleWhenImported
- : Decl::ModuleOwnershipKind::Visible);
- cast<Decl>(DC)->setLocalOwningModule(Mod);
- }
- }
-}
-
-void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
- if (getLangOpts().ModulesLocalVisibility) {
- VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
- // Leaving a module hides namespace names, so our visible namespace cache
- // is now out of date.
- VisibleNamespaceCache.clear();
- }
-
- assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
- "left the wrong module scope");
- ModuleScopes.pop_back();
-
- // We got to the end of processing a local module. Create an
- // ImportDecl as we would for an imported module.
- FileID File = getSourceManager().getFileID(EomLoc);
- SourceLocation DirectiveLoc;
- if (EomLoc == getSourceManager().getLocForEndOfFile(File)) {
- // We reached the end of a #included module header. Use the #include loc.
- assert(File != getSourceManager().getMainFileID() &&
- "end of submodule in main source file");
- DirectiveLoc = getSourceManager().getIncludeLoc(File);
- } else {
- // We reached an EOM pragma. Use the pragma location.
- DirectiveLoc = EomLoc;
- }
- BuildModuleInclude(DirectiveLoc, Mod);
-
- // Any further declarations are in whatever module we returned to.
- if (getLangOpts().trackLocalOwningModule()) {
- // The parser guarantees that this is the same context that we entered
- // the module within.
- for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
- cast<Decl>(DC)->setLocalOwningModule(getCurrentModule());
- if (!getCurrentModule())
- cast<Decl>(DC)->setModuleOwnershipKind(
- Decl::ModuleOwnershipKind::Unowned);
- }
- }
-}
-
-void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
- Module *Mod) {
- // Bail if we're not allowed to implicitly import a module here.
- if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery ||
- VisibleModules.isVisible(Mod))
- return;
-
- // Create the implicit import declaration.
- TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
- ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
- Loc, Mod, Loc);
- TU->addDecl(ImportD);
- Consumer.HandleImplicitImportDecl(ImportD);
-
- // Make the module visible.
- getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc);
- VisibleModules.setVisible(Mod, Loc);
-}
-
-/// We have parsed the start of an export declaration, including the '{'
-/// (if present).
-Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
- SourceLocation LBraceLoc) {
- ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
-
- // C++ Modules TS draft:
- // An export-declaration shall appear in the purview of a module other than
- // the global module.
- if (ModuleScopes.empty() || !ModuleScopes.back().ModuleInterface)
- Diag(ExportLoc, diag::err_export_not_in_module_interface);
-
- // An export-declaration [...] shall not contain more than one
- // export keyword.
- //
- // The intent here is that an export-declaration cannot appear within another
- // export-declaration.
- if (D->isExported())
- Diag(ExportLoc, diag::err_export_within_export);
-
- CurContext->addDecl(D);
- PushDeclContext(S, D);
- D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
- return D;
-}
-
-/// Complete the definition of an export declaration.
-Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) {
- auto *ED = cast<ExportDecl>(D);
- if (RBraceLoc.isValid())
- ED->setRBraceLoc(RBraceLoc);
-
- // FIXME: Diagnose export of internal-linkage declaration (including
- // anonymous namespace).
-
- PopDeclContext();
- return D;
-}
-
void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
IdentifierInfo* AliasName,
SourceLocation PragmaLoc,