diff options
Diffstat (limited to 'include/clang/Sema/Initialization.h')
-rw-r--r-- | include/clang/Sema/Initialization.h | 117 |
1 files changed, 88 insertions, 29 deletions
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 58781ac..83fb2be 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -35,6 +35,7 @@ class ParmVarDecl; class Sema; class TypeLoc; class VarDecl; +class ObjCMethodDecl; /// \brief Describes an entity that is being initialized. class InitializedEntity { @@ -78,7 +79,17 @@ public: EK_LambdaCapture, /// \brief The entity being initialized is the initializer for a compound /// literal. - EK_CompoundLiteralInit + EK_CompoundLiteralInit, + /// \brief The entity being implicitly initialized back to the formal + /// result type. + EK_RelatedResult, + /// \brief The entity being initialized is a function parameter; function + /// is member of group of audited CF APIs. + EK_Parameter_CF_Audited + + // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this + // enum as an index for its first %select. When modifying this list, + // that diagnostic text needs to be updated as well. }; private: @@ -105,8 +116,8 @@ private: }; struct C { - /// \brief The variable being captured by an EK_LambdaCapture. - VarDecl *Var; + /// \brief The name of the variable being captured by an EK_LambdaCapture. + IdentifierInfo *VarID; /// \brief The source location at which the capture occurs. unsigned Location; @@ -116,6 +127,10 @@ private: /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or /// FieldDecl, respectively. DeclaratorDecl *VariableOrMember; + + /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where + /// result type was implicitly changed to accommodate ARC semantics. + ObjCMethodDecl *MethodDecl; /// \brief When Kind == EK_Parameter, the ParmVarDecl, with the /// low bit indicating whether the parameter is "consumed". @@ -168,10 +183,10 @@ private: const InitializedEntity &Parent); /// \brief Create the initialization entity for a lambda capture. - InitializedEntity(VarDecl *Var, FieldDecl *Field, SourceLocation Loc) - : Kind(EK_LambdaCapture), Parent(0), Type(Field->getType()) + InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) + : Kind(EK_LambdaCapture), Parent(0), Type(FieldType) { - Capture.Var = Var; + Capture.VarID = VarID; Capture.Location = Loc.getRawEncoding(); } @@ -254,10 +269,19 @@ public: Result.TypeInfo = TypeInfo; return Result; } + + /// \brief Create the initialization entity for a related result. + static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, + QualType Type) { + InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type); + Result.MethodDecl = MD; + return Result; + } + /// \brief Create the initialization entity for a base class subobject. static InitializedEntity InitializeBase(ASTContext &Context, - CXXBaseSpecifier *Base, + const CXXBaseSpecifier *Base, bool IsInheritedVirtualBase); /// \brief Create the initialization entity for a delegated constructor. @@ -285,10 +309,10 @@ public: } /// \brief Create the initialization entity for a lambda capture. - static InitializedEntity InitializeLambdaCapture(VarDecl *Var, - FieldDecl *Field, + static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID, + QualType FieldType, SourceLocation Loc) { - return InitializedEntity(Var, Field, Loc); + return InitializedEntity(VarID, FieldType, Loc); } /// \brief Create the entity for a compound literal initializer. @@ -326,22 +350,29 @@ public: /// \brief Retrieve the variable, parameter, or field being /// initialized. DeclaratorDecl *getDecl() const; + + /// \brief Retrieve the ObjectiveC method being initialized. + ObjCMethodDecl *getMethodDecl() const { return MethodDecl; } /// \brief Determine whether this initialization allows the named return /// value optimization, which also applies to thrown objects. bool allowsNRVO() const; + bool isParameterKind() const { + return (getKind() == EK_Parameter || + getKind() == EK_Parameter_CF_Audited); + } /// \brief Determine whether this initialization consumes the /// parameter. bool isParameterConsumed() const { - assert(getKind() == EK_Parameter && "Not a parameter"); + assert(isParameterKind() && "Not a parameter"); return (Parameter & 1); } /// \brief Retrieve the base specifier. - CXXBaseSpecifier *getBaseSpecifier() const { + const CXXBaseSpecifier *getBaseSpecifier() const { assert(getKind() == EK_Base && "Not a base specifier"); - return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1); + return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1); } /// \brief Return whether the base is an inherited virtual base. @@ -371,19 +402,28 @@ public: getKind() == EK_ComplexElement); this->Index = Index; } - - /// \brief Retrieve the variable for a captured variable in a lambda. - VarDecl *getCapturedVar() const { + /// \brief For a lambda capture, return the capture's name. + StringRef getCapturedVarName() const { assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); - return Capture.Var; + return Capture.VarID->getName(); } - /// \brief Determine the location of the capture when initializing /// field from a captured variable in a lambda. SourceLocation getCaptureLoc() const { assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); return SourceLocation::getFromRawEncoding(Capture.Location); } + + void setParameterCFAudited() { + Kind = EK_Parameter_CF_Audited; + } + + /// Dump a representation of the initialized entity to standard error, + /// for debugging purposes. + void dump() const; + +private: + unsigned dumpImpl(raw_ostream &OS) const; }; /// \brief Describes the kind of initialization being performed, along with @@ -544,8 +584,10 @@ public: bool AllowExplicit() const { return !isCopyInit(); } /// \brief Retrieve whether this initialization allows the use of explicit - /// conversion functions. - bool allowExplicitConversionFunctions() const { + /// conversion functions when binding a reference. If the reference is the + /// first parameter in a copy or move constructor, such conversions are + /// permitted even though we are performing copy-initialization. + bool allowExplicitConversionFunctionsInRefBinding() const { return !isCopyInit() || Context == IC_ExplicitConvs; } @@ -610,6 +652,8 @@ public: SK_LValueToRValue, /// \brief Perform an implicit conversion sequence. SK_ConversionSequence, + /// \brief Perform an implicit conversion sequence without narrowing. + SK_ConversionSequenceNoNarrowing, /// \brief Perform list-initialization without a constructor SK_ListInitialization, /// \brief Perform list-initialization with a constructor. @@ -706,6 +750,16 @@ public: /// \brief Array must be initialized with an initializer list or a /// string literal. FK_ArrayNeedsInitListOrStringLiteral, + /// \brief Array must be initialized with an initializer list or a + /// wide string literal. + FK_ArrayNeedsInitListOrWideStringLiteral, + /// \brief Initializing a wide char array with narrow string literal. + FK_NarrowStringIntoWideCharArray, + /// \brief Initializing char array with wide string literal. + FK_WideStringIntoCharArray, + /// \brief Initializing wide char array with incompatible wide string + /// literal. + FK_IncompatWideStringIntoWideChar, /// \brief Array type mismatch. FK_ArrayTypeMismatch, /// \brief Non-constant array initializer @@ -753,9 +807,6 @@ public: /// \brief Initializer has a placeholder type which cannot be /// resolved by initialization. FK_PlaceholderType, - /// \brief Failed to initialize a std::initializer_list because copy - /// construction of some element failed. - FK_InitListElementCopyFailure, /// \brief List-copy-initialization chose an explicit constructor. FK_ExplicitConstructor }; @@ -791,11 +842,19 @@ public: /// \param Kind the kind of initialization being performed. /// /// \param Args the argument(s) provided for initialization. + /// + /// \param InInitList true if we are initializing from an expression within + /// an initializer list. This disallows narrowing conversions in C++11 + /// onwards. InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, - MultiExprArg Args); - + MultiExprArg Args, + bool InInitList = false); + void InitializeFrom(Sema &S, const InitializedEntity &Entity, + const InitializationKind &Kind, MultiExprArg Args, + bool InInitList); + ~InitializationSequence(); /// \brief Perform the actual initialization of the given entity based on @@ -841,12 +900,12 @@ public: void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } /// \brief Determine whether the initialization sequence is valid. - operator bool() const { return !Failed(); } + LLVM_EXPLICIT operator bool() const { return !Failed(); } /// \brief Determine whether the initialization sequence is invalid. bool Failed() const { return SequenceKind == FailedSequence; } - - typedef SmallVector<Step, 4>::const_iterator step_iterator; + + typedef SmallVectorImpl<Step>::const_iterator step_iterator; step_iterator step_begin() const { return Steps.begin(); } step_iterator step_end() const { return Steps.end(); } @@ -930,7 +989,7 @@ public: /// \brief Add a new step that applies an implicit conversion sequence. void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, - QualType T); + QualType T, bool TopLevelOfInitList = false); /// \brief Add a list-initialization step. void AddListInitializationStep(QualType T); |