10b57cec5SDimitry Andric //===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the actions class which performs semantic analysis and
100b57cec5SDimitry Andric // builds an AST out of a parse stream.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
145ffd83dbSDimitry Andric #include "UsedDeclVisitor.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTDiagnostic.h"
17d409305fSDimitry Andric #include "clang/AST/Decl.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclFriend.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
210b57cec5SDimitry Andric #include "clang/AST/Expr.h"
220b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
230b57cec5SDimitry Andric #include "clang/AST/PrettyDeclStackTrace.h"
240b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h"
25fe6060f1SDimitry Andric #include "clang/Basic/DarwinSDKInfo.h"
260b57cec5SDimitry Andric #include "clang/Basic/DiagnosticOptions.h"
270b57cec5SDimitry Andric #include "clang/Basic/PartialDiagnostic.h"
285ffd83dbSDimitry Andric #include "clang/Basic/SourceManager.h"
29a7dea167SDimitry Andric #include "clang/Basic/Stack.h"
300b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
310b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h"
32fe6060f1SDimitry Andric #include "clang/Lex/HeaderSearchOptions.h"
330b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
340b57cec5SDimitry Andric #include "clang/Sema/CXXFieldCollector.h"
350b57cec5SDimitry Andric #include "clang/Sema/DelayedDiagnostic.h"
3606c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h"
370b57cec5SDimitry Andric #include "clang/Sema/ExternalSemaSource.h"
380b57cec5SDimitry Andric #include "clang/Sema/Initialization.h"
390b57cec5SDimitry Andric #include "clang/Sema/MultiplexExternalSemaSource.h"
400b57cec5SDimitry Andric #include "clang/Sema/ObjCMethodList.h"
41972a253aSDimitry Andric #include "clang/Sema/RISCVIntrinsicManager.h"
420b57cec5SDimitry Andric #include "clang/Sema/Scope.h"
430b57cec5SDimitry Andric #include "clang/Sema/ScopeInfo.h"
44*0fca6ea1SDimitry Andric #include "clang/Sema/SemaAMDGPU.h"
45*0fca6ea1SDimitry Andric #include "clang/Sema/SemaARM.h"
46*0fca6ea1SDimitry Andric #include "clang/Sema/SemaAVR.h"
47*0fca6ea1SDimitry Andric #include "clang/Sema/SemaBPF.h"
48*0fca6ea1SDimitry Andric #include "clang/Sema/SemaCUDA.h"
49*0fca6ea1SDimitry Andric #include "clang/Sema/SemaCodeCompletion.h"
500b57cec5SDimitry Andric #include "clang/Sema/SemaConsumer.h"
51*0fca6ea1SDimitry Andric #include "clang/Sema/SemaHLSL.h"
52*0fca6ea1SDimitry Andric #include "clang/Sema/SemaHexagon.h"
530b57cec5SDimitry Andric #include "clang/Sema/SemaInternal.h"
54*0fca6ea1SDimitry Andric #include "clang/Sema/SemaLoongArch.h"
55*0fca6ea1SDimitry Andric #include "clang/Sema/SemaM68k.h"
56*0fca6ea1SDimitry Andric #include "clang/Sema/SemaMIPS.h"
57*0fca6ea1SDimitry Andric #include "clang/Sema/SemaMSP430.h"
58*0fca6ea1SDimitry Andric #include "clang/Sema/SemaNVPTX.h"
59*0fca6ea1SDimitry Andric #include "clang/Sema/SemaObjC.h"
60*0fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenACC.h"
61*0fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenCL.h"
62*0fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenMP.h"
63*0fca6ea1SDimitry Andric #include "clang/Sema/SemaPPC.h"
64*0fca6ea1SDimitry Andric #include "clang/Sema/SemaPseudoObject.h"
65*0fca6ea1SDimitry Andric #include "clang/Sema/SemaRISCV.h"
66*0fca6ea1SDimitry Andric #include "clang/Sema/SemaSYCL.h"
67*0fca6ea1SDimitry Andric #include "clang/Sema/SemaSwift.h"
68*0fca6ea1SDimitry Andric #include "clang/Sema/SemaSystemZ.h"
69*0fca6ea1SDimitry Andric #include "clang/Sema/SemaWasm.h"
70*0fca6ea1SDimitry Andric #include "clang/Sema/SemaX86.h"
710b57cec5SDimitry Andric #include "clang/Sema/TemplateDeduction.h"
720b57cec5SDimitry Andric #include "clang/Sema/TemplateInstCallback.h"
73a7dea167SDimitry Andric #include "clang/Sema/TypoCorrection.h"
740b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
75bdd1243dSDimitry Andric #include "llvm/ADT/STLExtras.h"
76e8d8bef9SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
770b57cec5SDimitry Andric #include "llvm/Support/TimeProfiler.h"
78bdd1243dSDimitry Andric #include <optional>
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric using namespace clang;
810b57cec5SDimitry Andric using namespace sema;
820b57cec5SDimitry Andric
getLocForEndOfToken(SourceLocation Loc,unsigned Offset)830b57cec5SDimitry Andric SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) {
840b57cec5SDimitry Andric return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
getModuleLoader() const870b57cec5SDimitry Andric ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
880b57cec5SDimitry Andric
89fe6060f1SDimitry Andric DarwinSDKInfo *
getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,StringRef Platform)90fe6060f1SDimitry Andric Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
91fe6060f1SDimitry Andric StringRef Platform) {
9204eeddc0SDimitry Andric auto *SDKInfo = getDarwinSDKInfoForAvailabilityChecking();
9304eeddc0SDimitry Andric if (!SDKInfo && !WarnedDarwinSDKInfoMissing) {
9404eeddc0SDimitry Andric Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking)
9504eeddc0SDimitry Andric << Platform;
9604eeddc0SDimitry Andric WarnedDarwinSDKInfoMissing = true;
9704eeddc0SDimitry Andric }
9804eeddc0SDimitry Andric return SDKInfo;
9904eeddc0SDimitry Andric }
10004eeddc0SDimitry Andric
getDarwinSDKInfoForAvailabilityChecking()10104eeddc0SDimitry Andric DarwinSDKInfo *Sema::getDarwinSDKInfoForAvailabilityChecking() {
102fe6060f1SDimitry Andric if (CachedDarwinSDKInfo)
103fe6060f1SDimitry Andric return CachedDarwinSDKInfo->get();
104fe6060f1SDimitry Andric auto SDKInfo = parseDarwinSDKInfo(
105fe6060f1SDimitry Andric PP.getFileManager().getVirtualFileSystem(),
106fe6060f1SDimitry Andric PP.getHeaderSearchInfo().getHeaderSearchOpts().Sysroot);
107fe6060f1SDimitry Andric if (SDKInfo && *SDKInfo) {
108fe6060f1SDimitry Andric CachedDarwinSDKInfo = std::make_unique<DarwinSDKInfo>(std::move(**SDKInfo));
109fe6060f1SDimitry Andric return CachedDarwinSDKInfo->get();
110fe6060f1SDimitry Andric }
111fe6060f1SDimitry Andric if (!SDKInfo)
112fe6060f1SDimitry Andric llvm::consumeError(SDKInfo.takeError());
113fe6060f1SDimitry Andric CachedDarwinSDKInfo = std::unique_ptr<DarwinSDKInfo>();
114fe6060f1SDimitry Andric return nullptr;
115fe6060f1SDimitry Andric }
116fe6060f1SDimitry Andric
InventAbbreviatedTemplateParameterTypeName(const IdentifierInfo * ParamName,unsigned int Index)117*0fca6ea1SDimitry Andric IdentifierInfo *Sema::InventAbbreviatedTemplateParameterTypeName(
118*0fca6ea1SDimitry Andric const IdentifierInfo *ParamName, unsigned int Index) {
11955e4f9d5SDimitry Andric std::string InventedName;
12055e4f9d5SDimitry Andric llvm::raw_string_ostream OS(InventedName);
12155e4f9d5SDimitry Andric
12255e4f9d5SDimitry Andric if (!ParamName)
12355e4f9d5SDimitry Andric OS << "auto:" << Index + 1;
12455e4f9d5SDimitry Andric else
12555e4f9d5SDimitry Andric OS << ParamName->getName() << ":auto";
12655e4f9d5SDimitry Andric
12755e4f9d5SDimitry Andric OS.flush();
12855e4f9d5SDimitry Andric return &Context.Idents.get(OS.str());
12955e4f9d5SDimitry Andric }
13055e4f9d5SDimitry Andric
getPrintingPolicy(const ASTContext & Context,const Preprocessor & PP)1310b57cec5SDimitry Andric PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
1320b57cec5SDimitry Andric const Preprocessor &PP) {
1330b57cec5SDimitry Andric PrintingPolicy Policy = Context.getPrintingPolicy();
1340b57cec5SDimitry Andric // In diagnostics, we print _Bool as bool if the latter is defined as the
1350b57cec5SDimitry Andric // former.
1360b57cec5SDimitry Andric Policy.Bool = Context.getLangOpts().Bool;
1370b57cec5SDimitry Andric if (!Policy.Bool) {
1380b57cec5SDimitry Andric if (const MacroInfo *BoolMacro = PP.getMacroInfo(Context.getBoolName())) {
1390b57cec5SDimitry Andric Policy.Bool = BoolMacro->isObjectLike() &&
1400b57cec5SDimitry Andric BoolMacro->getNumTokens() == 1 &&
1410b57cec5SDimitry Andric BoolMacro->getReplacementToken(0).is(tok::kw__Bool);
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric
14581ad6265SDimitry Andric // Shorten the data output if needed
14681ad6265SDimitry Andric Policy.EntireContentsOfLargeArray = false;
14781ad6265SDimitry Andric
1480b57cec5SDimitry Andric return Policy;
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric
ActOnTranslationUnitScope(Scope * S)1510b57cec5SDimitry Andric void Sema::ActOnTranslationUnitScope(Scope *S) {
1520b57cec5SDimitry Andric TUScope = S;
1530b57cec5SDimitry Andric PushDeclContext(S, Context.getTranslationUnitDecl());
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric namespace clang {
1570b57cec5SDimitry Andric namespace sema {
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric class SemaPPCallbacks : public PPCallbacks {
1600b57cec5SDimitry Andric Sema *S = nullptr;
1610b57cec5SDimitry Andric llvm::SmallVector<SourceLocation, 8> IncludeStack;
162*0fca6ea1SDimitry Andric llvm::SmallVector<llvm::TimeTraceProfilerEntry *, 8> ProfilerStack;
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric public:
set(Sema & S)1650b57cec5SDimitry Andric void set(Sema &S) { this->S = &S; }
1660b57cec5SDimitry Andric
reset()1670b57cec5SDimitry Andric void reset() { S = nullptr; }
1680b57cec5SDimitry Andric
FileChanged(SourceLocation Loc,FileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID)169972a253aSDimitry Andric void FileChanged(SourceLocation Loc, FileChangeReason Reason,
1700b57cec5SDimitry Andric SrcMgr::CharacteristicKind FileType,
1710b57cec5SDimitry Andric FileID PrevFID) override {
1720b57cec5SDimitry Andric if (!S)
1730b57cec5SDimitry Andric return;
1740b57cec5SDimitry Andric switch (Reason) {
1750b57cec5SDimitry Andric case EnterFile: {
1760b57cec5SDimitry Andric SourceManager &SM = S->getSourceManager();
1770b57cec5SDimitry Andric SourceLocation IncludeLoc = SM.getIncludeLoc(SM.getFileID(Loc));
1780b57cec5SDimitry Andric if (IncludeLoc.isValid()) {
1790b57cec5SDimitry Andric if (llvm::timeTraceProfilerEnabled()) {
1805f757f3fSDimitry Andric OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
181*0fca6ea1SDimitry Andric ProfilerStack.push_back(llvm::timeTraceAsyncProfilerBegin(
182*0fca6ea1SDimitry Andric "Source", FE ? FE->getName() : StringRef("<unknown>")));
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric IncludeStack.push_back(IncludeLoc);
186e8d8bef9SDimitry Andric S->DiagnoseNonDefaultPragmaAlignPack(
187e8d8bef9SDimitry Andric Sema::PragmaAlignPackDiagnoseKind::NonDefaultStateAtInclude,
188e8d8bef9SDimitry Andric IncludeLoc);
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric break;
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric case ExitFile:
1930b57cec5SDimitry Andric if (!IncludeStack.empty()) {
1940b57cec5SDimitry Andric if (llvm::timeTraceProfilerEnabled())
195*0fca6ea1SDimitry Andric llvm::timeTraceProfilerEnd(ProfilerStack.pop_back_val());
1960b57cec5SDimitry Andric
197e8d8bef9SDimitry Andric S->DiagnoseNonDefaultPragmaAlignPack(
198e8d8bef9SDimitry Andric Sema::PragmaAlignPackDiagnoseKind::ChangedStateAtExit,
1990b57cec5SDimitry Andric IncludeStack.pop_back_val());
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric break;
2020b57cec5SDimitry Andric default:
2030b57cec5SDimitry Andric break;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric };
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric } // end namespace sema
2090b57cec5SDimitry Andric } // end namespace clang
2100b57cec5SDimitry Andric
2115ffd83dbSDimitry Andric const unsigned Sema::MaxAlignmentExponent;
212349cc55cSDimitry Andric const uint64_t Sema::MaximumAlignment;
2135ffd83dbSDimitry Andric
Sema(Preprocessor & pp,ASTContext & ctxt,ASTConsumer & consumer,TranslationUnitKind TUKind,CodeCompleteConsumer * CodeCompleter)2140b57cec5SDimitry Andric Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
2150b57cec5SDimitry Andric TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter)
216*0fca6ea1SDimitry Andric : SemaBase(*this), CollectStats(false), TUKind(TUKind),
217*0fca6ea1SDimitry Andric CurFPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp),
218*0fca6ea1SDimitry Andric Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()),
219*0fca6ea1SDimitry Andric SourceMgr(PP.getSourceManager()), APINotes(SourceMgr, LangOpts),
220*0fca6ea1SDimitry Andric AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr),
221*0fca6ea1SDimitry Andric LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr),
222*0fca6ea1SDimitry Andric OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr),
223*0fca6ea1SDimitry Andric CurScope(nullptr), Ident_super(nullptr),
224*0fca6ea1SDimitry Andric AMDGPUPtr(std::make_unique<SemaAMDGPU>(*this)),
225*0fca6ea1SDimitry Andric ARMPtr(std::make_unique<SemaARM>(*this)),
226*0fca6ea1SDimitry Andric AVRPtr(std::make_unique<SemaAVR>(*this)),
227*0fca6ea1SDimitry Andric BPFPtr(std::make_unique<SemaBPF>(*this)),
228*0fca6ea1SDimitry Andric CodeCompletionPtr(
229*0fca6ea1SDimitry Andric std::make_unique<SemaCodeCompletion>(*this, CodeCompleter)),
230*0fca6ea1SDimitry Andric CUDAPtr(std::make_unique<SemaCUDA>(*this)),
231*0fca6ea1SDimitry Andric HLSLPtr(std::make_unique<SemaHLSL>(*this)),
232*0fca6ea1SDimitry Andric HexagonPtr(std::make_unique<SemaHexagon>(*this)),
233*0fca6ea1SDimitry Andric LoongArchPtr(std::make_unique<SemaLoongArch>(*this)),
234*0fca6ea1SDimitry Andric M68kPtr(std::make_unique<SemaM68k>(*this)),
235*0fca6ea1SDimitry Andric MIPSPtr(std::make_unique<SemaMIPS>(*this)),
236*0fca6ea1SDimitry Andric MSP430Ptr(std::make_unique<SemaMSP430>(*this)),
237*0fca6ea1SDimitry Andric NVPTXPtr(std::make_unique<SemaNVPTX>(*this)),
238*0fca6ea1SDimitry Andric ObjCPtr(std::make_unique<SemaObjC>(*this)),
239*0fca6ea1SDimitry Andric OpenACCPtr(std::make_unique<SemaOpenACC>(*this)),
240*0fca6ea1SDimitry Andric OpenCLPtr(std::make_unique<SemaOpenCL>(*this)),
241*0fca6ea1SDimitry Andric OpenMPPtr(std::make_unique<SemaOpenMP>(*this)),
242*0fca6ea1SDimitry Andric PPCPtr(std::make_unique<SemaPPC>(*this)),
243*0fca6ea1SDimitry Andric PseudoObjectPtr(std::make_unique<SemaPseudoObject>(*this)),
244*0fca6ea1SDimitry Andric RISCVPtr(std::make_unique<SemaRISCV>(*this)),
245*0fca6ea1SDimitry Andric SYCLPtr(std::make_unique<SemaSYCL>(*this)),
246*0fca6ea1SDimitry Andric SwiftPtr(std::make_unique<SemaSwift>(*this)),
247*0fca6ea1SDimitry Andric SystemZPtr(std::make_unique<SemaSystemZ>(*this)),
248*0fca6ea1SDimitry Andric WasmPtr(std::make_unique<SemaWasm>(*this)),
249*0fca6ea1SDimitry Andric X86Ptr(std::make_unique<SemaX86>(*this)),
2500b57cec5SDimitry Andric MSPointerToMemberRepresentationMethod(
2510b57cec5SDimitry Andric LangOpts.getMSPointerToMemberRepresentationMethod()),
252*0fca6ea1SDimitry Andric MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()),
253e8d8bef9SDimitry Andric AlignPackStack(AlignPackInfo(getLangOpts().XLPragmaPack)),
2540b57cec5SDimitry Andric DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
255bdd1243dSDimitry Andric CodeSegStack(nullptr), StrictGuardStackCheckStack(false),
256bdd1243dSDimitry Andric FpPragmaStack(FPOptionsOverride()), CurInitSeg(nullptr),
257bdd1243dSDimitry Andric VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr),
258*0fca6ea1SDimitry Andric StdCoroutineTraitsCache(nullptr), IdResolver(pp),
259*0fca6ea1SDimitry Andric OriginalLexicalContext(nullptr), StdInitializerList(nullptr),
2600b57cec5SDimitry Andric FullyCheckedComparisonCategories(
2610b57cec5SDimitry Andric static_cast<unsigned>(ComparisonCategoryType::Last) + 1),
262*0fca6ea1SDimitry Andric StdSourceLocationImplDecl(nullptr), CXXTypeInfoDecl(nullptr),
263*0fca6ea1SDimitry Andric GlobalNewDeleteDeclared(false), DisableTypoCorrection(false),
264*0fca6ea1SDimitry Andric TyposCorrected(0), IsBuildingRecoveryCallExpr(false), NumSFINAEErrors(0),
265*0fca6ea1SDimitry Andric AccessCheckingSFINAE(false), CurrentInstantiationScope(nullptr),
26655e4f9d5SDimitry Andric InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0),
267*0fca6ea1SDimitry Andric ArgumentPackSubstitutionIndex(-1), SatisfactionCache(Context) {
268fe6060f1SDimitry Andric assert(pp.TUKind == TUKind);
2690b57cec5SDimitry Andric TUScope = nullptr;
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric LoadedExternalKnownNamespaces = false;
2720b57cec5SDimitry Andric for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I)
273*0fca6ea1SDimitry Andric ObjC().NSNumberLiteralMethods[I] = nullptr;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric if (getLangOpts().ObjC)
276*0fca6ea1SDimitry Andric ObjC().NSAPIObj.reset(new NSAPI(Context));
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andric if (getLangOpts().CPlusPlus)
2790b57cec5SDimitry Andric FieldCollector.reset(new CXXFieldCollector());
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric // Tell diagnostics how to render things from the AST library.
2820b57cec5SDimitry Andric Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context);
2830b57cec5SDimitry Andric
28481ad6265SDimitry Andric // This evaluation context exists to ensure that there's always at least one
28581ad6265SDimitry Andric // valid evaluation context available. It is never removed from the
28681ad6265SDimitry Andric // evaluation stack.
2870b57cec5SDimitry Andric ExprEvalContexts.emplace_back(
2880b57cec5SDimitry Andric ExpressionEvaluationContext::PotentiallyEvaluated, 0, CleanupInfo{},
2890b57cec5SDimitry Andric nullptr, ExpressionEvaluationContextRecord::EK_Other);
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric // Initialization of data sharing attributes stack for OpenMP
292*0fca6ea1SDimitry Andric OpenMP().InitDataSharingAttributesStack();
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric std::unique_ptr<sema::SemaPPCallbacks> Callbacks =
295a7dea167SDimitry Andric std::make_unique<sema::SemaPPCallbacks>();
2960b57cec5SDimitry Andric SemaPPCallbackHandler = Callbacks.get();
2970b57cec5SDimitry Andric PP.addPPCallbacks(std::move(Callbacks));
2980b57cec5SDimitry Andric SemaPPCallbackHandler->set(*this);
29981ad6265SDimitry Andric
30081ad6265SDimitry Andric CurFPFeatures.setFPEvalMethod(PP.getCurrentFPEvalMethod());
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric
303480093f4SDimitry Andric // Anchor Sema's type info to this TU.
anchor()304480093f4SDimitry Andric void Sema::anchor() {}
305480093f4SDimitry Andric
addImplicitTypedef(StringRef Name,QualType T)3060b57cec5SDimitry Andric void Sema::addImplicitTypedef(StringRef Name, QualType T) {
3070b57cec5SDimitry Andric DeclarationName DN = &Context.Idents.get(Name);
3080b57cec5SDimitry Andric if (IdResolver.begin(DN) == IdResolver.end())
3090b57cec5SDimitry Andric PushOnScopeChains(Context.buildImplicitTypedef(T, Name), TUScope);
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric
Initialize()3120b57cec5SDimitry Andric void Sema::Initialize() {
3130b57cec5SDimitry Andric if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
3140b57cec5SDimitry Andric SC->InitializeSema(*this);
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric // Tell the external Sema source about this Sema object.
3170b57cec5SDimitry Andric if (ExternalSemaSource *ExternalSema
3180b57cec5SDimitry Andric = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
3190b57cec5SDimitry Andric ExternalSema->InitializeSema(*this);
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric // This needs to happen after ExternalSemaSource::InitializeSema(this) or we
3220b57cec5SDimitry Andric // will not be able to merge any duplicate __va_list_tag decls correctly.
3230b57cec5SDimitry Andric VAListTagName = PP.getIdentifierInfo("__va_list_tag");
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric if (!TUScope)
3260b57cec5SDimitry Andric return;
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric // Initialize predefined 128-bit integer types, if needed.
329e8d8bef9SDimitry Andric if (Context.getTargetInfo().hasInt128Type() ||
330e8d8bef9SDimitry Andric (Context.getAuxTargetInfo() &&
331e8d8bef9SDimitry Andric Context.getAuxTargetInfo()->hasInt128Type())) {
3320b57cec5SDimitry Andric // If either of the 128-bit integer types are unavailable to name lookup,
3330b57cec5SDimitry Andric // define them now.
3340b57cec5SDimitry Andric DeclarationName Int128 = &Context.Idents.get("__int128_t");
3350b57cec5SDimitry Andric if (IdResolver.begin(Int128) == IdResolver.end())
3360b57cec5SDimitry Andric PushOnScopeChains(Context.getInt128Decl(), TUScope);
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric DeclarationName UInt128 = &Context.Idents.get("__uint128_t");
3390b57cec5SDimitry Andric if (IdResolver.begin(UInt128) == IdResolver.end())
3400b57cec5SDimitry Andric PushOnScopeChains(Context.getUInt128Decl(), TUScope);
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric // Initialize predefined Objective-C types:
3450b57cec5SDimitry Andric if (getLangOpts().ObjC) {
3460b57cec5SDimitry Andric // If 'SEL' does not yet refer to any declarations, make it refer to the
3470b57cec5SDimitry Andric // predefined 'SEL'.
3480b57cec5SDimitry Andric DeclarationName SEL = &Context.Idents.get("SEL");
3490b57cec5SDimitry Andric if (IdResolver.begin(SEL) == IdResolver.end())
3500b57cec5SDimitry Andric PushOnScopeChains(Context.getObjCSelDecl(), TUScope);
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric // If 'id' does not yet refer to any declarations, make it refer to the
3530b57cec5SDimitry Andric // predefined 'id'.
3540b57cec5SDimitry Andric DeclarationName Id = &Context.Idents.get("id");
3550b57cec5SDimitry Andric if (IdResolver.begin(Id) == IdResolver.end())
3560b57cec5SDimitry Andric PushOnScopeChains(Context.getObjCIdDecl(), TUScope);
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric // Create the built-in typedef for 'Class'.
3590b57cec5SDimitry Andric DeclarationName Class = &Context.Idents.get("Class");
3600b57cec5SDimitry Andric if (IdResolver.begin(Class) == IdResolver.end())
3610b57cec5SDimitry Andric PushOnScopeChains(Context.getObjCClassDecl(), TUScope);
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric // Create the built-in forward declaratino for 'Protocol'.
3640b57cec5SDimitry Andric DeclarationName Protocol = &Context.Idents.get("Protocol");
3650b57cec5SDimitry Andric if (IdResolver.begin(Protocol) == IdResolver.end())
3660b57cec5SDimitry Andric PushOnScopeChains(Context.getObjCProtocolDecl(), TUScope);
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric // Create the internal type for the *StringMakeConstantString builtins.
3700b57cec5SDimitry Andric DeclarationName ConstantString = &Context.Idents.get("__NSConstantString");
3710b57cec5SDimitry Andric if (IdResolver.begin(ConstantString) == IdResolver.end())
3720b57cec5SDimitry Andric PushOnScopeChains(Context.getCFConstantStringDecl(), TUScope);
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric // Initialize Microsoft "predefined C++ types".
3750b57cec5SDimitry Andric if (getLangOpts().MSVCCompat) {
3760b57cec5SDimitry Andric if (getLangOpts().CPlusPlus &&
3770b57cec5SDimitry Andric IdResolver.begin(&Context.Idents.get("type_info")) == IdResolver.end())
3785f757f3fSDimitry Andric PushOnScopeChains(
3795f757f3fSDimitry Andric Context.buildImplicitRecord("type_info", TagTypeKind::Class),
3800b57cec5SDimitry Andric TUScope);
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric addImplicitTypedef("size_t", Context.getSizeType());
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric
3850b57cec5SDimitry Andric // Initialize predefined OpenCL types and supported extensions and (optional)
3860b57cec5SDimitry Andric // core features.
3870b57cec5SDimitry Andric if (getLangOpts().OpenCL) {
3880b57cec5SDimitry Andric getOpenCLOptions().addSupport(
389e8d8bef9SDimitry Andric Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts());
3900b57cec5SDimitry Andric addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
3910b57cec5SDimitry Andric addImplicitTypedef("event_t", Context.OCLEventTy);
39204eeddc0SDimitry Andric auto OCLCompatibleVersion = getLangOpts().getOpenCLCompatibleVersion();
39304eeddc0SDimitry Andric if (OCLCompatibleVersion >= 200) {
39404eeddc0SDimitry Andric if (getLangOpts().OpenCLCPlusPlus || getLangOpts().Blocks) {
3950b57cec5SDimitry Andric addImplicitTypedef("clk_event_t", Context.OCLClkEventTy);
3960b57cec5SDimitry Andric addImplicitTypedef("queue_t", Context.OCLQueueTy);
39704eeddc0SDimitry Andric }
3986e75b2fbSDimitry Andric if (getLangOpts().OpenCLPipes)
3990b57cec5SDimitry Andric addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy);
4000b57cec5SDimitry Andric addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy));
4010b57cec5SDimitry Andric addImplicitTypedef("atomic_uint",
4020b57cec5SDimitry Andric Context.getAtomicType(Context.UnsignedIntTy));
4030b57cec5SDimitry Andric addImplicitTypedef("atomic_float",
4040b57cec5SDimitry Andric Context.getAtomicType(Context.FloatTy));
4050b57cec5SDimitry Andric // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as
4060b57cec5SDimitry Andric // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide.
4070b57cec5SDimitry Andric addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy));
408fe6060f1SDimitry Andric
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric // OpenCL v2.0 s6.13.11.6:
4110b57cec5SDimitry Andric // - The atomic_long and atomic_ulong types are supported if the
4120b57cec5SDimitry Andric // cl_khr_int64_base_atomics and cl_khr_int64_extended_atomics
4130b57cec5SDimitry Andric // extensions are supported.
4140b57cec5SDimitry Andric // - The atomic_double type is only supported if double precision
4150b57cec5SDimitry Andric // is supported and the cl_khr_int64_base_atomics and
4160b57cec5SDimitry Andric // cl_khr_int64_extended_atomics extensions are supported.
4170b57cec5SDimitry Andric // - If the device address space is 64-bits, the data types
4180b57cec5SDimitry Andric // atomic_intptr_t, atomic_uintptr_t, atomic_size_t and
4190b57cec5SDimitry Andric // atomic_ptrdiff_t are supported if the cl_khr_int64_base_atomics and
4200b57cec5SDimitry Andric // cl_khr_int64_extended_atomics extensions are supported.
421fe6060f1SDimitry Andric
422fe6060f1SDimitry Andric auto AddPointerSizeDependentTypes = [&]() {
423fe6060f1SDimitry Andric auto AtomicSizeT = Context.getAtomicType(Context.getSizeType());
424fe6060f1SDimitry Andric auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType());
425fe6060f1SDimitry Andric auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType());
426fe6060f1SDimitry Andric auto AtomicPtrDiffT =
427fe6060f1SDimitry Andric Context.getAtomicType(Context.getPointerDiffType());
428fe6060f1SDimitry Andric addImplicitTypedef("atomic_size_t", AtomicSizeT);
429fe6060f1SDimitry Andric addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT);
430fe6060f1SDimitry Andric addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT);
431fe6060f1SDimitry Andric addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT);
432fe6060f1SDimitry Andric };
433fe6060f1SDimitry Andric
434fe6060f1SDimitry Andric if (Context.getTypeSize(Context.getSizeType()) == 32) {
435fe6060f1SDimitry Andric AddPointerSizeDependentTypes();
436fe6060f1SDimitry Andric }
437fe6060f1SDimitry Andric
438349cc55cSDimitry Andric if (getOpenCLOptions().isSupported("cl_khr_fp16", getLangOpts())) {
439349cc55cSDimitry Andric auto AtomicHalfT = Context.getAtomicType(Context.HalfTy);
440349cc55cSDimitry Andric addImplicitTypedef("atomic_half", AtomicHalfT);
441349cc55cSDimitry Andric }
442349cc55cSDimitry Andric
4430b57cec5SDimitry Andric std::vector<QualType> Atomic64BitTypes;
444fe6060f1SDimitry Andric if (getOpenCLOptions().isSupported("cl_khr_int64_base_atomics",
445fe6060f1SDimitry Andric getLangOpts()) &&
446fe6060f1SDimitry Andric getOpenCLOptions().isSupported("cl_khr_int64_extended_atomics",
447fe6060f1SDimitry Andric getLangOpts())) {
448fe6060f1SDimitry Andric if (getOpenCLOptions().isSupported("cl_khr_fp64", getLangOpts())) {
449fe6060f1SDimitry Andric auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy);
450fe6060f1SDimitry Andric addImplicitTypedef("atomic_double", AtomicDoubleT);
4510b57cec5SDimitry Andric Atomic64BitTypes.push_back(AtomicDoubleT);
4520b57cec5SDimitry Andric }
453fe6060f1SDimitry Andric auto AtomicLongT = Context.getAtomicType(Context.LongTy);
454fe6060f1SDimitry Andric auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy);
455fe6060f1SDimitry Andric addImplicitTypedef("atomic_long", AtomicLongT);
456fe6060f1SDimitry Andric addImplicitTypedef("atomic_ulong", AtomicULongT);
4570b57cec5SDimitry Andric
458fe6060f1SDimitry Andric
459fe6060f1SDimitry Andric if (Context.getTypeSize(Context.getSizeType()) == 64) {
460fe6060f1SDimitry Andric AddPointerSizeDependentTypes();
461fe6060f1SDimitry Andric }
462fe6060f1SDimitry Andric }
4630b57cec5SDimitry Andric }
4640b57cec5SDimitry Andric
4650b57cec5SDimitry Andric #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
466fe6060f1SDimitry Andric if (getOpenCLOptions().isSupported(#Ext, getLangOpts())) { \
4670b57cec5SDimitry Andric addImplicitTypedef(#ExtType, Context.Id##Ty); \
468fe6060f1SDimitry Andric }
4690b57cec5SDimitry Andric #include "clang/Basic/OpenCLExtensionTypes.def"
470a7dea167SDimitry Andric }
471a7dea167SDimitry Andric
472*0fca6ea1SDimitry Andric if (Context.getTargetInfo().hasAArch64SVETypes() ||
473*0fca6ea1SDimitry Andric (Context.getAuxTargetInfo() &&
474*0fca6ea1SDimitry Andric Context.getAuxTargetInfo()->hasAArch64SVETypes())) {
475a7dea167SDimitry Andric #define SVE_TYPE(Name, Id, SingletonId) \
476a7dea167SDimitry Andric addImplicitTypedef(Name, Context.SingletonId);
477a7dea167SDimitry Andric #include "clang/Basic/AArch64SVEACLETypes.def"
478a7dea167SDimitry Andric }
4790b57cec5SDimitry Andric
480349cc55cSDimitry Andric if (Context.getTargetInfo().getTriple().isPPC64()) {
481e8d8bef9SDimitry Andric #define PPC_VECTOR_MMA_TYPE(Name, Id, Size) \
482e8d8bef9SDimitry Andric addImplicitTypedef(#Name, Context.Id##Ty);
483e8d8bef9SDimitry Andric #include "clang/Basic/PPCTypes.def"
484e8d8bef9SDimitry Andric #define PPC_VECTOR_VSX_TYPE(Name, Id, Size) \
485e8d8bef9SDimitry Andric addImplicitTypedef(#Name, Context.Id##Ty);
486e8d8bef9SDimitry Andric #include "clang/Basic/PPCTypes.def"
487e8d8bef9SDimitry Andric }
488e8d8bef9SDimitry Andric
489fe6060f1SDimitry Andric if (Context.getTargetInfo().hasRISCVVTypes()) {
490fe6060f1SDimitry Andric #define RVV_TYPE(Name, Id, SingletonId) \
491fe6060f1SDimitry Andric addImplicitTypedef(Name, Context.SingletonId);
492fe6060f1SDimitry Andric #include "clang/Basic/RISCVVTypes.def"
493fe6060f1SDimitry Andric }
494fe6060f1SDimitry Andric
49506c3fb27SDimitry Andric if (Context.getTargetInfo().getTriple().isWasm() &&
49606c3fb27SDimitry Andric Context.getTargetInfo().hasFeature("reference-types")) {
49706c3fb27SDimitry Andric #define WASM_TYPE(Name, Id, SingletonId) \
49806c3fb27SDimitry Andric addImplicitTypedef(Name, Context.SingletonId);
49906c3fb27SDimitry Andric #include "clang/Basic/WebAssemblyReferenceTypes.def"
50006c3fb27SDimitry Andric }
50106c3fb27SDimitry Andric
502*0fca6ea1SDimitry Andric if (Context.getTargetInfo().getTriple().isAMDGPU() ||
503*0fca6ea1SDimitry Andric (Context.getAuxTargetInfo() &&
504*0fca6ea1SDimitry Andric Context.getAuxTargetInfo()->getTriple().isAMDGPU())) {
505*0fca6ea1SDimitry Andric #define AMDGPU_TYPE(Name, Id, SingletonId) \
506*0fca6ea1SDimitry Andric addImplicitTypedef(Name, Context.SingletonId);
507*0fca6ea1SDimitry Andric #include "clang/Basic/AMDGPUTypes.def"
508*0fca6ea1SDimitry Andric }
509*0fca6ea1SDimitry Andric
5100b57cec5SDimitry Andric if (Context.getTargetInfo().hasBuiltinMSVaList()) {
5110b57cec5SDimitry Andric DeclarationName MSVaList = &Context.Idents.get("__builtin_ms_va_list");
5120b57cec5SDimitry Andric if (IdResolver.begin(MSVaList) == IdResolver.end())
5130b57cec5SDimitry Andric PushOnScopeChains(Context.getBuiltinMSVaListDecl(), TUScope);
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andric DeclarationName BuiltinVaList = &Context.Idents.get("__builtin_va_list");
5170b57cec5SDimitry Andric if (IdResolver.begin(BuiltinVaList) == IdResolver.end())
5180b57cec5SDimitry Andric PushOnScopeChains(Context.getBuiltinVaListDecl(), TUScope);
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric
~Sema()5210b57cec5SDimitry Andric Sema::~Sema() {
522e8d8bef9SDimitry Andric assert(InstantiatingSpecializations.empty() &&
523e8d8bef9SDimitry Andric "failed to clean up an InstantiatingTemplate?");
524e8d8bef9SDimitry Andric
5250b57cec5SDimitry Andric if (VisContext) FreeVisContext();
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andric // Kill all the active scopes.
5280b57cec5SDimitry Andric for (sema::FunctionScopeInfo *FSI : FunctionScopes)
5290b57cec5SDimitry Andric delete FSI;
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric // Tell the SemaConsumer to forget about us; we're going out of scope.
5320b57cec5SDimitry Andric if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
5330b57cec5SDimitry Andric SC->ForgetSema();
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric // Detach from the external Sema source.
5360b57cec5SDimitry Andric if (ExternalSemaSource *ExternalSema
5370b57cec5SDimitry Andric = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
5380b57cec5SDimitry Andric ExternalSema->ForgetSema();
5390b57cec5SDimitry Andric
54055e4f9d5SDimitry Andric // Delete cached satisfactions.
54155e4f9d5SDimitry Andric std::vector<ConstraintSatisfaction *> Satisfactions;
5425f757f3fSDimitry Andric Satisfactions.reserve(SatisfactionCache.size());
54355e4f9d5SDimitry Andric for (auto &Node : SatisfactionCache)
54455e4f9d5SDimitry Andric Satisfactions.push_back(&Node);
54555e4f9d5SDimitry Andric for (auto *Node : Satisfactions)
54655e4f9d5SDimitry Andric delete Node;
54755e4f9d5SDimitry Andric
5480b57cec5SDimitry Andric threadSafety::threadSafetyCleanup(ThreadSafetyDeclCache);
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric // Destroys data sharing attributes stack for OpenMP
551*0fca6ea1SDimitry Andric OpenMP().DestroyDataSharingAttributesStack();
5520b57cec5SDimitry Andric
5530b57cec5SDimitry Andric // Detach from the PP callback handler which outlives Sema since it's owned
5540b57cec5SDimitry Andric // by the preprocessor.
5550b57cec5SDimitry Andric SemaPPCallbackHandler->reset();
556a7dea167SDimitry Andric }
5570b57cec5SDimitry Andric
warnStackExhausted(SourceLocation Loc)558a7dea167SDimitry Andric void Sema::warnStackExhausted(SourceLocation Loc) {
559a7dea167SDimitry Andric // Only warn about this once.
560a7dea167SDimitry Andric if (!WarnedStackExhausted) {
561a7dea167SDimitry Andric Diag(Loc, diag::warn_stack_exhausted);
562a7dea167SDimitry Andric WarnedStackExhausted = true;
563a7dea167SDimitry Andric }
564a7dea167SDimitry Andric }
565a7dea167SDimitry Andric
runWithSufficientStackSpace(SourceLocation Loc,llvm::function_ref<void ()> Fn)566a7dea167SDimitry Andric void Sema::runWithSufficientStackSpace(SourceLocation Loc,
567a7dea167SDimitry Andric llvm::function_ref<void()> Fn) {
568a7dea167SDimitry Andric clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn);
5690b57cec5SDimitry Andric }
5700b57cec5SDimitry Andric
makeUnavailableInSystemHeader(SourceLocation loc,UnavailableAttr::ImplicitReason reason)5710b57cec5SDimitry Andric bool Sema::makeUnavailableInSystemHeader(SourceLocation loc,
5720b57cec5SDimitry Andric UnavailableAttr::ImplicitReason reason) {
5730b57cec5SDimitry Andric // If we're not in a function, it's an error.
5740b57cec5SDimitry Andric FunctionDecl *fn = dyn_cast<FunctionDecl>(CurContext);
5750b57cec5SDimitry Andric if (!fn) return false;
5760b57cec5SDimitry Andric
5770b57cec5SDimitry Andric // If we're in template instantiation, it's an error.
5780b57cec5SDimitry Andric if (inTemplateInstantiation())
5790b57cec5SDimitry Andric return false;
5800b57cec5SDimitry Andric
5810b57cec5SDimitry Andric // If that function's not in a system header, it's an error.
5820b57cec5SDimitry Andric if (!Context.getSourceManager().isInSystemHeader(loc))
5830b57cec5SDimitry Andric return false;
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric // If the function is already unavailable, it's not an error.
5860b57cec5SDimitry Andric if (fn->hasAttr<UnavailableAttr>()) return true;
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andric fn->addAttr(UnavailableAttr::CreateImplicit(Context, "", reason, loc));
5890b57cec5SDimitry Andric return true;
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric
getASTMutationListener() const5920b57cec5SDimitry Andric ASTMutationListener *Sema::getASTMutationListener() const {
5930b57cec5SDimitry Andric return getASTConsumer().GetASTMutationListener();
5940b57cec5SDimitry Andric }
5950b57cec5SDimitry Andric
addExternalSource(ExternalSemaSource * E)5960b57cec5SDimitry Andric void Sema::addExternalSource(ExternalSemaSource *E) {
5970b57cec5SDimitry Andric assert(E && "Cannot use with NULL ptr");
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andric if (!ExternalSource) {
6000b57cec5SDimitry Andric ExternalSource = E;
6010b57cec5SDimitry Andric return;
6020b57cec5SDimitry Andric }
6030b57cec5SDimitry Andric
604bdd1243dSDimitry Andric if (auto *Ex = dyn_cast<MultiplexExternalSemaSource>(ExternalSource))
605bdd1243dSDimitry Andric Ex->AddSource(E);
606bdd1243dSDimitry Andric else
607bdd1243dSDimitry Andric ExternalSource = new MultiplexExternalSemaSource(ExternalSource.get(), E);
6080b57cec5SDimitry Andric }
6090b57cec5SDimitry Andric
PrintStats() const6100b57cec5SDimitry Andric void Sema::PrintStats() const {
6110b57cec5SDimitry Andric llvm::errs() << "\n*** Semantic Analysis Stats:\n";
6120b57cec5SDimitry Andric llvm::errs() << NumSFINAEErrors << " SFINAE diagnostics trapped.\n";
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric BumpAlloc.PrintStats();
6150b57cec5SDimitry Andric AnalysisWarnings.PrintStats();
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric
diagnoseNullableToNonnullConversion(QualType DstType,QualType SrcType,SourceLocation Loc)6180b57cec5SDimitry Andric void Sema::diagnoseNullableToNonnullConversion(QualType DstType,
6190b57cec5SDimitry Andric QualType SrcType,
6200b57cec5SDimitry Andric SourceLocation Loc) {
621bdd1243dSDimitry Andric std::optional<NullabilityKind> ExprNullability = SrcType->getNullability();
622e8d8bef9SDimitry Andric if (!ExprNullability || (*ExprNullability != NullabilityKind::Nullable &&
623e8d8bef9SDimitry Andric *ExprNullability != NullabilityKind::NullableResult))
6240b57cec5SDimitry Andric return;
6250b57cec5SDimitry Andric
626bdd1243dSDimitry Andric std::optional<NullabilityKind> TypeNullability = DstType->getNullability();
6270b57cec5SDimitry Andric if (!TypeNullability || *TypeNullability != NullabilityKind::NonNull)
6280b57cec5SDimitry Andric return;
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric Diag(Loc, diag::warn_nullability_lost) << SrcType << DstType;
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric
633*0fca6ea1SDimitry Andric // Generate diagnostics when adding or removing effects in a type conversion.
diagnoseFunctionEffectConversion(QualType DstType,QualType SrcType,SourceLocation Loc)634*0fca6ea1SDimitry Andric void Sema::diagnoseFunctionEffectConversion(QualType DstType, QualType SrcType,
635*0fca6ea1SDimitry Andric SourceLocation Loc) {
636*0fca6ea1SDimitry Andric const auto SrcFX = FunctionEffectsRef::get(SrcType);
637*0fca6ea1SDimitry Andric const auto DstFX = FunctionEffectsRef::get(DstType);
638*0fca6ea1SDimitry Andric if (SrcFX != DstFX) {
639*0fca6ea1SDimitry Andric for (const auto &Diff : FunctionEffectDifferences(SrcFX, DstFX)) {
640*0fca6ea1SDimitry Andric if (Diff.shouldDiagnoseConversion(SrcType, SrcFX, DstType, DstFX))
641*0fca6ea1SDimitry Andric Diag(Loc, diag::warn_invalid_add_func_effects) << Diff.effectName();
642*0fca6ea1SDimitry Andric }
643*0fca6ea1SDimitry Andric }
644*0fca6ea1SDimitry Andric }
645*0fca6ea1SDimitry Andric
diagnoseZeroToNullptrConversion(CastKind Kind,const Expr * E)6460b57cec5SDimitry Andric void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E) {
6470b57cec5SDimitry Andric // nullptr only exists from C++11 on, so don't warn on its absence earlier.
6480b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus11)
6490b57cec5SDimitry Andric return;
6500b57cec5SDimitry Andric
6510b57cec5SDimitry Andric if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
6520b57cec5SDimitry Andric return;
6535f757f3fSDimitry Andric
6545f757f3fSDimitry Andric const Expr *EStripped = E->IgnoreParenImpCasts();
6555f757f3fSDimitry Andric if (EStripped->getType()->isNullPtrType())
6565f757f3fSDimitry Andric return;
6575f757f3fSDimitry Andric if (isa<GNUNullExpr>(EStripped))
6580b57cec5SDimitry Andric return;
6590b57cec5SDimitry Andric
660bdd1243dSDimitry Andric if (Diags.isIgnored(diag::warn_zero_as_null_pointer_constant,
661bdd1243dSDimitry Andric E->getBeginLoc()))
662bdd1243dSDimitry Andric return;
663bdd1243dSDimitry Andric
664d409305fSDimitry Andric // Don't diagnose the conversion from a 0 literal to a null pointer argument
665d409305fSDimitry Andric // in a synthesized call to operator<=>.
666d409305fSDimitry Andric if (!CodeSynthesisContexts.empty() &&
667d409305fSDimitry Andric CodeSynthesisContexts.back().Kind ==
668d409305fSDimitry Andric CodeSynthesisContext::RewritingOperatorAsSpaceship)
669d409305fSDimitry Andric return;
670d409305fSDimitry Andric
671bdd1243dSDimitry Andric // Ignore null pointers in defaulted comparison operators.
672bdd1243dSDimitry Andric FunctionDecl *FD = getCurFunctionDecl();
673bdd1243dSDimitry Andric if (FD && FD->isDefaulted()) {
674bdd1243dSDimitry Andric return;
675bdd1243dSDimitry Andric }
676bdd1243dSDimitry Andric
6770b57cec5SDimitry Andric // If it is a macro from system header, and if the macro name is not "NULL",
6780b57cec5SDimitry Andric // do not warn.
6795f757f3fSDimitry Andric // Note that uses of "NULL" will be ignored above on systems that define it
6805f757f3fSDimitry Andric // as __null.
6810b57cec5SDimitry Andric SourceLocation MaybeMacroLoc = E->getBeginLoc();
6820b57cec5SDimitry Andric if (Diags.getSuppressSystemWarnings() &&
6830b57cec5SDimitry Andric SourceMgr.isInSystemMacro(MaybeMacroLoc) &&
6840b57cec5SDimitry Andric !findMacroSpelling(MaybeMacroLoc, "NULL"))
6850b57cec5SDimitry Andric return;
6860b57cec5SDimitry Andric
6870b57cec5SDimitry Andric Diag(E->getBeginLoc(), diag::warn_zero_as_null_pointer_constant)
6880b57cec5SDimitry Andric << FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
6920b57cec5SDimitry Andric /// If there is already an implicit cast, merge into the existing one.
6930b57cec5SDimitry Andric /// The result is of the given category.
ImpCastExprToType(Expr * E,QualType Ty,CastKind Kind,ExprValueKind VK,const CXXCastPath * BasePath,CheckedConversionKind CCK)6940b57cec5SDimitry Andric ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
6950b57cec5SDimitry Andric CastKind Kind, ExprValueKind VK,
6960b57cec5SDimitry Andric const CXXCastPath *BasePath,
6970b57cec5SDimitry Andric CheckedConversionKind CCK) {
6980b57cec5SDimitry Andric #ifndef NDEBUG
699fe6060f1SDimitry Andric if (VK == VK_PRValue && !E->isPRValue()) {
7000b57cec5SDimitry Andric switch (Kind) {
7010b57cec5SDimitry Andric default:
702fe6060f1SDimitry Andric llvm_unreachable(
703fe6060f1SDimitry Andric ("can't implicitly cast glvalue to prvalue with this cast "
704e8d8bef9SDimitry Andric "kind: " +
705e8d8bef9SDimitry Andric std::string(CastExpr::getCastKindName(Kind)))
706e8d8bef9SDimitry Andric .c_str());
7070b57cec5SDimitry Andric case CK_Dependent:
7080b57cec5SDimitry Andric case CK_LValueToRValue:
7090b57cec5SDimitry Andric case CK_ArrayToPointerDecay:
7100b57cec5SDimitry Andric case CK_FunctionToPointerDecay:
7110b57cec5SDimitry Andric case CK_ToVoid:
7120b57cec5SDimitry Andric case CK_NonAtomicToAtomic:
713*0fca6ea1SDimitry Andric case CK_HLSLArrayRValue:
7140b57cec5SDimitry Andric break;
7150b57cec5SDimitry Andric }
7160b57cec5SDimitry Andric }
717fe6060f1SDimitry Andric assert((VK == VK_PRValue || Kind == CK_Dependent || !E->isPRValue()) &&
718fe6060f1SDimitry Andric "can't cast prvalue to glvalue");
7190b57cec5SDimitry Andric #endif
7200b57cec5SDimitry Andric
7210b57cec5SDimitry Andric diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getBeginLoc());
7220b57cec5SDimitry Andric diagnoseZeroToNullptrConversion(Kind, E);
723*0fca6ea1SDimitry Andric if (Context.hasAnyFunctionEffects() && !isCast(CCK) &&
724*0fca6ea1SDimitry Andric Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
725*0fca6ea1SDimitry Andric diagnoseFunctionEffectConversion(Ty, E->getType(), E->getBeginLoc());
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric QualType ExprTy = Context.getCanonicalType(E->getType());
7280b57cec5SDimitry Andric QualType TypeTy = Context.getCanonicalType(Ty);
7290b57cec5SDimitry Andric
7300b57cec5SDimitry Andric if (ExprTy == TypeTy)
7310b57cec5SDimitry Andric return E;
7320b57cec5SDimitry Andric
733fe6060f1SDimitry Andric if (Kind == CK_ArrayToPointerDecay) {
7340b57cec5SDimitry Andric // C++1z [conv.array]: The temporary materialization conversion is applied.
7350b57cec5SDimitry Andric // We also use this to fuel C++ DR1213, which applies to C++11 onwards.
736fe6060f1SDimitry Andric if (getLangOpts().CPlusPlus && E->isPRValue()) {
7370b57cec5SDimitry Andric // The temporary is an lvalue in C++98 and an xvalue otherwise.
7380b57cec5SDimitry Andric ExprResult Materialized = CreateMaterializeTemporaryExpr(
7390b57cec5SDimitry Andric E->getType(), E, !getLangOpts().CPlusPlus11);
7400b57cec5SDimitry Andric if (Materialized.isInvalid())
7410b57cec5SDimitry Andric return ExprError();
7420b57cec5SDimitry Andric E = Materialized.get();
7430b57cec5SDimitry Andric }
744fe6060f1SDimitry Andric // C17 6.7.1p6 footnote 124: The implementation can treat any register
745fe6060f1SDimitry Andric // declaration simply as an auto declaration. However, whether or not
746fe6060f1SDimitry Andric // addressable storage is actually used, the address of any part of an
747fe6060f1SDimitry Andric // object declared with storage-class specifier register cannot be
748fe6060f1SDimitry Andric // computed, either explicitly(by use of the unary & operator as discussed
749fe6060f1SDimitry Andric // in 6.5.3.2) or implicitly(by converting an array name to a pointer as
750fe6060f1SDimitry Andric // discussed in 6.3.2.1).Thus, the only operator that can be applied to an
751fe6060f1SDimitry Andric // array declared with storage-class specifier register is sizeof.
752fe6060f1SDimitry Andric if (VK == VK_PRValue && !getLangOpts().CPlusPlus && !E->isPRValue()) {
753fe6060f1SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
754fe6060f1SDimitry Andric if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
755fe6060f1SDimitry Andric if (VD->getStorageClass() == SC_Register) {
756fe6060f1SDimitry Andric Diag(E->getExprLoc(), diag::err_typecheck_address_of)
757fe6060f1SDimitry Andric << /*register variable*/ 3 << E->getSourceRange();
758fe6060f1SDimitry Andric return ExprError();
759fe6060f1SDimitry Andric }
760fe6060f1SDimitry Andric }
761fe6060f1SDimitry Andric }
762fe6060f1SDimitry Andric }
763fe6060f1SDimitry Andric }
7640b57cec5SDimitry Andric
7650b57cec5SDimitry Andric if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
7660b57cec5SDimitry Andric if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
7670b57cec5SDimitry Andric ImpCast->setType(Ty);
7680b57cec5SDimitry Andric ImpCast->setValueKind(VK);
7690b57cec5SDimitry Andric return E;
7700b57cec5SDimitry Andric }
7710b57cec5SDimitry Andric }
7720b57cec5SDimitry Andric
773e8d8bef9SDimitry Andric return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK,
774e8d8bef9SDimitry Andric CurFPFeatureOverrides());
7750b57cec5SDimitry Andric }
7760b57cec5SDimitry Andric
ScalarTypeToBooleanCastKind(QualType ScalarTy)7770b57cec5SDimitry Andric CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) {
7780b57cec5SDimitry Andric switch (ScalarTy->getScalarTypeKind()) {
7790b57cec5SDimitry Andric case Type::STK_Bool: return CK_NoOp;
7800b57cec5SDimitry Andric case Type::STK_CPointer: return CK_PointerToBoolean;
7810b57cec5SDimitry Andric case Type::STK_BlockPointer: return CK_PointerToBoolean;
7820b57cec5SDimitry Andric case Type::STK_ObjCObjectPointer: return CK_PointerToBoolean;
7830b57cec5SDimitry Andric case Type::STK_MemberPointer: return CK_MemberPointerToBoolean;
7840b57cec5SDimitry Andric case Type::STK_Integral: return CK_IntegralToBoolean;
7850b57cec5SDimitry Andric case Type::STK_Floating: return CK_FloatingToBoolean;
7860b57cec5SDimitry Andric case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean;
7870b57cec5SDimitry Andric case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean;
7880b57cec5SDimitry Andric case Type::STK_FixedPoint: return CK_FixedPointToBoolean;
7890b57cec5SDimitry Andric }
7900b57cec5SDimitry Andric llvm_unreachable("unknown scalar type kind");
7910b57cec5SDimitry Andric }
7920b57cec5SDimitry Andric
7930b57cec5SDimitry Andric /// Used to prune the decls of Sema's UnusedFileScopedDecls vector.
ShouldRemoveFromUnused(Sema * SemaRef,const DeclaratorDecl * D)7940b57cec5SDimitry Andric static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
7950b57cec5SDimitry Andric if (D->getMostRecentDecl()->isUsed())
7960b57cec5SDimitry Andric return true;
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric if (D->isExternallyVisible())
7990b57cec5SDimitry Andric return true;
8000b57cec5SDimitry Andric
8010b57cec5SDimitry Andric if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8020b57cec5SDimitry Andric // If this is a function template and none of its specializations is used,
8030b57cec5SDimitry Andric // we should warn.
8040b57cec5SDimitry Andric if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
8050b57cec5SDimitry Andric for (const auto *Spec : Template->specializations())
8060b57cec5SDimitry Andric if (ShouldRemoveFromUnused(SemaRef, Spec))
8070b57cec5SDimitry Andric return true;
8080b57cec5SDimitry Andric
8090b57cec5SDimitry Andric // UnusedFileScopedDecls stores the first declaration.
8100b57cec5SDimitry Andric // The declaration may have become definition so check again.
8110b57cec5SDimitry Andric const FunctionDecl *DeclToCheck;
8120b57cec5SDimitry Andric if (FD->hasBody(DeclToCheck))
8130b57cec5SDimitry Andric return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andric // Later redecls may add new information resulting in not having to warn,
8160b57cec5SDimitry Andric // so check again.
8170b57cec5SDimitry Andric DeclToCheck = FD->getMostRecentDecl();
8180b57cec5SDimitry Andric if (DeclToCheck != FD)
8190b57cec5SDimitry Andric return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8230b57cec5SDimitry Andric // If a variable usable in constant expressions is referenced,
8240b57cec5SDimitry Andric // don't warn if it isn't used: if the value of a variable is required
8250b57cec5SDimitry Andric // for the computation of a constant expression, it doesn't make sense to
8260b57cec5SDimitry Andric // warn even if the variable isn't odr-used. (isReferenced doesn't
8270b57cec5SDimitry Andric // precisely reflect that, but it's a decent approximation.)
8280b57cec5SDimitry Andric if (VD->isReferenced() &&
8290b57cec5SDimitry Andric VD->mightBeUsableInConstantExpressions(SemaRef->Context))
8300b57cec5SDimitry Andric return true;
8310b57cec5SDimitry Andric
8320b57cec5SDimitry Andric if (VarTemplateDecl *Template = VD->getDescribedVarTemplate())
8330b57cec5SDimitry Andric // If this is a variable template and none of its specializations is used,
8340b57cec5SDimitry Andric // we should warn.
8350b57cec5SDimitry Andric for (const auto *Spec : Template->specializations())
8360b57cec5SDimitry Andric if (ShouldRemoveFromUnused(SemaRef, Spec))
8370b57cec5SDimitry Andric return true;
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric // UnusedFileScopedDecls stores the first declaration.
8400b57cec5SDimitry Andric // The declaration may have become definition so check again.
8410b57cec5SDimitry Andric const VarDecl *DeclToCheck = VD->getDefinition();
8420b57cec5SDimitry Andric if (DeclToCheck)
8430b57cec5SDimitry Andric return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
8440b57cec5SDimitry Andric
8450b57cec5SDimitry Andric // Later redecls may add new information resulting in not having to warn,
8460b57cec5SDimitry Andric // so check again.
8470b57cec5SDimitry Andric DeclToCheck = VD->getMostRecentDecl();
8480b57cec5SDimitry Andric if (DeclToCheck != VD)
8490b57cec5SDimitry Andric return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
8500b57cec5SDimitry Andric }
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andric return false;
8530b57cec5SDimitry Andric }
8540b57cec5SDimitry Andric
isFunctionOrVarDeclExternC(const NamedDecl * ND)85506c3fb27SDimitry Andric static bool isFunctionOrVarDeclExternC(const NamedDecl *ND) {
85606c3fb27SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(ND))
8570b57cec5SDimitry Andric return FD->isExternC();
8580b57cec5SDimitry Andric return cast<VarDecl>(ND)->isExternC();
8590b57cec5SDimitry Andric }
8600b57cec5SDimitry Andric
8610b57cec5SDimitry Andric /// Determine whether ND is an external-linkage function or variable whose
8620b57cec5SDimitry Andric /// type has no linkage.
isExternalWithNoLinkageType(const ValueDecl * VD) const86306c3fb27SDimitry Andric bool Sema::isExternalWithNoLinkageType(const ValueDecl *VD) const {
8640b57cec5SDimitry Andric // Note: it's not quite enough to check whether VD has UniqueExternalLinkage,
8650b57cec5SDimitry Andric // because we also want to catch the case where its type has VisibleNoLinkage,
8660b57cec5SDimitry Andric // which does not affect the linkage of VD.
8670b57cec5SDimitry Andric return getLangOpts().CPlusPlus && VD->hasExternalFormalLinkage() &&
8680b57cec5SDimitry Andric !isExternalFormalLinkage(VD->getType()->getLinkage()) &&
8690b57cec5SDimitry Andric !isFunctionOrVarDeclExternC(VD);
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric
8720b57cec5SDimitry Andric /// Obtains a sorted list of functions and variables that are undefined but
8730b57cec5SDimitry Andric /// ODR-used.
getUndefinedButUsed(SmallVectorImpl<std::pair<NamedDecl *,SourceLocation>> & Undefined)8740b57cec5SDimitry Andric void Sema::getUndefinedButUsed(
8750b57cec5SDimitry Andric SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) {
8760b57cec5SDimitry Andric for (const auto &UndefinedUse : UndefinedButUsed) {
8770b57cec5SDimitry Andric NamedDecl *ND = UndefinedUse.first;
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andric // Ignore attributes that have become invalid.
8800b57cec5SDimitry Andric if (ND->isInvalidDecl()) continue;
8810b57cec5SDimitry Andric
8820b57cec5SDimitry Andric // __attribute__((weakref)) is basically a definition.
8830b57cec5SDimitry Andric if (ND->hasAttr<WeakRefAttr>()) continue;
8840b57cec5SDimitry Andric
8850b57cec5SDimitry Andric if (isa<CXXDeductionGuideDecl>(ND))
8860b57cec5SDimitry Andric continue;
8870b57cec5SDimitry Andric
8880b57cec5SDimitry Andric if (ND->hasAttr<DLLImportAttr>() || ND->hasAttr<DLLExportAttr>()) {
8890b57cec5SDimitry Andric // An exported function will always be emitted when defined, so even if
8900b57cec5SDimitry Andric // the function is inline, it doesn't have to be emitted in this TU. An
8910b57cec5SDimitry Andric // imported function implies that it has been exported somewhere else.
8920b57cec5SDimitry Andric continue;
8930b57cec5SDimitry Andric }
8940b57cec5SDimitry Andric
8955f757f3fSDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
8960b57cec5SDimitry Andric if (FD->isDefined())
8970b57cec5SDimitry Andric continue;
8980b57cec5SDimitry Andric if (FD->isExternallyVisible() &&
8990b57cec5SDimitry Andric !isExternalWithNoLinkageType(FD) &&
9000b57cec5SDimitry Andric !FD->getMostRecentDecl()->isInlined() &&
9010b57cec5SDimitry Andric !FD->hasAttr<ExcludeFromExplicitInstantiationAttr>())
9020b57cec5SDimitry Andric continue;
9030b57cec5SDimitry Andric if (FD->getBuiltinID())
9040b57cec5SDimitry Andric continue;
9050b57cec5SDimitry Andric } else {
9065f757f3fSDimitry Andric const auto *VD = cast<VarDecl>(ND);
9070b57cec5SDimitry Andric if (VD->hasDefinition() != VarDecl::DeclarationOnly)
9080b57cec5SDimitry Andric continue;
9090b57cec5SDimitry Andric if (VD->isExternallyVisible() &&
9100b57cec5SDimitry Andric !isExternalWithNoLinkageType(VD) &&
9110b57cec5SDimitry Andric !VD->getMostRecentDecl()->isInline() &&
9120b57cec5SDimitry Andric !VD->hasAttr<ExcludeFromExplicitInstantiationAttr>())
9130b57cec5SDimitry Andric continue;
9140b57cec5SDimitry Andric
9150b57cec5SDimitry Andric // Skip VarDecls that lack formal definitions but which we know are in
9160b57cec5SDimitry Andric // fact defined somewhere.
9170b57cec5SDimitry Andric if (VD->isKnownToBeDefined())
9180b57cec5SDimitry Andric continue;
9190b57cec5SDimitry Andric }
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andric Undefined.push_back(std::make_pair(ND, UndefinedUse.second));
9220b57cec5SDimitry Andric }
9230b57cec5SDimitry Andric }
9240b57cec5SDimitry Andric
9250b57cec5SDimitry Andric /// checkUndefinedButUsed - Check for undefined objects with internal linkage
9260b57cec5SDimitry Andric /// or that are inline.
checkUndefinedButUsed(Sema & S)9270b57cec5SDimitry Andric static void checkUndefinedButUsed(Sema &S) {
9280b57cec5SDimitry Andric if (S.UndefinedButUsed.empty()) return;
9290b57cec5SDimitry Andric
9300b57cec5SDimitry Andric // Collect all the still-undefined entities with internal linkage.
9310b57cec5SDimitry Andric SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
9320b57cec5SDimitry Andric S.getUndefinedButUsed(Undefined);
9335f757f3fSDimitry Andric S.UndefinedButUsed.clear();
9340b57cec5SDimitry Andric if (Undefined.empty()) return;
9350b57cec5SDimitry Andric
93606c3fb27SDimitry Andric for (const auto &Undef : Undefined) {
9370b57cec5SDimitry Andric ValueDecl *VD = cast<ValueDecl>(Undef.first);
9380b57cec5SDimitry Andric SourceLocation UseLoc = Undef.second;
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andric if (S.isExternalWithNoLinkageType(VD)) {
9410b57cec5SDimitry Andric // C++ [basic.link]p8:
9420b57cec5SDimitry Andric // A type without linkage shall not be used as the type of a variable
9430b57cec5SDimitry Andric // or function with external linkage unless
9440b57cec5SDimitry Andric // -- the entity has C language linkage
9450b57cec5SDimitry Andric // -- the entity is not odr-used or is defined in the same TU
9460b57cec5SDimitry Andric //
9470b57cec5SDimitry Andric // As an extension, accept this in cases where the type is externally
9480b57cec5SDimitry Andric // visible, since the function or variable actually can be defined in
9490b57cec5SDimitry Andric // another translation unit in that case.
9500b57cec5SDimitry Andric S.Diag(VD->getLocation(), isExternallyVisible(VD->getType()->getLinkage())
9510b57cec5SDimitry Andric ? diag::ext_undefined_internal_type
9520b57cec5SDimitry Andric : diag::err_undefined_internal_type)
9530b57cec5SDimitry Andric << isa<VarDecl>(VD) << VD;
9540b57cec5SDimitry Andric } else if (!VD->isExternallyVisible()) {
9550b57cec5SDimitry Andric // FIXME: We can promote this to an error. The function or variable can't
9560b57cec5SDimitry Andric // be defined anywhere else, so the program must necessarily violate the
9570b57cec5SDimitry Andric // one definition rule.
958fe6060f1SDimitry Andric bool IsImplicitBase = false;
959fe6060f1SDimitry Andric if (const auto *BaseD = dyn_cast<FunctionDecl>(VD)) {
960fe6060f1SDimitry Andric auto *DVAttr = BaseD->getAttr<OMPDeclareVariantAttr>();
961fe6060f1SDimitry Andric if (DVAttr && !DVAttr->getTraitInfo().isExtensionActive(
962fe6060f1SDimitry Andric llvm::omp::TraitProperty::
963fe6060f1SDimitry Andric implementation_extension_disable_implicit_base)) {
964fe6060f1SDimitry Andric const auto *Func = cast<FunctionDecl>(
965fe6060f1SDimitry Andric cast<DeclRefExpr>(DVAttr->getVariantFuncRef())->getDecl());
966fe6060f1SDimitry Andric IsImplicitBase = BaseD->isImplicit() &&
967fe6060f1SDimitry Andric Func->getIdentifier()->isMangledOpenMPVariantName();
968fe6060f1SDimitry Andric }
969fe6060f1SDimitry Andric }
970fe6060f1SDimitry Andric if (!S.getLangOpts().OpenMP || !IsImplicitBase)
9710b57cec5SDimitry Andric S.Diag(VD->getLocation(), diag::warn_undefined_internal)
9720b57cec5SDimitry Andric << isa<VarDecl>(VD) << VD;
9730b57cec5SDimitry Andric } else if (auto *FD = dyn_cast<FunctionDecl>(VD)) {
9740b57cec5SDimitry Andric (void)FD;
9750b57cec5SDimitry Andric assert(FD->getMostRecentDecl()->isInlined() &&
9760b57cec5SDimitry Andric "used object requires definition but isn't inline or internal?");
9770b57cec5SDimitry Andric // FIXME: This is ill-formed; we should reject.
9780b57cec5SDimitry Andric S.Diag(VD->getLocation(), diag::warn_undefined_inline) << VD;
9790b57cec5SDimitry Andric } else {
9800b57cec5SDimitry Andric assert(cast<VarDecl>(VD)->getMostRecentDecl()->isInline() &&
9810b57cec5SDimitry Andric "used var requires definition but isn't inline or internal?");
9820b57cec5SDimitry Andric S.Diag(VD->getLocation(), diag::err_undefined_inline_var) << VD;
9830b57cec5SDimitry Andric }
9840b57cec5SDimitry Andric if (UseLoc.isValid())
9850b57cec5SDimitry Andric S.Diag(UseLoc, diag::note_used_here);
9860b57cec5SDimitry Andric }
9870b57cec5SDimitry Andric }
9880b57cec5SDimitry Andric
LoadExternalWeakUndeclaredIdentifiers()9890b57cec5SDimitry Andric void Sema::LoadExternalWeakUndeclaredIdentifiers() {
9900b57cec5SDimitry Andric if (!ExternalSource)
9910b57cec5SDimitry Andric return;
9920b57cec5SDimitry Andric
9930b57cec5SDimitry Andric SmallVector<std::pair<IdentifierInfo *, WeakInfo>, 4> WeakIDs;
9940b57cec5SDimitry Andric ExternalSource->ReadWeakUndeclaredIdentifiers(WeakIDs);
9950b57cec5SDimitry Andric for (auto &WeakID : WeakIDs)
99681ad6265SDimitry Andric (void)WeakUndeclaredIdentifiers[WeakID.first].insert(WeakID.second);
9970b57cec5SDimitry Andric }
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andric typedef llvm::DenseMap<const CXXRecordDecl*, bool> RecordCompleteMap;
10010b57cec5SDimitry Andric
10020b57cec5SDimitry Andric /// Returns true, if all methods and nested classes of the given
10030b57cec5SDimitry Andric /// CXXRecordDecl are defined in this translation unit.
10040b57cec5SDimitry Andric ///
10050b57cec5SDimitry Andric /// Should only be called from ActOnEndOfTranslationUnit so that all
10060b57cec5SDimitry Andric /// definitions are actually read.
MethodsAndNestedClassesComplete(const CXXRecordDecl * RD,RecordCompleteMap & MNCComplete)10070b57cec5SDimitry Andric static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD,
10080b57cec5SDimitry Andric RecordCompleteMap &MNCComplete) {
10090b57cec5SDimitry Andric RecordCompleteMap::iterator Cache = MNCComplete.find(RD);
10100b57cec5SDimitry Andric if (Cache != MNCComplete.end())
10110b57cec5SDimitry Andric return Cache->second;
10120b57cec5SDimitry Andric if (!RD->isCompleteDefinition())
10130b57cec5SDimitry Andric return false;
10140b57cec5SDimitry Andric bool Complete = true;
10150b57cec5SDimitry Andric for (DeclContext::decl_iterator I = RD->decls_begin(),
10160b57cec5SDimitry Andric E = RD->decls_end();
10170b57cec5SDimitry Andric I != E && Complete; ++I) {
10180b57cec5SDimitry Andric if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I))
10190b57cec5SDimitry Andric Complete = M->isDefined() || M->isDefaulted() ||
10207a6dacacSDimitry Andric (M->isPureVirtual() && !isa<CXXDestructorDecl>(M));
10210b57cec5SDimitry Andric else if (const FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(*I))
10220b57cec5SDimitry Andric // If the template function is marked as late template parsed at this
10230b57cec5SDimitry Andric // point, it has not been instantiated and therefore we have not
10240b57cec5SDimitry Andric // performed semantic analysis on it yet, so we cannot know if the type
10250b57cec5SDimitry Andric // can be considered complete.
10260b57cec5SDimitry Andric Complete = !F->getTemplatedDecl()->isLateTemplateParsed() &&
10270b57cec5SDimitry Andric F->getTemplatedDecl()->isDefined();
10280b57cec5SDimitry Andric else if (const CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(*I)) {
10290b57cec5SDimitry Andric if (R->isInjectedClassName())
10300b57cec5SDimitry Andric continue;
10310b57cec5SDimitry Andric if (R->hasDefinition())
10320b57cec5SDimitry Andric Complete = MethodsAndNestedClassesComplete(R->getDefinition(),
10330b57cec5SDimitry Andric MNCComplete);
10340b57cec5SDimitry Andric else
10350b57cec5SDimitry Andric Complete = false;
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric }
10380b57cec5SDimitry Andric MNCComplete[RD] = Complete;
10390b57cec5SDimitry Andric return Complete;
10400b57cec5SDimitry Andric }
10410b57cec5SDimitry Andric
10420b57cec5SDimitry Andric /// Returns true, if the given CXXRecordDecl is fully defined in this
10430b57cec5SDimitry Andric /// translation unit, i.e. all methods are defined or pure virtual and all
10440b57cec5SDimitry Andric /// friends, friend functions and nested classes are fully defined in this
10450b57cec5SDimitry Andric /// translation unit.
10460b57cec5SDimitry Andric ///
10470b57cec5SDimitry Andric /// Should only be called from ActOnEndOfTranslationUnit so that all
10480b57cec5SDimitry Andric /// definitions are actually read.
IsRecordFullyDefined(const CXXRecordDecl * RD,RecordCompleteMap & RecordsComplete,RecordCompleteMap & MNCComplete)10490b57cec5SDimitry Andric static bool IsRecordFullyDefined(const CXXRecordDecl *RD,
10500b57cec5SDimitry Andric RecordCompleteMap &RecordsComplete,
10510b57cec5SDimitry Andric RecordCompleteMap &MNCComplete) {
10520b57cec5SDimitry Andric RecordCompleteMap::iterator Cache = RecordsComplete.find(RD);
10530b57cec5SDimitry Andric if (Cache != RecordsComplete.end())
10540b57cec5SDimitry Andric return Cache->second;
10550b57cec5SDimitry Andric bool Complete = MethodsAndNestedClassesComplete(RD, MNCComplete);
10560b57cec5SDimitry Andric for (CXXRecordDecl::friend_iterator I = RD->friend_begin(),
10570b57cec5SDimitry Andric E = RD->friend_end();
10580b57cec5SDimitry Andric I != E && Complete; ++I) {
10590b57cec5SDimitry Andric // Check if friend classes and methods are complete.
10600b57cec5SDimitry Andric if (TypeSourceInfo *TSI = (*I)->getFriendType()) {
10610b57cec5SDimitry Andric // Friend classes are available as the TypeSourceInfo of the FriendDecl.
10620b57cec5SDimitry Andric if (CXXRecordDecl *FriendD = TSI->getType()->getAsCXXRecordDecl())
10630b57cec5SDimitry Andric Complete = MethodsAndNestedClassesComplete(FriendD, MNCComplete);
10640b57cec5SDimitry Andric else
10650b57cec5SDimitry Andric Complete = false;
10660b57cec5SDimitry Andric } else {
10670b57cec5SDimitry Andric // Friend functions are available through the NamedDecl of FriendDecl.
10680b57cec5SDimitry Andric if (const FunctionDecl *FD =
10690b57cec5SDimitry Andric dyn_cast<FunctionDecl>((*I)->getFriendDecl()))
10700b57cec5SDimitry Andric Complete = FD->isDefined();
10710b57cec5SDimitry Andric else
10720b57cec5SDimitry Andric // This is a template friend, give up.
10730b57cec5SDimitry Andric Complete = false;
10740b57cec5SDimitry Andric }
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric RecordsComplete[RD] = Complete;
10770b57cec5SDimitry Andric return Complete;
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric
emitAndClearUnusedLocalTypedefWarnings()10800b57cec5SDimitry Andric void Sema::emitAndClearUnusedLocalTypedefWarnings() {
10810b57cec5SDimitry Andric if (ExternalSource)
10820b57cec5SDimitry Andric ExternalSource->ReadUnusedLocalTypedefNameCandidates(
10830b57cec5SDimitry Andric UnusedLocalTypedefNameCandidates);
10840b57cec5SDimitry Andric for (const TypedefNameDecl *TD : UnusedLocalTypedefNameCandidates) {
10850b57cec5SDimitry Andric if (TD->isReferenced())
10860b57cec5SDimitry Andric continue;
10870b57cec5SDimitry Andric Diag(TD->getLocation(), diag::warn_unused_local_typedef)
10880b57cec5SDimitry Andric << isa<TypeAliasDecl>(TD) << TD->getDeclName();
10890b57cec5SDimitry Andric }
10900b57cec5SDimitry Andric UnusedLocalTypedefNameCandidates.clear();
10910b57cec5SDimitry Andric }
10920b57cec5SDimitry Andric
ActOnStartOfTranslationUnit()10930b57cec5SDimitry Andric void Sema::ActOnStartOfTranslationUnit() {
109481ad6265SDimitry Andric if (getLangOpts().CPlusPlusModules &&
109581ad6265SDimitry Andric getLangOpts().getCompilingModule() == LangOptions::CMK_HeaderUnit)
109681ad6265SDimitry Andric HandleStartOfHeaderUnit();
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric
ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind)10990b57cec5SDimitry Andric void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
11000b57cec5SDimitry Andric // No explicit actions are required at the end of the global module fragment.
11010b57cec5SDimitry Andric if (Kind == TUFragmentKind::Global)
11020b57cec5SDimitry Andric return;
11030b57cec5SDimitry Andric
11040b57cec5SDimitry Andric // Transfer late parsed template instantiations over to the pending template
11050b57cec5SDimitry Andric // instantiation list. During normal compilation, the late template parser
11060b57cec5SDimitry Andric // will be installed and instantiating these templates will succeed.
11070b57cec5SDimitry Andric //
11080b57cec5SDimitry Andric // If we are building a TU prefix for serialization, it is also safe to
11090b57cec5SDimitry Andric // transfer these over, even though they are not parsed. The end of the TU
11100b57cec5SDimitry Andric // should be outside of any eager template instantiation scope, so when this
11110b57cec5SDimitry Andric // AST is deserialized, these templates will not be parsed until the end of
11120b57cec5SDimitry Andric // the combined TU.
11130b57cec5SDimitry Andric PendingInstantiations.insert(PendingInstantiations.end(),
11140b57cec5SDimitry Andric LateParsedInstantiations.begin(),
11150b57cec5SDimitry Andric LateParsedInstantiations.end());
11160b57cec5SDimitry Andric LateParsedInstantiations.clear();
11170b57cec5SDimitry Andric
11180b57cec5SDimitry Andric // If DefinedUsedVTables ends up marking any virtual member functions it
11190b57cec5SDimitry Andric // might lead to more pending template instantiations, which we then need
11200b57cec5SDimitry Andric // to instantiate.
11210b57cec5SDimitry Andric DefineUsedVTables();
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric // C++: Perform implicit template instantiations.
11240b57cec5SDimitry Andric //
11250b57cec5SDimitry Andric // FIXME: When we perform these implicit instantiations, we do not
11260b57cec5SDimitry Andric // carefully keep track of the point of instantiation (C++ [temp.point]).
11270b57cec5SDimitry Andric // This means that name lookup that occurs within the template
11280b57cec5SDimitry Andric // instantiation will always happen at the end of the translation unit,
11290b57cec5SDimitry Andric // so it will find some names that are not required to be found. This is
11300b57cec5SDimitry Andric // valid, but we could do better by diagnosing if an instantiation uses a
11310b57cec5SDimitry Andric // name that was not visible at its first point of instantiation.
11320b57cec5SDimitry Andric if (ExternalSource) {
11330b57cec5SDimitry Andric // Load pending instantiations from the external source.
11340b57cec5SDimitry Andric SmallVector<PendingImplicitInstantiation, 4> Pending;
11350b57cec5SDimitry Andric ExternalSource->ReadPendingInstantiations(Pending);
11360b57cec5SDimitry Andric for (auto PII : Pending)
11370b57cec5SDimitry Andric if (auto Func = dyn_cast<FunctionDecl>(PII.first))
11380b57cec5SDimitry Andric Func->setInstantiationIsPending(true);
11390b57cec5SDimitry Andric PendingInstantiations.insert(PendingInstantiations.begin(),
11400b57cec5SDimitry Andric Pending.begin(), Pending.end());
11410b57cec5SDimitry Andric }
11420b57cec5SDimitry Andric
11430b57cec5SDimitry Andric {
1144480093f4SDimitry Andric llvm::TimeTraceScope TimeScope("PerformPendingInstantiations");
11450b57cec5SDimitry Andric PerformPendingInstantiations();
11460b57cec5SDimitry Andric }
11470b57cec5SDimitry Andric
11485ffd83dbSDimitry Andric emitDeferredDiags();
1149a7dea167SDimitry Andric
11500b57cec5SDimitry Andric assert(LateParsedInstantiations.empty() &&
11510b57cec5SDimitry Andric "end of TU template instantiation should not create more "
11520b57cec5SDimitry Andric "late-parsed templates");
1153a7dea167SDimitry Andric
1154a7dea167SDimitry Andric // Report diagnostics for uncorrected delayed typos. Ideally all of them
1155a7dea167SDimitry Andric // should have been corrected by that time, but it is very hard to cover all
1156a7dea167SDimitry Andric // cases in practice.
1157a7dea167SDimitry Andric for (const auto &Typo : DelayedTypos) {
1158a7dea167SDimitry Andric // We pass an empty TypoCorrection to indicate no correction was performed.
1159a7dea167SDimitry Andric Typo.second.DiagHandler(TypoCorrection());
1160a7dea167SDimitry Andric }
1161a7dea167SDimitry Andric DelayedTypos.clear();
11620b57cec5SDimitry Andric }
11630b57cec5SDimitry Andric
ActOnEndOfTranslationUnit()11640b57cec5SDimitry Andric void Sema::ActOnEndOfTranslationUnit() {
11650b57cec5SDimitry Andric assert(DelayedDiagnostics.getCurrentPool() == nullptr
11660b57cec5SDimitry Andric && "reached end of translation unit with a pool attached?");
11670b57cec5SDimitry Andric
11680b57cec5SDimitry Andric // If code completion is enabled, don't perform any end-of-translation-unit
11690b57cec5SDimitry Andric // work.
11700b57cec5SDimitry Andric if (PP.isCodeCompletionEnabled())
11710b57cec5SDimitry Andric return;
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andric // Complete translation units and modules define vtables and perform implicit
11740b57cec5SDimitry Andric // instantiations. PCH files do not.
11750b57cec5SDimitry Andric if (TUKind != TU_Prefix) {
1176*0fca6ea1SDimitry Andric ObjC().DiagnoseUseOfUnimplementedSelectors();
11770b57cec5SDimitry Andric
11780b57cec5SDimitry Andric ActOnEndOfTranslationUnitFragment(
11790b57cec5SDimitry Andric !ModuleScopes.empty() && ModuleScopes.back().Module->Kind ==
11800b57cec5SDimitry Andric Module::PrivateModuleFragment
11810b57cec5SDimitry Andric ? TUFragmentKind::Private
11820b57cec5SDimitry Andric : TUFragmentKind::Normal);
11830b57cec5SDimitry Andric
11840b57cec5SDimitry Andric if (LateTemplateParserCleanup)
11850b57cec5SDimitry Andric LateTemplateParserCleanup(OpaqueParser);
11860b57cec5SDimitry Andric
11870b57cec5SDimitry Andric CheckDelayedMemberExceptionSpecs();
11880b57cec5SDimitry Andric } else {
11890b57cec5SDimitry Andric // If we are building a TU prefix for serialization, it is safe to transfer
11900b57cec5SDimitry Andric // these over, even though they are not parsed. The end of the TU should be
11910b57cec5SDimitry Andric // outside of any eager template instantiation scope, so when this AST is
11920b57cec5SDimitry Andric // deserialized, these templates will not be parsed until the end of the
11930b57cec5SDimitry Andric // combined TU.
11940b57cec5SDimitry Andric PendingInstantiations.insert(PendingInstantiations.end(),
11950b57cec5SDimitry Andric LateParsedInstantiations.begin(),
11960b57cec5SDimitry Andric LateParsedInstantiations.end());
11970b57cec5SDimitry Andric LateParsedInstantiations.clear();
11985ffd83dbSDimitry Andric
11995ffd83dbSDimitry Andric if (LangOpts.PCHInstantiateTemplates) {
12005ffd83dbSDimitry Andric llvm::TimeTraceScope TimeScope("PerformPendingInstantiations");
12015ffd83dbSDimitry Andric PerformPendingInstantiations();
12025ffd83dbSDimitry Andric }
12030b57cec5SDimitry Andric }
12040b57cec5SDimitry Andric
1205e8d8bef9SDimitry Andric DiagnoseUnterminatedPragmaAlignPack();
12060b57cec5SDimitry Andric DiagnoseUnterminatedPragmaAttribute();
1207*0fca6ea1SDimitry Andric OpenMP().DiagnoseUnterminatedOpenMPDeclareTarget();
12080b57cec5SDimitry Andric
12090b57cec5SDimitry Andric // All delayed member exception specs should be checked or we end up accepting
12100b57cec5SDimitry Andric // incompatible declarations.
12110b57cec5SDimitry Andric assert(DelayedOverridingExceptionSpecChecks.empty());
12120b57cec5SDimitry Andric assert(DelayedEquivalentExceptionSpecChecks.empty());
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andric // All dllexport classes should have been processed already.
12150b57cec5SDimitry Andric assert(DelayedDllExportClasses.empty());
12160b57cec5SDimitry Andric assert(DelayedDllExportMemberFunctions.empty());
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andric // Remove file scoped decls that turned out to be used.
12190b57cec5SDimitry Andric UnusedFileScopedDecls.erase(
12200b57cec5SDimitry Andric std::remove_if(UnusedFileScopedDecls.begin(nullptr, true),
12210b57cec5SDimitry Andric UnusedFileScopedDecls.end(),
12220b57cec5SDimitry Andric [this](const DeclaratorDecl *DD) {
12230b57cec5SDimitry Andric return ShouldRemoveFromUnused(this, DD);
12240b57cec5SDimitry Andric }),
12250b57cec5SDimitry Andric UnusedFileScopedDecls.end());
12260b57cec5SDimitry Andric
12270b57cec5SDimitry Andric if (TUKind == TU_Prefix) {
12280b57cec5SDimitry Andric // Translation unit prefixes don't need any of the checking below.
12290b57cec5SDimitry Andric if (!PP.isIncrementalProcessingEnabled())
12300b57cec5SDimitry Andric TUScope = nullptr;
12310b57cec5SDimitry Andric return;
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric
12340b57cec5SDimitry Andric // Check for #pragma weak identifiers that were never declared
12350b57cec5SDimitry Andric LoadExternalWeakUndeclaredIdentifiers();
123681ad6265SDimitry Andric for (const auto &WeakIDs : WeakUndeclaredIdentifiers) {
123781ad6265SDimitry Andric if (WeakIDs.second.empty())
12380b57cec5SDimitry Andric continue;
12390b57cec5SDimitry Andric
124081ad6265SDimitry Andric Decl *PrevDecl = LookupSingleName(TUScope, WeakIDs.first, SourceLocation(),
12410b57cec5SDimitry Andric LookupOrdinaryName);
12420b57cec5SDimitry Andric if (PrevDecl != nullptr &&
12430b57cec5SDimitry Andric !(isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl)))
124481ad6265SDimitry Andric for (const auto &WI : WeakIDs.second)
124581ad6265SDimitry Andric Diag(WI.getLocation(), diag::warn_attribute_wrong_decl_type)
124606c3fb27SDimitry Andric << "'weak'" << /*isRegularKeyword=*/0 << ExpectedVariableOrFunction;
12470b57cec5SDimitry Andric else
124881ad6265SDimitry Andric for (const auto &WI : WeakIDs.second)
124981ad6265SDimitry Andric Diag(WI.getLocation(), diag::warn_weak_identifier_undeclared)
125081ad6265SDimitry Andric << WeakIDs.first;
12510b57cec5SDimitry Andric }
12520b57cec5SDimitry Andric
12530b57cec5SDimitry Andric if (LangOpts.CPlusPlus11 &&
12540b57cec5SDimitry Andric !Diags.isIgnored(diag::warn_delegating_ctor_cycle, SourceLocation()))
12550b57cec5SDimitry Andric CheckDelegatingCtorCycles();
12560b57cec5SDimitry Andric
12570b57cec5SDimitry Andric if (!Diags.hasErrorOccurred()) {
12580b57cec5SDimitry Andric if (ExternalSource)
12590b57cec5SDimitry Andric ExternalSource->ReadUndefinedButUsed(UndefinedButUsed);
12600b57cec5SDimitry Andric checkUndefinedButUsed(*this);
12610b57cec5SDimitry Andric }
12620b57cec5SDimitry Andric
12630b57cec5SDimitry Andric // A global-module-fragment is only permitted within a module unit.
126406c3fb27SDimitry Andric if (!ModuleScopes.empty() && ModuleScopes.back().Module->Kind ==
126506c3fb27SDimitry Andric Module::ExplicitGlobalModuleFragment) {
12660b57cec5SDimitry Andric Diag(ModuleScopes.back().BeginLoc,
12670b57cec5SDimitry Andric diag::err_module_declaration_missing_after_global_module_introducer);
12680b57cec5SDimitry Andric }
12690b57cec5SDimitry Andric
12705f757f3fSDimitry Andric // Now we can decide whether the modules we're building need an initializer.
12715f757f3fSDimitry Andric if (Module *CurrentModule = getCurrentModule();
12725f757f3fSDimitry Andric CurrentModule && CurrentModule->isInterfaceOrPartition()) {
12735f757f3fSDimitry Andric auto DoesModNeedInit = [this](Module *M) {
12745f757f3fSDimitry Andric if (!getASTContext().getModuleInitializers(M).empty())
12755f757f3fSDimitry Andric return true;
12765f757f3fSDimitry Andric for (auto [Exported, _] : M->Exports)
12775f757f3fSDimitry Andric if (Exported->isNamedModuleInterfaceHasInit())
12785f757f3fSDimitry Andric return true;
12795f757f3fSDimitry Andric for (Module *I : M->Imports)
12805f757f3fSDimitry Andric if (I->isNamedModuleInterfaceHasInit())
12815f757f3fSDimitry Andric return true;
12825f757f3fSDimitry Andric
12835f757f3fSDimitry Andric return false;
12845f757f3fSDimitry Andric };
12855f757f3fSDimitry Andric
12865f757f3fSDimitry Andric CurrentModule->NamedModuleHasInit =
12875f757f3fSDimitry Andric DoesModNeedInit(CurrentModule) ||
12885f757f3fSDimitry Andric llvm::any_of(CurrentModule->submodules(),
12895f757f3fSDimitry Andric [&](auto *SubM) { return DoesModNeedInit(SubM); });
12905f757f3fSDimitry Andric }
12915f757f3fSDimitry Andric
1292*0fca6ea1SDimitry Andric if (TUKind == TU_ClangModule) {
1293*0fca6ea1SDimitry Andric // If we are building a module, resolve all of the exported declarations
1294*0fca6ea1SDimitry Andric // now.
1295*0fca6ea1SDimitry Andric if (Module *CurrentModule = PP.getCurrentModule()) {
1296*0fca6ea1SDimitry Andric ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
1297*0fca6ea1SDimitry Andric
1298*0fca6ea1SDimitry Andric SmallVector<Module *, 2> Stack;
1299*0fca6ea1SDimitry Andric Stack.push_back(CurrentModule);
1300*0fca6ea1SDimitry Andric while (!Stack.empty()) {
1301*0fca6ea1SDimitry Andric Module *Mod = Stack.pop_back_val();
1302*0fca6ea1SDimitry Andric
1303*0fca6ea1SDimitry Andric // Resolve the exported declarations and conflicts.
1304*0fca6ea1SDimitry Andric // FIXME: Actually complain, once we figure out how to teach the
1305*0fca6ea1SDimitry Andric // diagnostic client to deal with complaints in the module map at this
1306*0fca6ea1SDimitry Andric // point.
1307*0fca6ea1SDimitry Andric ModMap.resolveExports(Mod, /*Complain=*/false);
1308*0fca6ea1SDimitry Andric ModMap.resolveUses(Mod, /*Complain=*/false);
1309*0fca6ea1SDimitry Andric ModMap.resolveConflicts(Mod, /*Complain=*/false);
1310*0fca6ea1SDimitry Andric
1311*0fca6ea1SDimitry Andric // Queue the submodules, so their exports will also be resolved.
1312*0fca6ea1SDimitry Andric auto SubmodulesRange = Mod->submodules();
1313*0fca6ea1SDimitry Andric Stack.append(SubmodulesRange.begin(), SubmodulesRange.end());
1314*0fca6ea1SDimitry Andric }
1315*0fca6ea1SDimitry Andric }
1316*0fca6ea1SDimitry Andric
13170b57cec5SDimitry Andric // Warnings emitted in ActOnEndOfTranslationUnit() should be emitted for
13180b57cec5SDimitry Andric // modules when they are built, not every time they are used.
13190b57cec5SDimitry Andric emitAndClearUnusedLocalTypedefWarnings();
13200b57cec5SDimitry Andric }
13210b57cec5SDimitry Andric
1322bdd1243dSDimitry Andric // C++ standard modules. Diagnose cases where a function is declared inline
1323bdd1243dSDimitry Andric // in the module purview but has no definition before the end of the TU or
1324bdd1243dSDimitry Andric // the start of a Private Module Fragment (if one is present).
1325bdd1243dSDimitry Andric if (!PendingInlineFuncDecls.empty()) {
1326bdd1243dSDimitry Andric for (auto *D : PendingInlineFuncDecls) {
1327bdd1243dSDimitry Andric if (auto *FD = dyn_cast<FunctionDecl>(D)) {
1328bdd1243dSDimitry Andric bool DefInPMF = false;
1329bdd1243dSDimitry Andric if (auto *FDD = FD->getDefinition()) {
1330bdd1243dSDimitry Andric DefInPMF = FDD->getOwningModule()->isPrivateModule();
1331bdd1243dSDimitry Andric if (!DefInPMF)
1332bdd1243dSDimitry Andric continue;
1333bdd1243dSDimitry Andric }
1334bdd1243dSDimitry Andric Diag(FD->getLocation(), diag::err_export_inline_not_defined)
1335bdd1243dSDimitry Andric << DefInPMF;
1336bdd1243dSDimitry Andric // If we have a PMF it should be at the end of the ModuleScopes.
1337bdd1243dSDimitry Andric if (DefInPMF &&
1338bdd1243dSDimitry Andric ModuleScopes.back().Module->Kind == Module::PrivateModuleFragment) {
1339bdd1243dSDimitry Andric Diag(ModuleScopes.back().BeginLoc,
1340bdd1243dSDimitry Andric diag::note_private_module_fragment);
1341bdd1243dSDimitry Andric }
1342bdd1243dSDimitry Andric }
1343bdd1243dSDimitry Andric }
1344bdd1243dSDimitry Andric PendingInlineFuncDecls.clear();
1345bdd1243dSDimitry Andric }
1346bdd1243dSDimitry Andric
13470b57cec5SDimitry Andric // C99 6.9.2p2:
13480b57cec5SDimitry Andric // A declaration of an identifier for an object that has file
13490b57cec5SDimitry Andric // scope without an initializer, and without a storage-class
13500b57cec5SDimitry Andric // specifier or with the storage-class specifier static,
13510b57cec5SDimitry Andric // constitutes a tentative definition. If a translation unit
13520b57cec5SDimitry Andric // contains one or more tentative definitions for an identifier,
13530b57cec5SDimitry Andric // and the translation unit contains no external definition for
13540b57cec5SDimitry Andric // that identifier, then the behavior is exactly as if the
13550b57cec5SDimitry Andric // translation unit contains a file scope declaration of that
13560b57cec5SDimitry Andric // identifier, with the composite type as of the end of the
13570b57cec5SDimitry Andric // translation unit, with an initializer equal to 0.
13580b57cec5SDimitry Andric llvm::SmallSet<VarDecl *, 32> Seen;
13590b57cec5SDimitry Andric for (TentativeDefinitionsType::iterator
1360bdd1243dSDimitry Andric T = TentativeDefinitions.begin(ExternalSource.get()),
13610b57cec5SDimitry Andric TEnd = TentativeDefinitions.end();
13620b57cec5SDimitry Andric T != TEnd; ++T) {
13630b57cec5SDimitry Andric VarDecl *VD = (*T)->getActingDefinition();
13640b57cec5SDimitry Andric
13650b57cec5SDimitry Andric // If the tentative definition was completed, getActingDefinition() returns
13660b57cec5SDimitry Andric // null. If we've already seen this variable before, insert()'s second
13670b57cec5SDimitry Andric // return value is false.
13680b57cec5SDimitry Andric if (!VD || VD->isInvalidDecl() || !Seen.insert(VD).second)
13690b57cec5SDimitry Andric continue;
13700b57cec5SDimitry Andric
13710b57cec5SDimitry Andric if (const IncompleteArrayType *ArrayT
13720b57cec5SDimitry Andric = Context.getAsIncompleteArrayType(VD->getType())) {
13730b57cec5SDimitry Andric // Set the length of the array to 1 (C99 6.9.2p5).
13740b57cec5SDimitry Andric Diag(VD->getLocation(), diag::warn_tentative_incomplete_array);
13750b57cec5SDimitry Andric llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true);
13765f757f3fSDimitry Andric QualType T = Context.getConstantArrayType(
13775f757f3fSDimitry Andric ArrayT->getElementType(), One, nullptr, ArraySizeModifier::Normal, 0);
13780b57cec5SDimitry Andric VD->setType(T);
13790b57cec5SDimitry Andric } else if (RequireCompleteType(VD->getLocation(), VD->getType(),
13800b57cec5SDimitry Andric diag::err_tentative_def_incomplete_type))
13810b57cec5SDimitry Andric VD->setInvalidDecl();
13820b57cec5SDimitry Andric
13830b57cec5SDimitry Andric // No initialization is performed for a tentative definition.
13840b57cec5SDimitry Andric CheckCompleteVariableDeclaration(VD);
13850b57cec5SDimitry Andric
13860b57cec5SDimitry Andric // Notify the consumer that we've completed a tentative definition.
13870b57cec5SDimitry Andric if (!VD->isInvalidDecl())
13880b57cec5SDimitry Andric Consumer.CompleteTentativeDefinition(VD);
13890b57cec5SDimitry Andric }
13900b57cec5SDimitry Andric
1391bdd1243dSDimitry Andric for (auto *D : ExternalDeclarations) {
1392480093f4SDimitry Andric if (!D || D->isInvalidDecl() || D->getPreviousDecl() || !D->isUsed())
1393480093f4SDimitry Andric continue;
1394480093f4SDimitry Andric
1395480093f4SDimitry Andric Consumer.CompleteExternalDeclaration(D);
1396480093f4SDimitry Andric }
1397480093f4SDimitry Andric
1398*0fca6ea1SDimitry Andric if (LangOpts.HLSL)
1399*0fca6ea1SDimitry Andric HLSL().DiagnoseAvailabilityViolations(
1400*0fca6ea1SDimitry Andric getASTContext().getTranslationUnitDecl());
1401*0fca6ea1SDimitry Andric
14020b57cec5SDimitry Andric // If there were errors, disable 'unused' warnings since they will mostly be
14030b57cec5SDimitry Andric // noise. Don't warn for a use from a module: either we should warn on all
14040b57cec5SDimitry Andric // file-scope declarations in modules or not at all, but whether the
14050b57cec5SDimitry Andric // declaration is used is immaterial.
1406*0fca6ea1SDimitry Andric if (!Diags.hasErrorOccurred() && TUKind != TU_ClangModule) {
14070b57cec5SDimitry Andric // Output warning for unused file scoped decls.
14080b57cec5SDimitry Andric for (UnusedFileScopedDeclsType::iterator
1409bdd1243dSDimitry Andric I = UnusedFileScopedDecls.begin(ExternalSource.get()),
1410bdd1243dSDimitry Andric E = UnusedFileScopedDecls.end();
1411bdd1243dSDimitry Andric I != E; ++I) {
14120b57cec5SDimitry Andric if (ShouldRemoveFromUnused(this, *I))
14130b57cec5SDimitry Andric continue;
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andric if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
14160b57cec5SDimitry Andric const FunctionDecl *DiagD;
14170b57cec5SDimitry Andric if (!FD->hasBody(DiagD))
14180b57cec5SDimitry Andric DiagD = FD;
14190b57cec5SDimitry Andric if (DiagD->isDeleted())
14200b57cec5SDimitry Andric continue; // Deleted functions are supposed to be unused.
142106c3fb27SDimitry Andric SourceRange DiagRange = DiagD->getLocation();
142206c3fb27SDimitry Andric if (const ASTTemplateArgumentListInfo *ASTTAL =
142306c3fb27SDimitry Andric DiagD->getTemplateSpecializationArgsAsWritten())
142406c3fb27SDimitry Andric DiagRange.setEnd(ASTTAL->RAngleLoc);
14250b57cec5SDimitry Andric if (DiagD->isReferenced()) {
14260b57cec5SDimitry Andric if (isa<CXXMethodDecl>(DiagD))
14270b57cec5SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unneeded_member_function)
142806c3fb27SDimitry Andric << DiagD << DiagRange;
14290b57cec5SDimitry Andric else {
14300b57cec5SDimitry Andric if (FD->getStorageClass() == SC_Static &&
14310b57cec5SDimitry Andric !FD->isInlineSpecified() &&
14320b57cec5SDimitry Andric !SourceMgr.isInMainFile(
14330b57cec5SDimitry Andric SourceMgr.getExpansionLoc(FD->getLocation())))
14340b57cec5SDimitry Andric Diag(DiagD->getLocation(),
14350b57cec5SDimitry Andric diag::warn_unneeded_static_internal_decl)
143606c3fb27SDimitry Andric << DiagD << DiagRange;
14370b57cec5SDimitry Andric else
14380b57cec5SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
143906c3fb27SDimitry Andric << /*function=*/0 << DiagD << DiagRange;
14400b57cec5SDimitry Andric }
1441*0fca6ea1SDimitry Andric } else if (!FD->isTargetMultiVersion() ||
1442*0fca6ea1SDimitry Andric FD->isTargetMultiVersionDefault()) {
14430b57cec5SDimitry Andric if (FD->getDescribedFunctionTemplate())
14440b57cec5SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unused_template)
144506c3fb27SDimitry Andric << /*function=*/0 << DiagD << DiagRange;
14460b57cec5SDimitry Andric else
1447e8d8bef9SDimitry Andric Diag(DiagD->getLocation(), isa<CXXMethodDecl>(DiagD)
1448e8d8bef9SDimitry Andric ? diag::warn_unused_member_function
14490b57cec5SDimitry Andric : diag::warn_unused_function)
145006c3fb27SDimitry Andric << DiagD << DiagRange;
14510b57cec5SDimitry Andric }
14520b57cec5SDimitry Andric } else {
14530b57cec5SDimitry Andric const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
14540b57cec5SDimitry Andric if (!DiagD)
14550b57cec5SDimitry Andric DiagD = cast<VarDecl>(*I);
145606c3fb27SDimitry Andric SourceRange DiagRange = DiagD->getLocation();
145706c3fb27SDimitry Andric if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(DiagD)) {
145806c3fb27SDimitry Andric if (const ASTTemplateArgumentListInfo *ASTTAL =
1459*0fca6ea1SDimitry Andric VTSD->getTemplateArgsAsWritten())
146006c3fb27SDimitry Andric DiagRange.setEnd(ASTTAL->RAngleLoc);
146106c3fb27SDimitry Andric }
14620b57cec5SDimitry Andric if (DiagD->isReferenced()) {
14630b57cec5SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
146406c3fb27SDimitry Andric << /*variable=*/1 << DiagD << DiagRange;
146506c3fb27SDimitry Andric } else if (DiagD->getDescribedVarTemplate()) {
146606c3fb27SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unused_template)
146706c3fb27SDimitry Andric << /*variable=*/1 << DiagD << DiagRange;
14680b57cec5SDimitry Andric } else if (DiagD->getType().isConstQualified()) {
14690b57cec5SDimitry Andric const SourceManager &SM = SourceMgr;
14700b57cec5SDimitry Andric if (SM.getMainFileID() != SM.getFileID(DiagD->getLocation()) ||
14710b57cec5SDimitry Andric !PP.getLangOpts().IsHeaderFile)
14720b57cec5SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unused_const_variable)
147306c3fb27SDimitry Andric << DiagD << DiagRange;
14740b57cec5SDimitry Andric } else {
147506c3fb27SDimitry Andric Diag(DiagD->getLocation(), diag::warn_unused_variable)
147606c3fb27SDimitry Andric << DiagD << DiagRange;
14770b57cec5SDimitry Andric }
14780b57cec5SDimitry Andric }
14790b57cec5SDimitry Andric }
14800b57cec5SDimitry Andric
14810b57cec5SDimitry Andric emitAndClearUnusedLocalTypedefWarnings();
14820b57cec5SDimitry Andric }
14830b57cec5SDimitry Andric
14840b57cec5SDimitry Andric if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) {
14850b57cec5SDimitry Andric // FIXME: Load additional unused private field candidates from the external
14860b57cec5SDimitry Andric // source.
14870b57cec5SDimitry Andric RecordCompleteMap RecordsComplete;
14880b57cec5SDimitry Andric RecordCompleteMap MNCComplete;
148906c3fb27SDimitry Andric for (const NamedDecl *D : UnusedPrivateFields) {
14900b57cec5SDimitry Andric const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext());
14910b57cec5SDimitry Andric if (RD && !RD->isUnion() &&
14920b57cec5SDimitry Andric IsRecordFullyDefined(RD, RecordsComplete, MNCComplete)) {
14930b57cec5SDimitry Andric Diag(D->getLocation(), diag::warn_unused_private_field)
14940b57cec5SDimitry Andric << D->getDeclName();
14950b57cec5SDimitry Andric }
14960b57cec5SDimitry Andric }
14970b57cec5SDimitry Andric }
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andric if (!Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) {
15000b57cec5SDimitry Andric if (ExternalSource)
15010b57cec5SDimitry Andric ExternalSource->ReadMismatchingDeleteExpressions(DeleteExprs);
15020b57cec5SDimitry Andric for (const auto &DeletedFieldInfo : DeleteExprs) {
15030b57cec5SDimitry Andric for (const auto &DeleteExprLoc : DeletedFieldInfo.second) {
15040b57cec5SDimitry Andric AnalyzeDeleteExprMismatch(DeletedFieldInfo.first, DeleteExprLoc.first,
15050b57cec5SDimitry Andric DeleteExprLoc.second);
15060b57cec5SDimitry Andric }
15070b57cec5SDimitry Andric }
15080b57cec5SDimitry Andric }
15090b57cec5SDimitry Andric
151006c3fb27SDimitry Andric AnalysisWarnings.IssueWarnings(Context.getTranslationUnitDecl());
151106c3fb27SDimitry Andric
15120b57cec5SDimitry Andric // Check we've noticed that we're no longer parsing the initializer for every
15130b57cec5SDimitry Andric // variable. If we miss cases, then at best we have a performance issue and
15140b57cec5SDimitry Andric // at worst a rejects-valid bug.
15150b57cec5SDimitry Andric assert(ParsingInitForAutoVars.empty() &&
15160b57cec5SDimitry Andric "Didn't unmark var as having its initializer parsed");
15170b57cec5SDimitry Andric
15180b57cec5SDimitry Andric if (!PP.isIncrementalProcessingEnabled())
15190b57cec5SDimitry Andric TUScope = nullptr;
15200b57cec5SDimitry Andric }
15210b57cec5SDimitry Andric
15220b57cec5SDimitry Andric
15230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15240b57cec5SDimitry Andric // Helper functions.
15250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15260b57cec5SDimitry Andric
getFunctionLevelDeclContext(bool AllowLambda) const152706c3fb27SDimitry Andric DeclContext *Sema::getFunctionLevelDeclContext(bool AllowLambda) const {
15280b57cec5SDimitry Andric DeclContext *DC = CurContext;
15290b57cec5SDimitry Andric
15300b57cec5SDimitry Andric while (true) {
153155e4f9d5SDimitry Andric if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC) || isa<CapturedDecl>(DC) ||
153255e4f9d5SDimitry Andric isa<RequiresExprBodyDecl>(DC)) {
15330b57cec5SDimitry Andric DC = DC->getParent();
153481ad6265SDimitry Andric } else if (!AllowLambda && isa<CXXMethodDecl>(DC) &&
15350b57cec5SDimitry Andric cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
15360b57cec5SDimitry Andric cast<CXXRecordDecl>(DC->getParent())->isLambda()) {
15370b57cec5SDimitry Andric DC = DC->getParent()->getParent();
153881ad6265SDimitry Andric } else break;
15390b57cec5SDimitry Andric }
15400b57cec5SDimitry Andric
15410b57cec5SDimitry Andric return DC;
15420b57cec5SDimitry Andric }
15430b57cec5SDimitry Andric
15440b57cec5SDimitry Andric /// getCurFunctionDecl - If inside of a function body, this returns a pointer
15450b57cec5SDimitry Andric /// to the function decl for the function being parsed. If we're currently
15460b57cec5SDimitry Andric /// in a 'block', this returns the containing context.
getCurFunctionDecl(bool AllowLambda) const154706c3fb27SDimitry Andric FunctionDecl *Sema::getCurFunctionDecl(bool AllowLambda) const {
154881ad6265SDimitry Andric DeclContext *DC = getFunctionLevelDeclContext(AllowLambda);
15490b57cec5SDimitry Andric return dyn_cast<FunctionDecl>(DC);
15500b57cec5SDimitry Andric }
15510b57cec5SDimitry Andric
getCurMethodDecl()15520b57cec5SDimitry Andric ObjCMethodDecl *Sema::getCurMethodDecl() {
15530b57cec5SDimitry Andric DeclContext *DC = getFunctionLevelDeclContext();
15540b57cec5SDimitry Andric while (isa<RecordDecl>(DC))
15550b57cec5SDimitry Andric DC = DC->getParent();
15560b57cec5SDimitry Andric return dyn_cast<ObjCMethodDecl>(DC);
15570b57cec5SDimitry Andric }
15580b57cec5SDimitry Andric
getCurFunctionOrMethodDecl() const155906c3fb27SDimitry Andric NamedDecl *Sema::getCurFunctionOrMethodDecl() const {
15600b57cec5SDimitry Andric DeclContext *DC = getFunctionLevelDeclContext();
15610b57cec5SDimitry Andric if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
15620b57cec5SDimitry Andric return cast<NamedDecl>(DC);
15630b57cec5SDimitry Andric return nullptr;
15640b57cec5SDimitry Andric }
15650b57cec5SDimitry Andric
getDefaultCXXMethodAddrSpace() const1566480093f4SDimitry Andric LangAS Sema::getDefaultCXXMethodAddrSpace() const {
1567480093f4SDimitry Andric if (getLangOpts().OpenCL)
1568349cc55cSDimitry Andric return getASTContext().getDefaultOpenCLPointeeAddrSpace();
1569480093f4SDimitry Andric return LangAS::Default;
1570480093f4SDimitry Andric }
1571480093f4SDimitry Andric
EmitCurrentDiagnostic(unsigned DiagID)15720b57cec5SDimitry Andric void Sema::EmitCurrentDiagnostic(unsigned DiagID) {
15730b57cec5SDimitry Andric // FIXME: It doesn't make sense to me that DiagID is an incoming argument here
15740b57cec5SDimitry Andric // and yet we also use the current diag ID on the DiagnosticsEngine. This has
15750b57cec5SDimitry Andric // been made more painfully obvious by the refactor that introduced this
15760b57cec5SDimitry Andric // function, but it is possible that the incoming argument can be
15770b57cec5SDimitry Andric // eliminated. If it truly cannot be (for example, there is some reentrancy
15780b57cec5SDimitry Andric // issue I am not seeing yet), then there should at least be a clarifying
15790b57cec5SDimitry Andric // comment somewhere.
1580bdd1243dSDimitry Andric if (std::optional<TemplateDeductionInfo *> Info = isSFINAEContext()) {
15810b57cec5SDimitry Andric switch (DiagnosticIDs::getDiagnosticSFINAEResponse(
15820b57cec5SDimitry Andric Diags.getCurrentDiagID())) {
15830b57cec5SDimitry Andric case DiagnosticIDs::SFINAE_Report:
15840b57cec5SDimitry Andric // We'll report the diagnostic below.
15850b57cec5SDimitry Andric break;
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andric case DiagnosticIDs::SFINAE_SubstitutionFailure:
15880b57cec5SDimitry Andric // Count this failure so that we know that template argument deduction
15890b57cec5SDimitry Andric // has failed.
15900b57cec5SDimitry Andric ++NumSFINAEErrors;
15910b57cec5SDimitry Andric
15920b57cec5SDimitry Andric // Make a copy of this suppressed diagnostic and store it with the
15930b57cec5SDimitry Andric // template-deduction information.
15940b57cec5SDimitry Andric if (*Info && !(*Info)->hasSFINAEDiagnostic()) {
15950b57cec5SDimitry Andric Diagnostic DiagInfo(&Diags);
15960b57cec5SDimitry Andric (*Info)->addSFINAEDiagnostic(DiagInfo.getLocation(),
15970b57cec5SDimitry Andric PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric
1600a7dea167SDimitry Andric Diags.setLastDiagnosticIgnored(true);
16010b57cec5SDimitry Andric Diags.Clear();
16020b57cec5SDimitry Andric return;
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andric case DiagnosticIDs::SFINAE_AccessControl: {
16050b57cec5SDimitry Andric // Per C++ Core Issue 1170, access control is part of SFINAE.
16060b57cec5SDimitry Andric // Additionally, the AccessCheckingSFINAE flag can be used to temporarily
16070b57cec5SDimitry Andric // make access control a part of SFINAE for the purposes of checking
16080b57cec5SDimitry Andric // type traits.
16090b57cec5SDimitry Andric if (!AccessCheckingSFINAE && !getLangOpts().CPlusPlus11)
16100b57cec5SDimitry Andric break;
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andric SourceLocation Loc = Diags.getCurrentDiagLoc();
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andric // Suppress this diagnostic.
16150b57cec5SDimitry Andric ++NumSFINAEErrors;
16160b57cec5SDimitry Andric
16170b57cec5SDimitry Andric // Make a copy of this suppressed diagnostic and store it with the
16180b57cec5SDimitry Andric // template-deduction information.
16190b57cec5SDimitry Andric if (*Info && !(*Info)->hasSFINAEDiagnostic()) {
16200b57cec5SDimitry Andric Diagnostic DiagInfo(&Diags);
16210b57cec5SDimitry Andric (*Info)->addSFINAEDiagnostic(DiagInfo.getLocation(),
16220b57cec5SDimitry Andric PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
16230b57cec5SDimitry Andric }
16240b57cec5SDimitry Andric
1625a7dea167SDimitry Andric Diags.setLastDiagnosticIgnored(true);
16260b57cec5SDimitry Andric Diags.Clear();
16270b57cec5SDimitry Andric
16280b57cec5SDimitry Andric // Now the diagnostic state is clear, produce a C++98 compatibility
16290b57cec5SDimitry Andric // warning.
16300b57cec5SDimitry Andric Diag(Loc, diag::warn_cxx98_compat_sfinae_access_control);
16310b57cec5SDimitry Andric
16320b57cec5SDimitry Andric // The last diagnostic which Sema produced was ignored. Suppress any
16330b57cec5SDimitry Andric // notes attached to it.
1634a7dea167SDimitry Andric Diags.setLastDiagnosticIgnored(true);
16350b57cec5SDimitry Andric return;
16360b57cec5SDimitry Andric }
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andric case DiagnosticIDs::SFINAE_Suppress:
16390b57cec5SDimitry Andric // Make a copy of this suppressed diagnostic and store it with the
16400b57cec5SDimitry Andric // template-deduction information;
16410b57cec5SDimitry Andric if (*Info) {
16420b57cec5SDimitry Andric Diagnostic DiagInfo(&Diags);
16430b57cec5SDimitry Andric (*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
16440b57cec5SDimitry Andric PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
16450b57cec5SDimitry Andric }
16460b57cec5SDimitry Andric
16470b57cec5SDimitry Andric // Suppress this diagnostic.
1648a7dea167SDimitry Andric Diags.setLastDiagnosticIgnored(true);
16490b57cec5SDimitry Andric Diags.Clear();
16500b57cec5SDimitry Andric return;
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric }
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andric // Copy the diagnostic printing policy over the ASTContext printing policy.
16550b57cec5SDimitry Andric // TODO: Stop doing that. See: https://reviews.llvm.org/D45093#1090292
16560b57cec5SDimitry Andric Context.setPrintingPolicy(getPrintingPolicy());
16570b57cec5SDimitry Andric
16580b57cec5SDimitry Andric // Emit the diagnostic.
16590b57cec5SDimitry Andric if (!Diags.EmitCurrentDiagnostic())
16600b57cec5SDimitry Andric return;
16610b57cec5SDimitry Andric
16620b57cec5SDimitry Andric // If this is not a note, and we're in a template instantiation
16630b57cec5SDimitry Andric // that is different from the last template instantiation where
16640b57cec5SDimitry Andric // we emitted an error, print a template instantiation
16650b57cec5SDimitry Andric // backtrace.
16660b57cec5SDimitry Andric if (!DiagnosticIDs::isBuiltinNote(DiagID))
16670b57cec5SDimitry Andric PrintContextStack();
16680b57cec5SDimitry Andric }
16690b57cec5SDimitry Andric
hasUncompilableErrorOccurred() const1670e8d8bef9SDimitry Andric bool Sema::hasUncompilableErrorOccurred() const {
1671e8d8bef9SDimitry Andric if (getDiagnostics().hasUncompilableErrorOccurred())
1672e8d8bef9SDimitry Andric return true;
1673e8d8bef9SDimitry Andric auto *FD = dyn_cast<FunctionDecl>(CurContext);
1674e8d8bef9SDimitry Andric if (!FD)
1675e8d8bef9SDimitry Andric return false;
1676e8d8bef9SDimitry Andric auto Loc = DeviceDeferredDiags.find(FD);
1677e8d8bef9SDimitry Andric if (Loc == DeviceDeferredDiags.end())
1678e8d8bef9SDimitry Andric return false;
1679e8d8bef9SDimitry Andric for (auto PDAt : Loc->second) {
1680e8d8bef9SDimitry Andric if (DiagnosticIDs::isDefaultMappingAsError(PDAt.second.getDiagID()))
1681e8d8bef9SDimitry Andric return true;
1682e8d8bef9SDimitry Andric }
1683e8d8bef9SDimitry Andric return false;
16840b57cec5SDimitry Andric }
16850b57cec5SDimitry Andric
16860b57cec5SDimitry Andric // Print notes showing how we can reach FD starting from an a priori
16870b57cec5SDimitry Andric // known-callable function.
emitCallStackNotes(Sema & S,const FunctionDecl * FD)168806c3fb27SDimitry Andric static void emitCallStackNotes(Sema &S, const FunctionDecl *FD) {
1689*0fca6ea1SDimitry Andric auto FnIt = S.CUDA().DeviceKnownEmittedFns.find(FD);
1690*0fca6ea1SDimitry Andric while (FnIt != S.CUDA().DeviceKnownEmittedFns.end()) {
16915ffd83dbSDimitry Andric // Respect error limit.
16925ffd83dbSDimitry Andric if (S.Diags.hasFatalErrorOccurred())
16935ffd83dbSDimitry Andric return;
16940b57cec5SDimitry Andric DiagnosticBuilder Builder(
16950b57cec5SDimitry Andric S.Diags.Report(FnIt->second.Loc, diag::note_called_by));
16960b57cec5SDimitry Andric Builder << FnIt->second.FD;
1697*0fca6ea1SDimitry Andric FnIt = S.CUDA().DeviceKnownEmittedFns.find(FnIt->second.FD);
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric }
17000b57cec5SDimitry Andric
17015ffd83dbSDimitry Andric namespace {
17025ffd83dbSDimitry Andric
17035ffd83dbSDimitry Andric /// Helper class that emits deferred diagnostic messages if an entity directly
17045ffd83dbSDimitry Andric /// or indirectly using the function that causes the deferred diagnostic
17055ffd83dbSDimitry Andric /// messages is known to be emitted.
17065ffd83dbSDimitry Andric ///
17075ffd83dbSDimitry Andric /// During parsing of AST, certain diagnostic messages are recorded as deferred
17085ffd83dbSDimitry Andric /// diagnostics since it is unknown whether the functions containing such
17095ffd83dbSDimitry Andric /// diagnostics will be emitted. A list of potentially emitted functions and
17105ffd83dbSDimitry Andric /// variables that may potentially trigger emission of functions are also
17115ffd83dbSDimitry Andric /// recorded. DeferredDiagnosticsEmitter recursively visits used functions
17125ffd83dbSDimitry Andric /// by each function to emit deferred diagnostics.
17135ffd83dbSDimitry Andric ///
17145ffd83dbSDimitry Andric /// During the visit, certain OpenMP directives or initializer of variables
17155ffd83dbSDimitry Andric /// with certain OpenMP attributes will cause subsequent visiting of any
17165ffd83dbSDimitry Andric /// functions enter a state which is called OpenMP device context in this
17175ffd83dbSDimitry Andric /// implementation. The state is exited when the directive or initializer is
17185ffd83dbSDimitry Andric /// exited. This state can change the emission states of subsequent uses
17195ffd83dbSDimitry Andric /// of functions.
17205ffd83dbSDimitry Andric ///
17215ffd83dbSDimitry Andric /// Conceptually the functions or variables to be visited form a use graph
17225ffd83dbSDimitry Andric /// where the parent node uses the child node. At any point of the visit,
17235ffd83dbSDimitry Andric /// the tree nodes traversed from the tree root to the current node form a use
17245ffd83dbSDimitry Andric /// stack. The emission state of the current node depends on two factors:
17255ffd83dbSDimitry Andric /// 1. the emission state of the root node
17265ffd83dbSDimitry Andric /// 2. whether the current node is in OpenMP device context
17275ffd83dbSDimitry Andric /// If the function is decided to be emitted, its contained deferred diagnostics
17285ffd83dbSDimitry Andric /// are emitted, together with the information about the use stack.
17295ffd83dbSDimitry Andric ///
17305ffd83dbSDimitry Andric class DeferredDiagnosticsEmitter
17315ffd83dbSDimitry Andric : public UsedDeclVisitor<DeferredDiagnosticsEmitter> {
17325ffd83dbSDimitry Andric public:
17335ffd83dbSDimitry Andric typedef UsedDeclVisitor<DeferredDiagnosticsEmitter> Inherited;
17345ffd83dbSDimitry Andric
17355ffd83dbSDimitry Andric // Whether the function is already in the current use-path.
1736e8d8bef9SDimitry Andric llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> InUsePath;
17375ffd83dbSDimitry Andric
17385ffd83dbSDimitry Andric // The current use-path.
17395ffd83dbSDimitry Andric llvm::SmallVector<CanonicalDeclPtr<FunctionDecl>, 4> UsePath;
17405ffd83dbSDimitry Andric
17415ffd83dbSDimitry Andric // Whether the visiting of the function has been done. Done[0] is for the
17425ffd83dbSDimitry Andric // case not in OpenMP device context. Done[1] is for the case in OpenMP
17435ffd83dbSDimitry Andric // device context. We need two sets because diagnostics emission may be
17445ffd83dbSDimitry Andric // different depending on whether it is in OpenMP device context.
1745e8d8bef9SDimitry Andric llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> DoneMap[2];
17465ffd83dbSDimitry Andric
17475ffd83dbSDimitry Andric // Emission state of the root node of the current use graph.
17485ffd83dbSDimitry Andric bool ShouldEmitRootNode;
17495ffd83dbSDimitry Andric
17505ffd83dbSDimitry Andric // Current OpenMP device context level. It is initialized to 0 and each
17515ffd83dbSDimitry Andric // entering of device context increases it by 1 and each exit decreases
17525ffd83dbSDimitry Andric // it by 1. Non-zero value indicates it is currently in device context.
17535ffd83dbSDimitry Andric unsigned InOMPDeviceContext;
17545ffd83dbSDimitry Andric
DeferredDiagnosticsEmitter(Sema & S)17555ffd83dbSDimitry Andric DeferredDiagnosticsEmitter(Sema &S)
17565ffd83dbSDimitry Andric : Inherited(S), ShouldEmitRootNode(false), InOMPDeviceContext(0) {}
17575ffd83dbSDimitry Andric
shouldVisitDiscardedStmt() const1758fe6060f1SDimitry Andric bool shouldVisitDiscardedStmt() const { return false; }
1759fe6060f1SDimitry Andric
VisitOMPTargetDirective(OMPTargetDirective * Node)17605ffd83dbSDimitry Andric void VisitOMPTargetDirective(OMPTargetDirective *Node) {
17615ffd83dbSDimitry Andric ++InOMPDeviceContext;
17625ffd83dbSDimitry Andric Inherited::VisitOMPTargetDirective(Node);
17635ffd83dbSDimitry Andric --InOMPDeviceContext;
17645ffd83dbSDimitry Andric }
17655ffd83dbSDimitry Andric
visitUsedDecl(SourceLocation Loc,Decl * D)17665ffd83dbSDimitry Andric void visitUsedDecl(SourceLocation Loc, Decl *D) {
17675ffd83dbSDimitry Andric if (isa<VarDecl>(D))
17685ffd83dbSDimitry Andric return;
17695ffd83dbSDimitry Andric if (auto *FD = dyn_cast<FunctionDecl>(D))
17705ffd83dbSDimitry Andric checkFunc(Loc, FD);
17715ffd83dbSDimitry Andric else
17725ffd83dbSDimitry Andric Inherited::visitUsedDecl(Loc, D);
17735ffd83dbSDimitry Andric }
17745ffd83dbSDimitry Andric
checkVar(VarDecl * VD)17755ffd83dbSDimitry Andric void checkVar(VarDecl *VD) {
17765ffd83dbSDimitry Andric assert(VD->isFileVarDecl() &&
17775ffd83dbSDimitry Andric "Should only check file-scope variables");
17785ffd83dbSDimitry Andric if (auto *Init = VD->getInit()) {
17795ffd83dbSDimitry Andric auto DevTy = OMPDeclareTargetDeclAttr::getDeviceType(VD);
17805ffd83dbSDimitry Andric bool IsDev = DevTy && (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost ||
17815ffd83dbSDimitry Andric *DevTy == OMPDeclareTargetDeclAttr::DT_Any);
17825ffd83dbSDimitry Andric if (IsDev)
17835ffd83dbSDimitry Andric ++InOMPDeviceContext;
17845ffd83dbSDimitry Andric this->Visit(Init);
17855ffd83dbSDimitry Andric if (IsDev)
17865ffd83dbSDimitry Andric --InOMPDeviceContext;
17875ffd83dbSDimitry Andric }
17885ffd83dbSDimitry Andric }
17895ffd83dbSDimitry Andric
checkFunc(SourceLocation Loc,FunctionDecl * FD)17905ffd83dbSDimitry Andric void checkFunc(SourceLocation Loc, FunctionDecl *FD) {
17915ffd83dbSDimitry Andric auto &Done = DoneMap[InOMPDeviceContext > 0 ? 1 : 0];
17925ffd83dbSDimitry Andric FunctionDecl *Caller = UsePath.empty() ? nullptr : UsePath.back();
17935ffd83dbSDimitry Andric if ((!ShouldEmitRootNode && !S.getLangOpts().OpenMP && !Caller) ||
17945ffd83dbSDimitry Andric S.shouldIgnoreInHostDeviceCheck(FD) || InUsePath.count(FD))
17955ffd83dbSDimitry Andric return;
17965ffd83dbSDimitry Andric // Finalize analysis of OpenMP-specific constructs.
1797e8d8bef9SDimitry Andric if (Caller && S.LangOpts.OpenMP && UsePath.size() == 1 &&
1798e8d8bef9SDimitry Andric (ShouldEmitRootNode || InOMPDeviceContext))
1799*0fca6ea1SDimitry Andric S.OpenMP().finalizeOpenMPDelayedAnalysis(Caller, FD, Loc);
18005ffd83dbSDimitry Andric if (Caller)
1801*0fca6ea1SDimitry Andric S.CUDA().DeviceKnownEmittedFns[FD] = {Caller, Loc};
18025ffd83dbSDimitry Andric // Always emit deferred diagnostics for the direct users. This does not
18035ffd83dbSDimitry Andric // lead to explosion of diagnostics since each user is visited at most
18045ffd83dbSDimitry Andric // twice.
18055ffd83dbSDimitry Andric if (ShouldEmitRootNode || InOMPDeviceContext)
18065ffd83dbSDimitry Andric emitDeferredDiags(FD, Caller);
18075ffd83dbSDimitry Andric // Do not revisit a function if the function body has been completely
18085ffd83dbSDimitry Andric // visited before.
18095ffd83dbSDimitry Andric if (!Done.insert(FD).second)
18105ffd83dbSDimitry Andric return;
18115ffd83dbSDimitry Andric InUsePath.insert(FD);
18125ffd83dbSDimitry Andric UsePath.push_back(FD);
18135ffd83dbSDimitry Andric if (auto *S = FD->getBody()) {
18145ffd83dbSDimitry Andric this->Visit(S);
18155ffd83dbSDimitry Andric }
18165ffd83dbSDimitry Andric UsePath.pop_back();
18175ffd83dbSDimitry Andric InUsePath.erase(FD);
18185ffd83dbSDimitry Andric }
18195ffd83dbSDimitry Andric
checkRecordedDecl(Decl * D)18205ffd83dbSDimitry Andric void checkRecordedDecl(Decl *D) {
18215ffd83dbSDimitry Andric if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18225ffd83dbSDimitry Andric ShouldEmitRootNode = S.getEmissionStatus(FD, /*Final=*/true) ==
18235ffd83dbSDimitry Andric Sema::FunctionEmissionStatus::Emitted;
18245ffd83dbSDimitry Andric checkFunc(SourceLocation(), FD);
18255ffd83dbSDimitry Andric } else
18265ffd83dbSDimitry Andric checkVar(cast<VarDecl>(D));
18275ffd83dbSDimitry Andric }
18285ffd83dbSDimitry Andric
18295ffd83dbSDimitry Andric // Emit any deferred diagnostics for FD
emitDeferredDiags(FunctionDecl * FD,bool ShowCallStack)18305ffd83dbSDimitry Andric void emitDeferredDiags(FunctionDecl *FD, bool ShowCallStack) {
18310b57cec5SDimitry Andric auto It = S.DeviceDeferredDiags.find(FD);
18320b57cec5SDimitry Andric if (It == S.DeviceDeferredDiags.end())
18330b57cec5SDimitry Andric return;
18340b57cec5SDimitry Andric bool HasWarningOrError = false;
18355ffd83dbSDimitry Andric bool FirstDiag = true;
18360b57cec5SDimitry Andric for (PartialDiagnosticAt &PDAt : It->second) {
18375ffd83dbSDimitry Andric // Respect error limit.
18385ffd83dbSDimitry Andric if (S.Diags.hasFatalErrorOccurred())
18395ffd83dbSDimitry Andric return;
18400b57cec5SDimitry Andric const SourceLocation &Loc = PDAt.first;
18410b57cec5SDimitry Andric const PartialDiagnostic &PD = PDAt.second;
18425ffd83dbSDimitry Andric HasWarningOrError |=
18435ffd83dbSDimitry Andric S.getDiagnostics().getDiagnosticLevel(PD.getDiagID(), Loc) >=
18445ffd83dbSDimitry Andric DiagnosticsEngine::Warning;
18455ffd83dbSDimitry Andric {
18460b57cec5SDimitry Andric DiagnosticBuilder Builder(S.Diags.Report(Loc, PD.getDiagID()));
18470b57cec5SDimitry Andric PD.Emit(Builder);
18480b57cec5SDimitry Andric }
18495ffd83dbSDimitry Andric // Emit the note on the first diagnostic in case too many diagnostics
18505ffd83dbSDimitry Andric // cause the note not emitted.
18515ffd83dbSDimitry Andric if (FirstDiag && HasWarningOrError && ShowCallStack) {
18520b57cec5SDimitry Andric emitCallStackNotes(S, FD);
18535ffd83dbSDimitry Andric FirstDiag = false;
18545ffd83dbSDimitry Andric }
18555ffd83dbSDimitry Andric }
18565ffd83dbSDimitry Andric }
18575ffd83dbSDimitry Andric };
18585ffd83dbSDimitry Andric } // namespace
18595ffd83dbSDimitry Andric
emitDeferredDiags()18605ffd83dbSDimitry Andric void Sema::emitDeferredDiags() {
18615ffd83dbSDimitry Andric if (ExternalSource)
18625ffd83dbSDimitry Andric ExternalSource->ReadDeclsToCheckForDeferredDiags(
18635ffd83dbSDimitry Andric DeclsToCheckForDeferredDiags);
18645ffd83dbSDimitry Andric
18655ffd83dbSDimitry Andric if ((DeviceDeferredDiags.empty() && !LangOpts.OpenMP) ||
18665ffd83dbSDimitry Andric DeclsToCheckForDeferredDiags.empty())
18675ffd83dbSDimitry Andric return;
18685ffd83dbSDimitry Andric
18695ffd83dbSDimitry Andric DeferredDiagnosticsEmitter DDE(*this);
1870bdd1243dSDimitry Andric for (auto *D : DeclsToCheckForDeferredDiags)
18715ffd83dbSDimitry Andric DDE.checkRecordedDecl(D);
18720b57cec5SDimitry Andric }
18730b57cec5SDimitry Andric
18740b57cec5SDimitry Andric // In CUDA, there are some constructs which may appear in semantically-valid
18750b57cec5SDimitry Andric // code, but trigger errors if we ever generate code for the function in which
18760b57cec5SDimitry Andric // they appear. Essentially every construct you're not allowed to use on the
18770b57cec5SDimitry Andric // device falls into this category, because you are allowed to use these
18780b57cec5SDimitry Andric // constructs in a __host__ __device__ function, but only if that function is
18790b57cec5SDimitry Andric // never codegen'ed on the device.
18800b57cec5SDimitry Andric //
18810b57cec5SDimitry Andric // To handle semantic checking for these constructs, we keep track of the set of
18820b57cec5SDimitry Andric // functions we know will be emitted, either because we could tell a priori that
18830b57cec5SDimitry Andric // they would be emitted, or because they were transitively called by a
18840b57cec5SDimitry Andric // known-emitted function.
18850b57cec5SDimitry Andric //
18860b57cec5SDimitry Andric // We also keep a partial call graph of which not-known-emitted functions call
18870b57cec5SDimitry Andric // which other not-known-emitted functions.
18880b57cec5SDimitry Andric //
18890b57cec5SDimitry Andric // When we see something which is illegal if the current function is emitted
1890*0fca6ea1SDimitry Andric // (usually by way of DiagIfDeviceCode, DiagIfHostCode, or
1891*0fca6ea1SDimitry Andric // CheckCall), we first check if the current function is known-emitted. If
18920b57cec5SDimitry Andric // so, we immediately output the diagnostic.
18930b57cec5SDimitry Andric //
18940b57cec5SDimitry Andric // Otherwise, we "defer" the diagnostic. It sits in Sema::DeviceDeferredDiags
18950b57cec5SDimitry Andric // until we discover that the function is known-emitted, at which point we take
18960b57cec5SDimitry Andric // it out of this map and emit the diagnostic.
18970b57cec5SDimitry Andric
SemaDiagnosticBuilder(Kind K,SourceLocation Loc,unsigned DiagID,const FunctionDecl * Fn,Sema & S)1898e8d8bef9SDimitry Andric Sema::SemaDiagnosticBuilder::SemaDiagnosticBuilder(Kind K, SourceLocation Loc,
1899e8d8bef9SDimitry Andric unsigned DiagID,
190006c3fb27SDimitry Andric const FunctionDecl *Fn,
190106c3fb27SDimitry Andric Sema &S)
19020b57cec5SDimitry Andric : S(S), Loc(Loc), DiagID(DiagID), Fn(Fn),
19030b57cec5SDimitry Andric ShowCallStack(K == K_ImmediateWithCallStack || K == K_Deferred) {
19040b57cec5SDimitry Andric switch (K) {
19050b57cec5SDimitry Andric case K_Nop:
19060b57cec5SDimitry Andric break;
19070b57cec5SDimitry Andric case K_Immediate:
19080b57cec5SDimitry Andric case K_ImmediateWithCallStack:
1909e8d8bef9SDimitry Andric ImmediateDiag.emplace(
1910e8d8bef9SDimitry Andric ImmediateDiagBuilder(S.Diags.Report(Loc, DiagID), S, DiagID));
19110b57cec5SDimitry Andric break;
19120b57cec5SDimitry Andric case K_Deferred:
19130b57cec5SDimitry Andric assert(Fn && "Must have a function to attach the deferred diag to.");
19140b57cec5SDimitry Andric auto &Diags = S.DeviceDeferredDiags[Fn];
19150b57cec5SDimitry Andric PartialDiagId.emplace(Diags.size());
19160b57cec5SDimitry Andric Diags.emplace_back(Loc, S.PDiag(DiagID));
19170b57cec5SDimitry Andric break;
19180b57cec5SDimitry Andric }
19190b57cec5SDimitry Andric }
19200b57cec5SDimitry Andric
SemaDiagnosticBuilder(SemaDiagnosticBuilder && D)1921e8d8bef9SDimitry Andric Sema::SemaDiagnosticBuilder::SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D)
19220b57cec5SDimitry Andric : S(D.S), Loc(D.Loc), DiagID(D.DiagID), Fn(D.Fn),
19230b57cec5SDimitry Andric ShowCallStack(D.ShowCallStack), ImmediateDiag(D.ImmediateDiag),
19240b57cec5SDimitry Andric PartialDiagId(D.PartialDiagId) {
19250b57cec5SDimitry Andric // Clean the previous diagnostics.
19260b57cec5SDimitry Andric D.ShowCallStack = false;
19270b57cec5SDimitry Andric D.ImmediateDiag.reset();
19280b57cec5SDimitry Andric D.PartialDiagId.reset();
19290b57cec5SDimitry Andric }
19300b57cec5SDimitry Andric
~SemaDiagnosticBuilder()1931e8d8bef9SDimitry Andric Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
19320b57cec5SDimitry Andric if (ImmediateDiag) {
19330b57cec5SDimitry Andric // Emit our diagnostic and, if it was a warning or error, output a callstack
19340b57cec5SDimitry Andric // if Fn isn't a priori known-emitted.
19350b57cec5SDimitry Andric bool IsWarningOrError = S.getDiagnostics().getDiagnosticLevel(
19360b57cec5SDimitry Andric DiagID, Loc) >= DiagnosticsEngine::Warning;
19370b57cec5SDimitry Andric ImmediateDiag.reset(); // Emit the immediate diag.
19380b57cec5SDimitry Andric if (IsWarningOrError && ShowCallStack)
19390b57cec5SDimitry Andric emitCallStackNotes(S, Fn);
19400b57cec5SDimitry Andric } else {
19410b57cec5SDimitry Andric assert((!PartialDiagId || ShowCallStack) &&
19420b57cec5SDimitry Andric "Must always show call stack for deferred diags.");
19430b57cec5SDimitry Andric }
19440b57cec5SDimitry Andric }
19450b57cec5SDimitry Andric
1946d409305fSDimitry Andric Sema::SemaDiagnosticBuilder
targetDiag(SourceLocation Loc,unsigned DiagID,const FunctionDecl * FD)194706c3fb27SDimitry Andric Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
1948d409305fSDimitry Andric FD = FD ? FD : getCurFunctionDecl();
1949a7dea167SDimitry Andric if (LangOpts.OpenMP)
195006c3fb27SDimitry Andric return LangOpts.OpenMPIsTargetDevice
1951*0fca6ea1SDimitry Andric ? OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD)
1952*0fca6ea1SDimitry Andric : OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
19530b57cec5SDimitry Andric if (getLangOpts().CUDA)
1954*0fca6ea1SDimitry Andric return getLangOpts().CUDAIsDevice ? CUDA().DiagIfDeviceCode(Loc, DiagID)
1955*0fca6ea1SDimitry Andric : CUDA().DiagIfHostCode(Loc, DiagID);
19565ffd83dbSDimitry Andric
19575ffd83dbSDimitry Andric if (getLangOpts().SYCLIsDevice)
1958*0fca6ea1SDimitry Andric return SYCL().DiagIfDeviceCode(Loc, DiagID);
19595ffd83dbSDimitry Andric
1960e8d8bef9SDimitry Andric return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc, DiagID,
1961d409305fSDimitry Andric FD, *this);
19620b57cec5SDimitry Andric }
19630b57cec5SDimitry Andric
checkTypeSupport(QualType Ty,SourceLocation Loc,ValueDecl * D)1964349cc55cSDimitry Andric void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
1965349cc55cSDimitry Andric if (isUnevaluatedContext() || Ty.isNull())
19665ffd83dbSDimitry Andric return;
19675ffd83dbSDimitry Andric
196804eeddc0SDimitry Andric // The original idea behind checkTypeSupport function is that unused
196904eeddc0SDimitry Andric // declarations can be replaced with an array of bytes of the same size during
197004eeddc0SDimitry Andric // codegen, such replacement doesn't seem to be possible for types without
197104eeddc0SDimitry Andric // constant byte size like zero length arrays. So, do a deep check for SYCL.
197204eeddc0SDimitry Andric if (D && LangOpts.SYCLIsDevice) {
197304eeddc0SDimitry Andric llvm::DenseSet<QualType> Visited;
1974*0fca6ea1SDimitry Andric SYCL().deepTypeCheckForDevice(Loc, Visited, D);
197504eeddc0SDimitry Andric }
197604eeddc0SDimitry Andric
19775ffd83dbSDimitry Andric Decl *C = cast<Decl>(getCurLexicalContext());
19785ffd83dbSDimitry Andric
19795ffd83dbSDimitry Andric // Memcpy operations for structs containing a member with unsupported type
19805ffd83dbSDimitry Andric // are ok, though.
19815ffd83dbSDimitry Andric if (const auto *MD = dyn_cast<CXXMethodDecl>(C)) {
19825ffd83dbSDimitry Andric if ((MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) &&
19835ffd83dbSDimitry Andric MD->isTrivial())
19845ffd83dbSDimitry Andric return;
19855ffd83dbSDimitry Andric
19865ffd83dbSDimitry Andric if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(MD))
19875ffd83dbSDimitry Andric if (Ctor->isCopyOrMoveConstructor() && Ctor->isTrivial())
19885ffd83dbSDimitry Andric return;
19895ffd83dbSDimitry Andric }
19905ffd83dbSDimitry Andric
1991d409305fSDimitry Andric // Try to associate errors with the lexical context, if that is a function, or
1992d409305fSDimitry Andric // the value declaration otherwise.
199306c3fb27SDimitry Andric const FunctionDecl *FD = isa<FunctionDecl>(C)
199406c3fb27SDimitry Andric ? cast<FunctionDecl>(C)
1995349cc55cSDimitry Andric : dyn_cast_or_null<FunctionDecl>(D);
1996349cc55cSDimitry Andric
1997349cc55cSDimitry Andric auto CheckDeviceType = [&](QualType Ty) {
19985ffd83dbSDimitry Andric if (Ty->isDependentType())
19995ffd83dbSDimitry Andric return;
20005ffd83dbSDimitry Andric
20010eae32dcSDimitry Andric if (Ty->isBitIntType()) {
20020eae32dcSDimitry Andric if (!Context.getTargetInfo().hasBitIntType()) {
2003349cc55cSDimitry Andric PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
2004349cc55cSDimitry Andric if (D)
2005349cc55cSDimitry Andric PD << D;
2006349cc55cSDimitry Andric else
2007349cc55cSDimitry Andric PD << "expression";
2008349cc55cSDimitry Andric targetDiag(Loc, PD, FD)
2009349cc55cSDimitry Andric << false /*show bit size*/ << 0 /*bitsize*/ << false /*return*/
2010e8d8bef9SDimitry Andric << Ty << Context.getTargetInfo().getTriple().str();
2011e8d8bef9SDimitry Andric }
2012e8d8bef9SDimitry Andric return;
2013e8d8bef9SDimitry Andric }
2014e8d8bef9SDimitry Andric
2015349cc55cSDimitry Andric // Check if we are dealing with two 'long double' but with different
2016349cc55cSDimitry Andric // semantics.
2017349cc55cSDimitry Andric bool LongDoubleMismatched = false;
2018349cc55cSDimitry Andric if (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128) {
2019349cc55cSDimitry Andric const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(Ty);
2020349cc55cSDimitry Andric if ((&Sem != &llvm::APFloat::PPCDoubleDouble() &&
20215ffd83dbSDimitry Andric !Context.getTargetInfo().hasFloat128Type()) ||
2022349cc55cSDimitry Andric (&Sem == &llvm::APFloat::PPCDoubleDouble() &&
2023349cc55cSDimitry Andric !Context.getTargetInfo().hasIbm128Type()))
2024349cc55cSDimitry Andric LongDoubleMismatched = true;
2025349cc55cSDimitry Andric }
2026349cc55cSDimitry Andric
2027349cc55cSDimitry Andric if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
2028349cc55cSDimitry Andric (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) ||
2029349cc55cSDimitry Andric (Ty->isIbm128Type() && !Context.getTargetInfo().hasIbm128Type()) ||
20305ffd83dbSDimitry Andric (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
2031349cc55cSDimitry Andric !Context.getTargetInfo().hasInt128Type()) ||
203206c3fb27SDimitry Andric (Ty->isBFloat16Type() && !Context.getTargetInfo().hasBFloat16Type() &&
203306c3fb27SDimitry Andric !LangOpts.CUDAIsDevice) ||
2034349cc55cSDimitry Andric LongDoubleMismatched) {
2035349cc55cSDimitry Andric PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
2036349cc55cSDimitry Andric if (D)
2037349cc55cSDimitry Andric PD << D;
2038349cc55cSDimitry Andric else
2039349cc55cSDimitry Andric PD << "expression";
2040349cc55cSDimitry Andric
2041349cc55cSDimitry Andric if (targetDiag(Loc, PD, FD)
2042349cc55cSDimitry Andric << true /*show bit size*/
2043e8d8bef9SDimitry Andric << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
2044349cc55cSDimitry Andric << false /*return*/ << Context.getTargetInfo().getTriple().str()) {
2045349cc55cSDimitry Andric if (D)
2046d409305fSDimitry Andric D->setInvalidDecl();
2047349cc55cSDimitry Andric }
2048349cc55cSDimitry Andric if (D)
2049d409305fSDimitry Andric targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
20505ffd83dbSDimitry Andric }
20515ffd83dbSDimitry Andric };
20525ffd83dbSDimitry Andric
2053349cc55cSDimitry Andric auto CheckType = [&](QualType Ty, bool IsRetTy = false) {
205406c3fb27SDimitry Andric if (LangOpts.SYCLIsDevice ||
205506c3fb27SDimitry Andric (LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice) ||
205604eeddc0SDimitry Andric LangOpts.CUDAIsDevice)
2057349cc55cSDimitry Andric CheckDeviceType(Ty);
20585ffd83dbSDimitry Andric
2059349cc55cSDimitry Andric QualType UnqualTy = Ty.getCanonicalType().getUnqualifiedType();
2060349cc55cSDimitry Andric const TargetInfo &TI = Context.getTargetInfo();
2061349cc55cSDimitry Andric if (!TI.hasLongDoubleType() && UnqualTy == Context.LongDoubleTy) {
2062349cc55cSDimitry Andric PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
2063349cc55cSDimitry Andric if (D)
2064349cc55cSDimitry Andric PD << D;
2065349cc55cSDimitry Andric else
2066349cc55cSDimitry Andric PD << "expression";
2067349cc55cSDimitry Andric
2068349cc55cSDimitry Andric if (Diag(Loc, PD, FD)
2069349cc55cSDimitry Andric << false /*show bit size*/ << 0 << Ty << false /*return*/
207006c3fb27SDimitry Andric << TI.getTriple().str()) {
2071349cc55cSDimitry Andric if (D)
2072349cc55cSDimitry Andric D->setInvalidDecl();
2073349cc55cSDimitry Andric }
2074349cc55cSDimitry Andric if (D)
2075349cc55cSDimitry Andric targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
2076349cc55cSDimitry Andric }
2077349cc55cSDimitry Andric
2078349cc55cSDimitry Andric bool IsDouble = UnqualTy == Context.DoubleTy;
2079349cc55cSDimitry Andric bool IsFloat = UnqualTy == Context.FloatTy;
2080349cc55cSDimitry Andric if (IsRetTy && !TI.hasFPReturn() && (IsDouble || IsFloat)) {
2081349cc55cSDimitry Andric PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
2082349cc55cSDimitry Andric if (D)
2083349cc55cSDimitry Andric PD << D;
2084349cc55cSDimitry Andric else
2085349cc55cSDimitry Andric PD << "expression";
2086349cc55cSDimitry Andric
2087349cc55cSDimitry Andric if (Diag(Loc, PD, FD)
2088349cc55cSDimitry Andric << false /*show bit size*/ << 0 << Ty << true /*return*/
208906c3fb27SDimitry Andric << TI.getTriple().str()) {
2090349cc55cSDimitry Andric if (D)
2091349cc55cSDimitry Andric D->setInvalidDecl();
2092349cc55cSDimitry Andric }
2093349cc55cSDimitry Andric if (D)
2094349cc55cSDimitry Andric targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
2095349cc55cSDimitry Andric }
2096bdd1243dSDimitry Andric
2097*0fca6ea1SDimitry Andric if (TI.hasRISCVVTypes() && Ty->isRVVSizelessBuiltinType() && FD) {
2098bdd1243dSDimitry Andric llvm::StringMap<bool> CallerFeatureMap;
2099bdd1243dSDimitry Andric Context.getFunctionFeatureMap(CallerFeatureMap, FD);
2100*0fca6ea1SDimitry Andric RISCV().checkRVVTypeSupport(Ty, Loc, D, CallerFeatureMap);
2101*0fca6ea1SDimitry Andric }
2102*0fca6ea1SDimitry Andric
2103*0fca6ea1SDimitry Andric // Don't allow SVE types in functions without a SVE target.
2104*0fca6ea1SDimitry Andric if (Ty->isSVESizelessBuiltinType() && FD) {
2105*0fca6ea1SDimitry Andric llvm::StringMap<bool> CallerFeatureMap;
2106*0fca6ea1SDimitry Andric Context.getFunctionFeatureMap(CallerFeatureMap, FD);
2107*0fca6ea1SDimitry Andric if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
2108*0fca6ea1SDimitry Andric if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap))
2109*0fca6ea1SDimitry Andric Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
2110*0fca6ea1SDimitry Andric else if (!IsArmStreamingFunction(FD,
2111*0fca6ea1SDimitry Andric /*IncludeLocallyStreaming=*/true)) {
2112*0fca6ea1SDimitry Andric Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
2113*0fca6ea1SDimitry Andric }
2114*0fca6ea1SDimitry Andric }
2115bdd1243dSDimitry Andric }
2116349cc55cSDimitry Andric };
2117349cc55cSDimitry Andric
2118349cc55cSDimitry Andric CheckType(Ty);
21195ffd83dbSDimitry Andric if (const auto *FPTy = dyn_cast<FunctionProtoType>(Ty)) {
21205ffd83dbSDimitry Andric for (const auto &ParamTy : FPTy->param_types())
21215ffd83dbSDimitry Andric CheckType(ParamTy);
2122349cc55cSDimitry Andric CheckType(FPTy->getReturnType(), /*IsRetTy=*/true);
21235ffd83dbSDimitry Andric }
2124d409305fSDimitry Andric if (const auto *FNPTy = dyn_cast<FunctionNoProtoType>(Ty))
2125349cc55cSDimitry Andric CheckType(FNPTy->getReturnType(), /*IsRetTy=*/true);
21265ffd83dbSDimitry Andric }
21275ffd83dbSDimitry Andric
findMacroSpelling(SourceLocation & locref,StringRef name)21280b57cec5SDimitry Andric bool Sema::findMacroSpelling(SourceLocation &locref, StringRef name) {
21290b57cec5SDimitry Andric SourceLocation loc = locref;
21300b57cec5SDimitry Andric if (!loc.isMacroID()) return false;
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andric // There's no good way right now to look at the intermediate
21330b57cec5SDimitry Andric // expansions, so just jump to the expansion location.
21340b57cec5SDimitry Andric loc = getSourceManager().getExpansionLoc(loc);
21350b57cec5SDimitry Andric
21360b57cec5SDimitry Andric // If that's written with the name, stop here.
2137e8d8bef9SDimitry Andric SmallString<16> buffer;
21380b57cec5SDimitry Andric if (getPreprocessor().getSpelling(loc, buffer) == name) {
21390b57cec5SDimitry Andric locref = loc;
21400b57cec5SDimitry Andric return true;
21410b57cec5SDimitry Andric }
21420b57cec5SDimitry Andric return false;
21430b57cec5SDimitry Andric }
21440b57cec5SDimitry Andric
getScopeForContext(DeclContext * Ctx)21450b57cec5SDimitry Andric Scope *Sema::getScopeForContext(DeclContext *Ctx) {
21460b57cec5SDimitry Andric
21470b57cec5SDimitry Andric if (!Ctx)
21480b57cec5SDimitry Andric return nullptr;
21490b57cec5SDimitry Andric
21500b57cec5SDimitry Andric Ctx = Ctx->getPrimaryContext();
21510b57cec5SDimitry Andric for (Scope *S = getCurScope(); S; S = S->getParent()) {
21520b57cec5SDimitry Andric // Ignore scopes that cannot have declarations. This is important for
21530b57cec5SDimitry Andric // out-of-line definitions of static class members.
21540b57cec5SDimitry Andric if (S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope))
21550b57cec5SDimitry Andric if (DeclContext *Entity = S->getEntity())
21560b57cec5SDimitry Andric if (Ctx == Entity->getPrimaryContext())
21570b57cec5SDimitry Andric return S;
21580b57cec5SDimitry Andric }
21590b57cec5SDimitry Andric
21600b57cec5SDimitry Andric return nullptr;
21610b57cec5SDimitry Andric }
21620b57cec5SDimitry Andric
21630b57cec5SDimitry Andric /// Enter a new function scope
PushFunctionScope()21640b57cec5SDimitry Andric void Sema::PushFunctionScope() {
21650b57cec5SDimitry Andric if (FunctionScopes.empty() && CachedFunctionScope) {
21660b57cec5SDimitry Andric // Use CachedFunctionScope to avoid allocating memory when possible.
21670b57cec5SDimitry Andric CachedFunctionScope->Clear();
21680b57cec5SDimitry Andric FunctionScopes.push_back(CachedFunctionScope.release());
21690b57cec5SDimitry Andric } else {
21700b57cec5SDimitry Andric FunctionScopes.push_back(new FunctionScopeInfo(getDiagnostics()));
21710b57cec5SDimitry Andric }
21720b57cec5SDimitry Andric if (LangOpts.OpenMP)
2173*0fca6ea1SDimitry Andric OpenMP().pushOpenMPFunctionRegion();
21740b57cec5SDimitry Andric }
21750b57cec5SDimitry Andric
PushBlockScope(Scope * BlockScope,BlockDecl * Block)21760b57cec5SDimitry Andric void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
21770b57cec5SDimitry Andric FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics(),
21780b57cec5SDimitry Andric BlockScope, Block));
217906c3fb27SDimitry Andric CapturingFunctionScopes++;
21800b57cec5SDimitry Andric }
21810b57cec5SDimitry Andric
PushLambdaScope()21820b57cec5SDimitry Andric LambdaScopeInfo *Sema::PushLambdaScope() {
21830b57cec5SDimitry Andric LambdaScopeInfo *const LSI = new LambdaScopeInfo(getDiagnostics());
21840b57cec5SDimitry Andric FunctionScopes.push_back(LSI);
218506c3fb27SDimitry Andric CapturingFunctionScopes++;
21860b57cec5SDimitry Andric return LSI;
21870b57cec5SDimitry Andric }
21880b57cec5SDimitry Andric
RecordParsingTemplateParameterDepth(unsigned Depth)21890b57cec5SDimitry Andric void Sema::RecordParsingTemplateParameterDepth(unsigned Depth) {
21900b57cec5SDimitry Andric if (LambdaScopeInfo *const LSI = getCurLambda()) {
21910b57cec5SDimitry Andric LSI->AutoTemplateParameterDepth = Depth;
21920b57cec5SDimitry Andric return;
21930b57cec5SDimitry Andric }
21940b57cec5SDimitry Andric llvm_unreachable(
21950b57cec5SDimitry Andric "Remove assertion if intentionally called in a non-lambda context.");
21960b57cec5SDimitry Andric }
21970b57cec5SDimitry Andric
21980b57cec5SDimitry Andric // Check that the type of the VarDecl has an accessible copy constructor and
21990b57cec5SDimitry Andric // resolve its destructor's exception specification.
2200fe6060f1SDimitry Andric // This also performs initialization of block variables when they are moved
2201fe6060f1SDimitry Andric // to the heap. It uses the same rules as applicable for implicit moves
2202fe6060f1SDimitry Andric // according to the C++ standard in effect ([class.copy.elision]p3).
checkEscapingByref(VarDecl * VD,Sema & S)22030b57cec5SDimitry Andric static void checkEscapingByref(VarDecl *VD, Sema &S) {
22040b57cec5SDimitry Andric QualType T = VD->getType();
22050b57cec5SDimitry Andric EnterExpressionEvaluationContext scope(
22060b57cec5SDimitry Andric S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
22070b57cec5SDimitry Andric SourceLocation Loc = VD->getLocation();
22080b57cec5SDimitry Andric Expr *VarRef =
22090b57cec5SDimitry Andric new (S.Context) DeclRefExpr(S.Context, VD, false, T, VK_LValue, Loc);
2210fe6060f1SDimitry Andric ExprResult Result;
221128a41182SDimitry Andric auto IE = InitializedEntity::InitializeBlock(Loc, T);
221206c3fb27SDimitry Andric if (S.getLangOpts().CPlusPlus23) {
2213fe6060f1SDimitry Andric auto *E = ImplicitCastExpr::Create(S.Context, T, CK_NoOp, VarRef, nullptr,
2214fe6060f1SDimitry Andric VK_XValue, FPOptionsOverride());
2215fe6060f1SDimitry Andric Result = S.PerformCopyInitialization(IE, SourceLocation(), E);
2216fe6060f1SDimitry Andric } else {
2217fe6060f1SDimitry Andric Result = S.PerformMoveOrCopyInitialization(
2218fe6060f1SDimitry Andric IE, Sema::NamedReturnInfo{VD, Sema::NamedReturnInfo::MoveEligible},
2219fe6060f1SDimitry Andric VarRef);
2220fe6060f1SDimitry Andric }
2221fe6060f1SDimitry Andric
22220b57cec5SDimitry Andric if (!Result.isInvalid()) {
22230b57cec5SDimitry Andric Result = S.MaybeCreateExprWithCleanups(Result);
22240b57cec5SDimitry Andric Expr *Init = Result.getAs<Expr>();
22250b57cec5SDimitry Andric S.Context.setBlockVarCopyInit(VD, Init, S.canThrow(Init));
22260b57cec5SDimitry Andric }
22270b57cec5SDimitry Andric
22280b57cec5SDimitry Andric // The destructor's exception specification is needed when IRGen generates
22290b57cec5SDimitry Andric // block copy/destroy functions. Resolve it here.
22300b57cec5SDimitry Andric if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
22310b57cec5SDimitry Andric if (CXXDestructorDecl *DD = RD->getDestructor()) {
2232*0fca6ea1SDimitry Andric auto *FPT = DD->getType()->castAs<FunctionProtoType>();
22330b57cec5SDimitry Andric S.ResolveExceptionSpec(Loc, FPT);
22340b57cec5SDimitry Andric }
22350b57cec5SDimitry Andric }
22360b57cec5SDimitry Andric
markEscapingByrefs(const FunctionScopeInfo & FSI,Sema & S)22370b57cec5SDimitry Andric static void markEscapingByrefs(const FunctionScopeInfo &FSI, Sema &S) {
22380b57cec5SDimitry Andric // Set the EscapingByref flag of __block variables captured by
22390b57cec5SDimitry Andric // escaping blocks.
22400b57cec5SDimitry Andric for (const BlockDecl *BD : FSI.Blocks) {
22410b57cec5SDimitry Andric for (const BlockDecl::Capture &BC : BD->captures()) {
22420b57cec5SDimitry Andric VarDecl *VD = BC.getVariable();
22430b57cec5SDimitry Andric if (VD->hasAttr<BlocksAttr>()) {
22440b57cec5SDimitry Andric // Nothing to do if this is a __block variable captured by a
22450b57cec5SDimitry Andric // non-escaping block.
22460b57cec5SDimitry Andric if (BD->doesNotEscape())
22470b57cec5SDimitry Andric continue;
22480b57cec5SDimitry Andric VD->setEscapingByref();
22490b57cec5SDimitry Andric }
22500b57cec5SDimitry Andric // Check whether the captured variable is or contains an object of
22510b57cec5SDimitry Andric // non-trivial C union type.
22520b57cec5SDimitry Andric QualType CapType = BC.getVariable()->getType();
22530b57cec5SDimitry Andric if (CapType.hasNonTrivialToPrimitiveDestructCUnion() ||
22540b57cec5SDimitry Andric CapType.hasNonTrivialToPrimitiveCopyCUnion())
22550b57cec5SDimitry Andric S.checkNonTrivialCUnion(BC.getVariable()->getType(),
22560b57cec5SDimitry Andric BD->getCaretLocation(),
22570b57cec5SDimitry Andric Sema::NTCUC_BlockCapture,
22580b57cec5SDimitry Andric Sema::NTCUK_Destruct|Sema::NTCUK_Copy);
22590b57cec5SDimitry Andric }
22600b57cec5SDimitry Andric }
22610b57cec5SDimitry Andric
22620b57cec5SDimitry Andric for (VarDecl *VD : FSI.ByrefBlockVars) {
22630b57cec5SDimitry Andric // __block variables might require us to capture a copy-initializer.
22640b57cec5SDimitry Andric if (!VD->isEscapingByref())
22650b57cec5SDimitry Andric continue;
22660b57cec5SDimitry Andric // It's currently invalid to ever have a __block variable with an
22670b57cec5SDimitry Andric // array type; should we diagnose that here?
22680b57cec5SDimitry Andric // Regardless, we don't want to ignore array nesting when
22690b57cec5SDimitry Andric // constructing this copy.
22700b57cec5SDimitry Andric if (VD->getType()->isStructureOrClassType())
22710b57cec5SDimitry Andric checkEscapingByref(VD, S);
22720b57cec5SDimitry Andric }
22730b57cec5SDimitry Andric }
22740b57cec5SDimitry Andric
22750b57cec5SDimitry Andric Sema::PoppedFunctionScopePtr
PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy * WP,const Decl * D,QualType BlockType)22760b57cec5SDimitry Andric Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
22770b57cec5SDimitry Andric const Decl *D, QualType BlockType) {
22780b57cec5SDimitry Andric assert(!FunctionScopes.empty() && "mismatched push/pop!");
22790b57cec5SDimitry Andric
22800b57cec5SDimitry Andric markEscapingByrefs(*FunctionScopes.back(), *this);
22810b57cec5SDimitry Andric
22820b57cec5SDimitry Andric PoppedFunctionScopePtr Scope(FunctionScopes.pop_back_val(),
22830b57cec5SDimitry Andric PoppedFunctionScopeDeleter(this));
22840b57cec5SDimitry Andric
22850b57cec5SDimitry Andric if (LangOpts.OpenMP)
2286*0fca6ea1SDimitry Andric OpenMP().popOpenMPFunctionRegion(Scope.get());
22870b57cec5SDimitry Andric
22880b57cec5SDimitry Andric // Issue any analysis-based warnings.
22890b57cec5SDimitry Andric if (WP && D)
22900b57cec5SDimitry Andric AnalysisWarnings.IssueWarnings(*WP, Scope.get(), D, BlockType);
22910b57cec5SDimitry Andric else
22920b57cec5SDimitry Andric for (const auto &PUD : Scope->PossiblyUnreachableDiags)
22930b57cec5SDimitry Andric Diag(PUD.Loc, PUD.PD);
22940b57cec5SDimitry Andric
22950b57cec5SDimitry Andric return Scope;
22960b57cec5SDimitry Andric }
22970b57cec5SDimitry Andric
22980b57cec5SDimitry Andric void Sema::PoppedFunctionScopeDeleter::
operator ()(sema::FunctionScopeInfo * Scope) const22990b57cec5SDimitry Andric operator()(sema::FunctionScopeInfo *Scope) const {
230006c3fb27SDimitry Andric if (!Scope->isPlainFunction())
230106c3fb27SDimitry Andric Self->CapturingFunctionScopes--;
23020b57cec5SDimitry Andric // Stash the function scope for later reuse if it's for a normal function.
23030b57cec5SDimitry Andric if (Scope->isPlainFunction() && !Self->CachedFunctionScope)
23040b57cec5SDimitry Andric Self->CachedFunctionScope.reset(Scope);
23050b57cec5SDimitry Andric else
23060b57cec5SDimitry Andric delete Scope;
23070b57cec5SDimitry Andric }
23080b57cec5SDimitry Andric
PushCompoundScope(bool IsStmtExpr)23090b57cec5SDimitry Andric void Sema::PushCompoundScope(bool IsStmtExpr) {
231081ad6265SDimitry Andric getCurFunction()->CompoundScopes.push_back(
231181ad6265SDimitry Andric CompoundScopeInfo(IsStmtExpr, getCurFPFeatures()));
23120b57cec5SDimitry Andric }
23130b57cec5SDimitry Andric
PopCompoundScope()23140b57cec5SDimitry Andric void Sema::PopCompoundScope() {
23150b57cec5SDimitry Andric FunctionScopeInfo *CurFunction = getCurFunction();
23160b57cec5SDimitry Andric assert(!CurFunction->CompoundScopes.empty() && "mismatched push/pop");
23170b57cec5SDimitry Andric
23180b57cec5SDimitry Andric CurFunction->CompoundScopes.pop_back();
23190b57cec5SDimitry Andric }
23200b57cec5SDimitry Andric
hasAnyUnrecoverableErrorsInThisFunction() const23210b57cec5SDimitry Andric bool Sema::hasAnyUnrecoverableErrorsInThisFunction() const {
23225ffd83dbSDimitry Andric return getCurFunction()->hasUnrecoverableErrorOccurred();
23230b57cec5SDimitry Andric }
23240b57cec5SDimitry Andric
setFunctionHasBranchIntoScope()23250b57cec5SDimitry Andric void Sema::setFunctionHasBranchIntoScope() {
23260b57cec5SDimitry Andric if (!FunctionScopes.empty())
23270b57cec5SDimitry Andric FunctionScopes.back()->setHasBranchIntoScope();
23280b57cec5SDimitry Andric }
23290b57cec5SDimitry Andric
setFunctionHasBranchProtectedScope()23300b57cec5SDimitry Andric void Sema::setFunctionHasBranchProtectedScope() {
23310b57cec5SDimitry Andric if (!FunctionScopes.empty())
23320b57cec5SDimitry Andric FunctionScopes.back()->setHasBranchProtectedScope();
23330b57cec5SDimitry Andric }
23340b57cec5SDimitry Andric
setFunctionHasIndirectGoto()23350b57cec5SDimitry Andric void Sema::setFunctionHasIndirectGoto() {
23360b57cec5SDimitry Andric if (!FunctionScopes.empty())
23370b57cec5SDimitry Andric FunctionScopes.back()->setHasIndirectGoto();
23380b57cec5SDimitry Andric }
23390b57cec5SDimitry Andric
setFunctionHasMustTail()2340fe6060f1SDimitry Andric void Sema::setFunctionHasMustTail() {
2341fe6060f1SDimitry Andric if (!FunctionScopes.empty())
2342fe6060f1SDimitry Andric FunctionScopes.back()->setHasMustTail();
2343fe6060f1SDimitry Andric }
2344fe6060f1SDimitry Andric
getCurBlock()23450b57cec5SDimitry Andric BlockScopeInfo *Sema::getCurBlock() {
23460b57cec5SDimitry Andric if (FunctionScopes.empty())
23470b57cec5SDimitry Andric return nullptr;
23480b57cec5SDimitry Andric
23490b57cec5SDimitry Andric auto CurBSI = dyn_cast<BlockScopeInfo>(FunctionScopes.back());
23500b57cec5SDimitry Andric if (CurBSI && CurBSI->TheDecl &&
23510b57cec5SDimitry Andric !CurBSI->TheDecl->Encloses(CurContext)) {
23520b57cec5SDimitry Andric // We have switched contexts due to template instantiation.
23530b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty());
23540b57cec5SDimitry Andric return nullptr;
23550b57cec5SDimitry Andric }
23560b57cec5SDimitry Andric
23570b57cec5SDimitry Andric return CurBSI;
23580b57cec5SDimitry Andric }
23590b57cec5SDimitry Andric
getEnclosingFunction() const23600b57cec5SDimitry Andric FunctionScopeInfo *Sema::getEnclosingFunction() const {
23610b57cec5SDimitry Andric if (FunctionScopes.empty())
23620b57cec5SDimitry Andric return nullptr;
23630b57cec5SDimitry Andric
23640b57cec5SDimitry Andric for (int e = FunctionScopes.size() - 1; e >= 0; --e) {
23650b57cec5SDimitry Andric if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
23660b57cec5SDimitry Andric continue;
23670b57cec5SDimitry Andric return FunctionScopes[e];
23680b57cec5SDimitry Andric }
23690b57cec5SDimitry Andric return nullptr;
23700b57cec5SDimitry Andric }
23710b57cec5SDimitry Andric
getEnclosingLambda() const2372a7dea167SDimitry Andric LambdaScopeInfo *Sema::getEnclosingLambda() const {
2373a7dea167SDimitry Andric for (auto *Scope : llvm::reverse(FunctionScopes)) {
2374a7dea167SDimitry Andric if (auto *LSI = dyn_cast<sema::LambdaScopeInfo>(Scope)) {
237506c3fb27SDimitry Andric if (LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
237606c3fb27SDimitry Andric LSI->AfterParameterList) {
2377a7dea167SDimitry Andric // We have switched contexts due to template instantiation.
2378a7dea167SDimitry Andric // FIXME: We should swap out the FunctionScopes during code synthesis
2379a7dea167SDimitry Andric // so that we don't need to check for this.
2380a7dea167SDimitry Andric assert(!CodeSynthesisContexts.empty());
2381a7dea167SDimitry Andric return nullptr;
2382a7dea167SDimitry Andric }
2383a7dea167SDimitry Andric return LSI;
2384a7dea167SDimitry Andric }
2385a7dea167SDimitry Andric }
2386a7dea167SDimitry Andric return nullptr;
2387a7dea167SDimitry Andric }
2388a7dea167SDimitry Andric
getCurLambda(bool IgnoreNonLambdaCapturingScope)23890b57cec5SDimitry Andric LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
23900b57cec5SDimitry Andric if (FunctionScopes.empty())
23910b57cec5SDimitry Andric return nullptr;
23920b57cec5SDimitry Andric
23930b57cec5SDimitry Andric auto I = FunctionScopes.rbegin();
23940b57cec5SDimitry Andric if (IgnoreNonLambdaCapturingScope) {
23950b57cec5SDimitry Andric auto E = FunctionScopes.rend();
23960b57cec5SDimitry Andric while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I))
23970b57cec5SDimitry Andric ++I;
23980b57cec5SDimitry Andric if (I == E)
23990b57cec5SDimitry Andric return nullptr;
24000b57cec5SDimitry Andric }
24010b57cec5SDimitry Andric auto *CurLSI = dyn_cast<LambdaScopeInfo>(*I);
240206c3fb27SDimitry Andric if (CurLSI && CurLSI->Lambda && CurLSI->CallOperator &&
240306c3fb27SDimitry Andric !CurLSI->Lambda->Encloses(CurContext) && CurLSI->AfterParameterList) {
24040b57cec5SDimitry Andric // We have switched contexts due to template instantiation.
24050b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty());
24060b57cec5SDimitry Andric return nullptr;
24070b57cec5SDimitry Andric }
24080b57cec5SDimitry Andric
24090b57cec5SDimitry Andric return CurLSI;
24100b57cec5SDimitry Andric }
2411a7dea167SDimitry Andric
24120b57cec5SDimitry Andric // We have a generic lambda if we parsed auto parameters, or we have
24130b57cec5SDimitry Andric // an associated template parameter list.
getCurGenericLambda()24140b57cec5SDimitry Andric LambdaScopeInfo *Sema::getCurGenericLambda() {
24150b57cec5SDimitry Andric if (LambdaScopeInfo *LSI = getCurLambda()) {
24160b57cec5SDimitry Andric return (LSI->TemplateParams.size() ||
24170b57cec5SDimitry Andric LSI->GLTemplateParameterList) ? LSI : nullptr;
24180b57cec5SDimitry Andric }
24190b57cec5SDimitry Andric return nullptr;
24200b57cec5SDimitry Andric }
24210b57cec5SDimitry Andric
24220b57cec5SDimitry Andric
ActOnComment(SourceRange Comment)24230b57cec5SDimitry Andric void Sema::ActOnComment(SourceRange Comment) {
24240b57cec5SDimitry Andric if (!LangOpts.RetainCommentsFromSystemHeaders &&
24250b57cec5SDimitry Andric SourceMgr.isInSystemHeader(Comment.getBegin()))
24260b57cec5SDimitry Andric return;
24270b57cec5SDimitry Andric RawComment RC(SourceMgr, Comment, LangOpts.CommentOpts, false);
242806c3fb27SDimitry Andric if (RC.isAlmostTrailingComment() || RC.hasUnsupportedSplice(SourceMgr)) {
24290b57cec5SDimitry Andric SourceRange MagicMarkerRange(Comment.getBegin(),
24300b57cec5SDimitry Andric Comment.getBegin().getLocWithOffset(3));
24310b57cec5SDimitry Andric StringRef MagicMarkerText;
24320b57cec5SDimitry Andric switch (RC.getKind()) {
24330b57cec5SDimitry Andric case RawComment::RCK_OrdinaryBCPL:
24340b57cec5SDimitry Andric MagicMarkerText = "///<";
24350b57cec5SDimitry Andric break;
24360b57cec5SDimitry Andric case RawComment::RCK_OrdinaryC:
24370b57cec5SDimitry Andric MagicMarkerText = "/**<";
24380b57cec5SDimitry Andric break;
243906c3fb27SDimitry Andric case RawComment::RCK_Invalid:
244006c3fb27SDimitry Andric // FIXME: are there other scenarios that could produce an invalid
244106c3fb27SDimitry Andric // raw comment here?
244206c3fb27SDimitry Andric Diag(Comment.getBegin(), diag::warn_splice_in_doxygen_comment);
244306c3fb27SDimitry Andric return;
24440b57cec5SDimitry Andric default:
24450b57cec5SDimitry Andric llvm_unreachable("if this is an almost Doxygen comment, "
24460b57cec5SDimitry Andric "it should be ordinary");
24470b57cec5SDimitry Andric }
24480b57cec5SDimitry Andric Diag(Comment.getBegin(), diag::warn_not_a_doxygen_trailing_member_comment) <<
24490b57cec5SDimitry Andric FixItHint::CreateReplacement(MagicMarkerRange, MagicMarkerText);
24500b57cec5SDimitry Andric }
24510b57cec5SDimitry Andric Context.addComment(RC);
24520b57cec5SDimitry Andric }
24530b57cec5SDimitry Andric
24540b57cec5SDimitry Andric // Pin this vtable to this file.
~ExternalSemaSource()24550b57cec5SDimitry Andric ExternalSemaSource::~ExternalSemaSource() {}
2456480093f4SDimitry Andric char ExternalSemaSource::ID;
24570b57cec5SDimitry Andric
ReadMethodPool(Selector Sel)24580b57cec5SDimitry Andric void ExternalSemaSource::ReadMethodPool(Selector Sel) { }
updateOutOfDateSelector(Selector Sel)24590b57cec5SDimitry Andric void ExternalSemaSource::updateOutOfDateSelector(Selector Sel) { }
24600b57cec5SDimitry Andric
ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl * > & Namespaces)24610b57cec5SDimitry Andric void ExternalSemaSource::ReadKnownNamespaces(
24620b57cec5SDimitry Andric SmallVectorImpl<NamespaceDecl *> &Namespaces) {
24630b57cec5SDimitry Andric }
24640b57cec5SDimitry Andric
ReadUndefinedButUsed(llvm::MapVector<NamedDecl *,SourceLocation> & Undefined)24650b57cec5SDimitry Andric void ExternalSemaSource::ReadUndefinedButUsed(
24660b57cec5SDimitry Andric llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {}
24670b57cec5SDimitry Andric
ReadMismatchingDeleteExpressions(llvm::MapVector<FieldDecl *,llvm::SmallVector<std::pair<SourceLocation,bool>,4>> &)24680b57cec5SDimitry Andric void ExternalSemaSource::ReadMismatchingDeleteExpressions(llvm::MapVector<
24690b57cec5SDimitry Andric FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &) {}
24700b57cec5SDimitry Andric
tryExprAsCall(Expr & E,QualType & ZeroArgCallReturnTy,UnresolvedSetImpl & OverloadSet)24710b57cec5SDimitry Andric bool Sema::tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
24720b57cec5SDimitry Andric UnresolvedSetImpl &OverloadSet) {
24730b57cec5SDimitry Andric ZeroArgCallReturnTy = QualType();
24740b57cec5SDimitry Andric OverloadSet.clear();
24750b57cec5SDimitry Andric
24760b57cec5SDimitry Andric const OverloadExpr *Overloads = nullptr;
24770b57cec5SDimitry Andric bool IsMemExpr = false;
24780b57cec5SDimitry Andric if (E.getType() == Context.OverloadTy) {
2479*0fca6ea1SDimitry Andric OverloadExpr::FindResult FR = OverloadExpr::find(&E);
24800b57cec5SDimitry Andric
24810b57cec5SDimitry Andric // Ignore overloads that are pointer-to-member constants.
24820b57cec5SDimitry Andric if (FR.HasFormOfMemberPointer)
24830b57cec5SDimitry Andric return false;
24840b57cec5SDimitry Andric
24850b57cec5SDimitry Andric Overloads = FR.Expression;
24860b57cec5SDimitry Andric } else if (E.getType() == Context.BoundMemberTy) {
24870b57cec5SDimitry Andric Overloads = dyn_cast<UnresolvedMemberExpr>(E.IgnoreParens());
24880b57cec5SDimitry Andric IsMemExpr = true;
24890b57cec5SDimitry Andric }
24900b57cec5SDimitry Andric
24910b57cec5SDimitry Andric bool Ambiguous = false;
24920b57cec5SDimitry Andric bool IsMV = false;
24930b57cec5SDimitry Andric
24940b57cec5SDimitry Andric if (Overloads) {
24950b57cec5SDimitry Andric for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
24960b57cec5SDimitry Andric DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
24970b57cec5SDimitry Andric OverloadSet.addDecl(*it);
24980b57cec5SDimitry Andric
24990b57cec5SDimitry Andric // Check whether the function is a non-template, non-member which takes no
25000b57cec5SDimitry Andric // arguments.
25010b57cec5SDimitry Andric if (IsMemExpr)
25020b57cec5SDimitry Andric continue;
25030b57cec5SDimitry Andric if (const FunctionDecl *OverloadDecl
25040b57cec5SDimitry Andric = dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl())) {
25050b57cec5SDimitry Andric if (OverloadDecl->getMinRequiredArguments() == 0) {
25060b57cec5SDimitry Andric if (!ZeroArgCallReturnTy.isNull() && !Ambiguous &&
25070b57cec5SDimitry Andric (!IsMV || !(OverloadDecl->isCPUDispatchMultiVersion() ||
25080b57cec5SDimitry Andric OverloadDecl->isCPUSpecificMultiVersion()))) {
25090b57cec5SDimitry Andric ZeroArgCallReturnTy = QualType();
25100b57cec5SDimitry Andric Ambiguous = true;
25110b57cec5SDimitry Andric } else {
25120b57cec5SDimitry Andric ZeroArgCallReturnTy = OverloadDecl->getReturnType();
25130b57cec5SDimitry Andric IsMV = OverloadDecl->isCPUDispatchMultiVersion() ||
25140b57cec5SDimitry Andric OverloadDecl->isCPUSpecificMultiVersion();
25150b57cec5SDimitry Andric }
25160b57cec5SDimitry Andric }
25170b57cec5SDimitry Andric }
25180b57cec5SDimitry Andric }
25190b57cec5SDimitry Andric
25200b57cec5SDimitry Andric // If it's not a member, use better machinery to try to resolve the call
25210b57cec5SDimitry Andric if (!IsMemExpr)
25220b57cec5SDimitry Andric return !ZeroArgCallReturnTy.isNull();
25230b57cec5SDimitry Andric }
25240b57cec5SDimitry Andric
25250b57cec5SDimitry Andric // Attempt to call the member with no arguments - this will correctly handle
25260b57cec5SDimitry Andric // member templates with defaults/deduction of template arguments, overloads
25270b57cec5SDimitry Andric // with default arguments, etc.
25280b57cec5SDimitry Andric if (IsMemExpr && !E.isTypeDependent()) {
2529a7dea167SDimitry Andric Sema::TentativeAnalysisScope Trap(*this);
25300b57cec5SDimitry Andric ExprResult R = BuildCallToMemberFunction(nullptr, &E, SourceLocation(),
2531bdd1243dSDimitry Andric std::nullopt, SourceLocation());
25320b57cec5SDimitry Andric if (R.isUsable()) {
25330b57cec5SDimitry Andric ZeroArgCallReturnTy = R.get()->getType();
25340b57cec5SDimitry Andric return true;
25350b57cec5SDimitry Andric }
25360b57cec5SDimitry Andric return false;
25370b57cec5SDimitry Andric }
25380b57cec5SDimitry Andric
253906c3fb27SDimitry Andric if (const auto *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) {
254006c3fb27SDimitry Andric if (const auto *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) {
25410b57cec5SDimitry Andric if (Fun->getMinRequiredArguments() == 0)
25420b57cec5SDimitry Andric ZeroArgCallReturnTy = Fun->getReturnType();
25430b57cec5SDimitry Andric return true;
25440b57cec5SDimitry Andric }
25450b57cec5SDimitry Andric }
25460b57cec5SDimitry Andric
25470b57cec5SDimitry Andric // We don't have an expression that's convenient to get a FunctionDecl from,
25480b57cec5SDimitry Andric // but we can at least check if the type is "function of 0 arguments".
25490b57cec5SDimitry Andric QualType ExprTy = E.getType();
25500b57cec5SDimitry Andric const FunctionType *FunTy = nullptr;
25510b57cec5SDimitry Andric QualType PointeeTy = ExprTy->getPointeeType();
25520b57cec5SDimitry Andric if (!PointeeTy.isNull())
25530b57cec5SDimitry Andric FunTy = PointeeTy->getAs<FunctionType>();
25540b57cec5SDimitry Andric if (!FunTy)
25550b57cec5SDimitry Andric FunTy = ExprTy->getAs<FunctionType>();
25560b57cec5SDimitry Andric
255706c3fb27SDimitry Andric if (const auto *FPT = dyn_cast_if_present<FunctionProtoType>(FunTy)) {
25580b57cec5SDimitry Andric if (FPT->getNumParams() == 0)
25590b57cec5SDimitry Andric ZeroArgCallReturnTy = FunTy->getReturnType();
25600b57cec5SDimitry Andric return true;
25610b57cec5SDimitry Andric }
25620b57cec5SDimitry Andric return false;
25630b57cec5SDimitry Andric }
25640b57cec5SDimitry Andric
25650b57cec5SDimitry Andric /// Give notes for a set of overloads.
25660b57cec5SDimitry Andric ///
25670b57cec5SDimitry Andric /// A companion to tryExprAsCall. In cases when the name that the programmer
25680b57cec5SDimitry Andric /// wrote was an overloaded function, we may be able to make some guesses about
25690b57cec5SDimitry Andric /// plausible overloads based on their return types; such guesses can be handed
25700b57cec5SDimitry Andric /// off to this method to be emitted as notes.
25710b57cec5SDimitry Andric ///
25720b57cec5SDimitry Andric /// \param Overloads - The overloads to note.
25730b57cec5SDimitry Andric /// \param FinalNoteLoc - If we've suppressed printing some overloads due to
25740b57cec5SDimitry Andric /// -fshow-overloads=best, this is the location to attach to the note about too
25750b57cec5SDimitry Andric /// many candidates. Typically this will be the location of the original
25760b57cec5SDimitry Andric /// ill-formed expression.
noteOverloads(Sema & S,const UnresolvedSetImpl & Overloads,const SourceLocation FinalNoteLoc)25770b57cec5SDimitry Andric static void noteOverloads(Sema &S, const UnresolvedSetImpl &Overloads,
25780b57cec5SDimitry Andric const SourceLocation FinalNoteLoc) {
2579fe6060f1SDimitry Andric unsigned ShownOverloads = 0;
2580fe6060f1SDimitry Andric unsigned SuppressedOverloads = 0;
25810b57cec5SDimitry Andric for (UnresolvedSetImpl::iterator It = Overloads.begin(),
25820b57cec5SDimitry Andric DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) {
2583fe6060f1SDimitry Andric if (ShownOverloads >= S.Diags.getNumOverloadCandidatesToShow()) {
25840b57cec5SDimitry Andric ++SuppressedOverloads;
25850b57cec5SDimitry Andric continue;
25860b57cec5SDimitry Andric }
25870b57cec5SDimitry Andric
258806c3fb27SDimitry Andric const NamedDecl *Fn = (*It)->getUnderlyingDecl();
25890b57cec5SDimitry Andric // Don't print overloads for non-default multiversioned functions.
25900b57cec5SDimitry Andric if (const auto *FD = Fn->getAsFunction()) {
25910b57cec5SDimitry Andric if (FD->isMultiVersion() && FD->hasAttr<TargetAttr>() &&
25920b57cec5SDimitry Andric !FD->getAttr<TargetAttr>()->isDefaultVersion())
25930b57cec5SDimitry Andric continue;
2594bdd1243dSDimitry Andric if (FD->isMultiVersion() && FD->hasAttr<TargetVersionAttr>() &&
2595bdd1243dSDimitry Andric !FD->getAttr<TargetVersionAttr>()->isDefaultVersion())
2596bdd1243dSDimitry Andric continue;
25970b57cec5SDimitry Andric }
25980b57cec5SDimitry Andric S.Diag(Fn->getLocation(), diag::note_possible_target_of_call);
25990b57cec5SDimitry Andric ++ShownOverloads;
26000b57cec5SDimitry Andric }
26010b57cec5SDimitry Andric
2602fe6060f1SDimitry Andric S.Diags.overloadCandidatesShown(ShownOverloads);
2603fe6060f1SDimitry Andric
26040b57cec5SDimitry Andric if (SuppressedOverloads)
26050b57cec5SDimitry Andric S.Diag(FinalNoteLoc, diag::note_ovl_too_many_candidates)
26060b57cec5SDimitry Andric << SuppressedOverloads;
26070b57cec5SDimitry Andric }
26080b57cec5SDimitry Andric
notePlausibleOverloads(Sema & S,SourceLocation Loc,const UnresolvedSetImpl & Overloads,bool (* IsPlausibleResult)(QualType))26090b57cec5SDimitry Andric static void notePlausibleOverloads(Sema &S, SourceLocation Loc,
26100b57cec5SDimitry Andric const UnresolvedSetImpl &Overloads,
26110b57cec5SDimitry Andric bool (*IsPlausibleResult)(QualType)) {
26120b57cec5SDimitry Andric if (!IsPlausibleResult)
26130b57cec5SDimitry Andric return noteOverloads(S, Overloads, Loc);
26140b57cec5SDimitry Andric
26150b57cec5SDimitry Andric UnresolvedSet<2> PlausibleOverloads;
26160b57cec5SDimitry Andric for (OverloadExpr::decls_iterator It = Overloads.begin(),
26170b57cec5SDimitry Andric DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) {
261806c3fb27SDimitry Andric const auto *OverloadDecl = cast<FunctionDecl>(*It);
26190b57cec5SDimitry Andric QualType OverloadResultTy = OverloadDecl->getReturnType();
26200b57cec5SDimitry Andric if (IsPlausibleResult(OverloadResultTy))
26210b57cec5SDimitry Andric PlausibleOverloads.addDecl(It.getDecl());
26220b57cec5SDimitry Andric }
26230b57cec5SDimitry Andric noteOverloads(S, PlausibleOverloads, Loc);
26240b57cec5SDimitry Andric }
26250b57cec5SDimitry Andric
26260b57cec5SDimitry Andric /// Determine whether the given expression can be called by just
26270b57cec5SDimitry Andric /// putting parentheses after it. Notably, expressions with unary
26280b57cec5SDimitry Andric /// operators can't be because the unary operator will start parsing
26290b57cec5SDimitry Andric /// outside the call.
IsCallableWithAppend(const Expr * E)263006c3fb27SDimitry Andric static bool IsCallableWithAppend(const Expr *E) {
26310b57cec5SDimitry Andric E = E->IgnoreImplicit();
26320b57cec5SDimitry Andric return (!isa<CStyleCastExpr>(E) &&
26330b57cec5SDimitry Andric !isa<UnaryOperator>(E) &&
26340b57cec5SDimitry Andric !isa<BinaryOperator>(E) &&
26350b57cec5SDimitry Andric !isa<CXXOperatorCallExpr>(E));
26360b57cec5SDimitry Andric }
26370b57cec5SDimitry Andric
IsCPUDispatchCPUSpecificMultiVersion(const Expr * E)26380b57cec5SDimitry Andric static bool IsCPUDispatchCPUSpecificMultiVersion(const Expr *E) {
26390b57cec5SDimitry Andric if (const auto *UO = dyn_cast<UnaryOperator>(E))
26400b57cec5SDimitry Andric E = UO->getSubExpr();
26410b57cec5SDimitry Andric
26420b57cec5SDimitry Andric if (const auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
26430b57cec5SDimitry Andric if (ULE->getNumDecls() == 0)
26440b57cec5SDimitry Andric return false;
26450b57cec5SDimitry Andric
26460b57cec5SDimitry Andric const NamedDecl *ND = *ULE->decls_begin();
26470b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(ND))
26480b57cec5SDimitry Andric return FD->isCPUDispatchMultiVersion() || FD->isCPUSpecificMultiVersion();
26490b57cec5SDimitry Andric }
26500b57cec5SDimitry Andric return false;
26510b57cec5SDimitry Andric }
26520b57cec5SDimitry Andric
tryToRecoverWithCall(ExprResult & E,const PartialDiagnostic & PD,bool ForceComplain,bool (* IsPlausibleResult)(QualType))26530b57cec5SDimitry Andric bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
26540b57cec5SDimitry Andric bool ForceComplain,
26550b57cec5SDimitry Andric bool (*IsPlausibleResult)(QualType)) {
26560b57cec5SDimitry Andric SourceLocation Loc = E.get()->getExprLoc();
26570b57cec5SDimitry Andric SourceRange Range = E.get()->getSourceRange();
26580b57cec5SDimitry Andric UnresolvedSet<4> Overloads;
26591fd87a68SDimitry Andric
26601fd87a68SDimitry Andric // If this is a SFINAE context, don't try anything that might trigger ADL
26611fd87a68SDimitry Andric // prematurely.
26621fd87a68SDimitry Andric if (!isSFINAEContext()) {
26631fd87a68SDimitry Andric QualType ZeroArgCallTy;
26640b57cec5SDimitry Andric if (tryExprAsCall(*E.get(), ZeroArgCallTy, Overloads) &&
26650b57cec5SDimitry Andric !ZeroArgCallTy.isNull() &&
26660b57cec5SDimitry Andric (!IsPlausibleResult || IsPlausibleResult(ZeroArgCallTy))) {
26670b57cec5SDimitry Andric // At this point, we know E is potentially callable with 0
26680b57cec5SDimitry Andric // arguments and that it returns something of a reasonable type,
26690b57cec5SDimitry Andric // so we can emit a fixit and carry on pretending that E was
26700b57cec5SDimitry Andric // actually a CallExpr.
26710b57cec5SDimitry Andric SourceLocation ParenInsertionLoc = getLocForEndOfToken(Range.getEnd());
26720b57cec5SDimitry Andric bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get());
26730b57cec5SDimitry Andric Diag(Loc, PD) << /*zero-arg*/ 1 << IsMV << Range
26740b57cec5SDimitry Andric << (IsCallableWithAppend(E.get())
26751fd87a68SDimitry Andric ? FixItHint::CreateInsertion(ParenInsertionLoc,
26761fd87a68SDimitry Andric "()")
26770b57cec5SDimitry Andric : FixItHint());
26780b57cec5SDimitry Andric if (!IsMV)
26790b57cec5SDimitry Andric notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult);
26800b57cec5SDimitry Andric
26810b57cec5SDimitry Andric // FIXME: Try this before emitting the fixit, and suppress diagnostics
26820b57cec5SDimitry Andric // while doing so.
2683bdd1243dSDimitry Andric E = BuildCallExpr(nullptr, E.get(), Range.getEnd(), std::nullopt,
26840b57cec5SDimitry Andric Range.getEnd().getLocWithOffset(1));
26850b57cec5SDimitry Andric return true;
26860b57cec5SDimitry Andric }
26871fd87a68SDimitry Andric }
26880b57cec5SDimitry Andric if (!ForceComplain) return false;
26890b57cec5SDimitry Andric
26900b57cec5SDimitry Andric bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get());
26910b57cec5SDimitry Andric Diag(Loc, PD) << /*not zero-arg*/ 0 << IsMV << Range;
26920b57cec5SDimitry Andric if (!IsMV)
26930b57cec5SDimitry Andric notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult);
26940b57cec5SDimitry Andric E = ExprError();
26950b57cec5SDimitry Andric return true;
26960b57cec5SDimitry Andric }
26970b57cec5SDimitry Andric
getSuperIdentifier() const26980b57cec5SDimitry Andric IdentifierInfo *Sema::getSuperIdentifier() const {
26990b57cec5SDimitry Andric if (!Ident_super)
27000b57cec5SDimitry Andric Ident_super = &Context.Idents.get("super");
27010b57cec5SDimitry Andric return Ident_super;
27020b57cec5SDimitry Andric }
27030b57cec5SDimitry Andric
PushCapturedRegionScope(Scope * S,CapturedDecl * CD,RecordDecl * RD,CapturedRegionKind K,unsigned OpenMPCaptureLevel)27040b57cec5SDimitry Andric void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD,
2705a7dea167SDimitry Andric CapturedRegionKind K,
2706a7dea167SDimitry Andric unsigned OpenMPCaptureLevel) {
2707a7dea167SDimitry Andric auto *CSI = new CapturedRegionScopeInfo(
27080b57cec5SDimitry Andric getDiagnostics(), S, CD, RD, CD->getContextParam(), K,
2709*0fca6ea1SDimitry Andric (getLangOpts().OpenMP && K == CR_OpenMP)
2710*0fca6ea1SDimitry Andric ? OpenMP().getOpenMPNestingLevel()
2711*0fca6ea1SDimitry Andric : 0,
2712a7dea167SDimitry Andric OpenMPCaptureLevel);
27130b57cec5SDimitry Andric CSI->ReturnType = Context.VoidTy;
27140b57cec5SDimitry Andric FunctionScopes.push_back(CSI);
271506c3fb27SDimitry Andric CapturingFunctionScopes++;
27160b57cec5SDimitry Andric }
27170b57cec5SDimitry Andric
getCurCapturedRegion()27180b57cec5SDimitry Andric CapturedRegionScopeInfo *Sema::getCurCapturedRegion() {
27190b57cec5SDimitry Andric if (FunctionScopes.empty())
27200b57cec5SDimitry Andric return nullptr;
27210b57cec5SDimitry Andric
27220b57cec5SDimitry Andric return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back());
27230b57cec5SDimitry Andric }
27240b57cec5SDimitry Andric
27250b57cec5SDimitry Andric const llvm::MapVector<FieldDecl *, Sema::DeleteLocs> &
getMismatchingDeleteExpressions() const27260b57cec5SDimitry Andric Sema::getMismatchingDeleteExpressions() const {
27270b57cec5SDimitry Andric return DeleteExprs;
27280b57cec5SDimitry Andric }
272981ad6265SDimitry Andric
FPFeaturesStateRAII(Sema & S)273081ad6265SDimitry Andric Sema::FPFeaturesStateRAII::FPFeaturesStateRAII(Sema &S)
273181ad6265SDimitry Andric : S(S), OldFPFeaturesState(S.CurFPFeatures),
273281ad6265SDimitry Andric OldOverrides(S.FpPragmaStack.CurrentValue),
273381ad6265SDimitry Andric OldEvalMethod(S.PP.getCurrentFPEvalMethod()),
273481ad6265SDimitry Andric OldFPPragmaLocation(S.PP.getLastFPEvalPragmaLocation()) {}
273581ad6265SDimitry Andric
~FPFeaturesStateRAII()273681ad6265SDimitry Andric Sema::FPFeaturesStateRAII::~FPFeaturesStateRAII() {
273781ad6265SDimitry Andric S.CurFPFeatures = OldFPFeaturesState;
273881ad6265SDimitry Andric S.FpPragmaStack.CurrentValue = OldOverrides;
273981ad6265SDimitry Andric S.PP.setCurrentFPEvalMethod(OldFPPragmaLocation, OldEvalMethod);
274081ad6265SDimitry Andric }
2741bdd1243dSDimitry Andric
isDeclaratorFunctionLike(Declarator & D)2742bdd1243dSDimitry Andric bool Sema::isDeclaratorFunctionLike(Declarator &D) {
2743bdd1243dSDimitry Andric assert(D.getCXXScopeSpec().isSet() &&
2744bdd1243dSDimitry Andric "can only be called for qualified names");
2745bdd1243dSDimitry Andric
2746bdd1243dSDimitry Andric auto LR = LookupResult(*this, D.getIdentifier(), D.getBeginLoc(),
2747bdd1243dSDimitry Andric LookupOrdinaryName, forRedeclarationInCurContext());
2748bdd1243dSDimitry Andric DeclContext *DC = computeDeclContext(D.getCXXScopeSpec(),
2749bdd1243dSDimitry Andric !D.getDeclSpec().isFriendSpecified());
2750bdd1243dSDimitry Andric if (!DC)
2751bdd1243dSDimitry Andric return false;
2752bdd1243dSDimitry Andric
2753bdd1243dSDimitry Andric LookupQualifiedName(LR, DC);
27547a6dacacSDimitry Andric bool Result = llvm::all_of(LR, [](Decl *Dcl) {
2755bdd1243dSDimitry Andric if (NamedDecl *ND = dyn_cast<NamedDecl>(Dcl)) {
2756bdd1243dSDimitry Andric ND = ND->getUnderlyingDecl();
2757bdd1243dSDimitry Andric return isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
2758bdd1243dSDimitry Andric isa<UsingDecl>(ND);
2759bdd1243dSDimitry Andric }
2760bdd1243dSDimitry Andric return false;
2761bdd1243dSDimitry Andric });
2762bdd1243dSDimitry Andric return Result;
2763bdd1243dSDimitry Andric }
2764*0fca6ea1SDimitry Andric
FunctionEffectDifferences(const FunctionEffectsRef & Old,const FunctionEffectsRef & New)2765*0fca6ea1SDimitry Andric FunctionEffectDifferences::FunctionEffectDifferences(
2766*0fca6ea1SDimitry Andric const FunctionEffectsRef &Old, const FunctionEffectsRef &New) {
2767*0fca6ea1SDimitry Andric
2768*0fca6ea1SDimitry Andric FunctionEffectsRef::iterator POld = Old.begin();
2769*0fca6ea1SDimitry Andric FunctionEffectsRef::iterator OldEnd = Old.end();
2770*0fca6ea1SDimitry Andric FunctionEffectsRef::iterator PNew = New.begin();
2771*0fca6ea1SDimitry Andric FunctionEffectsRef::iterator NewEnd = New.end();
2772*0fca6ea1SDimitry Andric
2773*0fca6ea1SDimitry Andric while (true) {
2774*0fca6ea1SDimitry Andric int cmp = 0;
2775*0fca6ea1SDimitry Andric if (POld == OldEnd) {
2776*0fca6ea1SDimitry Andric if (PNew == NewEnd)
2777*0fca6ea1SDimitry Andric break;
2778*0fca6ea1SDimitry Andric cmp = 1;
2779*0fca6ea1SDimitry Andric } else if (PNew == NewEnd)
2780*0fca6ea1SDimitry Andric cmp = -1;
2781*0fca6ea1SDimitry Andric else {
2782*0fca6ea1SDimitry Andric FunctionEffectWithCondition Old = *POld;
2783*0fca6ea1SDimitry Andric FunctionEffectWithCondition New = *PNew;
2784*0fca6ea1SDimitry Andric if (Old.Effect.kind() < New.Effect.kind())
2785*0fca6ea1SDimitry Andric cmp = -1;
2786*0fca6ea1SDimitry Andric else if (New.Effect.kind() < Old.Effect.kind())
2787*0fca6ea1SDimitry Andric cmp = 1;
2788*0fca6ea1SDimitry Andric else {
2789*0fca6ea1SDimitry Andric cmp = 0;
2790*0fca6ea1SDimitry Andric if (Old.Cond.getCondition() != New.Cond.getCondition()) {
2791*0fca6ea1SDimitry Andric // FIXME: Cases where the expressions are equivalent but
2792*0fca6ea1SDimitry Andric // don't have the same identity.
2793*0fca6ea1SDimitry Andric push_back(FunctionEffectDiff{
2794*0fca6ea1SDimitry Andric Old.Effect.kind(), FunctionEffectDiff::Kind::ConditionMismatch,
2795*0fca6ea1SDimitry Andric Old, New});
2796*0fca6ea1SDimitry Andric }
2797*0fca6ea1SDimitry Andric }
2798*0fca6ea1SDimitry Andric }
2799*0fca6ea1SDimitry Andric
2800*0fca6ea1SDimitry Andric if (cmp < 0) {
2801*0fca6ea1SDimitry Andric // removal
2802*0fca6ea1SDimitry Andric FunctionEffectWithCondition Old = *POld;
2803*0fca6ea1SDimitry Andric push_back(FunctionEffectDiff{
2804*0fca6ea1SDimitry Andric Old.Effect.kind(), FunctionEffectDiff::Kind::Removed, Old, {}});
2805*0fca6ea1SDimitry Andric ++POld;
2806*0fca6ea1SDimitry Andric } else if (cmp > 0) {
2807*0fca6ea1SDimitry Andric // addition
2808*0fca6ea1SDimitry Andric FunctionEffectWithCondition New = *PNew;
2809*0fca6ea1SDimitry Andric push_back(FunctionEffectDiff{
2810*0fca6ea1SDimitry Andric New.Effect.kind(), FunctionEffectDiff::Kind::Added, {}, New});
2811*0fca6ea1SDimitry Andric ++PNew;
2812*0fca6ea1SDimitry Andric } else {
2813*0fca6ea1SDimitry Andric ++POld;
2814*0fca6ea1SDimitry Andric ++PNew;
2815*0fca6ea1SDimitry Andric }
2816*0fca6ea1SDimitry Andric }
2817*0fca6ea1SDimitry Andric }
2818*0fca6ea1SDimitry Andric
shouldDiagnoseConversion(QualType SrcType,const FunctionEffectsRef & SrcFX,QualType DstType,const FunctionEffectsRef & DstFX) const2819*0fca6ea1SDimitry Andric bool FunctionEffectDiff::shouldDiagnoseConversion(
2820*0fca6ea1SDimitry Andric QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType,
2821*0fca6ea1SDimitry Andric const FunctionEffectsRef &DstFX) const {
2822*0fca6ea1SDimitry Andric
2823*0fca6ea1SDimitry Andric switch (EffectKind) {
2824*0fca6ea1SDimitry Andric case FunctionEffect::Kind::NonAllocating:
2825*0fca6ea1SDimitry Andric // nonallocating can't be added (spoofed) during a conversion, unless we
2826*0fca6ea1SDimitry Andric // have nonblocking.
2827*0fca6ea1SDimitry Andric if (DiffKind == Kind::Added) {
2828*0fca6ea1SDimitry Andric for (const auto &CFE : SrcFX) {
2829*0fca6ea1SDimitry Andric if (CFE.Effect.kind() == FunctionEffect::Kind::NonBlocking)
2830*0fca6ea1SDimitry Andric return false;
2831*0fca6ea1SDimitry Andric }
2832*0fca6ea1SDimitry Andric }
2833*0fca6ea1SDimitry Andric [[fallthrough]];
2834*0fca6ea1SDimitry Andric case FunctionEffect::Kind::NonBlocking:
2835*0fca6ea1SDimitry Andric // nonblocking can't be added (spoofed) during a conversion.
2836*0fca6ea1SDimitry Andric switch (DiffKind) {
2837*0fca6ea1SDimitry Andric case Kind::Added:
2838*0fca6ea1SDimitry Andric return true;
2839*0fca6ea1SDimitry Andric case Kind::Removed:
2840*0fca6ea1SDimitry Andric return false;
2841*0fca6ea1SDimitry Andric case Kind::ConditionMismatch:
2842*0fca6ea1SDimitry Andric // FIXME: Condition mismatches are too coarse right now -- expressions
2843*0fca6ea1SDimitry Andric // which are equivalent but don't have the same identity are detected as
2844*0fca6ea1SDimitry Andric // mismatches. We're going to diagnose those anyhow until expression
2845*0fca6ea1SDimitry Andric // matching is better.
2846*0fca6ea1SDimitry Andric return true;
2847*0fca6ea1SDimitry Andric }
2848*0fca6ea1SDimitry Andric case FunctionEffect::Kind::Blocking:
2849*0fca6ea1SDimitry Andric case FunctionEffect::Kind::Allocating:
2850*0fca6ea1SDimitry Andric return false;
2851*0fca6ea1SDimitry Andric case FunctionEffect::Kind::None:
2852*0fca6ea1SDimitry Andric break;
2853*0fca6ea1SDimitry Andric }
2854*0fca6ea1SDimitry Andric llvm_unreachable("unknown effect kind");
2855*0fca6ea1SDimitry Andric }
2856*0fca6ea1SDimitry Andric
shouldDiagnoseRedeclaration(const FunctionDecl & OldFunction,const FunctionEffectsRef & OldFX,const FunctionDecl & NewFunction,const FunctionEffectsRef & NewFX) const2857*0fca6ea1SDimitry Andric bool FunctionEffectDiff::shouldDiagnoseRedeclaration(
2858*0fca6ea1SDimitry Andric const FunctionDecl &OldFunction, const FunctionEffectsRef &OldFX,
2859*0fca6ea1SDimitry Andric const FunctionDecl &NewFunction, const FunctionEffectsRef &NewFX) const {
2860*0fca6ea1SDimitry Andric switch (EffectKind) {
2861*0fca6ea1SDimitry Andric case FunctionEffect::Kind::NonAllocating:
2862*0fca6ea1SDimitry Andric case FunctionEffect::Kind::NonBlocking:
2863*0fca6ea1SDimitry Andric // nonblocking/nonallocating can't be removed in a redeclaration.
2864*0fca6ea1SDimitry Andric switch (DiffKind) {
2865*0fca6ea1SDimitry Andric case Kind::Added:
2866*0fca6ea1SDimitry Andric return false; // No diagnostic.
2867*0fca6ea1SDimitry Andric case Kind::Removed:
2868*0fca6ea1SDimitry Andric return true; // Issue diagnostic.
2869*0fca6ea1SDimitry Andric case Kind::ConditionMismatch:
2870*0fca6ea1SDimitry Andric // All these forms of mismatches are diagnosed.
2871*0fca6ea1SDimitry Andric return true;
2872*0fca6ea1SDimitry Andric }
2873*0fca6ea1SDimitry Andric case FunctionEffect::Kind::Blocking:
2874*0fca6ea1SDimitry Andric case FunctionEffect::Kind::Allocating:
2875*0fca6ea1SDimitry Andric return false;
2876*0fca6ea1SDimitry Andric case FunctionEffect::Kind::None:
2877*0fca6ea1SDimitry Andric break;
2878*0fca6ea1SDimitry Andric }
2879*0fca6ea1SDimitry Andric llvm_unreachable("unknown effect kind");
2880*0fca6ea1SDimitry Andric }
2881*0fca6ea1SDimitry Andric
2882*0fca6ea1SDimitry Andric FunctionEffectDiff::OverrideResult
shouldDiagnoseMethodOverride(const CXXMethodDecl & OldMethod,const FunctionEffectsRef & OldFX,const CXXMethodDecl & NewMethod,const FunctionEffectsRef & NewFX) const2883*0fca6ea1SDimitry Andric FunctionEffectDiff::shouldDiagnoseMethodOverride(
2884*0fca6ea1SDimitry Andric const CXXMethodDecl &OldMethod, const FunctionEffectsRef &OldFX,
2885*0fca6ea1SDimitry Andric const CXXMethodDecl &NewMethod, const FunctionEffectsRef &NewFX) const {
2886*0fca6ea1SDimitry Andric switch (EffectKind) {
2887*0fca6ea1SDimitry Andric case FunctionEffect::Kind::NonAllocating:
2888*0fca6ea1SDimitry Andric case FunctionEffect::Kind::NonBlocking:
2889*0fca6ea1SDimitry Andric switch (DiffKind) {
2890*0fca6ea1SDimitry Andric
2891*0fca6ea1SDimitry Andric // If added on an override, that's fine and not diagnosed.
2892*0fca6ea1SDimitry Andric case Kind::Added:
2893*0fca6ea1SDimitry Andric return OverrideResult::NoAction;
2894*0fca6ea1SDimitry Andric
2895*0fca6ea1SDimitry Andric // If missing from an override (removed), propagate from base to derived.
2896*0fca6ea1SDimitry Andric case Kind::Removed:
2897*0fca6ea1SDimitry Andric return OverrideResult::Merge;
2898*0fca6ea1SDimitry Andric
2899*0fca6ea1SDimitry Andric // If there's a mismatch involving the effect's polarity or condition,
2900*0fca6ea1SDimitry Andric // issue a warning.
2901*0fca6ea1SDimitry Andric case Kind::ConditionMismatch:
2902*0fca6ea1SDimitry Andric return OverrideResult::Warn;
2903*0fca6ea1SDimitry Andric }
2904*0fca6ea1SDimitry Andric
2905*0fca6ea1SDimitry Andric case FunctionEffect::Kind::Blocking:
2906*0fca6ea1SDimitry Andric case FunctionEffect::Kind::Allocating:
2907*0fca6ea1SDimitry Andric return OverrideResult::NoAction;
2908*0fca6ea1SDimitry Andric
2909*0fca6ea1SDimitry Andric case FunctionEffect::Kind::None:
2910*0fca6ea1SDimitry Andric break;
2911*0fca6ea1SDimitry Andric }
2912*0fca6ea1SDimitry Andric llvm_unreachable("unknown effect kind");
2913*0fca6ea1SDimitry Andric }
2914