for ( ; I != E; ++I) {
switch (*I) {
default: hasMore = false; break;
- case '\'':
+ case '\'':
// FIXME: POSIX specific. Always accept?
FS.setHasThousandsGrouping(I);
break;
ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
const PrintfConversionSpecifier &CS = getConversionSpecifier();
-
+
if (!CS.consumesDataArgument())
return ArgTypeResult::Invalid();
default:
return ArgTypeResult::Invalid();
}
-
+
if (CS.isIntArg())
switch (LM.getKind()) {
case LengthModifier::AsLongDouble:
bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
if (!HasThousandsGrouping)
return true;
-
+
switch (CS.getKind()) {
case ConversionSpecifier::dArg:
case ConversionSpecifier::iArg:
using namespace sema;
ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
- IdentifierInfo &II,
+ IdentifierInfo &II,
SourceLocation NameLoc,
Scope *S, CXXScopeSpec &SS,
ParsedType ObjectTypePtr,
if (SS.isSet()) {
NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
-
+
bool AlreadySearched = false;
bool LookAtPrefix = true;
// C++ [basic.lookup.qual]p6:
- // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier,
+ // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier,
// the type-names are looked up as types in the scope designated by the
// nested-name-specifier. In a qualified-id of the form:
//
//
// ::opt nested-name-specifier class-name :: ~ class-name
//
- // the class-names are looked up as types in the scope designated by
+ // the class-names are looked up as types in the scope designated by
// the nested-name-specifier.
//
// Here, we check the first case (completely) and determine whether the
- // code below is permitted to look at the prefix of the
+ // code below is permitted to look at the prefix of the
// nested-name-specifier.
DeclContext *DC = computeDeclContext(SS, EnteringContext);
if (DC && DC->isFileContext()) {
isDependent = false;
} else if (DC && isa<CXXRecordDecl>(DC))
LookAtPrefix = false;
-
+
// The second case from the C++03 rules quoted further above.
NestedNameSpecifier *Prefix = 0;
if (AlreadySearched) {
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = LookupCtx && LookupCtx->isDependentContext();
}
-
+
LookInScope = false;
} else if (ObjectTypePtr) {
// C++ [basic.lookup.classref]p3:
// cv-qualified) T.
LookupCtx = computeDeclContext(SearchType);
isDependent = SearchType->isDependentType();
- assert((isDependent || !SearchType->isIncompleteType()) &&
+ assert((isDependent || !SearchType->isIncompleteType()) &&
"Caller should have completed object type");
LookInScope = true;
// nested-name-specifier (if present) or the object type, then
// this is the destructor for that class.
// FIXME: This is a workaround until we get real drafting for core
- // issue 399, for which there isn't even an obvious direction.
+ // issue 399, for which there isn't even an obvious direction.
if (ClassTemplateDecl *Template = Found.getAsSingle<ClassTemplateDecl>()) {
QualType MemberOfType;
if (SS.isSet()) {
}
if (MemberOfType.isNull())
MemberOfType = SearchType;
-
+
if (MemberOfType.isNull())
continue;
continue;
}
-
+
// We're referring to an unresolved class template
// specialization. Determine whether we class template we found
// is the same as the template being specialized or, if we don't
// The class template we found has the same name as the
// (dependent) template name being specialized.
- if (DependentTemplateName *DepTemplate
+ if (DependentTemplateName *DepTemplate
= SpecName.getAsDependentTemplateName()) {
if (DepTemplate->isIdentifier() &&
DepTemplate->getIdentifier() == Template->getIdentifier())
if (ObjectTypePtr)
Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
- << &II;
+ << &II;
else
Diag(NameLoc, diag::err_destructor_class_name);
TypeSourceInfo *Operand,
SourceLocation RParenLoc) {
// C++ [expr.typeid]p4:
- // The top-level cv-qualifiers of the lvalue expression or the type-id
+ // The top-level cv-qualifiers of the lvalue expression or the type-id
// that is the operand of typeid are always ignored.
- // If the type of the type-id is a class type or a reference to a class
+ // If the type of the type-id is a class type or a reference to a class
// type, the class shall be completely-defined.
Qualifiers Quals;
QualType T
if (T->getAs<RecordType>() &&
RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
return ExprError();
-
+
return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
Operand,
SourceRange(TypeidLoc, RParenLoc)));
// shall be completely-defined.
if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
return ExprError();
-
+
// C++ [expr.typeid]p3:
// When typeid is applied to an expression other than an glvalue of a
// polymorphic class type [...] [the] expression is an unevaluated
MarkVTableUsed(TypeidLoc, RecordD);
}
}
-
+
// C++ [expr.typeid]p4:
// [...] If the type of the type-id is a reference to a possibly
- // cv-qualified type, the result of the typeid expression refers to a
- // std::type_info object representing the cv-unqualified referenced
+ // cv-qualified type, the result of the typeid expression refers to a
+ // std::type_info object representing the cv-unqualified referenced
// type.
Qualifiers Quals;
QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
ImpCastExprToType(E, UnqualT, CK_NoOp, CastCategory(E));
}
}
-
+
// If this is an unevaluated operand, clear out the set of
// declaration references we have been computing and eliminate any
// temporaries introduced in its computation.
if (isUnevaluatedOperand)
ExprEvalContexts.back().Context = Unevaluated;
-
+
return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
E,
- SourceRange(TypeidLoc, RParenLoc)));
+ SourceRange(TypeidLoc, RParenLoc)));
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
if (!CXXTypeInfoDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
}
-
+
QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl);
-
+
if (isType) {
// The operand is a type; handle it as such.
TypeSourceInfo *TInfo = 0;
&TInfo);
if (T.isNull())
return ExprError();
-
+
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc);
}
- // The operand is an expression.
+ // The operand is an expression.
return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
}
if (!GetUuidAttrOfType(Operand->getType()))
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
}
-
+
// FIXME: add __uuidof semantic analysis for type operand.
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
Operand,
Expr *E,
SourceLocation RParenLoc) {
if (!E->getType()->isDependentType()) {
- if (!GetUuidAttrOfType(E->getType()) &&
+ if (!GetUuidAttrOfType(E->getType()) &&
!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
}
// FIXME: add __uuidof semantic analysis for type operand.
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
E,
- SourceRange(TypeidLoc, RParenLoc)));
+ SourceRange(TypeidLoc, RParenLoc)));
}
/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
ExprResult
Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
- // If MSVCGuidDecl has not been cached, do the lookup.
+ // If MSVCGuidDecl has not been cached, do the lookup.
if (!MSVCGuidDecl) {
IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID");
LookupResult R(*this, GuidII, SourceLocation(), LookupTagName);
MSVCGuidDecl = R.getAsSingle<RecordDecl>();
if (!MSVCGuidDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof));
- }
-
+ }
+
QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl);
-
+
if (isType) {
// The operand is a type; handle it as such.
TypeSourceInfo *TInfo = 0;
&TInfo);
if (T.isNull())
return ExprError();
-
+
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc);
}
- // The operand is an expression.
+ // The operand is an expression.
return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
}
// A throw-expression initializes a temporary object, called the exception
// object, the type of which is determined by removing any top-level
// cv-qualifiers from the static type of the operand of throw and adjusting
- // the type from "array of T" or "function returning T" to "pointer to T"
+ // the type from "array of T" or "function returning T" to "pointer to T"
// or "pointer to function returning T", [...]
if (E->getType().hasQualifiers())
ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
CastCategory(E));
-
+
DefaultFunctionArrayConversion(E);
// If the type of the exception would be an incomplete type or a pointer
InitializedEntity Entity =
InitializedEntity::InitializeException(ThrowLoc, E->getType(),
/*NRVO=*/false);
- ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable,
+ ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable,
QualType(), E);
if (Res.isInvalid())
return true;
if (RD->hasTrivialDestructor())
return false;
- CXXDestructorDecl *Destructor
+ CXXDestructorDecl *Destructor
= const_cast<CXXDestructorDecl*>(LookupDestructor(RD));
if (!Destructor)
return false;
SourceLocation RParenLoc) {
if (!TypeRep)
return ExprError();
-
+
TypeSourceInfo *TInfo;
QualType Ty = GetTypeFromParser(TypeRep, &TInfo);
if (!TInfo)
PDiag(diag::err_invalid_incomplete_type_use)
<< FullRange))
return ExprError();
-
+
if (RequireNonAbstractType(TyBeginLoc, Ty,
diag::err_allocation_of_abstract_type))
return ExprError();
CastKind Kind = CK_Invalid;
ExprValueKind VK = VK_RValue;
CXXCastPath BasePath;
- if (CheckCastTypes(TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0],
+ if (CheckCastTypes(TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0],
Kind, VK, BasePath,
/*FunctionalStyle=*/true))
return ExprError();
InitializationKind Kind
= NumExprs ? InitializationKind::CreateDirect(TyBeginLoc,
LParenLoc, RParenLoc)
- : InitializationKind::CreateValue(TyBeginLoc,
+ : InitializationKind::CreateValue(TyBeginLoc,
LParenLoc, RParenLoc);
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs));
ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
- SourceLocation PlacementRParen, SourceRange TypeIdParens,
+ SourceLocation PlacementRParen, SourceRange TypeIdParens,
Declarator &D, SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
QualType AllocType = TInfo->getType();
if (D.isInvalidType())
return ExprError();
-
+
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(AllocType);
-
+
return BuildCXXNew(StartLoc, UseGlobal,
PlacementLParen,
move(PlacementArgs),
// C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral
// or enumeration type with a non-negative value."
if (ArraySize && !ArraySize->isTypeDependent()) {
-
+
QualType SizeType = ArraySize->getType();
-
+
ExprResult ConvertedSize
= ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
PDiag(diag::err_array_size_not_integral),
PDiag(diag::note_array_size_conversion),
PDiag(diag::err_array_size_ambiguous_conversion),
PDiag(diag::note_array_size_conversion),
- PDiag(getLangOptions().CPlusPlus0x? 0
+ PDiag(getLangOptions().CPlusPlus0x? 0
: diag::ext_array_size_conversion));
if (ConvertedSize.isInvalid())
return ExprError();
-
+
ArraySize = ConvertedSize.take();
SizeType = ArraySize->getType();
if (!SizeType->isIntegralOrUnscopedEnumerationType())
return ExprError();
-
+
// Let's see if this is a constant < 0. If so, we reject it out of hand.
// We don't care about special rules, so we tell the machinery it's not
// evaluated - it gives us a result in more cases.
llvm::APSInt Value;
if (ArraySize->isIntegerConstantExpr(Value, Context, 0, false)) {
if (Value < llvm::APSInt(
- llvm::APInt::getNullValue(Value.getBitWidth()),
+ llvm::APInt::getNullValue(Value.getBitWidth()),
Value.isUnsigned()))
return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
diag::err_typecheck_negative_array_size)
<< ArraySize->getSourceRange());
-
+
if (!AllocType->isDependentType()) {
unsigned ActiveSizeBits
= ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
- Diag(ArraySize->getSourceRange().getBegin(),
+ Diag(ArraySize->getSourceRange().getBegin(),
diag::err_array_too_large)
<< Value.toString(10)
<< ArraySize->getSourceRange();
<< ArraySize->getSourceRange()
<< FixItHint::CreateRemoval(TypeIdParens.getBegin())
<< FixItHint::CreateRemoval(TypeIdParens.getEnd());
-
+
TypeIdParens = SourceRange();
}
}
-
+
ImpCastExprToType(ArraySize, Context.getSizeType(),
CK_IntegralCast);
}
FunctionDecl *OperatorDelete = 0;
Expr **PlaceArgs = (Expr**)PlacementArgs.get();
unsigned NumPlaceArgs = PlacementArgs.size();
-
+
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) &&
FindAllocationFunctions(StartLoc,
llvm::SmallVector<Expr *, 8> AllPlaceArgs;
if (OperatorNew) {
// Add default arguments, if any.
- const FunctionProtoType *Proto =
+ const FunctionProtoType *Proto =
OperatorNew->getType()->getAs<FunctionProtoType>();
- VariadicCallType CallType =
+ VariadicCallType CallType =
Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply;
-
+
if (GatherArgumentsForCall(PlacementLParen, OperatorNew,
- Proto, 1, PlaceArgs, NumPlaceArgs,
+ Proto, 1, PlaceArgs, NumPlaceArgs,
AllPlaceArgs, CallType))
return ExprError();
-
+
NumPlaceArgs = AllPlaceArgs.size();
if (NumPlaceArgs > 0)
PlaceArgs = &AllPlaceArgs[0];
}
-
+
bool Init = ConstructorLParen.isValid();
// --- Choosing a constructor ---
CXXConstructorDecl *Constructor = 0;
if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
SourceRange InitRange(ConsArgs[0]->getLocStart(),
ConsArgs[NumConsArgs - 1]->getLocEnd());
-
+
Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
return ExprError();
}
// initialized (8.5); if no initialization is performed,
// the object has indeterminate value
= !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
- // - Otherwise, the new-initializer is interpreted according to the
+ // - Otherwise, the new-initializer is interpreted according to the
// initialization rules of 8.5 for direct-initialization.
: InitializationKind::CreateDirect(TypeRange.getBegin(),
- ConstructorLParen,
+ ConstructorLParen,
ConstructorRParen);
-
+
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, AllocType);
InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
- ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
+ ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
move(ConstructorArgs));
if (FullInit.isInvalid())
return ExprError();
-
- // FullInit is our initializer; walk through it to determine if it's a
+
+ // FullInit is our initializer; walk through it to determine if it's a
// constructor call, which CXXNewExpr handles directly.
if (Expr *FullInitExpr = (Expr *)FullInit.get()) {
if (CXXBindTemporaryExpr *Binder
} else {
// No initialization required.
}
-
+
// Take the converted arguments and use them for the new expression.
NumConsArgs = ConvertedConstructorArgs.size();
ConsArgs = (Expr **)ConvertedConstructorArgs.take();
}
-
+
// Mark the new and delete operators as referenced.
if (OperatorNew)
MarkDeclarationReferenced(StartLoc, OperatorNew);
MarkDeclarationReferenced(StartLoc, OperatorDelete);
// FIXME: Also check that the destructor is accessible. (C++ 5.3.4p16)
-
+
PlacementArgs.release();
ConstructorArgs.release();
-
+
return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
PlaceArgs, NumPlaceArgs, TypeIdParens,
ArraySize, Constructor, Init,
else if (AllocType->isVariablyModifiedType())
return Diag(Loc, diag::err_variably_modified_new_type)
<< AllocType;
-
+
return false;
}
// same number of parameters and, after parameter transformations
// (8.3.5), all parameter types except the first are
// identical. [...]
- //
+ //
// To perform this comparison, we compute the function type that
// the deallocation function should have, and use that type both
// for template argument deduction and for comparison purposes.
= OperatorNew->getType()->getAs<FunctionProtoType>();
llvm::SmallVector<QualType, 4> ArgTypes;
- ArgTypes.push_back(Context.VoidPtrTy);
+ ArgTypes.push_back(Context.VoidPtrTy);
for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I)
ArgTypes.push_back(Proto->getArgType(I));
ArgTypes.size(), EPI);
}
- for (LookupResult::iterator D = FoundDelete.begin(),
+ for (LookupResult::iterator D = FoundDelete.begin(),
DEnd = FoundDelete.end();
D != DEnd; ++D) {
FunctionDecl *Fn = 0;
- if (FunctionTemplateDecl *FnTmpl
+ if (FunctionTemplateDecl *FnTmpl
= dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
// Perform template argument deduction to try to match the
// expected function type.
// C++ [expr.new]p20:
// [...] Any non-placement deallocation function matches a
// non-placement allocation function. [...]
- for (LookupResult::iterator D = FoundDelete.begin(),
+ for (LookupResult::iterator D = FoundDelete.begin(),
DEnd = FoundDelete.end();
D != DEnd; ++D) {
if (FunctionDecl *Fn = dyn_cast<FunctionDecl>((*D)->getUnderlyingDecl()))
if (NumPlaceArgs && getLangOptions().CPlusPlus0x &&
isNonPlacementDeallocationFunction(OperatorDelete)) {
Diag(StartLoc, diag::err_placement_new_non_placement_delete)
- << SourceRange(PlaceArgs[0]->getLocStart(),
+ << SourceRange(PlaceArgs[0]->getLocStart(),
PlaceArgs[NumPlaceArgs - 1]->getLocEnd());
Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
<< DeleteName;
R.suppressDiagnostics();
OverloadCandidateSet Candidates(StartLoc);
- for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
+ for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
Alloc != AllocEnd; ++Alloc) {
// Even member operator new/delete are implicitly treated as
// static, so don't use AddMemberCandidate.
Owned(Args[i]));
if (Result.isInvalid())
return true;
-
+
Args[i] = Result.takeAs<Expr>();
}
Operator = FnDecl;
void Sema::DeclareGlobalNewDelete() {
if (GlobalNewDeleteDeclared)
return;
-
+
// C++ [basic.std.dynamic]p2:
- // [...] The following allocation and deallocation functions (18.4) are
- // implicitly declared in global scope in each translation unit of a
+ // [...] The following allocation and deallocation functions (18.4) are
+ // implicitly declared in global scope in each translation unit of a
// program
- //
+ //
// void* operator new(std::size_t) throw(std::bad_alloc);
- // void* operator new[](std::size_t) throw(std::bad_alloc);
- // void operator delete(void*) throw();
+ // void* operator new[](std::size_t) throw(std::bad_alloc);
+ // void operator delete(void*) throw();
// void operator delete[](void*) throw();
//
- // These implicit declarations introduce only the function names operator
+ // These implicit declarations introduce only the function names operator
// new, operator new[], operator delete, operator delete[].
//
// Here, we need to refer to std::bad_alloc, so we will implicitly declare
if (!StdBadAlloc) {
// The "std::bad_alloc" class has not yet been declared, so build it
// implicitly.
- StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
- getOrCreateStdNamespace(),
- SourceLocation(),
- &PP.getIdentifierTable().get("bad_alloc"),
+ StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
+ getOrCreateStdNamespace(),
+ SourceLocation(),
+ &PP.getIdentifierTable().get("bad_alloc"),
SourceLocation(), 0);
getStdBadAlloc()->setImplicit(true);
}
-
+
GlobalNewDeleteDeclared = true;
QualType VoidPtr = Context.getPointerType(Context.VoidTy);
}
QualType BadAllocType;
- bool HasBadAllocExceptionSpec
+ bool HasBadAllocExceptionSpec
= (Name.getCXXOverloadedOperator() == OO_New ||
Name.getCXXOverloadedOperator() == OO_Array_New);
if (HasBadAllocExceptionSpec) {
EPI.NumExceptions = 1;
EPI.Exceptions = &BadAllocType;
}
-
+
QualType FnType = Context.getFunctionType(Return, &Argument, 1, EPI);
FunctionDecl *Alloc =
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
FnType, /*TInfo=*/0, SC_None,
SC_None, false, true);
Alloc->setImplicit();
-
+
if (AddMallocAttr)
Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
-
+
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
SC_None,
LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
// Try to find operator delete/operator delete[] in class scope.
LookupQualifiedName(Found, RD);
-
+
if (Found.isAmbiguous())
return true;
if (!Found.empty()) {
Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
<< Name << RD;
-
+
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
F != FEnd; ++F)
Diag((*F)->getUnderlyingDecl()->getLocation(),
// Look for a global declaration.
DeclareGlobalNewDelete();
DeclContext *TUDecl = Context.getTranslationUnitDecl();
-
+
CXXNullPtrLiteralExpr Null(Context.VoidPtrTy, SourceLocation());
Expr* DeallocArgs[1];
DeallocArgs[0] = &Null;
QualType Type = Ex->getType();
if (const RecordType *Record = Type->getAs<RecordType>()) {
- if (RequireCompleteType(StartLoc, Type,
+ if (RequireCompleteType(StartLoc, Type,
PDiag(diag::err_delete_incomplete_class_type)))
return ExprError();
-
+
llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
- const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions();
+ const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
NamedDecl *D = I.getDecl();
// Skip over templated conversion functions; they aren't considered.
if (isa<FunctionTemplateDecl>(D))
continue;
-
+
CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
-
+
QualType ConvType = Conv->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
QualType Pointee = Type->getAs<PointerType>()->getPointeeType();
if (Pointee->isVoidType() && !isSFINAEContext()) {
- // The C++ standard bans deleting a pointer to a non-object type, which
+ // The C++ standard bans deleting a pointer to a non-object type, which
// effectively bans deletion of "void*". However, most compilers support
// this, so we treat it as a warning unless we're in a SFINAE context.
Diag(StartLoc, diag::ext_delete_void_ptr_operand)
return ExprError();
// C++ [expr.delete]p2:
- // [Note: a pointer to a const type can be the operand of a
- // delete-expression; it is not necessary to cast away the constness
- // (5.2.11) of the pointer expression before it is used as the operand
+ // [Note: a pointer to a const type can be the operand of a
+ // delete-expression; it is not necessary to cast away the constness
+ // (5.2.11) of the pointer expression before it is used as the operand
// of the delete-expression. ]
- ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy),
+ ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy),
CK_NoOp);
if (Pointee->isArrayType() && !ArrayForm) {
if (const RecordType *RT = PointeeElem->getAs<RecordType>()) {
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (!UseGlobal &&
+ if (!UseGlobal &&
FindDeallocationFunction(StartLoc, RD, DeleteName, OperatorDelete))
return ExprError();
-
+
if (!RD->hasTrivialDestructor())
if (CXXDestructorDecl *Dtor = LookupDestructor(RD)) {
MarkDeclarationReferenced(StartLoc,
DiagnoseUseOfDecl(Dtor, StartLoc);
}
}
-
+
if (!OperatorDelete) {
// Look for a global declaration.
DeclareGlobalNewDelete();
SourceLocation StmtLoc,
bool ConvertToBoolean) {
QualType T = ConditionVar->getType();
-
+
// C++ [stmt.select]p2:
// The declarator shall not specify a function or an array.
if (T->isFunctionType())
- return ExprError(Diag(ConditionVar->getLocation(),
+ return ExprError(Diag(ConditionVar->getLocation(),
diag::err_invalid_use_of_function_type)
<< ConditionVar->getSourceRange());
else if (T->isArrayType())
- return ExprError(Diag(ConditionVar->getLocation(),
+ return ExprError(Diag(ConditionVar->getLocation(),
diag::err_invalid_use_of_array_type)
<< ConditionVar->getSourceRange());
Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
- ConditionVar->getLocation(),
+ ConditionVar->getLocation(),
ConditionVar->getType().getNonReferenceType(),
VK_LValue);
if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc))
return ExprError();
-
+
return Owned(Condition);
}
return false;
}
-static ExprResult BuildCXXCastArgument(Sema &S,
+static ExprResult BuildCXXCastArgument(Sema &S,
SourceLocation CastLoc,
QualType Ty,
CastKind Kind,
default: assert(0 && "Unhandled cast kind!");
case CK_ConstructorConversion: {
ASTOwningVector<Expr*> ConstructorArgs(S);
-
+
if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
MultiExprArg(&From, 1),
CastLoc, ConstructorArgs))
return ExprError();
-
- ExprResult Result =
- S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
+
+ ExprResult Result =
+ S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
move_arg(ConstructorArgs),
/*ZeroInit*/ false, CXXConstructExpr::CK_Complete,
SourceRange());
if (Result.isInvalid())
return ExprError();
-
+
return S.MaybeBindToTemporary(Result.takeAs<Expr>());
}
-
+
case CK_UserDefinedConversion: {
assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
-
+
// Create an implicit call expr that calls it.
ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method);
if (Result.isInvalid())
return ExprError();
-
+
return S.MaybeBindToTemporary(Result.get());
}
}
-}
+}
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType using the pre-computed implicit
break;
case ImplicitConversionSequence::UserDefinedConversion: {
-
+
FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
CastKind CastKind;
QualType BeforeToType;
if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
CastKind = CK_UserDefinedConversion;
-
+
// If the user-defined conversion is specified by a conversion function,
// the initial standard conversion sequence converts the source type to
// the implicit object parameter of the conversion function.
CastKind = CK_ConstructorConversion;
// Do no conversion if dealing with ... for the first conversion.
if (!ICS.UserDefined.EllipsisConversion) {
- // If the user-defined conversion is specified by a constructor, the
+ // If the user-defined conversion is specified by a constructor, the
// initial standard conversion sequence converts the source type to the
// type required by the argument of the constructor
BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType();
}
- }
+ }
// Watch out for elipsis conversion.
if (!ICS.UserDefined.EllipsisConversion) {
- if (PerformImplicitConversion(From, BeforeToType,
+ if (PerformImplicitConversion(From, BeforeToType,
ICS.UserDefined.Before, AA_Converting,
CStyle))
return true;
}
-
- ExprResult CastArg
+
+ ExprResult CastArg
= BuildCXXCastArgument(*this,
From->getLocStart(),
ToType.getNonReferenceType(),
PDiag(diag::err_typecheck_ambiguous_condition)
<< From->getSourceRange());
return true;
-
+
case ImplicitConversionSequence::EllipsisConversion:
assert(false && "Cannot perform an ellipsis conversion");
return false;
ASTOwningVector<Expr*> ConstructorArgs(*this);
if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor),
MultiExprArg(*this, &From, 1),
- /*FIXME:ConstructLoc*/SourceLocation(),
+ /*FIXME:ConstructLoc*/SourceLocation(),
ConstructorArgs))
return true;
ExprResult FromResult =
if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin()))
return true;
-
+
From = FixOverloadedFunctionReference(From, Found, Fn);
FromType = From->getType();
}
// If both sides are functions (or pointers/references to them), there could
// be incompatible exception declarations.
if (CheckExceptionSpecCompatibility(From, ToType))
- return true;
-
+ return true;
+
ImpCastExprToType(From, ToType, CK_NoOp);
break;
-
+
case ICK_Integral_Promotion:
case ICK_Integral_Conversion:
ImpCastExprToType(From, ToType, CK_IntegralCast);
<< From->getType() << ToType << Action
<< From->getSourceRange();
}
-
+
CastKind Kind = CK_Invalid;
CXXCastPath BasePath;
if (CheckPointerConversion(From, ToType, Kind, BasePath, CStyle))
ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
break;
}
-
+
case ICK_Pointer_Member: {
CastKind Kind = CK_Invalid;
CXXCastPath BasePath;
case Type::STK_IntegralComplex: Kind = CK_IntegralComplexToBoolean; break;
case Type::STK_FloatingComplex: Kind = CK_FloatingComplexToBoolean; break;
}
-
+
ImpCastExprToType(From, Context.BoolTy, Kind);
break;
}
case ICK_Derived_To_Base: {
CXXCastPath BasePath;
- if (CheckDerivedToBaseConversion(From->getType(),
+ if (CheckDerivedToBaseConversion(From->getType(),
ToType.getNonReferenceType(),
From->getLocStart(),
- From->getSourceRange(),
+ From->getSourceRange(),
&BasePath,
CStyle))
return true;
case ICK_Vector_Splat:
ImpCastExprToType(From, ToType, CK_VectorSplat);
break;
-
+
case ICK_Complex_Real:
// Case 1. x -> _Complex y
if (const ComplexType *ToComplex = ToType->getAs<ComplexType>()) {
}
}
break;
-
+
case ICK_Lvalue_To_Rvalue:
case ICK_Array_To_Pointer:
case ICK_Function_To_Pointer:
TypeSourceInfo *TSInfo,
SourceLocation RParen) {
QualType T = TSInfo->getType();
-
+
// According to http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
// all traits except __is_class, __is_enum and __is_union require a the type
// to be complete, an array of unknown bound, or void.
// Base is a base class of Derived without regard to cv-qualifiers or
// Base and Derived are not unions and name the same class type without
// regard to cv-qualifiers.
- if (Self.IsDerivedFrom(RhsT, LhsT) ||
+ if (Self.IsDerivedFrom(RhsT, LhsT) ||
(!LhsT->isUnionType() && !RhsT->isUnionType()
&& LhsT->getAsCXXRecordDecl() == RhsT->getAsCXXRecordDecl()))
return true;
SourceLocation RParen) {
QualType LhsT = LhsTSInfo->getType();
QualType RhsT = RhsTSInfo->getType();
-
+
if (BTT == BTT_IsBaseOf) {
// C++0x [meta.rel]p2
// If Base and Derived are class types and are different types
// C++0x [expr.mptr.oper]p6:
// In a .* expression whose object expression is an rvalue, the program is
- // ill-formed if the second operand is a pointer to member function with
- // ref-qualifier &. In a ->* expression or in a .* expression whose object
- // expression is an lvalue, the program is ill-formed if the second operand
+ // ill-formed if the second operand is a pointer to member function with
+ // ref-qualifier &. In a ->* expression or in a .* expression whose object
+ // expression is an lvalue, the program is ill-formed if the second operand
// is a pointer to member function with ref-qualifier &&.
if (const FunctionProtoType *Proto = Result->getAs<FunctionProtoType>()) {
switch (Proto->getRefQualifier()) {
Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
<< RType << 1 << lex->getSourceRange();
break;
-
+
case RQ_RValue:
if (isIndirect || !lex->Classify(Context).isRValue())
Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
break;
}
}
-
+
// C++ [expr.mptr.oper]p6:
// The result of a .* expression whose second operand is a pointer
// to a data member is of the same value category as its
QualType &ToType) {
HaveConversion = false;
ToType = To->getType();
-
- InitializationKind Kind = InitializationKind::CreateCopy(To->getLocStart(),
+
+ InitializationKind Kind = InitializationKind::CreateCopy(To->getLocStart(),
SourceLocation());
// C++0x 5.16p3
// The process for determining whether an operand expression E1 of type T1
// conversion the reference must bind directly to E1.
QualType T = Self.Context.getLValueReferenceType(ToType);
InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
-
+
InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
if (InitSeq.isDirectReferenceBinding()) {
ToType = T;
HaveConversion = true;
return false;
}
-
+
if (InitSeq.isAmbiguous())
return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
}
QualType TTy = To->getType();
const RecordType *FRec = FTy->getAs<RecordType>();
const RecordType *TRec = TTy->getAs<RecordType>();
- bool FDerivedFromT = FRec && TRec && FRec != TRec &&
+ bool FDerivedFromT = FRec && TRec && FRec != TRec &&
Self.IsDerivedFrom(FTy, TTy);
- if (FRec && TRec &&
+ if (FRec && TRec &&
(FRec == TRec || FDerivedFromT || Self.IsDerivedFrom(TTy, FTy))) {
// E1 can be converted to match E2 if the class of T2 is the
// same type as, or a base class of, the class of T1, and
HaveConversion = true;
return false;
}
-
+
if (InitSeq.isAmbiguous())
return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
- }
+ }
}
-
+
return false;
}
-
+
// -- Otherwise: E1 can be converted to match E2 if E1 can be
// implicitly converted to the type that expression E2 would have
- // if E2 were converted to an rvalue (or the type it has, if E2 is
+ // if E2 were converted to an rvalue (or the type it has, if E2 is
// an rvalue).
//
// This actually refers very narrowly to the lvalue-to-rvalue conversion, not
// to the array-to-pointer or function-to-pointer conversions.
if (!TTy->getAs<TagType>())
TTy = TTy.getUnqualifiedType();
-
+
InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
- HaveConversion = InitSeq.getKind() != InitializationSequence::FailedSequence;
+ HaveConversion = InitSeq.getKind() != InitializationSequence::FailedSequence;
ToType = TTy;
if (InitSeq.isAmbiguous())
return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&E, 1));
if (Result.isInvalid())
return true;
-
+
E = Result.takeAs<Expr>();
return false;
}
// Otherwise, if the second and third operand have different types, and
// either has (cv) class type, and attempt is made to convert each of those
// operands to the other.
- if (!Context.hasSameType(LTy, RTy) &&
+ if (!Context.hasSameType(LTy, RTy) &&
(LTy->isRecordType() || RTy->isRecordType())) {
ImplicitConversionSequence ICSLeftToRight, ICSRightToLeft;
// These return true if a single direction is already ambiguous.
return QualType();
if (TryClassUnification(*this, RHS, LHS, QuestionLoc, HaveR2L, R2LType))
return QualType();
-
+
// If both can be converted, [...] the program is ill-formed.
if (HaveL2R && HaveR2L) {
Diag(QuestionLoc, diag::err_conditional_ambiguous)
if (LTy->isRecordType()) {
// The operands have class type. Make a temporary copy.
InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
- ExprResult LHSCopy = PerformCopyInitialization(Entity,
- SourceLocation(),
+ ExprResult LHSCopy = PerformCopyInitialization(Entity,
+ SourceLocation(),
Owned(LHS));
if (LHSCopy.isInvalid())
return QualType();
-
- ExprResult RHSCopy = PerformCopyInitialization(Entity,
- SourceLocation(),
+
+ ExprResult RHSCopy = PerformCopyInitialization(Entity,
+ SourceLocation(),
Owned(RHS));
if (RHSCopy.isInvalid())
return QualType();
-
+
LHS = LHSCopy.takeAs<Expr>();
RHS = RHSCopy.takeAs<Expr>();
}
}
// Extension: conditional operator involving vector types.
- if (LTy->isVectorType() || RTy->isVectorType())
+ if (LTy->isVectorType() || RTy->isVectorType())
return CheckVectorOperands(QuestionLoc, LHS, RHS);
// -- The second and third operands have arithmetic or enumeration type;
isSFINAEContext()? 0 : &NonStandardCompositeType);
if (!Composite.isNull()) {
if (NonStandardCompositeType)
- Diag(QuestionLoc,
+ Diag(QuestionLoc,
diag::ext_typecheck_cond_incompatible_operands_nonstandard)
<< LTy << RTy << Composite
<< LHS->getSourceRange() << RHS->getSourceRange();
-
+
return Composite;
}
-
+
// Similarly, attempt to find composite type of two objective-c pointers.
Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
if (!Composite.isNull())
/// a non-standard (but still sane) composite type to which both expressions
/// can be converted. When such a type is chosen, \c *NonStandardCompositeType
/// will be set true.
-QualType Sema::FindCompositePointerType(SourceLocation Loc,
+QualType Sema::FindCompositePointerType(SourceLocation Loc,
Expr *&E1, Expr *&E2,
bool *NonStandardCompositeType) {
if (NonStandardCompositeType)
*NonStandardCompositeType = false;
-
+
assert(getLangOptions().CPlusPlus && "This function assumes C++");
QualType T1 = E1->getType(), T2 = E2->getType();
ContainingClassVector MemberOfClass;
QualType Composite1 = Context.getCanonicalType(T1),
Composite2 = Context.getCanonicalType(T2);
- unsigned NeedConstBefore = 0;
+ unsigned NeedConstBefore = 0;
do {
const PointerType *Ptr1, *Ptr2;
if ((Ptr1 = Composite1->getAs<PointerType>()) &&
(Ptr2 = Composite2->getAs<PointerType>())) {
Composite1 = Ptr1->getPointeeType();
Composite2 = Ptr2->getPointeeType();
-
+
// If we're allowed to create a non-standard composite type, keep track
- // of where we need to fill in additional 'const' qualifiers.
+ // of where we need to fill in additional 'const' qualifiers.
if (NonStandardCompositeType &&
Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
NeedConstBefore = QualifierUnion.size();
-
+
QualifierUnion.push_back(
Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers());
MemberOfClass.push_back(std::make_pair((const Type *)0, (const Type *)0));
(MemPtr2 = Composite2->getAs<MemberPointerType>())) {
Composite1 = MemPtr1->getPointeeType();
Composite2 = MemPtr2->getPointeeType();
-
+
// If we're allowed to create a non-standard composite type, keep track
- // of where we need to fill in additional 'const' qualifiers.
+ // of where we need to fill in additional 'const' qualifiers.
if (NonStandardCompositeType &&
Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
NeedConstBefore = QualifierUnion.size();
-
+
QualifierUnion.push_back(
Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers());
MemberOfClass.push_back(std::make_pair(MemPtr1->getClass(),
if (NeedConstBefore && NonStandardCompositeType) {
// Extension: Add 'const' to qualifiers that come before the first qualifier
- // mismatch, so that our (non-standard!) composite type meets the
+ // mismatch, so that our (non-standard!) composite type meets the
// requirements of C++ [conv.qual]p4 bullet 3.
for (unsigned I = 0; I != NeedConstBefore; ++I) {
if ((QualifierUnion[I] & Qualifiers::Const) == 0) {
}
}
}
-
+
// Rewrap the composites as pointers or member pointers with the union CVRs.
ContainingClassVector::reverse_iterator MOC
= MemberOfClass.rbegin();
if (E2Result.isInvalid())
return QualType();
E2 = E2Result.takeAs<Expr>();
-
+
return Composite1;
}
InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
if (!E1ToC2 || !E2ToC2)
return QualType();
-
+
// Convert E1 to Composite2
ExprResult E1Result
= E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E1, 1));
if (E1Result.isInvalid())
return QualType();
E1 = E1Result.takeAs<Expr>();
-
+
// Convert E2 to Composite2
ExprResult E2Result
= E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1));
if (E2Result.isInvalid())
return QualType();
E2 = E2Result.takeAs<Expr>();
-
+
return Composite2;
}
ExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!E)
return ExprError();
-
+
if (!Context.getLangOptions().CPlusPlus)
return Owned(E);
} else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
if (const ObjCMethodDecl *MD = ME->getMethodDecl()) {
if (MD->getResultType()->isReferenceType())
- return Owned(E);
+ return Owned(E);
}
}
return E;
}
-ExprResult
+ExprResult
Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) {
if (SubExpr.isInvalid())
return ExprError();
-
+
return Owned(MaybeCreateExprWithCleanups(SubExpr.take()));
}
if (OpKind == tok::arrow)
if (const PointerType *Ptr = BaseType->getAs<PointerType>())
BaseType = Ptr->getPointeeType();
-
+
ObjectType = ParsedType::make(BaseType);
MayBePseudoDestructor = true;
return Owned(Base);
llvm::SmallPtrSet<CanQualType,8> CTypes;
llvm::SmallVector<SourceLocation, 8> Locations;
CTypes.insert(Context.getCanonicalType(BaseType));
-
+
while (BaseType->isRecordType()) {
Result = BuildOverloadedArrowExpr(S, Base, OpLoc);
if (Result.isInvalid())
// The object type must be complete (or dependent).
if (!BaseType->isDependentType() &&
- RequireCompleteType(OpLoc, BaseType,
+ RequireCompleteType(OpLoc, BaseType,
PDiag(diag::err_incomplete_member_access)))
return ExprError();
-
+
// C++ [basic.lookup.classref]p2:
// If the id-expression in a class member access (5.2.5) is an
// unqualified-id, and the type of the object expression is of a class
Diag(MemExpr->getLocStart(), diag::err_dtor_expr_without_call)
<< isa<CXXPseudoDestructorExpr>(MemExpr)
<< FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
-
+
return ActOnCallExpr(/*Scope*/ 0,
MemExpr,
/*LPLoc*/ ExpectedLParenLoc,
PseudoDestructorTypeStorage Destructed,
bool HasTrailingLParen) {
TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo();
-
+
// C++ [expr.pseudo]p2:
- // The left-hand side of the dot operator shall be of scalar type. The
+ // The left-hand side of the dot operator shall be of scalar type. The
// left-hand side of the arrow operator shall be of pointer to scalar type.
- // This scalar type is the object type.
+ // This scalar type is the object type.
QualType ObjectType = Base->getType();
if (OpKind == tok::arrow) {
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
<< FixItHint::CreateReplacement(OpLoc, ".");
if (isSFINAEContext())
return ExprError();
-
+
OpKind = tok::period;
}
}
-
+
if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
<< ObjectType << Base->getSourceRange();
}
// C++ [expr.pseudo]p2:
- // [...] The cv-unqualified versions of the object type and of the type
+ // [...] The cv-unqualified versions of the object type and of the type
// designated by the pseudo-destructor-name shall be the same type.
if (DestructedTypeInfo) {
QualType DestructedType = DestructedTypeInfo->getType();
Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
<< ObjectType << DestructedType << Base->getSourceRange()
<< DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
-
+
// Recover by setting the destructed type to the object type.
DestructedType = ObjectType;
DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
}
}
-
+
// C++ [expr.pseudo]p2:
// [...] Furthermore, the two type-names in a pseudo-destructor-name of the
// form
//
- // ::[opt] nested-name-specifier[opt] type-name :: ~ type-name
+ // ::[opt] nested-name-specifier[opt] type-name :: ~ type-name
//
// shall designate the same scalar type.
if (ScopeTypeInfo) {
QualType ScopeType = ScopeTypeInfo->getType();
if (!ScopeType->isDependentType() && !ObjectType->isDependentType() &&
!Context.hasSameUnqualifiedType(ScopeType, ObjectType)) {
-
+
Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(),
diag::err_pseudo_dtor_type_mismatch)
<< ObjectType << ScopeType << Base->getSourceRange()
<< ScopeTypeInfo->getTypeLoc().getLocalSourceRange();
-
+
ScopeType = QualType();
ScopeTypeInfo = 0;
}
}
-
+
Expr *Result
= new (Context) CXXPseudoDestructorExpr(Context, Base,
OpKind == tok::arrow, OpLoc,
CCLoc,
TildeLoc,
Destructed);
-
+
if (HasTrailingLParen)
return Owned(Result);
-
+
return DiagnoseDtorReference(Destructed.getLocation(), Result);
}
"Invalid second type name in pseudo-destructor");
// C++ [expr.pseudo]p2:
- // The left-hand side of the dot operator shall be of scalar type. The
+ // The left-hand side of the dot operator shall be of scalar type. The
// left-hand side of the arrow operator shall be of pointer to scalar type.
- // This scalar type is the object type.
+ // This scalar type is the object type.
QualType ObjectType = Base->getType();
if (OpKind == tok::arrow) {
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
<< FixItHint::CreateReplacement(OpLoc, ".");
if (isSFINAEContext())
return ExprError();
-
+
OpKind = tok::period;
}
}
else if (ObjectType->isDependentType())
ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
}
-
- // Convert the name of the type being destructed (following the ~) into a
+
+ // Convert the name of the type being destructed (following the ~) into a
// type (with source-location information).
QualType DestructedType;
TypeSourceInfo *DestructedTypeInfo = 0;
PseudoDestructorTypeStorage Destructed;
if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
- ParsedType T = getTypeName(*SecondTypeName.Identifier,
+ ParsedType T = getTypeName(*SecondTypeName.Identifier,
SecondTypeName.StartLocation,
S, &SS, true, ObjectTypePtrForLookup);
- if (!T &&
+ if (!T &&
((SS.isSet() && !computeDeclContext(SS, false)) ||
(!SS.isSet() && ObjectType->isDependentType()))) {
- // The name of the type being destroyed is a dependent name, and we
+ // The name of the type being destroyed is a dependent name, and we
// couldn't find anything useful in scope. Just store the identifier and
// it's location, and we'll perform (qualified) name lookup again at
// template instantiation time.
Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier,
SecondTypeName.StartLocation);
} else if (!T) {
- Diag(SecondTypeName.StartLocation,
+ Diag(SecondTypeName.StartLocation,
diag::err_pseudo_dtor_destructor_non_type)
<< SecondTypeName.Identifier << ObjectType;
if (isSFINAEContext())
return ExprError();
-
+
// Recover by assuming we had the right type all along.
DestructedType = ObjectType;
} else
} else
DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo);
}
-
- // If we've performed some kind of recovery, (re-)build the type source
+
+ // If we've performed some kind of recovery, (re-)build the type source
// information.
if (!DestructedType.isNull()) {
if (!DestructedTypeInfo)
SecondTypeName.StartLocation);
Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
}
-
+
// Convert the name of the scope type (the type prior to '::') into a type.
TypeSourceInfo *ScopeTypeInfo = 0;
QualType ScopeType;
- if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
+ if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
FirstTypeName.Identifier) {
if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
- ParsedType T = getTypeName(*FirstTypeName.Identifier,
+ ParsedType T = getTypeName(*FirstTypeName.Identifier,
FirstTypeName.StartLocation,
S, &SS, false, ObjectTypePtrForLookup);
if (!T) {
- Diag(FirstTypeName.StartLocation,
+ Diag(FirstTypeName.StartLocation,
diag::err_pseudo_dtor_destructor_non_type)
<< FirstTypeName.Identifier << ObjectType;
-
+
if (isSFINAEContext())
return ExprError();
-
+
// Just drop this type. It's unnecessary anyway.
ScopeType = QualType();
} else
// Recover by dropping this type.
ScopeType = QualType();
} else
- ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo);
+ ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo);
}
}
-
+
if (!ScopeType.isNull() && !ScopeTypeInfo)
ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType,
FirstTypeName.StartLocation);
-
+
return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
ScopeTypeInfo, CCLoc, TildeLoc,
Destructed, HasTrailingLParen);
FoundDecl, Method))
return true;
- MemberExpr *ME =
+ MemberExpr *ME =
new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
SourceLocation(), Method->getType(),
VK_RValue, OK_Ordinary);
}
ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
- if (!FullExpr)
+ if (!FullExpr)
return ExprError();
if (DiagnoseUnexpandedParameterPack(FullExpr))
void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
const InitializedEntity &ParentEntity,
- InitListExpr *ILE,
+ InitListExpr *ILE,
bool &RequiresSecondPass) {
SourceLocation Loc = ILE->getSourceRange().getBegin();
unsigned NumInits = ILE->getNumInits();
- InitializedEntity MemberEntity
+ InitializedEntity MemberEntity
= InitializedEntity::InitializeMember(Field, &ParentEntity);
if (Init >= NumInits || !ILE->getInit(Init)) {
// FIXME: We probably don't need to handle references
hadError = true;
return;
}
-
+
InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
true);
InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, 0, 0);
hadError = true;
return;
}
-
+
ExprResult MemberInit
= InitSeq.Perform(SemaRef, MemberEntity, Kind, MultiExprArg());
if (MemberInit.isInvalid()) {
hadError = true;
return;
}
-
+
if (hadError) {
// Do nothing
} else if (Init < NumInits) {
}
} else if (InitListExpr *InnerILE
= dyn_cast<InitListExpr>(ILE->getInit(Init)))
- FillInValueInitializations(MemberEntity, InnerILE,
- RequiresSecondPass);
+ FillInValueInitializations(MemberEntity, InnerILE,
+ RequiresSecondPass);
}
/// Recursively replaces NULL values within the given initializer list
/// with expressions that perform value-initialization of the
/// appropriate type.
-void
+void
InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
InitListExpr *ILE,
bool &RequiresSecondPass) {
ElementType = AType->getElementType();
if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType))
NumElements = CAType->getSize().getZExtValue();
- ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context,
+ ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context,
0, Entity);
} else if (const VectorType *VType = ILE->getType()->getAs<VectorType>()) {
ElementType = VType->getElementType();
NumElements = VType->getNumElements();
- ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context,
+ ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context,
0, Entity);
} else
ElementType = ILE->getType();
-
+
for (unsigned Init = 0; Init != NumElements; ++Init) {
if (hadError)
return;
unsigned newStructuredIndex = 0;
FullyStructuredList
= getStructuredSubobjectInit(IL, newIndex, T, 0, 0, IL->getSourceRange());
- CheckExplicitInitList(Entity, IL, T, newIndex,
+ CheckExplicitInitList(Entity, IL, T, newIndex,
FullyStructuredList, newStructuredIndex,
/*TopLevelObject=*/true);
bool RequiresSecondPass = false;
FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass);
if (RequiresSecondPass && !hadError)
- FillInValueInitializations(Entity, FullyStructuredList,
+ FillInValueInitializations(Entity, FullyStructuredList,
RequiresSecondPass);
}
}
// Check the element types and build the structural subobject.
unsigned StartIndex = Index;
- CheckListElementTypes(Entity, ParentIList, T,
+ CheckListElementTypes(Entity, ParentIList, T,
/*SubobjectIsDesignatorContext=*/false, Index,
StructuredSubobjectInitList,
StructuredSubobjectInitIndex,
= ParentIList->getInit(EndIndex)->getSourceRange().getEnd();
StructuredSubobjectInitList->setRBraceLoc(EndLoc);
}
-
+
// Warn about missing braces.
if (T->isArrayType() || T->isRecordType()) {
SemaRef.Diag(StructuredSubobjectInitList->getLocStart(),
diag::warn_missing_braces)
<< StructuredSubobjectInitList->getSourceRange()
- << FixItHint::CreateInsertion(StructuredSubobjectInitList->getLocStart(),
+ << FixItHint::CreateInsertion(StructuredSubobjectInitList->getLocStart(),
"{")
<< FixItHint::CreateInsertion(SemaRef.PP.getLocForEndOfToken(
- StructuredSubobjectInitList->getLocEnd()),
+ StructuredSubobjectInitList->getLocEnd()),
"}");
}
}
assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
SyntacticToSemantic[IList] = StructuredList;
StructuredList->setSyntacticForm(IList);
- CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
+ CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
Index, StructuredList, StructuredIndex, TopLevelObject);
QualType ExprTy = T.getNonLValueExprType(SemaRef.Context);
IList->setType(ExprTy);
CheckScalarType(Entity, IList, DeclType, Index,
StructuredList, StructuredIndex);
} else if (DeclType->isVectorType()) {
- CheckVectorType(Entity, IList, DeclType, Index,
+ CheckVectorType(Entity, IList, DeclType, Index,
StructuredList, StructuredIndex);
} else if (DeclType->isAggregateType()) {
if (DeclType->isRecordType()) {
llvm::APSInt Zero(
SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
false);
- CheckArrayType(Entity, IList, DeclType, Zero,
+ CheckArrayType(Entity, IList, DeclType, Zero,
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex);
} else
UpdateStructuredListElement(StructuredList, StructuredIndex, Str);
++Index;
} else if (ElemType->isScalarType()) {
- CheckScalarType(Entity, IList, ElemType, Index,
+ CheckScalarType(Entity, IList, ElemType, Index,
StructuredList, StructuredIndex);
} else if (ElemType->isReferenceType()) {
CheckReferenceType(Entity, IList, ElemType, Index,
// member, the member is initialized. [...]
// FIXME: Better EqualLoc?
- InitializationKind Kind =
+ InitializationKind Kind =
InitializationKind::CreateCopy(expr->getLocStart(), SourceLocation());
InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1);
-
+
if (Seq) {
- ExprResult Result =
+ ExprResult Result =
Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
if (Result.isInvalid())
hadError = true;
-
- UpdateStructuredListElement(StructuredList, StructuredIndex,
+
+ UpdateStructuredListElement(StructuredList, StructuredIndex,
Result.takeAs<Expr>());
++Index;
return;
} else {
// We cannot initialize this element, so let
// PerformCopyInitialization produce the appropriate diagnostic.
- SemaRef.PerformCopyInitialization(Entity, SourceLocation(),
+ SemaRef.PerformCopyInitialization(Entity, SourceLocation(),
SemaRef.Owned(expr));
hadError = true;
++Index;
hadError = true; // types weren't compatible.
else {
ResultExpr = Result.takeAs<Expr>();
-
+
if (ResultExpr != expr) {
// The type was promoted, update initializer list.
IList->setInit(Index, ResultExpr);
hadError = true; // types weren't compatible.
else {
ResultExpr = Result.takeAs<Expr>();
-
+
if (ResultExpr != Init) {
// The type was promoted, update initializer list.
IList->setInit(Index, ResultExpr);
InitializedEntity ElementEntity =
InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
-
+
for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) {
// Don't attempt to go past the end of the init list
if (Index >= IList->getNumInits())
break;
-
+
ElementEntity.setElementIndex(Index);
CheckSubElementType(ElementEntity, IList, elementType, Index,
StructuredList, StructuredIndex);
InitializedEntity ElementEntity =
InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
-
+
// OpenCL initializers allows vectors to be constructed from vectors.
for (unsigned i = 0; i < maxElements; ++i) {
// Don't attempt to go past the end of the init list
if (Index >= IList->getNumInits())
break;
-
+
ElementEntity.setElementIndex(Index);
QualType IType = IList->getInit(Index)->getType();
QualType VecType;
const VectorType *IVT = IType->getAs<VectorType>();
unsigned numIElts = IVT->getNumElements();
-
+
if (IType->isExtVectorType())
VecType = SemaRef.Context.getExtVectorType(elementType, numIElts);
else
break;
InitializedEntity ElementEntity =
- InitializedEntity::InitializeElement(SemaRef.Context, StructuredIndex,
+ InitializedEntity::InitializeElement(SemaRef.Context, StructuredIndex,
Entity);
// Check this element.
CheckSubElementType(ElementEntity, IList, elementType, Index,
}
// Emit warnings for missing struct field initializers.
- if (InitializedSomething && CheckForMissingFields && Field != FieldEnd &&
+ if (InitializedSomething && CheckForMissingFields && Field != FieldEnd &&
!Field->getType()->isIncompleteArrayType() && !DeclType->isUnionType()) {
// It is possible we have one or more unnamed bitfields remaining.
// Find first (if any) named field and emit warning.
InitializedEntity MemberEntity =
InitializedEntity::InitializeMember(*Field, &Entity);
-
+
if (isa<InitListExpr>(IList->getInit(Index)))
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
+ CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
StructuredList, StructuredIndex);
else
- CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index,
+ CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index,
StructuredList, StructuredIndex);
}
&Replacements[0] + Replacements.size());
}
-/// \brief Given an implicit anonymous field, search the IndirectField that
+/// \brief Given an implicit anonymous field, search the IndirectField that
/// corresponds to FieldName.
static IndirectFieldDecl *FindIndirectFieldDesignator(FieldDecl *AnonField,
IdentifierInfo *FieldName) {
for (; Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
-
+
// If we find a field representing an anonymous field, look in the
// IndirectFieldDecl that follow for the designated initializer.
if (!KnownField && Field->isAnonymousStructOrUnion()) {
if (Lookup.first == Lookup.second) {
// Name lookup didn't find anything. Determine whether this
// was a typo for another field name.
- LookupResult R(SemaRef, FieldName, D->getFieldLoc(),
+ LookupResult R(SemaRef, FieldName, D->getFieldLoc(),
Sema::LookupMemberName);
if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false,
- Sema::CTC_NoKeywords) &&
+ Sema::CTC_NoKeywords) &&
(ReplacementField = R.getAsSingle<FieldDecl>()) &&
ReplacementField->getDeclContext()->getRedeclContext()
->Equals(RT->getDecl())) {
- SemaRef.Diag(D->getFieldLoc(),
+ SemaRef.Diag(D->getFieldLoc(),
diag::err_field_designator_unknown_suggest)
<< FieldName << CurrentObjectType << R.getLookupName()
<< FixItHint::CreateReplacement(D->getFieldLoc(),
R.getLookupName().getAsString());
- SemaRef.Diag(ReplacementField->getLocation(),
+ SemaRef.Diag(ReplacementField->getLocation(),
diag::note_previous_decl)
<< ReplacementField->getDeclName();
} else {
return true;
}
}
-
+
if (!ReplacementField) {
// Name lookup found something, but it wasn't a field.
SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
if (Field->isUnnamedBitfield())
continue;
- if (ReplacementField == *Field ||
+ if (ReplacementField == *Field ||
Field->getIdentifier() == ReplacementField->getIdentifier())
break;
// Recurse to check later designated subobjects.
QualType FieldType = (*Field)->getType();
unsigned newStructuredIndex = FieldIndex;
-
+
InitializedEntity MemberEntity =
InitializedEntity::InitializeMember(*Field, &Entity);
- if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1,
- FieldType, 0, 0, Index,
+ if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1,
+ FieldType, 0, 0, Index,
StructuredList, newStructuredIndex,
true, false))
return true;
// Check the remaining fields within this class/struct/union subobject.
bool prevHadError = hadError;
-
+
CheckStructUnionTypes(Entity, IList, CurrentObjectType, Field, false, Index,
StructuredList, FieldIndex);
return hadError && !prevHadError;
// Move to the next designator
unsigned ElementIndex = DesignatedStartIndex.getZExtValue();
unsigned OldIndex = Index;
-
+
InitializedEntity ElementEntity =
InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
// Recurse to check later designated subobjects.
QualType ElementType = AT->getElementType();
Index = OldIndex;
-
+
ElementEntity.setElementIndex(ElementIndex);
- if (CheckDesignatedInitializer(ElementEntity, IList, DIE, DesigIdx + 1,
- ElementType, 0, 0, Index,
+ if (CheckDesignatedInitializer(ElementEntity, IList, DIE, DesigIdx + 1,
+ ElementType, 0, 0, Index,
StructuredList, ElementIndex,
(DesignatedStartIndex == DesignatedEndIndex),
false))
// Check the remaining elements within this array subobject.
bool prevHadError = hadError;
- CheckArrayType(Entity, IList, CurrentObjectType, DesignatedStartIndex,
+ CheckArrayType(Entity, IList, CurrentObjectType, DesignatedStartIndex,
/*SubobjectIsDesignatorContext=*/false, Index,
StructuredList, ElementIndex);
return hadError && !prevHadError;
Designators.data(), Designators.size(),
InitExpressions.data(), InitExpressions.size(),
Loc, GNUSyntax, Init.takeAs<Expr>());
-
+
if (getLangOptions().CPlusPlus)
Diag(DIE->getLocStart(), diag::ext_designated_init)
<< DIE->getSourceRange();
-
+
return Owned(DIE);
}
// Initialization entity
//===----------------------------------------------------------------------===//
-InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index,
+InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index,
const InitializedEntity &Parent)
- : Parent(&Parent), Index(Index)
+ : Parent(&Parent), Index(Index)
{
if (const ArrayType *AT = Context.getAsArrayType(Parent.getType())) {
Kind = EK_ArrayElement;
}
}
-InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context,
+InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context,
CXXBaseSpecifier *Base,
bool IsInheritedVirtualBase)
{
Result.Base = reinterpret_cast<uintptr_t>(Base);
if (IsInheritedVirtualBase)
Result.Base |= 0x01;
-
+
Result.Type = Base->getType();
return Result;
}
case EK_BlockElement:
return DeclarationName();
}
-
+
// Silence GCC warning
return DeclarationName();
}
case EK_BlockElement:
return 0;
}
-
+
// Silence GCC warning
return 0;
}
case EK_Result:
case EK_Exception:
return LocAndNRVO.NRVO;
-
+
case EK_Variable:
case EK_Parameter:
case EK_Member:
case SK_StringInit:
case SK_ObjCObjectConversion:
break;
-
+
case SK_ConversionSequence:
delete ICS;
}
bool InitializationSequence::isAmbiguous() const {
if (getKind() != FailedSequence)
return false;
-
+
switch (getFailureKind()) {
case FK_TooManyInitsForReference:
case FK_ArrayNeedsInitList:
case FK_DefaultInitOfConst:
case FK_Incomplete:
return false;
-
+
case FK_ReferenceInitOverloadFailed:
case FK_UserConversionOverloadFailed:
case FK_ConstructorOverloadFailed:
return FailedOverloadResult == OR_Ambiguous;
}
-
+
return false;
}
Steps.push_back(S);
}
-void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType,
+void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType,
ExprValueKind VK) {
Step S;
switch (VK) {
Steps.push_back(S);
}
-void InitializationSequence::AddReferenceBindingStep(QualType T,
+void InitializationSequence::AddReferenceBindingStep(QualType T,
bool BindingTemporary) {
Step S;
S.Kind = BindingTemporary? SK_BindReferenceToTemporary : SK_BindReference;
Steps.push_back(S);
}
-void
+void
InitializationSequence::AddConstructorInitializationStep(
CXXConstructorDecl *Constructor,
AccessSpecifier Access,
Steps.push_back(S);
}
-void InitializationSequence::SetOverloadFailure(FailureKind Failure,
+void InitializationSequence::SetOverloadFailure(FailureKind Failure,
OverloadingResult Result) {
SequenceKind = FailedSequence;
this->Failure = Failure;
// Attempt initialization
//===----------------------------------------------------------------------===//
-/// \brief Attempt list initialization (C++0x [dcl.init.list])
-static void TryListInitialization(Sema &S,
+/// \brief Attempt list initialization (C++0x [dcl.init.list])
+static void TryListInitialization(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
InitListExpr *InitList,
QualType DestType = Entity.getType();
// C++ [dcl.init]p13:
- // If T is a scalar type, then a declaration of the form
+ // If T is a scalar type, then a declaration of the form
//
// T x = { a };
//
bool DerivedToBase;
bool ObjCConversion;
- assert(!S.CompareReferenceRelationship(Initializer->getLocStart(),
+ assert(!S.CompareReferenceRelationship(Initializer->getLocStart(),
T1, T2, DerivedToBase,
ObjCConversion) &&
"Must have incompatible references when binding via conversion");
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
-
+
const RecordType *T1RecordType = 0;
if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) &&
!S.RequireCompleteType(Kind.getLocation(), T1, 0)) {
ConstructorTmpl->getTemplatedDecl());
else
Constructor = cast<CXXConstructorDecl>(D);
-
+
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
&Initializer, 1, CandidateSet,
/*SuppressUserConversions=*/true);
}
- }
+ }
}
if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
return OR_No_Viable_Function;
-
+
const RecordType *T2RecordType = 0;
if ((T2RecordType = T2->getAs<RecordType>()) &&
!S.RequireCompleteType(Kind.getLocation(), T2, 0)) {
CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
-
+
FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
CXXConversionDecl *Conv;
if (ConvTemplate)
Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
Conv = cast<CXXConversionDecl>(D);
-
+
// If the conversion function doesn't return a reference type,
// it can't be considered for this conversion unless we're allowed to
// consider rvalues.
- // FIXME: Do we need to make sure that we only consider conversion
- // candidates with reference-compatible results? That might be needed to
+ // FIXME: Do we need to make sure that we only consider conversion
+ // candidates with reference-compatible results? That might be needed to
// break recursion.
if ((AllowExplicit || !Conv->isExplicit()) &&
(AllowRValues || Conv->getConversionType()->isLValueReferenceType())){
}
if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
return OR_No_Viable_Function;
-
+
SourceLocation DeclLoc = Initializer->getLocStart();
- // Perform overload resolution. If it fails, return the failed result.
+ // Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
- if (OverloadingResult Result
+ if (OverloadingResult Result
= CandidateSet.BestViableFunction(S, DeclLoc, Best, true))
return Result;
Sequence.AddUserConversionStep(Function, Best->FoundDecl,
T2.getNonLValueExprType(S.Context));
- // Determine whether we need to perform derived-to-base or
+ // Determine whether we need to perform derived-to-base or
// cv-qualification adjustments.
ExprValueKind VK = VK_RValue;
if (T2->isLValueReferenceType())
bool NewDerivedToBase = false;
bool NewObjCConversion = false;
Sema::ReferenceCompareResult NewRefRelationship
- = S.CompareReferenceRelationship(DeclLoc, T1,
+ = S.CompareReferenceRelationship(DeclLoc, T1,
T2.getNonLValueExprType(S.Context),
NewDerivedToBase, NewObjCConversion);
if (NewRefRelationship == Sema::Ref_Incompatible) {
} else if (NewDerivedToBase)
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1,
- T2.getNonReferenceType().getQualifiers()),
+ T2.getNonReferenceType().getQualifiers()),
VK);
else if (NewObjCConversion)
Sequence.AddObjCObjectConversionStep(
if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
Sequence.AddQualificationConversionStep(cv1T1, VK);
-
+
Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
return OR_Success;
}
-
-/// \brief Attempt reference initialization (C++0x [dcl.init.ref])
-static void TryReferenceInitialization(Sema &S,
+
+/// \brief Attempt reference initialization (C++0x [dcl.init.ref])
+static void TryReferenceInitialization(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr *Initializer,
// type of the resulting function.
if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
DeclAccessPair Found;
- if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer,
+ if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer,
T1,
false,
Found)) {
ObjCConversion);
// C++0x [dcl.init.ref]p5:
- // A reference to type "cv1 T1" is initialized by an expression of type
+ // A reference to type "cv1 T1" is initialized by an expression of type
// "cv2 T2" as follows:
//
- // - If the reference is an lvalue reference and the initializer
+ // - If the reference is an lvalue reference and the initializer
// expression
// Note the analogous bullet points for rvlaue refs to functions. Because
// there are no function rvalues in C++, rvalue refs to functions are treated
OverloadingResult ConvOvlResult = OR_Success;
bool T1Function = T1->isFunctionType();
if (isLValueRef || T1Function) {
- if (InitCategory.isLValue() &&
+ if (InitCategory.isLValue() &&
(RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification ||
- (Kind.isCStyleOrFunctionalCast() &&
+ (Kind.isCStyleOrFunctionalCast() &&
RefRelationship == Sema::Ref_Related))) {
- // - is an lvalue (but is not a bit-field), and "cv1 T1" is
+ // - is an lvalue (but is not a bit-field), and "cv1 T1" is
// reference-compatible with "cv2 T2," or
//
- // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a
+ // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a
// bit-field when we're determining whether the reference initialization
// can occur. However, we do pay attention to whether it is a bit-field
// to decide whether we're actually binding to a temporary created from
// the bit-field.
if (DerivedToBase)
Sequence.AddDerivedToBaseCastStep(
- S.Context.getQualifiedType(T1, T2Quals),
+ S.Context.getQualifiedType(T1, T2Quals),
VK_LValue);
else if (ObjCConversion)
Sequence.AddObjCObjectConversionStep(
Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
return;
}
-
- // - has a class type (i.e., T2 is a class type), where T1 is not
- // reference-related to T2, and can be implicitly converted to an
- // lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible
- // with "cv3 T3" (this conversion is selected by enumerating the
+
+ // - has a class type (i.e., T2 is a class type), where T1 is not
+ // reference-related to T2, and can be implicitly converted to an
+ // lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible
+ // with "cv3 T3" (this conversion is selected by enumerating the
// applicable conversion functions (13.3.1.6) and choosing the best
// one through overload resolution (13.3)),
// If we have an rvalue ref to function type here, the rhs must be
// an rvalue.
if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
(isLValueRef || InitCategory.isRValue())) {
- ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind,
+ ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind,
Initializer,
/*AllowRValues=*/isRValueRef,
Sequence);
}
}
- // - Otherwise, the reference shall be an lvalue reference to a
+ // - Otherwise, the reference shall be an lvalue reference to a
// non-volatile const type (i.e., cv1 shall be const), or the reference
// shall be an rvalue reference.
if (isLValueRef && !(T1Quals.hasConst() && !T1Quals.hasVolatile())) {
// Note: functions are handled below.
if (!T1Function &&
(RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification ||
- (Kind.isCStyleOrFunctionalCast() &&
+ (Kind.isCStyleOrFunctionalCast() &&
RefRelationship == Sema::Ref_Related)) &&
(InitCategory.isXValue() ||
(InitCategory.isPRValue() && T2->isRecordType()) ||
if (!S.getLangOptions().CPlusPlus0x && !S.getLangOptions().Microsoft)
Sequence.AddExtraneousCopyToTemporary(cv2T2);
}
-
+
if (DerivedToBase)
Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals),
ValueKind);
else if (ObjCConversion)
Sequence.AddObjCObjectConversionStep(
S.Context.getQualifiedType(T1, T2Quals));
-
+
if (T1Quals != T2Quals)
Sequence.AddQualificationConversionStep(cv1T1, ValueKind);
- Sequence.AddReferenceBindingStep(cv1T1,
+ Sequence.AddReferenceBindingStep(cv1T1,
/*bindingTemporary=*/(InitCategory.isPRValue() && !T2->isArrayType()));
- return;
+ return;
}
-
- // - has a class type (i.e., T2 is a class type), where T1 is not
- // reference-related to T2, and can be implicitly converted to an
+
+ // - has a class type (i.e., T2 is a class type), where T1 is not
+ // reference-related to T2, and can be implicitly converted to an
// xvalue, class prvalue, or function lvalue of type "cv3 T3",
// where "cv1 T1" is reference-compatible with "cv3 T3",
if (T2->isRecordType()) {
Sequence.SetOverloadFailure(
InitializationSequence::FK_ReferenceInitOverloadFailed,
ConvOvlResult);
-
+
return;
}
-
+
Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
return;
}
// - Otherwise, a temporary of type "cv1 T1" is created and initialized
// from the initializer expression using the rules for a non-reference
- // copy initialization (8.5). The reference is then bound to the
+ // copy initialization (8.5). The reference is then bound to the
// temporary. [...]
// Determine whether we are allowed to call explicit constructors or
// than, cv2; otherwise, the program is ill-formed.
unsigned T1CVRQuals = T1Quals.getCVRQualifiers();
unsigned T2CVRQuals = T2Quals.getCVRQualifiers();
- if (RefRelationship == Sema::Ref_Related &&
+ if (RefRelationship == Sema::Ref_Related &&
(T1CVRQuals | T2CVRQuals) != T1CVRQuals) {
Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
return;
}
- // [...] If T1 is reference-related to T2 and the reference is an rvalue
+ // [...] If T1 is reference-related to T2 and the reference is an rvalue
// reference, the initializer expression shall not be an lvalue.
- if (RefRelationship >= Sema::Ref_Related && !isLValueRef &&
+ if (RefRelationship >= Sema::Ref_Related && !isLValueRef &&
InitCategory.isLValue()) {
Sequence.SetFailed(
InitializationSequence::FK_RValueReferenceBindingToLValue);
return;
}
-
+
Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
return;
}
/// \brief Attempt character array initialization from a string literal
-/// (C++ [dcl.init.string], C99 6.7.8).
-static void TryStringLiteralInitialization(Sema &S,
+/// (C++ [dcl.init.string], C99 6.7.8).
+static void TryStringLiteralInitialization(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr *Initializer,
/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
/// enumerates the constructors of the initialized entity and performs overload
/// resolution to select the best.
-static void TryConstructorInitialization(Sema &S,
+static void TryConstructorInitialization(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr **Args, unsigned NumArgs,
QualType DestType,
InitializationSequence &Sequence) {
Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
-
+
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
CandidateSet.clear();
-
+
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct ||
Sequence.SetFailed(InitializationSequence::FK_Incomplete);
return;
}
-
+
// The type we're converting to is a class type. Enumerate its constructors
// to see if one is suitable.
const RecordType *DestRecordType = DestType->getAs<RecordType>();
- assert(DestRecordType && "Constructor initialization requires record type");
+ assert(DestRecordType && "Constructor initialization requires record type");
CXXRecordDecl *DestRecordDecl
= cast<CXXRecordDecl>(DestRecordType->getDecl());
-
+
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl);
Con != ConEnd; ++Con) {
NamedDecl *D = *Con;
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
bool SuppressUserConversions = false;
-
+
// Find the constructor (which may be a template).
CXXConstructorDecl *Constructor = 0;
FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
else {
Constructor = cast<CXXConstructorDecl>(D);
- // If we're performing copy initialization using a copy constructor, we
+ // If we're performing copy initialization using a copy constructor, we
// suppress user-defined conversions on the arguments.
// FIXME: Move constructors?
if (Kind.getKind() == InitializationKind::IK_Copy &&
Constructor->isCopyConstructor())
SuppressUserConversions = true;
}
-
+
if (!Constructor->isInvalidDecl() &&
(AllowExplicit || !Constructor->isExplicit())) {
if (ConstructorTmpl)
Args, NumArgs, CandidateSet,
SuppressUserConversions);
}
- }
-
+ }
+
SourceLocation DeclLoc = Kind.getLocation();
-
- // Perform overload resolution. If it fails, return the failed result.
+
+ // Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
- if (OverloadingResult Result
+ if (OverloadingResult Result
= CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
- InitializationSequence::FK_ConstructorOverloadFailed,
+ InitializationSequence::FK_ConstructorOverloadFailed,
Result);
return;
}
// Add the constructor initialization step. Any cv-qualification conversion is
// subsumed by the initialization.
Sequence.AddConstructorInitializationStep(
- cast<CXXConstructorDecl>(Best->Function),
+ cast<CXXConstructorDecl>(Best->Function),
Best->FoundDecl.getAccess(),
DestType);
}
/// \brief Attempt value initialization (C++ [dcl.init]p7).
-static void TryValueInitialization(Sema &S,
+static void TryValueInitialization(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
InitializationSequence &Sequence) {
//
// To value-initialize an object of type T means:
QualType T = Entity.getType();
-
+
// -- if T is an array type, then each element is value-initialized;
while (const ArrayType *AT = S.Context.getAsArrayType(T))
T = AT->getElementType();
-
+
if (const RecordType *RT = T->getAs<RecordType>()) {
if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
// -- if T is a class type (clause 9) with a user-declared
// but Entity doesn't have a way to capture that (yet).
if (ClassDecl->hasUserDeclaredConstructor())
return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
-
+
// -- if T is a (possibly cv-qualified) non-union class type
// without a user-provided constructor, then the object is
// zero-initialized and, if T's implicitly-declared default
if ((ClassDecl->getTagKind() == TTK_Class ||
ClassDecl->getTagKind() == TTK_Struct)) {
Sequence.AddZeroInitializationStep(Entity.getType());
- return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
+ return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
}
}
}
const InitializationKind &Kind,
InitializationSequence &Sequence) {
assert(Kind.getKind() == InitializationKind::IK_Default);
-
+
// C++ [dcl.init]p6:
// To default-initialize an object of type T means:
// - if T is an array type, each element is default-initialized;
QualType DestType = Entity.getType();
while (const ArrayType *Array = S.Context.getAsArrayType(DestType))
DestType = Array->getElementType();
-
+
// - if T is a (possibly cv-qualified) class type (Clause 9), the default
// constructor for T is called (and the initialization is ill-formed if
// T has no accessible default constructor);
TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, Sequence);
return;
}
-
+
// - otherwise, no initialization is performed.
Sequence.setSequenceKind(InitializationSequence::NoInitialization);
-
+
// If a program calls for the default initialization of an object of
- // a const-qualified type T, T shall be a class type with a user-provided
+ // a const-qualified type T, T shall be a class type with a user-provided
// default constructor.
if (DestType.isConstQualified() && S.getLangOptions().CPlusPlus)
Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
/// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]),
/// which enumerates all conversion functions and performs overload resolution
/// to select the best.
-static void TryUserDefinedConversion(Sema &S,
+static void TryUserDefinedConversion(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr *Initializer,
InitializationSequence &Sequence) {
Sequence.setSequenceKind(InitializationSequence::UserDefinedConversion);
-
+
QualType DestType = Entity.getType();
assert(!DestType->isReferenceType() && "References are handled elsewhere");
QualType SourceType = Initializer->getType();
assert((DestType->isRecordType() || SourceType->isRecordType()) &&
"Must have a class type to perform a user-defined conversion");
-
+
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
CandidateSet.clear();
-
+
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
-
+
if (const RecordType *DestRecordType = DestType->getAs<RecordType>()) {
// The type we're converting to is a class type. Enumerate its constructors
// to see if there is a suitable conversion.
CXXRecordDecl *DestRecordDecl
= cast<CXXRecordDecl>(DestRecordType->getDecl());
-
+
// Try to complete the type we're converting to.
- if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {
+ if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl);
Con != ConEnd; ++Con) {
NamedDecl *D = *Con;
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
-
+
// Find the constructor (which may be a template).
CXXConstructorDecl *Constructor = 0;
FunctionTemplateDecl *ConstructorTmpl
ConstructorTmpl->getTemplatedDecl());
else
Constructor = cast<CXXConstructorDecl>(D);
-
+
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
&Initializer, 1, CandidateSet,
/*SuppressUserConversions=*/true);
}
- }
+ }
}
}
if (!S.RequireCompleteType(DeclLoc, SourceType, 0)) {
CXXRecordDecl *SourceRecordDecl
= cast<CXXRecordDecl>(SourceRecordType->getDecl());
-
+
const UnresolvedSetImpl *Conversions
= SourceRecordDecl->getVisibleConversionFunctions();
for (UnresolvedSetImpl::const_iterator I = Conversions->begin(),
- E = Conversions->end();
+ E = Conversions->end();
I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
-
+
FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
CXXConversionDecl *Conv;
if (ConvTemplate)
Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
Conv = cast<CXXConversionDecl>(D);
-
+
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
}
}
}
-
- // Perform overload resolution. If it fails, return the failed result.
+
+ // Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
= CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
Sequence.SetOverloadFailure(
- InitializationSequence::FK_UserConversionOverloadFailed,
+ InitializationSequence::FK_UserConversionOverloadFailed,
Result);
return;
}
FunctionDecl *Function = Best->Function;
-
+
if (isa<CXXConstructorDecl>(Function)) {
// Add the user-defined conversion step. Any cv-qualification conversion is
// subsumed by the initialization.
}
Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType);
-
+
// If the conversion following the call to the conversion function
// is interesting, add it as a separate step.
if (Best->FinalConversion.First || Best->FinalConversion.Second ||
unsigned NumArgs)
: FailedCandidateSet(Kind.getLocation()) {
ASTContext &Context = S.Context;
-
+
// C++0x [dcl.init]p16:
- // The semantics of initializers are as follows. The destination type is
- // the type of the object or reference being initialized and the source
+ // The semantics of initializers are as follows. The destination type is
+ // the type of the object or reference being initialized and the source
// type is the type of the initializer expression. The source type is not
- // defined when the initializer is a braced-init-list or when it is a
+ // defined when the initializer is a braced-init-list or when it is a
// parenthesized list of expressions.
QualType DestType = Entity.getType();
if (!isa<InitListExpr>(Initializer))
SourceType = Initializer->getType();
}
-
- // - If the initializer is a braced-init-list, the object is
+
+ // - If the initializer is a braced-init-list, the object is
// list-initialized (8.5.4).
if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
TryListInitialization(S, Entity, Kind, InitList, *this);
return;
}
-
+
// - If the destination type is a reference type, see 8.5.3.
if (DestType->isReferenceType()) {
// C++0x [dcl.init.ref]p1:
TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
return;
}
-
- // - If the destination type is an array of characters, an array of
- // char16_t, an array of char32_t, or an array of wchar_t, and the
+
+ // - If the destination type is an array of characters, an array of
+ // char16_t, an array of char32_t, or an array of wchar_t, and the
// initializer is a string literal, see 8.5.2.
if (Initializer && IsStringInit(Initializer, DestType, Context)) {
TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this);
return;
}
-
+
// - If the initializer is (), the object is value-initialized.
if (Kind.getKind() == InitializationKind::IK_Value ||
(Kind.getKind() == InitializationKind::IK_Direct && NumArgs == 0)) {
TryValueInitialization(S, Entity, Kind, *this);
return;
}
-
+
// Handle default initialization.
if (Kind.getKind() == InitializationKind::IK_Default) {
TryDefaultInitialization(S, Entity, Kind, *this);
return;
}
- // - Otherwise, if the destination type is an array, the program is
+ // - Otherwise, if the destination type is an array, the program is
// ill-formed.
if (const ArrayType *AT = Context.getAsArrayType(DestType)) {
if (AT->getElementType()->isAnyCharacterType())
SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
else
SetFailed(FK_ArrayNeedsInitList);
-
+
return;
}
AddCAssignmentStep(DestType);
return;
}
-
+
// - If the destination type is a (possibly cv-qualified) class type:
if (DestType->isRecordType()) {
- // - If the initialization is direct-initialization, or if it is
- // copy-initialization where the cv-unqualified version of the
- // source type is the same class as, or a derived class of, the
+ // - If the initialization is direct-initialization, or if it is
+ // copy-initialization where the cv-unqualified version of the
+ // source type is the same class as, or a derived class of, the
// class of the destination, constructors are considered. [...]
if (Kind.getKind() == InitializationKind::IK_Direct ||
(Kind.getKind() == InitializationKind::IK_Copy &&
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
S.IsDerivedFrom(SourceType, DestType))))
- TryConstructorInitialization(S, Entity, Kind, Args, NumArgs,
+ TryConstructorInitialization(S, Entity, Kind, Args, NumArgs,
Entity.getType(), *this);
- // - Otherwise (i.e., for the remaining copy-initialization cases),
+ // - Otherwise (i.e., for the remaining copy-initialization cases),
// user-defined conversion sequences that can convert from the source
- // type to the destination type or (when a conversion function is
+ // type to the destination type or (when a conversion function is
// used) to a derived class thereof are enumerated as described in
// 13.3.1.4, and the best one is chosen through overload resolution
// (13.3).
TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
return;
}
-
+
if (NumArgs > 1) {
SetFailed(FK_TooManyInitsForScalar);
return;
}
assert(NumArgs == 1 && "Zero-argument case handled above");
-
- // - Otherwise, if the source type is a (possibly cv-qualified) class
+
+ // - Otherwise, if the source type is a (possibly cv-qualified) class
// type, conversion functions are considered.
if (!SourceType.isNull() && SourceType->isRecordType()) {
TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
return;
}
-
+
// - Otherwise, the initial value of the object being initialized is the
// (possibly converted) value of the initializer expression. Standard
// conversions (Clause 4) will be used, if necessary, to convert the
- // initializer expression to the cv-unqualified version of the
+ // initializer expression to the cv-unqualified version of the
// destination type; no user-defined conversions are considered.
if (S.TryImplicitConversion(*this, Entity, Initializer,
/*SuppressUserConversions*/ true,
//===----------------------------------------------------------------------===//
// Perform initialization
//===----------------------------------------------------------------------===//
-static Sema::AssignmentAction
+static Sema::AssignmentAction
getAssignmentAction(const InitializedEntity &Entity) {
switch(Entity.getKind()) {
case InitializedEntity::EK_Variable:
return Sema::AA_Initializing;
case InitializedEntity::EK_Parameter:
- if (Entity.getDecl() &&
+ if (Entity.getDecl() &&
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
return Sema::AA_Sending;
case InitializedEntity::EK_Temporary:
// FIXME: Can we tell apart casting vs. converting?
return Sema::AA_Casting;
-
+
case InitializedEntity::EK_Member:
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_VectorElement:
case InitializedEntity::EK_Exception:
case InitializedEntity::EK_BlockElement:
return false;
-
+
case InitializedEntity::EK_Parameter:
case InitializedEntity::EK_Temporary:
return true;
}
-
+
llvm_unreachable("missed an InitializedEntity kind?");
}
case InitializedEntity::EK_VectorElement:
case InitializedEntity::EK_BlockElement:
return false;
-
+
case InitializedEntity::EK_Variable:
case InitializedEntity::EK_Parameter:
case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_Exception:
return true;
}
-
- llvm_unreachable("missed an InitializedEntity kind?");
+
+ llvm_unreachable("missed an InitializedEntity kind?");
}
/// \brief Make a (potentially elidable) temporary copy of the object
bool IsExtraneousCopy) {
// Determine which class type we're copying to.
Expr *CurInitExpr = (Expr *)CurInit.get();
- CXXRecordDecl *Class = 0;
+ CXXRecordDecl *Class = 0;
if (const RecordType *Record = T->getAs<RecordType>())
Class = cast<CXXRecordDecl>(Record->getDecl());
if (!Class)
// with the same cv-unqualified type, the copy/move operation
// can be omitted by constructing the temporary object
// directly into the target of the omitted copy/move
- //
+ //
// Note that the other three bullets are handled elsewhere. Copy
// elision for return statements and throw expressions are handled as part
- // of constructor initialization, while copy elision for exception handlers
+ // of constructor initialization, while copy elision for exception handlers
// is handled by the run-time.
bool Elidable = CurInitExpr->isTemporaryObject(S.Context, Class);
SourceLocation Loc;
case InitializedEntity::EK_Result:
Loc = Entity.getReturnLoc();
break;
-
+
case InitializedEntity::EK_Exception:
Loc = Entity.getThrowLoc();
break;
-
+
case InitializedEntity::EK_Variable:
Loc = Entity.getDecl()->getLocation();
break;
break;
}
- // Make sure that the type we are copying is complete.
+ // Make sure that the type we are copying is complete.
if (S.RequireCompleteType(Loc, T, S.PDiag(diag::err_temp_copy_incomplete)))
return move(CurInit);
S.AddOverloadCandidate(Constructor, FoundDecl,
&CurInitExpr, 1, CandidateSet);
continue;
- }
+ }
// Handle constructor templates.
FunctionTemplateDecl *ConstructorTmpl = cast<FunctionTemplateDecl>(*Con);
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, 0,
&CurInitExpr, 1, CandidateSet, true);
}
-
+
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
case OR_Success:
break;
-
+
case OR_No_Viable_Function:
S.Diag(Loc, IsExtraneousCopy && !S.isSFINAEContext()
? diag::ext_rvalue_to_reference_temp_copy_no_viable
if (!IsExtraneousCopy || S.isSFINAEContext())
return ExprError();
return move(CurInit);
-
+
case OR_Ambiguous:
S.Diag(Loc, diag::err_temp_copy_ambiguous)
<< (int)Entity.getKind() << CurInitExpr->getType()
<< CurInitExpr->getSourceRange();
CandidateSet.NoteCandidates(S, OCD_ViableCandidates, &CurInitExpr, 1);
return ExprError();
-
+
case OR_Deleted:
S.Diag(Loc, diag::err_temp_copy_deleted)
<< (int)Entity.getKind() << CurInitExpr->getType()
return S.Owned(CurInitExpr);
}
-
+
// Determine the arguments required to actually perform the
// constructor call (we might have derived-to-base conversions, or
// the copy constructor may have default arguments).
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
-
+
// If we're supposed to bind temporaries, do so.
if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
}
}
-ExprResult
+ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs);
return ExprError();
}
-
+
if (SequenceKind == DependentSequence) {
// If the declaration is a non-dependent, incomplete array type
// that has an initializer, then its type will be completed once
unsigned NumArgs = Args.size();
return S.Owned(new (S.Context) ParenListExpr(S.Context,
SourceLocation(),
- (Expr **)Args.release(),
+ (Expr **)Args.release(),
NumArgs,
SourceLocation()));
}
if (SequenceKind == NoInitialization)
return S.Owned((Expr *)0);
-
+
QualType DestType = Entity.getType().getNonReferenceType();
// FIXME: Ugly hack around the fact that Entity.getType() is not
// the same as Entity.getDecl()->getType() in cases involving type merging,
Entity.getType();
ExprResult CurInit = S.Owned((Expr *)0);
-
+
assert(!Steps.empty() && "Cannot have an empty initialization sequence");
-
- // For initialization steps that start with a single initializer,
+
+ // For initialization steps that start with a single initializer,
// grab the only argument out the Args and place it into the "current"
// initializer.
switch (Steps.front().Kind) {
CurInit = ExprResult(CurInitExpr);
break;
}
-
+
case SK_ConstructorInitialization:
case SK_ZeroInitialization:
break;
}
-
- // Walk through the computed steps for the initialization sequence,
+
+ // Walk through the computed steps for the initialization sequence,
// performing the specified conversions along the way.
bool ConstructorInitRequiresZeroInit = false;
for (step_iterator Step = step_begin(), StepEnd = step_end();
Step != StepEnd; ++Step) {
if (CurInit.isInvalid())
return ExprError();
-
+
Expr *CurInitExpr = CurInit.get();
QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType();
-
+
switch (Step->Kind) {
case SK_ResolveAddressOfOverloadedFunction:
- // Overload resolution determined which function invoke; update the
+ // Overload resolution determined which function invoke; update the
// initializer to reflect that choice.
S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl);
S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation());
Step->Function.FoundDecl,
Step->Function.Function);
break;
-
+
case SK_CastDerivedToBaseRValue:
case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue: {
// We have a derived-to-base cast that produces either an rvalue or an
// lvalue. Perform that cast.
-
+
CXXCastPath BasePath;
// Casts to inaccessible base classes are allowed with C-style casts.
bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
if (S.CheckDerivedToBaseConversion(SourceType, Step->Type,
CurInitExpr->getLocStart(),
- CurInitExpr->getSourceRange(),
+ CurInitExpr->getSourceRange(),
&BasePath, IgnoreBaseAccess))
return ExprError();
-
+
if (S.BasePathInvolvesVirtualBase(BasePath)) {
QualType T = SourceType;
if (const PointerType *Pointer = T->getAs<PointerType>())
T = Pointer->getPointeeType();
if (const RecordType *RecordTy = T->getAs<RecordType>())
- S.MarkVTableUsed(CurInitExpr->getLocStart(),
+ S.MarkVTableUsed(CurInitExpr->getLocStart(),
cast<CXXRecordDecl>(RecordTy->getDecl()));
}
&BasePath, VK));
break;
}
-
+
case SK_BindReference:
if (FieldDecl *BitField = CurInitExpr->getBitField()) {
// References cannot bind to bit fields (C++ [dcl.init.ref]p5).
PrintInitLocationNote(S, Entity);
return ExprError();
}
-
+
// Reference binding does not have any corresponding ASTs.
// Check exception specifications
return ExprError();
break;
-
+
case SK_ExtraneousCopyToTemporary:
- CurInit = CopyObject(S, Step->Type, Entity, move(CurInit),
+ CurInit = CopyObject(S, Step->Type, Entity, move(CurInit),
/*IsExtraneousCopy=*/true);
break;
MultiExprArg(&CurInitExpr, 1),
Loc, ConstructorArgs))
return ExprError();
-
+
// Build the an expression that constructs a temporary.
- CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
+ CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
move_arg(ConstructorArgs),
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
FoundFn.getAccess());
S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
-
+
CastKind = CK_ConstructorConversion;
QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
if (S.Context.hasSameUnqualifiedType(SourceType, Class) ||
S.IsDerivedFrom(SourceType, Class))
IsCopy = true;
-
+
CreatedObject = true;
} else {
// Build a call to the conversion function.
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
FoundFn);
S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
-
- // FIXME: Should we move this initialization into a separate
+
+ // FIXME: Should we move this initialization into a separate
// derived-to-base conversion? I believe the answer is "no", because
// we don't want to turn off access control here for c-style casts.
if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
// Do a little dance to make sure that CurInit has the proper
// pointer.
CurInit.release();
-
+
// Build the actual call to the conversion function.
CurInit = S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn, Conversion);
if (CurInit.isInvalid() || !CurInit.get())
return ExprError();
-
+
CastKind = CK_UserDefinedConversion;
-
+
CreatedObject = Conversion->getResultType()->isRecordType();
}
-
- bool RequiresCopy = !IsCopy &&
+
+ bool RequiresCopy = !IsCopy &&
getKind() != InitializationSequence::ReferenceBinding;
if (RequiresCopy || shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
CurInitExpr = static_cast<Expr *>(CurInit.get());
QualType T = CurInitExpr->getType();
if (const RecordType *Record = T->getAs<RecordType>()) {
- CXXDestructorDecl *Destructor
+ CXXDestructorDecl *Destructor
= S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
- S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor,
+ S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor,
S.PDiag(diag::err_access_dtor_temp) << T);
S.MarkDeclarationReferenced(CurInitExpr->getLocStart(), Destructor);
S.DiagnoseUseOfDecl(Destructor, CurInitExpr->getLocStart());
}
}
-
+
CurInitExpr = CurInit.takeAs<Expr>();
// FIXME: xvalues
CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
CurInitExpr->getType(),
CastKind, CurInitExpr, 0,
IsLvalue ? VK_LValue : VK_RValue));
-
+
if (RequiresCopy)
CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
move(CurInit), /*IsExtraneousCopy=*/false);
getAssignmentAction(Entity),
Kind.isCStyleOrFunctionalCast()))
return ExprError();
-
+
CurInit.release();
CurInit = S.Owned(CurInitExpr);
break;
}
-
+
case SK_ListInitialization: {
InitListExpr *InitList = cast<InitListExpr>(CurInitExpr);
QualType Ty = Step->Type;
unsigned NumArgs = Args.size();
CXXConstructorDecl *Constructor
= cast<CXXConstructorDecl>(Step->Function.Function);
-
+
// Build a call to the selected constructor.
ASTOwningVector<Expr*> ConstructorArgs(S);
SourceLocation Loc = (Kind.isCopyInit() && Kind.getEqualLoc().isValid())
// Determine the arguments required to actually perform the constructor
// call.
- if (S.CompleteConstructorCall(Constructor, move(Args),
+ if (S.CompleteConstructorCall(Constructor, move(Args),
Loc, ConstructorArgs))
return ExprError();
-
-
+
+
if (Entity.getKind() == InitializedEntity::EK_Temporary &&
NumArgs != 1 && // FIXME: Hack to work around cast weirdness
(Kind.getKind() == InitializationKind::IK_Direct ||
Expr **Exprs = (Expr **)ConstructorArgs.take();
S.MarkDeclarationReferenced(Loc, Constructor);
S.DiagnoseUseOfDecl(Constructor, Loc);
-
+
TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
if (!TSInfo)
TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc);
-
+
CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
Constructor,
TSInfo,
- Exprs,
+ Exprs,
NumExprs,
Kind.getParenRange(),
ConstructorInitRequiresZeroInit));
} else {
CXXConstructExpr::ConstructionKind ConstructKind =
CXXConstructExpr::CK_Complete;
-
+
if (Entity.getKind() == InitializedEntity::EK_Base) {
ConstructKind = Entity.getBaseSpecifier()->isVirtual() ?
- CXXConstructExpr::CK_VirtualBase :
+ CXXConstructExpr::CK_VirtualBase :
CXXConstructExpr::CK_NonVirtualBase;
- }
-
+ }
+
// Only get the parenthesis range if it is a direct construction.
SourceRange parenRange =
Kind.getKind() == InitializationKind::IK_Direct ?
parenRange);
else
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
- Constructor,
+ Constructor,
move_arg(ConstructorArgs),
ConstructorInitRequiresZeroInit,
ConstructKind,
S.CheckConstructorAccess(Loc, Constructor, Entity,
Step->Function.FoundDecl.getAccess());
S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Loc);
-
+
if (shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
-
+
break;
}
-
+
case SK_ZeroInitialization: {
step_iterator NextStep = Step;
++NextStep;
- if (NextStep != StepEnd &&
+ if (NextStep != StepEnd &&
NextStep->Kind == SK_ConstructorInitialization) {
// The need for zero-initialization is recorded directly into
// the call to the object's constructor within the next step.
!Kind.isImplicitValueInit()) {
TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
if (!TSInfo)
- TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type,
+ TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type,
Kind.getRange().getBegin());
CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(
bool Complained;
if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
Step->Type, SourceType,
- CurInitExpr,
+ CurInitExpr,
getAssignmentAction(Entity),
&Complained)) {
PrintInitLocationNote(S, Entity);
}
case SK_ObjCObjectConversion:
- S.ImpCastExprToType(CurInitExpr, Step->Type,
+ S.ImpCastExprToType(CurInitExpr, Step->Type,
CK_ObjCObjectLValueCast,
S.CastCategory(CurInitExpr));
CurInit.release();
S.CheckBitFieldInitialization(Kind.getLocation(),
cast<FieldDecl>(Entity.getDecl()),
CurInit.get());
-
+
return move(CurInit);
}
//===----------------------------------------------------------------------===//
// Diagnose initialization failures
//===----------------------------------------------------------------------===//
-bool InitializationSequence::Diagnose(Sema &S,
+bool InitializationSequence::Diagnose(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr **Args, unsigned NumArgs) {
if (SequenceKind != FailedSequence)
return false;
-
+
QualType DestType = Entity.getType();
switch (Failure) {
case FK_TooManyInitsForReference:
S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits)
<< SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd());
break;
-
+
case FK_ArrayNeedsInitList:
case FK_ArrayNeedsInitListOrStringLiteral:
S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list)
<< (Failure == FK_ArrayNeedsInitListOrStringLiteral);
break;
-
+
case FK_AddressOfOverloadFailed: {
DeclAccessPair Found;
- S.ResolveAddressOfOverloadedFunction(Args[0],
+ S.ResolveAddressOfOverloadedFunction(Args[0],
DestType.getNonReferenceType(),
true,
Found);
break;
}
-
+
case FK_ReferenceInitOverloadFailed:
case FK_UserConversionOverloadFailed:
switch (FailedOverloadResult) {
FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args, NumArgs);
break;
-
+
case OR_No_Viable_Function:
S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
<< Args[0]->getType() << DestType.getNonReferenceType()
<< Args[0]->getSourceRange();
FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
break;
-
+
case OR_Deleted: {
S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
<< Args[0]->getType() << DestType.getNonReferenceType()
}
break;
}
-
+
case OR_Success:
llvm_unreachable("Conversion did not fail!");
break;
}
break;
-
+
case FK_NonConstLValueReferenceBindingToTemporary:
case FK_NonConstLValueReferenceBindingToUnrelated:
- S.Diag(Kind.getLocation(),
+ S.Diag(Kind.getLocation(),
Failure == FK_NonConstLValueReferenceBindingToTemporary
? diag::err_lvalue_reference_bind_to_temporary
: diag::err_lvalue_reference_bind_to_unrelated)
<< Args[0]->getType()
<< Args[0]->getSourceRange();
break;
-
+
case FK_RValueReferenceBindingToLValue:
S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
<< DestType.getNonReferenceType() << Args[0]->getType()
<< Args[0]->getSourceRange();
break;
-
+
case FK_ReferenceInitDropsQualifiers:
S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals)
<< DestType.getNonReferenceType()
<< Args[0]->getType()
<< Args[0]->getSourceRange();
break;
-
+
case FK_ReferenceInitFailed:
S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
<< DestType.getNonReferenceType()
<< Args[0]->getType()
<< Args[0]->getSourceRange();
break;
-
+
case FK_ConversionFailed:
S.Diag(Kind.getLocation(), diag::err_init_conversion_failed)
<< (int)Entity.getKind()
if (InitListExpr *InitList = dyn_cast<InitListExpr>(Args[0]))
R = SourceRange(InitList->getInit(0)->getLocEnd(),
InitList->getLocEnd());
- else
+ else
R = SourceRange(Args[0]->getLocEnd(), Args[NumArgs - 1]->getLocEnd());
R.setBegin(S.PP.getLocForEndOfToken(R.getBegin()));
S.Diag(Kind.getLocation(), diag::err_init_list_bad_dest_type)
<< (DestType->isRecordType()) << DestType << Args[0]->getSourceRange();
break;
-
+
case FK_ConstructorOverloadFailed: {
SourceRange ArgsRange;
if (NumArgs)
- ArgsRange = SourceRange(Args[0]->getLocStart(),
+ ArgsRange = SourceRange(Args[0]->getLocStart(),
Args[NumArgs - 1]->getLocEnd());
-
+
// FIXME: Using "DestType" for the entity we're printing is probably
// bad.
switch (FailedOverloadResult) {
FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
Args, NumArgs);
break;
-
+
case OR_No_Viable_Function:
if (Kind.getKind() == InitializationKind::IK_Default &&
(Entity.getKind() == InitializedEntity::EK_Base ||
if (const RecordType *Record
= Entity.getType()->getAs<RecordType>())
- S.Diag(Record->getDecl()->getLocation(),
+ S.Diag(Record->getDecl()->getLocation(),
diag::note_previous_decl)
<< S.Context.getTagDeclType(Record->getDecl());
}
<< DestType << ArgsRange;
FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
break;
-
+
case OR_Deleted: {
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
<< true << DestType << ArgsRange;
}
break;
}
-
+
case OR_Success:
llvm_unreachable("Conversion did not fail!");
break;
}
break;
}
-
+
case FK_DefaultInitOfConst:
if (Entity.getKind() == InitializedEntity::EK_Member &&
isa<CXXConstructorDecl>(S.CurContext)) {
<< DestType << (bool)DestType->getAs<RecordType>();
}
break;
-
+
case FK_Incomplete:
- S.RequireCompleteType(Kind.getLocation(), DestType,
+ S.RequireCompleteType(Kind.getLocation(), DestType,
diag::err_init_incomplete_type);
- break;
+ break;
}
-
+
PrintInitLocationNote(S, Entity);
return true;
}
case FK_TooManyInitsForReference:
OS << "too many initializers for reference";
break;
-
+
case FK_ArrayNeedsInitList:
OS << "array requires initializer list";
break;
-
+
case FK_ArrayNeedsInitListOrStringLiteral:
OS << "array requires initializer list or string literal";
break;
-
+
case FK_AddressOfOverloadFailed:
OS << "address of overloaded function failed";
break;
-
+
case FK_ReferenceInitOverloadFailed:
OS << "overload resolution for reference initialization failed";
break;
-
+
case FK_NonConstLValueReferenceBindingToTemporary:
OS << "non-const lvalue reference bound to temporary";
break;
-
+
case FK_NonConstLValueReferenceBindingToUnrelated:
OS << "non-const lvalue reference bound to unrelated type";
break;
-
+
case FK_RValueReferenceBindingToLValue:
OS << "rvalue reference bound to an lvalue";
break;
-
+
case FK_ReferenceInitDropsQualifiers:
OS << "reference initialization drops qualifiers";
break;
-
+
case FK_ReferenceInitFailed:
OS << "reference initialization failed";
break;
-
+
case FK_ConversionFailed:
OS << "conversion failed";
break;
-
+
case FK_TooManyInitsForScalar:
OS << "too many initializers for scalar";
break;
-
+
case FK_ReferenceBindingToInitList:
OS << "referencing binding to initializer list";
break;
-
+
case FK_InitListBadDestinationType:
OS << "initializer list for non-aggregate, non-scalar type";
break;
-
+
case FK_UserConversionOverloadFailed:
OS << "overloading failed for user-defined conversion";
break;
-
+
case FK_ConstructorOverloadFailed:
OS << "constructor overloading failed";
break;
-
+
case FK_DefaultInitOfConst:
OS << "default initialization of a const variable";
break;
-
+
case FK_Incomplete:
OS << "initialization of incomplete type";
break;
- }
+ }
OS << '\n';
return;
}
-
+
case DependentSequence:
OS << "Dependent sequence: ";
return;
-
+
case UserDefinedConversion:
OS << "User-defined conversion sequence: ";
break;
-
+
case ConstructorInitialization:
OS << "Constructor initialization sequence: ";
break;
-
+
case ReferenceBinding:
OS << "Reference binding: ";
break;
-
+
case ListInitialization:
OS << "List initialization: ";
break;
case ZeroInitialization:
OS << "Zero initialization\n";
return;
-
+
case NoInitialization:
OS << "No initialization\n";
return;
-
+
case StandardConversion:
OS << "Standard conversion: ";
break;
-
+
case CAssignment:
OS << "C assignment: ";
break;
-
+
case StringInit:
OS << "String initialization: ";
break;
}
-
+
for (step_iterator S = step_begin(), SEnd = step_end(); S != SEnd; ++S) {
if (S != step_begin()) {
OS << " -> ";
}
-
+
switch (S->Kind) {
case SK_ResolveAddressOfOverloadedFunction:
OS << "resolve address of overloaded function";
break;
-
+
case SK_CastDerivedToBaseRValue:
OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
break;
-
+
case SK_CastDerivedToBaseXValue:
OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")";
break;
-
+
case SK_CastDerivedToBaseLValue:
OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
break;
-
+
case SK_BindReference:
OS << "bind reference to lvalue";
break;
-
+
case SK_BindReferenceToTemporary:
OS << "bind reference to a temporary";
break;
-
+
case SK_ExtraneousCopyToTemporary:
OS << "extraneous C++03 copy to temporary";
break;
case SK_QualificationConversionLValue:
OS << "qualification conversion (lvalue)";
break;
-
+
case SK_ConversionSequence:
OS << "implicit conversion sequence (";
S->ICS->DebugPrint(); // FIXME: use OS
OS << ")";
break;
-
+
case SK_ListInitialization:
OS << "list initialization";
break;
-
+
case SK_ConstructorInitialization:
OS << "constructor initialization";
break;
-
+
case SK_ZeroInitialization:
OS << "zero initialization";
break;
-
+
case SK_CAssignment:
OS << "C assignment";
break;
-
+
case SK_StringInit:
OS << "string initialization";
break;
//===----------------------------------------------------------------------===//
// Initialization helper functions
//===----------------------------------------------------------------------===//
-ExprResult
+ExprResult
Sema::PerformCopyInitialization(const InitializedEntity &Entity,
SourceLocation EqualLoc,
ExprResult Init) {
UnqualUsingDirectiveSet() {}
void visitScopeChain(Scope *S, Scope *InnermostFileScope) {
- // C++ [namespace.udir]p1:
+ // C++ [namespace.udir]p1:
// During unqualified name lookup, the names appear as if they
// were declared in the nearest enclosing namespace which contains
// both the using-directive and the nominated namespace.
} else {
Scope::udir_iterator I = S->using_directives_begin(),
End = S->using_directives_end();
-
+
for (; I != End; ++I)
visit(*I, InnermostFileDC);
}
while (!Common->Encloses(EffectiveDC))
Common = Common->getParent();
Common = Common->getPrimaryContext();
-
+
list.push_back(UnqualUsingEntry(UD->getNominatedNamespace(), Common));
}
}
typedef ListTy::const_iterator const_iterator;
-
+
const_iterator begin() const { return list.begin(); }
const_iterator end() const { return list.end(); }
case Sema::LookupObjCProtocolName:
IDNS = Decl::IDNS_ObjCProtocol;
break;
-
+
case Sema::LookupAnyName:
- IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member
+ IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member
| Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
| Decl::IDNS_Type;
break;
/// Resolves the result kind of this lookup.
void LookupResult::resolveKind() {
unsigned N = Decls.size();
-
+
// Fast case: no possible ambiguity.
if (N == 0) {
assert(ResultKind == NotFound || ResultKind == NotFoundInCurrentInstantiation);
llvm::SmallPtrSet<NamedDecl*, 16> Unique;
llvm::SmallPtrSet<QualType, 16> UniqueTypes;
-
+
bool Ambiguous = false;
bool HasTag = false, HasFunction = false, HasNonFunction = false;
bool HasFunctionTemplate = false, HasUnresolved = false;
unsigned UniqueTagIndex = 0;
-
+
unsigned I = 0;
while (I < N) {
NamedDecl *D = Decls[I]->getUnderlyingDecl();
}
}
}
-
+
if (!Unique.insert(D)) {
// If it's not unique, pull something off the back (and
// continue at this index).
Decls[I] = Decls[--N];
continue;
- }
-
+ }
+
// Otherwise, do some decl type analysis and then continue.
if (isa<UnresolvedUsingValueDecl>(D)) {
Out << Decls.size() << " result(s)";
if (isAmbiguous()) Out << ", ambiguous";
if (Paths) Out << ", base paths present";
-
+
for (iterator I = begin(), E = end(); I != E; ++I) {
Out << "\n";
(*I)->print(Out, 2);
if (S.getLangOptions().CPlusPlus &&
S.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
return false;
-
- if (NamedDecl *D = S.LazilyCreateBuiltin((IdentifierInfo *)II,
- BuiltinID, S.TUScope,
+
+ if (NamedDecl *D = S.LazilyCreateBuiltin((IdentifierInfo *)II,
+ BuiltinID, S.TUScope,
R.isForRedeclaration(),
R.getNameLoc())) {
R.addDecl(D);
// Don't do it if the class is invalid.
if (Class->isInvalidDecl())
return false;
-
+
// We need to have a definition for the class.
if (!Class->getDefinition() || Class->isDependentContext())
return false;
-
+
// We can't be in the middle of defining the class.
if (const RecordType *RecordTy
= Context.getTypeDeclType(Class)->getAs<RecordType>())
return !RecordTy->isBeingDefined();
-
+
return false;
}
// If the default constructor has not yet been declared, do so now.
if (!Class->hasDeclaredDefaultConstructor())
DeclareImplicitDefaultConstructor(Class);
-
+
// If the copy constructor has not yet been declared, do so now.
if (!Class->hasDeclaredCopyConstructor())
DeclareImplicitCopyConstructor(Class);
-
+
// If the copy assignment operator has not yet been declared, do so now.
if (!Class->hasDeclaredCopyAssignment())
DeclareImplicitCopyAssignment(Class);
// If the destructor has not yet been declared, do so now.
if (!Class->hasDeclaredDestructor())
- DeclareImplicitDestructor(Class);
+ DeclareImplicitDestructor(Class);
}
-/// \brief Determine whether this is the name of an implicitly-declared
+/// \brief Determine whether this is the name of an implicitly-declared
/// special member function.
static bool isImplicitlyDeclaredMemberFunctionName(DeclarationName Name) {
switch (Name.getNameKind()) {
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
return true;
-
+
case DeclarationName::CXXOperatorName:
return Name.getCXXOverloadedOperator() == OO_Equal;
-
+
default:
- break;
+ break;
}
-
+
return false;
}
/// \brief If there are any implicit member functions with the given name
/// that need to be declared in the given declaration context, do so.
-static void DeclareImplicitMemberFunctionsWithName(Sema &S,
+static void DeclareImplicitMemberFunctionsWithName(Sema &S,
DeclarationName Name,
const DeclContext *DC) {
if (!DC)
return;
-
+
switch (Name.getNameKind()) {
case DeclarationName::CXXConstructorName:
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
S.DeclareImplicitCopyConstructor(const_cast<CXXRecordDecl *>(Record));
}
break;
-
+
case DeclarationName::CXXDestructorName:
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
if (Record->getDefinition() && !Record->hasDeclaredDestructor() &&
CanDeclareSpecialMemberFunction(S.Context, Record))
S.DeclareImplicitDestructor(const_cast<CXXRecordDecl *>(Record));
break;
-
+
case DeclarationName::CXXOperatorName:
if (Name.getCXXOverloadedOperator() != OO_Equal)
break;
-
+
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
if (Record->getDefinition() && !Record->hasDeclaredCopyAssignment() &&
CanDeclareSpecialMemberFunction(S.Context, Record))
S.DeclareImplicitCopyAssignment(const_cast<CXXRecordDecl *>(Record));
break;
-
+
default:
- break;
+ break;
}
}
// Lazily declare C++ special member functions.
if (S.getLangOptions().CPlusPlus)
DeclareImplicitMemberFunctionsWithName(S, R.getLookupName(), DC);
-
+
// Perform lookup into this declaration context.
DeclContext::lookup_const_iterator I, E;
for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I) {
return Found;
// C++ [temp.mem]p6:
- // A specialization of a conversion function template is not found by
+ // A specialization of a conversion function template is not found by
// name lookup. Instead, any conversion function templates visible in the
// context of the use are considered. [...]
const CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
return Found;
const UnresolvedSetImpl *Unresolved = Record->getConversionFunctions();
- for (UnresolvedSetImpl::iterator U = Unresolved->begin(),
+ for (UnresolvedSetImpl::iterator U = Unresolved->begin(),
UEnd = Unresolved->end(); U != UEnd; ++U) {
FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(*U);
if (!ConvTemplate)
continue;
-
+
// When we're performing lookup for the purposes of redeclaration, just
- // add the conversion function template. When we deduce template
- // arguments for specializations, we'll end up unifying the return
+ // add the conversion function template. When we deduce template
+ // arguments for specializations, we'll end up unifying the return
// type of the new declaration with the type of the function template.
if (R.isForRedeclaration()) {
R.addDecl(ConvTemplate);
Found = true;
continue;
}
-
+
// C++ [temp.mem]p6:
- // [...] For each such operator, if argument deduction succeeds
- // (14.9.2.3), the resulting specialization is used as if found by
+ // [...] For each such operator, if argument deduction succeeds
+ // (14.9.2.3), the resulting specialization is used as if found by
// name lookup.
//
// When referencing a conversion function for any purpose other than
// a redeclaration (such that we'll be building an expression with the
- // result), perform template argument deduction and place the
+ // result), perform template argument deduction and place the
// specialization into the result set. We do this to avoid forcing all
// callers to perform special deduction for conversion functions.
TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
FunctionDecl *Specialization = 0;
-
- const FunctionProtoType *ConvProto
+
+ const FunctionProtoType *ConvProto
= ConvTemplate->getTemplatedDecl()->getType()->getAs<FunctionProtoType>();
assert(ConvProto && "Nonsensical conversion function template type");
QualType ExpectedType
= R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(),
0, 0, EPI);
-
+
// Perform template argument deduction against the type that we would
// expect the function to have.
if (R.getSema().DeduceTemplateArguments(ConvTemplate, 0, ExpectedType,
// Performs C++ unqualified lookup into the given file context.
static bool
-CppNamespaceLookup(Sema &S, LookupResult &R, ASTContext &Context,
+CppNamespaceLookup(Sema &S, LookupResult &R, ASTContext &Context,
DeclContext *NS, UnqualUsingDirectiveSet &UDirs) {
assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!");
static std::pair<DeclContext *, bool> findOuterContext(Scope *S) {
DeclContext *DC = static_cast<DeclContext *>(S->getEntity());
DeclContext *Lexical = 0;
- for (Scope *OuterS = S->getParent(); OuterS;
+ for (Scope *OuterS = S->getParent(); OuterS;
OuterS = OuterS->getParent()) {
if (OuterS->getEntity()) {
Lexical = static_cast<DeclContext *>(OuterS->getEntity());
//
// Example:
//
- // namespace N {
- // class C { };
+ // namespace N {
+ // class C { };
//
// template<class T> class B {
// void f(T);
- // };
+ // };
// }
//
// template<class C> void N::B<C>::f(C) {
//
// In this example, the lexical context we return is the
// TranslationUnit, while the semantic context is the namespace N.
- if (!Lexical || !DC || !S->getParent() ||
+ if (!Lexical || !DC || !S->getParent() ||
!S->getParent()->isTemplateParamScope())
return std::make_pair(Lexical, false);
- // Find the outermost template parameter scope.
+ // Find the outermost template parameter scope.
// For the example, this is the scope for the template parameters of
// template<class C>.
Scope *OutermostTemplateScope = S->getParent();
while (OutermostTemplateScope->getParent() &&
OutermostTemplateScope->getParent()->isTemplateParamScope())
OutermostTemplateScope = OutermostTemplateScope->getParent();
-
+
// Find the namespace context in which the original scope occurs. In
// the example, this is namespace N.
DeclContext *Semantic = DC;
while (!Semantic->isFileContext())
Semantic = Semantic->getParent();
-
+
// Find the declaration context just outside of the template
// parameter scope. This is the context in which the template is
// being lexically declaration (a namespace context). In the
if (DeclContext *DC = static_cast<DeclContext *>(PreS->getEntity()))
DeclareImplicitMemberFunctionsWithName(*this, Name, DC);
}
-
+
// Implicitly declare member functions with the name we're looking for, if in
// fact we are in a scope where it matters.
if (ObjCInterfaceDecl *Class = Method->getClassInterface()) {
ObjCInterfaceDecl *ClassDeclared;
if (ObjCIvarDecl *Ivar = Class->lookupInstanceVariable(
- Name.getAsIdentifierInfo(),
+ Name.getAsIdentifierInfo(),
ClassDeclared)) {
if (R.isAcceptableDecl(Ivar)) {
R.addDecl(Ivar);
Ctx = OutsideOfTemplateParamDC;
OutsideOfTemplateParamDC = 0;
}
-
+
if (Ctx) {
DeclContext *OuterCtx;
bool SearchAfterTemplateScope;
// non-transparent context.
if (Ctx->isTransparentContext())
continue;
-
+
// If we have a context, and it's not a context stashed in the
// template parameter scope for an out-of-line definition, also
// look into that context.
if (!(Found && S && S->isTemplateParamScope())) {
assert(Ctx->isFileContext() &&
"We should have been looking only at file context here already.");
-
+
// Look into context considering using-directives.
if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs))
Found = true;
}
-
+
if (Found) {
R.resolveKind();
return true;
}
-
+
if (R.isForRedeclaration() && !Ctx->isTransparentContext())
return false;
}
}
/// \brief Callback that looks for any member of a class with the given name.
-static bool LookupAnyMember(const CXXBaseSpecifier *Specifier,
+static bool LookupAnyMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *Name) {
RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
-
+
DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
Path.Decls = BaseRecord->lookup(N);
return Path.Decls.first != Path.Decls.second;
}
-/// \brief Determine whether the given set of member declarations contains only
+/// \brief Determine whether the given set of member declarations contains only
/// static members, nested types, and enumerators.
template<typename InputIterator>
static bool HasOnlyStaticMembers(InputIterator First, InputIterator Last) {
Decl *D = (*First)->getUnderlyingDecl();
if (isa<VarDecl>(D) || isa<TypeDecl>(D) || isa<EnumConstantDecl>(D))
return true;
-
+
if (isa<CXXMethodDecl>(D)) {
// Determine whether all of the methods are static.
bool AllMethodsAreStatic = true;
for(; First != Last; ++First) {
D = (*First)->getUnderlyingDecl();
-
+
if (!isa<CXXMethodDecl>(D)) {
assert(isa<TagDecl>(D) && "Non-function must be a tag decl");
break;
}
-
+
if (!cast<CXXMethodDecl>(D)->isStatic()) {
AllMethodsAreStatic = false;
break;
}
}
-
+
if (AllMethodsAreStatic)
return true;
}
/// search. If the lookup criteria permits, name lookup may also search
/// in the parent contexts or (for C++ classes) base classes.
///
-/// \param InUnqualifiedLookup true if this is qualified name lookup that
+/// \param InUnqualifiedLookup true if this is qualified name lookup that
/// occurs as part of unqualified name lookup.
///
/// \returns true if lookup succeeded, false if it failed.
// If we're performing qualified name lookup into a dependent class,
// then we are actually looking into a current instantiation. If we have any
- // dependent base classes, then we either have to delay lookup until
+ // dependent base classes, then we either have to delay lookup until
// template instantiation time (at which point all bases will be available)
// or we have to fail.
if (!InUnqualifiedLookup && LookupRec->isDependentContext() &&
R.setNotFoundInCurrentInstantiation();
return false;
}
-
+
// Perform lookup into our base classes.
CXXBasePaths Paths;
Paths.setOrigin(LookupRec);
case LookupRedeclarationWithLinkage:
BaseCallback = &CXXRecordDecl::FindOrdinaryMember;
break;
-
+
case LookupTagName:
BaseCallback = &CXXRecordDecl::FindTagMember;
break;
case LookupAnyName:
BaseCallback = &LookupAnyMember;
break;
-
+
case LookupUsingDeclName:
// This lookup is for redeclarations only.
-
+
case LookupOperatorName:
case LookupNamespaceName:
case LookupObjCProtocolName:
// These lookups will never find a member in a C++ class (or base class).
return false;
-
+
case LookupNestedNameSpecifierName:
BaseCallback = &CXXRecordDecl::FindNestedNameSpecifierMember;
break;
}
-
+
if (!LookupRec->lookupInBases(BaseCallback,
R.getLookupName().getAsOpaquePtr(), Paths))
return false;
QualType SubobjectType;
int SubobjectNumber = 0;
AccessSpecifier SubobjectAccess = AS_none;
-
+
for (CXXBasePaths::paths_iterator Path = Paths.begin(), PathEnd = Paths.end();
Path != PathEnd; ++Path) {
const CXXBasePathElement &PathElement = Path->back();
// Pick the best (i.e. most permissive i.e. numerically lowest) access
// across all paths.
SubobjectAccess = std::min(SubobjectAccess, Path->Access);
-
+
// Determine whether we're looking at a distinct sub-object or not.
if (SubobjectType.isNull()) {
// This is the first subobject we've looked at. Record its type.
SubobjectType = Context.getCanonicalType(PathElement.Base->getType());
SubobjectNumber = PathElement.SubobjectNumber;
continue;
- }
-
+ }
+
if (SubobjectType
!= Context.getCanonicalType(PathElement.Base->getType())) {
// We found members of the given name in two subobjects of
CXXBasePaths::paths_iterator FirstPath = Paths.begin();
DeclContext::lookup_iterator FirstD = FirstPath->Decls.first;
DeclContext::lookup_iterator CurrentD = Path->Decls.first;
-
+
while (FirstD != FirstPath->Decls.second &&
CurrentD != Path->Decls.second) {
if ((*FirstD)->getUnderlyingDecl()->getCanonicalDecl() !=
(*CurrentD)->getUnderlyingDecl()->getCanonicalDecl())
break;
-
+
++FirstD;
++CurrentD;
}
-
+
if (FirstD == FirstPath->Decls.second &&
CurrentD == Path->Decls.second)
continue;
}
-
+
R.setAmbiguousBaseSubobjectTypes(Paths);
return true;
- }
-
+ }
+
if (SubobjectNumber != PathElement.SubobjectNumber) {
// We have a different subobject of the same type.
// has more than one base class subobject of type T.
if (HasOnlyStaticMembers(Path->Decls.first, Path->Decls.second))
continue;
-
+
// We have found a nonstatic member name in multiple, distinct
// subobjects. Name lookup is ambiguous.
R.setAmbiguousBaseSubobjects(Paths);
Diag(NameLoc, diag::err_ambiguous_member_multiple_subobjects)
<< Name << SubobjectType << getAmbiguousPathsDisplayString(*Paths)
<< LookupRange;
-
+
DeclContext::lookup_iterator Found = Paths->front().Decls.first;
while (isa<CXXMethodDecl>(*Found) &&
cast<CXXMethodDecl>(*Found)->isStatic())
++Found;
-
+
Diag((*Found)->getLocation(), diag::note_ambiguous_member_found);
-
+
return true;
}
case LookupResult::AmbiguousBaseSubobjectTypes: {
Diag(NameLoc, diag::err_ambiguous_member_multiple_subobject_types)
<< Name << LookupRange;
-
+
CXXBasePaths *Paths = Result.getBasePaths();
std::set<Decl *> DeclsPrinted;
for (CXXBasePaths::paths_iterator Path = Paths->begin(),
case LookupResult::AmbiguousReference: {
Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
-
+
LookupResult::iterator DI = Result.begin(), DE = Result.end();
for (; DI != DE; ++DI)
Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
addAssociatedClassesAndNamespaces(Result, Arg.getAsType());
break;
- case TemplateArgument::Template:
+ case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion: {
// [...] the namespaces in which any template template arguments are
// defined; and the classes in which any member templates used as
}
break;
}
-
+
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::Expression:
}
/// \brief Find the protocol with the given name, if any.
-ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II,
+ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II,
SourceLocation IdLoc) {
Decl *D = LookupSingleName(TUScope, II, IdLoc,
LookupObjCProtocolName);
if (!Class->hasDeclaredCopyConstructor())
DeclareImplicitCopyConstructor(Class);
}
-
+
CanQualType T = Context.getCanonicalType(Context.getTypeDeclType(Class));
DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(T);
return Class->lookup(Name);
/// \brief Look for the destructor of the given class.
///
-/// During semantic analysis, this routine should be used in lieu of
+/// During semantic analysis, this routine should be used in lieu of
/// CXXRecordDecl::getDestructor().
///
/// \returns The destructor for this class.
/// of declarations.
class ShadowMapEntry {
typedef llvm::SmallVector<NamedDecl *, 4> DeclVector;
-
+
/// \brief Contains either the solitary NamedDecl * or a vector
/// of declarations.
llvm::PointerUnion<NamedDecl *, DeclVector*> DeclOrVector;
DeclOrVector = ND;
return;
}
-
+
if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
// 1 -> 2 elements: create the vector of results and push in the
// existing declaration.
}
}
-VisibleDeclsRecord::ShadowMapEntry::iterator
+VisibleDeclsRecord::ShadowMapEntry::iterator
VisibleDeclsRecord::ShadowMapEntry::begin() {
if (DeclOrVector.isNull())
return 0;
return DeclOrVector.get<DeclVector *>()->begin();
}
-VisibleDeclsRecord::ShadowMapEntry::iterator
+VisibleDeclsRecord::ShadowMapEntry::iterator
VisibleDeclsRecord::ShadowMapEntry::end() {
if (DeclOrVector.isNull())
return 0;
NamedDecl *VisibleDeclsRecord::checkHidden(NamedDecl *ND) {
// Look through using declarations.
ND = ND->getUnderlyingDecl();
-
+
unsigned IDNS = ND->getIdentifierNamespace();
std::list<ShadowMap>::reverse_iterator SM = ShadowMaps.rbegin();
for (std::list<ShadowMap>::reverse_iterator SMEnd = ShadowMaps.rend();
if (Pos == SM->end())
continue;
- for (ShadowMapEntry::iterator I = Pos->second.begin(),
+ for (ShadowMapEntry::iterator I = Pos->second.begin(),
IEnd = Pos->second.end();
I != IEnd; ++I) {
// A tag declaration does not hide a non-tag declaration.
if ((*I)->hasTagIdentifierNamespace() &&
- (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
+ (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
Decl::IDNS_ObjCProtocol)))
continue;
ND->isFunctionOrFunctionTemplate() &&
SM == ShadowMaps.rbegin())
continue;
-
+
// We've found a declaration that hides this one.
return *I;
}
// Make sure we don't visit the same context twice.
if (Visited.visitedContext(Ctx->getPrimaryContext()))
return;
-
+
if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx))
Result.getSema().ForceDeclarationOfImplicitMembers(Class);
// Enumerate all of the results in this context.
- for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
+ for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
CurCtx = CurCtx->getNextContext()) {
- for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
+ for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
DEnd = CurCtx->decls_end();
D != DEnd; ++D) {
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {
ShadowContextRAII Shadow(Visited);
DeclContext::udir_iterator I, E;
for (llvm::tie(I, E) = Ctx->getUsingDirectives(); I != E; ++I) {
- LookupVisibleDecls((*I)->getNominatedNamespace(), Result,
+ LookupVisibleDecls((*I)->getNominatedNamespace(), Result,
QualifiedNameLookup, InBaseClass, Consumer, Visited);
}
}
BEnd = Record->bases_end();
B != BEnd; ++B) {
QualType BaseType = B->getType();
-
+
// Don't look into dependent bases, because name lookup can't look
// there anyway.
if (BaseType->isDependentType())
continue;
-
+
const RecordType *Record = BaseType->getAs<RecordType>();
if (!Record)
continue;
-
+
// FIXME: It would be nice to be able to determine whether referencing
// a particular member would be ambiguous. For example, given
//
// or
//
// c->A::member
-
+
// Find results in this base class (and its bases).
ShadowContextRAII Shadow(Visited);
LookupVisibleDecls(Record->getDecl(), Result, QualifiedNameLookup,
true, Consumer, Visited);
}
}
-
+
// Traverse the contexts of Objective-C classes.
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Ctx)) {
// Traverse categories.
for (ObjCCategoryDecl *Category = IFace->getCategoryList();
Category; Category = Category->getNextClassCategory()) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(Category, Result, QualifiedNameLookup, false,
+ LookupVisibleDecls(Category, Result, QualifiedNameLookup, false,
Consumer, Visited);
}
I = IFace->all_referenced_protocol_begin(),
E = IFace->all_referenced_protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+ LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
Visited);
}
LookupVisibleDecls(IFace->getSuperClass(), Result, QualifiedNameLookup,
true, Consumer, Visited);
}
-
+
// If there is an implementation, traverse it. We do this to find
// synthesized ivars.
if (IFace->getImplementation()) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(IFace->getImplementation(), Result,
+ LookupVisibleDecls(IFace->getImplementation(), Result,
QualifiedNameLookup, true, Consumer, Visited);
}
} else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) {
for (ObjCProtocolDecl::protocol_iterator I = Protocol->protocol_begin(),
E = Protocol->protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+ LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
Visited);
}
} else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) {
for (ObjCCategoryDecl::protocol_iterator I = Category->protocol_begin(),
E = Category->protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+ LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
Visited);
}
-
+
// If there is an implementation, traverse it.
if (Category->getImplementation()) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(Category->getImplementation(), Result,
+ LookupVisibleDecls(Category->getImplementation(), Result,
QualifiedNameLookup, true, Consumer, Visited);
- }
+ }
}
}
if (!S)
return;
- if (!S->getEntity() ||
- (!S->getParent() &&
+ if (!S->getEntity() ||
+ (!S->getParent() &&
!Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||
((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
// Walk through the declarations in this Scope.
}
}
}
-
+
// FIXME: C++ [temp.local]p8
DeclContext *Entity = 0;
if (S->getEntity()) {
// where we hit the context stored in the next outer scope.
Entity = (DeclContext *)S->getEntity();
DeclContext *OuterCtx = findOuterContext(S).first; // FIXME
-
+
for (DeclContext *Ctx = Entity; Ctx && !Ctx->Equals(OuterCtx);
Ctx = Ctx->getLookupParent()) {
if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(Ctx)) {
LookupResult IvarResult(Result.getSema(), Result.getLookupName(),
Result.getNameLoc(), Sema::LookupMemberName);
if (ObjCInterfaceDecl *IFace = Method->getClassInterface()) {
- LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false,
+ LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false,
/*InBaseClass=*/false, Consumer, Visited);
-
+
// Look for properties from which we can synthesize ivars, if
// permitted.
if (Result.getSema().getLangOptions().ObjCNonFragileABI2 &&
IFace->getImplementation() &&
Result.getLookupKind() == Sema::LookupOrdinaryName) {
- for (ObjCInterfaceDecl::prop_iterator
+ for (ObjCInterfaceDecl::prop_iterator
P = IFace->prop_begin(),
PEnd = IFace->prop_end();
P != PEnd; ++P) {
Consumer.FoundDecl(*P, Visited.checkHidden(*P), false);
Visited.add(*P);
}
- }
- }
+ }
+ }
}
}
if (Ctx->isFunctionOrMethod())
continue;
-
- LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/false,
+
+ LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/false,
/*InBaseClass=*/false, Consumer, Visited);
}
} else if (!S->getParent()) {
// FIXME: We would like the translation unit's Scope object to point to the
// translation unit, so we don't need this special "if" branch. However,
// doing so would force the normal C++ name-lookup code to look into the
- // translation unit decl when the IdentifierInfo chains would suffice.
+ // translation unit decl when the IdentifierInfo chains would suffice.
// Once we fix that problem (which is part of a more general "don't look
// in DeclContexts unless we have to" optimization), we can eliminate this.
Entity = Result.getSema().Context.getTranslationUnitDecl();
- LookupVisibleDecls(Entity, Result, /*QualifiedNameLookup=*/false,
+ LookupVisibleDecls(Entity, Result, /*QualifiedNameLookup=*/false,
/*InBaseClass=*/false, Consumer, Visited);
- }
-
+ }
+
if (Entity) {
// Lookup visible declarations in any namespaces found by using
// directives.
llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(Entity);
for (; UI != UEnd; ++UI)
LookupVisibleDecls(const_cast<DeclContext *>(UI->getNominatedNamespace()),
- Result, /*QualifiedNameLookup=*/false,
+ Result, /*QualifiedNameLookup=*/false,
/*InBaseClass=*/false, Consumer, Visited);
}
if (!IncludeGlobalScope)
Visited.visitedContext(Context.getTranslationUnitDecl());
ShadowContextRAII Shadow(Visited);
- ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true,
+ ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true,
/*InBaseClass=*/false, Consumer, Visited);
}
/// \brief The best edit distance found so far.
unsigned BestEditDistance;
-
+
public:
explicit TypoCorrectionConsumer(IdentifierInfo *Typo)
- : Typo(Typo->getName()),
+ : Typo(Typo->getName()),
BestEditDistance((std::numeric_limits<unsigned>::max)()) { }
virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass);
return BestResults[Name];
}
- unsigned getBestEditDistance() const { return BestEditDistance; }
+ unsigned getBestEditDistance() const { return BestEditDistance; }
};
}
-void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
bool InBaseClass) {
// Don't consider hidden names for typo correction.
if (Hiding)
return;
-
+
// Only consider entities with identifiers for names, ignoring
// special names (constructors, overloaded operators, selectors,
// etc.).
void TypoCorrectionConsumer::FoundName(llvm::StringRef Name) {
using namespace std;
-
+
// Use a simple length-based heuristic to determine the minimum possible
// edit distance. If the minimum isn't good enough, bail out early.
unsigned MinED = abs((int)Name.size() - (int)Typo.size());
if (MinED > BestEditDistance || (MinED && Typo.size() / MinED < 3))
return;
-
+
// Compute an upper bound on the allowable edit distance, so that the
// edit-distance algorithm can short-circuit.
unsigned UpperBound = min(unsigned((Typo.size() + 2) / 3), BestEditDistance);
-
+
// Compute the edit distance between the typo and the name of this
// entity. If this edit distance is not worse than the best edit
// distance we've seen so far, add it to the list of results.
unsigned ED = Typo.edit_distance(Name, true, UpperBound);
if (ED == 0)
return;
-
+
if (ED < BestEditDistance) {
// This result is better than any we've seen before; clear out
// the previous results.
// ignore it.
return;
}
-
+
// Add this name to the list of results. By not assigning a value, we
// keep the current value if we've seen this name before (either as a
// keyword or as a declaration), or get the default value (not a keyword)
// if we haven't seen it before.
- (void)BestResults[Name];
+ (void)BestResults[Name];
}
-void TypoCorrectionConsumer::addKeywordResult(ASTContext &Context,
+void TypoCorrectionConsumer::addKeywordResult(ASTContext &Context,
llvm::StringRef Keyword) {
// Compute the edit distance between the typo and this keyword.
// If this edit distance is not worse than the best edit
// ignore it.
return;
}
-
+
BestResults[Keyword] = true;
}
Res.suppressDiagnostics();
Res.clear();
Res.setLookupName(Name);
- if (MemberContext) {
+ if (MemberContext) {
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(MemberContext)) {
if (CTC == Sema::CTC_ObjCIvarLookup) {
if (ObjCIvarDecl *Ivar = Class->lookupInstanceVariable(Name)) {
return;
}
}
-
+
if (ObjCPropertyDecl *Prop = Class->FindPropertyDeclaration(Name)) {
Res.addDecl(Prop);
Res.resolveKind();
return;
}
}
-
+
SemaRef.LookupQualifiedName(Res, MemberContext);
return;
}
-
- SemaRef.LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false,
+
+ SemaRef.LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false,
EnteringContext);
-
+
// Fake ivar lookup; this should really be part of
// LookupParsedName.
if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
if (Method->isInstanceMethod() && Method->getClassInterface() &&
- (Res.empty() ||
+ (Res.empty() ||
(Res.isSingleResult() &&
Res.getFoundDecl()->isDefinedOutsideFunctionOrMethod()))) {
- if (ObjCIvarDecl *IV
+ if (ObjCIvarDecl *IV
= Method->getClassInterface()->lookupInstanceVariable(Name)) {
Res.addDecl(IV);
Res.resolveKind();
/// \param MemberContext if non-NULL, the context in which to look for
/// a member access expression.
///
-/// \param EnteringContext whether we're entering the context described by
+/// \param EnteringContext whether we're entering the context described by
/// the nested-name-specifier SS.
///
/// \param CTC The context in which typo correction occurs, which impacts the
/// may contain the results of name lookup for the correct name or it may be
/// empty.
DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
- DeclContext *MemberContext,
+ DeclContext *MemberContext,
bool EnteringContext,
CorrectTypoContext CTC,
const ObjCObjectPointerType *OPT) {
if (Diags.hasFatalErrorOccurred() || !getLangOptions().SpellChecking)
return DeclarationName();
-
+
// We only attempt to correct typos for identifiers.
IdentifierInfo *Typo = Res.getLookupName().getAsIdentifierInfo();
if (!Typo)
// instantiation.
if (!ActiveTemplateInstantiations.empty())
return DeclarationName();
-
+
TypoCorrectionConsumer Consumer(Typo);
-
+
// Perform name lookup to find visible, similarly-named entities.
bool IsUnqualifiedLookup = false;
if (MemberContext) {
// Look in qualified interfaces.
if (OPT) {
- for (ObjCObjectPointerType::qual_iterator
- I = OPT->qual_begin(), E = OPT->qual_end();
+ for (ObjCObjectPointerType::qual_iterator
+ I = OPT->qual_begin(), E = OPT->qual_end();
I != E; ++I)
LookupVisibleDecls(*I, Res.getLookupKind(), Consumer);
}
DeclContext *DC = computeDeclContext(*SS, EnteringContext);
if (!DC)
return DeclarationName();
-
+
// Provide a stop gap for files that are just seriously broken. Trying
// to correct all typos can turn into a HUGE performance penalty, causing
// some files to take minutes to get rejected by the parser.
// some files to take minutes to get rejected by the parser.
if (TyposCorrected + UnqualifiedTyposCorrected.size() >= 20)
return DeclarationName();
-
+
// For unqualified lookup, look through all of the names that we have
// seen in this translation unit.
- for (IdentifierTable::iterator I = Context.Idents.begin(),
+ for (IdentifierTable::iterator I = Context.Idents.begin(),
IEnd = Context.Idents.end();
I != IEnd; ++I)
Consumer.FoundName(I->getKey());
-
+
// Walk through identifiers in external identifier sources.
if (IdentifierInfoLookup *External
= Context.Idents.getExternalIdentifierLookup()) {
// end up adding the keyword below.
if (Cached->second.first.empty())
return DeclarationName();
-
+
if (!Cached->second.second)
Consumer.FoundName(Cached->second.first);
}
WantExpressionKeywords = true;
WantCXXNamedCasts = true;
WantRemainingKeywords = true;
-
+
if (ObjCMethodDecl *Method = getCurMethodDecl())
if (Method->getClassInterface() &&
Method->getClassInterface()->getSuperClass())
Consumer.addKeywordResult(Context, "super");
-
+
break;
-
+
case CTC_NoKeywords:
break;
-
+
case CTC_Type:
WantTypeSpecifiers = true;
break;
-
+
case CTC_ObjCMessageReceiver:
Consumer.addKeywordResult(Context, "super");
// Fall through to handle message receivers like expressions.
-
+
case CTC_Expression:
if (getLangOptions().CPlusPlus)
WantTypeSpecifiers = true;
WantExpressionKeywords = true;
// Fall through to get C++ named casts.
-
+
case CTC_CXXCasts:
WantCXXNamedCasts = true;
break;
-
+
case CTC_ObjCPropertyLookup:
// FIXME: Add "isa"?
break;
-
+
case CTC_MemberLookup:
if (getLangOptions().CPlusPlus)
Consumer.addKeywordResult(Context, "template");
break;
-
+
case CTC_ObjCIvarLookup:
break;
}
// storage-specifiers as well
"extern", "inline", "static", "typedef"
};
-
+
const unsigned NumCTypeSpecs = sizeof(CTypeSpecs) / sizeof(CTypeSpecs[0]);
for (unsigned I = 0; I != NumCTypeSpecs; ++I)
Consumer.addKeywordResult(Context, CTypeSpecs[I]);
-
+
if (getLangOptions().C99)
Consumer.addKeywordResult(Context, "restrict");
if (getLangOptions().Bool || getLangOptions().CPlusPlus)
Consumer.addKeywordResult(Context, "bool");
-
+
if (getLangOptions().CPlusPlus) {
Consumer.addKeywordResult(Context, "class");
Consumer.addKeywordResult(Context, "typename");
Consumer.addKeywordResult(Context, "wchar_t");
-
+
if (getLangOptions().CPlusPlus0x) {
Consumer.addKeywordResult(Context, "char16_t");
Consumer.addKeywordResult(Context, "char32_t");
Consumer.addKeywordResult(Context, "constexpr");
Consumer.addKeywordResult(Context, "decltype");
Consumer.addKeywordResult(Context, "thread_local");
- }
+ }
}
-
+
if (getLangOptions().GNUMode)
Consumer.addKeywordResult(Context, "typeof");
}
-
+
if (WantCXXNamedCasts && getLangOptions().CPlusPlus) {
Consumer.addKeywordResult(Context, "const_cast");
Consumer.addKeywordResult(Context, "dynamic_cast");
Consumer.addKeywordResult(Context, "reinterpret_cast");
Consumer.addKeywordResult(Context, "static_cast");
}
-
+
if (WantExpressionKeywords) {
Consumer.addKeywordResult(Context, "sizeof");
if (getLangOptions().Bool || getLangOptions().CPlusPlus) {
Consumer.addKeywordResult(Context, "false");
Consumer.addKeywordResult(Context, "true");
}
-
+
if (getLangOptions().CPlusPlus) {
- const char *CXXExprs[] = {
- "delete", "new", "operator", "throw", "typeid"
+ const char *CXXExprs[] = {
+ "delete", "new", "operator", "throw", "typeid"
};
const unsigned NumCXXExprs = sizeof(CXXExprs) / sizeof(CXXExprs[0]);
for (unsigned I = 0; I != NumCXXExprs; ++I)
Consumer.addKeywordResult(Context, CXXExprs[I]);
-
+
if (isa<CXXMethodDecl>(CurContext) &&
cast<CXXMethodDecl>(CurContext)->isInstance())
Consumer.addKeywordResult(Context, "this");
-
+
if (getLangOptions().CPlusPlus0x) {
Consumer.addKeywordResult(Context, "alignof");
Consumer.addKeywordResult(Context, "nullptr");
}
}
}
-
+
if (WantRemainingKeywords) {
if (getCurFunctionOrMethodDecl() || getCurBlock()) {
// Statements.
const unsigned NumCStmts = sizeof(CStmts) / sizeof(CStmts[0]);
for (unsigned I = 0; I != NumCStmts; ++I)
Consumer.addKeywordResult(Context, CStmts[I]);
-
+
if (getLangOptions().CPlusPlus) {
Consumer.addKeywordResult(Context, "catch");
Consumer.addKeywordResult(Context, "try");
}
-
+
if (S && S->getBreakParent())
Consumer.addKeywordResult(Context, "break");
-
+
if (S && S->getContinueParent())
Consumer.addKeywordResult(Context, "continue");
-
+
if (!getCurFunction()->SwitchStack.empty()) {
Consumer.addKeywordResult(Context, "case");
Consumer.addKeywordResult(Context, "default");
Consumer.addKeywordResult(Context, "virtual");
}
}
-
+
if (getLangOptions().CPlusPlus) {
Consumer.addKeywordResult(Context, "using");
Consumer.addKeywordResult(Context, "static_assert");
}
}
-
+
// If we haven't found anything, we're done.
if (Consumer.empty()) {
// If this was an unqualified lookup, note that no correction was found.
if (IsUnqualifiedLookup)
(void)UnqualifiedTyposCorrected[Typo];
-
+
return DeclarationName();
}
- // Make sure that the user typed at least 3 characters for each correction
+ // Make sure that the user typed at least 3 characters for each correction
// made. Otherwise, we don't even both looking at the results.
// We also suppress exact matches; those should be handled by a
// Weed out any names that could not be found by name lookup.
bool LastLookupWasAccepted = false;
- for (TypoCorrectionConsumer::iterator I = Consumer.begin(),
+ for (TypoCorrectionConsumer::iterator I = Consumer.begin(),
IEnd = Consumer.end();
I != IEnd; /* Increment in loop. */) {
// Keywords are always found.
++I;
continue;
}
-
+
// Perform name lookup on this name.
IdentifierInfo *Name = &Context.Idents.get(I->getKey());
- LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext,
+ LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext,
EnteringContext, CTC);
-
+
switch (Res.getResultKind()) {
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
case LookupResult::Ambiguous:
- // We didn't find this name in our scope, or didn't like what we found;
+ // We didn't find this name in our scope, or didn't like what we found;
// ignore it.
Res.suppressDiagnostics();
{
I = Next;
}
LastLookupWasAccepted = false;
- break;
-
+ break;
+
case LookupResult::Found:
case LookupResult::FoundOverloaded:
case LookupResult::FoundUnresolvedValue:
LastLookupWasAccepted = true;
break;
}
-
+
if (Res.isAmbiguous()) {
// We don't deal with ambiguities.
Res.suppressDiagnostics();
Res.clear();
- return DeclarationName();
- }
+ return DeclarationName();
+ }
}
// If only a single name remains, return that result.
if (Consumer.begin()->second) {
Res.suppressDiagnostics();
Res.clear();
-
+
// Don't correct to a keyword that's the same as the typo; the keyword
// wasn't actually in scope.
if (ED == 0) {
Res.setLookupName(Typo);
return DeclarationName();
}
-
+
} else if (!LastLookupWasAccepted) {
// Perform name lookup on this name.
- LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext,
+ LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext,
EnteringContext, CTC);
}
// Record the correction for unqualified lookup.
if (IsUnqualifiedLookup)
- UnqualifiedTyposCorrected[Typo]
+ UnqualifiedTyposCorrected[Typo]
= std::make_pair(Name->getName(), Consumer.begin()->second);
-
- return &Context.Idents.get(Consumer.begin()->getKey());
+
+ return &Context.Idents.get(Consumer.begin()->getKey());
}
- else if (Consumer.size() > 1 && CTC == CTC_ObjCMessageReceiver
+ else if (Consumer.size() > 1 && CTC == CTC_ObjCMessageReceiver
&& Consumer["super"]) {
// Prefix 'super' when we're completing in a message-receiver
// context.
Res.suppressDiagnostics();
Res.clear();
-
+
// Don't correct to a keyword that's the same as the typo; the keyword
// wasn't actually in scope.
if (ED == 0) {
Res.setLookupName(Typo);
return DeclarationName();
}
-
+
// Record the correction for unqualified lookup.
if (IsUnqualifiedLookup)
UnqualifiedTyposCorrected[Typo]
= std::make_pair("super", Consumer.begin()->second);
-
+
return &Context.Idents.get("super");
}
-
+
Res.suppressDiagnostics();
Res.setLookupName(Typo);
Res.clear();
TemplateArgument SecondArg;
};
}
-
+
/// \brief Convert from Sema's representation of template deduction information
/// to the form used in overload-candidate information.
OverloadCandidate::DeductionFailureInfo
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
break;
-
+
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
Result.Data = Info.Param.getOpaqueValue();
break;
-
+
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified: {
// FIXME: Should allocate from normal heap so that we can free this later.
Result.Data = Saved;
break;
}
-
+
case Sema::TDK_SubstitutionFailure:
Result.Data = Info.take();
break;
-
+
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
- break;
+ break;
}
-
+
return Result;
}
case Sema::TDK_TooFewArguments:
case Sema::TDK_InvalidExplicitArguments:
break;
-
+
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
// FIXME: Destroy the data?
// FIXME: Destroy the template arugment list?
Data = 0;
break;
-
+
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
}
-
-TemplateParameter
+
+TemplateParameter
OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_Success:
case Sema::TDK_TooFewArguments:
case Sema::TDK_SubstitutionFailure:
return TemplateParameter();
-
+
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
- return TemplateParameter::getFromOpaqueValue(Data);
+ return TemplateParameter::getFromOpaqueValue(Data);
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
return static_cast<DFIParamWithArguments*>(Data)->Param;
-
+
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
-
+
return TemplateParameter();
}
-
+
TemplateArgumentList *
OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_SubstitutionFailure:
return static_cast<TemplateArgumentList*>(Data);
-
+
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
- return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;
+ return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
-
+
return 0;
-}
+}
const TemplateArgument *
OverloadCandidate::DeductionFailureInfo::getSecondArg() {
case Sema::TDK_FailedOverloadResolution:
break;
}
-
+
return 0;
}
inherited::clear();
Functions.clear();
}
-
+
// IsOverload - Determine whether the given New declaration is an
// overload of the declarations in Old. This routine returns false if
// New and Old cannot be overloaded, e.g., if New has the same
(OldMethod->getRefQualifier() == RQ_None ||
NewMethod->getRefQualifier() == RQ_None)) {
// C++0x [over.load]p2:
- // - Member function declarations with the same name and the same
- // parameter-type-list as well as member function template
- // declarations with the same name, the same parameter-type-list, and
- // the same template parameter lists cannot be overloaded if any of
+ // - Member function declarations with the same name and the same
+ // parameter-type-list as well as member function template
+ // declarations with the same name, the same parameter-type-list, and
+ // the same template parameter lists cannot be overloaded if any of
// them, but not all, have a ref-qualifier (8.3.5).
Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
<< NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
Diag(OldMethod->getLocation(), diag::note_previous_declaration);
}
-
+
return true;
}
-
+
// The signatures match; this is not an overload.
return false;
}
static ImplicitConversionSequence
TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
bool SuppressUserConversions,
- bool AllowExplicit,
+ bool AllowExplicit,
bool InOverloadResolution,
bool CStyle) {
ImplicitConversionSequence ICS;
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(FromType);
ICS.Standard.setAllToTypes(ToType);
-
+
// We don't actually check at this point whether there is a valid
// copy/move constructor, since overloading just assumes that it
// exists. When we actually perform initialization, we'll find the
// appropriate constructor to copy the returned object, if needed.
ICS.Standard.CopyConstructor = 0;
-
+
// Determine whether this is considered a derived-to-base conversion.
if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
ICS.Standard.Second = ICK_Derived_To_Base;
-
+
return ICS;
}
-
+
if (SuppressUserConversions) {
// We're not in the case above, so there is no conversion that
// we can perform.
ImplicitConversionSequence ICS
= clang::TryImplicitConversion(*this, Initializer, Entity.getType(),
SuppressUserConversions,
- AllowExplicitConversions,
+ AllowExplicitConversions,
InOverloadResolution,
CStyle);
if (ICS.isBad()) return true;
/*CStyle=*/false);
return PerformImplicitConversion(From, ToType, ICS, Action);
}
-
-/// \brief Determine whether the conversion from FromType to ToType is a valid
+
+/// \brief Determine whether the conversion from FromType to ToType is a valid
/// conversion that strips "noreturn" off the nested function type.
-static bool IsNoReturnConversion(ASTContext &Context, QualType FromType,
+static bool IsNoReturnConversion(ASTContext &Context, QualType FromType,
QualType ToType, QualType &ResultTy) {
if (Context.hasSameUnqualifiedType(FromType, ToType))
return false;
-
+
// Permit the conversion F(t __attribute__((noreturn))) -> F(t)
// where F adds one of the following at most once:
// - a pointer
ResultTy = ToType;
return true;
}
-
+
/// \brief Determine whether the conversion from FromType to ToType is a valid
/// vector conversion.
///
/// \param ICK Will be set to the vector conversion kind, if this is a vector
/// conversion.
-static bool IsVectorConversion(ASTContext &Context, QualType FromType,
- QualType ToType, ImplicitConversionKind &ICK) {
+static bool IsVectorConversion(ASTContext &Context, QualType FromType,
+ QualType ToType, ImplicitConversionKind &ICK) {
// We need at least one of these types to be a vector type to have a vector
// conversion.
if (!ToType->isVectorType() && !FromType->isVectorType())
// identity conversion.
if (FromType->isExtVectorType())
return false;
-
+
// Vector splat from any arithmetic type to a vector.
if (FromType->isArithmeticType()) {
ICK = ICK_Vector_Splat;
return false;
}
-
+
/// IsStandardConversion - Determines whether there is a standard
/// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the
/// expression From to the type ToType. Standard conversion sequences
StandardConversionSequence &SCS,
bool CStyle) {
QualType FromType = From->getType();
-
+
// Standard conversions (C++ [conv])
SCS.setAsIdentityConversion();
SCS.DeprecatedStringLiteralToCharPtr = false;
if (FromType == S.Context.OverloadTy) {
DeclAccessPair AccessPair;
if (FunctionDecl *Fn
- = S.ResolveAddressOfOverloadedFunction(From, ToType, false,
+ = S.ResolveAddressOfOverloadedFunction(From, ToType, false,
AccessPair)) {
// We were able to resolve the address of the overloaded function,
// so we can convert to the type of that function.
FromType = Fn->getType();
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
if (!Method->isStatic()) {
- const Type *ClassType
+ const Type *ClassType
= S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
FromType = S.Context.getMemberPointerType(FromType, ClassType);
}
}
-
+
// If the "from" expression takes the address of the overloaded
// function, update the type of the resulting expression accordingly.
if (FromType->getAs<FunctionType>())
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens()))
if (UnOp->getOpcode() == UO_AddrOf)
FromType = S.Context.getPointerType(FromType);
-
+
// Check that we've computed the proper type after overload resolution.
assert(S.Context.hasSameType(FromType,
S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
// Floating point conversions (C++ 4.8).
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
- } else if ((FromType->isRealFloatingType() &&
+ } else if ((FromType->isRealFloatingType() &&
ToType->isIntegralType(S.Context)) ||
(FromType->isIntegralOrUnscopedEnumerationType() &&
ToType->isRealFloatingType())) {
// Pointer conversions (C++ 4.10).
SCS.Second = ICK_Pointer_Conversion;
SCS.IncompatibleObjC = IncompatibleObjC;
- } else if (S.IsMemberPointerConversion(From, FromType, ToType,
+ } else if (S.IsMemberPointerConversion(From, FromType, ToType,
InOverloadResolution, FromType)) {
// Pointer to member conversions (4.11).
SCS.Second = ICK_Pointer_Member;
// a conversion. [...]
CanonFrom = S.Context.getCanonicalType(FromType);
CanonTo = S.Context.getCanonicalType(ToType);
- if (CanonFrom.getLocalUnqualifiedType()
+ if (CanonFrom.getLocalUnqualifiedType()
== CanonTo.getLocalUnqualifiedType() &&
(CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()
|| CanonFrom.getObjCGCAttr() != CanonTo.getObjCGCAttr())) {
return To->getKind() == BuiltinType::UInt;
}
- // C++0x [conv.prom]p3:
- // A prvalue of an unscoped enumeration type whose underlying type is not
- // fixed (7.2) can be converted to an rvalue a prvalue of the first of the
- // following types that can represent all the values of the enumeration
- // (i.e., the values in the range bmin to bmax as described in 7.2): int,
- // unsigned int, long int, unsigned long int, long long int, or unsigned
+ // C++0x [conv.prom]p3:
+ // A prvalue of an unscoped enumeration type whose underlying type is not
+ // fixed (7.2) can be converted to an rvalue a prvalue of the first of the
+ // following types that can represent all the values of the enumeration
+ // (i.e., the values in the range bmin to bmax as described in 7.2): int,
+ // unsigned int, long int, unsigned long int, long long int, or unsigned
// long long int. If none of the types in that list can represent all the
- // values of the enumeration, an rvalue a prvalue of an unscoped enumeration
+ // values of the enumeration, an rvalue a prvalue of an unscoped enumeration
// type can be converted to an rvalue a prvalue of the extended integer type
- // with lowest integer conversion rank (4.13) greater than the rank of long
- // long in which all the values of the enumeration can be represented. If
+ // with lowest integer conversion rank (4.13) greater than the rank of long
+ // long in which all the values of the enumeration can be represented. If
// there are two such extended types, the signed one is chosen.
if (const EnumType *FromEnumType = FromType->getAs<EnumType>()) {
// C++0x 7.2p9: Note that this implicit enum to int conversion is not
return false;
// We have already pre-calculated the promotion type, so this is trivial.
- if (ToType->isIntegerType() &&
+ if (ToType->isIntegerType() &&
!RequireCompleteType(From->getLocStart(), FromType, PDiag()))
return Context.hasSameUnqualifiedType(ToType,
FromEnumType->getDecl()->getPromotionType());
}
// C++0x [conv.prom]p2:
- // A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted
- // to an rvalue a prvalue of the first of the following types that can
- // represent all the values of its underlying type: int, unsigned int,
+ // A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted
+ // to an rvalue a prvalue of the first of the following types that can
+ // represent all the values of its underlying type: int, unsigned int,
// long int, unsigned long int, long long int, or unsigned long long int.
- // If none of the types in that list can represent all the values of its
+ // If none of the types in that list can represent all the values of its
// underlying type, an rvalue a prvalue of type char16_t, char32_t,
- // or wchar_t can be converted to an rvalue a prvalue of its underlying
+ // or wchar_t can be converted to an rvalue a prvalue of its underlying
// type.
- if (FromType->isAnyCharacterType() && !FromType->isCharType() &&
+ if (FromType->isAnyCharacterType() && !FromType->isCharType() &&
ToType->isIntegerType()) {
// Determine whether the type we're converting from is signed or
// unsigned.
bool FromIsSigned;
uint64_t FromSize = Context.getTypeSize(FromType);
-
+
// FIXME: Is wchar_t signed or unsigned? We assume it's signed for now.
FromIsSigned = true;
assert((FromPtr->getTypeClass() == Type::Pointer ||
FromPtr->getTypeClass() == Type::ObjCObjectPointer) &&
"Invalid similarly-qualified pointer type");
-
+
/// \brief Conversions to 'id' subsume cv-qualifier conversions.
if (ToType->isObjCIdType() || ToType->isObjCQualifiedIdType())
return ToType.getUnqualifiedType();
-
- QualType CanonFromPointee
+
+ QualType CanonFromPointee
= Context.getCanonicalType(FromPtr->getPointeeType());
QualType CanonToPointee = Context.getCanonicalType(ToPointee);
Qualifiers Quals = CanonFromPointee.getQualifiers();
// Just build a canonical type that has the right qualifiers.
QualType QualifiedCanonToPointee
= Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), Quals);
-
+
if (isa<ObjCObjectPointerType>(ToType))
return Context.getObjCObjectPointerType(QualifiedCanonToPointee);
return Context.getPointerType(QualifiedCanonToPointee);
}
-
+
static bool isNullPointerConstantForConversion(Expr *Expr,
bool InOverloadResolution,
ASTContext &Context) {
return true;
}
- // Beyond this point, both types need to be pointers
+ // Beyond this point, both types need to be pointers
// , including objective-c pointers.
QualType ToPointeeType = ToTypePtr->getPointeeType();
if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType()) {
QualType FromPointeeType = FromTypePtr->getPointeeType();
- // If the unqualified pointee types are the same, this can't be a
+ // If the unqualified pointee types are the same, this can't be a
// pointer conversion, so don't do all of the work below.
if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType))
return false;
bool &IncompatibleObjC) {
if (!getLangOptions().ObjC1)
return false;
-
+
// First, we handle all conversions on ObjC object pointer types.
const ObjCObjectPointerType* ToObjCPtr =
ToType->getAs<ObjCObjectPointerType>();
!ToObjCPtr->getPointeeType().isAtLeastAsQualifiedAs(
FromObjCPtr->getPointeeType()))
return false;
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr,
+ ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr,
ToObjCPtr->getPointeeType(),
ToType, Context);
return true;
// interfaces, which is permitted. However, we're going to
// complain about it.
IncompatibleObjC = true;
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr,
+ ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr,
ToObjCPtr->getPointeeType(),
ToType, Context);
return true;
QualType ToPointeeType;
if (const PointerType *ToCPtr = ToType->getAs<PointerType>())
ToPointeeType = ToCPtr->getPointeeType();
- else if (const BlockPointerType *ToBlockPtr =
+ else if (const BlockPointerType *ToBlockPtr =
ToType->getAs<BlockPointerType>()) {
// Objective C++: We're able to convert from a pointer to any object
// to a block pointer type.
}
ToPointeeType = ToBlockPtr->getPointeeType();
}
- else if (FromType->getAs<BlockPointerType>() &&
+ else if (FromType->getAs<BlockPointerType>() &&
ToObjCPtr && ToObjCPtr->isObjCBuiltinType()) {
- // Objective C++: We're able to convert from a block pointer type to a
+ // Objective C++: We're able to convert from a block pointer type to a
// pointer to any object.
ConvertedType = ToType;
return true;
ConvertedType = Context.getPointerType(ConvertedType);
return true;
}
-
+
// If we have pointers to functions or blocks, check whether the only
// differences in the argument and result types are in Objective-C
// pointer conversions. If so, we permit the conversion (but
return false;
}
-
+
/// FunctionArgTypesAreEqual - This routine checks two function proto types
/// for equlity of their argument types. Caller has already checked that
/// they have same number of arguments. This routine assumes that Objective-C
/// pointer types which only differ in their protocol qualifiers are equal.
-bool Sema::FunctionArgTypesAreEqual(const FunctionProtoType *OldType,
+bool Sema::FunctionArgTypesAreEqual(const FunctionProtoType *OldType,
const FunctionProtoType *NewType) {
if (!getLangOptions().ObjC1)
return std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
NewType->arg_type_begin());
-
+
for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(),
N = NewType->arg_type_begin(),
E = OldType->arg_type_end(); O && (O != E); ++O, ++N) {
}
else if (const ObjCObjectPointerType *PTTo =
ToType->getAs<ObjCObjectPointerType>()) {
- if (const ObjCObjectPointerType *PTFr =
+ if (const ObjCObjectPointerType *PTFr =
FromType->getAs<ObjCObjectPointerType>())
if (PTTo->getInterfaceDecl() == PTFr->getInterfaceDecl())
continue;
}
- return false;
+ return false;
}
}
return true;
From->getSourceRange(), &BasePath,
IgnoreBaseAccess))
return true;
-
+
// The conversion was successful.
Kind = CK_DerivedToBase;
}
/// If so, returns true and places the converted type (that might differ from
/// ToType in its cv-qualifiers at some level) into ConvertedType.
bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
- QualType ToType,
+ QualType ToType,
bool InOverloadResolution,
QualType &ConvertedType) {
const MemberPointerType *ToTypePtr = ToType->getAs<MemberPointerType>();
return false;
}
-
+
/// CheckMemberPointerConversion - Check the member pointer conversion from the
/// expression From to the type ToType. This routine checks for ambiguous or
/// virtual or inaccessible base-to-derived member pointer conversions
const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
if (!FromPtrType) {
// This must be a null pointer to member pointer conversion
- assert(From->isNullPointerConstant(Context,
+ assert(From->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull) &&
"Expr must be null pointer constant!");
Kind = CK_NullToMemberPointer;
/// an rvalue of type FromType to ToType is a qualification conversion
/// (C++ 4.4).
bool
-Sema::IsQualificationConversion(QualType FromType, QualType ToType,
+Sema::IsQualificationConversion(QualType FromType, QualType ToType,
bool CStyle) {
FromType = Context.getCanonicalType(FromType);
ToType = Context.getCanonicalType(ToType);
= cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
else
Constructor = cast<CXXConstructorDecl>(D);
-
+
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0,
- &From, 1, CandidateSet,
+ &From, 1, CandidateSet,
/*SuppressUserConversions=*/
!ConstructorsOnly);
else
case OR_Deleted:
// No conversion here! We're done.
return OR_Deleted;
-
+
case OR_Ambiguous:
return OR_Ambiguous;
}
return OR_No_Viable_Function;
}
-
+
bool
Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
ImplicitConversionSequence ICS;
OverloadCandidateSet CandidateSet(From->getExprLoc());
- OverloadingResult OvResult =
+ OverloadingResult OvResult =
IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
CandidateSet, false);
if (OvResult == OR_Ambiguous)
else
return false;
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &From, 1);
- return true;
+ return true;
}
/// CompareImplicitConversionSequences - Compare two implicit
while (Context.UnwrapSimilarPointerTypes(T1, T2)) {
Qualifiers Quals;
T1 = Context.getUnqualifiedArrayType(T1, Quals);
- T2 = Context.getUnqualifiedArrayType(T2, Quals);
+ T2 = Context.getUnqualifiedArrayType(T2, Quals);
}
-
+
return Context.hasSameUnqualifiedType(T1, T2);
}
-
+
// Per 13.3.3.2p3, compare the given standard conversion sequences to
// determine if one is a proper subset of the other.
static ImplicitConversionSequence::CompareKind
ImplicitConversionSequence::CompareKind Result
= ImplicitConversionSequence::Indistinguishable;
- // the identity conversion sequence is considered to be a subsequence of
+ // the identity conversion sequence is considered to be a subsequence of
// any non-identity conversion sequence
if (SCS1.ReferenceBinding == SCS2.ReferenceBinding) {
if (SCS1.isIdentityConversion() && !SCS2.isIdentityConversion())
else if (!SCS1.isIdentityConversion() && SCS2.isIdentityConversion())
return ImplicitConversionSequence::Worse;
}
-
+
if (SCS1.Second != SCS2.Second) {
if (SCS1.Second == ICK_Identity)
Result = ImplicitConversionSequence::Better;
return Result == ImplicitConversionSequence::Better
? ImplicitConversionSequence::Indistinguishable
: ImplicitConversionSequence::Worse;
-
+
return ImplicitConversionSequence::Indistinguishable;
}
// C++0x [over.ics.rank]p3b4:
// -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
// implicit object parameter of a non-static member function declared
- // without a ref-qualifier, and *either* S1 binds an rvalue reference
+ // without a ref-qualifier, and *either* S1 binds an rvalue reference
// to an rvalue and S2 binds an lvalue reference *or S1 binds an
- // lvalue reference to a function lvalue and S2 binds an rvalue
+ // lvalue reference to a function lvalue and S2 binds an rvalue
// reference*.
//
// FIXME: Rvalue references. We're going rogue with the above edits,
if (SCS1.BindsImplicitObjectArgumentWithoutRefQualifier ||
SCS2.BindsImplicitObjectArgumentWithoutRefQualifier)
return false;
-
+
return (!SCS1.IsLvalueReference && SCS1.BindsToRvalue &&
SCS2.IsLvalueReference) ||
(SCS1.IsLvalueReference && SCS1.BindsToFunctionLvalue &&
!SCS2.IsLvalueReference);
}
-
+
/// CompareStandardConversionSequences - Compare two standard
/// conversion sequences to determine whether one is better than the
/// other or if they are indistinguishable (C++ 13.3.3.2p3).
return ImplicitConversionSequence::Better;
else if (isBetterReferenceBindingKind(SCS2, SCS1))
return ImplicitConversionSequence::Worse;
-
+
// C++ [over.ics.rank]p3b4:
// -- S1 and S2 are reference bindings (8.5.3), and the types to
// which the references refer are the same type except for
if (SCS1.Second == ICK_Pointer_Member && SCS2.Second == ICK_Pointer_Member &&
FromType1->isMemberPointerType() && FromType2->isMemberPointerType() &&
ToType1->isMemberPointerType() && ToType2->isMemberPointerType()) {
- const MemberPointerType * FromMemPointer1 =
+ const MemberPointerType * FromMemPointer1 =
FromType1->getAs<MemberPointerType>();
- const MemberPointerType * ToMemPointer1 =
+ const MemberPointerType * ToMemPointer1 =
ToType1->getAs<MemberPointerType>();
- const MemberPointerType * FromMemPointer2 =
+ const MemberPointerType * FromMemPointer2 =
FromType2->getAs<MemberPointerType>();
- const MemberPointerType * ToMemPointer2 =
+ const MemberPointerType * ToMemPointer2 =
ToType2->getAs<MemberPointerType>();
const Type *FromPointeeType1 = FromMemPointer1->getClass();
const Type *ToPointeeType1 = ToMemPointer1->getClass();
return ImplicitConversionSequence::Worse;
}
}
-
+
if (SCS1.Second == ICK_Derived_To_Base) {
// -- conversion of C to B is better than conversion of C to A,
// -- binding of an expression of type C to a reference of type
else
Conv = cast<CXXConversionDecl>(D);
- // If this is an explicit conversion, and we're not allowed to consider
+ // If this is an explicit conversion, and we're not allowed to consider
// explicit conversions, skip it.
if (!AllowExplicit && Conv->isExplicit())
continue;
-
+
if (AllowRvalues) {
bool DerivedToBase = false;
bool ObjCConversion = false;
!RefType->getPointeeType()->isFunctionType()))
continue;
}
-
+
if (ConvTemplate)
S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
Init, DeclType, CandidateSet);
// conversion; continue with other checks.
return false;
}
-
+
return false;
}
// conversion functions (13.3.1.6) and choosing the best
// one through overload resolution (13.3)),
if (!SuppressUserConversions && T2->isRecordType() &&
- !S.RequireCompleteType(DeclLoc, T2, 0) &&
+ !S.RequireCompleteType(DeclLoc, T2, 0) &&
RefRelationship == Sema::Ref_Incompatible) {
if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
Init, T2, /*AllowRvalues=*/false,
// -- Otherwise, the reference shall be an lvalue reference to a
// non-volatile const type (i.e., cv1 shall be const), or the reference
// shall be an rvalue reference.
- //
+ //
// We actually handle one oddity of C++ [over.ics.ref] at this
// point, which is that, due to p2 (which short-circuits reference
// binding by only attempting a simple conversion for non-direct
(InitCategory.isLValue() && T2->isFunctionType()))) {
ICS.setStandard();
ICS.Standard.First = ICK_Identity;
- ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
+ ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
: ObjCConversion? ICK_Compatible_Conversion
: ICK_Identity;
ICS.Standard.Third = ICK_Identity;
// Note: Although xvalues wouldn't normally show up in C++98/03 code, we
// allow the use of rvalue references in C++98/03 for the benefit of
// standard library implementors; therefore, we need the xvalue check here.
- ICS.Standard.DirectBinding =
- S.getLangOptions().CPlusPlus0x ||
+ ICS.Standard.DirectBinding =
+ S.getLangOptions().CPlusPlus0x ||
(InitCategory.isPRValue() && !T2->isRecordType());
ICS.Standard.IsLvalueReference = !isRValRef;
ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
- ICS.Standard.BindsToRvalue = InitCategory.isRValue();
+ ICS.Standard.BindsToRvalue = InitCategory.isRValue();
ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
ICS.Standard.CopyConstructor = 0;
- return ICS;
+ return ICS;
}
-
+
// -- has a class type (i.e., T2 is a class type), where T1 is not
// reference-related to T2, and can be implicitly converted to
- // an xvalue, class prvalue, or function lvalue of type
- // "cv3 T3", where "cv1 T1" is reference-compatible with
+ // an xvalue, class prvalue, or function lvalue of type
+ // "cv3 T3", where "cv1 T1" is reference-compatible with
// "cv3 T3",
//
- // then the reference is bound to the value of the initializer
+ // then the reference is bound to the value of the initializer
// expression in the first case and to the result of the conversion
- // in the second case (or, in either case, to an appropriate base
+ // in the second case (or, in either case, to an appropriate base
// class subobject).
if (!SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible &&
- T2->isRecordType() && !S.RequireCompleteType(DeclLoc, T2, 0) &&
+ T2->isRecordType() && !S.RequireCompleteType(DeclLoc, T2, 0) &&
FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
Init, T2, /*AllowRvalues=*/true,
AllowExplicit)) {
// and the second standard conversion sequence of the
// user-defined conversion sequence includes an lvalue-to-rvalue
// conversion, the program is ill-formed.
- if (ICS.isUserDefined() && isRValRef &&
+ if (ICS.isUserDefined() && isRValRef &&
ICS.UserDefined.After.First == ICK_Lvalue_To_Rvalue)
ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType);
return ICS;
}
-
+
// -- Otherwise, a temporary of type "cv1 T1" is created and
// initialized from the initializer expression using the
// rules for a non-reference copy initialization (8.5). The
/// do not permit any user-defined conversion sequences.
static ImplicitConversionSequence
TryCopyInitialization(Sema &S, Expr *From, QualType ToType,
- bool SuppressUserConversions,
+ bool SuppressUserConversions,
bool InOverloadResolution) {
if (ToType->isReferenceType())
return TryReferenceInit(S, From, ToType,
assert(FromType->isRecordType());
// C++0x [over.match.funcs]p4:
- // For non-static member functions, the type of the implicit object
+ // For non-static member functions, the type of the implicit object
// parameter is
//
// - "lvalue reference to cv X" for functions declared without a
// - "rvalue reference to cv X" for functions declared with the &&
// ref-qualifier
//
- // where X is the class of which the function is a member and cv is the
+ // where X is the class of which the function is a member and cv is the
// cv-qualification on the member function declaration.
//
- // However, when finding an implicit conversion sequence for the argument, we
+ // However, when finding an implicit conversion sequence for the argument, we
// are not allowed to create temporaries or perform user-defined conversions
// (C++ [over.match.funcs]p5). We perform a simplified version of
// reference binding here, that allows class rvalues to bind to
// First check the qualifiers.
QualType FromTypeCanon = S.Context.getCanonicalType(FromType);
- if (ImplicitParamType.getCVRQualifiers()
+ if (ImplicitParamType.getCVRQualifiers()
!= FromTypeCanon.getLocalCVRQualifiers() &&
!ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) {
ICS.setBad(BadConversionSequence::bad_qualifiers,
case RQ_None:
// Do nothing; we don't care about lvalueness or rvalueness.
break;
-
+
case RQ_LValue:
if (!FromClassification.isLValue() && Quals != Qualifiers::Const) {
// non-const lvalue reference cannot bind to an rvalue
- ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, FromType,
+ ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, FromType,
ImplicitParamType);
return ICS;
}
case RQ_RValue:
if (!FromClassification.isRValue()) {
// rvalue reference cannot bind to an lvalue
- ICS.setBad(BadConversionSequence::rvalue_ref_to_lvalue, FromType,
+ ICS.setBad(BadConversionSequence::rvalue_ref_to_lvalue, FromType,
ImplicitParamType);
return ICS;
}
break;
}
-
+
// Success. Mark this as a reference binding.
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setAllToTypes(ImplicitParamType);
ICS.Standard.ReferenceBinding = true;
ICS.Standard.DirectBinding = true;
- ICS.Standard.IsLvalueReference = Method->getRefQualifier() != RQ_RValue;
+ ICS.Standard.IsLvalueReference = Method->getRefQualifier() != RQ_RValue;
ICS.Standard.BindsToFunctionLvalue = false;
ICS.Standard.BindsToRvalue = FromClassification.isRValue();
ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier
/// the implicit object parameter for the given Method with the given
/// expression.
bool
-Sema::PerformObjectArgumentInitialization(Expr *&From,
- NestedNameSpecifier *Qualifier,
+Sema::PerformObjectArgumentInitialization(Expr *&From,
+ NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
CXXMethodDecl *Method) {
QualType FromRecordType, DestType;
ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
-
+
if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
return Diag(From->getSourceRange().getBegin(),
diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
return true;
}
-
+
/// TryContextuallyConvertToObjCId - Attempt to contextually convert the
/// expression From to 'id'.
static ImplicitConversionSequence
return true;
}
-/// \brief Attempt to convert the given expression to an integral or
+/// \brief Attempt to convert the given expression to an integral or
/// enumeration type.
///
/// This routine will attempt to convert an expression of class type to an
/// \param AmbigDiag The diagnostic to be emitted if there is more than one
/// conversion function that could convert to integral or enumeration type.
///
-/// \param AmbigNote The note to be emitted with \p AmbigDiag for each
+/// \param AmbigNote The note to be emitted with \p AmbigDiag for each
/// usable conversion function.
///
/// \param ConvDiag The diagnostic to be emitted if we are calling a conversion
///
/// \returns The expression, converted to an integral or enumeration type if
/// successful.
-ExprResult
+ExprResult
Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
const PartialDiagnostic &NotIntDiag,
const PartialDiagnostic &IncompleteDiag,
// We can't perform any more checking for type-dependent expressions.
if (From->isTypeDependent())
return Owned(From);
-
+
// If the expression already has integral or enumeration type, we're golden.
QualType T = From->getType();
if (T->isIntegralOrEnumerationType())
// FIXME: Check for missing '()' if T is a function type?
- // If we don't have a class type in C++, there's no way we can get an
+ // If we don't have a class type in C++, there's no way we can get an
// expression of integral or enumeration type.
const RecordType *RecordTy = T->getAs<RecordType>();
if (!RecordTy || !getLangOptions().CPlusPlus) {
<< T << From->getSourceRange();
return Owned(From);
}
-
+
// We must have a complete class type.
if (RequireCompleteType(Loc, T, IncompleteDiag))
return Owned(From);
-
+
// Look for a conversion to an integral or enumeration type.
UnresolvedSet<4> ViableConversions;
UnresolvedSet<4> ExplicitConversions;
const UnresolvedSetImpl *Conversions
= cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
-
+
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
- E = Conversions->end();
- I != E;
+ E = Conversions->end();
+ I != E;
++I) {
if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl()))
ViableConversions.addDecl(I.getDecl(), I.getAccess());
}
}
-
+
switch (ViableConversions.size()) {
case 0:
if (ExplicitConversions.size() == 1) {
DeclAccessPair Found = ExplicitConversions[0];
CXXConversionDecl *Conversion
= cast<CXXConversionDecl>(Found->getUnderlyingDecl());
-
+
// The user probably meant to invoke the given explicit
// conversion; use it.
QualType ConvTy
= Conversion->getConversionType().getNonReferenceType();
std::string TypeStr;
ConvTy.getAsStringInternal(TypeStr, Context.PrintingPolicy);
-
+
Diag(Loc, ExplicitConvDiag)
<< T << ConvTy
<< FixItHint::CreateInsertion(From->getLocStart(),
")");
Diag(Conversion->getLocation(), ExplicitConvNote)
<< ConvTy->isEnumeralType() << ConvTy;
-
- // If we aren't in a SFINAE context, build a call to the
+
+ // If we aren't in a SFINAE context, build a call to the
// explicit conversion function.
if (isSFINAEContext())
return ExprError();
-
+
CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion);
if (Result.isInvalid())
return ExprError();
-
+
From = Result.get();
}
-
+
// We'll complain below about a non-integral condition type.
break;
-
+
case 1: {
// Apply this conversion.
DeclAccessPair Found = ViableConversions[0];
CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
-
+
CXXConversionDecl *Conversion
= cast<CXXConversionDecl>(Found->getUnderlyingDecl());
QualType ConvTy
- = Conversion->getConversionType().getNonReferenceType();
+ = Conversion->getConversionType().getNonReferenceType();
if (ConvDiag.getDiagID()) {
if (isSFINAEContext())
return ExprError();
-
+
Diag(Loc, ConvDiag)
<< T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
}
-
+
ExprResult Result = BuildCXXMemberCallExpr(From, Found,
cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
if (Result.isInvalid())
return ExprError();
-
+
From = Result.get();
break;
}
-
+
default:
Diag(Loc, AmbigDiag)
<< T << From->getSourceRange();
}
return Owned(From);
}
-
+
if (!From->getType()->isIntegralOrEnumerationType())
Diag(Loc, NotIntDiag)
<< From->getType() << From->getSourceRange();
// object argument (C++ [over.call.func]p3), and the acting context
// is irrelevant.
AddMethodCandidate(Method, FoundDecl, Method->getParent(),
- QualType(), Expr::Classification::makeSimpleLValue(),
+ QualType(), Expr::Classification::makeSimpleLValue(),
Args, NumArgs, CandidateSet,
SuppressUserConversions);
return;
// A member function template is never instantiated to perform the copy
// of a class object to an object of its class type.
QualType ClassType = Context.getTypeDeclType(Constructor->getParent());
- if (NumArgs == 1 &&
+ if (NumArgs == 1 &&
Constructor->isSpecializationCopyingObject() &&
(Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) ||
IsDerivedFrom(Args[0]->getType(), ClassType)))
return;
}
-
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = NumArgs;
-
+
unsigned NumArgsInProto = Proto->getNumArgs();
// (C++ 13.3.2p2): A candidate function having fewer than m
// parameters is viable only if it has an ellipsis in its parameter
// list (8.3.5).
- if ((NumArgs + (PartialOverloading && NumArgs)) > NumArgsInProto &&
+ if ((NumArgs + (PartialOverloading && NumArgs)) > NumArgsInProto &&
!Proto->isVariadic()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_too_many_arguments;
QualType ParamType = Proto->getArgType(ArgIdx);
Candidate.Conversions[ArgIdx]
= TryCopyInitialization(*this, Args[ArgIdx], ParamType,
- SuppressUserConversions,
+ SuppressUserConversions,
/*InOverloadResolution=*/true);
if (Candidate.Conversions[ArgIdx].isBad()) {
Candidate.Viable = false;
AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
cast<CXXMethodDecl>(FD)->getParent(),
Args[0]->getType(), Args[0]->Classify(Context),
- Args + 1, NumArgs - 1,
+ Args + 1, NumArgs - 1,
CandidateSet, SuppressUserConversions);
else
AddOverloadCandidate(FD, F.getPair(), Args, NumArgs, CandidateSet,
AddMethodTemplateCandidate(FunTmpl, F.getPair(),
cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
/*FIXME: explicit args */ 0,
- Args[0]->getType(),
+ Args[0]->getType(),
Args[0]->Classify(Context),
Args + 1, NumArgs - 1,
CandidateSet,
if (isa<UsingShadowDecl>(Decl))
Decl = cast<UsingShadowDecl>(Decl)->getTargetDecl();
-
+
if (FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(Decl)) {
assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) &&
"Expected a member function template");
QualType ParamType = Proto->getArgType(ArgIdx);
Candidate.Conversions[ArgIdx + 1]
= TryCopyInitialization(*this, Args[ArgIdx], ParamType,
- SuppressUserConversions,
+ SuppressUserConversions,
/*InOverloadResolution=*/true);
if (Candidate.Conversions[ArgIdx + 1].isBad()) {
Candidate.Viable = false;
}
}
}
-
+
/// \brief Add a C++ member function template as a candidate to the candidate
/// set, using template argument deduction to produce an appropriate member
/// function template specialization.
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = NumArgs;
- Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+ Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
return;
}
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = NumArgs;
- Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+ Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
return;
}
Candidate.ExplicitCallArguments = 1;
// C++ [over.match.funcs]p4:
- // For conversion functions, the function is considered to be a member of
- // the class of the implicit implied object argument for the purpose of
+ // For conversion functions, the function is considered to be a member of
+ // the class of the implicit implied object argument for the purpose of
// defining the type of the implicit object parameter.
//
// Determine the implicit conversion sequence for the implicit
ImplicitParamType = FromPtrType->getPointeeType();
CXXRecordDecl *ConversionContext
= cast<CXXRecordDecl>(ImplicitParamType->getAs<RecordType>()->getDecl());
-
+
Candidate.Conversions[0]
- = TryObjectArgumentInitialization(*this, From->getType(),
- From->Classify(Context),
+ = TryObjectArgumentInitialization(*this, From->getType(),
+ From->Classify(Context),
Conversion, ConversionContext);
-
+
if (Candidate.Conversions[0].isBad()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_conversion;
return;
}
- // We won't go through a user-define type conversion function to convert a
+ // We won't go through a user-define type conversion function to convert a
// derived to base as such conversions are given Conversion Rank. They only
// go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user]
QualType FromCanon
Candidate.FailureKind = ovl_fail_trivial_conversion;
return;
}
-
+
// To determine what the conversion from the result of calling the
// conversion function to the type we're eventually trying to
// convert to (ToType), we need to synthesize a call to the
switch (ICS.getKind()) {
case ImplicitConversionSequence::StandardConversion:
Candidate.FinalConversion = ICS.Standard;
-
+
// C++ [over.ics.user]p3:
// If the user-defined conversion is specified by a specialization of a
- // conversion function template, the second standard conversion sequence
+ // conversion function template, the second standard conversion sequence
// shall have exact match rank.
if (Conversion->getPrimaryTemplate() &&
GetConversionRank(ICS.Standard.Second) != ICR_Exact_Match) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_final_conversion_not_exact;
}
-
+
// C++0x [dcl.init.ref]p5:
// In the second case, if the reference is an rvalue reference and
// the second standard conversion sequence of the user-defined
// conversion sequence includes an lvalue-to-rvalue conversion, the
// program is ill-formed.
- if (ToType->isRValueReferenceType() &&
+ if (ToType->isRValueReferenceType() &&
ICS.Standard.First == ICK_Lvalue_To_Rvalue) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_final_conversion;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = 1;
- Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+ Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
return;
}
// Determine the implicit conversion sequence for the implicit
// object parameter.
ImplicitConversionSequence ObjectInit
- = TryObjectArgumentInitialization(*this, Object->getType(),
+ = TryObjectArgumentInitialization(*this, Object->getType(),
Object->Classify(Context),
Conversion, ActingContext);
if (ObjectInit.isBad()) {
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
- Candidate.Conversions[0].UserDefined.FoundConversionFunction
+ Candidate.Conversions[0].UserDefined.FoundConversionFunction
= FoundDecl.getDecl();
Candidate.Conversions[0].UserDefined.After
= Candidate.Conversions[0].UserDefined.Before;
Oper != OperEnd;
++Oper)
AddMethodCandidate(Oper.getPair(), Args[0]->getType(),
- Args[0]->Classify(Context), Args + 1, NumArgs - 1,
+ Args[0]->Classify(Context), Args + 1, NumArgs - 1,
CandidateSet,
/* SuppressUserConversions = */ false);
}
/// used in the built-in candidates.
TypeSet EnumerationTypes;
- /// \brief The set of vector types that will be used in the built-in
+ /// \brief The set of vector types that will be used in the built-in
/// candidates.
TypeSet VectorTypes;
SemaRef(SemaRef),
Context(SemaRef.Context) { }
- void AddTypesConvertedFrom(QualType Ty,
+ void AddTypesConvertedFrom(QualType Ty,
SourceLocation Loc,
bool AllowUserConversions,
bool AllowExplicitConversions,
/// enumeration_end - Past the last enumeration type found;
iterator enumeration_end() { return EnumerationTypes.end(); }
-
+
iterator vector_begin() { return VectorTypes.begin(); }
iterator vector_end() { return VectorTypes.end(); }
// Insert this type.
if (!PointerTypes.insert(Ty))
return false;
-
+
QualType PointeeTy;
const PointerType *PointerTy = Ty->getAs<PointerType>();
bool buildObjCPtr = false;
}
else
PointeeTy = PointerTy->getPointeeType();
-
+
// Don't add qualified variants of arrays. For one, they're not allowed
// (the qualifier would sink to the element type), and for another, the
// only overload situation where it matters is subscript or pointer +- int,
BaseCVR = Array->getElementType().getCVRQualifiers();
bool hasVolatile = VisibleQuals.hasVolatile();
bool hasRestrict = VisibleQuals.hasRestrict();
-
+
// Iterate through all strict supersets of BaseCVR.
for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) {
if ((CVR | BaseCVR) != CVR) continue;
unsigned BaseCVR = PointeeTy.getCVRQualifiers();
for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) {
if ((CVR | BaseCVR) != CVR) continue;
-
+
QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
MemberPointerTypes.insert(
Context.getMemberPointerType(QPointeeTy, ClassTy));
VRQuals.addRestrict();
return VRQuals;
}
-
+
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
if (!ClassDecl->hasDefinition())
return VRQuals;
const UnresolvedSetImpl *Conversions =
ClassDecl->getVisibleConversionFunctions();
-
+
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
NamedDecl *D = I.getDecl();
while (!done) {
if (const PointerType *ResTypePtr = CanTy->getAs<PointerType>())
CanTy = ResTypePtr->getPointeeType();
- else if (const MemberPointerType *ResTypeMPtr =
+ else if (const MemberPointerType *ResTypeMPtr =
CanTy->getAs<MemberPointerType>())
CanTy = ResTypeMPtr->getPointeeType();
else
// T& operator*(T*);
//
// C++ [over.built]p7:
- // For every function type T that does not have cv-qualifiers or a
+ // For every function type T that does not have cv-qualifiers or a
// ref-qualifier, there exist candidate operator functions of the form
// T& operator*(T*);
void addUnaryStarPointerOverloads() {
QualType PointeeTy = ParamTy->getPointeeType();
if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType())
continue;
-
+
if (const FunctionProtoType *Proto =PointeeTy->getAs<FunctionProtoType>())
if (Proto->getTypeQuals() || Proto->getRefQualifier())
continue;
-
+
S.AddBuiltinCandidate(S.Context.getLValueReferenceType(PointeeTy),
&ParamTy, Args, 1, CandidateSet);
}
QualType PointeeType = (*Ptr)->getPointeeType();
if (!PointeeType->isObjectType())
continue;
-
+
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
// T& operator[](T*, ptrdiff_t)
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
if (ExplicitTemplateArgs)
continue;
-
+
AddOverloadCandidate(FD, FoundDecl, Args, NumArgs, CandidateSet,
false, PartialOverloading);
} else
= S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
Cand2.Function->getPrimaryTemplate(),
Loc,
- isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
+ isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
: TPOC_Call,
Cand1.ExplicitCallArguments))
return BetterTemplate == Cand1.Function->getPrimaryTemplate();
}
-
+
// -- the context is an initialization by user-defined conversion
// (see 8.5, 13.3.1.5) and the standard conversion sequence
// from the return type of F1 to the destination type (i.e.,
Best = end();
for (iterator Cand = begin(); Cand != end(); ++Cand) {
if (Cand->Viable)
- if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc,
+ if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc,
UserDefinedConversion))
Best = Cand;
}
for (iterator Cand = begin(); Cand != end(); ++Cand) {
if (Cand->Viable &&
Cand != Best &&
- !isBetterOverloadCandidate(S, *Best, *Cand, Loc,
+ !isBetterOverloadCandidate(S, *Best, *Cand, Loc,
UserDefinedConversion)) {
Best = end();
return OR_Ambiguous;
// placement new (5.3.4), as well as non-default initialization (8.5).
if (Best->Function)
S.MarkDeclarationReferenced(Loc, Best->Function);
-
+
return OR_Success;
}
FromPtrTy->getPointeeType()) &&
!FromPtrTy->getPointeeType()->isIncompleteType() &&
!ToPtrTy->getPointeeType()->isIncompleteType() &&
- S.IsDerivedFrom(ToPtrTy->getPointeeType(),
+ S.IsDerivedFrom(ToPtrTy->getPointeeType(),
FromPtrTy->getPointeeType()))
BaseToDerivedConversion = 1;
}
S.IsDerivedFrom(ToRefTy->getPointeeType(), FromTy))
BaseToDerivedConversion = 3;
}
-
+
if (BaseToDerivedConversion) {
- S.Diag(Fn->getLocation(),
+ S.Diag(Fn->getLocation(),
diag::note_ovl_candidate_bad_base_to_derived_conv)
<< (unsigned) FnKind << FnDesc
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
<< (BaseToDerivedConversion - 1)
- << FromTy << ToTy << I+1;
+ << FromTy << ToTy << I+1;
return;
}
-
+
// TODO: specialize more based on the kind of mismatch
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
<< (unsigned) FnKind << FnDesc
const FunctionProtoType *FnTy = Fn->getType()->getAs<FunctionProtoType>();
unsigned MinParams = Fn->getMinRequiredArguments();
-
+
// at least / at most / exactly
unsigned mode, modeCount;
if (NumFormalArgs < MinParams) {
assert((Cand->FailureKind == ovl_fail_too_few_arguments) ||
(Cand->FailureKind == ovl_fail_bad_deduction &&
Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments));
- if (MinParams != FnTy->getNumArgs() ||
+ if (MinParams != FnTy->getNumArgs() ||
FnTy->isVariadic() || FnTy->isTemplateVariadic())
mode = 0; // "at least"
else
OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description);
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity)
- << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != 0) << mode
+ << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != 0) << mode
<< modeCount << NumFormalArgs;
}
else {
which = 2;
}
-
+
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_inconsistent_deduction)
- << which << ParamD->getDeclName()
+ << which << ParamD->getDeclName()
<< *Cand->DeductionFailure.getFirstArg()
<< *Cand->DeductionFailure.getSecondArg();
return;
}
case Sema::TDK_InvalidExplicitArguments:
- assert(ParamD && "no parameter found for invalid explicit arguments");
+ assert(ParamD && "no parameter found for invalid explicit arguments");
if (ParamD->getDeclName())
- S.Diag(Fn->getLocation(),
+ S.Diag(Fn->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_named)
<< ParamD->getDeclName();
else {
index = NTTP->getIndex();
else
index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
- S.Diag(Fn->getLocation(),
+ S.Diag(Fn->getLocation(),
diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
<< (index + 1);
}
return;
-
+
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
DiagnoseArityMismatch(S, Cand, NumArgs);
<< ArgString;
return;
}
-
+
// TODO: diagnose these individually, then kill off
// note_ovl_candidate_bad_deduction, which is uselessly vague.
case Sema::TDK_NonDeducedMismatch:
for (unsigned N = Cand->Conversions.size(); I != N; ++I)
if (Cand->Conversions[I].isBad())
return DiagnoseBadConversion(S, Cand, I);
-
+
// FIXME: this currently happens when we're called from SemaInit
// when user-conversion overload fails. Figure out how to handle
// those conditions and diagnose them well.
Cand->Conversions[ConvIdx]
= TryCopyInitialization(S, Args[ConvIdx],
Cand->BuiltinTypes.ParamTypes[ConvIdx],
- SuppressUserConversions,
+ SuppressUserConversions,
/*InOverloadResolution*/ true);
return;
}
if (ArgIdx < NumArgsInProto)
Cand->Conversions[ConvIdx]
= TryCopyInitialization(S, Args[ArgIdx], Proto->getArgType(ArgIdx),
- SuppressUserConversions,
+ SuppressUserConversions,
/*InOverloadResolution=*/true);
else
Cand->Conversions[ConvIdx].setEllipsis();
std::sort(Cands.begin(), Cands.end(),
CompareOverloadCandidatesForDisplay(S));
-
+
bool ReportedAmbiguousConversions = false;
llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
// parentheses.
OverloadExpr::FindResult Ovl = OverloadExpr::find(From);
OverloadExpr *OvlExpr = Ovl.Expression;
-
+
// We expect a pointer or reference to function, or a function pointer.
FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
if (!FunctionType->isFunctionType()) {
if (Complain)
Diag(From->getLocStart(), diag::err_addr_ovl_not_func_ptrref)
<< OvlExpr->getName() << ToType;
-
+
return 0;
}
// whose type matches exactly.
llvm::SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
llvm::SmallVector<FunctionDecl *, 4> NonMatches;
-
+
bool FoundNonTemplateFunction = false;
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
E = OvlExpr->decls_end(); I != E; ++I) {
// when converting to member pointer.
if (Method->isStatic() == IsMember)
continue;
-
+
// If we have explicit template arguments, skip non-templates.
if (OvlExpr->hasExplicitTemplateArgs())
continue;
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) {
QualType ResultTy;
if (Context.hasSameUnqualifiedType(FunctionType, FunDecl->getType()) ||
- IsNoReturnConversion(Context, FunDecl->getType(), FunctionType,
+ IsNoReturnConversion(Context, FunDecl->getType(), FunctionType,
ResultTy)) {
Matches.push_back(std::make_pair(I.getPair(),
cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
Diag(From->getLocStart(), diag::err_addr_ovl_no_viable)
<< OvlExpr->getName() << FunctionType;
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
- E = OvlExpr->decls_end();
+ E = OvlExpr->decls_end();
I != E; ++I)
if (FunctionDecl *F = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
NoteOverloadCandidate(F);
}
-
+
return 0;
} else if (Matches.size() == 1) {
FunctionDecl *Result = Matches[0].second;
- FoundResult = Matches[0].first;
+ FoundResult = Matches[0].first;
MarkDeclarationReferenced(From->getLocStart(), Result);
if (Complain) {
CheckAddressOfMemberAccess(OvlExpr, Matches[0].first);
UnresolvedSet<4> MatchesCopy; // TODO: avoid!
for (unsigned I = 0, E = Matches.size(); I != E; ++I)
MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess());
-
+
UnresolvedSetIterator Result =
getMostSpecialized(MatchesCopy.begin(), MatchesCopy.end(),
TPOC_Other, 0, From->getLocStart(),
<< (unsigned) oc_function_template);
if (Result == MatchesCopy.end())
return 0;
-
+
MarkDeclarationReferenced(From->getLocStart(), *Result);
FoundResult = Matches[Result - MatchesCopy.begin()].first;
if (Complain)
Matches.set_size(N);
}
}
-
+
// [...] After such eliminations, if any, there shall remain exactly one
// selected function.
if (Matches.size() == 1) {
return 0;
}
-/// \brief Given an expression that refers to an overloaded function, try to
+/// \brief Given an expression that refers to an overloaded function, try to
/// resolve that overloaded function expression down to a single function.
///
/// This routine can only resolve template-ids that refer to a single function
/// template, where that template-id refers to a single template whose template
-/// arguments are either provided by the template-id or have defaults,
+/// arguments are either provided by the template-id or have defaults,
/// as described in C++0x [temp.arg.explicit]p3.
FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
// C++ [over.over]p1:
return 0;
OverloadExpr *OvlExpr = OverloadExpr::find(From).Expression;
-
+
// If we didn't actually find any template-ids, we're done.
if (!OvlExpr->hasExplicitTemplateArgs())
return 0;
TemplateArgumentListInfo ExplicitTemplateArgs;
OvlExpr->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
-
+
// Look through all of the overloaded functions, searching for one
// whose type matches exactly.
FunctionDecl *Matched = 0;
E = OvlExpr->decls_end(); I != E; ++I) {
// C++0x [temp.arg.explicit]p3:
// [...] In contexts where deduction is done and fails, or in contexts
- // where deduction is not done, if a template argument list is
- // specified and it, along with any default template arguments,
- // identifies a single function template specialization, then the
+ // where deduction is not done, if a template argument list is
+ // specified and it, along with any default template arguments,
+ // identifies a single function template specialization, then the
// template-id is an lvalue for the function template specialization.
FunctionTemplateDecl *FunctionTemplate
= cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl());
-
+
// C++ [over.over]p2:
// If the name is a function template, template argument deduction is
// done (14.8.2.2), and if the argument deduction succeeds, the
// FIXME: make a note of the failed deduction for diagnostics.
(void)Result;
continue;
- }
-
+ }
+
// Multiple matches; we can't resolve to a single declaration.
if (Matched)
return 0;
Matched = Specialization;
}
-
+
return Matched;
}
-
+
/// \brief Add a single candidate to the overload set.
static void AddOverloadedCallCandidate(Sema &S,
DeclAccessPair FoundDecl,
// do nothing?
}
-
+
/// \brief Add the overload candidates named by callee and/or found by argument
/// dependent lookup to the given overload set.
void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
E = ULE->decls_end(); I != E; ++I)
AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs,
- Args, NumArgs, CandidateSet,
+ Args, NumArgs, CandidateSet,
PartialOverloading);
if (ULE->requiresADL())
Args, NumArgs,
ExplicitTemplateArgs,
CandidateSet,
- PartialOverloading);
+ PartialOverloading);
}
/// Attempts to recover from a call where no functions were found.
(F = dyn_cast<FunctionDecl>(*ULE->decls_begin())) &&
F->getBuiltinID() && F->isImplicit())
assert(0 && "performing ADL for builtin");
-
+
// We don't perform ADL in C.
assert(getLangOptions().CPlusPlus && "ADL enabled in C");
}
if (Input->isTypeDependent()) {
if (Fns.empty())
return Owned(new (Context) UnaryOperator(Input,
- Opc,
+ Opc,
Context.DependentTy,
VK_RValue, OK_Ordinary,
OpLoc));
-
+
CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, NamingClass,
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
Context,
FnDecl->getParamDecl(0)),
- SourceLocation(),
+ SourceLocation(),
Input);
if (InputInit.isInvalid())
return ExprError();
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
Args, NumArgs, ResultTy, VK, OpLoc);
- if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
+ if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
FnDecl))
return ExprError();
// expression.
if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
if (Fns.empty()) {
- // If there are no functions to store, just build a dependent
+ // If there are no functions to store, just build a dependent
// BinaryOperator or CompoundAssignment.
if (Opc <= BO_Assign || Opc > BO_OrAssign)
return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
Context.DependentTy,
VK_RValue, OK_Ordinary,
OpLoc));
-
+
return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc,
Context.DependentTy,
VK_LValue,
// TODO: provide better source location info in DNLoc component.
DeclarationNameInfo OpNameInfo(OpName, OpLoc);
UnresolvedLookupExpr *Fn
- = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(),
+ = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(),
OpNameInfo, /*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
if (Arg1.isInvalid())
return ExprError();
- if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+ if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Best->FoundDecl, Method))
return ExprError();
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
Args, 2, ResultTy, VK, OpLoc);
-
- if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
+
+ if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
FnDecl))
return ExprError();
// operator do not fall through to handling in built-in, but report that
// no overloaded assignment operator found
ExprResult Result = ExprError();
- if (Args[0]->getType()->isRecordType() &&
+ if (Args[0]->getType()->isRecordType() &&
Opc >= BO_Assign && Opc <= BO_OrAssign) {
Diag(OpLoc, diag::err_ovl_no_viable_oper)
<< BinaryOperator::getOpcodeStr(Opc)
// produce an error. Then, show the non-viable candidates.
Result = CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
}
- assert(Result.isInvalid() &&
+ assert(Result.isInvalid() &&
"C++ binary operator overloading is missing candidates!");
if (Result.isInvalid())
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
// Convert the arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
- if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+ if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Best->FoundDecl, Method))
return ExprError();
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
Context,
FnDecl->getParamDecl(0)),
- SourceLocation(),
+ SourceLocation(),
Owned(Args[1]));
if (InputInit.isInvalid())
return ExprError();
case OR_Ambiguous:
Diag(LLoc, diag::err_ovl_ambiguous_oper_binary)
- << "[]"
+ << "[]"
<< Args[0]->getType() << Args[1]->getType()
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, 2,
// Dig out the member expression. This holds both the object
// argument and the member function we're referring to.
Expr *NakedMemExpr = MemExprE->IgnoreParens();
-
+
MemberExpr *MemExpr;
CXXMethodDecl *Method = 0;
DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_public);
} else {
UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr);
Qualifier = UnresExpr->getQualifier();
-
+
QualType ObjectType = UnresExpr->getBaseType();
Expr::Classification ObjectClassification
= UnresExpr->isArrow()? Expr::Classification::makeSimpleLValue()
// non-template member function.
if (TemplateArgs)
continue;
-
+
AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType,
- ObjectClassification,
- Args, NumArgs, CandidateSet,
+ ObjectClassification,
+ Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/false);
} else {
AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(Func),
I.getPair(), ActingDC, TemplateArgs,
- ObjectType, ObjectClassification,
+ ObjectType, ObjectClassification,
Args, NumArgs, CandidateSet,
/*SuppressUsedConversions=*/false);
}
ResultType = ResultType.getNonLValueExprType(Context);
assert(Method && "Member call to something that isn't a method?");
- CXXMemberCallExpr *TheCall =
+ CXXMemberCallExpr *TheCall =
new (Context) CXXMemberCallExpr(Context, MemExprE, Args, NumArgs,
ResultType, VK, RParenLoc);
// Check for a valid return type.
- if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(),
+ if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(),
TheCall, Method))
return ExprError();
-
+
// Convert the object argument (for a non-static member function call).
// We only need to do this if there was actually an overload; otherwise
// it was done at lookup.
OverloadCandidateSet CandidateSet(LParenLoc);
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
- if (RequireCompleteType(LParenLoc, Object->getType(),
+ if (RequireCompleteType(LParenLoc, Object->getType(),
PDiag(diag::err_incomplete_object_call)
<< Object->getSourceRange()))
return true;
-
+
LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
LookupQualifiedName(R, Record->getDecl());
R.suppressDiagnostics();
Object->Classify(Context), Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/ false);
}
-
+
// C++ [over.call.object]p2:
// In addition, for each conversion function declared in T of the
// form
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
-
+
// Skip over templated conversion functions; they aren't
// surrogates.
if (isa<FunctionTemplateDecl>(D))
// We selected one of the surrogate functions that converts the
// object parameter to a function pointer. Perform the conversion
// on the object argument, then let ActOnCallExpr finish the job.
-
+
// Create an implicit member expr to refer to the conversion operator.
// and then call it.
ExprResult Call = BuildCXXMemberCallExpr(Object, Best->FoundDecl, Conv);
if (Call.isInvalid())
return ExprError();
-
+
return ActOnCallExpr(S, Call.get(), LParenLoc, MultiExprArg(Args, NumArgs),
RParenLoc);
}
ResultTy, VK, RParenLoc);
delete [] MethodArgs;
- if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall,
+ if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall,
Method))
return true;
-
+
// We may have default arguments. If so, we need to allocate more
// slots in the call for them.
if (NumArgs < NumArgsInProto)
bool IsError = false;
// Initialize the implicit object parameter.
- IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0,
+ IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0,
Best->FoundDecl, Method);
TheCall->setArg(0, Object);
Context,
Method->getParamDecl(i)),
SourceLocation(), Arg);
-
+
IsError |= InputInit.isInvalid();
Arg = InputInit.takeAs<Expr>();
} else {
IsError = true;
break;
}
-
+
Arg = DefArg.takeAs<Expr>();
}
// Build the operator call.
Expr *FnExpr = CreateFunctionRefExpr(*this, Method);
-
+
QualType ResultTy = Method->getResultType();
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
+ new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
&Base, 1, ResultTy, VK, OpLoc);
- if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall,
+ if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall,
Method))
return ExprError();
return Owned(TheCall);
Found, Fn);
if (SubExpr == PE->getSubExpr())
return PE;
-
+
return new (Context) ParenExpr(PE->getLParen(), PE->getRParen(), SubExpr);
- }
-
+ }
+
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(),
Found, Fn);
- assert(Context.hasSameType(ICE->getSubExpr()->getType(),
+ assert(Context.hasSameType(ICE->getSubExpr()->getType(),
SubExpr->getType()) &&
"Implicit cast type cannot be determined from overload");
assert(ICE->path_empty() && "fixing up hierarchy conversion?");
if (SubExpr == ICE->getSubExpr())
return ICE;
-
- return ImplicitCastExpr::Create(Context, ICE->getType(),
+
+ return ImplicitCastExpr::Create(Context, ICE->getType(),
ICE->getCastKind(),
SubExpr, 0,
ICE->getValueKind());
- }
-
+ }
+
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
assert(UnOp->getOpcode() == UO_AddrOf &&
"Can only take the address of an overloaded function");
Found, Fn);
if (SubExpr == UnOp->getSubExpr())
return UnOp;
-
+
return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
Context.getPointerType(SubExpr->getType()),
VK_RValue, OK_Ordinary,
UnOp->getOperatorLoc());
- }
+ }
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
// FIXME: avoid copy.
Base = MemExpr->getBase();
return MemberExpr::Create(Context, Base,
- MemExpr->isArrow(),
- MemExpr->getQualifier(),
+ MemExpr->isArrow(),
+ MemExpr->getQualifier(),
MemExpr->getQualifierRange(),
- Fn,
+ Fn,
Found,
MemExpr->getMemberNameInfo(),
TemplateArgs,
? VK_LValue : VK_RValue,
OK_Ordinary);
}
-
+
llvm_unreachable("Invalid reference to overloaded function");
return E;
}
-ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
+ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
DeclAccessPair Found,
FunctionDecl *Fn) {
return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
-
+
// If we have an invalid decl, just return.
if (DG.isNull() || !DG.isSingleDecl()) return;
// suppress any potential 'unused variable' warning.
Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
return;
}
- }
+ }
} else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
const ObjCMethodDecl *MD = ME->getMethodDecl();
if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
Expr *ConditionExpr = CondResult.takeAs<Expr>();
if (!ConditionExpr)
return StmtError();
-
+
DiagnoseUnusedExprResult(thenStmt);
// Warn if the if block has a null body without an else value.
DiagnoseUnusedExprResult(elseStmt);
- return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
+ return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
thenStmt, ElseLoc, elseStmt));
}
} else if (NewSign != Val.isSigned()) {
// Convert the sign to match the sign of the condition. This can cause
// overflow as well: unsigned(INTMIN)
- // We don't diagnose this overflow, because it is implementation-defined
+ // We don't diagnose this overflow, because it is implementation-defined
// behavior.
// FIXME: Introduce a second, default-ignored warning for this case?
llvm::APSInt OldVal(Val);
}
StmtResult
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
Decl *CondVar) {
ExprResult CondResult;
CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
if (CondResult.isInvalid())
return StmtError();
-
+
Cond = CondResult.release();
}
-
+
if (!Cond)
return StmtError();
-
+
CondResult
- = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond,
+ = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond,
PDiag(diag::err_typecheck_statement_requires_integer),
PDiag(diag::err_switch_incomplete_class_type)
<< Cond->getSourceRange(),
PDiag(0));
if (CondResult.isInvalid()) return StmtError();
Cond = CondResult.take();
-
+
if (!CondVar) {
CheckImplicitConversions(Cond, SwitchLoc);
CondResult = MaybeCreateExprWithCleanups(Cond);
}
getCurFunction()->setHasBranchIntoScope();
-
+
SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
getCurFunction()->SwitchStack.push_back(SS);
return Owned(SS);
if (SS->getCond() == 0)
return StmtError();
-
+
Expr *CondExpr = SS->getCond();
Expr *CondExprBeforePromotion = CondExpr;
QualType CondTypeBeforePromotion =
// the pre-promotion type of the switch condition.
if (!CondExpr->isTypeDependent()) {
// We have already converted the expression to an integral or enumeration
- // type, when we started the switch statement. If we don't have an
+ // type, when we started the switch statement. If we don't have an
// appropriate type now, just return an error.
if (!CondType->isIntegralOrEnumerationType())
return StmtError();
RI != CaseRanges.end() && EI != EIend; RI++) {
while (EI != EIend && EI->first < RI->first)
EI++;
-
+
if (EI == EIend || EI->first != RI->first) {
Diag(RI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
<< ED->getDeclName();
<< ED->getDeclName();
}
}
-
+
// Check which enum vals aren't in switch
CaseValsTy::const_iterator CI = CaseVals.begin();
CaseRangesTy::const_iterator RI = CaseRanges.begin();
bool hasCasesNotInSwitch = false;
llvm::SmallVector<DeclarationName,8> UnhandledNames;
-
+
for (EnumValsTy::const_iterator EI = EnumVals.begin(); EI != EIend; EI++){
// Drop unneeded case values
llvm::APSInt CIVal;
while (CI != CaseVals.end() && CI->first < EI->first)
CI++;
-
+
if (CI != CaseVals.end() && CI->first == EI->first)
continue;
UnhandledNames.push_back(EI->second->getDeclName());
}
}
-
+
// Produce a nice diagnostic if multiple values aren't handled.
switch (UnhandledNames.size()) {
case 0: break;
}
StmtResult
-Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
+Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
Decl *CondVar, Stmt *Body) {
ExprResult CondResult(Cond.release());
-
+
VarDecl *ConditionVar = 0;
if (CondVar) {
ConditionVar = cast<VarDecl>(CondVar);
Expr *ConditionExpr = CondResult.take();
if (!ConditionExpr)
return StmtError();
-
+
DiagnoseUnusedExprResult(Body);
return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
if (CondResult.isInvalid())
return StmtError();
Cond = CondResult.take();
-
+
DiagnoseUnusedExprResult(Body);
return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
if (SecondResult.isInvalid())
return StmtError();
}
-
+
Expr *Third = third.release().takeAs<Expr>();
-
+
DiagnoseUnusedExprResult(First);
DiagnoseUnusedExprResult(Third);
DiagnoseUnusedExprResult(Body);
- return Owned(new (Context) ForStmt(Context, First,
- SecondResult.take(), ConditionVar,
- Third, Body, ForLoc, LParenLoc,
+ return Owned(new (Context) ForStmt(Context, First,
+ SecondResult.take(), ConditionVar,
+ Third, Body, ForLoc, LParenLoc,
RParenLoc));
}
else if (const ObjCObjectPointerType *OPT =
SecondType->getAsObjCInterfacePointerType()) {
llvm::SmallVector<IdentifierInfo *, 4> KeyIdents;
- IdentifierInfo* selIdent =
+ IdentifierInfo* selIdent =
&Context.Idents.get("countByEnumeratingWithState");
KeyIdents.push_back(selIdent);
selIdent = &Context.Idents.get("objects");
KeyIdents.push_back(selIdent);
Selector CSelector = Context.Selectors.getSelector(3, &KeyIdents[0]);
if (ObjCInterfaceDecl *IDecl = OPT->getInterfaceDecl()) {
- if (!IDecl->isForwardDecl() &&
+ if (!IDecl->isForwardDecl() &&
!IDecl->lookupInstanceMethod(CSelector)) {
// Must further look into private implementation methods.
if (!LookupPrivateInstanceMethod(CSelector, IDecl))
return Owned(new (Context) BreakStmt(BreakLoc));
}
-/// \brief Determine whether the given expression is a candidate for
+/// \brief Determine whether the given expression is a candidate for
/// copy elision in either a return statement or a throw expression.
///
/// \param ReturnType If we're determining the copy elision candidate for
if (!Context.hasSameUnqualifiedType(ReturnType, ExprType))
return 0;
}
-
- // ... the expression is the name of a non-volatile automatic object
+
+ // ... the expression is the name of a non-volatile automatic object
// (other than a function or catch-clause parameter)) ...
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
if (!DR)
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
if (!VD)
return 0;
-
+
if (VD->hasLocalStorage() && !VD->isExceptionVariable() &&
!VD->getType()->isReferenceType() && !VD->hasAttr<BlocksAttr>() &&
!VD->getType().isVolatileQualified() &&
((VD->getKind() == Decl::Var) ||
(AllowFunctionParameter && VD->getKind() == Decl::ParmVar)))
return VD;
-
+
return 0;
}
/// This routine implements C++0x [class.copy]p33, which attempts to treat
/// returned lvalues as rvalues in certain cases (to prefer move construction),
/// then falls back to treating them as lvalues if that failed.
-ExprResult
+ExprResult
Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
const VarDecl *NRVOCandidate,
QualType ResultType,
Expr *Value) {
// C++0x [class.copy]p33:
- // When the criteria for elision of a copy operation are met or would
- // be met save for the fact that the source object is a function
- // parameter, and the object to be copied is designated by an lvalue,
+ // When the criteria for elision of a copy operation are met or would
+ // be met save for the fact that the source object is a function
+ // parameter, and the object to be copied is designated by an lvalue,
// overload resolution to select the constructor for the copy is first
// performed as if the object were designated by an rvalue.
ExprResult Res = ExprError();
if (NRVOCandidate || getCopyElisionCandidate(ResultType, Value, true)) {
- ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack,
+ ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack,
Value->getType(), CK_LValueToRValue,
Value, VK_XValue);
-
+
Expr *InitExpr = &AsRvalue;
- InitializationKind Kind
+ InitializationKind Kind
= InitializationKind::CreateCopy(Value->getLocStart(),
Value->getLocStart());
InitializationSequence Seq(*this, Entity, Kind, &InitExpr, 1);
-
- // [...] If overload resolution fails, or if the type of the first
+
+ // [...] If overload resolution fails, or if the type of the first
// parameter of the selected constructor is not an rvalue reference
// to the object's type (possibly cv-qualified), overload resolution
// is performed again, considering the object as an lvalue.
for (InitializationSequence::step_iterator Step = Seq.step_begin(),
StepEnd = Seq.step_end();
Step != StepEnd; ++Step) {
- if (Step->Kind
+ if (Step->Kind
!= InitializationSequence::SK_ConstructorInitialization)
continue;
-
- CXXConstructorDecl *Constructor
+
+ CXXConstructorDecl *Constructor
= cast<CXXConstructorDecl>(Step->Function.Function);
-
+
const RValueReferenceType *RRefType
= Constructor->getParamDecl(0)->getType()
->getAs<RValueReferenceType>();
-
+
// If we don't meet the criteria, break out now.
- if (!RRefType ||
+ if (!RRefType ||
!Context.hasSameUnqualifiedType(RRefType->getPointeeType(),
Context.getTypeDeclType(Constructor->getParent())))
break;
-
+
// Promote "AsRvalue" to the heap, since we now need this
// expression node to persist.
Value = ImplicitCastExpr::Create(Context, Value->getType(),
- CK_LValueToRValue, Value, 0,
+ CK_LValueToRValue, Value, 0,
VK_XValue);
-
+
// Complete type-checking the initialization of the return type
// using the constructor we found.
Res = Seq.Perform(*this, Entity, Kind, MultiExprArg(&Value, 1));
}
}
}
-
+
// Either we didn't meet the criteria for treating an lvalue as an rvalue,
- // above, or overload resolution failed. Either way, we need to try
+ // above, or overload resolution failed. Either way, we need to try
// (again) now with the return value expression as written.
if (Res.isInvalid())
Res = PerformCopyInitialization(Entity, SourceLocation(), Value);
-
+
return Res;
}
return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
} else {
const VarDecl *NRVOCandidate = 0;
-
+
if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
// we have a non-void block with an expression, continue checking
// In C++ the return statement is handled via a copy initialization.
// the C version of which boils down to CheckSingleAssignmentConstraints.
NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
- InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
+ InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
FnRetType,
NRVOCandidate != 0);
- ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
+ ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
FnRetType, RetValExp);
if (Res.isInvalid()) {
// FIXME: Cleanup temporaries here, anyway?
return StmtError();
}
-
+
if (RetValExp) {
CheckImplicitConversions(RetValExp, ReturnLoc);
RetValExp = MaybeCreateExprWithCleanups(RetValExp);
}
RetValExp = Res.takeAs<Expr>();
- if (RetValExp)
+ if (RetValExp)
CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
}
-
+
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
}
- // If we need to check for the named return value optimization, save the
+ // If we need to check for the named return value optimization, save the
// return statement in our scope for later processing.
if (getLangOptions().CPlusPlus && FnRetType->isRecordType() &&
!CurContext->isDependentContext())
FunctionScopes.back()->Returns.push_back(Result);
-
+
return Owned(Result);
}
CheckImplicitConversions(RetValExp, ReturnLoc);
RetValExp = MaybeCreateExprWithCleanups(RetValExp);
}
-
+
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
} else if (!RetValExp && !FnRetType->isDependentType()) {
unsigned DiagID = diag::warn_return_missing_expr; // C90 6.6.6.4p4
// In C++ the return statement is handled via a copy initialization.
// the C version of which boils down to CheckSingleAssignmentConstraints.
NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
- InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
+ InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
FnRetType,
NRVOCandidate != 0);
- ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
+ ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
FnRetType, RetValExp);
if (Res.isInvalid()) {
// FIXME: Cleanup temporaries here, anyway?
}
RetValExp = Res.takeAs<Expr>();
- if (RetValExp)
+ if (RetValExp)
CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
}
-
+
if (RetValExp) {
CheckImplicitConversions(RetValExp, ReturnLoc);
RetValExp = MaybeCreateExprWithCleanups(RetValExp);
}
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
}
-
- // If we need to check for the named return value optimization, save the
+
+ // If we need to check for the named return value optimization, save the
// return statement in our scope for later processing.
if (getLangOptions().CPlusPlus && FnRetType->isRecordType() &&
!CurContext->isDependentContext())
FunctionScopes.back()->Returns.push_back(Result);
-
+
return Owned(Result);
}
// Type dependent expressions will be checked during instantiation.
if (E->isTypeDependent())
return false;
-
+
if (E->isLValue())
return false; // Cool, this is an lvalue.
}
AsmStmt *NS =
- new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm,
- NumOutputs, NumInputs, Names, Constraints, Exprs,
+ new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm,
+ NumOutputs, NumInputs, Names, Constraints, Exprs,
AsmString, NumClobbers, Clobbers, RParenLoc);
// Validate the asm string, ensuring it makes sense given the operands we
// have.
enum AsmDomain {
AD_Int, AD_FP, AD_Other
} InputDomain, OutputDomain;
-
+
if (InTy->isIntegerType() || InTy->isPointerType())
InputDomain = AD_Int;
else if (InTy->isRealFloatingType())
OutputDomain = AD_FP;
else
OutputDomain = AD_Other;
-
+
// They are ok if they are the same size and in the same domain. This
// allows tying things like:
// void* to int*
// void* to int if they are the same size.
// double to long double if they are the same size.
- //
+ //
uint64_t OutSize = Context.getTypeSize(OutTy);
uint64_t InSize = Context.getTypeSize(InTy);
if (OutSize == InSize && InputDomain == OutputDomain &&
InputDomain != AD_Other)
continue;
-
+
// If the smaller input/output operand is not mentioned in the asm string,
// then we can promote it and the asm string won't notice. Check this
// case now.
VarDecl *Var = cast_or_null<VarDecl>(Parm);
if (Var && Var->isInvalidDecl())
return StmtError();
-
+
return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
}
}
StmtResult
-Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
+Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
MultiStmtArg CatchStmts, Stmt *Finally) {
getCurFunction()->setHasBranchProtectedScope();
unsigned NumCatchStmts = CatchStmts.size();
<< Throw->getType() << Throw->getSourceRange());
}
}
-
+
return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
}
StmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
Scope *CurScope) {
if (!Throw) {
// @throw without an expression designates a rethrow (which much occur
AtCatchParent = AtCatchParent->getParent();
if (!AtCatchParent)
return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
- }
-
+ }
+
return BuildObjCAtThrowStmt(AtLoc, Throw);
}
else if (Repl != Orig) {
// C++ [temp.local]p3:
- // A lookup that finds an injected-class-name (10.2) can result in an
+ // A lookup that finds an injected-class-name (10.2) can result in an
// ambiguity in certain cases (for example, if it is found in more than
- // one base class). If all of the injected-class-names that are found
- // refer to specializations of the same class template, and if the name
- // is followed by a template-argument-list, the reference refers to the
- // class template itself and not a specialization thereof, and is not
+ // one base class). If all of the injected-class-names that are found
+ // refer to specializations of the same class template, and if the name
+ // is followed by a template-argument-list, the reference refers to the
+ // class template itself and not a specialization thereof, and is not
// ambiguous.
//
// FIXME: Will we eventually have to do the same for alias templates?
DeclarationName TName;
MemberOfUnknownSpecialization = false;
-
+
switch (Name.getKind()) {
case UnqualifiedId::IK_Identifier:
TName = DeclarationName(Name.Identifier);
break;
-
+
case UnqualifiedId::IK_OperatorFunctionId:
TName = Context.DeclarationNames.getCXXOperatorName(
Name.OperatorFunctionId.Operator);
QualType ObjectType = ObjectTypePtr.get();
- LookupResult R(*this, TName, Name.getSourceRange().getBegin(),
+ LookupResult R(*this, TName, Name.getSourceRange().getBegin(),
LookupOrdinaryName);
LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
MemberOfUnknownSpecialization);
return TemplateKind;
}
-bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II,
+bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II,
SourceLocation IILoc,
Scope *S,
const CXXScopeSpec *SS,
if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
computeDeclContext(*SS))
return false;
-
+
// The code is missing a 'template' keyword prior to the dependent template
// name.
NestedNameSpecifier *Qualifier = (NestedNameSpecifier*)SS->getScopeRep();
Diag(IILoc, diag::err_template_kw_missing)
<< Qualifier << II.getName()
<< FixItHint::CreateInsertion(IILoc, "template ");
- SuggestedTemplate
+ SuggestedTemplate
= TemplateTy::make(Context.getDependentTemplateName(Qualifier, &II));
SuggestedKind = TNK_Dependent_template_name;
return true;
assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
LookupCtx = computeDeclContext(ObjectType);
isDependent = ObjectType->isDependentType();
- assert((isDependent || !ObjectType->isIncompleteType()) &&
+ assert((isDependent || !ObjectType->isIncompleteType()) &&
"Caller should have completed object type");
} else if (SS.isSet()) {
// This nested-name-specifier occurs after another nested-name-specifier,
// so long into the context associated with the prior nested-name-specifier.
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = isDependentScopeSpecifier(SS);
-
+
// The declaration context must be complete.
if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx))
return;
if (Found.empty() && !isDependent) {
// If we did not find any names, attempt to correct any typos.
DeclarationName Name = Found.getLookupName();
- if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx,
+ if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx,
false, CTC_CXXCasts)) {
FilterAcceptableTemplateNames(Context, Found);
if (!Found.empty()) {
LookupOrdinaryName);
LookupName(FoundOuter, S);
FilterAcceptableTemplateNames(Context, FoundOuter);
-
+
if (FoundOuter.empty()) {
// - if the name is not found, the name found in the class of the
// object expression is used, otherwise
if (!Found.isSingleResult() ||
Found.getFoundDecl()->getCanonicalDecl()
!= FoundOuter.getFoundDecl()->getCanonicalDecl()) {
- Diag(Found.getNameLoc(),
+ Diag(Found.getNameLoc(),
diag::ext_nested_name_member_ref_lookup_ambiguous)
<< Found.getLookupName()
<< ObjectType;
= static_cast<NestedNameSpecifier*>(SS.getScopeRep());
DeclContext *DC = getFunctionLevelDeclContext();
-
+
if (!isAddressOfOperand &&
isa<CXXMethodDecl>(DC) &&
cast<CXXMethodDecl>(DC)->isInstance()) {
QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context);
-
+
// Since the 'this' expression is synthesized, we don't need to
// perform the double-lookup check.
NamedDecl *FirstQualifierInScope = 0;
ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion(
SourceLocation EllipsisLoc) const {
- assert(Kind == Template &&
+ assert(Kind == Template &&
"Only template template arguments can be pack expansions here");
assert(getAsTemplate().get().containsUnexpandedParameterPack() &&
"Template template argument pack expansion without packs");
static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
const ParsedTemplateArgument &Arg) {
-
+
switch (Arg.getKind()) {
case ParsedTemplateArgument::Type: {
TypeSourceInfo *DI;
QualType T = SemaRef.GetTypeFromParser(Arg.getAsType(), &DI);
- if (!DI)
+ if (!DI)
DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getLocation());
return TemplateArgumentLoc(TemplateArgument(T), DI);
}
-
+
case ParsedTemplateArgument::NonType: {
Expr *E = static_cast<Expr *>(Arg.getAsExpr());
return TemplateArgumentLoc(TemplateArgument(E), E);
}
-
+
case ParsedTemplateArgument::Template: {
TemplateName Template = Arg.getAsTemplate().get();
TemplateArgument TArg;
Arg.getEllipsisLoc());
}
}
-
+
llvm_unreachable("Unhandled parsed template argument");
return TemplateArgumentLoc();
}
-
+
/// \brief Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis.
void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
TemplateArgs.addArgument(translateTemplateArgument(*this,
TemplateArgsIn[I]));
}
-
+
/// ActOnTypeParameter - Called when a C++ template type parameter
/// (e.g., "typename T") has been parsed. Typename specifies whether
/// the keyword "typename" was used to declare the type parameter
if (DefaultArg) {
TypeSourceInfo *DefaultTInfo;
GetTypeFromParser(DefaultArg, &DefaultTInfo);
-
+
assert(DefaultTInfo && "expected source information for type");
-
+
// Check for unexpanded parameter packs.
- if (DiagnoseUnexpandedParameterPack(Loc, DefaultTInfo,
+ if (DiagnoseUnexpandedParameterPack(Loc, DefaultTInfo,
UPPC_DefaultArgument))
return Param;
-
+
// Check the template argument itself.
if (CheckTemplateArgument(Param, DefaultTInfo)) {
Param->setInvalidDecl();
return Param;
}
-
+
Param->setDefaultArgument(DefaultTInfo, false);
}
-
+
return Param;
}
else if (T->isFunctionType())
// FIXME: Keep the type prior to promotion?
return Context.getPointerType(T);
-
+
Diag(Loc, diag::err_template_nontype_parm_bad_type)
<< T;
T = Context.IntTy; // Recover with an 'int' type.
Invalid = true;
}
-
+
bool IsParameterPack = D.hasEllipsis();
NonTypeTemplateParmDecl *Param
= NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
D.getIdentifierLoc(),
- Depth, Position, ParamName, T,
+ Depth, Position, ParamName, T,
IsParameterPack, TInfo);
if (Invalid)
Param->setInvalidDecl();
S->AddDecl(Param);
IdResolver.AddDecl(Param);
}
-
+
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
// template-parameter that is not a template parameter pack.
Param->setInvalidDecl();
return Param;
}
-
+
Param->setDefaultArgument(Default, false);
}
-
+
return Param;
}
// FIXME: Pack-ness is dropped
TemplateTemplateParmDecl *Param =
TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
- NameLoc.isInvalid()? TmpLoc : NameLoc,
- Depth, Position, IsParameterPack,
+ NameLoc.isInvalid()? TmpLoc : NameLoc,
+ Depth, Position, IsParameterPack,
Name, Params);
- // If the template template parameter has a name, then link the identifier
+ // If the template template parameter has a name, then link the identifier
// into the scope and lookup mechanisms.
if (Name) {
S->AddDecl(Param);
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
Default = ParsedTemplateArgument();
}
-
+
if (!Default.isInvalid()) {
// Check only that we have a template template argument. We don't want to
// try to check well-formedness now, because our template template parameter
<< DefaultArg.getSourceRange();
return Param;
}
-
+
// Check for unexpanded parameter packs.
- if (DiagnoseUnexpandedParameterPack(DefaultArg.getLocation(),
+ if (DiagnoseUnexpandedParameterPack(DefaultArg.getLocation(),
DefaultArg.getArgument().getAsTemplate(),
UPPC_DefaultArgument))
return Param;
-
+
Param->setDefaultArgument(DefaultArg, false);
}
-
+
return Param;
}
Diag(ExportLoc, diag::warn_template_export_unsupported);
return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
- (NamedDecl**)Params, NumParams,
+ (NamedDecl**)Params, NumParams,
RAngleLoc);
}
if (Previous.isAmbiguous())
return true;
-
+
NamedDecl *PrevDecl = 0;
if (Previous.begin() != Previous.end())
PrevDecl = (*Previous.begin())->getUnderlyingDecl();
= dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
// We may have found the injected-class-name of a class template,
- // class template partial specialization, or class template specialization.
+ // class template partial specialization, or class template specialization.
// In these cases, grab the template that is being defined or specialized.
- if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) &&
+ if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) &&
cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) {
PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext());
- PrevClassTemplate
+ PrevClassTemplate
= cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate();
if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) {
PrevClassTemplate
if (TUK == TUK_Friend) {
// C++ [namespace.memdef]p3:
- // [...] When looking for a prior declaration of a class or a function
- // declared as a friend, and when the name of the friend class or
+ // [...] When looking for a prior declaration of a class or a function
+ // declared as a friend, and when the name of the friend class or
// function is neither a qualified name nor a template-id, scopes outside
// the innermost enclosing namespace scope are not considered.
if (!SS.isSet()) {
SemanticContext = PrevDecl->getDeclContext();
} else {
// Declarations in outer scopes don't matter. However, the outermost
- // context we computed is the semantic context for our new
+ // context we computed is the semantic context for our new
// declaration.
PrevDecl = PrevClassTemplate = 0;
SemanticContext = OutermostContext;
}
} else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S))
PrevDecl = PrevClassTemplate = 0;
-
+
if (PrevClassTemplate) {
// Ensure that the template parameter lists are compatible.
if (!TemplateParameterListsAreEqual(TemplateParams,
Invalid = true;
if (SS.isSet()) {
- // If the name of the template was qualified, we must be defining the
+ // If the name of the template was qualified, we must be defining the
// template out-of-line.
if (!SS.isInvalid() && !Invalid && !PrevClassTemplate &&
!(TUK == TUK_Friend && CurContext->isDependentContext()))
Diag(NameLoc, diag::err_member_def_does_not_match)
<< Name << SemanticContext << SS.getRange();
- }
-
+ }
+
CXXRecordDecl *NewClass =
CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name, KWLoc,
PrevClassTemplate?
assert(T->isDependentType() && "Class template type is not dependent?");
(void)T;
- // If we are providing an explicit specialization of a member that is a
+ // If we are providing an explicit specialization of a member that is a
// class template, make a note of that.
- if (PrevClassTemplate &&
+ if (PrevClassTemplate &&
PrevClassTemplate->getInstantiatedFromMemberTemplate())
PrevClassTemplate->setMemberSpecialization();
-
+
// Set the access specifier.
if (!Invalid && TUK != TUK_Friend)
SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
NewTemplate->setObjectOfFriendDecl(/* PreviouslyDeclared = */
PrevClassTemplate != NULL);
-
+
// Friend templates are visible in fairly strange ways.
if (!CurContext->isDependentContext()) {
DeclContext *DC = SemanticContext->getRedeclContext();
DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false);
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
PushOnScopeChains(NewTemplate, EnclosingScope,
- /* AddToContext = */ false);
+ /* AddToContext = */ false);
}
-
+
FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
NewClass->getLocation(),
NewTemplate,
/// template parameter, which is ill-formed in certain contexts.
///
/// \returns true if the default template argument should be dropped.
-static bool DiagnoseDefaultTemplateArgument(Sema &S,
+static bool DiagnoseDefaultTemplateArgument(Sema &S,
Sema::TemplateParamListContext TPC,
SourceLocation ParamLoc,
SourceRange DefArgRange) {
return false;
case Sema::TPC_FunctionTemplate:
- // C++ [temp.param]p9:
+ // C++ [temp.param]p9:
// A default template-argument shall not be specified in a
// function template declaration or a function template
// definition [...]
// (This sentence is not in C++0x, per DR226).
if (!S.getLangOptions().CPlusPlus0x)
- S.Diag(ParamLoc,
+ S.Diag(ParamLoc,
diag::err_template_parameter_default_in_function_template)
<< DefArgRange;
return false;
for (unsigned I = 0, N = Params->size(); I != N; ++I) {
NamedDecl *P = Params->getParam(I);
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
- if (S.DiagnoseUnexpandedParameterPack(NTTP->getLocation(),
+ if (S.DiagnoseUnexpandedParameterPack(NTTP->getLocation(),
NTTP->getTypeSourceInfo(),
Sema::UPPC_NonTypeTemplateParameterType))
return true;
-
+
continue;
}
-
- if (TemplateTemplateParmDecl *InnerTTP
+
+ if (TemplateTemplateParmDecl *InnerTTP
= dyn_cast<TemplateTemplateParmDecl>(P))
if (DiagnoseUnexpandedParameterPacks(S, InnerTTP))
return true;
}
-
+
return false;
}
bool MissingDefaultArg = false;
// C++0x [temp.param]p11:
- // If a template parameter of a primary class template is a template
+ // If a template parameter of a primary class template is a template
// parameter pack, it shall be the last template parameter.
if (SawParameterPack && TPC == TPC_ClassTemplate) {
Diag(ParameterPackLoc,
if (TemplateTypeParmDecl *NewTypeParm
= dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
// Check the presence of a default argument here.
- if (NewTypeParm->hasDefaultArgument() &&
- DiagnoseDefaultTemplateArgument(*this, TPC,
- NewTypeParm->getLocation(),
+ if (NewTypeParm->hasDefaultArgument() &&
+ DiagnoseDefaultTemplateArgument(*this, TPC,
+ NewTypeParm->getLocation(),
NewTypeParm->getDefaultArgumentInfo()->getTypeLoc()
.getSourceRange()))
NewTypeParm->removeDefaultArgument();
= dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) {
// Check for unexpanded parameter packs.
if (DiagnoseUnexpandedParameterPack(NewNonTypeParm->getLocation(),
- NewNonTypeParm->getTypeSourceInfo(),
+ NewNonTypeParm->getTypeSourceInfo(),
UPPC_NonTypeTemplateParameterType)) {
Invalid = true;
continue;
}
// Check the presence of a default argument here.
- if (NewNonTypeParm->hasDefaultArgument() &&
- DiagnoseDefaultTemplateArgument(*this, TPC,
- NewNonTypeParm->getLocation(),
+ if (NewNonTypeParm->hasDefaultArgument() &&
+ DiagnoseDefaultTemplateArgument(*this, TPC,
+ NewNonTypeParm->getLocation(),
NewNonTypeParm->getDefaultArgument()->getSourceRange())) {
NewNonTypeParm->removeDefaultArgument();
}
// Check the presence of a default argument here.
TemplateTemplateParmDecl *NewTemplateParm
= cast<TemplateTemplateParmDecl>(*NewParam);
-
+
// Check for unexpanded parameter packs, recursively.
if (DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) {
Invalid = true;
continue;
}
-
- if (NewTemplateParm->hasDefaultArgument() &&
- DiagnoseDefaultTemplateArgument(*this, TPC,
- NewTemplateParm->getLocation(),
+
+ if (NewTemplateParm->hasDefaultArgument() &&
+ DiagnoseDefaultTemplateArgument(*this, TPC,
+ NewTemplateParm->getLocation(),
NewTemplateParm->getDefaultArgument().getSourceRange()))
NewTemplateParm->removeDefaultArgument();
Invalid = true;
} else if (MissingDefaultArg) {
// C++ [temp.param]p11:
- // If a template-parameter of a class template has a default
- // template-argument, each subsequent template-parameter shall either
+ // If a template-parameter of a class template has a default
+ // template-argument, each subsequent template-parameter shall either
// have a default template-argument supplied or be a template parameter
// pack.
Diag((*NewParam)->getLocation(),
NewParam != NewParamEnd; ++NewParam) {
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*NewParam))
TTP->removeDefaultArgument();
- else if (NonTypeTemplateParmDecl *NTTP
+ else if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(*NewParam))
NTTP->removeDefaultArgument();
else
cast<TemplateTemplateParmDecl>(*NewParam)->removeDefaultArgument();
}
}
-
+
return Invalid;
}
bool &IsExplicitSpecialization,
bool &Invalid) {
IsExplicitSpecialization = false;
-
+
// Find the template-ids that occur within the nested-name-specifier. These
// template-ids will match up with the template parameter lists.
llvm::SmallVector<const TemplateSpecializationType *, 4>
ExplicitSpecializationsInSpecifier.pop_back();
}
- // We have a template parameter list with no corresponding scope, which
+ // We have a template parameter list with no corresponding scope, which
// means that the resulting template declaration can't be instantiated
// properly (we'll end up with dependent nodes when we shouldn't).
if (!isExplicitSpecHeader)
Invalid = true;
-
+
++ParamIdx;
}
}
if (!isa<ClassTemplatePartialSpecializationDecl>(Record) &&
!Record->getDescribedClassTemplate())
continue;
-
+
// Fetch the injected class name type and check whether its
// injected type is equal to the type we just built.
QualType ICNT = Context.getTypeDeclType(Record);
// corresponds to these arguments.
void *InsertPos = 0;
ClassTemplateSpecializationDecl *Decl
- = ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
+ = ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
InsertPos);
if (!Decl) {
// This is the first time we have referenced this class template
ClassTemplate->getDeclContext(),
ClassTemplate->getLocation(),
ClassTemplate,
- Converted.data(),
+ Converted.data(),
Converted.size(), 0);
ClassTemplate->AddSpecialization(Decl, InsertPos);
Decl->setLexicalDeclContext(CurContext);
// We don't want lookup warnings at this point.
R.suppressDiagnostics();
-
+
UnresolvedLookupExpr *ULE
= UnresolvedLookupExpr::Create(Context, R.getNamingClass(),
Qualifier, QualifierRange,
R.getLookupNameInfo(),
- RequiresADL, TemplateArgs,
+ RequiresADL, TemplateArgs,
R.begin(), R.end());
return Owned(ULE);
if (R.isAmbiguous())
return ExprError();
-
+
if (R.empty()) {
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template)
<< NameInfo.getName() << SS.getRange();
/// example, given "MetaFun::template apply", the scope specifier \p
/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
/// of the "template" keyword, and "apply" is the \p Name.
-TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
+TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
SourceLocation TemplateKWLoc,
CXXScopeSpec &SS,
UnqualifiedId &Name,
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
!getLangOptions().CPlusPlus0x)
Diag(TemplateKWLoc, diag::ext_template_outside_of_template)
- << FixItHint::CreateRemoval(TemplateKWLoc);
-
+ << FixItHint::CreateRemoval(TemplateKWLoc);
+
DeclContext *LookupCtx = 0;
if (SS.isSet())
LookupCtx = computeDeclContext(SS, EnteringContext);
cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) {
// This is a dependent template. Handle it below.
} else if (TNK == TNK_Non_template) {
- Diag(Name.getSourceRange().getBegin(),
+ Diag(Name.getSourceRange().getBegin(),
diag::err_template_kw_refers_to_non_template)
<< GetNameFromUnqualifiedId(Name).getName()
<< Name.getSourceRange()
NestedNameSpecifier *Qualifier
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
-
+
switch (Name.getKind()) {
case UnqualifiedId::IK_Identifier:
- Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
+ Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
Name.Identifier));
return TNK_Dependent_template_name;
-
+
case UnqualifiedId::IK_OperatorFunctionId:
Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
Name.OperatorFunctionId.Operator));
default:
break;
}
-
- Diag(Name.getSourceRange().getBegin(),
+
+ Diag(Name.getSourceRange().getBegin(),
diag::err_template_kw_refers_to_non_template)
<< GetNameFromUnqualifiedId(Name).getName()
<< Name.getSourceRange()
/// \param SemaRef the semantic analysis object for which we are performing
/// the substitution.
///
-/// \param Template the template that we are synthesizing template arguments
+/// \param Template the template that we are synthesizing template arguments
/// for.
///
/// \param TemplateLoc the location of the template name that started the
// If the argument type is dependent, instantiate it now based
// on the previously-computed template arguments.
if (ArgType->getType()->isDependentType()) {
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Converted.data(), Converted.size());
-
+
MultiLevelTemplateArgumentList AllTemplateArgs
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
Template, Converted.data(),
Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
-
+
ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs,
Param->getDefaultArgumentLoc(),
Param->getDeclName());
/// \param SemaRef the semantic analysis object for which we are performing
/// the substitution.
///
-/// \param Template the template that we are synthesizing template arguments
+/// \param Template the template that we are synthesizing template arguments
/// for.
///
/// \param TemplateLoc the location of the template name that started the
SourceLocation RAngleLoc,
NonTypeTemplateParmDecl *Param,
llvm::SmallVectorImpl<TemplateArgument> &Converted) {
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Converted.data(), Converted.size());
-
+
MultiLevelTemplateArgumentList AllTemplateArgs
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
-
+
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
Template, Converted.data(),
Converted.size(),
/// \param SemaRef the semantic analysis object for which we are performing
/// the substitution.
///
-/// \param Template the template that we are synthesizing template arguments
+/// \param Template the template that we are synthesizing template arguments
/// for.
///
/// \param TemplateLoc the location of the template name that started the
SourceLocation RAngleLoc,
TemplateTemplateParmDecl *Param,
llvm::SmallVectorImpl<TemplateArgument> &Converted) {
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Converted.data(), Converted.size());
-
+
MultiLevelTemplateArgumentList AllTemplateArgs
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
-
+
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
Template, Converted.data(),
Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
-
+
return SemaRef.SubstTemplateName(
Param->getDefaultArgument().getArgument().getAsTemplate(),
- Param->getDefaultArgument().getTemplateNameLoc(),
+ Param->getDefaultArgument().getTemplateNameLoc(),
AllTemplateArgs);
}
/// \brief If the given template parameter has a default template
/// argument, substitute into that default template argument and
/// return the corresponding template argument.
-TemplateArgumentLoc
+TemplateArgumentLoc
Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
return TemplateArgumentLoc();
TemplateName TName = SubstDefaultTemplateArgument(*this, Template,
- TemplateLoc,
+ TemplateLoc,
RAngleLoc,
TempTempParm,
Converted);
if (TName.isNull())
return TemplateArgumentLoc();
- return TemplateArgumentLoc(TemplateArgument(TName),
+ return TemplateArgumentLoc(TemplateArgument(TName),
TempTempParm->getDefaultArgument().getTemplateQualifierRange(),
TempTempParm->getDefaultArgument().getTemplateNameLoc());
}
/// \brief Check that the given template argument corresponds to the given
/// template parameter.
///
-/// \param Param The template parameter against which the argument will be
+/// \param Param The template parameter against which the argument will be
/// checked.
///
/// \param Arg The template argument.
// Check template type parameters.
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
return CheckTemplateTypeArgument(TTP, Arg, Converted);
-
+
// Check non-type template parameters.
- if (NonTypeTemplateParmDecl *NTTP =dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+ if (NonTypeTemplateParmDecl *NTTP =dyn_cast<NonTypeTemplateParmDecl>(Param)) {
// Do substitution on the type of the non-type template parameter
// with the template arguments we've seen thus far. But if the
// template has a dependent context then we cannot substitute yet.
QualType NTTPType = NTTP->getType();
if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack())
NTTPType = NTTP->getExpansionType(ArgumentPackIndex);
-
+
if (NTTPType->isDependentType() &&
!isa<TemplateTemplateParmDecl>(Template) &&
!Template->getDeclContext()->isDependentContext()) {
InstantiatingTemplate Inst(*this, TemplateLoc, Template,
NTTP, Converted.data(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
-
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Converted.data(), Converted.size());
NTTPType = SubstType(NTTPType,
MultiLevelTemplateArgumentList(TemplateArgs),
if (NTTPType.isNull())
return true;
}
-
+
switch (Arg.getArgument().getKind()) {
case TemplateArgument::Null:
assert(false && "Should never see a NULL template argument here");
return true;
-
+
case TemplateArgument::Expression: {
Expr *E = Arg.getArgument().getAsExpr();
TemplateArgument Result;
if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK))
return true;
-
+
Converted.push_back(Result);
break;
}
-
+
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
// We've already checked this template argument, so just copy
// it to the list of converted arguments.
Converted.push_back(Arg.getArgument());
break;
-
+
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
// We were given a template template argument. It may not be ill-formed;
DTN->getQualifier(),
Arg.getTemplateQualifierRange(),
NameInfo);
-
+
// If we parsed the template argument as a pack expansion, create a
// pack expansion expression.
if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
- ExprResult Expansion = ActOnPackExpansion(E,
+ ExprResult Expansion = ActOnPackExpansion(E,
Arg.getTemplateEllipsisLoc());
if (Expansion.isInvalid())
return true;
-
+
E = Expansion.get();
}
-
+
TemplateArgument Result;
if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
return true;
-
+
Converted.push_back(Result);
break;
}
-
+
// We have a template argument that actually does refer to a class
// template, template alias, or template template parameter, and
// therefore cannot be a non-type template argument.
Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr)
<< Arg.getSourceRange();
-
+
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
-
+
case TemplateArgument::Type: {
// We have a non-type template parameter but the template
// argument is a type.
-
+
// C++ [temp.arg]p2:
// In a template-argument, an ambiguity between a type-id and
// an expression is resolved to a type-id, regardless of the
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
}
-
+
case TemplateArgument::Pack:
llvm_unreachable("Caller must expand template argument packs");
break;
}
-
+
return false;
- }
-
-
+ }
+
+
// Check template template parameters.
TemplateTemplateParmDecl *TempParm = cast<TemplateTemplateParmDecl>(Param);
-
+
// Substitute into the template parameter list of the template
// template parameter, since previously-supplied template arguments
// may appear within the template template parameter.
InstantiatingTemplate Inst(*this, TemplateLoc, Template,
TempParm, Converted.data(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
-
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Converted.data(), Converted.size());
TempParm = cast_or_null<TemplateTemplateParmDecl>(
- SubstDecl(TempParm, CurContext,
+ SubstDecl(TempParm, CurContext,
MultiLevelTemplateArgumentList(TemplateArgs)));
if (!TempParm)
return true;
}
-
+
switch (Arg.getArgument().getKind()) {
case TemplateArgument::Null:
assert(false && "Should never see a NULL template argument here");
return true;
-
+
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
if (CheckTemplateArgument(TempParm, Arg))
return true;
-
+
Converted.push_back(Arg.getArgument());
break;
-
+
case TemplateArgument::Expression:
case TemplateArgument::Type:
// We have a template template parameter but the template
// argument does not refer to a template.
Diag(Arg.getLocation(), diag::err_template_arg_must_be_template);
return true;
-
+
case TemplateArgument::Declaration:
llvm_unreachable(
"Declaration argument with template template parameter");
llvm_unreachable(
"Integral argument with template template parameter");
break;
-
+
case TemplateArgument::Pack:
llvm_unreachable("Caller must expand template argument packs");
break;
}
-
+
return false;
}
if (ArgIdx < NumArgs) {
// If we have an expanded parameter pack, make sure we don't have too
// many arguments.
- if (NonTypeTemplateParmDecl *NTTP
+ if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
- if (NTTP->isExpandedParameterPack() &&
+ if (NTTP->isExpandedParameterPack() &&
ArgumentPack.size() >= NTTP->getNumExpansionTypes()) {
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
<< true
return true;
}
}
-
+
// Check the template argument we were given.
- if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template,
- TemplateLoc, RAngleLoc,
+ if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template,
+ TemplateLoc, RAngleLoc,
ArgumentPack.size(), Converted))
return true;
-
+
if ((*Param)->isTemplateParameterPack()) {
// The template parameter was a template parameter pack, so take the
// deduced argument and place it on the argument pack. Note that we
++ArgIdx;
continue;
}
-
- // If we have a template parameter pack with no more corresponding
+
+ // If we have a template parameter pack with no more corresponding
// arguments, just break out now and we'll fill in the argument pack below.
if ((*Param)->isTemplateParameterPack())
break;
-
+
// We have a default template argument that we will use.
TemplateArgumentLoc Arg;
-
+
// Retrieve the default template argument from the template
// parameter. For each kind of template parameter, we substitute the
// template arguments provided thus far and any "outer" template arguments
- // (when the template parameter was part of a nested template) into
+ // (when the template parameter was part of a nested template) into
// the default argument.
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
if (!TTP->hasDefaultArgument()) {
break;
}
- TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this,
+ TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this,
Template,
TemplateLoc,
RAngleLoc,
Converted);
if (!ArgType)
return true;
-
+
Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()),
ArgType);
} else if (NonTypeTemplateParmDecl *NTTP
}
ExprResult E = SubstDefaultTemplateArgument(*this, Template,
- TemplateLoc,
- RAngleLoc,
- NTTP,
+ TemplateLoc,
+ RAngleLoc,
+ NTTP,
Converted);
if (E.isInvalid())
return true;
}
TemplateName Name = SubstDefaultTemplateArgument(*this, Template,
- TemplateLoc,
- RAngleLoc,
+ TemplateLoc,
+ RAngleLoc,
TempParm,
Converted);
if (Name.isNull())
return true;
-
- Arg = TemplateArgumentLoc(TemplateArgument(Name),
+
+ Arg = TemplateArgumentLoc(TemplateArgument(Name),
TempParm->getDefaultArgument().getTemplateQualifierRange(),
TempParm->getDefaultArgument().getTemplateNameLoc());
}
-
+
// Introduce an instantiation record that describes where we are using
// the default template argument.
InstantiatingTemplate Instantiating(*this, RAngleLoc, Template, *Param,
Converted.data(), Converted.size(),
- SourceRange(TemplateLoc, RAngleLoc));
-
+ SourceRange(TemplateLoc, RAngleLoc));
+
// Check the default template argument.
if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc,
RAngleLoc, 0, Converted))
return true;
-
+
// Move to the next template parameter and argument.
++Param;
++ArgIdx;
}
-
+
// Form argument packs for each of the parameter packs remaining.
while (Param != ParamEnd) {
// If we're checking a partial list of template arguments, don't fill
// in arguments for non-template parameter packs.
-
- if ((*Param)->isTemplateParameterPack()) {
+
+ if ((*Param)->isTemplateParameterPack()) {
if (PartialTemplateArgs && ArgumentPack.empty()) {
Converted.push_back(TemplateArgument());
} else if (ArgumentPack.empty())
Converted.push_back(TemplateArgument(0, 0));
else {
- Converted.push_back(TemplateArgument::CreatePackCopy(Context,
- ArgumentPack.data(),
+ Converted.push_back(TemplateArgument::CreatePackCopy(Context,
+ ArgumentPack.data(),
ArgumentPack.size()));
ArgumentPack.clear();
}
}
-
+
++Param;
}
-
+
return Invalid;
}
namespace {
- class UnnamedLocalNoLinkageFinder
- : public TypeVisitor<UnnamedLocalNoLinkageFinder, bool>
+ class UnnamedLocalNoLinkageFinder
+ : public TypeVisitor<UnnamedLocalNoLinkageFinder, bool>
{
Sema &S;
SourceRange SR;
-
+
typedef TypeVisitor<UnnamedLocalNoLinkageFinder, bool> inherited;
-
+
public:
UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { }
- bool Visit(QualType T) {
- return inherited::Visit(T.getTypePtr());
+ bool Visit(QualType T) {
+ return inherited::Visit(T.getTypePtr());
}
-
+
#define TYPE(Class, Parent) \
bool Visit##Class##Type(const Class##Type *);
#define ABSTRACT_TYPE(Class, Parent) \
#define NON_CANONICAL_TYPE(Class, Parent) \
bool Visit##Class##Type(const Class##Type *) { return false; }
#include "clang/AST/TypeNodes.def"
-
+
bool VisitTagDecl(const TagDecl *Tag);
bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
};
}
-bool UnnamedLocalNoLinkageFinder::VisitBuiltinType(const BuiltinType*) {
+bool UnnamedLocalNoLinkageFinder::VisitBuiltinType(const BuiltinType*) {
return false;
}
return Visit(T->getElementType());
}
-bool UnnamedLocalNoLinkageFinder::VisitPointerType(const PointerType* T) {
+bool UnnamedLocalNoLinkageFinder::VisitPointerType(const PointerType* T) {
return Visit(T->getPointeeType());
}
bool UnnamedLocalNoLinkageFinder::VisitBlockPointerType(
- const BlockPointerType* T) {
+ const BlockPointerType* T) {
return Visit(T->getPointeeType());
}
bool UnnamedLocalNoLinkageFinder::VisitLValueReferenceType(
- const LValueReferenceType* T) {
+ const LValueReferenceType* T) {
return Visit(T->getPointeeType());
}
bool UnnamedLocalNoLinkageFinder::VisitRValueReferenceType(
- const RValueReferenceType* T) {
+ const RValueReferenceType* T) {
return Visit(T->getPointeeType());
}
bool UnnamedLocalNoLinkageFinder::VisitMemberPointerType(
- const MemberPointerType* T) {
+ const MemberPointerType* T) {
return Visit(T->getPointeeType()) || Visit(QualType(T->getClass(), 0));
}
bool UnnamedLocalNoLinkageFinder::VisitConstantArrayType(
- const ConstantArrayType* T) {
+ const ConstantArrayType* T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitIncompleteArrayType(
- const IncompleteArrayType* T) {
+ const IncompleteArrayType* T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitVariableArrayType(
- const VariableArrayType* T) {
+ const VariableArrayType* T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitDependentSizedArrayType(
- const DependentSizedArrayType* T) {
+ const DependentSizedArrayType* T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitDependentSizedExtVectorType(
- const DependentSizedExtVectorType* T) {
+ const DependentSizedExtVectorType* T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitFunctionProtoType(
const FunctionProtoType* T) {
for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
+ AEnd = T->arg_type_end();
A != AEnd; ++A) {
if (Visit(*A))
return true;
}
-
+
return Visit(T->getResultType());
}
S.Diag(SR.getBegin(), diag::ext_template_arg_local_type)
<< S.Context.getTypeDeclType(Tag) << SR;
return true;
- }
-
+ }
+
if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl()) {
S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR;
S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here);
NestedNameSpecifier *NNS) {
if (NNS->getPrefix() && VisitNestedNameSpecifier(NNS->getPrefix()))
return true;
-
+
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::Global:
return false;
-
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
return Visit(QualType(NNS->getAsType(), 0));
/// \brief Checks whether the given template argument is the address
/// of an object or function according to C++ [temp.arg.nontype]p1.
-static bool
+static bool
CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
NonTypeTemplateParmDecl *Param,
QualType ParamType,
// A value of reference type is not an object.
if (Var->getType()->isReferenceType()) {
- S.Diag(Arg->getSourceRange().getBegin(),
+ S.Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_reference_var)
<< Var->getType() << Arg->getSourceRange();
S.Diag(Param->getLocation(), diag::note_template_param_here);
return true;
}
- if (ParamType->isPointerType() &&
+ if (ParamType->isPointerType() &&
!ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType() &&
S.IsQualificationConversion(ArgType, ParamType, false)) {
// For pointer-to-object types, qualification conversions are
<< Arg->getSourceRange();
S.Diag(Param->getLocation(), diag::note_template_param_here);
return true;
- }
+ }
}
}
/// \brief Checks whether the given template argument is a pointer to
/// member constant according to C++ [temp.arg.nontype]p1.
-bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
+bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
TemplateArgument &Converted) {
bool Invalid = false;
if (DRE && !DRE->getQualifier())
DRE = 0;
}
- }
+ }
// A constant of pointer-to-member type.
else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
if (VD->getType()->isMemberPointerType()) {
if (isa<NonTypeTemplateParmDecl>(VD) ||
- (isa<VarDecl>(VD) &&
+ (isa<VarDecl>(VD) &&
Context.getCanonicalType(VD->getType()).isConstQualified())) {
if (Arg->isTypeDependent() || Arg->isValueDependent())
Converted = TemplateArgument(Arg);
}
}
}
-
+
DRE = 0;
}
-
+
if (!DRE)
return Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_pointer_to_member_form)
if (!Arg->isValueDependent()) {
llvm::APSInt OldValue = Value;
-
- // Coerce the template argument's value to the value it will have
+
+ // Coerce the template argument's value to the value it will have
// based on the template parameter's type.
unsigned AllowedBits = Context.getTypeSize(IntegerType);
if (Value.getBitWidth() != AllowedBits)
// from a template argument of type std::nullptr_t to a non-type
// template parameter of type pointer to object, pointer to
// function, or pointer-to-member, respectively.
- if (ArgType->isNullPtrType() &&
+ if (ArgType->isNullPtrType() &&
(ParamType->isPointerType() || ParamType->isMemberPointerType())) {
Converted = TemplateArgument((NamedDecl *)0);
return false;
->isFunctionType())) {
if (Arg->getType() == Context.OverloadTy) {
- if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType,
+ if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType,
true,
FoundResult)) {
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
} else
return true;
}
-
+
if (!ParamType->isMemberPointerType())
return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
- ParamType,
+ ParamType,
Arg, Converted);
if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType(),
assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
"Only object pointers allowed here");
- return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
+ return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted);
}
"Only object references allowed here");
if (Arg->getType() == Context.OverloadTy) {
- if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg,
- ParamRefType->getPointeeType(),
+ if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg,
+ ParamRefType->getPointeeType(),
true,
FoundResult)) {
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
} else
return true;
}
-
- return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
+
+ return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted);
}
return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
Param->getTemplateParameters(),
- true,
+ true,
TPL_TemplateTemplateArgumentMatch,
Arg.getLocation());
}
/// declaration and the type of its corresponding non-type template
/// parameter, produce an expression that properly refers to that
/// declaration.
-ExprResult
+ExprResult
Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
QualType ParamType,
SourceLocation Loc) {
"Only declaration template arguments permitted here");
ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl());
- if (VD->getDeclContext()->isRecord() &&
+ if (VD->getDeclContext()->isRecord() &&
(isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD))) {
// If the value is a class member, we might have a pointer-to-member.
// Determine whether the non-type template template parameter is of
if (isa<CXXMethodDecl>(VD) && cast<CXXMethodDecl>(VD)->isInstance())
VK = VK_RValue;
- ExprResult RefExpr = BuildDeclRefExpr(VD,
+ ExprResult RefExpr = BuildDeclRefExpr(VD,
VD->getType().getNonReferenceType(),
VK,
Loc,
&SS);
if (RefExpr.isInvalid())
return ExprError();
-
+
RefExpr = CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
-
+
// We might need to perform a trailing qualification conversion, since
// the element type on the parameter could be more qualified than the
// element type in the expression we constructed.
ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp);
RefExpr = Owned(RefE);
}
-
+
assert(!RefExpr.isInvalid() &&
Context.hasSameType(((Expr*) RefExpr.get())->getType(),
ParamType.getUnqualifiedType()));
return move(RefExpr);
}
}
-
+
QualType T = VD->getType().getNonReferenceType();
if (ParamType->isPointerType()) {
// When the non-type template parameter is a pointer, take the
return move(RefExpr);
}
-
+
// Take the address of everything else
return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
}
T = Context.getQualifiedType(T,
TargetRef->getPointeeType().getQualifiers());
}
-
+
return BuildDeclRefExpr(VD, T, VK, Loc);
}
/// This routine takes care of the mapping from an integral template
/// argument (which may have any integral type) to the appropriate
/// literal value.
-ExprResult
+ExprResult
Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
SourceLocation Loc) {
assert(Arg.getKind() == TemplateArgument::Integral &&
S.Diag(Old->getLocation(), diag::note_template_prev_declaration)
<< (Kind != Sema::TPL_TemplateMatch);
}
-
+
return false;
}
- // Check that both are parameter packs are neither are parameter packs.
- // However, if we are matching a template template argument to a
+ // Check that both are parameter packs are neither are parameter packs.
+ // However, if we are matching a template template argument to a
// template template parameter, the template template parameter can have
// a parameter pack where the template template argument does not.
if (Old->isTemplateParameterPack() != New->isTemplateParameterPack() &&
diag::err_template_arg_template_params_mismatch);
NextDiag = diag::note_template_parameter_pack_non_pack;
}
-
+
unsigned ParamKind = isa<TemplateTypeParmDecl>(New)? 0
: isa<NonTypeTemplateParmDecl>(New)? 1
: 2;
S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here)
<< ParamKind << Old->isParameterPack();
}
-
+
return false;
}
-
+
// For non-type template parameters, check the type of the parameter.
if (NonTypeTemplateParmDecl *OldNTTP
= dyn_cast<NonTypeTemplateParmDecl>(Old)) {
NonTypeTemplateParmDecl *NewNTTP = cast<NonTypeTemplateParmDecl>(New);
-
+
// If we are matching a template template argument to a template
// template parameter and one of the non-type template parameter types
// is dependent, then we must wait until template instantiation time
(OldNTTP->getType()->isDependentType() ||
NewNTTP->getType()->isDependentType()))
return true;
-
+
if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) {
if (Complain) {
unsigned NextDiag = diag::err_template_nontype_parm_different_type;
if (TemplateArgLoc.isValid()) {
- S.Diag(TemplateArgLoc,
+ S.Diag(TemplateArgLoc,
diag::err_template_arg_template_params_mismatch);
NextDiag = diag::note_template_nontype_parm_different_type;
}
diag::note_template_nontype_parm_prev_declaration)
<< OldNTTP->getType();
}
-
+
return false;
}
-
+
return true;
}
-
+
// For template template parameters, check the template parameter types.
// The template parameter lists of template template
// parameters must agree.
if (TemplateTemplateParmDecl *OldTTP
= dyn_cast<TemplateTemplateParmDecl>(Old)) {
- TemplateTemplateParmDecl *NewTTP = cast<TemplateTemplateParmDecl>(New);
+ TemplateTemplateParmDecl *NewTTP = cast<TemplateTemplateParmDecl>(New);
return S.TemplateParameterListsAreEqual(NewTTP->getTemplateParameters(),
OldTTP->getTemplateParameters(),
Complain,
(Kind == Sema::TPL_TemplateMatch
- ? Sema::TPL_TemplateTemplateParmMatch
+ ? Sema::TPL_TemplateTemplateParmMatch
: Kind),
TemplateArgLoc);
}
-
+
return true;
}
/// \brief Diagnose a known arity mismatch when comparing template argument
/// lists.
static
-void DiagnoseTemplateParameterListArityMismatch(Sema &S,
+void DiagnoseTemplateParameterListArityMismatch(Sema &S,
TemplateParameterList *New,
TemplateParameterList *Old,
Sema::TemplateParameterListEqualKind Kind,
if (Complain)
DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
TemplateArgLoc);
-
+
return false;
}
-
+
if (!MatchTemplateParameterKind(*this, *NewParm, *OldParm, Complain,
Kind, TemplateArgLoc))
- return false;
-
+ return false;
+
++NewParm;
continue;
}
-
+
// C++0x [temp.arg.template]p3:
// [...] When P's template- parameter-list contains a template parameter
// pack (14.5.3), the template parameter pack will match zero or more
for (; NewParm != NewParmEnd; ++NewParm) {
if (!MatchTemplateParameterKind(*this, *NewParm, *OldParm, Complain,
Kind, TemplateArgLoc))
- return false;
+ return false;
}
}
-
+
// Make sure we exhausted all of the arguments.
if (NewParm != NewParmEnd) {
if (Complain)
DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
TemplateArgLoc);
-
+
return false;
}
-
+
return true;
}
static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) {
if (!D)
return TSK_Undeclared;
-
+
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
return Record->getTemplateSpecializationKind();
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
return Function->getTemplateSpecializationKind();
if (VarDecl *Var = dyn_cast<VarDecl>(D))
return Var->getTemplateSpecializationKind();
-
+
return TSK_Undeclared;
}
-/// \brief Check whether a specialization is well-formed in the current
+/// \brief Check whether a specialization is well-formed in the current
/// context.
///
/// This routine determines whether a template specialization can be declared
///
/// \param Specialized the entity being specialized or instantiated, which
/// may be a kind of template (class template, function template, etc.) or
-/// a member of a class template (member function, static data member,
+/// a member of a class template (member function, static data member,
/// member class).
///
/// \param PrevDecl the previous declaration of this entity, if any.
<< Specialized;
return true;
}
-
+
// C++ [temp.class.spec]p6:
// A class template partial specialization may be declared or redeclared
- // in any namespace scope in which its definition may be defined (14.5.1
- // and 14.5.2).
+ // in any namespace scope in which its definition may be defined (14.5.1
+ // and 14.5.2).
bool ComplainedAboutScope = false;
- DeclContext *SpecializedContext
+ DeclContext *SpecializedContext
= Specialized->getDeclContext()->getEnclosingNamespaceContext();
DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
- if ((!PrevDecl ||
+ if ((!PrevDecl ||
getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
// C++ [temp.exp.spec]p2:
// An explicit specialization shall be declared in the namespace of which
- // the template is a member, or, for member templates, in the namespace
+ // the template is a member, or, for member templates, in the namespace
// of which the enclosing class or enclosing class template is a member.
- // An explicit specialization of a member function, member class or
- // static data member of a class template shall be declared in the
+ // An explicit specialization of a member function, member class or
+ // static data member of a class template shall be declared in the
// namespace of which the class template is a member.
//
// C++0x [temp.expl.spec]p2:
- // An explicit specialization shall be declared in a namespace enclosing
+ // An explicit specialization shall be declared in a namespace enclosing
// the specialized template.
if (!DC->InEnclosingNamespaceSetOf(SpecializedContext) &&
!(S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext))) {
: diag::err_template_spec_decl_out_of_scope)
<< EntityKind << Specialized
<< cast<NamedDecl>(SpecializedContext);
-
+
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
ComplainedAboutScope = true;
}
}
-
- // Make sure that this redeclaration (or definition) occurs in an enclosing
+
+ // Make sure that this redeclaration (or definition) occurs in an enclosing
// namespace.
- // Note that HandleDeclarator() performs this check for explicit
+ // Note that HandleDeclarator() performs this check for explicit
// specializations of function templates, static data members, and member
// functions, so we skip the check here for those kinds of entities.
// FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
<< EntityKind << Specialized
<< cast<NamedDecl>(SpecializedContext);
-
+
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
}
-
+
// FIXME: check for specialization-after-instantiation errors and such.
-
+
return false;
}
-
+
/// \brief Subroutine of Sema::CheckClassTemplatePartialSpecializationArgs
/// that checks non-type template partial specialization arguments.
static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S,
for (unsigned I = 0; I != NumArgs; ++I) {
if (Args[I].getKind() == TemplateArgument::Pack) {
if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
- Args[I].pack_begin(),
+ Args[I].pack_begin(),
Args[I].pack_size()))
return true;
-
+
continue;
}
-
+
Expr *ArgExpr = Args[I].getAsExpr();
if (!ArgExpr) {
continue;
// Strip off any implicit casts we added as part of type checking.
while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr))
ArgExpr = ICE->getSubExpr();
-
+
// C++ [temp.class.spec]p8:
// A non-type argument is non-specialized if it is the name of a
// non-type parameter. All other non-type arguments are
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr))
if (isa<NonTypeTemplateParmDecl>(DRE->getDecl()))
continue;
-
+
// C++ [temp.class.spec]p9:
// Within the argument list of a class template partial
// specialization, the following restrictions apply:
<< ArgExpr->getSourceRange();
return true;
}
-
+
// -- The type of a template parameter corresponding to a
// specialized non-type argument shall not be dependent on a
// parameter of the specialization.
return true;
}
}
-
+
return false;
}
-
+
/// \brief Check the non-type template arguments of a class template
/// partial specialization according to C++ [temp.class.spec]p9.
///
if (!Param)
continue;
- if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
+ if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
&ArgList[I], 1))
return true;
}
if (!ClassTemplate) {
Diag(TemplateNameLoc, diag::err_not_class_template_specialization)
- << (Name.getAsTemplateDecl() &&
+ << (Name.getAsTemplateDecl() &&
isa<TemplateTemplateParmDecl>(Name.getAsTemplateDecl()));
return true;
}
Invalid);
if (Invalid)
return true;
-
+
unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
if (TemplateParams)
--NumMatchedTemplateParamLists;
<< SourceRange(LAngleLoc, RAngleLoc);
return true;
}
-
+
// C++ [temp.class.spec]p10:
// The template parameter list of a specialization shall not
// contain default template argument values.
// Check for unexpanded parameter packs in any of the template arguments.
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
- if (DiagnoseUnexpandedParameterPack(TemplateArgs[I],
+ if (DiagnoseUnexpandedParameterPack(TemplateArgs[I],
UPPC_PartialSpecialization))
return true;
-
+
// Check that the template argument list is well-formed for this
// template.
llvm::SmallVector<TemplateArgument, 4> Converted;
Converted))
return true;
- if (!Name.isDependent() &&
+ if (!Name.isDependent() &&
!TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs.getArgumentArray(),
+ TemplateArgs.getArgumentArray(),
TemplateArgs.size())) {
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
<< ClassTemplate->getDeclName();
// Check whether we can declare a class template specialization in
// the current scope.
if (TUK != TUK_Friend &&
- CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl,
- TemplateNameLoc,
+ CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl,
+ TemplateNameLoc,
isPartialSpecialization))
return true;
-
+
// The canonical type
QualType CanonType;
- if (PrevDecl &&
+ if (PrevDecl &&
(PrevDecl->getSpecializationKind() == TSK_Undeclared ||
TUK == TUK_Friend)) {
// Since the only prior class template specialization with these
CanonType = Context.getTemplateSpecializationType(CanonTemplate,
Converted.data(),
Converted.size());
-
- if (Context.hasSameType(CanonType,
+
+ if (Context.hasSameType(CanonType,
ClassTemplate->getInjectedClassNameSpecialization())) {
// C++ [temp.class.spec]p9b3:
//
ClassTemplate->AddPartialSpecialization(Partial, InsertPos);
Specialization = Partial;
- // If we are providing an explicit specialization of a member class
+ // If we are providing an explicit specialization of a member class
// template specialization, make a note of that.
if (PrevPartial && PrevPartial->getInstantiatedFromMember())
PrevPartial->setMemberSpecialization();
-
+
// Check that all of the template parameters of the class template
// partial specialization are deducible from the template
// arguments. If not, this class template partial specialization
// will never be used.
llvm::SmallVector<bool, 8> DeducibleParams;
DeducibleParams.resize(TemplateParams->size());
- MarkUsedTemplateParameters(Partial->getTemplateArgs(), true,
+ MarkUsedTemplateParameters(Partial->getTemplateArgs(), true,
TemplateParams->getDepth(),
DeducibleParams);
unsigned NumNonDeducible = 0;
// C++ [temp.expl.spec]p6:
// If a template, a member template or the member of a class template is
- // explicitly specialized then that specialization shall be declared
+ // explicitly specialized then that specialization shall be declared
// before the first use of that specialization that would cause an implicit
- // instantiation to take place, in every translation unit in which such a
+ // instantiation to take place, in every translation unit in which such a
// use occurs; no diagnostic is required.
if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) {
bool Okay = false;
Diag(TemplateNameLoc, diag::err_specialization_after_instantiation)
<< Context.getTypeDeclType(Specialization) << Range;
- Diag(PrevDecl->getPointOfInstantiation(),
+ Diag(PrevDecl->getPointOfInstantiation(),
diag::note_instantiation_required_here)
- << (PrevDecl->getTemplateSpecializationKind()
+ << (PrevDecl->getTemplateSpecializationKind()
!= TSK_ImplicitInstantiation);
return true;
}
}
-
+
// If this is not a friend, note that this is an explicit specialization.
if (TUK != TUK_Friend)
Specialization->setSpecializationKind(TSK_ExplicitSpecialization);
}
}
-/// \brief Diagnose cases where we have an explicit template specialization
+/// \brief Diagnose cases where we have an explicit template specialization
/// before/after an explicit template instantiation, producing diagnostics
-/// for those cases where they are required and determining whether the
+/// for those cases where they are required and determining whether the
/// new specialization/instantiation will have any effect.
///
-/// \param NewLoc the location of the new explicit specialization or
+/// \param NewLoc the location of the new explicit specialization or
/// instantiation.
///
/// \param NewTSK the kind of the new explicit specialization or instantiation.
///
/// \param PrevTSK the kind of the old explicit specialization or instantiatin.
///
-/// \param PrevPointOfInstantiation if valid, indicates where the previus
+/// \param PrevPointOfInstantiation if valid, indicates where the previus
/// declaration was instantiated (either implicitly or explicitly).
///
-/// \param HasNoEffect will be set to true to indicate that the new
+/// \param HasNoEffect will be set to true to indicate that the new
/// specialization or instantiation has no effect and should be ignored.
///
/// \returns true if there was an error that should prevent the introduction of
SourceLocation PrevPointOfInstantiation,
bool &HasNoEffect) {
HasNoEffect = false;
-
+
switch (NewTSK) {
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
assert(false && "Don't check implicit instantiations here");
return false;
-
+
case TSK_ExplicitSpecialization:
switch (PrevTSK) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
- // Okay, we're just specializing something that is either already
+ // Okay, we're just specializing something that is either already
// explicitly specialized or has merely been mentioned without any
// instantiation.
return false;
return false;
}
// Fall through
-
+
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
- assert((PrevTSK == TSK_ImplicitInstantiation ||
- PrevPointOfInstantiation.isValid()) &&
+ assert((PrevTSK == TSK_ImplicitInstantiation ||
+ PrevPointOfInstantiation.isValid()) &&
"Explicit instantiation without point of instantiation?");
-
+
// C++ [temp.expl.spec]p6:
- // If a template, a member template or the member of a class template
+ // If a template, a member template or the member of a class template
// is explicitly specialized then that specialization shall be declared
- // before the first use of that specialization that would cause an
+ // before the first use of that specialization that would cause an
// implicit instantiation to take place, in every translation unit in
// which such a use occurs; no diagnostic is required.
for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) {
<< PrevDecl;
Diag(PrevPointOfInstantiation, diag::note_instantiation_required_here)
<< (PrevTSK != TSK_ImplicitInstantiation);
-
+
return true;
}
break;
-
+
case TSK_ExplicitInstantiationDeclaration:
switch (PrevTSK) {
case TSK_ExplicitInstantiationDeclaration:
// This explicit instantiation declaration is redundant (that's okay).
HasNoEffect = true;
return false;
-
+
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
// We're explicitly instantiating something that may have already been
// implicitly instantiated; that's fine.
return false;
-
+
case TSK_ExplicitSpecialization:
// C++0x [temp.explicit]p4:
// For a given set of template parameters, if an explicit instantiation
- // of a template appears after a declaration of an explicit
+ // of a template appears after a declaration of an explicit
// specialization for that template, the explicit instantiation has no
// effect.
HasNoEffect = true;
return false;
-
+
case TSK_ExplicitInstantiationDefinition:
// C++0x [temp.explicit]p10:
- // If an entity is the subject of both an explicit instantiation
- // declaration and an explicit instantiation definition in the same
+ // If an entity is the subject of both an explicit instantiation
+ // declaration and an explicit instantiation definition in the same
// translation unit, the definition shall follow the declaration.
- Diag(NewLoc,
+ Diag(NewLoc,
diag::err_explicit_instantiation_declaration_after_definition);
- Diag(PrevPointOfInstantiation,
+ Diag(PrevPointOfInstantiation,
diag::note_explicit_instantiation_definition_here);
assert(PrevPointOfInstantiation.isValid() &&
"Explicit instantiation without point of instantiation?");
return false;
}
break;
-
+
case TSK_ExplicitInstantiationDefinition:
switch (PrevTSK) {
case TSK_Undeclared:
// We're explicitly instantiating something that may have already been
// implicitly instantiated; that's fine.
return false;
-
+
case TSK_ExplicitSpecialization:
// C++ DR 259, C++0x [temp.explicit]p4:
// For a given set of template parameters, if an explicit
// an explicit specialization for that template, the explicit
// instantiation has no effect.
//
- // In C++98/03 mode, we only give an extension warning here, because it
+ // In C++98/03 mode, we only give an extension warning here, because it
// is not harmful to try to explicitly instantiate something that
// has been explicitly specialized.
if (!getLangOptions().CPlusPlus0x) {
}
HasNoEffect = true;
return false;
-
+
case TSK_ExplicitInstantiationDeclaration:
// We're explicity instantiating a definition for something for which we
- // were previously asked to suppress instantiations. That's fine.
+ // were previously asked to suppress instantiations. That's fine.
return false;
-
+
case TSK_ExplicitInstantiationDefinition:
// C++0x [temp.spec]p5:
// For a given template and a given set of template-arguments,
// in a program,
Diag(NewLoc, diag::err_explicit_instantiation_duplicate)
<< PrevDecl;
- Diag(PrevPointOfInstantiation,
+ Diag(PrevPointOfInstantiation,
diag::note_previous_explicit_instantiation);
HasNoEffect = true;
- return false;
+ return false;
}
break;
}
-
+
assert(false && "Missing specialization/instantiation case?");
-
+
return false;
}
// The set of function template specializations that could match this
// explicit function template specialization.
UnresolvedSet<8> Candidates;
-
+
DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
I != E; ++I) {
NamedDecl *Ovl = (*I)->getUnderlyingDecl();
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
- // Only consider templates found within the same semantic lookup scope as
+ // Only consider templates found within the same semantic lookup scope as
// FD.
if (!FDLookupContext->InEnclosingNamespaceSetOf(
Ovl->getDeclContext()->getRedeclContext()))
continue;
-
+
// C++ [temp.expl.spec]p11:
- // A trailing template-argument can be left unspecified in the
- // template-id naming an explicit function template specialization
+ // A trailing template-argument can be left unspecified in the
+ // template-id naming an explicit function template specialization
// provided it can be deduced from the function argument type.
// Perform template argument deduction to determine whether we may be
// specializing this template.
(void)TDK;
continue;
}
-
+
// Record this candidate.
Candidates.addDecl(Specialization, I.getAccess());
}
}
-
+
// Find the most specialized function template.
UnresolvedSetIterator Result
= getMostSpecialized(Candidates.begin(), Candidates.end(),
TPOC_Other, 0, FD->getLocation(),
- PDiag(diag::err_function_template_spec_no_match)
+ PDiag(diag::err_function_template_spec_no_match)
<< FD->getDeclName(),
PDiag(diag::err_function_template_spec_ambiguous)
<< FD->getDeclName() << (ExplicitTemplateArgs != 0),
// Ignore access information; it doesn't figure into redeclaration checking.
FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
Specialization->setLocation(FD->getLocation());
-
+
// FIXME: Check if the prior specialization has a point of instantiation.
// If so, we have run afoul of .
// If this is a friend declaration, then we're not really declaring
// an explicit specialization.
bool isFriend = (FD->getFriendObjectKind() != Decl::FOK_None);
-
+
// Check the scope of this explicit specialization.
if (!isFriend &&
- CheckTemplateSpecializationScope(*this,
+ CheckTemplateSpecializationScope(*this,
Specialization->getPrimaryTemplate(),
- Specialization, FD->getLocation(),
+ Specialization, FD->getLocation(),
false))
return true;
// C++ [temp.expl.spec]p6:
// If a template, a member template or the member of a class template is
- // explicitly specialized then that specialization shall be declared
+ // explicitly specialized then that specialization shall be declared
// before the first use of that specialization that would cause an implicit
- // instantiation to take place, in every translation unit in which such a
+ // instantiation to take place, in every translation unit in which such a
// use occurs; no diagnostic is required.
FunctionTemplateSpecializationInfo *SpecInfo
= Specialization->getTemplateSpecializationInfo();
SpecInfo->getPointOfInstantiation(),
HasNoEffect))
return true;
-
+
// Mark the prior declaration as an explicit specialization, so that later
// clients know that this is an explicit specialization.
if (!isFriend) {
SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
MarkUnusedFileScopedDecl(Specialization);
}
-
+
// Turn the given function declaration into a function template
// specialization, with the template arguments from the previous
// specialization.
/// \brief Perform semantic analysis for the given non-template member
/// specialization.
///
-/// This routine performs all of the semantic analysis required for an
+/// This routine performs all of the semantic analysis required for an
/// explicit member function specialization. On successful completion,
/// the function declaration \p FD will become a member function
/// specialization.
/// \param Previous the set of declarations, one of which may be specialized
/// by this function specialization; the set will be modified to contain the
/// redeclared member.
-bool
+bool
Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
MSInfo = PrevRecord->getMemberSpecializationInfo();
}
}
-
+
if (!Instantiation) {
// There is no previous declaration that matches. Since member
// specializations are always out-of-line, the caller will complain about
Previous.addDecl(Instantiation);
return false;
}
-
+
// Make sure that this is a specialization of a member.
if (!InstantiatedFrom) {
Diag(Member->getLocation(), diag::err_spec_member_not_instantiated)
Diag(Instantiation->getLocation(), diag::note_specialized_decl);
return true;
}
-
+
// C++ [temp.expl.spec]p6:
// If a template, a member template or the member of a class template is
- // explicitly specialized then that spe- cialization shall be declared
+ // explicitly specialized then that spe- cialization shall be declared
// before the first use of that specialization that would cause an implicit
- // instantiation to take place, in every translation unit in which such a
+ // instantiation to take place, in every translation unit in which such a
// use occurs; no diagnostic is required.
assert(MSInfo && "Member specialization info missing?");
MSInfo->getPointOfInstantiation(),
HasNoEffect))
return true;
-
+
// Check the scope of this explicit specialization.
- if (CheckTemplateSpecializationScope(*this,
+ if (CheckTemplateSpecializationScope(*this,
InstantiatedFrom,
- Instantiation, Member->getLocation(),
+ Instantiation, Member->getLocation(),
false))
return true;
TSK_ExplicitSpecialization);
InstantiationFunction->setLocation(Member->getLocation());
}
-
+
cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
cast<CXXMethodDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
TSK_ExplicitSpecialization);
InstantiationVar->setLocation(Member->getLocation());
}
-
+
Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
cast<VarDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
TSK_ExplicitSpecialization);
InstantiationClass->setLocation(Member->getLocation());
}
-
+
cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
cast<CXXRecordDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
}
-
+
// Save the caller the trouble of having to figure out which declaration
// this specialization matches.
Previous.clear();
bool WasQualifiedName) {
DeclContext *OrigContext= D->getDeclContext()->getEnclosingNamespaceContext();
DeclContext *CurContext = S.CurContext->getRedeclContext();
-
+
if (CurContext->isRecord()) {
S.Diag(InstLoc, diag::err_explicit_instantiation_in_class)
<< D;
return true;
}
-
+
// C++0x [temp.explicit]p2:
- // An explicit instantiation shall appear in an enclosing namespace of its
+ // An explicit instantiation shall appear in an enclosing namespace of its
// template.
//
// This is DR275, which we do not retroactively apply to C++98/03.
- if (S.getLangOptions().CPlusPlus0x &&
+ if (S.getLangOptions().CPlusPlus0x &&
!CurContext->Encloses(OrigContext)) {
if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext))
- S.Diag(InstLoc,
- S.getLangOptions().CPlusPlus0x?
+ S.Diag(InstLoc,
+ S.getLangOptions().CPlusPlus0x?
diag::err_explicit_instantiation_out_of_scope
: diag::warn_explicit_instantiation_out_of_scope_0x)
<< D << NS;
else
- S.Diag(InstLoc,
+ S.Diag(InstLoc,
S.getLangOptions().CPlusPlus0x?
diag::err_explicit_instantiation_must_be_global
: diag::warn_explicit_instantiation_out_of_scope_0x)
}
// C++0x [temp.explicit]p2:
- // If the name declared in the explicit instantiation is an unqualified
- // name, the explicit instantiation shall appear in the namespace where
+ // If the name declared in the explicit instantiation is an unqualified
+ // name, the explicit instantiation shall appear in the namespace where
// its template is declared or, if that namespace is inline (7.3.1), any
// namespace from its enclosing namespace set.
if (WasQualifiedName)
if (CurContext->InEnclosingNamespaceSetOf(OrigContext))
return false;
- S.Diag(InstLoc,
+ S.Diag(InstLoc,
S.getLangOptions().CPlusPlus0x?
diag::err_explicit_instantiation_unqualified_wrong_namespace
: diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
if (!SS.isSet())
return false;
-
+
// C++0x [temp.explicit]p2:
- // If the explicit instantiation is for a member function, a member class
+ // If the explicit instantiation is for a member function, a member class
// or a static data member of a class template specialization, the name of
// the class template specialization in the qualified-id for the member
// name shall be a simple-template-id.
// C++0x [temp.explicit]p2:
// There are two forms of explicit instantiation: an explicit instantiation
- // definition and an explicit instantiation declaration. An explicit
- // instantiation declaration begins with the extern keyword. [...]
+ // definition and an explicit instantiation declaration. An explicit
+ // instantiation declaration begins with the extern keyword. [...]
TemplateSpecializationKind TSK
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
-
+
// Translate the parser's template argument list in our AST format.
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
SS.isSet()))
return true;
-
+
ClassTemplateSpecializationDecl *Specialization = 0;
bool HasNoEffect = false;
if (Tag->isInvalidDecl())
return true;
-
+
CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag);
CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
if (!Pattern) {
}
// C++0x [temp.explicit]p2:
- // If the explicit instantiation is for a class or member class, the
- // elaborated-type-specifier in the declaration shall include a
+ // If the explicit instantiation is for a class or member class, the
+ // elaborated-type-specifier in the declaration shall include a
// simple-template-id.
//
// C++98 has the same restriction, just worded differently.
if (!ScopeSpecifierHasTemplateId(SS))
Diag(TemplateLoc, diag::ext_explicit_instantiation_without_qualified_id)
<< Record << SS.getRange();
-
+
// C++0x [temp.explicit]p2:
// There are two forms of explicit instantiation: an explicit instantiation
- // definition and an explicit instantiation declaration. An explicit
+ // definition and an explicit instantiation declaration. An explicit
// instantiation declaration begins with the extern keyword. [...]
TemplateSpecializationKind TSK
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
-
+
// C++0x [temp.explicit]p2:
// [...] An explicit instantiation shall appear in an enclosing
// namespace of its template. [...]
//
// This is C++ DR 275.
CheckExplicitInstantiationScope(*this, Record, NameLoc, true);
-
+
// Verify that it is okay to explicitly instantiate here.
- CXXRecordDecl *PrevDecl
+ CXXRecordDecl *PrevDecl
= cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration());
if (!PrevDecl && Record->getDefinition())
PrevDecl = Record;
MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
bool HasNoEffect = false;
assert(MSInfo && "No member specialization information?");
- if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK,
+ if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK,
PrevDecl,
MSInfo->getTemplateSpecializationKind(),
- MSInfo->getPointOfInstantiation(),
+ MSInfo->getPointOfInstantiation(),
HasNoEffect))
return true;
if (HasNoEffect)
return TagD;
}
-
+
CXXRecordDecl *RecordDef
= cast_or_null<CXXRecordDecl>(Record->getDefinition());
if (!RecordDef) {
// C++ [temp.explicit]p3:
- // A definition of a member class of a class template shall be in scope
+ // A definition of a member class of a class template shall be in scope
// at the point of an explicit instantiation of the member class.
- CXXRecordDecl *Def
+ CXXRecordDecl *Def
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
if (!Def) {
Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member)
if (!RecordDef)
return true;
}
- }
-
+ }
+
// Instantiate all of the members of the class.
InstantiateClassMembers(NameLoc, RecordDef,
getTemplateInstantiationArgs(Record), TSK);
diag::err_explicit_instantiation_requires_name)
<< D.getDeclSpec().getSourceRange()
<< D.getSourceRange();
-
+
return true;
}
QualType R = T->getType();
if (R.isNull())
return true;
-
+
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
// Cannot explicitly instantiate a typedef.
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_of_typedef)
// Presumably, this also applies to member functions of class templates as
// well.
if (D.getDeclSpec().isInlineSpecified() && getLangOptions().CPlusPlus0x)
- Diag(D.getDeclSpec().getInlineSpecLoc(),
+ Diag(D.getDeclSpec().getInlineSpecLoc(),
diag::err_explicit_instantiation_inline)
<<FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
-
+
// FIXME: check for constexpr specifier.
-
+
// C++0x [temp.explicit]p2:
// There are two forms of explicit instantiation: an explicit instantiation
- // definition and an explicit instantiation declaration. An explicit
- // instantiation declaration begins with the extern keyword. [...]
+ // definition and an explicit instantiation declaration. An explicit
+ // instantiation declaration begins with the extern keyword. [...]
TemplateSpecializationKind TSK
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
-
+
LookupResult Previous(*this, NameInfo, LookupOrdinaryName);
LookupParsedName(Previous, S, &D.getCXXScopeSpec());
if (!R->isFunctionType()) {
// C++ [temp.explicit]p1:
- // A [...] static data member of a class template can be explicitly
- // instantiated from the member definition associated with its class
+ // A [...] static data member of a class template can be explicitly
+ // instantiated from the member definition associated with its class
// template.
if (Previous.isAmbiguous())
return true;
-
+
VarDecl *Prev = Previous.getAsSingle<VarDecl>();
if (!Prev || !Prev->isStaticDataMember()) {
// We expect to see a data data member here.
Diag((*P)->getLocation(), diag::note_explicit_instantiation_here);
return true;
}
-
+
if (!Prev->getInstantiatedFromStaticDataMember()) {
// FIXME: Check for explicit specialization?
- Diag(D.getIdentifierLoc(),
+ Diag(D.getIdentifierLoc(),
diag::err_explicit_instantiation_data_member_not_instantiated)
<< Prev;
Diag(Prev->getLocation(), diag::note_explicit_instantiation_here);
// FIXME: Can we provide a note showing where this was declared?
return true;
}
-
+
// C++0x [temp.explicit]p2:
- // If the explicit instantiation is for a member function, a member class
+ // If the explicit instantiation is for a member function, a member class
// or a static data member of a class template specialization, the name of
// the class template specialization in the qualified-id for the member
// name shall be a simple-template-id.
//
// C++98 has the same restriction, just worded differently.
if (!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
- Diag(D.getIdentifierLoc(),
+ Diag(D.getIdentifierLoc(),
diag::ext_explicit_instantiation_without_qualified_id)
<< Prev << D.getCXXScopeSpec().getRange();
-
+
// Check the scope of this explicit instantiation.
CheckExplicitInstantiationScope(*this, Prev, D.getIdentifierLoc(), true);
-
+
// Verify that it is okay to explicitly instantiate here.
MemberSpecializationInfo *MSInfo = Prev->getMemberSpecializationInfo();
assert(MSInfo && "Missing static data member specialization info?");
bool HasNoEffect = false;
if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, Prev,
MSInfo->getTemplateSpecializationKind(),
- MSInfo->getPointOfInstantiation(),
+ MSInfo->getPointOfInstantiation(),
HasNoEffect))
return true;
if (HasNoEffect)
return (Decl*) 0;
-
+
// Instantiate static data member.
Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
if (TSK == TSK_ExplicitInstantiationDefinition)
InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev);
-
+
// FIXME: Create an ExplicitInstantiation node?
return (Decl*) 0;
}
-
- // If the declarator is a template-id, translate the parser's template
+
+ // If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
bool HasExplicitTemplateArgs = false;
TemplateArgumentListInfo TemplateArgs;
HasExplicitTemplateArgs = true;
TemplateArgsPtr.release();
}
-
+
// C++ [temp.explicit]p1:
- // A [...] function [...] can be explicitly instantiated from its template.
- // A member function [...] of a class template can be explicitly
- // instantiated from the member definition associated with its class
+ // A [...] function [...] can be explicitly instantiated from its template.
+ // A member function [...] of a class template can be explicitly
+ // instantiated from the member definition associated with its class
// template.
UnresolvedSet<8> Matches;
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
}
}
}
-
+
FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Prev);
if (!FunTmpl)
continue;
TemplateDeductionInfo Info(Context, D.getIdentifierLoc());
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
- = DeduceTemplateArguments(FunTmpl,
+ = DeduceTemplateArguments(FunTmpl,
(HasExplicitTemplateArgs ? &TemplateArgs : 0),
R, Specialization, Info)) {
// FIXME: Keep track of almost-matches?
(void)TDK;
continue;
}
-
+
Matches.addDecl(Specialization, P.getAccess());
}
-
+
// Find the most specialized function template specialization.
UnresolvedSetIterator Result
= getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 0,
- D.getIdentifierLoc(),
+ D.getIdentifierLoc(),
PDiag(diag::err_explicit_instantiation_not_known) << Name,
PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
PDiag(diag::note_explicit_instantiation_candidate));
// Ignore access control bits, we don't need them for redeclaration checking.
FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
-
+
if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) {
- Diag(D.getIdentifierLoc(),
+ Diag(D.getIdentifierLoc(),
diag::err_explicit_instantiation_member_function_not_instantiated)
<< Specialization
<< (Specialization->getTemplateSpecializationKind() ==
TSK_ExplicitSpecialization);
Diag(Specialization->getLocation(), diag::note_explicit_instantiation_here);
return true;
- }
-
+ }
+
FunctionDecl *PrevDecl = Specialization->getPreviousDeclaration();
if (!PrevDecl && Specialization->isThisDeclarationADefinition())
PrevDecl = Specialization;
if (PrevDecl) {
bool HasNoEffect = false;
if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK,
- PrevDecl,
- PrevDecl->getTemplateSpecializationKind(),
+ PrevDecl,
+ PrevDecl->getTemplateSpecializationKind(),
PrevDecl->getPointOfInstantiation(),
HasNoEffect))
return true;
-
+
// FIXME: We may still want to build some representation of this
// explicit specialization.
if (HasNoEffect)
}
Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
-
+
if (TSK == TSK_ExplicitInstantiationDefinition)
InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
-
+
// C++0x [temp.explicit]p2:
- // If the explicit instantiation is for a member function, a member class
+ // If the explicit instantiation is for a member function, a member class
// or a static data member of a class template specialization, the name of
// the class template specialization in the qualified-id for the member
// name shall be a simple-template-id.
// C++98 has the same restriction, just worded differently.
FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate();
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId && !FunTmpl &&
- D.getCXXScopeSpec().isSet() &&
+ D.getCXXScopeSpec().isSet() &&
!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
- Diag(D.getIdentifierLoc(),
+ Diag(D.getIdentifierLoc(),
diag::ext_explicit_instantiation_without_qualified_id)
<< Specialization << D.getCXXScopeSpec().getRange();
-
+
CheckExplicitInstantiationScope(*this,
- FunTmpl? (NamedDecl *)FunTmpl
+ FunTmpl? (NamedDecl *)FunTmpl
: Specialization->getInstantiatedFromMemberFunction(),
- D.getIdentifierLoc(),
+ D.getIdentifierLoc(),
D.getCXXScopeSpec().isSet());
-
+
// FIXME: Create some kind of ExplicitInstantiationDecl here.
return (Decl*) 0;
}
}
TypeResult
-Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS, const IdentifierInfo &II,
+Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
+ const CXXScopeSpec &SS, const IdentifierInfo &II,
SourceLocation IdLoc) {
NestedNameSpecifier *NNS
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
!getLangOptions().CPlusPlus0x)
Diag(TypenameLoc, diag::ext_typename_outside_of_template)
- << FixItHint::CreateRemoval(TypenameLoc);
-
+ << FixItHint::CreateRemoval(TypenameLoc);
+
QualType T = CheckTypenameType(ETK_Typename, NNS, II,
TypenameLoc, SS.getRange(), IdLoc);
if (T.isNull())
TL.setQualifierRange(SS.getRange());
cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
}
-
+
return CreateParsedType(T, TSI);
}
TypeResult
-Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS, SourceLocation TemplateLoc,
+Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
+ const CXXScopeSpec &SS, SourceLocation TemplateLoc,
ParsedType Ty) {
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
!getLangOptions().CPlusPlus0x)
Diag(TypenameLoc, diag::ext_typename_outside_of_template)
- << FixItHint::CreateRemoval(TypenameLoc);
-
+ << FixItHint::CreateRemoval(TypenameLoc);
+
TypeSourceInfo *InnerTSI = 0;
QualType T = GetTypeFromParser(Ty, &InnerTSI);
- assert(isa<TemplateSpecializationType>(T) &&
+ assert(isa<TemplateSpecializationType>(T) &&
"Expected a template specialization type");
if (computeDeclContext(SS, false)) {
}
// Fall through to create a dependent typename type, from which we can recover
// better.
-
+
case LookupResult::NotFoundInCurrentInstantiation:
// Okay, it's a member of an unknown instantiation.
return Context.getDependentNameType(Keyword, NNS, &II);
case LookupResult::Found:
- if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
+ if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
// We found a type. Build an ElaboratedType, since the
// typename-specifier was just sugar.
return Context.getElaboratedType(ETK_Typename, NNS,
Referenced = Result.getFoundDecl();
break;
-
+
llvm_unreachable("unresolved using decl in non-dependent context");
return QualType();
public:
typedef TreeTransform<CurrentInstantiationRebuilder> inherited;
-
+
CurrentInstantiationRebuilder(Sema &SemaRef,
SourceLocation Loc,
DeclarationName Entity)
NestedNameSpecifier *NNS = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
CurrentInstantiationRebuilder Rebuilder(*this, SS.getRange().getBegin(),
DeclarationName());
- NestedNameSpecifier *Rebuilt =
+ NestedNameSpecifier *Rebuilt =
Rebuilder.TransformNestedNameSpecifier(NNS, SS.getRange());
if (!Rebuilt) return true;
if (!Params || Params->size() == 0 || NumArgs == 0)
return std::string();
-
+
for (unsigned I = 0, N = Params->size(); I != N; ++I) {
if (I >= NumArgs)
break;
-
+
if (I == 0)
Out << "[with ";
else
Out << ", ";
-
+
if (const IdentifierInfo *Id = Params->getParam(I)->getIdentifier()) {
Out << Id->getName();
} else {
Out << '$' << I;
}
-
+
Out << " = ";
Args[I].print(Context.PrintingPolicy, Out);
}
/// may apply.
TDF_SkipNonDependent = 0x08,
/// \brief Whether we are performing template argument deduction for
- /// parameters and arguments in a top-level template argument
+ /// parameters and arguments in a top-level template argument
TDF_TopLevelParameterTypeList = 0x10
};
}
/// \brief Whether template argument deduction for two reference parameters
/// resulted in the argument type, parameter type, or neither type being more
/// qualified than the other.
-enum DeductionQualifierComparison {
- NeitherMoreQualified = 0,
- ParamMoreQualified,
- ArgMoreQualified
+enum DeductionQualifierComparison {
+ NeitherMoreQualified = 0,
+ ParamMoreQualified,
+ ArgMoreQualified
};
/// \brief Stores the result of comparing two reference parameters while
/// performing template argument deduction for partial ordering of function
-/// templates.
+/// templates.
struct RefParamPartialOrderingComparison {
/// \brief Whether the parameter type is an rvalue reference type.
bool ParamIsRvalueRef;
/// \brief Whether the argument type is an rvalue reference type.
bool ArgIsRvalueRef;
-
+
/// \brief Whether the parameter or argument (or neither) is more qualified.
DeductionQualifierComparison Qualifiers;
};
static bool isSameDeclaration(Decl *X, Decl *Y) {
if (!X || !Y)
return !X && !Y;
-
+
if (NamedDecl *NX = dyn_cast<NamedDecl>(X))
X = NX->getUnderlyingDecl();
if (NamedDecl *NY = dyn_cast<NamedDecl>(Y))
Y = NY->getUnderlyingDecl();
-
+
return X->getCanonicalDecl() == Y->getCanonicalDecl();
}
///
/// \returns The deduced template argument, or a NULL template argument if
/// the deduced template arguments were incompatible.
-static DeducedTemplateArgument
+static DeducedTemplateArgument
checkDeducedTemplateArguments(ASTContext &Context,
const DeducedTemplateArgument &X,
const DeducedTemplateArgument &Y) {
if (X.isNull())
return Y;
if (Y.isNull())
- return X;
+ return X;
switch (X.getKind()) {
case TemplateArgument::Null:
if (Y.getKind() == TemplateArgument::Type &&
Context.hasSameType(X.getAsType(), Y.getAsType()))
return X;
-
+
return DeducedTemplateArgument();
-
+
case TemplateArgument::Integral:
// If we deduced a constant in one case and either a dependent expression or
// declaration in another case, keep the integral constant.
Y.getKind() == TemplateArgument::Declaration ||
(Y.getKind() == TemplateArgument::Integral &&
hasSameExtendedValue(*X.getAsIntegral(), *Y.getAsIntegral())))
- return DeducedTemplateArgument(X,
+ return DeducedTemplateArgument(X,
X.wasDeducedFromArrayBound() &&
Y.wasDeducedFromArrayBound());
// All other combinations are incompatible.
return DeducedTemplateArgument();
-
+
case TemplateArgument::Template:
if (Y.getKind() == TemplateArgument::Template &&
Context.hasSameTemplateName(X.getAsTemplate(), Y.getAsTemplate()))
return X;
-
+
// All other combinations are incompatible.
- return DeducedTemplateArgument();
+ return DeducedTemplateArgument();
case TemplateArgument::TemplateExpansion:
if (Y.getKind() == TemplateArgument::TemplateExpansion &&
- Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(),
+ Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(),
Y.getAsTemplateOrTemplatePattern()))
return X;
-
+
// All other combinations are incompatible.
- return DeducedTemplateArgument();
+ return DeducedTemplateArgument();
case TemplateArgument::Expression:
- // If we deduced a dependent expression in one case and either an integral
- // constant or a declaration in another case, keep the integral constant
+ // If we deduced a dependent expression in one case and either an integral
+ // constant or a declaration in another case, keep the integral constant
// or declaration.
if (Y.getKind() == TemplateArgument::Integral ||
Y.getKind() == TemplateArgument::Declaration)
return DeducedTemplateArgument(Y, X.wasDeducedFromArrayBound() &&
Y.wasDeducedFromArrayBound());
-
+
if (Y.getKind() == TemplateArgument::Expression) {
// Compare the expressions for equality
llvm::FoldingSetNodeID ID1, ID2;
if (ID1 == ID2)
return X;
}
-
+
// All other combinations are incompatible.
return DeducedTemplateArgument();
-
+
case TemplateArgument::Declaration:
// If we deduced a declaration and a dependent expression, keep the
// declaration.
if (Y.getKind() == TemplateArgument::Expression)
return X;
-
+
// If we deduced a declaration and an integral constant, keep the
// integral constant.
if (Y.getKind() == TemplateArgument::Integral)
return Y;
-
+
// If we deduced two declarations, make sure they they refer to the
// same declaration.
if (Y.getKind() == TemplateArgument::Declaration &&
isSameDeclaration(X.getAsDecl(), Y.getAsDecl()))
return X;
-
+
// All other combinations are incompatible.
return DeducedTemplateArgument();
-
+
case TemplateArgument::Pack:
if (Y.getKind() != TemplateArgument::Pack ||
X.pack_size() != Y.pack_size())
return DeducedTemplateArgument();
-
- for (TemplateArgument::pack_iterator XA = X.pack_begin(),
+
+ for (TemplateArgument::pack_iterator XA = X.pack_begin(),
XAEnd = X.pack_end(),
YA = Y.pack_begin();
XA != XAEnd; ++XA, ++YA) {
- if (checkDeducedTemplateArguments(Context,
- DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
+ if (checkDeducedTemplateArguments(Context,
+ DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()))
.isNull())
return DeducedTemplateArgument();
}
-
+
return X;
}
-
+
return DeducedTemplateArgument();
}
"Cannot deduce non-type template argument with depth > 0");
DeducedTemplateArgument NewDeduced(Value, ValueType, DeducedFromArrayBound);
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
+ DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[NTTP->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
+ return Sema::TDK_Inconsistent;
}
-
+
Deduced[NTTP->getIndex()] = Result;
return Sema::TDK_Success;
}
"Expression template argument must be type- or value-dependent.");
DeducedTemplateArgument NewDeduced(Value);
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
- Deduced[NTTP->getIndex()],
+ DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
+ Deduced[NTTP->getIndex()],
NewDeduced);
-
+
if (Result.isNull()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
+ return Sema::TDK_Inconsistent;
}
-
+
Deduced[NTTP->getIndex()] = Result;
return Sema::TDK_Success;
}
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
-
+
DeducedTemplateArgument NewDeduced(D? D->getCanonicalDecl() : 0);
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
+ DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[NTTP->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
+ return Sema::TDK_Inconsistent;
}
-
+
Deduced[NTTP->getIndex()] = Result;
return Sema::TDK_Success;
}
// so there is nothing that we can deduce.
return Sema::TDK_Success;
}
-
+
if (TemplateTemplateParmDecl *TempParam
= dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
DeducedTemplateArgument NewDeduced(S.Context.getCanonicalTemplateName(Arg));
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
+ DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[TempParam->getIndex()],
NewDeduced);
if (Result.isNull()) {
Info.Param = TempParam;
Info.FirstArg = Deduced[TempParam->getIndex()];
Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
+ return Sema::TDK_Inconsistent;
}
-
+
Deduced[TempParam->getIndex()] = Result;
- return Sema::TDK_Success;
+ return Sema::TDK_Success;
}
-
+
// Verify that the two template names are equivalent.
if (S.Context.hasSameTemplateName(Param, Arg))
return Sema::TDK_Success;
-
+
// Mismatch of non-dependent template parameter to argument.
Info.FirstArg = TemplateArgument(Param);
Info.SecondArg = TemplateArgument(Arg);
// Perform template argument deduction on each template
// argument. Ignore any missing/extra arguments, since they could be
// filled in by default arguments.
- return DeduceTemplateArguments(S, TemplateParams,
- Param->getArgs(), Param->getNumArgs(),
+ return DeduceTemplateArguments(S, TemplateParams,
+ Param->getArgs(), Param->getNumArgs(),
SpecArg->getArgs(), SpecArg->getNumArgs(),
Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
return Result;
// Perform template argument deduction for the template arguments.
- return DeduceTemplateArguments(S, TemplateParams,
+ return DeduceTemplateArguments(S, TemplateParams,
Param->getArgs(), Param->getNumArgs(),
SpecArg->getTemplateArgs().data(),
SpecArg->getTemplateArgs().size(),
}
/// \brief Retrieve the depth and index of a template parameter.
-static std::pair<unsigned, unsigned>
+static std::pair<unsigned, unsigned>
getDepthAndIndex(NamedDecl *ND) {
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
return std::make_pair(TTP->getDepth(), TTP->getIndex());
-
+
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
-
+
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
return std::make_pair(TTP->getDepth(), TTP->getIndex());
}
/// \brief Retrieve the depth and index of an unexpanded parameter pack.
-static std::pair<unsigned, unsigned>
+static std::pair<unsigned, unsigned>
getDepthAndIndex(UnexpandedParameterPack UPP) {
if (const TemplateTypeParmType *TTP
= UPP.first.dyn_cast<const TemplateTypeParmType *>())
return std::make_pair(TTP->getDepth(), TTP->getIndex());
-
+
return getDepthAndIndex(UPP.first.get<NamedDecl *>());
}
return TemplateParameter(TTP);
else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
return TemplateParameter(NTTP);
-
+
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
/// \brief Prepare to perform template argument deduction for all of the
/// arguments in a set of argument packs.
-static void PrepareArgumentPackDeduction(Sema &S,
- llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+static void PrepareArgumentPackDeduction(Sema &S,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
const llvm::SmallVectorImpl<unsigned> &PackIndices,
- llvm::SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
llvm::SmallVectorImpl<
llvm::SmallVector<DeducedTemplateArgument, 4> > &NewlyDeducedPacks) {
// Save the deduced template arguments for each parameter pack expanded
// Save the previously-deduced argument pack, then clear it out so that we
// can deduce a new argument pack.
SavedPacks[I] = Deduced[PackIndices[I]];
- Deduced[PackIndices[I]] = TemplateArgument();
-
+ Deduced[PackIndices[I]] = TemplateArgument();
+
// If the template arugment pack was explicitly specified, add that to
// the set of deduced arguments.
const TemplateArgument *ExplicitArgs;
unsigned NumExplicitArgs;
- if (NamedDecl *PartiallySubstitutedPack
+ if (NamedDecl *PartiallySubstitutedPack
= S.CurrentInstantiationScope->getPartiallySubstitutedPack(
&ExplicitArgs,
&NumExplicitArgs)) {
if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
- NewlyDeducedPacks[I].append(ExplicitArgs,
+ NewlyDeducedPacks[I].append(ExplicitArgs,
ExplicitArgs + NumExplicitArgs);
}
}
FinishArgumentPackDeduction(Sema &S,
TemplateParameterList *TemplateParams,
bool HasAnyArguments,
- llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
const llvm::SmallVectorImpl<unsigned> &PackIndices,
- llvm::SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
llvm::SmallVectorImpl<
llvm::SmallVector<DeducedTemplateArgument, 4> > &NewlyDeducedPacks,
TemplateDeductionInfo &Info) {
Deduced[PackIndices[I]] = SavedPacks[I];
continue;
}
-
+
DeducedTemplateArgument NewPack;
-
+
if (NewlyDeducedPacks[I].empty()) {
// If we deduced an empty argument pack, create it now.
NewPack = DeducedTemplateArgument(TemplateArgument(0, 0));
NewPack
= DeducedTemplateArgument(TemplateArgument(ArgumentPack,
NewlyDeducedPacks[I].size()),
- NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
+ NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
}
-
+
DeducedTemplateArgument Result
= checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
if (Result.isNull()) {
Info.SecondArg = NewPack;
return Sema::TDK_Inconsistent;
}
-
+
Deduced[PackIndices[I]] = Result;
}
-
+
return Sema::TDK_Success;
}
/// \brief Deduce the template arguments by comparing the list of parameter
-/// types to the list of argument types, as in the parameter-type-lists of
-/// function types (C++ [temp.deduct.type]p10).
+/// types to the list of argument types, as in the parameter-type-lists of
+/// function types (C++ [temp.deduct.type]p10).
///
/// \param S The semantic analysis object within which we are deducing
///
/// how template argument deduction is performed.
///
/// \param PartialOrdering If true, we are performing template argument
-/// deduction for during partial ordering for a call
+/// deduction for during partial ordering for a call
/// (C++0x [temp.deduct.partial]).
///
/// \param RefParamComparisons If we're performing template argument deduction
!(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) &&
!(NumArgs && isa<PackExpansionType>(Args[NumArgs - 1])))
return Sema::TDK_NonDeducedMismatch;
-
+
// C++0x [temp.deduct.type]p10:
- // Similarly, if P has a form that contains (T), then each parameter type
- // Pi of the respective parameter-type- list of P is compared with the
- // corresponding parameter type Ai of the corresponding parameter-type-list
- // of A. [...]
+ // Similarly, if P has a form that contains (T), then each parameter type
+ // Pi of the respective parameter-type- list of P is compared with the
+ // corresponding parameter type Ai of the corresponding parameter-type-list
+ // of A. [...]
unsigned ArgIdx = 0, ParamIdx = 0;
for (; ParamIdx != NumParams; ++ParamIdx) {
// Check argument types.
- const PackExpansionType *Expansion
+ const PackExpansionType *Expansion
= dyn_cast<PackExpansionType>(Params[ParamIdx]);
if (!Expansion) {
// Simple case: compare the parameter and argument types at this point.
-
+
// Make sure we have an argument.
if (ArgIdx >= NumArgs)
return Sema::TDK_NonDeducedMismatch;
-
+
if (isa<PackExpansionType>(Args[ArgIdx])) {
// C++0x [temp.deduct.type]p22:
// If the original function parameter associated with A is a function
// a function parameter pack, then template argument deduction fails.
return Sema::TDK_NonDeducedMismatch;
}
-
+
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams,
Params[ParamIdx],
PartialOrdering,
RefParamComparisons))
return Result;
-
+
++ArgIdx;
continue;
}
-
+
// C++0x [temp.deduct.type]p5:
// The non-deduced contexts are:
- // - A function parameter pack that does not occur at the end of the
+ // - A function parameter pack that does not occur at the end of the
// parameter-declaration-clause.
if (ParamIdx + 1 < NumParams)
return Sema::TDK_Success;
// C++0x [temp.deduct.type]p10:
- // If the parameter-declaration corresponding to Pi is a function
+ // If the parameter-declaration corresponding to Pi is a function
// parameter pack, then the type of its declarator- id is compared with
- // each remaining parameter type in the parameter-type-list of A. Each
+ // each remaining parameter type in the parameter-type-list of A. Each
// comparison deduces template arguments for subsequent positions in the
// template parameter packs expanded by the function parameter pack.
-
+
// Compute the set of template parameter indices that correspond to
// parameter packs expanded by the pack expansion.
llvm::SmallVector<unsigned, 2> PackIndices;
assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
// Keep track of the deduced template arguments for each parameter pack
- // expanded by this pack expansion (the outer index) and for each
+ // expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
NewlyDeducedPacks(PackIndices.size());
- llvm::SmallVector<DeducedTemplateArgument, 2>
+ llvm::SmallVector<DeducedTemplateArgument, 2>
SavedPacks(PackIndices.size());
- PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
+ PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
NewlyDeducedPacks);
-
+
bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
HasAnyArguments = true;
-
+
// Deduce template arguments from the pattern.
- if (Sema::TemplateDeductionResult Result
+ if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
Info, Deduced, TDF, PartialOrdering,
RefParamComparisons))
return Result;
-
+
// Capture the deduced template arguments for each parameter pack expanded
// by this pack expansion, add them to the list of arguments we've deduced
// for that pack, then clear out the deduced argument.
}
}
}
-
+
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
if (Sema::TemplateDeductionResult Result
- = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
+ = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
Deduced, PackIndices, SavedPacks,
NewlyDeducedPacks, Info))
- return Result;
+ return Result;
}
-
+
// Make sure we don't have any extra arguments.
if (ArgIdx < NumArgs)
return Sema::TDK_NonDeducedMismatch;
-
+
return Sema::TDK_Success;
}
QualType Arg = S.Context.getCanonicalType(ArgIn);
// If the argument type is a pack expansion, look at its pattern.
- // This isn't explicitly called out
+ // This isn't explicitly called out
if (const PackExpansionType *ArgExpansion
= dyn_cast<PackExpansionType>(Arg))
Arg = ArgExpansion->getPattern();
-
+
if (PartialOrdering) {
// C++0x [temp.deduct.partial]p5:
- // Before the partial ordering is done, certain transformations are
- // performed on the types used for partial ordering:
- // - If P is a reference type, P is replaced by the type referred to.
+ // Before the partial ordering is done, certain transformations are
+ // performed on the types used for partial ordering:
+ // - If P is a reference type, P is replaced by the type referred to.
const ReferenceType *ParamRef = Param->getAs<ReferenceType>();
if (ParamRef)
Param = ParamRef->getPointeeType();
-
+
// - If A is a reference type, A is replaced by the type referred to.
const ReferenceType *ArgRef = Arg->getAs<ReferenceType>();
if (ArgRef)
Arg = ArgRef->getPointeeType();
-
+
if (RefParamComparisons && ParamRef && ArgRef) {
// C++0x [temp.deduct.partial]p6:
- // If both P and A were reference types (before being replaced with the
- // type referred to above), determine which of the two types (if any) is
+ // If both P and A were reference types (before being replaced with the
+ // type referred to above), determine which of the two types (if any) is
// more cv-qualified than the other; otherwise the types are considered
- // to be equally cv-qualified for partial ordering purposes. The result
+ // to be equally cv-qualified for partial ordering purposes. The result
// of this determination will be used below.
//
- // We save this information for later, using it only when deduction
+ // We save this information for later, using it only when deduction
// succeeds in both directions.
RefParamPartialOrderingComparison Comparison;
Comparison.ParamIsRvalueRef = ParamRef->getAs<RValueReferenceType>();
Comparison.Qualifiers = ArgMoreQualified;
RefParamComparisons->push_back(Comparison);
}
-
+
// C++0x [temp.deduct.partial]p7:
// Remove any top-level cv-qualifiers:
- // - If P is a cv-qualified type, P is replaced by the cv-unqualified
+ // - If P is a cv-qualified type, P is replaced by the cv-unqualified
// version of P.
Param = Param.getUnqualifiedType();
- // - If A is a cv-qualified type, A is replaced by the cv-unqualified
+ // - If A is a cv-qualified type, A is replaced by the cv-unqualified
// version of A.
Arg = Arg.getUnqualifiedType();
} else {
Arg.getCVRQualifiers());
Param = S.Context.getQualifiedType(UnqualParam, Quals);
}
-
+
if ((TDF & TDF_TopLevelParameterTypeList) && !Param->isFunctionType()) {
// C++0x [temp.deduct.type]p10:
// If P and A are function types that originated from deduction when
// taking the address of a function template (14.8.2.2) or when deducing
// template arguments from a function declaration (14.8.2.6) and Pi and
- // Ai are parameters of the top-level parameter-type-list of P and A,
- // respectively, Pi is adjusted if it is an rvalue reference to a
- // cv-unqualified template parameter and Ai is an lvalue reference, in
- // which case the type of Pi is changed to be the template parameter
+ // Ai are parameters of the top-level parameter-type-list of P and A,
+ // respectively, Pi is adjusted if it is an rvalue reference to a
+ // cv-unqualified template parameter and Ai is an lvalue reference, in
+ // which case the type of Pi is changed to be the template parameter
// type (i.e., T&& is changed to simply T). [ Note: As a result, when
// Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be
// deduced as X&. - end note ]
TDF &= ~TDF_TopLevelParameterTypeList;
-
+
if (const RValueReferenceType *ParamRef
= Param->getAs<RValueReferenceType>()) {
if (isa<TemplateTypeParmType>(ParamRef->getPointeeType()) &&
}
}
}
-
+
// If the parameter type is not dependent, there is nothing to deduce.
if (!Param->isDependentType()) {
if (!(TDF & TDF_SkipNonDependent) && Param != Arg)
return Sema::TDK_NonDeducedMismatch;
-
+
return Sema::TDK_Success;
}
DeducedType = S.Context.getCanonicalType(DeducedType);
DeducedTemplateArgument NewDeduced(DeducedType);
- DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
+ DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[Index],
NewDeduced);
if (Result.isNull()) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = Deduced[Index];
Info.SecondArg = NewDeduced;
- return Sema::TDK_Inconsistent;
+ return Sema::TDK_Inconsistent;
}
-
+
Deduced[Index] = Result;
- return Sema::TDK_Success;
+ return Sema::TDK_Success;
}
// Set up the template argument deduction information for a failure.
if (const ConstantArrayType *ConstantArrayArg
= dyn_cast<ConstantArrayType>(ArrayArg)) {
llvm::APSInt Size(ConstantArrayArg->getSize());
- return DeduceNonTypeTemplateArgument(S, NTTP, Size,
+ return DeduceNonTypeTemplateArgument(S, NTTP, Size,
S.Context.getSizeType(),
/*ArrayBound=*/true,
Info, Deduced);
const FunctionProtoType *FunctionProtoParam =
cast<FunctionProtoType>(Param);
- if (FunctionProtoParam->getTypeQuals()
+ if (FunctionProtoParam->getTypeQuals()
!= FunctionProtoArg->getTypeQuals() ||
- FunctionProtoParam->getRefQualifier()
+ FunctionProtoParam->getRefQualifier()
!= FunctionProtoArg->getRefQualifier() ||
FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
return Sema::TDK_NonDeducedMismatch;
// partial ordering.
if (Arg.isPackExpansion())
Arg = Arg.getPackExpansionPattern();
-
+
switch (Param.getKind()) {
case TemplateArgument::Null:
assert(false && "Null template argument in parameter list");
case TemplateArgument::Template:
if (Arg.getKind() == TemplateArgument::Template)
- return DeduceTemplateArguments(S, TemplateParams,
+ return DeduceTemplateArguments(S, TemplateParams,
Param.getAsTemplate(),
Arg.getAsTemplate(), Info, Deduced);
Info.FirstArg = Param;
case TemplateArgument::TemplateExpansion:
llvm_unreachable("caller should handle pack expansions");
break;
-
+
case TemplateArgument::Declaration:
if (Arg.getKind() == TemplateArgument::Declaration &&
Param.getAsDecl()->getCanonicalDecl() ==
Arg.getAsDecl()->getCanonicalDecl())
return Sema::TDK_Success;
-
+
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
if (Arg.getKind() == TemplateArgument::Declaration)
return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
Info, Deduced);
-
+
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
///
/// \returns true if there is another template argument (which will be at
/// \c Args[ArgIdx]), false otherwise.
-static bool hasTemplateArgumentForDeduction(const TemplateArgument *&Args,
+static bool hasTemplateArgumentForDeduction(const TemplateArgument *&Args,
unsigned &ArgIdx,
unsigned &NumArgs) {
if (ArgIdx == NumArgs)
return false;
-
+
const TemplateArgument &Arg = Args[ArgIdx];
if (Arg.getKind() != TemplateArgument::Pack)
return true;
unsigned ArgIdx = 0;
while (ArgIdx < NumArgs) {
const TemplateArgument &Arg = Args[ArgIdx];
-
+
// Unwrap argument packs.
if (Args[ArgIdx].getKind() == TemplateArgument::Pack) {
Args = Arg.pack_begin();
ArgIdx = 0;
continue;
}
-
+
++ArgIdx;
if (ArgIdx == NumArgs)
return false;
-
+
if (Arg.isPackExpansion())
return true;
}
-
+
return false;
}
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch) {
// C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is not
- // the last template argument, the entire template argument list is a
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
// non-deduced context.
if (hasPackExpansionBeforeEnd(Params, NumParams))
return Sema::TDK_Success;
-
+
// C++0x [temp.deduct.type]p9:
- // If P has a form that contains <T> or <i>, then each argument Pi of the
- // respective template argument list P is compared with the corresponding
+ // If P has a form that contains <T> or <i>, then each argument Pi of the
+ // respective template argument list P is compared with the corresponding
// argument Ai of the corresponding template argument list of A.
unsigned ArgIdx = 0, ParamIdx = 0;
- for (; hasTemplateArgumentForDeduction(Params, ParamIdx, NumParams);
+ for (; hasTemplateArgumentForDeduction(Params, ParamIdx, NumParams);
++ParamIdx) {
if (!Params[ParamIdx].isPackExpansion()) {
// The simple case: deduce template arguments by matching Pi and Ai.
-
+
// Check whether we have enough arguments.
if (!hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
return NumberOfArgumentsMustMatch? Sema::TDK_NonDeducedMismatch
: Sema::TDK_Success;
-
+
if (Args[ArgIdx].isPackExpansion()) {
// FIXME: We follow the logic of C++0x [temp.deduct.type]p22 here,
// but applied to pack expansions that are template arguments.
return Sema::TDK_NonDeducedMismatch;
}
-
+
// Perform deduction for this Pi/Ai pair.
if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams,
Params[ParamIdx], Args[ArgIdx],
Info, Deduced))
- return Result;
-
+ return Result;
+
// Move to the next argument.
++ArgIdx;
continue;
}
-
+
// The parameter is a pack expansion.
-
+
// C++0x [temp.deduct.type]p9:
- // If Pi is a pack expansion, then the pattern of Pi is compared with
- // each remaining argument in the template argument list of A. Each
- // comparison deduces template arguments for subsequent positions in the
+ // If Pi is a pack expansion, then the pattern of Pi is compared with
+ // each remaining argument in the template argument list of A. Each
+ // comparison deduces template arguments for subsequent positions in the
// template parameter packs expanded by Pi.
TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern();
-
+
// Compute the set of template parameter indices that correspond to
// parameter packs expanded by the pack expansion.
llvm::SmallVector<unsigned, 2> PackIndices;
}
}
assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
+
// FIXME: If there are no remaining arguments, we can bail out early
// and set any deduced parameter packs to an empty argument pack.
// The latter part of this is a (minor) correctness issue.
-
+
// Save the deduced template arguments for each parameter pack expanded
// by this pack expansion, then clear out the deduction.
- llvm::SmallVector<DeducedTemplateArgument, 2>
+ llvm::SmallVector<DeducedTemplateArgument, 2>
SavedPacks(PackIndices.size());
llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
NewlyDeducedPacks(PackIndices.size());
- PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
+ PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
NewlyDeducedPacks);
// Keep track of the deduced template arguments for each parameter pack
- // expanded by this pack expansion (the outer index) and for each
+ // expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
bool HasAnyArguments = false;
while (hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) {
HasAnyArguments = true;
-
+
// Deduce template arguments from the pattern.
- if (Sema::TemplateDeductionResult Result
+ if (Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
Info, Deduced))
return Result;
-
+
// Capture the deduced template arguments for each parameter pack expanded
// by this pack expansion, add them to the list of arguments we've deduced
// for that pack, then clear out the deduced argument.
DeducedArg = DeducedTemplateArgument();
}
}
-
+
++ArgIdx;
}
-
+
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
if (Sema::TemplateDeductionResult Result
- = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
+ = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
Deduced, PackIndices, SavedPacks,
NewlyDeducedPacks, Info))
- return Result;
+ return Result;
}
-
+
// If there is an argument remaining, then we had too many arguments.
if (NumberOfArgumentsMustMatch &&
hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
return Sema::TDK_NonDeducedMismatch;
-
+
return Sema::TDK_Success;
}
const TemplateArgumentList &ArgList,
TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- return DeduceTemplateArguments(S, TemplateParams,
+ return DeduceTemplateArguments(S, TemplateParams,
ParamList.data(), ParamList.size(),
ArgList.data(), ArgList.size(),
Info, Deduced);
X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() ==
Context.getCanonicalTemplateName(
Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
-
+
case TemplateArgument::Integral:
return *X.getAsIntegral() == *Y.getAsIntegral();
case TemplateArgument::Expression: {
llvm::FoldingSetNodeID XID, YID;
X.getAsExpr()->Profile(XID, Context, true);
- Y.getAsExpr()->Profile(YID, Context, true);
+ Y.getAsExpr()->Profile(YID, Context, true);
return XID == YID;
}
///
/// \param Loc The source location to use for the resulting template
/// argument.
-static TemplateArgumentLoc
+static TemplateArgumentLoc
getTrivialTemplateArgumentLoc(Sema &S,
- const TemplateArgument &Arg,
+ const TemplateArgument &Arg,
QualType NTTPType,
SourceLocation Loc) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Can't get a NULL template argument here");
break;
-
+
case TemplateArgument::Type:
- return TemplateArgumentLoc(Arg,
+ return TemplateArgumentLoc(Arg,
S.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
-
+
case TemplateArgument::Declaration: {
Expr *E
= S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
.takeAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
-
+
case TemplateArgument::Integral: {
Expr *E
= S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
-
+
case TemplateArgument::Template:
return TemplateArgumentLoc(Arg, SourceRange(), Loc);
case TemplateArgument::Expression:
return TemplateArgumentLoc(Arg, Arg.getAsExpr());
-
+
case TemplateArgument::Pack:
return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
}
-
+
return TemplateArgumentLoc();
}
/// \brief Convert the given deduced template argument and add it to the set of
/// fully-converted template arguments.
-static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
+static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
DeducedTemplateArgument Arg,
- NamedDecl *Template,
- QualType NTTPType,
+ NamedDecl *Template,
+ QualType NTTPType,
unsigned ArgumentPackIndex,
TemplateDeductionInfo &Info,
bool InFunctionTemplate,
// This is a template argument pack, so check each of its arguments against
// the template parameter.
llvm::SmallVector<TemplateArgument, 2> PackedArgsBuilder;
- for (TemplateArgument::pack_iterator PA = Arg.pack_begin(),
+ for (TemplateArgument::pack_iterator PA = Arg.pack_begin(),
PAEnd = Arg.pack_end();
PA != PAEnd; ++PA) {
// When converting the deduced template argument, append it to the
// checking logic has all of the prior template arguments available.
DeducedTemplateArgument InnerArg(*PA);
InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
- if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template,
+ if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template,
NTTPType, PackedArgsBuilder.size(),
Info, InFunctionTemplate, Output))
return true;
-
+
// Move the converted template argument into our argument pack.
PackedArgsBuilder.push_back(Output.back());
Output.pop_back();
}
-
+
// Create the resulting argument pack.
- Output.push_back(TemplateArgument::CreatePackCopy(S.Context,
+ Output.push_back(TemplateArgument::CreatePackCopy(S.Context,
PackedArgsBuilder.data(),
PackedArgsBuilder.size()));
return false;
}
-
+
// Convert the deduced template argument into a template
// argument that we can check, almost as if the user had written
// the template argument explicitly.
TemplateArgumentLoc ArgLoc = getTrivialTemplateArgumentLoc(S, Arg, NTTPType,
Info.getLocation());
-
+
// Check the template argument, converting it as necessary.
return S.CheckTemplateArgument(Param, ArgLoc,
Template,
Output,
InFunctionTemplate
? (Arg.wasDeducedFromArrayBound()
- ? Sema::CTAK_DeducedFromArrayBound
+ ? Sema::CTAK_DeducedFromArrayBound
: Sema::CTAK_Deduced)
: Sema::CTAK_Specified);
}
/// Complete template argument deduction for a class template partial
/// specialization.
static Sema::TemplateDeductionResult
-FinishTemplateArgumentDeduction(Sema &S,
+FinishTemplateArgumentDeduction(Sema &S,
ClassTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info) {
// Trap errors.
Sema::SFINAETrap Trap(S);
-
+
Sema::ContextRAII SavedContext(S, Partial);
// C++ [temp.deduct.type]p2:
Info.Param = makeTemplateParameter(Param);
return Sema::TDK_Incomplete;
}
-
+
// We have deduced this argument, so it still needs to be
// checked and converted.
-
+
// First, for a non-type template parameter type that is
// initialized by a declaration, we need the type of the
// corresponding non-type template parameter.
QualType NTTPType;
- if (NonTypeTemplateParmDecl *NTTP
+ if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
NTTPType = NTTP->getType();
if (NTTPType->isDependentType()) {
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Builder.data(), Builder.size());
NTTPType = S.SubstType(NTTPType,
MultiLevelTemplateArgumentList(TemplateArgs),
if (NTTPType.isNull()) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(S.Context,
- Builder.data(),
+ Info.reset(TemplateArgumentList::CreateCopy(S.Context,
+ Builder.data(),
Builder.size()));
return Sema::TDK_SubstitutionFailure;
}
Builder)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
- Builder.size()));
+ Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
+ Builder.size()));
return Sema::TDK_SubstitutionFailure;
}
}
-
+
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList
- = TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
+ = TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
Builder.size());
Info.reset(DeducedArgumentList);
if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
InstArgs, false, ConvertedInstArgs))
return Sema::TDK_SubstitutionFailure;
-
+
TemplateParameterList *TemplateParams
= ClassTemplate->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
-
- return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
+
+ return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
Deduced, Info);
}
TemplateArgumentList *ExplicitArgumentList
= TemplateArgumentList::CreateCopy(Context, Builder.data(), Builder.size());
Info.reset(ExplicitArgumentList);
-
+
// Template argument deduction and the final substitution should be
// done in the context of the templated declaration. Explicit
// argument substitution, on the other hand, needs to happen in the
// calling context.
ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
- // If we deduced template arguments for a template parameter pack,
+ // If we deduced template arguments for a template parameter pack,
// note that the template argument pack is partially substituted and record
// the explicit template arguments. They'll be used as part of deduction
// for this template parameter pack.
const TemplateArgument &Arg = Builder[I];
if (Arg.getKind() == TemplateArgument::Pack) {
CurrentInstantiationScope->SetPartiallySubstitutedPack(
- TemplateParams->getParam(I),
+ TemplateParams->getParam(I),
Arg.pack_begin(),
Arg.pack_size());
break;
// Instantiate the types of each of the function parameters given the
// explicitly-specified template arguments.
- if (SubstParmTypes(Function->getLocation(),
+ if (SubstParmTypes(Function->getLocation(),
Function->param_begin(), Function->getNumParams(),
MultiLevelTemplateArgumentList(*ExplicitArgumentList),
ParamTypes))
llvm::SmallVector<TemplateArgument, 4> Builder;
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
NamedDecl *Param = TemplateParams->getParam(I);
-
+
if (!Deduced[I].isNull()) {
if (I < NumExplicitlySpecified) {
// We have already fully type-checked and converted this
- // argument, because it was explicitly-specified. Just record the
+ // argument, because it was explicitly-specified. Just record the
// presence of this argument.
Builder.push_back(Deduced[I]);
continue;
// initialized by a declaration, we need the type of the
// corresponding non-type template parameter.
QualType NTTPType;
- if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+ if (NonTypeTemplateParmDecl *NTTP
+ = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
NTTPType = NTTP->getType();
if (NTTPType->isDependentType()) {
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
Builder.data(), Builder.size());
NTTPType = SubstType(NTTPType,
MultiLevelTemplateArgumentList(TemplateArgs),
if (NTTPType.isNull()) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(Context,
- Builder.data(),
+ Info.reset(TemplateArgumentList::CreateCopy(Context,
+ Builder.data(),
Builder.size()));
return TDK_SubstitutionFailure;
}
true, Builder)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
- Builder.size()));
+ Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
+ Builder.size()));
return TDK_SubstitutionFailure;
}
continue;
}
-
+
// C++0x [temp.arg.explicit]p3:
- // A trailing template parameter pack (14.5.3) not otherwise deduced will
+ // A trailing template parameter pack (14.5.3) not otherwise deduced will
// be deduced to an empty sequence of template arguments.
// FIXME: Where did the word "trailing" come from?
if (Param->isTemplateParameterPack()) {
&NumExplicitArgs)
== Param)
Builder.push_back(TemplateArgument(ExplicitArgs, NumExplicitArgs));
- else
+ else
Builder.push_back(TemplateArgument(0, 0));
-
+
continue;
}
- // Substitute into the default template argument, if available.
+ // Substitute into the default template argument, if available.
TemplateArgumentLoc DefArg
= SubstDefaultTemplateArgumentIfAvailable(FunctionTemplate,
FunctionTemplate->getLocation(),
const_cast<NamedDecl *>(TemplateParams->getParam(I)));
return TDK_Incomplete;
}
-
+
// Check whether we can actually use the default argument.
if (CheckTemplateArgument(Param, DefArg,
FunctionTemplate,
Info.Param = makeTemplateParameter(
const_cast<NamedDecl *>(TemplateParams->getParam(I)));
// FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
+ Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
Builder.size()));
return TDK_SubstitutionFailure;
}
if (!Specialization)
return TDK_SubstitutionFailure;
- assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
+ assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
FunctionTemplate->getCanonicalDecl());
-
+
// If the template argument list is owned by the function template
// specialization, release it.
if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList &&
if (Pos == SuppressedDiagnostics.end())
SuppressedDiagnostics[Specialization->getCanonicalDecl()]
.append(Info.diag_begin(), Info.diag_end());
- }
+ }
return TDK_Success;
}
ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
Expr *Arg, QualType ParamType,
bool ParamWasReference) {
-
+
OverloadExpr::FindResult R = OverloadExpr::find(Arg);
OverloadExpr *Ovl = R.Expression;
if (ArgType.isNull()) continue;
// Function-to-pointer conversion.
- if (!ParamWasReference && ParamType->isPointerType() &&
+ if (!ParamWasReference && ParamType->isPointerType() &&
ArgType->isFunctionType())
ArgType = S.Context.getPointerType(ArgType);
-
+
// - If the argument is an overload set (not containing function
// templates), trial argument deduction is attempted using each
// of the members of the set. If deduction succeeds for only one
// Type deduction is done independently for each P/A pair, and
// the deduced template argument values are then combined.
// So we do not reject deductions which were made elsewhere.
- llvm::SmallVector<DeducedTemplateArgument, 8>
+ llvm::SmallVector<DeducedTemplateArgument, 8>
Deduced(TemplateParams->size());
TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
Sema::TemplateDeductionResult Result
return Match;
}
-/// \brief Perform the adjustments to the parameter and argument types
+/// \brief Perform the adjustments to the parameter and argument types
/// described in C++ [temp.deduct.call].
///
/// \returns true if the caller should not attempt to perform any template
// for type deduction.
ParamType = ParamRefType->getPointeeType();
}
-
+
// Overload sets usually make this parameter an undeduced
// context, but there are sometimes special circumstances.
if (ArgType == S.Context.OverloadTy) {
if (ArgType.isNull())
return true;
}
-
+
if (ParamRefType) {
// C++0x [temp.deduct.call]p3:
// [...] If P is of the form T&&, where T is a template parameter, and
ArgType = ArgType.getUnqualifiedType();
}
}
-
+
// C++0x [temp.deduct.call]p4:
// In general, the deduction process attempts to find template argument
// values that will make the deduced A identical to A (after the type A
// is transformed as described above). [...]
TDF = TDF_SkipNonDependent;
-
+
// - If the original P is a reference type, the deduced A (i.e., the
// type referred to by the reference) can be more cv-qualified than
// the transformed A.
isSimpleTemplateIdType(
ParamType->getAs<PointerType>()->getPointeeType())))
TDF |= TDF_DerivedClass;
-
+
return false;
}
/// \param Name the name of the function being called. This is only significant
/// when the function template is a conversion function template, in which
/// case this routine will also perform template argument deduction based on
-/// the function to which
+/// the function to which
///
/// \param Specialization if template argument deduction was successful,
/// this will be set to the function template specialization produced by
/* Do nothing */;
else if (Proto->isVariadic())
CheckArgs = Function->getNumParams();
- else
+ else
return TDK_TooManyArguments;
}
// Deduce template arguments from the function parameters.
Deduced.resize(TemplateParams->size());
unsigned ArgIdx = 0;
- for (unsigned ParamIdx = 0, NumParams = ParamTypes.size();
+ for (unsigned ParamIdx = 0, NumParams = ParamTypes.size();
ParamIdx != NumParams; ++ParamIdx) {
QualType ParamType = ParamTypes[ParamIdx];
-
- const PackExpansionType *ParamExpansion
+
+ const PackExpansionType *ParamExpansion
= dyn_cast<PackExpansionType>(ParamType);
if (!ParamExpansion) {
// Simple case: matching a function parameter to a function argument.
if (ArgIdx >= CheckArgs)
break;
-
+
Expr *Arg = Args[ArgIdx++];
QualType ArgType = Arg->getType();
unsigned TDF = 0;
ParamType, ArgType, Arg,
TDF))
continue;
-
+
if (TemplateDeductionResult Result
= ::DeduceTemplateArguments(*this, TemplateParams,
ParamType, ArgType, Info, Deduced,
// modulo the various allowed differences.
continue;
}
-
+
// C++0x [temp.deduct.call]p1:
- // For a function parameter pack that occurs at the end of the
- // parameter-declaration-list, the type A of each remaining argument of
- // the call is compared with the type P of the declarator-id of the
- // function parameter pack. Each comparison deduces template arguments
- // for subsequent positions in the template parameter packs expanded by
+ // For a function parameter pack that occurs at the end of the
+ // parameter-declaration-list, the type A of each remaining argument of
+ // the call is compared with the type P of the declarator-id of the
+ // function parameter pack. Each comparison deduces template arguments
+ // for subsequent positions in the template parameter packs expanded by
// the function parameter pack. For a function parameter pack that does
- // not occur at the end of the parameter-declaration-list, the type of
+ // not occur at the end of the parameter-declaration-list, the type of
// the parameter pack is a non-deduced context.
if (ParamIdx + 1 < NumParams)
break;
-
+
QualType ParamPattern = ParamExpansion->getPattern();
llvm::SmallVector<unsigned, 2> PackIndices;
{
}
}
assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
+
// Keep track of the deduced template arguments for each parameter pack
- // expanded by this pack expansion (the outer index) and for each
+ // expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
NewlyDeducedPacks(PackIndices.size());
- llvm::SmallVector<DeducedTemplateArgument, 2>
+ llvm::SmallVector<DeducedTemplateArgument, 2>
SavedPacks(PackIndices.size());
PrepareArgumentPackDeduction(*this, Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks);
+ NewlyDeducedPacks);
bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
HasAnyArguments = true;
-
+
ParamType = ParamPattern;
Expr *Arg = Args[ArgIdx];
QualType ArgType = Arg->getType();
++ArgIdx;
break;
}
-
+
if (TemplateDeductionResult Result
= ::DeduceTemplateArguments(*this, TemplateParams,
ParamType, ArgType, Info, Deduced,
}
}
}
-
+
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
if (Sema::TemplateDeductionResult Result
- = FinishArgumentPackDeduction(*this, TemplateParams, HasAnyArguments,
+ = FinishArgumentPackDeduction(*this, TemplateParams, HasAnyArguments,
Deduced, PackIndices, SavedPacks,
NewlyDeducedPacks, Info))
- return Result;
+ return Result;
// After we've matching against a parameter pack, we're done.
break;
/// \param FunctionTemplate the function template for which we are performing
/// template argument deduction.
///
-/// \param ExplicitTemplateArguments the explicitly-specified template
+/// \param ExplicitTemplateArguments the explicitly-specified template
/// arguments.
///
/// \param ArgFunctionType the function type that will be used as the
return Result;
}
- if (TemplateDeductionResult Result
+ if (TemplateDeductionResult Result
= FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
NumExplicitlySpecified,
Specialization, Info))
LocalInstantiationScope InstScope(*this);
FunctionDecl *Spec = 0;
TemplateDeductionResult Result
- = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec,
+ = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec,
Info);
Specialization = cast_or_null<CXXConversionDecl>(Spec);
return Result;
/// \param FunctionTemplate the function template for which we are performing
/// template argument deduction.
///
-/// \param ExplicitTemplateArguments the explicitly-specified template
+/// \param ExplicitTemplateArguments the explicitly-specified template
/// arguments.
///
/// \param Specialization if template argument deduction was successful,
bool OnlyDeduced,
unsigned Level,
llvm::SmallVectorImpl<bool> &Deduced);
-
-/// \brief If this is a non-static member function,
+
+/// \brief If this is a non-static member function,
static void MaybeAddImplicitObjectParameterType(ASTContext &Context,
CXXMethodDecl *Method,
llvm::SmallVectorImpl<QualType> &ArgTypes) {
FunctionTemplateDecl *FT1,
FunctionTemplateDecl *FT2,
TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments,
+ unsigned NumCallArguments,
llvm::SmallVectorImpl<RefParamPartialOrderingComparison> *RefParamComparisons) {
FunctionDecl *FD1 = FT1->getTemplatedDecl();
- FunctionDecl *FD2 = FT2->getTemplatedDecl();
+ FunctionDecl *FD2 = FT2->getTemplatedDecl();
const FunctionProtoType *Proto1 = FD1->getType()->getAs<FunctionProtoType>();
const FunctionProtoType *Proto2 = FD2->getType()->getAs<FunctionProtoType>();
-
+
assert(Proto1 && Proto2 && "Function templates must have prototypes");
TemplateParameterList *TemplateParams = FT2->getTemplateParameters();
llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
// first argument of the free function or static member, which
// seems to match existing practice.
llvm::SmallVector<QualType, 4> Args1;
- unsigned Skip1 = !S.getLangOptions().CPlusPlus0x &&
+ unsigned Skip1 = !S.getLangOptions().CPlusPlus0x &&
IsNonStatic2 && !IsNonStatic1;
if (S.getLangOptions().CPlusPlus0x && IsNonStatic1 && !IsNonStatic2)
- MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1);
- Args1.insert(Args1.end(),
+ MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1);
+ Args1.insert(Args1.end(),
Proto1->arg_type_begin() + Skip1, Proto1->arg_type_end());
llvm::SmallVector<QualType, 4> Args2;
- Skip2 = !S.getLangOptions().CPlusPlus0x &&
+ Skip2 = !S.getLangOptions().CPlusPlus0x &&
IsNonStatic1 && !IsNonStatic2;
if (S.getLangOptions().CPlusPlus0x && IsNonStatic2 && !IsNonStatic1)
MaybeAddImplicitObjectParameterType(S.Context, Method2, Args2);
- Args2.insert(Args2.end(),
+ Args2.insert(Args2.end(),
Proto2->arg_type_begin() + Skip2, Proto2->arg_type_end());
-
+
// C++ [temp.func.order]p5:
// The presence of unused ellipsis and default arguments has no effect on
// the partial ordering of function templates.
TDF_None, /*PartialOrdering=*/true,
RefParamComparisons))
return false;
-
+
break;
}
-
+
case TPOC_Conversion:
// - In the context of a call to a conversion operator, the return types
// of the conversion function templates are used.
RefParamComparisons))
return false;
break;
-
+
case TPOC_Other:
// - In other contexts (14.6.6.2) the function template's function type
// is used.
// FIXME: Don't we actually want to perform the adjustments on the parameter
// types?
- if (DeduceTemplateArguments(S, TemplateParams, FD2->getType(),
+ if (DeduceTemplateArguments(S, TemplateParams, FD2->getType(),
FD1->getType(), Info, Deduced, TDF_None,
/*PartialOrdering=*/true, RefParamComparisons))
return false;
break;
}
-
+
// C++0x [temp.deduct.partial]p11:
- // In most cases, all template parameters must have values in order for
- // deduction to succeed, but for partial ordering purposes a template
- // parameter may remain without a value provided it is not used in the
+ // In most cases, all template parameters must have values in order for
+ // deduction to succeed, but for partial ordering purposes a template
+ // parameter may remain without a value provided it is not used in the
// types being used for partial ordering. [ Note: a template parameter used
// in a non-deduced context is considered used. -end note]
unsigned ArgIdx = 0, NumArgs = Deduced.size();
break;
if (ArgIdx == NumArgs) {
- // All template arguments were deduced. FT1 is at least as specialized
+ // All template arguments were deduced. FT1 is at least as specialized
// as FT2.
return true;
}
UsedParameters.resize(TemplateParams->size());
switch (TPOC) {
case TPOC_Call: {
- unsigned NumParams = std::min(NumCallArguments,
- std::min(Proto1->getNumArgs(),
+ unsigned NumParams = std::min(NumCallArguments,
+ std::min(Proto1->getNumArgs(),
Proto2->getNumArgs()));
if (S.getLangOptions().CPlusPlus0x && IsNonStatic2 && !IsNonStatic1)
- ::MarkUsedTemplateParameters(S, Method2->getThisType(S.Context), false,
+ ::MarkUsedTemplateParameters(S, Method2->getThisType(S.Context), false,
TemplateParams->getDepth(), UsedParameters);
for (unsigned I = Skip2; I < NumParams; ++I)
- ::MarkUsedTemplateParameters(S, Proto2->getArgType(I), false,
+ ::MarkUsedTemplateParameters(S, Proto2->getArgType(I), false,
TemplateParams->getDepth(),
UsedParameters);
break;
}
-
+
case TPOC_Conversion:
- ::MarkUsedTemplateParameters(S, Proto2->getResultType(), false,
+ ::MarkUsedTemplateParameters(S, Proto2->getResultType(), false,
TemplateParams->getDepth(),
UsedParameters);
break;
-
+
case TPOC_Other:
- ::MarkUsedTemplateParameters(S, FD2->getType(), false,
+ ::MarkUsedTemplateParameters(S, FD2->getType(), false,
TemplateParams->getDepth(),
UsedParameters);
break;
}
-
+
for (; ArgIdx != NumArgs; ++ArgIdx)
// If this argument had no value deduced but was used in one of the types
// used for partial ordering, then deduction fails.
if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
return false;
-
+
return true;
}
-
+
/// \brief Determine whether this a function template whose parameter-type-list
/// ends with a function parameter pack.
static bool isVariadicFunctionTemplate(FunctionTemplateDecl *FunTmpl) {
unsigned NumParams = Function->getNumParams();
if (NumParams == 0)
return false;
-
+
ParmVarDecl *Last = Function->getParamDecl(NumParams - 1);
if (!Last->isParameterPack())
return false;
-
+
// Make sure that no previous parameter is a parameter pack.
while (--NumParams > 0) {
if (Function->getParamDecl(NumParams - 1)->isParameterPack())
return false;
}
-
+
return true;
}
-
+
/// \brief Returns the more specialized function template according
/// to the rules of function template partial ordering (C++ [temp.func.order]).
///
TemplatePartialOrderingContext TPOC,
unsigned NumCallArguments) {
llvm::SmallVector<RefParamPartialOrderingComparison, 4> RefParamComparisons;
- bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
+ bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
NumCallArguments, 0);
- bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
+ bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
NumCallArguments,
&RefParamComparisons);
-
+
if (Better1 != Better2) // We have a clear winner
return Better1? FT1 : FT2;
-
+
if (!Better1 && !Better2) // Neither is better than the other
return 0;
// C++0x [temp.deduct.partial]p10:
- // If for each type being considered a given template is at least as
+ // If for each type being considered a given template is at least as
// specialized for all types and more specialized for some set of types and
- // the other template is not more specialized for any types or is not at
+ // the other template is not more specialized for any types or is not at
// least as specialized for any types, then the given template is more
// specialized than the other template. Otherwise, neither template is more
// specialized than the other.
// were reference types (before being replaced with the type referred to
// above):
- // -- if the type from the argument template was an lvalue reference
+ // -- if the type from the argument template was an lvalue reference
// and the type from the parameter template was not, the argument
// type is considered to be more specialized than the other;
// otherwise,
return 0;
continue;
}
-
+
// -- if the type from the argument template is more cv-qualified than
// the type from the parameter template (as described above), the
// argument type is considered to be more specialized than the
switch (RefParamComparisons[I].Qualifiers) {
case NeitherMoreQualified:
break;
-
+
case ParamMoreQualified:
Better1 = true;
if (Better2)
return 0;
continue;
-
+
case ArgMoreQualified:
Better2 = true;
if (Better1)
return 0;
continue;
}
-
+
// -- neither type is more specialized than the other.
}
-
+
assert(!(Better1 && Better2) && "Should have broken out in the loop above");
if (Better1)
return FT1;
else if (Better2)
return FT2;
-
+
// FIXME: This mimics what GCC implements, but doesn't match up with the
// proposed resolution for core issue 692. This area needs to be sorted out,
// but for now we attempt to maintain compatibility.
bool Variadic2 = isVariadicFunctionTemplate(FT2);
if (Variadic1 != Variadic2)
return Variadic1? FT2 : FT1;
-
+
return 0;
}
static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) {
if (T1 == T2)
return true;
-
+
if (!T1 || !T2)
return false;
-
+
return T1->getCanonicalDecl() == T2->getCanonicalDecl();
}
/// \param NumCallArguments The number of arguments in a call, used only
/// when \c TPOC is \c TPOC_Call.
///
-/// \param Loc the location where the ambiguity or no-specializations
+/// \param Loc the location where the ambiguity or no-specializations
/// diagnostic should occur.
///
/// \param NoneDiag partial diagnostic used to diagnose cases where there are
/// in this diagnostic should be unbound, which will correspond to the string
/// describing the template arguments for the function template specialization.
///
-/// \param Index if non-NULL and the result of this function is non-nULL,
+/// \param Index if non-NULL and the result of this function is non-nULL,
/// receives the index corresponding to the resulting function template
/// specialization.
///
-/// \returns the most specialized function template specialization, if
+/// \returns the most specialized function template specialization, if
/// found. Otherwise, returns SpecEnd.
///
-/// \todo FIXME: Consider passing in the "also-ran" candidates that failed
+/// \todo FIXME: Consider passing in the "also-ran" candidates that failed
/// template argument deduction.
UnresolvedSetIterator
Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
Diag(Loc, NoneDiag);
return SpecEnd;
}
-
- if (SpecBegin + 1 == SpecEnd)
+
+ if (SpecBegin + 1 == SpecEnd)
return SpecBegin;
-
+
// Find the function template that is better than all of the templates it
// has been compared to.
UnresolvedSetIterator Best = SpecBegin;
- FunctionTemplateDecl *BestTemplate
+ FunctionTemplateDecl *BestTemplate
= cast<FunctionDecl>(*Best)->getPrimaryTemplate();
assert(BestTemplate && "Not a function template specialization?");
for (UnresolvedSetIterator I = SpecBegin + 1; I != SpecEnd; ++I) {
BestTemplate = Challenger;
}
}
-
+
// Make sure that the "best" function template is more specialized than all
// of the others.
bool Ambiguous = false;
FunctionTemplateDecl *Challenger
= cast<FunctionDecl>(*I)->getPrimaryTemplate();
if (I != Best &&
- !isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
+ !isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
Loc, TPOC, NumCallArguments),
BestTemplate)) {
Ambiguous = true;
break;
}
}
-
+
if (!Ambiguous) {
// We found an answer. Return it.
return Best;
}
-
+
// Diagnose the ambiguity.
Diag(Loc, AmbigDiag);
-
+
// FIXME: Can we order the candidates in some sane way?
for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I)
Diag((*I)->getLocation(), CandidateDiag)
<< getTemplateArgumentBindingsText(
cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
*cast<FunctionDecl>(*I)->getTemplateSpecializationArgs());
-
+
return SpecEnd;
}
SourceLocation Loc) {
// C++ [temp.class.order]p1:
// For two class template partial specializations, the first is at least as
- // specialized as the second if, given the following rewrite to two
- // function templates, the first function template is at least as
- // specialized as the second according to the ordering rules for function
+ // specialized as the second if, given the following rewrite to two
+ // function templates, the first function template is at least as
+ // specialized as the second according to the ordering rules for function
// templates (14.6.6.2):
// - the first function template has the same template parameters as the
- // first partial specialization and has a single function parameter
- // whose type is a class template specialization with the template
+ // first partial specialization and has a single function parameter
+ // whose type is a class template specialization with the template
// arguments of the first partial specialization, and
// - the second function template has the same template parameters as the
- // second partial specialization and has a single function parameter
- // whose type is a class template specialization with the template
+ // second partial specialization and has a single function parameter
+ // whose type is a class template specialization with the template
// arguments of the second partial specialization.
//
// Rather than synthesize function templates, we merely perform the
QualType PT1 = PS1->getInjectedSpecializationType();
QualType PT2 = PS2->getInjectedSpecializationType();
-
+
// Determine whether PS1 is at least as specialized as PS2
Deduced.resize(PS2->getTemplateParameters()->size());
bool Better1 = !::DeduceTemplateArguments(*this, PS2->getTemplateParameters(),
PT2, PT1, Info, Deduced, TDF_None,
- /*PartialOrdering=*/true,
+ /*PartialOrdering=*/true,
/*RefParamComparisons=*/0);
if (Better1) {
InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2,
Deduced.data(), Deduced.size(), Info);
- Better1 = !::FinishTemplateArgumentDeduction(*this, PS2,
- PS1->getTemplateArgs(),
+ Better1 = !::FinishTemplateArgumentDeduction(*this, PS2,
+ PS1->getTemplateArgs(),
Deduced, Info);
}
-
+
// Determine whether PS2 is at least as specialized as PS1
Deduced.clear();
Deduced.resize(PS1->getTemplateParameters()->size());
if (Better2) {
InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1,
Deduced.data(), Deduced.size(), Info);
- Better2 = !::FinishTemplateArgumentDeduction(*this, PS1,
- PS2->getTemplateArgs(),
+ Better2 = !::FinishTemplateArgumentDeduction(*this, PS1,
+ PS2->getTemplateArgs(),
Deduced, Info);
}
-
+
if (Better1 == Better2)
return 0;
-
+
return Better1? PS1 : PS2;
}
// We can deduce from a pack expansion.
if (const PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(E))
E = Expansion->getPattern();
-
+
// Skip through any implicit casts we added while type-checking.
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
E = ICE->getSubExpr();
-
- // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to
+
+ // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to
// find other occurrences of template parameters.
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
if (!DRE)
llvm::SmallVectorImpl<bool> &Used) {
if (!NNS)
return;
-
+
MarkUsedTemplateParameters(SemaRef, NNS->getPrefix(), OnlyDeduced, Depth,
Used);
- MarkUsedTemplateParameters(SemaRef, QualType(NNS->getAsType(), 0),
+ MarkUsedTemplateParameters(SemaRef, QualType(NNS->getAsType(), 0),
OnlyDeduced, Depth, Used);
}
-
+
/// \brief Mark the template parameters that are used by the given
/// template name.
static void
}
return;
}
-
+
if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName())
- MarkUsedTemplateParameters(SemaRef, QTN->getQualifier(), OnlyDeduced,
+ MarkUsedTemplateParameters(SemaRef, QTN->getQualifier(), OnlyDeduced,
Depth, Used);
if (DependentTemplateName *DTN = Name.getAsDependentTemplateName())
- MarkUsedTemplateParameters(SemaRef, DTN->getQualifier(), OnlyDeduced,
+ MarkUsedTemplateParameters(SemaRef, DTN->getQualifier(), OnlyDeduced,
Depth, Used);
}
llvm::SmallVectorImpl<bool> &Used) {
if (T.isNull())
return;
-
+
// Non-dependent types have nothing deducible
if (!T->isDependentType())
return;
= cast<DependentSizedExtVectorType>(T);
MarkUsedTemplateParameters(SemaRef, VecType->getElementType(), OnlyDeduced,
Depth, Used);
- MarkUsedTemplateParameters(SemaRef, VecType->getSizeExpr(), OnlyDeduced,
+ MarkUsedTemplateParameters(SemaRef, VecType->getSizeExpr(), OnlyDeduced,
Depth, Used);
break;
}
case Type::SubstTemplateTypeParmPack: {
const SubstTemplateTypeParmPackType *Subst
= cast<SubstTemplateTypeParmPackType>(T);
- MarkUsedTemplateParameters(SemaRef,
+ MarkUsedTemplateParameters(SemaRef,
QualType(Subst->getReplacedParameter(), 0),
OnlyDeduced, Depth, Used);
MarkUsedTemplateParameters(SemaRef, Subst->getArgumentPack(),
= cast<TemplateSpecializationType>(T);
MarkUsedTemplateParameters(SemaRef, Spec->getTemplateName(), OnlyDeduced,
Depth, Used);
-
+
// C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is not
- // the last template argument, the entire template argument list is a
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
// non-deduced context.
- if (OnlyDeduced &&
+ if (OnlyDeduced &&
hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs()))
break;
case Type::Complex:
if (!OnlyDeduced)
- MarkUsedTemplateParameters(SemaRef,
+ MarkUsedTemplateParameters(SemaRef,
cast<ComplexType>(T)->getElementType(),
OnlyDeduced, Depth, Used);
break;
if (!OnlyDeduced)
MarkUsedTemplateParameters(SemaRef, Spec->getQualifier(),
OnlyDeduced, Depth, Used);
-
+
// C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is not
- // the last template argument, the entire template argument list is a
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
// non-deduced context.
- if (OnlyDeduced &&
+ if (OnlyDeduced &&
hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs()))
break;
break;
case Type::PackExpansion:
- MarkUsedTemplateParameters(SemaRef,
+ MarkUsedTemplateParameters(SemaRef,
cast<PackExpansionType>(T)->getPattern(),
OnlyDeduced, Depth, Used);
break;
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
- MarkUsedTemplateParameters(SemaRef,
- TemplateArg.getAsTemplateOrTemplatePattern(),
+ MarkUsedTemplateParameters(SemaRef,
+ TemplateArg.getAsTemplateOrTemplatePattern(),
OnlyDeduced, Depth, Used);
break;
case TemplateArgument::Expression:
- MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsExpr(), OnlyDeduced,
+ MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsExpr(), OnlyDeduced,
Depth, Used);
break;
-
+
case TemplateArgument::Pack:
for (TemplateArgument::pack_iterator P = TemplateArg.pack_begin(),
PEnd = TemplateArg.pack_end();
bool OnlyDeduced, unsigned Depth,
llvm::SmallVectorImpl<bool> &Used) {
// C++0x [temp.deduct.type]p9:
- // If the template argument list of P contains a pack expansion that is not
- // the last template argument, the entire template argument list is a
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
// non-deduced context.
- if (OnlyDeduced &&
+ if (OnlyDeduced &&
hasPackExpansionBeforeEnd(TemplateArgs.data(), TemplateArgs.size()))
return;
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
- ::MarkUsedTemplateParameters(*this, TemplateArgs[I], OnlyDeduced,
+ ::MarkUsedTemplateParameters(*this, TemplateArgs[I], OnlyDeduced,
Depth, Used);
}
/// \brief Marks all of the template parameters that will be deduced by a
/// call to the given function template.
-void
+void
Sema::MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
llvm::SmallVectorImpl<bool> &Deduced) {
- TemplateParameterList *TemplateParams
+ TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
Deduced.clear();
Deduced.resize(TemplateParams->size());
-
+
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I)
::MarkUsedTemplateParameters(*this, Function->getParamDecl(I)->getType(),
SVal V = svalBuilder.getConjuredSymbolVal(R, E, T, Count);
return Bind(store, loc::MemRegionVal(R), V);
}
-