diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/CodeCompleteConsumer.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/JumpDiagnostics.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 51 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 60 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 37 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 38 |
17 files changed, 177 insertions, 69 deletions
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 542b65327b7d..3431ddcf70a2 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -562,7 +562,7 @@ void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { // Do nothing: Patterns can come with cursor kinds! break; } - // Fall through + LLVM_FALLTHROUGH; case RK_Declaration: { // Set the availability based on attributes. diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 865aea9e2284..64fa2c34b238 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -323,7 +323,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, BuildScopeInformation(Var, ParentScope); ++StmtsToSkip; } - // Fall through + LLVM_FALLTHROUGH; case Stmt::GotoStmtClass: // Remember both what scope a goto is in as well as the fact that we have diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 94070bb9c9aa..803f87b3c568 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2278,7 +2278,7 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { default: return false; case X86::BI_mm_prefetch: - i = 1; l = 0; u = 3; + i = 1; l = 0; u = 7; break; case X86::BI__builtin_ia32_sha1rnds4: case X86::BI__builtin_ia32_shuf_f32x4_256_mask: @@ -3020,7 +3020,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, case AtomicExpr::AO__atomic_add_fetch: case AtomicExpr::AO__atomic_sub_fetch: IsAddSub = true; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_xor: @@ -8487,7 +8487,7 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth) { return IntRange(R.Width, /*NonNegative*/ true); } } - // fallthrough + LLVM_FALLTHROUGH; case BO_ShlAssign: return IntRange::forValueOfType(C, GetExprType(E)); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 834e149d1af4..9aed178763dc 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -1420,7 +1420,7 @@ static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, Results.AddResult(Result("mutable")); Results.AddResult(Result("virtual")); } - // Fall through + LLVM_FALLTHROUGH; case Sema::PCC_ObjCInterface: case Sema::PCC_ObjCImplementation: @@ -1638,7 +1638,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, AddObjCTopLevelResults(Results, true); AddTypedefResult(Results); - // Fall through + LLVM_FALLTHROUGH; case Sema::PCC_Class: if (SemaRef.getLangOpts().CPlusPlus) { @@ -1688,7 +1688,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Results.AddResult(Result(Builder.TakeString())); } } - // Fall through + LLVM_FALLTHROUGH; case Sema::PCC_Template: case Sema::PCC_MemberTemplate: diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ec5ca6973568..a1fc725f8df4 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -10671,7 +10671,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { // that has an in-class initializer, so we type-check this like // a declaration. // - // Fall through + LLVM_FALLTHROUGH; case VarDecl::DeclarationOnly: // It's only a declaration. @@ -12179,9 +12179,11 @@ bool Sema::canSkipFunctionBody(Decl *D) { } Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { - if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Decl)) + if (!Decl) + return nullptr; + if (FunctionDecl *FD = Decl->getAsFunction()) FD->setHasSkippedBody(); - else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Decl)) + else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(Decl)) MD->setHasSkippedBody(); return Decl; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 676d00357c96..21fe46ad9dd1 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1844,12 +1844,6 @@ static void handleIFuncAttr(Sema &S, Decl *D, const AttributeList &Attr) { S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD << 1; return; } - // FIXME: it should be handled as a target specific attribute. - if (S.Context.getTargetInfo().getTriple().getObjectFormat() != - llvm::Triple::ELF) { - S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); - return; - } D->addAttr(::new (S.Context) IFuncAttr(Attr.getRange(), S.Context, Str, Attr.getAttributeSpellingListIndex())); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 96472a0a70fe..f2fb95c39163 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8157,7 +8157,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, PastFunctionChunk = true; break; } - // Fall through. + LLVM_FALLTHROUGH; case DeclaratorChunk::Array: NeedsTypedef = true; extendRight(After, Chunk.getSourceRange()); @@ -12352,7 +12352,7 @@ static bool hasOneRealArgument(MultiExprArg Args) { if (!Args[1]->isDefaultArgument()) return false; - // fall through + LLVM_FALLTHROUGH; case 1: return !Args[0]->isDefaultArgument(); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 929806ac6bfa..4746355e9800 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -817,7 +817,7 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { E->getLocStart(), nullptr, PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) << Ty << CT); - // Fall through. + LLVM_FALLTHROUGH; case VAK_Valid: if (Ty->isRecordType()) { // This is unlikely to be what the user intended. If the class has a @@ -2881,7 +2881,7 @@ ExprResult Sema::BuildDeclarationNameExpr( valueKind = VK_RValue; break; } - // fallthrough + LLVM_FALLTHROUGH; case Decl::ImplicitParam: case Decl::ParmVar: { @@ -2978,7 +2978,7 @@ ExprResult Sema::BuildDeclarationNameExpr( valueKind = VK_LValue; break; } - // fallthrough + LLVM_FALLTHROUGH; case Decl::CXXConversion: case Decl::CXXDestructor: diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 03ddcc0a3eca..dd516ea3b428 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -251,7 +251,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, case IMA_Field_Uneval_Context: Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use) << R.getLookupNameInfo().getName(); - // Fall through. + LLVM_FALLTHROUGH; case IMA_Static: case IMA_Abstract: case IMA_Mixed_StaticContext: diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 6ed5047c35da..cd0c2c47ae4c 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -2981,6 +2981,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, case OMF_init: if (Method) checkInitMethod(Method, ReceiverType); + break; case OMF_None: case OMF_alloc: diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index e4789cdf53bf..011051da58e5 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6212,7 +6212,7 @@ static const InitializedEntity *getEntityForTemporaryLifetimeExtension( if (Entity->getParent()) return getEntityForTemporaryLifetimeExtension(Entity->getParent(), Entity); - // Fall through. + LLVM_FALLTHROUGH; case InitializedEntity::EK_Delegating: // We can reach this case for aggregate initialization in a constructor: // struct A { int &&r; }; @@ -7656,7 +7656,7 @@ bool InitializationSequence::Diagnose(Sema &S, << Args[0]->getSourceRange(); break; } - // Intentional fallthrough + LLVM_FALLTHROUGH; case FK_NonConstLValueReferenceBindingToUnrelated: S.Diag(Kind.getLocation(), diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index b34bb3388d71..0880b2d79060 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1290,9 +1290,14 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { } if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { - IsByRef = !DSAStack->hasExplicitDSA( - D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, - Level, /*NotLastprivate=*/true); + IsByRef = + !DSAStack->hasExplicitDSA( + D, + [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, + Level, /*NotLastprivate=*/true) && + // If the variable is artificial and must be captured by value - try to + // capture by value. + !(isa<OMPCapturedExprDecl>(D) && D->hasAttr<OMPCaptureKindAttr>()); } // When passing data by copy, we need to make sure it fits the uintptr size @@ -2321,10 +2326,11 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, ASTContext &C = S.getASTContext(); Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); QualType Ty = Init->getType(); + Attr *OMPCaptureKind = nullptr; if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { - if (S.getLangOpts().CPlusPlus) + if (S.getLangOpts().CPlusPlus) { Ty = C.getLValueReferenceType(Ty); - else { + } else { Ty = C.getPointerType(Ty); ExprResult Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); @@ -2333,11 +2339,16 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, Init = Res.get(); } WithInit = true; + } else if (AsExpression) { + // This variable must be captured by value. + OMPCaptureKind = OMPCaptureKindAttr::CreateImplicit(C, OMPC_unknown); } auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, CaptureExpr->getLocStart()); if (!WithInit) CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); + if (OMPCaptureKind) + CED->addAttr(OMPCaptureKind); S.CurContext->addHiddenDecl(CED); S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); return CED; @@ -2346,31 +2357,34 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit) { OMPCapturedExprDecl *CD; - if (auto *VD = S.IsOpenMPCapturedDecl(D)) + if (auto *VD = S.IsOpenMPCapturedDecl(D)) { CD = cast<OMPCapturedExprDecl>(VD); - else + } else { CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, /*AsExpression=*/false); + } return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), CaptureExpr->getExprLoc()); } static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { + CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); if (!Ref) { - auto *CD = - buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), - CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); + OMPCapturedExprDecl *CD = buildCaptureDecl( + S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, + /*WithInit=*/true, /*AsExpression=*/true); Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), CaptureExpr->getExprLoc()); } ExprResult Res = Ref; if (!S.getLangOpts().CPlusPlus && CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && - Ref->getType()->isPointerType()) + Ref->getType()->isPointerType()) { Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); - if (!Res.isUsable()) - return ExprError(); - return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); + if (!Res.isUsable()) + return ExprError(); + } + return S.DefaultLvalueConversion(Res.get()); } namespace { @@ -8117,12 +8131,13 @@ OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, if (Val.isInvalid()) return nullptr; - ValExpr = MakeFullExpr(Val.get()).get(); + ValExpr = Val.get(); OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -8239,6 +8254,7 @@ OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -8666,6 +8682,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( DSAStack->getCurrentDirective(), OMPC_schedule) != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -11355,6 +11372,7 @@ OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_device); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -12378,6 +12396,7 @@ OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -12404,6 +12423,7 @@ OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -12514,6 +12534,7 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause( DSAStack->getCurrentDirective(), OMPC_dist_schedule) != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector<Expr *, DeclRefExpr *> Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 268be9430a56..2144845f4dd3 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5790,7 +5790,7 @@ ExprResult Sema::PerformContextualImplicitConversion( HadMultipleCandidates, ExplicitConversions)) return ExprError(); - // fall through 'OR_Deleted' case. + LLVM_FALLTHROUGH; case OR_Deleted: // We'll complain below about a non-integral condition type. break; @@ -8651,7 +8651,7 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_Plus: // '+' is either unary or binary if (Args.size() == 1) OpBuilder.addUnaryPlusPointerOverloads(); - // Fall through. + LLVM_FALLTHROUGH; case OO_Minus: // '-' is either unary or binary if (Args.size() == 1) { @@ -8682,7 +8682,7 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_EqualEqual: case OO_ExclaimEqual: OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads(); - // Fall through. + LLVM_FALLTHROUGH; case OO_Less: case OO_Greater: @@ -8719,12 +8719,12 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_Equal: OpBuilder.addAssignmentMemberPointerOrEnumeralOverloads(); - // Fall through. + LLVM_FALLTHROUGH; case OO_PlusEqual: case OO_MinusEqual: OpBuilder.addAssignmentPointerOverloads(Op == OO_Equal); - // Fall through. + LLVM_FALLTHROUGH; case OO_StarEqual: case OO_SlashEqual: diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c70a8ba8f126..d94cb0d0f485 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -792,7 +792,7 @@ static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S, /// ParamNameLoc is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. -Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, +NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename, SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, @@ -922,13 +922,67 @@ QualType Sema::CheckNonTypeTemplateParameterType(QualType T, return QualType(); } -Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, +NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, unsigned Depth, unsigned Position, SourceLocation EqualLoc, Expr *Default) { TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); + // Check that we have valid decl-specifiers specified. + auto CheckValidDeclSpecifiers = [this, &D] { + // C++ [temp.param] + // p1 + // template-parameter:
+ // ...
+ // parameter-declaration
+ // p2 + // ... A storage class shall not be specified in a template-parameter + // declaration. + // [dcl.typedef]p1: + // The typedef specifier [...] shall not be used in the decl-specifier-seq + // of a parameter-declaration + const DeclSpec &DS = D.getDeclSpec(); + auto EmitDiag = [this](SourceLocation Loc) { + Diag(Loc, diag::err_invalid_decl_specifier_in_nontype_parm) + << FixItHint::CreateRemoval(Loc); + }; + if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) + EmitDiag(DS.getStorageClassSpecLoc()); + + if (DS.getThreadStorageClassSpec() != TSCS_unspecified) + EmitDiag(DS.getThreadStorageClassSpecLoc()); + + // [dcl.inline]p1: + // The inline specifier can be applied only to the declaration or + // definition of a variable or function. + + if (DS.isInlineSpecified()) + EmitDiag(DS.getInlineSpecLoc()); + + // [dcl.constexpr]p1: + // The constexpr specifier shall be applied only to the definition of a + // variable or variable template or the declaration of a function or + // function template. + + if (DS.isConstexprSpecified()) + EmitDiag(DS.getConstexprSpecLoc()); + + // [dcl.fct.spec]p1: + // Function-specifiers can be used only in function declarations. + + if (DS.isVirtualSpecified()) + EmitDiag(DS.getVirtualSpecLoc()); + + if (DS.isExplicitSpecified()) + EmitDiag(DS.getExplicitSpecLoc()); + + if (DS.isNoreturnSpecified()) + EmitDiag(DS.getNoreturnSpecLoc()); + }; + + CheckValidDeclSpecifiers(); + if (TInfo->getType()->isUndeducedType()) { Diag(D.getIdentifierLoc(), diag::warn_cxx14_compat_template_nontype_parm_auto_type) @@ -999,7 +1053,7 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, /// ActOnTemplateTemplateParameter - Called when a C++ template template /// parameter (e.g. T in template <template \<typename> class T> class array) /// has been parsed. S is the current scope. -Decl *Sema::ActOnTemplateTemplateParameter(Scope* S, +NamedDecl *Sema::ActOnTemplateTemplateParameter(Scope* S, SourceLocation TmpLoc, TemplateParameterList *Params, SourceLocation EllipsisLoc, diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 564692b03020..f8ee60251698 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -5324,7 +5324,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, case Type::InjectedClassName: T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType(); - // fall through + LLVM_FALLTHROUGH; case Type::TemplateSpecialization: { const TemplateSpecializationType *Spec @@ -5431,6 +5431,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, MarkUsedTemplateParameters(Ctx, cast<DeducedType>(T)->getDeducedType(), OnlyDeduced, Depth, Used); + break; // None of these types have any template parameters in them. case Type::Builtin: diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f627f6017f38..1deb8638756b 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1587,9 +1587,10 @@ static QualType adjustFunctionTypeForInstantiation(ASTContext &Context, } /// Normal class members are of more specific types and therefore -/// don't make it here. This function serves two purposes: +/// don't make it here. This function serves three purposes: /// 1) instantiating function templates /// 2) substituting friend declarations +/// 3) substituting deduction guide declarations for nested class templates Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams) { // Check whether there is already a function template specialization for @@ -1650,16 +1651,19 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateArgs); } + DeclarationNameInfo NameInfo + = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); + FunctionDecl *Function; if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) { Function = CXXDeductionGuideDecl::Create( SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), - D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); + NameInfo, T, TInfo, D->getSourceRange().getEnd()); if (DGuide->isCopyDeductionCandidate()) cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate(); } else { Function = FunctionDecl::Create( - SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, + SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), D->hasWrittenPrototype(), D->isConstexpr()); Function->setRangeEnd(D->getSourceRange().getEnd()); @@ -3855,7 +3859,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } // Note, we should never try to instantiate a deleted function template. - assert((Pattern || PatternDecl->isDefaulted()) && + assert((Pattern || PatternDecl->isDefaulted() || + PatternDecl->hasSkippedBody()) && "unexpected kind of function template definition"); // C++1y [temp.explicit]p10: @@ -3940,16 +3945,20 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } } - // Instantiate the function body. - StmtResult Body = SubstStmt(Pattern, TemplateArgs); + if (PatternDecl->hasSkippedBody()) { + ActOnSkippedFunctionBody(Function); + } else { + // Instantiate the function body. + StmtResult Body = SubstStmt(Pattern, TemplateArgs); - if (Body.isInvalid()) - Function->setInvalidDecl(); + if (Body.isInvalid()) + Function->setInvalidDecl(); - // FIXME: finishing the function body while in an expression evaluation - // context seems wrong. Investigate more. - ActOnFinishFunctionBody(Function, Body.get(), - /*IsInstantiation=*/true); + // FIXME: finishing the function body while in an expression evaluation + // context seems wrong. Investigate more. + ActOnFinishFunctionBody(Function, Body.get(), + /*IsInstantiation=*/true); + } PerformDependentDiagnostics(PatternDecl, TemplateArgs); @@ -5195,7 +5204,9 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) { case TSK_ExplicitInstantiationDefinition: // We only need an instantiation if the pending instantiation *is* the // explicit instantiation. - if (Var != Var->getMostRecentDecl()) continue; + if (Var != Var->getMostRecentDecl()) + continue; + break; case TSK_ImplicitInstantiation: break; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 2fffe8e17970..2530b766f5f7 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -367,7 +367,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator, if (onlyBlockPointers) continue; - // fallthrough + LLVM_FALLTHROUGH; case DeclaratorChunk::BlockPointer: result = &ptrChunk; @@ -1340,7 +1340,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { } } - // FALL THROUGH. + LLVM_FALLTHROUGH; case DeclSpec::TST_int: { if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) { switch (DS.getTypeSpecWidth()) { @@ -3137,10 +3137,15 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) { (T->isRecordType() || T->isDependentType()) && D.getDeclSpec().getTypeQualifiers() == 0 && D.isFirstDeclarator(); + bool StartsWithDeclaratorId = true; for (auto &C : D.type_objects()) { switch (C.Kind) { - case DeclaratorChunk::Pointer: case DeclaratorChunk::Paren: + if (&C == &Paren) + continue; + LLVM_FALLTHROUGH; + case DeclaratorChunk::Pointer: + StartsWithDeclaratorId = false; continue; case DeclaratorChunk::Array: @@ -3154,18 +3159,25 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) { // We assume that something like 'T (&x) = y;' is highly likely to not // be intended to be a temporary object. CouldBeTemporaryObject = false; + StartsWithDeclaratorId = false; continue; case DeclaratorChunk::Function: // In a new-type-id, function chunks require parentheses. if (D.getContext() == Declarator::CXXNewContext) return; - LLVM_FALLTHROUGH; + // FIXME: "A(f())" deserves a vexing-parse warning, not just a + // redundant-parens warning, but we don't know whether the function + // chunk was syntactically valid as an expression here. + CouldBeTemporaryObject = false; + continue; + case DeclaratorChunk::BlockPointer: case DeclaratorChunk::MemberPointer: case DeclaratorChunk::Pipe: // These cannot appear in expressions. CouldBeTemporaryObject = false; + StartsWithDeclaratorId = false; continue; } } @@ -3186,6 +3198,18 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) { SourceRange ParenRange(Paren.Loc, Paren.EndLoc); if (!CouldBeTemporaryObject) { + // If we have A (::B), the parentheses affect the meaning of the program. + // Suppress the warning in that case. Don't bother looking at the DeclSpec + // here: even (e.g.) "int ::x" is visually ambiguous even though it's + // formally unambiguous. + if (StartsWithDeclaratorId && D.getCXXScopeSpec().isValid()) { + for (NestedNameSpecifier *NNS = D.getCXXScopeSpec().getScopeRep(); NNS; + NNS = NNS->getPrefix()) { + if (NNS->getKind() == NestedNameSpecifier::Global) + return; + } + } + S.Diag(Paren.Loc, diag::warn_redundant_parens_around_declarator) << ParenRange << FixItHint::CreateRemoval(Paren.Loc) << FixItHint::CreateRemoval(Paren.EndLoc); @@ -3890,7 +3914,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, case Declarator::PrototypeContext: case Declarator::TrailingReturnContext: isFunctionOrMethod = true; - // fallthrough + LLVM_FALLTHROUGH; case Declarator::MemberContext: if (state.getDeclarator().isObjCIvar() && !isFunctionOrMethod) { @@ -3904,7 +3928,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, break; } - // fallthrough + LLVM_FALLTHROUGH; case Declarator::FileContext: case Declarator::KNRTypeListContext: { @@ -4063,7 +4087,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, case CAMN_InnerPointers: if (NumPointersRemaining == 0) break; - // Fallthrough. + LLVM_FALLTHROUGH; case CAMN_Yes: checkNullabilityConsistency(S, pointerKind, pointerLoc, pointerEndLoc); |