2009-12-11 01:56:55 +08:00
|
|
|
//===--- SemaInit.h - Semantic Analysis for Initializers --------*- C++ -*-===//
|
2009-12-10 07:02:17 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file provides supporting data types for initialization of objects.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_SEMA_INIT_H
|
|
|
|
#define LLVM_CLANG_SEMA_INIT_H
|
|
|
|
|
|
|
|
#include "SemaOverload.h"
|
2009-12-22 23:35:07 +08:00
|
|
|
#include "clang/AST/Type.h"
|
2010-02-01 11:16:54 +08:00
|
|
|
#include "clang/AST/UnresolvedSet.h"
|
2009-12-10 07:02:17 +08:00
|
|
|
#include "clang/Parse/Action.h"
|
|
|
|
#include "clang/Basic/SourceLocation.h"
|
|
|
|
#include "llvm/ADT/PointerIntPair.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
#include <cassert>
|
|
|
|
|
2010-01-30 03:14:02 +08:00
|
|
|
namespace llvm {
|
|
|
|
class raw_ostream;
|
|
|
|
}
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
namespace clang {
|
|
|
|
|
|
|
|
class CXXBaseSpecifier;
|
|
|
|
class DeclaratorDecl;
|
|
|
|
class DeclaratorInfo;
|
|
|
|
class FieldDecl;
|
|
|
|
class FunctionDecl;
|
|
|
|
class ParmVarDecl;
|
|
|
|
class Sema;
|
|
|
|
class TypeLoc;
|
|
|
|
class VarDecl;
|
|
|
|
|
|
|
|
/// \brief Describes an entity that is being initialized.
|
|
|
|
class InitializedEntity {
|
|
|
|
public:
|
|
|
|
/// \brief Specifies the kind of entity being initialized.
|
|
|
|
enum EntityKind {
|
|
|
|
/// \brief The entity being initialized is a variable.
|
|
|
|
EK_Variable,
|
|
|
|
/// \brief The entity being initialized is a function parameter.
|
|
|
|
EK_Parameter,
|
|
|
|
/// \brief The entity being initialized is the result of a function call.
|
|
|
|
EK_Result,
|
|
|
|
/// \brief The entity being initialized is an exception object that
|
|
|
|
/// is being thrown.
|
|
|
|
EK_Exception,
|
2010-01-23 13:47:27 +08:00
|
|
|
/// \brief The entity being initialized is a non-static data member
|
|
|
|
/// subobject.
|
|
|
|
EK_Member,
|
|
|
|
/// \brief The entity being initialized is an element of an array.
|
|
|
|
EK_ArrayElement,
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
/// \brief The entity being initialized is an object (or array of
|
|
|
|
/// objects) allocated via new.
|
|
|
|
EK_New,
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief The entity being initialized is a temporary object.
|
|
|
|
EK_Temporary,
|
|
|
|
/// \brief The entity being initialized is a base member subobject.
|
|
|
|
EK_Base,
|
2010-01-23 12:34:47 +08:00
|
|
|
/// \brief The entity being initialized is an element of a vector.
|
2009-12-16 14:35:08 +08:00
|
|
|
/// or vector.
|
2010-01-23 12:34:47 +08:00
|
|
|
EK_VectorElement
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// \brief The kind of entity being initialized.
|
|
|
|
EntityKind Kind;
|
|
|
|
|
2009-12-16 14:35:08 +08:00
|
|
|
/// \brief If non-NULL, the parent entity in which this
|
|
|
|
/// initialization occurs.
|
|
|
|
const InitializedEntity *Parent;
|
|
|
|
|
2009-12-22 23:35:07 +08:00
|
|
|
/// \brief The type of the object or reference being initialized.
|
|
|
|
QualType Type;
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
union {
|
|
|
|
/// \brief When Kind == EK_Variable, EK_Parameter, or EK_Member,
|
|
|
|
/// the VarDecl, ParmVarDecl, or FieldDecl, respectively.
|
|
|
|
DeclaratorDecl *VariableOrMember;
|
|
|
|
|
2010-05-15 08:13:29 +08:00
|
|
|
struct {
|
|
|
|
/// \brief When Kind == EK_Result, EK_Exception, or EK_New, the
|
|
|
|
/// location of the 'return', 'throw', or 'new' keyword,
|
|
|
|
/// respectively. When Kind == EK_Temporary, the location where
|
|
|
|
/// the temporary is being created.
|
|
|
|
unsigned Location;
|
|
|
|
|
|
|
|
/// \brief Whether the
|
|
|
|
bool NRVO;
|
|
|
|
} LocAndNRVO;
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief When Kind == EK_Base, the base specifier that provides the
|
2010-04-22 03:52:01 +08:00
|
|
|
/// base class. The lower bit specifies whether the base is an inherited
|
|
|
|
/// virtual base.
|
|
|
|
uintptr_t Base;
|
2009-12-16 14:35:08 +08:00
|
|
|
|
2010-04-22 03:52:01 +08:00
|
|
|
/// \brief When Kind == EK_ArrayElement or EK_VectorElement, the
|
|
|
|
/// index of the array or vector element being initialized.
|
2009-12-16 14:35:08 +08:00
|
|
|
unsigned Index;
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
InitializedEntity() { }
|
|
|
|
|
|
|
|
/// \brief Create the initialization entity for a variable.
|
|
|
|
InitializedEntity(VarDecl *Var)
|
2009-12-22 23:35:07 +08:00
|
|
|
: Kind(EK_Variable), Parent(0), Type(Var->getType()),
|
|
|
|
VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Var)) { }
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief Create the initialization entity for a parameter.
|
|
|
|
InitializedEntity(ParmVarDecl *Parm)
|
2009-12-23 07:42:49 +08:00
|
|
|
: Kind(EK_Parameter), Parent(0), Type(Parm->getType().getUnqualifiedType()),
|
2009-12-22 23:35:07 +08:00
|
|
|
VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Parm)) { }
|
2009-12-10 07:02:17 +08:00
|
|
|
|
2009-12-23 00:09:06 +08:00
|
|
|
/// \brief Create the initialization entity for the result of a
|
|
|
|
/// function, throwing an object, performing an explicit cast, or
|
|
|
|
/// initializing a parameter for which there is no declaration.
|
2010-05-15 08:13:29 +08:00
|
|
|
InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
|
|
|
|
bool NRVO = false)
|
|
|
|
: Kind(Kind), Parent(0), Type(Type)
|
|
|
|
{
|
|
|
|
LocAndNRVO.Location = Loc.getRawEncoding();
|
|
|
|
LocAndNRVO.NRVO = NRVO;
|
|
|
|
}
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief Create the initialization entity for a member subobject.
|
2009-12-16 14:35:08 +08:00
|
|
|
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
|
2009-12-22 23:35:07 +08:00
|
|
|
: Kind(EK_Member), Parent(Parent), Type(Member->getType()),
|
|
|
|
VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Member)) { }
|
2009-12-10 07:02:17 +08:00
|
|
|
|
2009-12-16 14:35:08 +08:00
|
|
|
/// \brief Create the initialization entity for an array element.
|
|
|
|
InitializedEntity(ASTContext &Context, unsigned Index,
|
|
|
|
const InitializedEntity &Parent);
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
public:
|
|
|
|
/// \brief Create the initialization entity for a variable.
|
|
|
|
static InitializedEntity InitializeVariable(VarDecl *Var) {
|
|
|
|
return InitializedEntity(Var);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create the initialization entity for a parameter.
|
|
|
|
static InitializedEntity InitializeParameter(ParmVarDecl *Parm) {
|
|
|
|
return InitializedEntity(Parm);
|
|
|
|
}
|
|
|
|
|
2009-12-23 00:09:06 +08:00
|
|
|
/// \brief Create the initialization entity for a parameter that is
|
|
|
|
/// only known by its type.
|
|
|
|
static InitializedEntity InitializeParameter(QualType Type) {
|
2010-04-22 07:24:10 +08:00
|
|
|
InitializedEntity Entity;
|
|
|
|
Entity.Kind = EK_Parameter;
|
|
|
|
Entity.Type = Type;
|
|
|
|
Entity.Parent = 0;
|
|
|
|
Entity.VariableOrMember = 0;
|
|
|
|
return Entity;
|
2009-12-23 00:09:06 +08:00
|
|
|
}
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Create the initialization entity for the result of a function.
|
|
|
|
static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
|
2010-05-15 08:13:29 +08:00
|
|
|
QualType Type, bool NRVO) {
|
|
|
|
return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create the initialization entity for an exception object.
|
|
|
|
static InitializedEntity InitializeException(SourceLocation ThrowLoc,
|
2010-05-15 08:13:29 +08:00
|
|
|
QualType Type, bool NRVO) {
|
|
|
|
return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
|
|
|
|
/// \brief Create the initialization entity for an object allocated via new.
|
2009-12-22 23:35:07 +08:00
|
|
|
static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
|
|
|
|
return InitializedEntity(EK_New, NewLoc, Type);
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
}
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief Create the initialization entity for a temporary.
|
2009-12-22 23:35:07 +08:00
|
|
|
static InitializedEntity InitializeTemporary(QualType Type) {
|
|
|
|
return InitializedEntity(EK_Temporary, SourceLocation(), Type);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create the initialization entity for a base class subobject.
|
|
|
|
static InitializedEntity InitializeBase(ASTContext &Context,
|
2010-04-22 03:52:01 +08:00
|
|
|
CXXBaseSpecifier *Base,
|
|
|
|
bool IsInheritedVirtualBase);
|
2009-12-10 07:02:17 +08:00
|
|
|
|
2009-12-16 14:35:08 +08:00
|
|
|
/// \brief Create the initialization entity for a member subobject.
|
|
|
|
static InitializedEntity InitializeMember(FieldDecl *Member,
|
|
|
|
const InitializedEntity *Parent = 0) {
|
|
|
|
return InitializedEntity(Member, Parent);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
|
|
|
|
2009-12-16 14:35:08 +08:00
|
|
|
/// \brief Create the initialization entity for an array element.
|
|
|
|
static InitializedEntity InitializeElement(ASTContext &Context,
|
|
|
|
unsigned Index,
|
|
|
|
const InitializedEntity &Parent) {
|
|
|
|
return InitializedEntity(Context, Index, Parent);
|
|
|
|
}
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Determine the kind of initialization.
|
|
|
|
EntityKind getKind() const { return Kind; }
|
|
|
|
|
2009-12-16 14:35:08 +08:00
|
|
|
/// \brief Retrieve the parent of the entity being initialized, when
|
|
|
|
/// the initialization itself is occuring within the context of a
|
|
|
|
/// larger initialization.
|
|
|
|
const InitializedEntity *getParent() const { return Parent; }
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Retrieve type being initialized.
|
2009-12-22 23:35:07 +08:00
|
|
|
QualType getType() const { return Type; }
|
2009-12-10 07:02:17 +08:00
|
|
|
|
2009-12-16 09:38:02 +08:00
|
|
|
/// \brief Retrieve the name of the entity being initialized.
|
|
|
|
DeclarationName getName() const;
|
2009-12-19 11:01:41 +08:00
|
|
|
|
|
|
|
/// \brief Retrieve the variable, parameter, or field being
|
|
|
|
/// initialized.
|
|
|
|
DeclaratorDecl *getDecl() const;
|
|
|
|
|
2010-05-15 08:13:29 +08:00
|
|
|
/// \brief Determine whether this initialization allows the named return
|
|
|
|
/// value optimization, which also applies to thrown objects.
|
|
|
|
bool allowsNRVO() const;
|
|
|
|
|
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
|
|
|
/// \brief Retrieve the base specifier.
|
|
|
|
CXXBaseSpecifier *getBaseSpecifier() const {
|
|
|
|
assert(getKind() == EK_Base && "Not a base specifier");
|
2010-04-22 03:52:01 +08:00
|
|
|
return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Return whether the base is an inherited virtual base.
|
|
|
|
bool isInheritedVirtualBase() const {
|
|
|
|
assert(getKind() == EK_Base && "Not a base specifier");
|
|
|
|
return Base & 0x1;
|
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
|
|
|
}
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Determine the location of the 'return' keyword when initializing
|
|
|
|
/// the result of a function call.
|
|
|
|
SourceLocation getReturnLoc() const {
|
|
|
|
assert(getKind() == EK_Result && "No 'return' location!");
|
2010-05-15 08:13:29 +08:00
|
|
|
return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine the location of the 'throw' keyword when initializing
|
|
|
|
/// an exception object.
|
|
|
|
SourceLocation getThrowLoc() const {
|
|
|
|
assert(getKind() == EK_Exception && "No 'throw' location!");
|
2010-05-15 08:13:29 +08:00
|
|
|
return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
2009-12-16 14:35:08 +08:00
|
|
|
|
|
|
|
/// \brief If this is already the initializer for an array or vector
|
|
|
|
/// element, sets the element index.
|
|
|
|
void setElementIndex(unsigned Index) {
|
2010-01-23 12:34:47 +08:00
|
|
|
assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement);
|
2009-12-16 14:35:08 +08:00
|
|
|
this->Index = Index;
|
|
|
|
}
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Describes the kind of initialization being performed, along with
|
|
|
|
/// location information for tokens related to the initialization (equal sign,
|
|
|
|
/// parentheses).
|
|
|
|
class InitializationKind {
|
|
|
|
public:
|
|
|
|
/// \brief The kind of initialization being performed.
|
|
|
|
enum InitKind {
|
|
|
|
IK_Direct, ///< Direct initialization
|
|
|
|
IK_Copy, ///< Copy initialization
|
|
|
|
IK_Default, ///< Default initialization
|
|
|
|
IK_Value ///< Value initialization
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// \brief The kind of initialization that we're storing.
|
|
|
|
enum StoredInitKind {
|
|
|
|
SIK_Direct = IK_Direct, ///< Direct initialization
|
|
|
|
SIK_Copy = IK_Copy, ///< Copy initialization
|
|
|
|
SIK_Default = IK_Default, ///< Default initialization
|
|
|
|
SIK_Value = IK_Value, ///< Value initialization
|
2009-12-16 14:35:08 +08:00
|
|
|
SIK_ImplicitValue, ///< Implicit value initialization
|
2009-12-10 07:02:17 +08:00
|
|
|
SIK_DirectCast, ///< Direct initialization due to a cast
|
|
|
|
/// \brief Direct initialization due to a C-style or functional cast.
|
|
|
|
SIK_DirectCStyleOrFunctionalCast
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief The kind of initialization being performed.
|
|
|
|
StoredInitKind Kind;
|
|
|
|
|
|
|
|
/// \brief The source locations involved in the initialization.
|
|
|
|
SourceLocation Locations[3];
|
|
|
|
|
|
|
|
InitializationKind(StoredInitKind Kind, SourceLocation Loc1,
|
|
|
|
SourceLocation Loc2, SourceLocation Loc3)
|
|
|
|
: Kind(Kind)
|
|
|
|
{
|
|
|
|
Locations[0] = Loc1;
|
|
|
|
Locations[1] = Loc2;
|
|
|
|
Locations[2] = Loc3;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// \brief Create a direct initialization.
|
|
|
|
static InitializationKind CreateDirect(SourceLocation InitLoc,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
SourceLocation RParenLoc) {
|
|
|
|
return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create a direct initialization due to a cast.
|
|
|
|
static InitializationKind CreateCast(SourceRange TypeRange,
|
|
|
|
bool IsCStyleCast) {
|
|
|
|
return InitializationKind(IsCStyleCast? SIK_DirectCStyleOrFunctionalCast
|
|
|
|
: SIK_DirectCast,
|
|
|
|
TypeRange.getBegin(), TypeRange.getBegin(),
|
|
|
|
TypeRange.getEnd());
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create a copy initialization.
|
|
|
|
static InitializationKind CreateCopy(SourceLocation InitLoc,
|
|
|
|
SourceLocation EqualLoc) {
|
|
|
|
return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create a default initialization.
|
|
|
|
static InitializationKind CreateDefault(SourceLocation InitLoc) {
|
|
|
|
return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Create a value initialization.
|
|
|
|
static InitializationKind CreateValue(SourceLocation InitLoc,
|
|
|
|
SourceLocation LParenLoc,
|
2009-12-16 14:35:08 +08:00
|
|
|
SourceLocation RParenLoc,
|
|
|
|
bool isImplicit = false) {
|
|
|
|
return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value,
|
|
|
|
InitLoc, LParenLoc, RParenLoc);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine the initialization kind.
|
|
|
|
InitKind getKind() const {
|
2009-12-16 14:35:08 +08:00
|
|
|
if (Kind > SIK_ImplicitValue)
|
2009-12-10 07:02:17 +08:00
|
|
|
return IK_Direct;
|
2009-12-16 14:35:08 +08:00
|
|
|
if (Kind == SIK_ImplicitValue)
|
|
|
|
return IK_Value;
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
return (InitKind)Kind;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine whether this initialization is an explicit cast.
|
|
|
|
bool isExplicitCast() const {
|
|
|
|
return Kind == SIK_DirectCast || Kind == SIK_DirectCStyleOrFunctionalCast;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine whether this initialization is a C-style cast.
|
|
|
|
bool isCStyleOrFunctionalCast() const {
|
|
|
|
return Kind == SIK_DirectCStyleOrFunctionalCast;
|
|
|
|
}
|
2009-12-16 14:35:08 +08:00
|
|
|
|
|
|
|
/// \brief Determine whether this initialization is an implicit
|
|
|
|
/// value-initialization, e.g., as occurs during aggregate
|
|
|
|
/// initialization.
|
|
|
|
bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Retrieve the location at which initialization is occurring.
|
|
|
|
SourceLocation getLocation() const { return Locations[0]; }
|
|
|
|
|
|
|
|
/// \brief Retrieve the source range that covers the initialization.
|
|
|
|
SourceRange getRange() const {
|
2009-12-15 08:01:57 +08:00
|
|
|
return SourceRange(Locations[0], Locations[2]);
|
2009-12-10 07:02:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the equal sign for copy initialization
|
|
|
|
/// (if present).
|
|
|
|
SourceLocation getEqualLoc() const {
|
|
|
|
assert(Kind == SIK_Copy && "Only copy initialization has an '='");
|
|
|
|
return Locations[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Retrieve the source range containing the locations of the open
|
|
|
|
/// and closing parentheses for value and direct initializations.
|
|
|
|
SourceRange getParenRange() const {
|
|
|
|
assert((getKind() == IK_Direct || Kind == SIK_Value) &&
|
|
|
|
"Only direct- and value-initialization have parentheses");
|
|
|
|
return SourceRange(Locations[1], Locations[2]);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Describes the sequence of initializations required to initialize
|
|
|
|
/// a given object or reference with a set of arguments.
|
|
|
|
class InitializationSequence {
|
|
|
|
public:
|
|
|
|
/// \brief Describes the kind of initialization sequence computed.
|
2009-12-15 08:01:57 +08:00
|
|
|
///
|
|
|
|
/// FIXME: Much of this information is in the initialization steps... why is
|
|
|
|
/// it duplicated here?
|
2009-12-10 07:02:17 +08:00
|
|
|
enum SequenceKind {
|
|
|
|
/// \brief A failed initialization sequence. The failure kind tells what
|
|
|
|
/// happened.
|
|
|
|
FailedSequence = 0,
|
|
|
|
|
|
|
|
/// \brief A dependent initialization, which could not be
|
|
|
|
/// type-checked due to the presence of dependent types or
|
|
|
|
/// dependently-type expressions.
|
|
|
|
DependentSequence,
|
|
|
|
|
2009-12-15 01:27:33 +08:00
|
|
|
/// \brief A user-defined conversion sequence.
|
|
|
|
UserDefinedConversion,
|
|
|
|
|
2009-12-15 04:49:26 +08:00
|
|
|
/// \brief A constructor call.
|
2009-12-15 04:57:13 +08:00
|
|
|
ConstructorInitialization,
|
2009-12-15 04:49:26 +08:00
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief A reference binding.
|
2009-12-11 01:56:55 +08:00
|
|
|
ReferenceBinding,
|
|
|
|
|
|
|
|
/// \brief List initialization
|
2009-12-15 08:01:57 +08:00
|
|
|
ListInitialization,
|
|
|
|
|
|
|
|
/// \brief Zero-initialization.
|
2009-12-16 09:38:02 +08:00
|
|
|
ZeroInitialization,
|
|
|
|
|
|
|
|
/// \brief No initialization required.
|
|
|
|
NoInitialization,
|
|
|
|
|
|
|
|
/// \brief Standard conversion sequence.
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
StandardConversion,
|
|
|
|
|
|
|
|
/// \brief C conversion sequence.
|
2009-12-19 16:11:05 +08:00
|
|
|
CAssignment,
|
|
|
|
|
|
|
|
/// \brief String initialization
|
|
|
|
StringInit
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Describes the kind of a particular step in an initialization
|
|
|
|
/// sequence.
|
|
|
|
enum StepKind {
|
|
|
|
/// \brief Resolve the address of an overloaded function to a specific
|
|
|
|
/// function declaration.
|
|
|
|
SK_ResolveAddressOfOverloadedFunction,
|
|
|
|
/// \brief Perform a derived-to-base cast, producing an rvalue.
|
|
|
|
SK_CastDerivedToBaseRValue,
|
|
|
|
/// \brief Perform a derived-to-base cast, producing an lvalue.
|
|
|
|
SK_CastDerivedToBaseLValue,
|
|
|
|
/// \brief Reference binding to an lvalue.
|
|
|
|
SK_BindReference,
|
|
|
|
/// \brief Reference binding to a temporary.
|
|
|
|
SK_BindReferenceToTemporary,
|
2010-04-18 15:40:54 +08:00
|
|
|
/// \brief An optional copy of a temporary object to another
|
|
|
|
/// temporary object, which is permitted (but not required) by
|
|
|
|
/// C++98/03 but not C++0x.
|
|
|
|
SK_ExtraneousCopyToTemporary,
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Perform a user-defined conversion, either via a conversion
|
|
|
|
/// function or via a constructor.
|
|
|
|
SK_UserConversion,
|
|
|
|
/// \brief Perform a qualification conversion, producing an rvalue.
|
|
|
|
SK_QualificationConversionRValue,
|
|
|
|
/// \brief Perform a qualification conversion, producing an lvalue.
|
|
|
|
SK_QualificationConversionLValue,
|
|
|
|
/// \brief Perform an implicit conversion sequence.
|
2009-12-11 01:56:55 +08:00
|
|
|
SK_ConversionSequence,
|
|
|
|
/// \brief Perform list-initialization
|
2009-12-15 04:49:26 +08:00
|
|
|
SK_ListInitialization,
|
|
|
|
/// \brief Perform initialization via a constructor.
|
2009-12-15 08:01:57 +08:00
|
|
|
SK_ConstructorInitialization,
|
|
|
|
/// \brief Zero-initialize the object
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
SK_ZeroInitialization,
|
|
|
|
/// \brief C assignment
|
2009-12-19 16:11:05 +08:00
|
|
|
SK_CAssignment,
|
|
|
|
/// \brief Initialization by string
|
|
|
|
SK_StringInit
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief A single step in the initialization sequence.
|
|
|
|
class Step {
|
|
|
|
public:
|
|
|
|
/// \brief The kind of conversion or initialization step we are taking.
|
|
|
|
StepKind Kind;
|
|
|
|
|
|
|
|
// \brief The type that results from this initialization.
|
|
|
|
QualType Type;
|
|
|
|
|
|
|
|
union {
|
|
|
|
/// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
|
|
|
|
/// SK_UserConversion, the function that the expression should be
|
|
|
|
/// resolved to or the conversion function to call, respectively.
|
2010-02-01 11:16:54 +08:00
|
|
|
///
|
|
|
|
/// Always a FunctionDecl.
|
|
|
|
/// For conversion decls, the naming class is the source type.
|
|
|
|
/// For construct decls, the naming class is the target type.
|
2010-03-19 15:35:19 +08:00
|
|
|
struct {
|
|
|
|
FunctionDecl *Function;
|
|
|
|
DeclAccessPair FoundDecl;
|
|
|
|
} Function;
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief When Kind = SK_ConversionSequence, the implicit conversion
|
|
|
|
/// sequence
|
|
|
|
ImplicitConversionSequence *ICS;
|
|
|
|
};
|
|
|
|
|
|
|
|
void Destroy();
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// \brief The kind of initialization sequence computed.
|
|
|
|
enum SequenceKind SequenceKind;
|
|
|
|
|
|
|
|
/// \brief Steps taken by this initialization.
|
|
|
|
llvm::SmallVector<Step, 4> Steps;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// \brief Describes why initialization failed.
|
|
|
|
enum FailureKind {
|
|
|
|
/// \brief Too many initializers provided for a reference.
|
|
|
|
FK_TooManyInitsForReference,
|
|
|
|
/// \brief Array must be initialized with an initializer list.
|
|
|
|
FK_ArrayNeedsInitList,
|
|
|
|
/// \brief Array must be initialized with an initializer list or a
|
|
|
|
/// string literal.
|
|
|
|
FK_ArrayNeedsInitListOrStringLiteral,
|
|
|
|
/// \brief Cannot resolve the address of an overloaded function.
|
|
|
|
FK_AddressOfOverloadFailed,
|
|
|
|
/// \brief Overloading due to reference initialization failed.
|
|
|
|
FK_ReferenceInitOverloadFailed,
|
|
|
|
/// \brief Non-const lvalue reference binding to a temporary.
|
|
|
|
FK_NonConstLValueReferenceBindingToTemporary,
|
|
|
|
/// \brief Non-const lvalue reference binding to an lvalue of unrelated
|
|
|
|
/// type.
|
|
|
|
FK_NonConstLValueReferenceBindingToUnrelated,
|
|
|
|
/// \brief Rvalue reference binding to an lvalue.
|
|
|
|
FK_RValueReferenceBindingToLValue,
|
|
|
|
/// \brief Reference binding drops qualifiers.
|
|
|
|
FK_ReferenceInitDropsQualifiers,
|
|
|
|
/// \brief Reference binding failed.
|
|
|
|
FK_ReferenceInitFailed,
|
|
|
|
/// \brief Implicit conversion failed.
|
2009-12-11 01:56:55 +08:00
|
|
|
FK_ConversionFailed,
|
|
|
|
/// \brief Too many initializers for scalar
|
|
|
|
FK_TooManyInitsForScalar,
|
|
|
|
/// \brief Reference initialization from an initializer list
|
|
|
|
FK_ReferenceBindingToInitList,
|
|
|
|
/// \brief Initialization of some unused destination type with an
|
|
|
|
/// initializer list.
|
2009-12-15 01:27:33 +08:00
|
|
|
FK_InitListBadDestinationType,
|
|
|
|
/// \brief Overloading for a user-defined conversion failed.
|
2009-12-15 04:49:26 +08:00
|
|
|
FK_UserConversionOverloadFailed,
|
|
|
|
/// \brief Overloaded for initialization by constructor failed.
|
2009-12-16 09:38:02 +08:00
|
|
|
FK_ConstructorOverloadFailed,
|
|
|
|
/// \brief Default-initialization of a 'const' object.
|
2010-05-21 06:12:02 +08:00
|
|
|
FK_DefaultInitOfConst,
|
|
|
|
/// \brief Initialization of an incomplete type.
|
|
|
|
FK_Incomplete
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// \brief The reason why initialization failued.
|
|
|
|
FailureKind Failure;
|
|
|
|
|
|
|
|
/// \brief The failed result of overload resolution.
|
|
|
|
OverloadingResult FailedOverloadResult;
|
|
|
|
|
|
|
|
/// \brief The candidate set created when initialization failed.
|
|
|
|
OverloadCandidateSet FailedCandidateSet;
|
2010-04-22 08:20:18 +08:00
|
|
|
|
|
|
|
/// \brief Prints a follow-up note that highlights the location of
|
|
|
|
/// the initialized entity, if it's remote.
|
|
|
|
void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
public:
|
|
|
|
/// \brief Try to perform initialization of the given entity, creating a
|
|
|
|
/// record of the steps required to perform the initialization.
|
|
|
|
///
|
|
|
|
/// The generated initialization sequence will either contain enough
|
|
|
|
/// information to diagnose
|
|
|
|
///
|
|
|
|
/// \param S the semantic analysis object.
|
|
|
|
///
|
|
|
|
/// \param Entity the entity being initialized.
|
|
|
|
///
|
|
|
|
/// \param Kind the kind of initialization being performed.
|
|
|
|
///
|
|
|
|
/// \param Args the argument(s) provided for initialization.
|
|
|
|
///
|
|
|
|
/// \param NumArgs the number of arguments provided for initialization.
|
|
|
|
InitializationSequence(Sema &S,
|
|
|
|
const InitializedEntity &Entity,
|
|
|
|
const InitializationKind &Kind,
|
|
|
|
Expr **Args,
|
|
|
|
unsigned NumArgs);
|
|
|
|
|
|
|
|
~InitializationSequence();
|
|
|
|
|
|
|
|
/// \brief Perform the actual initialization of the given entity based on
|
|
|
|
/// the computed initialization sequence.
|
|
|
|
///
|
|
|
|
/// \param S the semantic analysis object.
|
|
|
|
///
|
|
|
|
/// \param Entity the entity being initialized.
|
|
|
|
///
|
|
|
|
/// \param Kind the kind of initialization being performed.
|
|
|
|
///
|
|
|
|
/// \param Args the argument(s) provided for initialization, ownership of
|
|
|
|
/// which is transfered into the routine.
|
|
|
|
///
|
2009-12-11 01:56:55 +08:00
|
|
|
/// \param ResultType if non-NULL, will be set to the type of the
|
|
|
|
/// initialized object, which is the type of the declaration in most
|
|
|
|
/// cases. However, when the initialized object is a variable of
|
|
|
|
/// incomplete array type and the initializer is an initializer
|
|
|
|
/// list, this type will be set to the completed array type.
|
|
|
|
///
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \returns an expression that performs the actual object initialization, if
|
|
|
|
/// the initialization is well-formed. Otherwise, emits diagnostics
|
|
|
|
/// and returns an invalid expression.
|
|
|
|
Action::OwningExprResult Perform(Sema &S,
|
|
|
|
const InitializedEntity &Entity,
|
|
|
|
const InitializationKind &Kind,
|
2009-12-11 01:56:55 +08:00
|
|
|
Action::MultiExprArg Args,
|
|
|
|
QualType *ResultType = 0);
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief Diagnose an potentially-invalid initialization sequence.
|
|
|
|
///
|
|
|
|
/// \returns true if the initialization sequence was ill-formed,
|
|
|
|
/// false otherwise.
|
|
|
|
bool Diagnose(Sema &S,
|
|
|
|
const InitializedEntity &Entity,
|
|
|
|
const InitializationKind &Kind,
|
|
|
|
Expr **Args, unsigned NumArgs);
|
|
|
|
|
|
|
|
/// \brief Determine the kind of initialization sequence computed.
|
|
|
|
enum SequenceKind getKind() const { return SequenceKind; }
|
|
|
|
|
|
|
|
/// \brief Set the kind of sequence computed.
|
|
|
|
void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
|
|
|
|
|
|
|
|
/// \brief Determine whether the initialization sequence is valid.
|
|
|
|
operator bool() const { return SequenceKind != FailedSequence; }
|
|
|
|
|
|
|
|
typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator;
|
|
|
|
step_iterator step_begin() const { return Steps.begin(); }
|
|
|
|
step_iterator step_end() const { return Steps.end(); }
|
|
|
|
|
2010-03-27 04:14:36 +08:00
|
|
|
/// \brief Determine whether this initialization is a direct reference
|
|
|
|
/// binding (C++ [dcl.init.ref]).
|
|
|
|
bool isDirectReferenceBinding() const;
|
|
|
|
|
|
|
|
/// \brief Determine whether this initialization failed due to an ambiguity.
|
|
|
|
bool isAmbiguous() const;
|
|
|
|
|
2010-04-17 06:09:46 +08:00
|
|
|
/// \brief Determine whether this initialization is direct call to a
|
|
|
|
/// constructor.
|
|
|
|
bool isConstructorInitialization() const;
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Add a new step in the initialization that resolves the address
|
|
|
|
/// of an overloaded function to a specific function declaration.
|
|
|
|
///
|
|
|
|
/// \param Function the function to which the overloaded function reference
|
|
|
|
/// resolves.
|
2010-03-31 05:47:33 +08:00
|
|
|
void AddAddressOverloadResolutionStep(FunctionDecl *Function,
|
|
|
|
DeclAccessPair Found);
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief Add a new step in the initialization that performs a derived-to-
|
|
|
|
/// base cast.
|
|
|
|
///
|
|
|
|
/// \param BaseType the base type to which we will be casting.
|
|
|
|
///
|
|
|
|
/// \param IsLValue true if the result of this cast will be treated as
|
|
|
|
/// an lvalue.
|
|
|
|
void AddDerivedToBaseCastStep(QualType BaseType, bool IsLValue);
|
|
|
|
|
|
|
|
/// \brief Add a new step binding a reference to an object.
|
|
|
|
///
|
2010-04-18 15:40:54 +08:00
|
|
|
/// \param BindingTemporary True if we are binding a reference to a temporary
|
2009-12-10 07:02:17 +08:00
|
|
|
/// object (thereby extending its lifetime); false if we are binding to an
|
|
|
|
/// lvalue or an lvalue treated as an rvalue.
|
2010-04-18 15:40:54 +08:00
|
|
|
///
|
|
|
|
/// \param UnnecessaryCopy True if we should check for a copy
|
|
|
|
/// constructor for a completely unnecessary but
|
2009-12-10 07:02:17 +08:00
|
|
|
void AddReferenceBindingStep(QualType T, bool BindingTemporary);
|
2010-04-18 15:40:54 +08:00
|
|
|
|
|
|
|
/// \brief Add a new step that makes an extraneous copy of the input
|
|
|
|
/// to a temporary of the same class type.
|
|
|
|
///
|
|
|
|
/// This extraneous copy only occurs during reference binding in
|
|
|
|
/// C++98/03, where we are permitted (but not required) to introduce
|
|
|
|
/// an extra copy. At a bare minimum, we must check that we could
|
|
|
|
/// call the copy constructor, and produce a diagnostic if the copy
|
|
|
|
/// constructor is inaccessible or no copy constructor matches.
|
|
|
|
//
|
|
|
|
/// \param T The type of the temporary being created.
|
|
|
|
void AddExtraneousCopyToTemporary(QualType T);
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Add a new step invoking a conversion function, which is either
|
|
|
|
/// a constructor or a conversion function.
|
2010-02-01 11:16:54 +08:00
|
|
|
void AddUserConversionStep(FunctionDecl *Function,
|
2010-03-19 15:35:19 +08:00
|
|
|
DeclAccessPair FoundDecl,
|
2010-02-01 11:16:54 +08:00
|
|
|
QualType T);
|
2009-12-10 07:02:17 +08:00
|
|
|
|
|
|
|
/// \brief Add a new step that performs a qualification conversion to the
|
|
|
|
/// given type.
|
|
|
|
void AddQualificationConversionStep(QualType Ty, bool IsLValue);
|
|
|
|
|
|
|
|
/// \brief Add a new step that applies an implicit conversion sequence.
|
|
|
|
void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
|
|
|
|
QualType T);
|
2009-12-11 01:56:55 +08:00
|
|
|
|
|
|
|
/// \brief Add a list-initialiation step
|
|
|
|
void AddListInitializationStep(QualType T);
|
|
|
|
|
2009-12-15 08:01:57 +08:00
|
|
|
/// \brief Add a constructor-initialization step.
|
2009-12-15 04:49:26 +08:00
|
|
|
void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
|
2010-02-01 11:16:54 +08:00
|
|
|
AccessSpecifier Access,
|
2009-12-15 04:49:26 +08:00
|
|
|
QualType T);
|
2009-12-15 08:01:57 +08:00
|
|
|
|
|
|
|
/// \brief Add a zero-initialization step.
|
|
|
|
void AddZeroInitializationStep(QualType T);
|
2009-12-15 04:49:26 +08:00
|
|
|
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
/// \brief Add a C assignment step.
|
|
|
|
//
|
|
|
|
// FIXME: It isn't clear whether this should ever be needed;
|
|
|
|
// ideally, we would handle everything needed in C in the common
|
|
|
|
// path. However, that isn't the case yet.
|
|
|
|
void AddCAssignmentStep(QualType T);
|
|
|
|
|
2009-12-19 16:11:05 +08:00
|
|
|
/// \brief Add a string init step.
|
|
|
|
void AddStringInitStep(QualType T);
|
|
|
|
|
2009-12-10 07:02:17 +08:00
|
|
|
/// \brief Note that this initialization sequence failed.
|
|
|
|
void SetFailed(FailureKind Failure) {
|
|
|
|
SequenceKind = FailedSequence;
|
|
|
|
this->Failure = Failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Note that this initialization sequence failed due to failed
|
|
|
|
/// overload resolution.
|
|
|
|
void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
|
|
|
|
|
|
|
|
/// \brief Retrieve a reference to the candidate set when overload
|
|
|
|
/// resolution fails.
|
|
|
|
OverloadCandidateSet &getFailedCandidateSet() {
|
|
|
|
return FailedCandidateSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine why initialization failed.
|
|
|
|
FailureKind getFailureKind() const {
|
|
|
|
assert(getKind() == FailedSequence && "Not an initialization failure!");
|
|
|
|
return Failure;
|
|
|
|
}
|
2010-01-30 03:14:02 +08:00
|
|
|
|
|
|
|
/// \brief Dump a representation of this initialization sequence to
|
|
|
|
/// the given stream, for debugging purposes.
|
|
|
|
void dump(llvm::raw_ostream &OS) const;
|
|
|
|
|
|
|
|
/// \brief Dump a representation of this initialization sequence to
|
|
|
|
/// standard error, for debugging purposes.
|
|
|
|
void dump() const;
|
2009-12-10 07:02:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace clang
|
|
|
|
|
|
|
|
#endif // LLVM_CLANG_SEMA_INIT_H
|