diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/Sema.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/Sema.cpp | 178 |
1 files changed, 116 insertions, 62 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp index 412f944..a18f714 100644 --- a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp @@ -71,42 +71,34 @@ void Sema::ActOnTranslationUnitScope(Scope *S) { } Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, - TranslationUnitKind TUKind, - CodeCompleteConsumer *CodeCompleter) - : ExternalSource(nullptr), - isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()), - LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer), - Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), - CollectStats(false), CodeCompleter(CodeCompleter), - CurContext(nullptr), OriginalLexicalContext(nullptr), - MSStructPragmaOn(false), - MSPointerToMemberRepresentationMethod( - LangOpts.getMSPointerToMemberRepresentationMethod()), - VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), - PackStack(0), DataSegStack(nullptr), BSSSegStack(nullptr), - ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr), - VisContext(nullptr), - IsBuildingRecoveryCallExpr(false), - Cleanup{}, LateTemplateParser(nullptr), - LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), - StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr), - CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr), - NSNumberDecl(nullptr), NSValueDecl(nullptr), - NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr), - ValueWithBytesObjCTypeMethod(nullptr), - NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr), - NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr), - GlobalNewDeleteDeclared(false), - TUKind(TUKind), - NumSFINAEErrors(0), - CachedFakeTopLevelModule(nullptr), - AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), - NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), - CurrentInstantiationScope(nullptr), DisableTypoCorrection(false), - TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr), - VarDataSharingAttributesStack(nullptr), CurScope(nullptr), - Ident_super(nullptr), Ident___float128(nullptr) -{ + TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter) + : ExternalSource(nullptr), isMultiplexExternalSource(false), + FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp), + Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()), + SourceMgr(PP.getSourceManager()), CollectStats(false), + CodeCompleter(CodeCompleter), CurContext(nullptr), + OriginalLexicalContext(nullptr), MSStructPragmaOn(false), + MSPointerToMemberRepresentationMethod( + LangOpts.getMSPointerToMemberRepresentationMethod()), + VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), PackStack(0), + DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr), + CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr), + PragmaAttributeCurrentTargetDecl(nullptr), + IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr), + LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), + StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr), + CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr), NSNumberDecl(nullptr), + NSValueDecl(nullptr), NSStringDecl(nullptr), + StringWithUTF8StringMethod(nullptr), + ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), + ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), + DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false), + TUKind(TUKind), NumSFINAEErrors(0), AccessCheckingSFINAE(false), + InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), + ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(nullptr), + DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this), + ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr), + CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) { TUScope = nullptr; LoadedExternalKnownNamespaces = false; @@ -122,8 +114,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, // Tell diagnostics how to render things from the AST library. Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context); - ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, CleanupInfo{}, nullptr, - false); + ExprEvalContexts.emplace_back( + ExpressionEvaluationContext::PotentiallyEvaluated, 0, CleanupInfo{}, + nullptr, false); FunctionScopes.push_back(new FunctionScopeInfo(Diags)); @@ -217,7 +210,6 @@ void Sema::Initialize() { if (getLangOpts().OpenCLVersion >= 200) { addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); addImplicitTypedef("queue_t", Context.OCLQueueTy); - addImplicitTypedef("ndrange_t", Context.OCLNDRangeTy); addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy); addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); addImplicitTypedef("atomic_uint", @@ -328,7 +320,7 @@ bool Sema::makeUnavailableInSystemHeader(SourceLocation loc, if (!fn) return false; // If we're in template instantiation, it's an error. - if (!ActiveTemplateInstantiations.empty()) + if (inTemplateInstantiation()) return false; // If that function's not in a system header, it's an error. @@ -390,6 +382,19 @@ void Sema::diagnoseNullableToNonnullConversion(QualType DstType, Diag(Loc, diag::warn_nullability_lost) << SrcType << DstType; } +void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr* E) { + if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer) + return; + if (E->getType()->isNullPtrType()) + return; + // nullptr only exists from C++11 on, so don't warn on its absence earlier. + if (!getLangOpts().CPlusPlus11) + return; + + Diag(E->getLocStart(), diag::warn_zero_as_null_pointer_constant) + << FixItHint::CreateReplacement(E->getSourceRange(), "nullptr"); +} + /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast. /// If there is already an implicit cast, merge into the existing one. /// The result is of the given category. @@ -414,6 +419,7 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty, #endif diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getLocStart()); + diagnoseZeroToNullptrConversion(Kind, E); QualType ExprTy = Context.getCanonicalType(E->getType()); QualType TypeTy = Context.getCanonicalType(Ty); @@ -470,6 +476,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) { return true; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + // If this is a function template and none of its specializations is used, + // we should warn. + if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate()) + for (const auto *Spec : Template->specializations()) + if (ShouldRemoveFromUnused(SemaRef, Spec)) + return true; + // UnusedFileScopedDecls stores the first declaration. // The declaration may have become definition so check again. const FunctionDecl *DeclToCheck; @@ -493,6 +506,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) { VD->isUsableInConstantExpressions(SemaRef->Context)) return true; + if (VarTemplateDecl *Template = VD->getDescribedVarTemplate()) + // If this is a variable template and none of its specializations is used, + // we should warn. + for (const auto *Spec : Template->specializations()) + if (ShouldRemoveFromUnused(SemaRef, Spec)) + return true; + // UnusedFileScopedDecls stores the first declaration. // The declaration may have become definition so check again. const VarDecl *DeclToCheck = VD->getDefinition(); @@ -522,6 +542,9 @@ void Sema::getUndefinedButUsed( // __attribute__((weakref)) is basically a definition. if (ND->hasAttr<WeakRefAttr>()) continue; + if (isa<CXXDeductionGuideDecl>(ND)) + continue; + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { if (FD->isDefined()) continue; @@ -685,6 +708,18 @@ void Sema::emitAndClearUnusedLocalTypedefWarnings() { UnusedLocalTypedefNameCandidates.clear(); } +/// This is called before the very first declaration in the translation unit +/// is parsed. Note that the ASTContext may have already injected some +/// declarations. +void Sema::ActOnStartOfTranslationUnit() { + if (getLangOpts().ModulesTS) { + // We start in the global module; all those declarations are implicitly + // module-private (though they do not have module linkage). + Context.getTranslationUnitDecl()->setModuleOwnershipKind( + Decl::ModuleOwnershipKind::ModulePrivate); + } +} + /// ActOnEndOfTranslationUnit - This is called at the very end of the /// translation unit when EOF is reached and all but the top-level scope is /// popped. @@ -720,6 +755,9 @@ void Sema::ActOnEndOfTranslationUnit() { // Load pending instantiations from the external source. SmallVector<PendingImplicitInstantiation, 4> Pending; ExternalSource->ReadPendingInstantiations(Pending); + for (auto PII : Pending) + if (auto Func = dyn_cast<FunctionDecl>(PII.first)) + Func->setInstantiationIsPending(true); PendingInstantiations.insert(PendingInstantiations.begin(), Pending.begin(), Pending.end()); } @@ -731,6 +769,8 @@ void Sema::ActOnEndOfTranslationUnit() { CheckDelayedMemberExceptionSpecs(); } + DiagnoseUnterminatedPragmaAttribute(); + // All delayed member exception specs should be checked or we end up accepting // incompatible declarations. // FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to @@ -745,7 +785,9 @@ void Sema::ActOnEndOfTranslationUnit() { UnusedFileScopedDecls.erase( std::remove_if(UnusedFileScopedDecls.begin(nullptr, true), UnusedFileScopedDecls.end(), - std::bind1st(std::ptr_fun(ShouldRemoveFromUnused), this)), + [this](const DeclaratorDecl *DD) { + return ShouldRemoveFromUnused(this, DD); + }), UnusedFileScopedDecls.end()); if (TUKind == TU_Prefix) { @@ -811,7 +853,8 @@ void Sema::ActOnEndOfTranslationUnit() { emitAndClearUnusedLocalTypedefWarnings(); // Modules don't need any of the checking below. - TUScope = nullptr; + if (!PP.isIncrementalProcessingEnabled()) + TUScope = nullptr; return; } @@ -894,10 +937,14 @@ void Sema::ActOnEndOfTranslationUnit() { << /*function*/0 << DiagD->getDeclName(); } } else { - Diag(DiagD->getLocation(), - isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function - : diag::warn_unused_function) - << DiagD->getDeclName(); + if (FD->getDescribedFunctionTemplate()) + Diag(DiagD->getLocation(), diag::warn_unused_template) + << /*function*/0 << DiagD->getDeclName(); + else + Diag(DiagD->getLocation(), + isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function + : diag::warn_unused_function) + << DiagD->getDeclName(); } } else { const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition(); @@ -913,7 +960,11 @@ void Sema::ActOnEndOfTranslationUnit() { Diag(DiagD->getLocation(), diag::warn_unused_const_variable) << DiagD->getDeclName(); } else { - Diag(DiagD->getLocation(), diag::warn_unused_variable) + if (DiagD->getDescribedVarTemplate()) + Diag(DiagD->getLocation(), diag::warn_unused_template) + << /*variable*/1 << DiagD->getDeclName(); + else + Diag(DiagD->getLocation(), diag::warn_unused_variable) << DiagD->getDeclName(); } } @@ -1007,7 +1058,7 @@ void Sema::EmitCurrentDiagnostic(unsigned DiagID) { // and yet we also use the current diag ID on the DiagnosticsEngine. This has // been made more painfully obvious by the refactor that introduced this // function, but it is possible that the incoming argument can be - // eliminnated. If it truly cannot be (for example, there is some reentrancy + // eliminated. If it truly cannot be (for example, there is some reentrancy // issue I am not seeing yet), then there should at least be a clarifying // comment somewhere. if (Optional<TemplateDeductionInfo*> Info = isSFINAEContext()) { @@ -1095,13 +1146,8 @@ void Sema::EmitCurrentDiagnostic(unsigned DiagID) { // that is different from the last template instantiation where // we emitted an error, print a template instantiation // backtrace. - if (!DiagnosticIDs::isBuiltinNote(DiagID) && - !ActiveTemplateInstantiations.empty() && - ActiveTemplateInstantiations.back() - != LastTemplateInstantiationErrorContext) { - PrintInstantiationStack(); - LastTemplateInstantiationErrorContext = ActiveTemplateInstantiations.back(); - } + if (!DiagnosticIDs::isBuiltinNote(DiagID)) + PrintContextStack(); } Sema::SemaDiagnosticBuilder @@ -1169,10 +1215,14 @@ void Sema::PushFunctionScope() { // memory for a new scope. FunctionScopes.back()->Clear(); FunctionScopes.push_back(FunctionScopes.back()); + if (LangOpts.OpenMP) + pushOpenMPFunctionRegion(); return; } FunctionScopes.push_back(new FunctionScopeInfo(getDiagnostics())); + if (LangOpts.OpenMP) + pushOpenMPFunctionRegion(); } void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) { @@ -1200,6 +1250,9 @@ void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP, FunctionScopeInfo *Scope = FunctionScopes.pop_back_val(); assert(!FunctionScopes.empty() && "mismatched push/pop!"); + if (LangOpts.OpenMP) + popOpenMPFunctionRegion(Scope); + // Issue any analysis-based warnings. if (WP && D) AnalysisWarnings.IssueWarnings(*WP, Scope, D, blkExpr); @@ -1236,21 +1289,21 @@ BlockScopeInfo *Sema::getCurBlock() { if (CurBSI && CurBSI->TheDecl && !CurBSI->TheDecl->Encloses(CurContext)) { // We have switched contexts due to template instantiation. - assert(!ActiveTemplateInstantiations.empty()); + assert(!CodeSynthesisContexts.empty()); return nullptr; } return CurBSI; } -LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) { +LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) { if (FunctionScopes.empty()) return nullptr; auto I = FunctionScopes.rbegin(); - if (IgnoreCapturedRegions) { + if (IgnoreNonLambdaCapturingScope) { auto E = FunctionScopes.rend(); - while (I != E && isa<CapturedRegionScopeInfo>(*I)) + while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I)) ++I; if (I == E) return nullptr; @@ -1259,7 +1312,7 @@ LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) { if (CurLSI && CurLSI->Lambda && !CurLSI->Lambda->Encloses(CurContext)) { // We have switched contexts due to template instantiation. - assert(!ActiveTemplateInstantiations.empty()); + assert(!CodeSynthesisContexts.empty()); return nullptr; } @@ -1651,7 +1704,8 @@ bool Sema::checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType QT) { QT, OpenCLTypeExtMap); } -bool Sema::checkOpenCLDisabledDecl(const Decl &D, const Expr &E) { - return checkOpenCLDisabledTypeOrDecl(&D, E.getLocStart(), "", +bool Sema::checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E) { + IdentifierInfo *FnName = D.getIdentifier(); + return checkOpenCLDisabledTypeOrDecl(&D, E.getLocStart(), FnName, OpenCLDeclExtMap, 1, D.getSourceRange()); } |