| //===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the Sema class, which performs semantic analysis and |
| // builds ASTs. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_SEMA_SEMA_H |
| #define LLVM_CLANG_SEMA_SEMA_H |
| |
| #include "clang/AST/Attr.h" |
| #include "clang/AST/DeclarationName.h" |
| #include "clang/AST/Expr.h" |
| #include "clang/AST/ExprObjC.h" |
| #include "clang/AST/ExternalASTSource.h" |
| #include "clang/AST/MangleNumberingContext.h" |
| #include "clang/AST/NSAPI.h" |
| #include "clang/AST/PrettyPrinter.h" |
| #include "clang/AST/TypeLoc.h" |
| #include "clang/APINotes/APINotesManager.h" |
| #include "clang/Basic/ExpressionTraits.h" |
| #include "clang/Basic/LangOptions.h" |
| #include "clang/Basic/Module.h" |
| #include "clang/Basic/OpenMPKinds.h" |
| #include "clang/Basic/Specifiers.h" |
| #include "clang/Basic/TemplateKinds.h" |
| #include "clang/Basic/TypeTraits.h" |
| #include "clang/Sema/AnalysisBasedWarnings.h" |
| #include "clang/Sema/DeclSpec.h" |
| #include "clang/Sema/ExternalSemaSource.h" |
| #include "clang/Sema/IdentifierResolver.h" |
| #include "clang/Sema/LocInfoType.h" |
| #include "clang/Sema/ObjCMethodList.h" |
| #include "clang/Sema/Ownership.h" |
| #include "clang/Sema/Scope.h" |
| #include "clang/Sema/ScopeInfo.h" |
| #include "clang/Sema/TypoCorrection.h" |
| #include "clang/Sema/Weak.h" |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/Optional.h" |
| #include "llvm/ADT/SetVector.h" |
| #include "llvm/ADT/SmallPtrSet.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/ADT/TinyPtrVector.h" |
| #include <deque> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| namespace llvm { |
| class APSInt; |
| template <typename ValueT> struct DenseMapInfo; |
| template <typename ValueT, typename ValueInfoT> class DenseSet; |
| class SmallBitVector; |
| class InlineAsmIdentifierInfo; |
| } |
| |
| namespace clang { |
| class ADLResult; |
| class ASTConsumer; |
| class ASTContext; |
| class ASTMutationListener; |
| class ASTReader; |
| class ASTWriter; |
| class ArrayType; |
| class AttributeList; |
| class BlockDecl; |
| class CapturedDecl; |
| class CXXBasePath; |
| class CXXBasePaths; |
| class CXXBindTemporaryExpr; |
| typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; |
| class CXXConstructorDecl; |
| class CXXConversionDecl; |
| class CXXDeleteExpr; |
| class CXXDestructorDecl; |
| class CXXFieldCollector; |
| class CXXMemberCallExpr; |
| class CXXMethodDecl; |
| class CXXScopeSpec; |
| class CXXTemporary; |
| class CXXTryStmt; |
| class CallExpr; |
| class ClassTemplateDecl; |
| class ClassTemplatePartialSpecializationDecl; |
| class ClassTemplateSpecializationDecl; |
| class VarTemplatePartialSpecializationDecl; |
| class CodeCompleteConsumer; |
| class CodeCompletionAllocator; |
| class CodeCompletionTUInfo; |
| class CodeCompletionResult; |
| class Decl; |
| class DeclAccessPair; |
| class DeclContext; |
| class DeclRefExpr; |
| class DeclaratorDecl; |
| class DeducedTemplateArgument; |
| class DependentDiagnostic; |
| class DesignatedInitExpr; |
| class Designation; |
| class EnableIfAttr; |
| class EnumConstantDecl; |
| class Expr; |
| class ExtVectorType; |
| class ExternalSemaSource; |
| class FormatAttr; |
| class FriendDecl; |
| class FunctionDecl; |
| class FunctionProtoType; |
| class FunctionTemplateDecl; |
| class ImplicitConversionSequence; |
| class InitListExpr; |
| class InitializationKind; |
| class InitializationSequence; |
| class InitializedEntity; |
| class IntegerLiteral; |
| class LabelStmt; |
| class LambdaExpr; |
| class LangOptions; |
| class LocalInstantiationScope; |
| class LookupResult; |
| class MacroInfo; |
| typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath; |
| class ModuleLoader; |
| class MultiLevelTemplateArgumentList; |
| class NamedDecl; |
| class ObjCCategoryDecl; |
| class ObjCCategoryImplDecl; |
| class ObjCCompatibleAliasDecl; |
| class ObjCContainerDecl; |
| class ObjCImplDecl; |
| class ObjCImplementationDecl; |
| class ObjCInterfaceDecl; |
| class ObjCIvarDecl; |
| template <class T> class ObjCList; |
| class ObjCMessageExpr; |
| class ObjCMethodDecl; |
| class ObjCPropertyDecl; |
| class ObjCProtocolDecl; |
| class OMPThreadPrivateDecl; |
| class OMPClause; |
| class OverloadCandidateSet; |
| class OverloadExpr; |
| class ParenListExpr; |
| class ParmVarDecl; |
| class Preprocessor; |
| class PseudoDestructorTypeStorage; |
| class PseudoObjectExpr; |
| class QualType; |
| class StandardConversionSequence; |
| class Stmt; |
| class StringLiteral; |
| class SwitchStmt; |
| class TemplateArgument; |
| class TemplateArgumentList; |
| class TemplateArgumentLoc; |
| class TemplateDecl; |
| class TemplateParameterList; |
| class TemplatePartialOrderingContext; |
| class TemplateTemplateParmDecl; |
| class Token; |
| class TypeAliasDecl; |
| class TypedefDecl; |
| class TypedefNameDecl; |
| class TypeLoc; |
| class TypoCorrectionConsumer; |
| class UnqualifiedId; |
| class UnresolvedLookupExpr; |
| class UnresolvedMemberExpr; |
| class UnresolvedSetImpl; |
| class UnresolvedSetIterator; |
| class UsingDecl; |
| class UsingShadowDecl; |
| class ValueDecl; |
| class VarDecl; |
| class VarTemplateSpecializationDecl; |
| class VisibilityAttr; |
| class VisibleDeclConsumer; |
| class IndirectFieldDecl; |
| struct DeductionFailureInfo; |
| class TemplateSpecCandidateSet; |
| |
| namespace sema { |
| class AccessedEntity; |
| class BlockScopeInfo; |
| class CapturedRegionScopeInfo; |
| class CapturingScopeInfo; |
| class CompoundScopeInfo; |
| class DelayedDiagnostic; |
| class DelayedDiagnosticPool; |
| class FunctionScopeInfo; |
| class LambdaScopeInfo; |
| class PossiblyUnreachableDiag; |
| class TemplateDeductionInfo; |
| } |
| |
| namespace threadSafety { |
| class BeforeSet; |
| void threadSafetyCleanup(BeforeSet* Cache); |
| } |
| |
| // FIXME: No way to easily map from TemplateTypeParmTypes to |
| // TemplateTypeParmDecls, so we have this horrible PointerUnion. |
| typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, |
| SourceLocation> UnexpandedParameterPack; |
| |
| /// Describes whether we've seen any nullability information for the given |
| /// file. |
| struct FileNullability { |
| /// The first pointer declarator (of any pointer kind) in the file that does |
| /// not have a corresponding nullability annotation. |
| SourceLocation PointerLoc; |
| |
| /// Which kind of pointer declarator we saw. |
| uint8_t PointerKind; |
| |
| /// Whether we saw any type nullability annotations in the given file. |
| bool SawTypeNullability = false; |
| }; |
| |
| /// A mapping from file IDs to a record of whether we've seen nullability |
| /// information in that file. |
| class FileNullabilityMap { |
| /// A mapping from file IDs to the nullability information for each file ID. |
| llvm::DenseMap<FileID, FileNullability> Map; |
| |
| /// A single-element cache based on the file ID. |
| struct { |
| FileID File; |
| FileNullability Nullability; |
| } Cache; |
| |
| public: |
| FileNullability &operator[](FileID file) { |
| // Check the single-element cache. |
| if (file == Cache.File) |
| return Cache.Nullability; |
| |
| // It's not in the single-element cache; flush the cache if we have one. |
| if (!Cache.File.isInvalid()) { |
| Map[Cache.File] = Cache.Nullability; |
| } |
| |
| // Pull this entry into the cache. |
| Cache.File = file; |
| Cache.Nullability = Map[file]; |
| return Cache.Nullability; |
| } |
| }; |
| |
| /// Sema - This implements semantic analysis and AST building for C. |
| class Sema { |
| Sema(const Sema &) = delete; |
| void operator=(const Sema &) = delete; |
| |
| ///\brief Source of additional semantic information. |
| ExternalSemaSource *ExternalSource; |
| |
| ///\brief Whether Sema has generated a multiplexer and has to delete it. |
| bool isMultiplexExternalSource; |
| |
| static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); |
| |
| bool isVisibleSlow(const NamedDecl *D); |
| |
| bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, |
| const NamedDecl *New) { |
| // We are about to link these. It is now safe to compute the linkage of |
| // the new decl. If the new decl has external linkage, we will |
| // link it with the hidden decl (which also has external linkage) and |
| // it will keep having external linkage. If it has internal linkage, we |
| // will not link it. Since it has no previous decls, it will remain |
| // with internal linkage. |
| if (getLangOpts().ModulesHideInternalLinkage) |
| return isVisible(Old) || New->isExternallyVisible(); |
| return true; |
| } |
| |
| public: |
| typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; |
| typedef OpaquePtr<TemplateName> TemplateTy; |
| typedef OpaquePtr<QualType> TypeTy; |
| |
| OpenCLOptions OpenCLFeatures; |
| FPOptions FPFeatures; |
| |
| const LangOptions &LangOpts; |
| Preprocessor &PP; |
| ASTContext &Context; |
| ASTConsumer &Consumer; |
| DiagnosticsEngine &Diags; |
| SourceManager &SourceMgr; |
| api_notes::APINotesManager APINotes; |
| |
| /// \brief Flag indicating whether or not to collect detailed statistics. |
| bool CollectStats; |
| |
| /// \brief Code-completion consumer. |
| CodeCompleteConsumer *CodeCompleter; |
| |
| /// CurContext - This is the current declaration context of parsing. |
| DeclContext *CurContext; |
| |
| /// \brief Generally null except when we temporarily switch decl contexts, |
| /// like in \see ActOnObjCTemporaryExitContainerContext. |
| DeclContext *OriginalLexicalContext; |
| |
| /// VAListTagName - The declaration name corresponding to __va_list_tag. |
| /// This is used as part of a hack to omit that class from ADL results. |
| DeclarationName VAListTagName; |
| |
| /// PackContext - Manages the stack for \#pragma pack. An alignment |
| /// of 0 indicates default alignment. |
| void *PackContext; // Really a "PragmaPackStack*" |
| |
| bool MSStructPragmaOn; // True when \#pragma ms_struct on |
| |
| /// \brief Controls member pointer representation format under the MS ABI. |
| LangOptions::PragmaMSPointersToMembersKind |
| MSPointerToMemberRepresentationMethod; |
| |
| enum PragmaVtorDispKind { |
| PVDK_Push, ///< #pragma vtordisp(push, mode) |
| PVDK_Set, ///< #pragma vtordisp(mode) |
| PVDK_Pop, ///< #pragma vtordisp(pop) |
| PVDK_Reset ///< #pragma vtordisp() |
| }; |
| |
| enum PragmaMsStackAction { |
| PSK_Reset, // #pragma () |
| PSK_Set, // #pragma ("name") |
| PSK_Push, // #pragma (push[, id]) |
| PSK_Push_Set, // #pragma (push[, id], "name") |
| PSK_Pop, // #pragma (pop[, id]) |
| PSK_Pop_Set, // #pragma (pop[, id], "name") |
| }; |
| |
| /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft |
| /// C++ ABI. Possible values are 0, 1, and 2, which mean: |
| /// |
| /// 0: Suppress all vtordisps |
| /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial |
| /// structors |
| /// 2: Always insert vtordisps to support RTTI on partially constructed |
| /// objects |
| /// |
| /// The stack always has at least one element in it. |
| SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack; |
| |
| /// Stack of active SEH __finally scopes. Can be empty. |
| SmallVector<Scope*, 2> CurrentSEHFinally; |
| |
| /// \brief Source location for newly created implicit MSInheritanceAttrs |
| SourceLocation ImplicitMSInheritanceAttrLoc; |
| |
| template<typename ValueType> |
| struct PragmaStack { |
| struct Slot { |
| llvm::StringRef StackSlotLabel; |
| ValueType Value; |
| SourceLocation PragmaLocation; |
| Slot(llvm::StringRef StackSlotLabel, |
| ValueType Value, |
| SourceLocation PragmaLocation) |
| : StackSlotLabel(StackSlotLabel), Value(Value), |
| PragmaLocation(PragmaLocation) {} |
| }; |
| void Act(SourceLocation PragmaLocation, |
| PragmaMsStackAction Action, |
| llvm::StringRef StackSlotLabel, |
| ValueType Value); |
| explicit PragmaStack(const ValueType &Value) |
| : CurrentValue(Value) {} |
| SmallVector<Slot, 2> Stack; |
| ValueType CurrentValue; |
| SourceLocation CurrentPragmaLocation; |
| }; |
| // FIXME: We should serialize / deserialize these if they occur in a PCH (but |
| // we shouldn't do so if they're in a module). |
| PragmaStack<StringLiteral *> DataSegStack; |
| PragmaStack<StringLiteral *> BSSSegStack; |
| PragmaStack<StringLiteral *> ConstSegStack; |
| PragmaStack<StringLiteral *> CodeSegStack; |
| |
| /// A mapping that describes the nullability we've seen in each header file. |
| FileNullabilityMap NullabilityMap; |
| |
| /// Last section used with #pragma init_seg. |
| StringLiteral *CurInitSeg; |
| SourceLocation CurInitSegLoc; |
| |
| /// VisContext - Manages the stack for \#pragma GCC visibility. |
| void *VisContext; // Really a "PragmaVisStack*" |
| |
| /// \brief This represents the last location of a "#pragma clang optimize off" |
| /// directive if such a directive has not been closed by an "on" yet. If |
| /// optimizations are currently "on", this is set to an invalid location. |
| SourceLocation OptimizeOffPragmaLocation; |
| |
| /// \brief Flag indicating if Sema is building a recovery call expression. |
| /// |
| /// This flag is used to avoid building recovery call expressions |
| /// if Sema is already doing so, which would cause infinite recursions. |
| bool IsBuildingRecoveryCallExpr; |
| |
| /// ExprNeedsCleanups - True if the current evaluation context |
| /// requires cleanups to be run at its conclusion. |
| bool ExprNeedsCleanups; |
| |
| /// ExprCleanupObjects - This is the stack of objects requiring |
| /// cleanup that are created by the current full expression. The |
| /// element type here is ExprWithCleanups::Object. |
| SmallVector<BlockDecl*, 8> ExprCleanupObjects; |
| |
| /// \brief Store a list of either DeclRefExprs or MemberExprs |
| /// that contain a reference to a variable (constant) that may or may not |
| /// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue |
| /// and discarded value conversions have been applied to all subexpressions |
| /// of the enclosing full expression. This is cleared at the end of each |
| /// full expression. |
| llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs; |
| |
| /// \brief Stack containing information about each of the nested |
| /// function, block, and method scopes that are currently active. |
| /// |
| /// This array is never empty. Clients should ignore the first |
| /// element, which is used to cache a single FunctionScopeInfo |
| /// that's used to parse every top-level function. |
| SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; |
| |
| typedef LazyVector<TypedefNameDecl *, ExternalSemaSource, |
| &ExternalSemaSource::ReadExtVectorDecls, 2, 2> |
| ExtVectorDeclsType; |
| |
| /// ExtVectorDecls - This is a list all the extended vector types. This allows |
| /// us to associate a raw vector type with one of the ext_vector type names. |
| /// This is only necessary for issuing pretty diagnostics. |
| ExtVectorDeclsType ExtVectorDecls; |
| |
| /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. |
| std::unique_ptr<CXXFieldCollector> FieldCollector; |
| |
| typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType; |
| |
| /// \brief Set containing all declared private fields that are not used. |
| NamedDeclSetType UnusedPrivateFields; |
| |
| /// \brief Set containing all typedefs that are likely unused. |
| llvm::SmallSetVector<const TypedefNameDecl *, 4> |
| UnusedLocalTypedefNameCandidates; |
| |
| /// \brief Delete-expressions to be analyzed at the end of translation unit |
| /// |
| /// This list contains class members, and locations of delete-expressions |
| /// that could not be proven as to whether they mismatch with new-expression |
| /// used in initializer of the field. |
| typedef std::pair<SourceLocation, bool> DeleteExprLoc; |
| typedef llvm::SmallVector<DeleteExprLoc, 4> DeleteLocs; |
| llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs; |
| |
| typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy; |
| |
| /// PureVirtualClassDiagSet - a set of class declarations which we have |
| /// emitted a list of pure virtual functions. Used to prevent emitting the |
| /// same list more than once. |
| std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet; |
| |
| /// ParsingInitForAutoVars - a set of declarations with auto types for which |
| /// we are currently parsing the initializer. |
| llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars; |
| |
| /// \brief Look for a locally scoped extern "C" declaration by the given name. |
| NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); |
| |
| typedef LazyVector<VarDecl *, ExternalSemaSource, |
| &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> |
| TentativeDefinitionsType; |
| |
| /// \brief All the tentative definitions encountered in the TU. |
| TentativeDefinitionsType TentativeDefinitions; |
| |
| typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource, |
| &ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2> |
| UnusedFileScopedDeclsType; |
| |
| /// \brief The set of file scoped decls seen so far that have not been used |
| /// and must warn if not used. Only contains the first declaration. |
| UnusedFileScopedDeclsType UnusedFileScopedDecls; |
| |
| typedef LazyVector<CXXConstructorDecl *, ExternalSemaSource, |
| &ExternalSemaSource::ReadDelegatingConstructors, 2, 2> |
| DelegatingCtorDeclsType; |
| |
| /// \brief All the delegating constructors seen so far in the file, used for |
| /// cycle detection at the end of the TU. |
| DelegatingCtorDeclsType DelegatingCtorDecls; |
| |
| /// \brief All the overriding functions seen during a class definition |
| /// that had their exception spec checks delayed, plus the overridden |
| /// function. |
| SmallVector<std::pair<const CXXMethodDecl*, const CXXMethodDecl*>, 2> |
| DelayedExceptionSpecChecks; |
| |
| /// \brief All the members seen during a class definition which were both |
| /// explicitly defaulted and had explicitly-specified exception |
| /// specifications, along with the function type containing their |
| /// user-specified exception specification. Those exception specifications |
| /// were overridden with the default specifications, but we still need to |
| /// check whether they are compatible with the default specification, and |
| /// we can't do that until the nesting set of class definitions is complete. |
| SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> |
| DelayedDefaultedMemberExceptionSpecs; |
| |
| typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> |
| LateParsedTemplateMapT; |
| LateParsedTemplateMapT LateParsedTemplateMap; |
| |
| /// \brief Callback to the parser to parse templated functions when needed. |
| typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT); |
| typedef void LateTemplateParserCleanupCB(void *P); |
| LateTemplateParserCB *LateTemplateParser; |
| LateTemplateParserCleanupCB *LateTemplateParserCleanup; |
| void *OpaqueParser; |
| |
| void SetLateTemplateParser(LateTemplateParserCB *LTP, |
| LateTemplateParserCleanupCB *LTPCleanup, |
| void *P) { |
| LateTemplateParser = LTP; |
| LateTemplateParserCleanup = LTPCleanup; |
| OpaqueParser = P; |
| } |
| |
| class DelayedDiagnostics; |
| |
| class DelayedDiagnosticsState { |
| sema::DelayedDiagnosticPool *SavedPool; |
| friend class Sema::DelayedDiagnostics; |
| }; |
| typedef DelayedDiagnosticsState ParsingDeclState; |
| typedef DelayedDiagnosticsState ProcessingContextState; |
| |
| /// A class which encapsulates the logic for delaying diagnostics |
| /// during parsing and other processing. |
| class DelayedDiagnostics { |
| /// \brief The current pool of diagnostics into which delayed |
| /// diagnostics should go. |
| sema::DelayedDiagnosticPool *CurPool; |
| |
| public: |
| DelayedDiagnostics() : CurPool(nullptr) {} |
| |
| /// Adds a delayed diagnostic. |
| void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h |
| |
| /// Determines whether diagnostics should be delayed. |
| bool shouldDelayDiagnostics() { return CurPool != nullptr; } |
| |
| /// Returns the current delayed-diagnostics pool. |
| sema::DelayedDiagnosticPool *getCurrentPool() const { |
| return CurPool; |
| } |
| |
| /// Enter a new scope. Access and deprecation diagnostics will be |
| /// collected in this pool. |
| DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) { |
| DelayedDiagnosticsState state; |
| state.SavedPool = CurPool; |
| CurPool = &pool; |
| return state; |
| } |
| |
| /// Leave a delayed-diagnostic state that was previously pushed. |
| /// Do not emit any of the diagnostics. This is performed as part |
| /// of the bookkeeping of popping a pool "properly". |
| void popWithoutEmitting(DelayedDiagnosticsState state) { |
| CurPool = state.SavedPool; |
| } |
| |
| /// Enter a new scope where access and deprecation diagnostics are |
| /// not delayed. |
| DelayedDiagnosticsState pushUndelayed() { |
| DelayedDiagnosticsState state; |
| state.SavedPool = CurPool; |
| CurPool = nullptr; |
| return state; |
| } |
| |
| /// Undo a previous pushUndelayed(). |
| void popUndelayed(DelayedDiagnosticsState state) { |
| assert(CurPool == nullptr); |
| CurPool = state.SavedPool; |
| } |
| } DelayedDiagnostics; |
| |
| /// A RAII object to temporarily push a declaration context. |
| class ContextRAII { |
| private: |
| Sema &S; |
| DeclContext *SavedContext; |
| ProcessingContextState SavedContextState; |
| QualType SavedCXXThisTypeOverride; |
| |
| public: |
| ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true) |
| : S(S), SavedContext(S.CurContext), |
| SavedContextState(S.DelayedDiagnostics.pushUndelayed()), |
| SavedCXXThisTypeOverride(S.CXXThisTypeOverride) |
| { |
| assert(ContextToPush && "pushing null context"); |
| S.CurContext = ContextToPush; |
| if (NewThisContext) |
| S.CXXThisTypeOverride = QualType(); |
| } |
| |
| void pop() { |
| if (!SavedContext) return; |
| S.CurContext = SavedContext; |
| S.DelayedDiagnostics.popUndelayed(SavedContextState); |
| S.CXXThisTypeOverride = SavedCXXThisTypeOverride; |
| SavedContext = nullptr; |
| } |
| |
| ~ContextRAII() { |
| pop(); |
| } |
| }; |
| |
| /// \brief RAII object to handle the state changes required to synthesize |
| /// a function body. |
| class SynthesizedFunctionScope { |
| Sema &S; |
| Sema::ContextRAII SavedContext; |
| |
| public: |
| SynthesizedFunctionScope(Sema &S, DeclContext *DC) |
| : S(S), SavedContext(S, DC) |
| { |
| S.PushFunctionScope(); |
| S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); |
| } |
| |
| ~SynthesizedFunctionScope() { |
| S.PopExpressionEvaluationContext(); |
| S.PopFunctionScopeInfo(); |
| } |
| }; |
| |
| /// WeakUndeclaredIdentifiers - Identifiers contained in |
| /// \#pragma weak before declared. rare. may alias another |
| /// identifier, declared or undeclared |
| llvm::MapVector<IdentifierInfo *, WeakInfo> WeakUndeclaredIdentifiers; |
| |
| /// ExtnameUndeclaredIdentifiers - Identifiers contained in |
| /// \#pragma redefine_extname before declared. Used in Solaris system headers |
| /// to define functions that occur in multiple standards to call the version |
| /// in the currently selected standard. |
| llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers; |
| |
| |
| /// \brief Load weak undeclared identifiers from the external source. |
| void LoadExternalWeakUndeclaredIdentifiers(); |
| |
| /// WeakTopLevelDecl - Translation-unit scoped declarations generated by |
| /// \#pragma weak during processing of other Decls. |
| /// I couldn't figure out a clean way to generate these in-line, so |
| /// we store them here and handle separately -- which is a hack. |
| /// It would be best to refactor this. |
| SmallVector<Decl*,2> WeakTopLevelDecl; |
| |
| IdentifierResolver IdResolver; |
| |
| /// Translation Unit Scope - useful to Objective-C actions that need |
| /// to lookup file scope declarations in the "ordinary" C decl namespace. |
| /// For example, user-defined classes, built-in "id" type, etc. |
| Scope *TUScope; |
| |
| /// \brief The C++ "std" namespace, where the standard library resides. |
| LazyDeclPtr StdNamespace; |
| |
| /// \brief The C++ "std::bad_alloc" class, which is defined by the C++ |
| /// standard library. |
| LazyDeclPtr StdBadAlloc; |
| |
| /// \brief The C++ "std::initializer_list" template, which is defined in |
| /// \<initializer_list>. |
| ClassTemplateDecl *StdInitializerList; |
| |
| /// \brief The C++ "type_info" declaration, which is defined in \<typeinfo>. |
| RecordDecl *CXXTypeInfoDecl; |
| |
| /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files. |
| RecordDecl *MSVCGuidDecl; |
| |
| /// \brief Caches identifiers/selectors for NSFoundation APIs. |
| std::unique_ptr<NSAPI> NSAPIObj; |
| |
| /// \brief The declaration of the Objective-C NSNumber class. |
| ObjCInterfaceDecl *NSNumberDecl; |
| |
| /// \brief The declaration of the Objective-C NSValue class. |
| ObjCInterfaceDecl *NSValueDecl; |
| |
| /// \brief Pointer to NSNumber type (NSNumber *). |
| QualType NSNumberPointer; |
| |
| /// \brief Pointer to NSValue type (NSValue *). |
| QualType NSValuePointer; |
| |
| /// \brief The Objective-C NSNumber methods used to create NSNumber literals. |
| ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]; |
| |
| /// \brief The declaration of the Objective-C NSString class. |
| ObjCInterfaceDecl *NSStringDecl; |
| |
| /// \brief Pointer to NSString type (NSString *). |
| QualType NSStringPointer; |
| |
| /// \brief The declaration of the stringWithUTF8String: method. |
| ObjCMethodDecl *StringWithUTF8StringMethod; |
| |
| /// \brief The declaration of the valueWithBytes:objCType: method. |
| ObjCMethodDecl *ValueWithBytesObjCTypeMethod; |
| |
| /// \brief The declaration of the Objective-C NSArray class. |
| ObjCInterfaceDecl *NSArrayDecl; |
| |
| /// \brief The declaration of the arrayWithObjects:count: method. |
| ObjCMethodDecl *ArrayWithObjectsMethod; |
| |
| /// \brief The declaration of the Objective-C NSDictionary class. |
| ObjCInterfaceDecl *NSDictionaryDecl; |
| |
| /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method. |
| ObjCMethodDecl *DictionaryWithObjectsMethod; |
| |
| /// \brief id<NSCopying> type. |
| QualType QIDNSCopying; |
| |
| /// \brief will hold 'respondsToSelector:' |
| Selector RespondsToSelectorSel; |
| |
| /// \brief counter for internal MS Asm label names. |
| unsigned MSAsmLabelNameCounter; |
| |
| /// A flag to remember whether the implicit forms of operator new and delete |
| /// have been declared. |
| bool GlobalNewDeleteDeclared; |
| |
| /// A flag to indicate that we're in a context that permits abstract |
| /// references to fields. This is really a |
| bool AllowAbstractFieldReference; |
| |
| /// \brief Describes how the expressions currently being parsed are |
| /// evaluated at run-time, if at all. |
| enum ExpressionEvaluationContext { |
| /// \brief The current expression and its subexpressions occur within an |
| /// unevaluated operand (C++11 [expr]p7), such as the subexpression of |
| /// \c sizeof, where the type of the expression may be significant but |
| /// no code will be generated to evaluate the value of the expression at |
| /// run time. |
| Unevaluated, |
| |
| /// \brief The current expression occurs within an unevaluated |
| /// operand that unconditionally permits abstract references to |
| /// fields, such as a SIZE operator in MS-style inline assembly. |
| UnevaluatedAbstract, |
| |
| /// \brief The current context is "potentially evaluated" in C++11 terms, |
| /// but the expression is evaluated at compile-time (like the values of |
| /// cases in a switch statement). |
| ConstantEvaluated, |
| |
| /// \brief The current expression is potentially evaluated at run time, |
| /// which means that code may be generated to evaluate the value of the |
| /// expression at run time. |
| PotentiallyEvaluated, |
| |
| /// \brief The current expression is potentially evaluated, but any |
| /// declarations referenced inside that expression are only used if |
| /// in fact the current expression is used. |
| /// |
| /// This value is used when parsing default function arguments, for which |
| /// we would like to provide diagnostics (e.g., passing non-POD arguments |
| /// through varargs) but do not want to mark declarations as "referenced" |
| /// until the default argument is used. |
| PotentiallyEvaluatedIfUsed |
| }; |
| |
| /// \brief Data structure used to record current or nested |
| /// expression evaluation contexts. |
| struct ExpressionEvaluationContextRecord { |
| /// \brief The expression evaluation context. |
| ExpressionEvaluationContext Context; |
| |
| /// \brief Whether the enclosing context needed a cleanup. |
| bool ParentNeedsCleanups; |
| |
| /// \brief Whether we are in a decltype expression. |
| bool IsDecltype; |
| |
| /// \brief The number of active cleanup objects when we entered |
| /// this expression evaluation context. |
| unsigned NumCleanupObjects; |
| |
| /// \brief The number of typos encountered during this expression evaluation |
| /// context (i.e. the number of TypoExprs created). |
| unsigned NumTypos; |
| |
| llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs; |
| |
| /// \brief The lambdas that are present within this context, if it |
| /// is indeed an unevaluated context. |
| SmallVector<LambdaExpr *, 2> Lambdas; |
| |
| /// \brief The declaration that provides context for lambda expressions |
| /// and block literals if the normal declaration context does not |
| /// suffice, e.g., in a default function argument. |
| Decl *ManglingContextDecl; |
| |
| /// \brief The context information used to mangle lambda expressions |
| /// and block literals within this context. |
| /// |
| /// This mangling information is allocated lazily, since most contexts |
| /// do not have lambda expressions or block literals. |
| IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering; |
| |
| /// \brief If we are processing a decltype type, a set of call expressions |
| /// for which we have deferred checking the completeness of the return type. |
| SmallVector<CallExpr *, 8> DelayedDecltypeCalls; |
| |
| /// \brief If we are processing a decltype type, a set of temporary binding |
| /// expressions for which we have deferred checking the destructor. |
| SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds; |
| |
| ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, |
| unsigned NumCleanupObjects, |
| bool ParentNeedsCleanups, |
| Decl *ManglingContextDecl, |
| bool IsDecltype) |
| : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), |
| IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), |
| NumTypos(0), |
| ManglingContextDecl(ManglingContextDecl), MangleNumbering() { } |
| |
| /// \brief Retrieve the mangling numbering context, used to consistently |
| /// number constructs like lambdas for mangling. |
| MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx); |
| |
| bool isUnevaluated() const { |
| return Context == Unevaluated || Context == UnevaluatedAbstract; |
| } |
| }; |
| |
| /// A stack of expression evaluation contexts. |
| SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; |
| |
| /// \brief Compute the mangling number context for a lambda expression or |
| /// block literal. |
| /// |
| /// \param DC - The DeclContext containing the lambda expression or |
| /// block literal. |
| /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl |
| /// associated with the context, if relevant. |
| MangleNumberingContext *getCurrentMangleNumberContext( |
| const DeclContext *DC, |
| Decl *&ManglingContextDecl); |
| |
| |
| /// SpecialMemberOverloadResult - The overloading result for a special member |
| /// function. |
| /// |
| /// This is basically a wrapper around PointerIntPair. The lowest bits of the |
| /// integer are used to determine whether overload resolution succeeded. |
| class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode { |
| public: |
| enum Kind { |
| NoMemberOrDeleted, |
| Ambiguous, |
| Success |
| }; |
| |
| private: |
| llvm::PointerIntPair<CXXMethodDecl*, 2> Pair; |
| |
| public: |
| SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID) |
| : FastFoldingSetNode(ID) |
| {} |
| |
| CXXMethodDecl *getMethod() const { return Pair.getPointer(); } |
| void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); } |
| |
| Kind getKind() const { return static_cast<Kind>(Pair.getInt()); } |
| void setKind(Kind K) { Pair.setInt(K); } |
| }; |
| |
| /// \brief A cache of special member function overload resolution results |
| /// for C++ records. |
| llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; |
| |
| /// \brief A cache of the flags available in enumerations with the flag_bits |
| /// attribute. |
| mutable llvm::DenseMap<const EnumDecl*, llvm::APInt> FlagBitsCache; |
| |
| /// \brief The kind of translation unit we are processing. |
| /// |
| /// When we're processing a complete translation unit, Sema will perform |
| /// end-of-translation-unit semantic tasks (such as creating |
| /// initializers for tentative definitions in C) once parsing has |
| /// completed. Modules and precompiled headers perform different kinds of |
| /// checks. |
| TranslationUnitKind TUKind; |
| |
| llvm::BumpPtrAllocator BumpAlloc; |
| |
| /// \brief The number of SFINAE diagnostics that have been trapped. |
| unsigned NumSFINAEErrors; |
| |
| typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>> |
| UnparsedDefaultArgInstantiationsMap; |
| |
| /// \brief A mapping from parameters with unparsed default arguments to the |
| /// set of instantiations of each parameter. |
| /// |
| /// This mapping is a temporary data structure used when parsing |
| /// nested class templates or nested classes of class templates, |
| /// where we might end up instantiating an inner class before the |
| /// default arguments of its methods have been parsed. |
| UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations; |
| |
| // Contains the locations of the beginning of unparsed default |
| // argument locations. |
| llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs; |
| |
| /// UndefinedInternals - all the used, undefined objects which require a |
| /// definition in this translation unit. |
| llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed; |
| |
| /// Obtain a sorted list of functions that are undefined but ODR-used. |
| void getUndefinedButUsed( |
| SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); |
| |
| /// Retrieves list of suspicious delete-expressions that will be checked at |
| /// the end of translation unit. |
| const llvm::MapVector<FieldDecl *, DeleteLocs> & |
| getMismatchingDeleteExpressions() const; |
| |
| typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; |
| typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; |
| |
| /// Method Pool - allows efficient lookup when typechecking messages to "id". |
| /// We need to maintain a list, since selectors can have differing signatures |
| /// across classes. In Cocoa, this happens to be extremely uncommon (only 1% |
| /// of selectors are "overloaded"). |
| /// At the head of the list it is recorded whether there were 0, 1, or >= 2 |
| /// methods inside categories with a particular selector. |
| GlobalMethodPool MethodPool; |
| |
| /// Method selectors used in a \@selector expression. Used for implementation |
| /// of -Wselector. |
| llvm::MapVector<Selector, SourceLocation> ReferencedSelectors; |
| |
| /// Kinds of C++ special members. |
| enum CXXSpecialMember { |
| CXXDefaultConstructor, |
| CXXCopyConstructor, |
| CXXMoveConstructor, |
| CXXCopyAssignment, |
| CXXMoveAssignment, |
| CXXDestructor, |
| CXXInvalid |
| }; |
| |
| typedef std::pair<CXXRecordDecl*, CXXSpecialMember> SpecialMemberDecl; |
| |
| /// The C++ special members which we are currently in the process of |
| /// declaring. If this process recursively triggers the declaration of the |
| /// same special member, we should act as if it is not yet declared. |
| llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared; |
| |
| void ReadMethodPool(Selector Sel); |
| |
| /// Private Helper predicate to check for 'self'. |
| bool isSelfExpr(Expr *RExpr); |
| bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method); |
| |
| /// \brief Cause the active diagnostic on the DiagosticsEngine to be |
| /// emitted. This is closely coupled to the SemaDiagnosticBuilder class and |
| /// should not be used elsewhere. |
| void EmitCurrentDiagnostic(unsigned DiagID); |
| |
| /// Records and restores the FP_CONTRACT state on entry/exit of compound |
| /// statements. |
| class FPContractStateRAII { |
| public: |
| FPContractStateRAII(Sema& S) |
| : S(S), OldFPContractState(S.FPFeatures.fp_contract) {} |
| ~FPContractStateRAII() { |
| S.FPFeatures.fp_contract = OldFPContractState; |
| } |
| private: |
| Sema& S; |
| bool OldFPContractState : 1; |
| }; |
| |
| void addImplicitTypedef(StringRef Name, QualType T); |
| |
| public: |
| Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, |
| TranslationUnitKind TUKind = TU_Complete, |
| CodeCompleteConsumer *CompletionConsumer = nullptr); |
| ~Sema(); |
| |
| /// \brief Perform initialization that occurs after the parser has been |
| /// initialized but before it parses anything. |
| void Initialize(); |
| |
| const LangOptions &getLangOpts() const { return LangOpts; } |
| OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; } |
| FPOptions &getFPOptions() { return FPFeatures; } |
| |
| DiagnosticsEngine &getDiagnostics() const { return Diags; } |
| SourceManager &getSourceManager() const { return SourceMgr; } |
| Preprocessor &getPreprocessor() const { return PP; } |
| ASTContext &getASTContext() const { return Context; } |
| ASTConsumer &getASTConsumer() const { return Consumer; } |
| ASTMutationListener *getASTMutationListener() const; |
| ExternalSemaSource* getExternalSource() const { return ExternalSource; } |
| |
| ///\brief Registers an external source. If an external source already exists, |
| /// creates a multiplex external source and appends to it. |
| /// |
| ///\param[in] E - A non-null external sema source. |
| /// |
| void addExternalSource(ExternalSemaSource *E); |
| |
| void PrintStats() const; |
| |
| /// \brief Helper class that creates diagnostics with optional |
| /// template instantiation stacks. |
| /// |
| /// This class provides a wrapper around the basic DiagnosticBuilder |
| /// class that emits diagnostics. SemaDiagnosticBuilder is |
| /// responsible for emitting the diagnostic (as DiagnosticBuilder |
| /// does) and, if the diagnostic comes from inside a template |
| /// instantiation, printing the template instantiation stack as |
| /// well. |
| class SemaDiagnosticBuilder : public DiagnosticBuilder { |
| Sema &SemaRef; |
| unsigned DiagID; |
| |
| public: |
| SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID) |
| : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { } |
| |
| // This is a cunning lie. DiagnosticBuilder actually performs move |
| // construction in its copy constructor (but due to varied uses, it's not |
| // possible to conveniently express this as actual move construction). So |
| // the default copy ctor here is fine, because the base class disables the |
| // source anyway, so the user-defined ~SemaDiagnosticBuilder is a safe no-op |
| // in that case anwyay. |
| SemaDiagnosticBuilder(const SemaDiagnosticBuilder&) = default; |
| |
| ~SemaDiagnosticBuilder() { |
| // If we aren't active, there is nothing to do. |
| if (!isActive()) return; |
| |
| // Otherwise, we need to emit the diagnostic. First flush the underlying |
| // DiagnosticBuilder data, and clear the diagnostic builder itself so it |
| // won't emit the diagnostic in its own destructor. |
| // |
| // This seems wasteful, in that as written the DiagnosticBuilder dtor will |
| // do its own needless checks to see if the diagnostic needs to be |
| // emitted. However, because we take care to ensure that the builder |
| // objects never escape, a sufficiently smart compiler will be able to |
| // eliminate that code. |
| FlushCounts(); |
| Clear(); |
| |
| // Dispatch to Sema to emit the diagnostic. |
| SemaRef.EmitCurrentDiagnostic(DiagID); |
| } |
| |
| /// Teach operator<< to produce an object of the correct type. |
| template<typename T> |
| friend const SemaDiagnosticBuilder &operator<<( |
| const SemaDiagnosticBuilder &Diag, const T &Value) { |
| const DiagnosticBuilder &BaseDiag = Diag; |
| BaseDiag << Value; |
| return Diag; |
| } |
| }; |
| |
| /// \brief Emit a diagnostic. |
| SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { |
| DiagnosticBuilder DB = Diags.Report(Loc, DiagID); |
| return SemaDiagnosticBuilder(DB, *this, DiagID); |
| } |
| |
| /// \brief Emit a partial diagnostic. |
| SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD); |
| |
| /// \brief Build a partial diagnostic. |
| PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h |
| |
| bool findMacroSpelling(SourceLocation &loc, StringRef name); |
| |
| /// \brief Get a string to suggest for zero-initialization of a type. |
| std::string |
| getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const; |
| std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const; |
| |
| /// \brief Calls \c Lexer::getLocForEndOfToken() |
| SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0); |
| |
| /// \brief Retrieve the module loader associated with the preprocessor. |
| ModuleLoader &getModuleLoader() const; |
| |
| void emitAndClearUnusedLocalTypedefWarnings(); |
| |
| void ActOnEndOfTranslationUnit(); |
| |
| void CheckDelegatingCtorCycles(); |
| |
| Scope *getScopeForContext(DeclContext *Ctx); |
| |
| void PushFunctionScope(); |
| void PushBlockScope(Scope *BlockScope, BlockDecl *Block); |
| sema::LambdaScopeInfo *PushLambdaScope(); |
| |
| /// \brief This is used to inform Sema what the current TemplateParameterDepth |
| /// is during Parsing. Currently it is used to pass on the depth |
| /// when parsing generic lambda 'auto' parameters. |
| void RecordParsingTemplateParameterDepth(unsigned Depth); |
| |
| void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, |
| RecordDecl *RD, |
| CapturedRegionKind K); |
| void |
| PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr, |
| const Decl *D = nullptr, |
| const BlockExpr *blkExpr = nullptr); |
| |
| sema::FunctionScopeInfo *getCurFunction() const { |
| return FunctionScopes.back(); |
| } |
| |
| sema::FunctionScopeInfo *getEnclosingFunction() const { |
| if (FunctionScopes.empty()) |
| return nullptr; |
| |
| for (int e = FunctionScopes.size()-1; e >= 0; --e) { |
| if (isa<sema::BlockScopeInfo>(FunctionScopes[e])) |
| continue; |
| return FunctionScopes[e]; |
| } |
| return nullptr; |
| } |
| |
| template <typename ExprT> |
| void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) { |
| if (!isUnevaluatedContext()) |
| getCurFunction()->recordUseOfWeak(E, IsRead); |
| } |
| |
| void PushCompoundScope(); |
| void PopCompoundScope(); |
| |
| sema::CompoundScopeInfo &getCurCompoundScope() const; |
| |
| bool hasAnyUnrecoverableErrorsInThisFunction() const; |
| |
| /// \brief Retrieve the current block, if any. |
| sema::BlockScopeInfo *getCurBlock(); |
| |
| /// \brief Retrieve the current lambda scope info, if any. |
| sema::LambdaScopeInfo *getCurLambda(); |
| |
| /// \brief Retrieve the current generic lambda info, if any. |
| sema::LambdaScopeInfo *getCurGenericLambda(); |
| |
| /// \brief Retrieve the current captured region, if any. |
| sema::CapturedRegionScopeInfo *getCurCapturedRegion(); |
| |
| /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls |
| SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; } |
| |
| void ActOnComment(SourceRange Comment); |
| |
| //===--------------------------------------------------------------------===// |
| // Type Analysis / Processing: SemaType.cpp. |
| // |
| |
| QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, |
| const DeclSpec *DS = nullptr); |
| QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA, |
| const DeclSpec *DS = nullptr); |
| QualType BuildPointerType(QualType T, |
| SourceLocation Loc, DeclarationName Entity); |
| QualType BuildReferenceType(QualType T, bool LValueRef, |
| SourceLocation Loc, DeclarationName Entity); |
| QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, |
| Expr *ArraySize, unsigned Quals, |
| SourceRange Brackets, DeclarationName Entity); |
| QualType BuildExtVectorType(QualType T, Expr *ArraySize, |
| SourceLocation AttrLoc); |
| |
| bool CheckFunctionReturnType(QualType T, SourceLocation Loc); |
| |
| /// \brief Build a function type. |
| /// |
| /// This routine checks the function type according to C++ rules and |
| /// under the assumption that the result type and parameter types have |
| /// just been instantiated from a template. It therefore duplicates |
| /// some of the behavior of GetTypeForDeclarator, but in a much |
| /// simpler form that is only suitable for this narrow use case. |
| /// |
| /// \param T The return type of the function. |
| /// |
| /// \param ParamTypes The parameter types of the function. This array |
| /// will be modified to account for adjustments to the types of the |
| /// function parameters. |
| /// |
| /// \param Loc The location of the entity whose type involves this |
| /// function type or, if there is no such entity, the location of the |
| /// type that will have function type. |
| /// |
| /// \param Entity The name of the entity that involves the function |
| /// type, if known. |
| /// |
| /// \param EPI Extra information about the function type. Usually this will |
| /// be taken from an existing function with the same prototype. |
| /// |
| /// \returns A suitable function type, if there are no errors. The |
| /// unqualified type will always be a FunctionProtoType. |
| /// Otherwise, returns a NULL type. |
| QualType BuildFunctionType(QualType T, |
| MutableArrayRef<QualType> ParamTypes, |
| SourceLocation Loc, DeclarationName Entity, |
| const FunctionProtoType::ExtProtoInfo &EPI); |
| |
| QualType BuildMemberPointerType(QualType T, QualType Class, |
| SourceLocation Loc, |
| DeclarationName Entity); |
| QualType BuildBlockPointerType(QualType T, |
| SourceLocation Loc, DeclarationName Entity); |
| QualType BuildParenType(QualType T); |
| QualType BuildAtomicType(QualType T, SourceLocation Loc); |
| |
| TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); |
| TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); |
| TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, |
| TypeSourceInfo *ReturnTypeInfo); |
| |
| /// \brief Package the given type and TSI into a ParsedType. |
| ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo); |
| DeclarationNameInfo GetNameForDeclarator(Declarator &D); |
| DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name); |
| static QualType GetTypeFromParser(ParsedType Ty, |
| TypeSourceInfo **TInfo = nullptr); |
| CanThrowResult canThrow(const Expr *E); |
| const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, |
| const FunctionProtoType *FPT); |
| void UpdateExceptionSpec(FunctionDecl *FD, |
| const FunctionProtoType::ExceptionSpecInfo &ESI); |
| bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range); |
| bool CheckDistantExceptionSpec(QualType T); |
| bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New); |
| bool CheckEquivalentExceptionSpec( |
| const FunctionProtoType *Old, SourceLocation OldLoc, |
| const FunctionProtoType *New, SourceLocation NewLoc); |
| bool CheckEquivalentExceptionSpec( |
| const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, |
| const FunctionProtoType *Old, SourceLocation OldLoc, |
| const FunctionProtoType *New, SourceLocation NewLoc, |
| bool *MissingExceptionSpecification = nullptr, |
| bool *MissingEmptyExceptionSpecification = nullptr, |
| bool AllowNoexceptAllMatchWithNoSpec = false, |
| bool IsOperatorNew = false); |
| bool CheckExceptionSpecSubset( |
| const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, |
| const FunctionProtoType *Superset, SourceLocation SuperLoc, |
| const FunctionProtoType *Subset, SourceLocation SubLoc); |
| bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID, |
| const FunctionProtoType *Target, SourceLocation TargetLoc, |
| const FunctionProtoType *Source, SourceLocation SourceLoc); |
| |
| TypeResult ActOnTypeName(Scope *S, Declarator &D); |
| |
| /// \brief The parser has parsed the context-sensitive type 'instancetype' |
| /// in an Objective-C message declaration. Return the appropriate type. |
| ParsedType ActOnObjCInstanceType(SourceLocation Loc); |
| |
| /// \brief Abstract class used to diagnose incomplete types. |
| struct TypeDiagnoser { |
| bool Suppressed; |
| |
| TypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { } |
| |
| virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0; |
| virtual ~TypeDiagnoser() {} |
| }; |
| |
| static int getPrintable(int I) { return I; } |
| static unsigned getPrintable(unsigned I) { return I; } |
| static bool getPrintable(bool B) { return B; } |
| static const char * getPrintable(const char *S) { return S; } |
| static StringRef getPrintable(StringRef S) { return S; } |
| static const std::string &getPrintable(const std::string &S) { return S; } |
| static const IdentifierInfo *getPrintable(const IdentifierInfo *II) { |
| return II; |
| } |
| static DeclarationName getPrintable(DeclarationName N) { return N; } |
| static QualType getPrintable(QualType T) { return T; } |
| static SourceRange getPrintable(SourceRange R) { return R; } |
| static SourceRange getPrintable(SourceLocation L) { return L; } |
| static SourceRange getPrintable(const Expr *E) { return E->getSourceRange(); } |
| static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} |
| |
| template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser { |
| unsigned DiagID; |
| std::tuple<const Ts &...> Args; |
| |
| template <std::size_t... Is> |
| void emit(const SemaDiagnosticBuilder &DB, |
| llvm::index_sequence<Is...>) const { |
| // Apply all tuple elements to the builder in order. |
| bool Dummy[] = {(DB << getPrintable(std::get<Is>(Args)))...}; |
| (void)Dummy; |
| } |
| |
| public: |
| BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args) |
| : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Args(Args...) {} |
| |
| void diagnose(Sema &S, SourceLocation Loc, QualType T) override { |
| if (Suppressed) |
| return; |
| const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID); |
| emit(DB, llvm::index_sequence_for<Ts...>()); |
| DB << T; |
| } |
| }; |
| |
| private: |
| bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, |
| TypeDiagnoser &Diagnoser); |
| |
| VisibleModuleSet VisibleModules; |
| llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack; |
| |
| Module *CachedFakeTopLevelModule; |
| |
| public: |
| /// \brief Get the module owning an entity. |
| Module *getOwningModule(Decl *Entity); |
| |
| /// \brief Make a merged definition of an existing hidden definition \p ND |
| /// visible at the specified location. |
| void makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc); |
| |
| bool isModuleVisible(Module *M) { return VisibleModules.isVisible(M); } |
| |
| /// Determine whether a declaration is visible to name lookup. |
| bool isVisible(const NamedDecl *D) { |
| return !D->isHidden() || isVisibleSlow(D); |
| } |
| bool hasVisibleMergedDefinition(NamedDecl *Def); |
| |
| /// Determine if \p D has a visible definition. If not, suggest a declaration |
| /// that should be made visible to expose the definition. |
| bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, |
| bool OnlyNeedComplete = false); |
| bool hasVisibleDefinition(const NamedDecl *D) { |
| NamedDecl *Hidden; |
| return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden); |
| } |
| |
| /// Determine if the template parameter \p D has a visible default argument. |
| bool |
| hasVisibleDefaultArgument(const NamedDecl *D, |
| llvm::SmallVectorImpl<Module *> *Modules = nullptr); |
| |
| /// Determine if \p A and \p B are equivalent internal linkage declarations |
| /// from different modules, and thus an ambiguity error can be downgraded to |
| /// an extension warning. |
| bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A, |
| const NamedDecl *B); |
| void diagnoseEquivalentInternalLinkageDeclarations( |
| SourceLocation Loc, const NamedDecl *D, |
| ArrayRef<const NamedDecl *> Equiv); |
| |
| bool RequireCompleteType(SourceLocation Loc, QualType T, |
| TypeDiagnoser &Diagnoser); |
| bool RequireCompleteType(SourceLocation Loc, QualType T, |
| unsigned DiagID); |
| |
| template <typename... Ts> |
| bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID, |
| const Ts &...Args) { |
| BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
| return RequireCompleteType(Loc, T, Diagnoser); |
| } |
| |
| bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser); |
| bool RequireCompleteExprType(Expr *E, unsigned DiagID); |
| |
| template <typename... Ts> |
| bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) { |
| BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
| return RequireCompleteExprType(E, Diagnoser); |
| } |
| |
| bool RequireLiteralType(SourceLocation Loc, QualType T, |
| TypeDiagnoser &Diagnoser); |
| bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID); |
| |
| template <typename... Ts> |
| bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID, |
| const Ts &...Args) { |
| BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); |
| return RequireLiteralType(Loc, T, Diagnoser); |
| } |
| |
| QualType getElaboratedType(ElaboratedTypeKeyword Keyword, |
| const CXXScopeSpec &SS, QualType T); |
| |
| QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); |
| /// If AsUnevaluated is false, E is treated as though it were an evaluated |
| /// context, such as when building a type for decltype(auto). |
| QualType BuildDecltypeType(Expr *E, SourceLocation Loc, |
| bool AsUnevaluated = true); |
| QualType BuildUnaryTransformType(QualType BaseType, |
| UnaryTransformType::UTTKind UKind, |
| SourceLocation Loc); |
| |
| //===--------------------------------------------------------------------===// |
| // Symbol table / Decl tracking callbacks: SemaDecl.cpp. |
| // |
| |
| struct SkipBodyInfo { |
| SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {} |
| bool ShouldSkip; |
| NamedDecl *Previous; |
| }; |
| |
| /// List of decls defined in a function prototype. This contains EnumConstants |
| /// that incorrectly end up in translation unit scope because there is no |
| /// function to pin them on. ActOnFunctionDeclarator reads this list and patches |
| /// them into the FunctionDecl. |
| std::vector<NamedDecl*> DeclsInPrototypeScope; |
| |
| DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr); |
| |
| void DiagnoseUseOfUnimplementedSelectors(); |
| |
| bool isSimpleTypeSpecifier(tok::TokenKind Kind) const; |
| |
| ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, |
| Scope *S, CXXScopeSpec *SS = nullptr, |
| bool isClassName = false, |
| bool HasTrailingDot = false, |
| ParsedType ObjectType = ParsedType(), |
| bool IsCtorOrDtorName = false, |
| bool WantNontrivialTypeSourceInfo = false, |
| IdentifierInfo **CorrectedII = nullptr); |
| TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); |
| bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); |
| void DiagnoseUnknownTypeName(IdentifierInfo *&II, |
| SourceLocation IILoc, |
| Scope *S, |
| CXXScopeSpec *SS, |
| ParsedType &SuggestedType, |
| bool AllowClassTemplates = false); |
| |
| /// \brief For compatibility with MSVC, we delay parsing of some default |
| /// template type arguments until instantiation time. Emits a warning and |
| /// returns a synthesized DependentNameType that isn't really dependent on any |
| /// other template arguments. |
| ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, |
| SourceLocation NameLoc); |
| |
| /// \brief Describes the result of the name lookup and resolution performed |
| /// by \c ClassifyName(). |
| enum NameClassificationKind { |
| NC_Unknown, |
| NC_Error, |
| NC_Keyword, |
| NC_Type, |
| NC_Expression, |
| NC_NestedNameSpecifier, |
| NC_TypeTemplate, |
| NC_VarTemplate, |
| NC_FunctionTemplate |
| }; |
| |
| class NameClassification { |
| NameClassificationKind Kind; |
| ExprResult Expr; |
| TemplateName Template; |
| ParsedType Type; |
| const IdentifierInfo *Keyword; |
| |
| explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {} |
| |
| public: |
| NameClassification(ExprResult Expr) : Kind(NC_Expression), Expr(Expr) {} |
| |
| NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {} |
| |
| NameClassification(const IdentifierInfo *Keyword) |
| : Kind(NC_Keyword), Keyword(Keyword) { } |
| |
| static NameClassification Error() { |
| return NameClassification(NC_Error); |
| } |
| |
| static NameClassification Unknown() { |
| return NameClassification(NC_Unknown); |
| } |
| |
| static NameClassification NestedNameSpecifier() { |
| return NameClassification(NC_NestedNameSpecifier); |
| } |
| |
| static NameClassification TypeTemplate(TemplateName Name) { |
| NameClassification Result(NC_TypeTemplate); |
| Result.Template = Name; |
| return Result; |
| } |
| |
| static NameClassification VarTemplate(TemplateName Name) { |
| NameClassification Result(NC_VarTemplate); |
| Result.Template = Name; |
| return Result; |
| } |
| |
| static NameClassification FunctionTemplate(TemplateName Name) { |
| NameClassification Result(NC_FunctionTemplate); |
| Result.Template = Name; |
| return Result; |
| } |
| |
| NameClassificationKind getKind() const { return Kind; } |
| |
| ParsedType getType() const { |
| assert(Kind == NC_Type); |
| return Type; |
| } |
| |
| ExprResult getExpression() const { |
| assert(Kind == NC_Expression); |
| return Expr; |
| } |
| |
| TemplateName getTemplateName() const { |
| assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || |
| Kind == NC_VarTemplate); |
| return Template; |
| } |
| |
| TemplateNameKind getTemplateNameKind() const { |
| switch (Kind) { |
| case NC_TypeTemplate: |
| return TNK_Type_template; |
| case NC_FunctionTemplate: |
| return TNK_Function_template; |
| case NC_VarTemplate: |
| return TNK_Var_template; |
| default: |
| llvm_unreachable("unsupported name classification."); |
| } |
| } |
| }; |
| |
| /// \brief Perform name lookup on the given name, classifying it based on |
| /// the results of name lookup and the following token. |
| /// |
| /// This routine is used by the parser to resolve identifiers and help direct |
| /// parsing. When the identifier cannot be found, this routine will attempt |
| /// to correct the typo and classify based on the resulting name. |
| /// |
| /// \param S The scope in which we're performing name lookup. |
| /// |
| /// \param SS The nested-name-specifier that precedes the name. |
| /// |
| /// \param Name The identifier. If typo correction finds an alternative name, |
| /// this pointer parameter will be updated accordingly. |
| /// |
| /// \param NameLoc The location of the identifier. |
| /// |
| /// \param NextToken The token following the identifier. Used to help |
| /// disambiguate the name. |
| /// |
| /// \param IsAddressOfOperand True if this name is the operand of a unary |
| /// address of ('&') expression, assuming it is classified as an |
| /// expression. |
| /// |
| /// \param CCC The correction callback, if typo correction is desired. |
| NameClassification |
| ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, |
| SourceLocation NameLoc, const Token &NextToken, |
| bool IsAddressOfOperand, |
| std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); |
| |
| Decl *ActOnDeclarator(Scope *S, Declarator &D); |
| |
| NamedDecl *HandleDeclarator(Scope *S, Declarator &D, |
| MultiTemplateParamsArg TemplateParameterLists); |
| void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S); |
| bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); |
| bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, |
| DeclarationName Name, |
| SourceLocation Loc); |
| void |
| diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, |
| SourceLocation FallbackLoc, |
| SourceLocation ConstQualLoc = SourceLocation(), |
| SourceLocation VolatileQualLoc = SourceLocation(), |
| SourceLocation RestrictQualLoc = SourceLocation(), |
| SourceLocation AtomicQualLoc = SourceLocation()); |
| |
| static bool adjustContextForLocalExternDecl(DeclContext *&DC); |
| void DiagnoseFunctionSpecifiers(const DeclSpec &DS); |
| void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); |
| void CheckShadow(Scope *S, VarDecl *D); |
| void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); |
| void handleTagNumbering(const TagDecl *Tag, Scope *TagScope); |
| void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, |
| TypedefNameDecl *NewTD); |
| void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D); |
| NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, |
| TypeSourceInfo *TInfo, |
| LookupResult &Previous); |
| NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, |
| LookupResult &Previous, bool &Redeclaration); |
| NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, |
| TypeSourceInfo *TInfo, |
| LookupResult &Previous, |
| MultiTemplateParamsArg TemplateParamLists, |
| bool &AddToScope); |
| // Returns true if the variable declaration is a redeclaration |
| bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); |
| void CheckVariableDeclarationType(VarDecl *NewVD); |
| void CheckCompleteVariableDeclaration(VarDecl *var); |
| void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); |
| |
| NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, |
| TypeSourceInfo *TInfo, |
| LookupResult &Previous, |
| MultiTemplateParamsArg TemplateParamLists, |
| bool &AddToScope); |
| bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); |
| |
| bool CheckConstexprFunctionDecl(const FunctionDecl *FD); |
| bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body); |
| |
| void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD); |
| void FindHiddenVirtualMethods(CXXMethodDecl *MD, |
| SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); |
| void NoteHiddenVirtualMethods(CXXMethodDecl *MD, |
| SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); |
| // Returns true if the function declaration is a redeclaration |
| bool CheckFunctionDeclaration(Scope *S, |
| FunctionDecl *NewFD, LookupResult &Previous, |
| bool IsExplicitSpecialization); |
| void CheckMain(FunctionDecl *FD, const DeclSpec &D); |
| void CheckMSVCRTEntryPoint(FunctionDecl *FD); |
| Decl *ActOnParamDeclarator(Scope *S, Declarator &D); |
| ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, |
| SourceLocation Loc, |
| QualType T); |
| ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc, |
| SourceLocation NameLoc, IdentifierInfo *Name, |
| QualType T, TypeSourceInfo *TSInfo, |
| StorageClass SC); |
| void ActOnParamDefaultArgument(Decl *param, |
| SourceLocation EqualLoc, |
| Expr *defarg); |
| void ActOnParamUnparsedDefaultArgument(Decl *param, |
| SourceLocation EqualLoc, |
| SourceLocation ArgLoc); |
| void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); |
| bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, |
| SourceLocation EqualLoc); |
| |
| void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, |
| bool TypeMayContainAuto); |
| void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); |
| void ActOnInitializerError(Decl *Dcl); |
| void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc); |
| void ActOnCXXForRangeDecl(Decl *D); |
| StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, |
| IdentifierInfo *Ident, |
| ParsedAttributes &Attrs, |
| SourceLocation AttrEnd); |
| void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); |
| void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); |
| void FinalizeDeclaration(Decl *D); |
| DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, |
| ArrayRef<Decl *> Group); |
| DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group, |
| bool TypeMayContainAuto = true); |
| |
| /// Should be called on all declarations that might have attached |
| /// documentation comments. |
| void ActOnDocumentableDecl(Decl *D); |
| void ActOnDocumentableDecls(ArrayRef<Decl *> Group); |
| |
| void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, |
| SourceLocation LocAfterDecls); |
| void CheckForFunctionRedefinition( |
| FunctionDecl *FD, const FunctionDecl *EffectiveDefinition = nullptr, |
| SkipBodyInfo *SkipBody = nullptr); |
| Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D, |
| MultiTemplateParamsArg TemplateParamLists, |
| SkipBodyInfo *SkipBody = nullptr); |
| Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D, |
| SkipBodyInfo *SkipBody = nullptr); |
| void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); |
| bool isObjCMethodDecl(Decl *D) { |
| return D && isa<ObjCMethodDecl>(D); |
| } |
| |
| /// \brief Determine whether we can delay parsing the body of a function or |
| /// function template until it is used, assuming we don't care about emitting |
| /// code for that function. |
| /// |
| /// This will be \c false if we may need the body of the function in the |
| /// middle of parsing an expression (where it's impractical to switch to |
| /// parsing a different function), for instance, if it's constexpr in C++11 |
| /// or has an 'auto' return type in C++14. These cases are essentially bugs. |
| bool canDelayFunctionBody(const Declarator &D); |
| |
| /// \brief Determine whether we can skip parsing the body of a function |
| /// definition, assuming we don't care about analyzing its body or emitting |
| /// code for that function. |
| /// |
| /// This will be \c false only if we may need the body of the function in |
| /// order to parse the rest of the program (for instance, if it is |
| /// \c constexpr in C++11 or has an 'auto' return type in C++14). |
| bool canSkipFunctionBody(Decl *D); |
| |
| void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); |
| Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); |
| Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); |
| Decl *ActOnSkippedFunctionBody(Decl *Decl); |
| void ActOnFinishInlineMethodDef(CXXMethodDecl *D); |
| |
| /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an |
| /// attribute for which parsing is delayed. |
| void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs); |
| |
| /// \brief Diagnose any unused parameters in the given sequence of |
| /// ParmVarDecl pointers. |
| void DiagnoseUnusedParameters(ParmVarDecl * const *Begin, |
| ParmVarDecl * const *End); |
| |
| /// \brief Diagnose whether the size of parameters or return value of a |
| /// function or obj-c method definition is pass-by-value and larger than a |
| /// specified threshold. |
| void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin, |
| ParmVarDecl * const *End, |
| QualType ReturnTy, |
| NamedDecl *D); |
| |
| void DiagnoseInvalidJumps(Stmt *Body); |
| Decl *ActOnFileScopeAsmDecl(Expr *expr, |
| SourceLocation AsmLoc, |
| SourceLocation RParenLoc); |
| |
| /// \brief Handle a C++11 empty-declaration and attribute-declaration. |
| Decl *ActOnEmptyDeclaration(Scope *S, |
| AttributeList *AttrList, |
| SourceLocation SemiLoc); |
| |
| /// \brief The parser has processed a module import declaration. |
| /// |
| /// \param AtLoc The location of the '@' symbol, if any. |
| /// |
| /// \param ImportLoc The location of the 'import' keyword. |
| /// |
| /// \param Path The module access path. |
| DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, |
| ModuleIdPath Path); |
| |
| /// \brief The parser has processed a module import translated from a |
| /// #include or similar preprocessing directive. |
| void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); |
| |
| /// \brief The parsed has entered a submodule. |
| void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod); |
| /// \brief The parser has left a submodule. |
| void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); |
| |
| /// \brief Check if module import may be found in the current context, |
| /// emit error if not. |
| void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc); |
| |
| /// \brief Create an implicit import of the given module at the given |
| /// source location, for error recovery, if possible. |
| /// |
| /// This routine is typically used when an entity found by name lookup |
| /// is actually hidden within a module that we know about but the user |
| /// has forgotten to import. |
| void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, |
| Module *Mod); |
| |
| /// Kinds of missing import. Note, the values of these enumerators correspond |
| /// to %select values in diagnostics. |
| enum class MissingImportKind { |
| Declaration, |
| Definition, |
| DefaultArgument |
| }; |
| |
| /// \brief Diagnose that the specified declaration needs to be visible but |
| /// isn't, and suggest a module import that would resolve the problem. |
| void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, |
| bool NeedDefinition, bool Recover = true); |
| void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, |
| SourceLocation DeclLoc, ArrayRef<Module *> Modules, |
| MissingImportKind MIK, bool Recover); |
| |
| /// \brief Retrieve a suitable printing policy. |
| PrintingPolicy getPrintingPolicy() const { |
| return getPrintingPolicy(Context, PP); |
| } |
| |
| /// \brief Retrieve a suitable printing policy. |
| static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx, |
| const Preprocessor &PP); |
| |
| /// Scope actions. |
| void ActOnPopScope(SourceLocation Loc, Scope *S); |
| void ActOnTranslationUnitScope(Scope *S); |
| |
| Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, |
| DeclSpec &DS); |
| Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, |
| DeclSpec &DS, |
| MultiTemplateParamsArg TemplateParams, |
| bool IsExplicitInstantiation = false); |
| |
| Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, |
| AccessSpecifier AS, |
| RecordDecl *Record, |
| const PrintingPolicy &Policy); |
| |
| Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, |
| RecordDecl *Record); |
| |
| bool isAcceptableTagRedeclaration(const TagDecl *Previous, |
| TagTypeKind NewTag, bool isDefinition, |
| SourceLocation NewTagLoc, |
| const IdentifierInfo *Name); |
| |
| enum TagUseKind { |
| TUK_Reference, // Reference to a tag: 'struct foo *X;' |
| TUK_Declaration, // Fwd decl of a tag: 'struct foo;' |
| TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;' |
| TUK_Friend // Friend declaration: 'friend struct foo;' |
| }; |
| |
| Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, |
| SourceLocation KWLoc, CXXScopeSpec &SS, |
| IdentifierInfo *Name, SourceLocation NameLoc, |
| AttributeList *Attr, AccessSpecifier AS, |
| SourceLocation ModulePrivateLoc, |
| MultiTemplateParamsArg TemplateParameterLists, |
| bool &OwnedDecl, bool &IsDependent, |
| SourceLocation ScopedEnumKWLoc, |
| bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, |
| bool IsTypeSpecifier, SkipBodyInfo *SkipBody = nullptr); |
| |
| Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, |
| unsigned TagSpec, SourceLocation TagLoc, |
| CXXScopeSpec &SS, |
| IdentifierInfo *Name, SourceLocation NameLoc, |
| AttributeList *Attr, |
| MultiTemplateParamsArg TempParamLists); |
| |
| TypeResult ActOnDependentTag(Scope *S, |
| unsigned TagSpec, |
| TagUseKind TUK, |
| const CXXScopeSpec &SS, |
| IdentifierInfo *Name, |
| SourceLocation TagLoc, |
| SourceLocation NameLoc); |
| |
| void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, |
| IdentifierInfo *ClassName, |
| SmallVectorImpl<Decl *> &Decls); |
| Decl *ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, |
| Declarator &D, Expr *BitfieldWidth); |
| |
| FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, |
| Declarator &D, Expr *BitfieldWidth, |
| InClassInitStyle InitStyle, |
| AccessSpecifier AS); |
| MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD, |
| SourceLocation DeclStart, |
| Declarator &D, Expr *BitfieldWidth, |
| InClassInitStyle InitStyle, |
| AccessSpecifier AS, |
| AttributeList *MSPropertyAttr); |
| |
| FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, |
| TypeSourceInfo *TInfo, |
| RecordDecl *Record, SourceLocation Loc, |
| bool Mutable, Expr *BitfieldWidth, |
| InClassInitStyle InitStyle, |
| SourceLocation TSSL, |
| AccessSpecifier AS, NamedDecl *PrevDecl, |
| Declarator *D = nullptr); |
| |
| bool CheckNontrivialField(FieldDecl *FD); |
| void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM); |
| bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM, |
| bool Diagnose = false); |
| CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD); |
| void ActOnLastBitfield(SourceLocation DeclStart, |
| SmallVectorImpl<Decl *> &AllIvarDecls); |
| Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, |
| Declarator &D, Expr *BitfieldWidth, |
| tok::ObjCKeywordKind visibility); |
| |
| // This is used for both record definitions and ObjC interface declarations. |
| void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl, |
| ArrayRef<Decl *> Fields, |
| SourceLocation LBrac, SourceLocation RBrac, |
| AttributeList *AttrList); |
| |
| /// ActOnTagStartDefinition - Invoked when we have entered the |
| /// scope of a tag's definition (e.g., for an enumeration, class, |
| /// struct, or union). |
| void ActOnTagStartDefinition(Scope *S, Decl *TagDecl); |
| |
| typedef void *SkippedDefinitionContext; |
| |
| /// \brief Invoked when we enter a tag definition that we're skipping. |
| SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD); |
| |
| Decl *ActOnObjCContainerStartDefinition(Decl *IDecl); |
| |
| /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a |
| /// C++ record definition's base-specifiers clause and are starting its |
| /// member declarations. |
| void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, |
| SourceLocation FinalLoc, |
| bool IsFinalSpelledSealed, |
| SourceLocation LBraceLoc); |
| |
| /// ActOnTagFinishDefinition - Invoked once we have finished parsing |
| /// the definition of a tag (enumeration, class, struct, or union). |
| void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, |
| SourceLocation RBraceLoc); |
| |
| void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context); |
| |
| void ActOnObjCContainerFinishDefinition(); |
| |
| /// \brief Invoked when we must temporarily exit the objective-c container |
| /// scope for parsing/looking-up C constructs. |
| /// |
| /// Must be followed by a call to \see ActOnObjCReenterContainerContext |
| void ActOnObjCTemporaryExitContainerContext(DeclContext *DC); |
| void ActOnObjCReenterContainerContext(DeclContext *DC); |
| |
| /// ActOnTagDefinitionError - Invoked when there was an unrecoverable |
| /// error parsing the definition of a tag. |
| void ActOnTagDefinitionError(Scope *S, Decl *TagDecl); |
| |
| EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum, |
| EnumConstantDecl *LastEnumConst, |
| SourceLocation IdLoc, |
| IdentifierInfo *Id, |
| Expr *val); |
| bool CheckEnumUnderlyingType(TypeSourceInfo *TI); |
| bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, |
| QualType EnumUnderlyingTy, |
| bool EnumUnderlyingIsImplicit, |
| const EnumDecl *Prev); |
| |
| /// Determine whether the body of an anonymous enumeration should be skipped. |
| /// \param II The name of the first enumerator. |
| SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, |
| SourceLocation IILoc); |
| |
| Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, |
| SourceLocation IdLoc, IdentifierInfo *Id, |
| AttributeList *Attrs, |
| SourceLocation EqualLoc, Expr *Val); |
| void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, |
| SourceLocation RBraceLoc, Decl *EnumDecl, |
| ArrayRef<Decl *> Elements, |
| Scope *S, AttributeList *Attr); |
| |
| DeclContext *getContainingDC(DeclContext *DC); |
| |
| /// Set the current declaration context until it gets popped. |
| void PushDeclContext(Scope *S, DeclContext *DC); |
| void PopDeclContext(); |
| |
| /// EnterDeclaratorContext - Used when we must lookup names in the context |
| /// of a declarator's nested name specifier. |
| void EnterDeclaratorContext(Scope *S, DeclContext *DC); |
| void ExitDeclaratorContext(Scope *S); |
| |
| /// Push the parameters of D, which must be a function, into scope. |
| void ActOnReenterFunctionContext(Scope* S, Decl* D); |
| void ActOnExitFunctionContext(); |
| |
| DeclContext *getFunctionLevelDeclContext(); |
| |
| /// getCurFunctionDecl - If inside of a function body, this returns a pointer |
| /// to the function decl for the function being parsed. If we're currently |
| /// in a 'block', this returns the containing context. |
| FunctionDecl *getCurFunctionDecl(); |
| |
| /// getCurMethodDecl - If inside of a method body, this returns a pointer to |
| /// the method decl for the method being parsed. If we're currently |
| /// in a 'block', this returns the containing context. |
| ObjCMethodDecl *getCurMethodDecl(); |
| |
| /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method |
| /// or C function we're in, otherwise return null. If we're currently |
| /// in a 'block', this returns the containing context. |
| NamedDecl *getCurFunctionOrMethodDecl(); |
| |
| /// Add this decl to the scope shadowed decl chains. |
| void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true); |
| |
| /// \brief Make the given externally-produced declaration visible at the |
| /// top level scope. |
| /// |
| /// \param D The externally-produced declaration to push. |
| /// |
| /// \param Name The name of the externally-produced declaration. |
| void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); |
| |
| /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true |
| /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns |
| /// true if 'D' belongs to the given declaration context. |
| /// |
| /// \param AllowInlineNamespace If \c true, allow the declaration to be in the |
| /// enclosing namespace set of the context, rather than contained |
| /// directly within it. |
| bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr, |
| bool AllowInlineNamespace = false); |
| |
| /// Finds the scope corresponding to the given decl context, if it |
| /// happens to be an enclosing scope. Otherwise return NULL. |
| static Scope *getScopeForDeclContext(Scope *S, DeclContext *DC); |
| |
| /// Subroutines of ActOnDeclarator(). |
| TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, |
| TypeSourceInfo *TInfo); |
| bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New); |
| |
| /// \brief Describes the kind of merge to perform for availability |
| /// attributes (including "deprecated", "unavailable", and "availability"). |
| enum AvailabilityMergeKind { |
| /// \brief Don't merge availability attributes at all. |
| AMK_None, |
| /// \brief Merge availability attributes for a redeclaration, which requires |
| /// an exact match. |
| AMK_Redeclaration, |
| /// \brief Merge availability attributes for an override, which requires |
| /// an exact match or a weakening of constraints. |
| AMK_Override, |
| /// \brief Merge availability attributes for an implementation of |
| /// a protocol requirement. |
| AMK_ProtocolImplementation, |
| }; |
| |
| /// Attribute merging methods. Return true if a new attribute was added. |
| AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, |
| IdentifierInfo *Platform, |
| VersionTuple Introduced, |
| VersionTuple Deprecated, |
| VersionTuple Obsoleted, |
| bool IsUnavailable, |
| StringRef Message, |
| AvailabilityMergeKind AMK, |
| unsigned AttrSpellingListIndex); |
| TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, |
| TypeVisibilityAttr::VisibilityType Vis, |
| unsigned AttrSpellingListIndex); |
| VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range, |
| VisibilityAttr::VisibilityType Vis, |
| unsigned AttrSpellingListIndex); |
| DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range, |
| unsigned AttrSpellingListIndex); |
| DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range, |
| unsigned AttrSpellingListIndex); |
| MSInheritanceAttr * |
| mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, |
| unsigned AttrSpellingListIndex, |
| MSInheritanceAttr::Spelling SemanticSpelling); |
| FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, |
| IdentifierInfo *Format, int FormatIdx, |
| int FirstArg, unsigned AttrSpellingListIndex); |
| SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name, |
| unsigned AttrSpellingListIndex); |
| AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, SourceRange Range, |
| IdentifierInfo *Ident, |
| unsigned AttrSpellingListIndex); |
| MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range, |
| unsigned AttrSpellingListIndex); |
| OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range, |
| unsigned AttrSpellingListIndex); |
| SwiftNameAttr *mergeSwiftNameAttr(Decl *D, SourceRange Range, |
| StringRef Name, bool Override, |
| unsigned AttrSpellingListIndex); |
| |
| void mergeDeclAttributes(NamedDecl *New, Decl *Old, |
| AvailabilityMergeKind AMK = AMK_Redeclaration); |
| void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls); |
| bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S, |
| bool MergeTypeWithOld); |
| bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, |
| Scope *S, bool MergeTypeWithOld); |
| void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old); |
| void MergeVarDecl(VarDecl *New, LookupResult &Previous); |
| void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld); |
| void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); |
| bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S); |
| |
| // AssignmentAction - This is used by all the assignment diagnostic functions |
| // to represent what is actually causing the operation |
| enum AssignmentAction { |
| AA_Assigning, |
| AA_Passing, |
| AA_Returning, |
| AA_Converting, |
| AA_Initializing, |
| AA_Sending, |
| AA_Casting, |
| AA_Passing_CFAudited |
| }; |
| |
| /// C++ Overloading. |
| enum OverloadKind { |
| /// This is a legitimate overload: the existing declarations are |
| /// functions or function templates with different signatures. |
| Ovl_Overload, |
| |
| /// This is not an overload because the signature exactly matches |
| /// an existing declaration. |
| Ovl_Match, |
| |
| /// This is not an overload because the lookup results contain a |
| /// non-function. |
| Ovl_NonFunction |
| }; |
| OverloadKind CheckOverload(Scope *S, |
| FunctionDecl *New, |
| const LookupResult &OldDecls, |
| NamedDecl *&OldDecl, |
| bool IsForUsingDecl); |
| bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl); |
| |
| /// \brief Checks availability of the function depending on the current |
| /// function context.Inside an unavailable function,unavailability is ignored. |
| /// |
| /// \returns true if \p FD is unavailable and current context is inside |
| /// an available function, false otherwise. |
| bool isFunctionConsideredUnavailable(FunctionDecl *FD); |
| |
| ImplicitConversionSequence |
| TryImplicitConversion(Expr *From, QualType ToType, |
| bool SuppressUserConversions, |
| bool AllowExplicit, |
| bool InOverloadResolution, |
| bool CStyle, |
| bool AllowObjCWritebackConversion); |
| |
| bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType); |
| bool IsFloatingPointPromotion(QualType FromType, QualType ToType); |
| bool IsComplexPromotion(QualType FromType, QualType ToType); |
| bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType, |
| bool InOverloadResolution, |
| QualType& ConvertedType, bool &IncompatibleObjC); |
| bool isObjCPointerConversion(QualType FromType, QualType ToType, |
| QualType& ConvertedType, bool &IncompatibleObjC); |
| bool isObjCWritebackConversion(QualType FromType, QualType ToType, |
| QualType &ConvertedType); |
| bool IsBlockPointerConversion(QualType FromType, QualType ToType, |
| QualType& ConvertedType); |
| bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType, |
| const FunctionProtoType *NewType, |
| unsigned *ArgPos = nullptr); |
| void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, |
| QualType FromType, QualType ToType); |
| |
| void maybeExtendBlockObject(ExprResult &E); |
| CastKind PrepareCastToObjCObjectPointer(ExprResult &E); |
| bool CheckPointerConversion(Expr *From, QualType ToType, |
| CastKind &Kind, |
| CXXCastPath& BasePath, |
| bool IgnoreBaseAccess); |
| bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, |
| bool InOverloadResolution, |
| QualType &ConvertedType); |
| bool CheckMemberPointerConversion(Expr *From, QualType ToType, |
| CastKind &Kind, |
| CXXCastPath &BasePath, |
| bool IgnoreBaseAccess); |
| bool IsQualificationConversion(QualType FromType, QualType ToType, |
| bool CStyle, bool &ObjCLifetimeConversion); |
| bool IsNoReturnConversion(QualType FromType, QualType ToType, |
| QualType &ResultTy); |
| bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); |
| bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg); |
| |
| ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, |
| const VarDecl *NRVOCandidate, |
| QualType ResultType, |
| Expr *Value, |
| bool AllowNRVO = true); |
| |
| bool CanPerformCopyInitialization(const InitializedEntity &Entity, |
| ExprResult Init); |
| ExprResult PerformCopyInitialization(const InitializedEntity &Entity, |
| SourceLocation EqualLoc, |
| ExprResult Init, |
| bool TopLevelOfInitList = false, |
| bool AllowExplicit = false); |
| ExprResult PerformObjectArgumentInitialization(Expr *From, |
| NestedNameSpecifier *Qualifier, |
| NamedDecl *FoundDecl, |
| CXXMethodDecl *Method); |
| |
| ExprResult PerformContextuallyConvertToBool(Expr *From); |
| ExprResult PerformContextuallyConvertToObjCPointer(Expr *From); |
| |
| /// Contexts in which a converted constant expression is required. |
| enum CCEKind { |
| CCEK_CaseValue, ///< Expression in a case label. |
| CCEK_Enumerator, ///< Enumerator value with fixed underlying type. |
| CCEK_TemplateArg, ///< Value of a non-type template parameter. |
| CCEK_NewExpr ///< Constant expression in a noptr-new-declarator. |
| }; |
| ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, |
| llvm::APSInt &Value, CCEKind CCE); |
| ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, |
| APValue &Value, CCEKind CCE); |
| |
| /// \brief Abstract base class used to perform a contextual implicit |
| /// conversion from an expression to any type passing a filter. |
| class ContextualImplicitConverter { |
| public: |
| bool Suppress; |
| bool SuppressConversion; |
| |
| ContextualImplicitConverter(bool Suppress = false, |
| bool SuppressConversion = false) |
| : Suppress(Suppress), SuppressConversion(SuppressConversion) {} |
| |
| /// \brief Determine whether the specified type is a valid destination type |
| /// for this conversion. |
| virtual bool match(QualType T) = 0; |
| |
| /// \brief Emits a diagnostic complaining that the expression does not have |
| /// integral or enumeration type. |
| virtual SemaDiagnosticBuilder |
| diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0; |
| |
| /// \brief Emits a diagnostic when the expression has incomplete class type. |
| virtual SemaDiagnosticBuilder |
| diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0; |
| |
| /// \brief Emits a diagnostic when the only matching conversion function |
| /// is explicit. |
| virtual SemaDiagnosticBuilder diagnoseExplicitConv( |
| Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; |
| |
| /// \brief Emits a note for the explicit conversion function. |
| virtual SemaDiagnosticBuilder |
| noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; |
| |
| /// \brief Emits a diagnostic when there are multiple possible conversion |
| /// functions. |
| virtual SemaDiagnosticBuilder |
| diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0; |
| |
| /// \brief Emits a note for one of the candidate conversions. |
| virtual SemaDiagnosticBuilder |
| noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; |
| |
| /// \brief Emits a diagnostic when we picked a conversion function |
| /// (for cases when we are not allowed to pick a conversion function). |
| virtual SemaDiagnosticBuilder diagnoseConversion( |
| Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; |
| |
| virtual ~ContextualImplicitConverter() {} |
| }; |
| |
| class ICEConvertDiagnoser : public ContextualImplicitConverter { |
| bool AllowScopedEnumerations; |
| |
| public: |
| ICEConvertDiagnoser(bool AllowScopedEnumerations, |
| bool Suppress, bool SuppressConversion) |
| : ContextualImplicitConverter(Suppress, SuppressConversion), |
| AllowScopedEnumerations(AllowScopedEnumerations) {} |
| |
| /// Match an integral or (possibly scoped) enumeration type. |
| bool match(QualType T) override; |
| |
| SemaDiagnosticBuilder |
| diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override { |
| return diagnoseNotInt(S, Loc, T); |
| } |
| |
| /// \brief Emits a diagnostic complaining that the expression does not have |
| /// integral or enumeration type. |
| virtual SemaDiagnosticBuilder |
| diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0; |
| }; |
| |
| /// Perform a contextual implicit conversion. |
| ExprResult PerformContextualImplicitConversion( |
| SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter); |
| |
| |
| enum ObjCSubscriptKind { |
| OS_Array, |
| OS_Dictionary, |
| OS_Error |
| }; |
| ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE); |
| |
| // Note that LK_String is intentionally after the other literals, as |
| // this is used for diagnostics logic. |
| enum ObjCLiteralKind { |
| LK_Array, |
| LK_Dictionary, |
| LK_Numeric, |
| LK_Boxed, |
| LK_String, |
| LK_Block, |
| LK_None |
| }; |
| ObjCLiteralKind CheckLiteralKind(Expr *FromE); |
| |
| ExprResult PerformObjectMemberConversion(Expr *From, |
| NestedNameSpecifier *Qualifier, |
| NamedDecl *FoundDecl, |
| NamedDecl *Member); |
| |
| // Members have to be NamespaceDecl* or TranslationUnitDecl*. |
| // TODO: make this is a typesafe union. |
| typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet; |
| typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet; |
| |
| void AddOverloadCandidate(FunctionDecl *Function, |
| DeclAccessPair FoundDecl, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| bool SuppressUserConversions = false, |
| bool PartialOverloading = false, |
| bool AllowExplicit = false); |
| void AddFunctionCandidates(const UnresolvedSetImpl &Functions, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet &CandidateSet, |
| TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, |
| bool SuppressUserConversions = false, |
| bool PartialOverloading = false); |
| void AddMethodCandidate(DeclAccessPair FoundDecl, |
| QualType ObjectType, |
| Expr::Classification ObjectClassification, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| bool SuppressUserConversion = false); |
| void AddMethodCandidate(CXXMethodDecl *Method, |
| DeclAccessPair FoundDecl, |
| CXXRecordDecl *ActingContext, QualType ObjectType, |
| Expr::Classification ObjectClassification, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| bool SuppressUserConversions = false, |
| bool PartialOverloading = false); |
| void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, |
| DeclAccessPair FoundDecl, |
| CXXRecordDecl *ActingContext, |
| TemplateArgumentListInfo *ExplicitTemplateArgs, |
| QualType ObjectType, |
| Expr::Classification ObjectClassification, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| bool SuppressUserConversions = false, |
| bool PartialOverloading = false); |
| void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, |
| DeclAccessPair FoundDecl, |
| TemplateArgumentListInfo *ExplicitTemplateArgs, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| bool SuppressUserConversions = false, |
| bool PartialOverloading = false); |
| void AddConversionCandidate(CXXConversionDecl *Conversion, |
| DeclAccessPair FoundDecl, |
| CXXRecordDecl *ActingContext, |
| Expr *From, QualType ToType, |
| OverloadCandidateSet& CandidateSet, |
| bool AllowObjCConversionOnExplicit); |
| void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, |
| DeclAccessPair FoundDecl, |
| CXXRecordDecl *ActingContext, |
| Expr *From, QualType ToType, |
| OverloadCandidateSet &CandidateSet, |
| bool AllowObjCConversionOnExplicit); |
| void AddSurrogateCandidate(CXXConversionDecl *Conversion, |
| DeclAccessPair FoundDecl, |
| CXXRecordDecl *ActingContext, |
| const FunctionProtoType *Proto, |
| Expr *Object, ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet); |
| void AddMemberOperatorCandidates(OverloadedOperatorKind Op, |
| SourceLocation OpLoc, ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| SourceRange OpRange = SourceRange()); |
| void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet, |
| bool IsAssignmentOperator = false, |
| unsigned NumContextualBoolArguments = 0); |
| void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, |
| SourceLocation OpLoc, ArrayRef<Expr *> Args, |
| OverloadCandidateSet& CandidateSet); |
| void AddArgumentDependentLookupCandidates(DeclarationName Name, |
| SourceLocation Loc, |
| ArrayRef<Expr *> Args, |
| TemplateArgumentListInfo *ExplicitTemplateArgs, |
| OverloadCandidateSet& CandidateSet, |
| bool PartialOverloading = false); |
| |
| // Emit as a 'note' the specific overload candidate |
| void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(), |
| bool TakingAddress = false); |
| |
| // Emit as a series of 'note's all template and non-templates identified by |
| // the expression Expr |
| void NoteAllOverloadCandidates(Expr *E, QualType DestType = QualType(), |
| bool TakingAddress = false); |
| |
| /// Check the enable_if expressions on the given function. Returns the first |
| /// failing attribute, or NULL if they were all successful. |
| EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, |
| bool MissingImplicitThis = false); |
| |
| // [PossiblyAFunctionType] --> [Return] |
| // NonFunctionType --> NonFunctionType |
| // R (A) --> R(A) |
| // R (*)(A) --> R (A) |
| // R (&)(A) --> R (A) |
| // R (S::*)(A) --> R (A) |
| QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType); |
| |
| FunctionDecl * |
| ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, |
| QualType TargetType, |
| bool Complain, |
| DeclAccessPair &Found, |
| bool *pHadMultipleCandidates = nullptr); |
| |
| FunctionDecl * |
| ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, |
| bool Complain = false, |
| DeclAccessPair *Found = nullptr); |
| |
| bool ResolveAndFixSingleFunctionTemplateSpecialization( |
| ExprResult &SrcExpr, |
| bool DoFunctionPointerConverion = false, |
| bool Complain = false, |
| SourceRange OpRangeForComplaining = SourceRange(), |
| QualType DestTypeForComplaining = QualType(), |
| unsigned DiagIDForComplaining = 0); |
| |
| |
| Expr *FixOverloadedFunctionReference(Expr *E, |
| DeclAccessPair FoundDecl, |
| FunctionDecl *Fn); |
| ExprResult FixOverloadedFunctionReference(ExprResult, |
| DeclAccessPair FoundDecl, |
| FunctionDecl *Fn); |
| |
| void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, |
| ArrayRef<Expr *> Args, |
| OverloadCandidateSet &CandidateSet, |
| bool PartialOverloading = false); |
| |
| // An enum used to represent the different possible results of building a |
| // range-based for loop. |
| enum ForRangeStatus { |
| FRS_Success, |
| FRS_NoViableFunction, |
| FRS_DiagnosticIssued |
| }; |
| |
| ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, |
| SourceLocation RangeLoc, |
| const DeclarationNameInfo &NameInfo, |
| LookupResult &MemberLookup, |
| OverloadCandidateSet *CandidateSet, |
| Expr *Range, ExprResult *CallExpr); |
| |
| ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn, |
| UnresolvedLookupExpr *ULE, |
| SourceLocation LParenLoc, |
| MultiExprArg Args, |
| SourceLocation RParenLoc, |
| Expr *ExecConfig, |
| bool AllowTypoCorrection=true); |
| |
| bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, |
| MultiExprArg Args, SourceLocation RParenLoc, |
| OverloadCandidateSet *CandidateSet, |
| ExprResult *Result); |
| |
| ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, |
| unsigned Opc, |
| const UnresolvedSetImpl &Fns, |
| Expr *input); |
| |
| ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, |
| unsigned Opc, |
| const UnresolvedSetImpl &Fns, |
| Expr *LHS, Expr *RHS); |
| |
| ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, |
| SourceLocation RLoc, |
| Expr *Base,Expr *Idx); |
| |
| ExprResult |
| BuildCallToMemberFunction(Scope *S, Expr *MemExpr, |
| SourceLocation LParenLoc, |
| MultiExprArg Args, |
| SourceLocation RParenLoc); |
| ExprResult |
| BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, |
| MultiExprArg Args, |
| SourceLocation RParenLoc); |
| |
| ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, |
| SourceLocation OpLoc, |
| bool *NoArrowOperatorFound = nullptr); |
| |
| /// CheckCallReturnType - Checks that a call expression's return type is |
| /// complete. Returns true on failure. The location passed in is the location |
| /// that best represents the call. |
| bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc, |
| CallExpr *CE, FunctionDecl *FD); |
| |
| /// Helpers for dealing with blocks and functions. |
| bool CheckParmsForFunctionDef(ParmVarDecl *const *Param, |
| ParmVarDecl *const *ParamEnd, |
| bool CheckParameterNames); |
| void CheckCXXDefaultArguments(FunctionDecl *FD); |
| void CheckExtraCXXDefaultArguments(Declarator &D); |
| Scope *getNonFieldDeclScope(Scope *S); |
| |
| /// \name Name lookup |
| /// |
| /// These routines provide name lookup that is used during semantic |
| /// analysis to resolve the various kinds of names (identifiers, |
| /// overloaded operator names, constructor names, etc.) into zero or |
| /// more declarations within a particular scope. The major entry |
| /// points are LookupName, which performs unqualified name lookup, |
| /// and LookupQualifiedName, which performs qualified name lookup. |
| /// |
| /// All name lookup is performed based on some specific criteria, |
| /// which specify what names will be visible to name lookup and how |
| /// far name lookup should work. These criteria are important both |
| /// for capturing language semantics (certain lookups will ignore |
| /// certain names, for example) and for performance, since name |
| /// lookup is often a bottleneck in the compilation of C++. Name |
| /// lookup criteria is specified via the LookupCriteria enumeration. |
| /// |
| /// The results of name lookup can vary based on the kind of name |
| /// lookup performed, the current language, and the translation |
| /// unit. In C, for example, name lookup will either return nothing |
| /// (no entity found) or a single declaration. In C++, name lookup |
| /// can additionally refer to a set of overloaded functions or |
| /// result in an ambiguity. All of the possible results of name |
| /// lookup are captured by the LookupResult class, which provides |
| /// the ability to distinguish among them. |
| //@{ |
| |
| /// @brief Describes the kind of name lookup to perform. |
| enum LookupNameKind { |
| /// Ordinary name lookup, which finds ordinary names (functions, |
| /// variables, typedefs, etc.) in C and most kinds of names |
| /// (functions, variables, members, types, etc.) in C++. |
| LookupOrdinaryName = 0, |
| /// Tag name lookup, which finds the names of enums, classes, |
| /// structs, and unions. |
| LookupTagName, |
| /// Label name lookup. |
| LookupLabel, |
| /// Member name lookup, which finds the names of |
| /// class/struct/union members. |
| LookupMemberName, |
| /// Look up of an operator name (e.g., operator+) for use with |
| /// operator overloading. This lookup is similar to ordinary name |
| /// lookup, but will ignore any declarations that are class members. |
| LookupOperatorName, |
| /// Look up of a name that precedes the '::' scope resolution |
| /// operator in C++. This lookup completely ignores operator, object, |
| /// function, and enumerator names (C++ [basic.lookup.qual]p1). |
| LookupNestedNameSpecifierName, |
| /// Look up a namespace name within a C++ using directive or |
| /// namespace alias definition, ignoring non-namespace names (C++ |
| /// [basic.lookup.udir]p1). |
| LookupNamespaceName, |
| /// Look up all declarations in a scope with the given name, |
| /// including resolved using declarations. This is appropriate |
| /// for checking redeclarations for a using declaration. |
| LookupUsingDeclName, |
| /// Look up an ordinary name that is going to be redeclared as a |
| /// name with linkage. This lookup ignores any declarations that |
| /// are outside of the current scope unless they have linkage. See |
| /// C99 6.2.2p4-5 and C++ [basic.link]p6. |
| LookupRedeclarationWithLinkage, |
| /// Look up a friend of a local class. This lookup does not look |
| /// outside the innermost non-class scope. See C++11 [class.friend]p11. |
| LookupLocalFriendName, |
| /// Look up the name of an Objective-C protocol. |
| LookupObjCProtocolName, |
| /// Look up implicit 'self' parameter of an objective-c method. |
| LookupObjCImplicitSelfParam, |
| /// \brief Look up any declaration with any name. |
| LookupAnyName |
| }; |
| |
| /// \brief Specifies whether (or how) name lookup is being performed for a |
| /// redeclaration (vs. a reference). |
| enum RedeclarationKind { |
| /// \brief The lookup is a reference to this name that is not for the |
| /// purpose of redeclaring the name. |
| NotForRedeclaration = 0, |
| /// \brief The lookup results will be used for redeclaration of a name, |
| /// if an entity by that name already exists. |
| ForRedeclaration |
| }; |
| |
| /// \brief The possible outcomes of name lookup for a literal operator. |
| enum LiteralOperatorLookupResult { |
| /// \brief The lookup resulted in an error. |
| LOLR_Error, |
| /// \brief The lookup found a single 'cooked' literal operator, which |
| /// expects a normal literal to be built and passed to it. |
| LOLR_Cooked, |
| /// \brief The lookup found a single 'raw' literal operator, which expects |
| /// a string literal containing the spelling of the literal token. |
| LOLR_Raw, |
| /// \brief The lookup found an overload set of literal operator templates, |
| /// which expect the characters of the spelling of the literal token to be |
| /// passed as a non-type template argument pack. |
| LOLR_Template, |
| /// \brief The lookup found an overload set of literal operator templates, |
| /// which expect the character type and characters of the spelling of the |
| /// string literal token to be passed as template arguments. |
| LOLR_StringTemplate |
| }; |
| |
| SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D, |
| CXXSpecialMember SM, |
| bool ConstArg, |
| bool VolatileArg, |
| bool RValueThis, |
| bool ConstThis, |
| bool VolatileThis); |
| |
| typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator; |
| typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)> |
| TypoRecoveryCallback; |
| |
| private: |
| bool CppLookupName(LookupResult &R, Scope *S); |
| |
| struct TypoExprState { |
| std::unique_ptr<TypoCorrectionConsumer> Consumer; |
| TypoDiagnosticGenerator DiagHandler; |
| TypoRecoveryCallback RecoveryHandler; |
| TypoExprState(); |
| TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT; |
| TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT; |
| }; |
| |
| /// \brief The set of unhandled TypoExprs and their associated state. |
| llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos; |
| |
| /// \brief Creates a new TypoExpr AST node. |
| TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, |
| TypoDiagnosticGenerator TDG, |
| TypoRecoveryCallback TRC); |
| |
| // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls. |
| // |
| // The boolean value will be true to indicate that the namespace was loaded |
| // from an AST/PCH file, or false otherwise. |
| llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces; |
| |
| /// \brief Whether we have already loaded known namespaces from an extenal |
| /// source. |
| bool LoadedExternalKnownNamespaces; |
| |
| /// \brief Helper for CorrectTypo and CorrectTypoDelayed used to create and |
| /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction |
| /// should be skipped entirely. |
| std::unique_ptr<TypoCorrectionConsumer> |
| makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, |
| Sema::LookupNameKind LookupKind, Scope *S, |
| CXXScopeSpec *SS, |
| std::unique_ptr<CorrectionCandidateCallback> CCC, |
| DeclContext *MemberContext, bool EnteringContext, |
| const ObjCObjectPointerType *OPT, |
| bool ErrorRecovery); |
| |
| public: |
| const TypoExprState &getTypoExprState(TypoExpr *TE) const; |
| |
| /// \brief Clears the state of the given TypoExpr. |
| void clearDelayedTypo(TypoExpr *TE); |
| |
| /// \brief Look up a name, looking for a single declaration. Return |
| /// null if the results were absent, ambiguous, or overloaded. |
| /// |
| /// It is preferable to use the elaborated form and explicitly handle |
| /// ambiguity and overloaded. |
| NamedDecl *LookupSingleName(Scope *S, DeclarationName Name, |
| SourceLocation Loc, |
| LookupNameKind NameKind, |
| RedeclarationKind Redecl |
| = NotForRedeclaration); |
| bool LookupName(LookupResult &R, Scope *S, |
| bool AllowBuiltinCreation = false); |
| bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, |
| bool InUnqualifiedLookup = false); |
| bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, |
| CXXScopeSpec &SS); |
| bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, |
| bool AllowBuiltinCreation = false, |
| bool EnteringContext = false); |
| ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, |
| RedeclarationKind Redecl |
| = NotForRedeclaration); |
| bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class); |
| |
| void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, |
| QualType T1, QualType T2, |
| UnresolvedSetImpl &Functions); |
| void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions, |
| DeclAccessPair Operator, |
| QualType T1, QualType T2); |
| |
| LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, |
| SourceLocation GnuLabelLoc = SourceLocation()); |
| |
| DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); |
| CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); |
| CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, |
| unsigned Quals); |
| CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, |
| bool RValueThis, unsigned ThisQuals); |
| CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class, |
| unsigned Quals); |
| CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, |
| bool RValueThis, unsigned ThisQuals); |
| CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); |
| |
| bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id); |
| LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, |
| ArrayRef<QualType> ArgTys, |
| bool AllowRaw, |
| bool AllowTemplate, |
| bool AllowStringTemplate); |
| bool isKnownName(StringRef name); |
| |
| void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, |
| ArrayRef<Expr *> Args, ADLResult &Functions); |
| |
| void LookupVisibleDecls(Scope *S, LookupNameKind Kind, |
| VisibleDeclConsumer &Consumer, |
| bool IncludeGlobalScope = true); |
| void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, |
| VisibleDeclConsumer &Consumer, |
| bool IncludeGlobalScope = true); |
| |
| enum CorrectTypoKind { |
| CTK_NonError, // CorrectTypo used in a non error recovery situation. |
| CTK_ErrorRecovery // CorrectTypo used in normal error recovery. |
| }; |
| |
| TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, |
| Sema::LookupNameKind LookupKind, |
| Scope *S, CXXScopeSpec *SS, |
| std::unique_ptr<CorrectionCandidateCallback> CCC, |
| CorrectTypoKind Mode, |
| DeclContext *MemberContext = nullptr, |
| bool EnteringContext = false, |
| const ObjCObjectPointerType *OPT = nullptr, |
| bool RecordFailure = true); |
| |
| TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, |
| Sema::LookupNameKind LookupKind, Scope *S, |
| CXXScopeSpec *SS, |
| std::unique_ptr<CorrectionCandidateCallback> CCC, |
| TypoDiagnosticGenerator TDG, |
| TypoRecoveryCallback TRC, CorrectTypoKind Mode, |
| DeclContext *MemberContext = nullptr, |
| bool EnteringContext = false, |
| const ObjCObjectPointerType *OPT = nullptr); |
| |
| /// \brief Process any TypoExprs in the given Expr and its children, |
| /// generating diagnostics as appropriate and returning a new Expr if there |
| /// were typos that were all successfully corrected and ExprError if one or |
| /// more typos could not be corrected. |
| /// |
| /// \param E The Expr to check for TypoExprs. |
| /// |
| /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its |
| /// initializer. |
| /// |
| /// \param Filter A function applied to a newly rebuilt Expr to determine if |
|
|