forked from OSchip/llvm-project
Split Sema::MarkDeclarationReferenced into multiple functions; the additional entry points are needed to implement C++11 odr-use marking correctly. No functional change in this patch; I'll actually make the change which fixes the odr-use marking in a followup patch.
llvm-svn: 149586
This commit is contained in:
parent
961883c1cf
commit
fa0df83eba
|
@ -2265,7 +2265,19 @@ public:
|
|||
ExprResult TranformToPotentiallyEvaluated(Expr *E);
|
||||
ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
|
||||
|
||||
void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
|
||||
// Functions for marking a declaration referenced. These functions also
|
||||
// contain the relevant logic for marking if a reference to a function or
|
||||
// variable is an odr-use (in the C++11 sense). There are separate variants
|
||||
// for expressions referring to a decl; these exist because odr-use marking
|
||||
// needs to be delayed for some constant variables when we build one of the
|
||||
// named expressions.
|
||||
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D);
|
||||
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
|
||||
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
|
||||
void MarkBlockDeclRefReferenced(BlockDeclRefExpr *E);
|
||||
void MarkDeclRefReferenced(DeclRefExpr *E);
|
||||
void MarkMemberReferenced(MemberExpr *E);
|
||||
|
||||
void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
|
||||
void MarkDeclarationsReferencedInExpr(Expr *E);
|
||||
|
||||
|
|
|
@ -2160,7 +2160,7 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
|||
}
|
||||
|
||||
D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
|
||||
S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
|
||||
S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
|
||||
}
|
||||
|
||||
/// Handle __attribute__((format_arg((idx)))) attribute based on
|
||||
|
|
|
@ -2382,14 +2382,14 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
|
|||
ParmVarDecl *Param = Constructor->getParamDecl(0);
|
||||
QualType ParamType = Param->getType().getNonReferenceType();
|
||||
|
||||
SemaRef.MarkDeclarationReferenced(Constructor->getLocation(), Param);
|
||||
|
||||
Expr *CopyCtorArg =
|
||||
DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
|
||||
SourceLocation(), Param,
|
||||
Constructor->getLocation(), ParamType,
|
||||
VK_LValue, 0);
|
||||
|
||||
SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(CopyCtorArg));
|
||||
|
||||
// Cast to the base class to avoid ambiguities.
|
||||
QualType ArgTy =
|
||||
SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(),
|
||||
|
@ -2454,8 +2454,6 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
|
|||
ParmVarDecl *Param = Constructor->getParamDecl(0);
|
||||
QualType ParamType = Param->getType().getNonReferenceType();
|
||||
|
||||
SemaRef.MarkDeclarationReferenced(Constructor->getLocation(), Param);
|
||||
|
||||
// Suppress copying zero-width bitfields.
|
||||
if (Field->isBitField() && Field->getBitWidthValue(SemaRef.Context) == 0)
|
||||
return false;
|
||||
|
@ -2465,6 +2463,8 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
|
|||
SourceLocation(), Param,
|
||||
Loc, ParamType, VK_LValue, 0);
|
||||
|
||||
SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase));
|
||||
|
||||
if (Moving) {
|
||||
MemberExprBase = CastForMoving(SemaRef, MemberExprBase);
|
||||
}
|
||||
|
@ -2796,7 +2796,7 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
|
|||
Constructor->setCtorInitializers(initializer);
|
||||
|
||||
if (CXXDestructorDecl *Dtor = LookupDestructor(Constructor->getParent())) {
|
||||
MarkDeclarationReferenced(Initializer->getSourceLocation(), Dtor);
|
||||
MarkFunctionReferenced(Initializer->getSourceLocation(), Dtor);
|
||||
DiagnoseUseOfDecl(Dtor, Initializer->getSourceLocation());
|
||||
}
|
||||
|
||||
|
@ -3272,7 +3272,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
|
|||
<< Field->getDeclName()
|
||||
<< FieldType);
|
||||
|
||||
MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
|
||||
MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
|
||||
}
|
||||
|
||||
llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
|
||||
|
@ -3304,7 +3304,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
|
|||
<< Base->getType()
|
||||
<< Base->getSourceRange());
|
||||
|
||||
MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
|
||||
MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
|
||||
}
|
||||
|
||||
// Virtual bases.
|
||||
|
@ -3332,7 +3332,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
|
|||
PDiag(diag::err_access_dtor_vbase)
|
||||
<< VBase->getType());
|
||||
|
||||
MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
|
||||
MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5306,7 +5306,7 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
|
|||
if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
|
||||
return true;
|
||||
|
||||
MarkDeclarationReferenced(Loc, OperatorDelete);
|
||||
MarkFunctionReferenced(Loc, OperatorDelete);
|
||||
|
||||
Destructor->setOperatorDelete(OperatorDelete);
|
||||
}
|
||||
|
@ -9030,7 +9030,7 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
|||
CheckNonNullArguments(NonNull, ExprArgs.get(), ConstructLoc);
|
||||
}
|
||||
|
||||
MarkDeclarationReferenced(ConstructLoc, Constructor);
|
||||
MarkFunctionReferenced(ConstructLoc, Constructor);
|
||||
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
|
||||
Constructor, Elidable, Exprs, NumExprs,
|
||||
HadMultipleCandidates, RequiresZeroInit,
|
||||
|
@ -9052,7 +9052,7 @@ bool Sema::InitializeVarWithConstructor(VarDecl *VD,
|
|||
|
||||
Expr *Temp = TempResult.takeAs<Expr>();
|
||||
CheckImplicitConversions(Temp, VD->getLocation());
|
||||
MarkDeclarationReferenced(VD->getLocation(), Constructor);
|
||||
MarkFunctionReferenced(VD->getLocation(), Constructor);
|
||||
Temp = MaybeCreateExprWithCleanups(Temp);
|
||||
VD->setInit(Temp);
|
||||
|
||||
|
@ -9068,7 +9068,7 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
|
|||
if (ClassDecl->isDependentContext()) return;
|
||||
|
||||
CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);
|
||||
MarkDeclarationReferenced(VD->getLocation(), Destructor);
|
||||
MarkFunctionReferenced(VD->getLocation(), Destructor);
|
||||
CheckDestructorAccess(VD->getLocation(), Destructor,
|
||||
PDiag(diag::err_access_dtor_var)
|
||||
<< VD->getDeclName()
|
||||
|
@ -10905,7 +10905,7 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
|
|||
// C++ [basic.def.odr]p2:
|
||||
// [...] A virtual member function is used if it is not pure. [...]
|
||||
if (MD->isVirtual() && !MD->isPure())
|
||||
MarkDeclarationReferenced(Loc, MD);
|
||||
MarkFunctionReferenced(Loc, MD);
|
||||
}
|
||||
|
||||
// Only classes that have virtual bases need a VTT.
|
||||
|
@ -10965,7 +10965,7 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
|
|||
->getAs<RecordType>()) {
|
||||
CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
|
||||
if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
|
||||
MarkDeclarationReferenced(Field->getLocation(), Destructor);
|
||||
MarkFunctionReferenced(Field->getLocation(), Destructor);
|
||||
CheckDestructorAccess(Field->getLocation(), Destructor,
|
||||
PDiag(diag::err_access_dtor_ivar)
|
||||
<< Context.getBaseElementType(Field->getType()));
|
||||
|
|
|
@ -1331,8 +1331,6 @@ static CaptureResult shouldCaptureValueReference(Sema &S, SourceLocation loc,
|
|||
return CR_Error;
|
||||
}
|
||||
|
||||
S.MarkDeclarationReferenced(loc, var);
|
||||
|
||||
// The BlocksAttr indicates the variable is bound by-reference.
|
||||
bool byRef = var->hasAttr<BlocksAttr>();
|
||||
|
||||
|
@ -1411,6 +1409,8 @@ static ExprResult BuildBlockDeclRefExpr(Sema &S, ValueDecl *VD,
|
|||
NameInfo.getLoc(), true);
|
||||
}
|
||||
|
||||
S.MarkBlockDeclRefReferenced(BDRE);
|
||||
|
||||
return S.Owned(BDRE);
|
||||
}
|
||||
|
||||
|
@ -1442,13 +1442,13 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
|
|||
}
|
||||
}
|
||||
|
||||
MarkDeclarationReferenced(NameInfo.getLoc(), D);
|
||||
DeclRefExpr *E = DeclRefExpr::Create(Context,
|
||||
SS ? SS->getWithLocInContext(Context)
|
||||
: NestedNameSpecifierLoc(),
|
||||
SourceLocation(),
|
||||
D, NameInfo, Ty, VK);
|
||||
|
||||
Expr *E = DeclRefExpr::Create(Context,
|
||||
SS ? SS->getWithLocInContext(Context)
|
||||
: NestedNameSpecifierLoc(),
|
||||
SourceLocation(),
|
||||
D, NameInfo, Ty, VK);
|
||||
MarkDeclRefReferenced(E);
|
||||
|
||||
// Just in case we're building an illegal pointer-to-member.
|
||||
FieldDecl *FD = dyn_cast<FieldDecl>(D);
|
||||
|
@ -2004,7 +2004,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
|
|||
if (SelfExpr.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
MarkDeclarationReferenced(Loc, IV);
|
||||
MarkAnyDeclReferenced(Loc, IV);
|
||||
return Owned(new (Context)
|
||||
ObjCIvarRefExpr(IV, IV->getType(), Loc,
|
||||
SelfExpr.take(), true, true));
|
||||
|
@ -3742,7 +3742,7 @@ Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
|
|||
|
||||
DeclRefExpr *ConfigDR = new (Context) DeclRefExpr(
|
||||
ConfigDecl, ConfigQTy, VK_LValue, LLLLoc);
|
||||
MarkDeclarationReferenced(LLLLoc, ConfigDecl);
|
||||
MarkFunctionReferenced(LLLLoc, ConfigDecl);
|
||||
|
||||
return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, 0,
|
||||
/*IsExecConfig=*/true);
|
||||
|
@ -9436,9 +9436,7 @@ Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
|
|||
}
|
||||
|
||||
void Sema::PopExpressionEvaluationContext() {
|
||||
// Pop the current expression evaluation context off the stack.
|
||||
ExpressionEvaluationContextRecord Rec = ExprEvalContexts.back();
|
||||
ExprEvalContexts.pop_back();
|
||||
ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
|
||||
|
||||
// When are coming out of an unevaluated context, clear out any
|
||||
// temporaries that we may have created as part of the evaluation of
|
||||
|
@ -9453,6 +9451,9 @@ void Sema::PopExpressionEvaluationContext() {
|
|||
} else {
|
||||
ExprNeedsCleanups |= Rec.ParentNeedsCleanups;
|
||||
}
|
||||
|
||||
// Pop the current expression evaluation context off the stack.
|
||||
ExprEvalContexts.pop_back();
|
||||
}
|
||||
|
||||
void Sema::DiscardCleanupsInEvaluationContext() {
|
||||
|
@ -9468,55 +9469,49 @@ ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) {
|
|||
return TranformToPotentiallyEvaluated(E);
|
||||
}
|
||||
|
||||
/// \brief Note that the given declaration was referenced in the source code.
|
||||
///
|
||||
/// This routine should be invoke whenever a given declaration is referenced
|
||||
/// in the source code, and where that reference occurred. If this declaration
|
||||
/// reference means that the the declaration is used (C++ [basic.def.odr]p2,
|
||||
/// C99 6.9p3), then the declaration will be marked as used.
|
||||
///
|
||||
/// \param Loc the location where the declaration was referenced.
|
||||
///
|
||||
/// \param D the declaration that has been referenced by the source code.
|
||||
void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
|
||||
assert(D && "No declaration?");
|
||||
|
||||
D->setReferenced();
|
||||
|
||||
if (D->isUsed(false))
|
||||
return;
|
||||
|
||||
if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D))
|
||||
return;
|
||||
|
||||
bool IsPotentiallyEvaluatedContext(Sema &SemaRef) {
|
||||
// Do not mark anything as "used" within a dependent context; wait for
|
||||
// an instantiation.
|
||||
if (CurContext->isDependentContext())
|
||||
return;
|
||||
if (SemaRef.CurContext->isDependentContext())
|
||||
return false;
|
||||
|
||||
switch (ExprEvalContexts.back().Context) {
|
||||
case Unevaluated:
|
||||
switch (SemaRef.ExprEvalContexts.back().Context) {
|
||||
case Sema::Unevaluated:
|
||||
// We are in an expression that is not potentially evaluated; do nothing.
|
||||
// (Depending on how you read the standard, we actually do need to do
|
||||
// something here for null pointer constants, but the standard's
|
||||
// definition of a null pointer constant is completely crazy.)
|
||||
return;
|
||||
return false;
|
||||
|
||||
case ConstantEvaluated:
|
||||
case PotentiallyEvaluated:
|
||||
case Sema::ConstantEvaluated:
|
||||
case Sema::PotentiallyEvaluated:
|
||||
// We are in a potentially evaluated expression (or a constant-expression
|
||||
// in C++03); we need to do implicit template instantiation, implicitly
|
||||
// define class members, and mark most declarations as used.
|
||||
break;
|
||||
return true;
|
||||
|
||||
case PotentiallyEvaluatedIfUsed:
|
||||
case Sema::PotentiallyEvaluatedIfUsed:
|
||||
// Referenced declarations will only be used if the construct in the
|
||||
// containing expression is used.
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Mark a function referenced, and check whether it is odr-used
|
||||
/// (C++ [basic.def.odr]p2, C99 6.9p3)
|
||||
void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
|
||||
assert(Func && "No function?");
|
||||
|
||||
Func->setReferenced();
|
||||
|
||||
if (Func->isUsed(false))
|
||||
return;
|
||||
|
||||
if (!IsPotentiallyEvaluatedContext(*this))
|
||||
return;
|
||||
|
||||
// Note that this declaration has been used.
|
||||
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
|
||||
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Func)) {
|
||||
if (Constructor->isDefaulted()) {
|
||||
if (Constructor->isDefaultConstructor()) {
|
||||
if (Constructor->isTrivial())
|
||||
|
@ -9533,12 +9528,13 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
|
|||
}
|
||||
|
||||
MarkVTableUsed(Loc, Constructor->getParent());
|
||||
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
|
||||
} else if (CXXDestructorDecl *Destructor =
|
||||
dyn_cast<CXXDestructorDecl>(Func)) {
|
||||
if (Destructor->isDefaulted() && !Destructor->isUsed(false))
|
||||
DefineImplicitDestructor(Loc, Destructor);
|
||||
if (Destructor->isVirtual())
|
||||
MarkVTableUsed(Loc, Destructor->getParent());
|
||||
} else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
|
||||
} else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(Func)) {
|
||||
if (MethodDecl->isDefaulted() && MethodDecl->isOverloadedOperator() &&
|
||||
MethodDecl->getOverloadedOperator() == OO_Equal) {
|
||||
if (!MethodDecl->isUsed(false)) {
|
||||
|
@ -9550,99 +9546,143 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
|
|||
} else if (MethodDecl->isVirtual())
|
||||
MarkVTableUsed(Loc, MethodDecl->getParent());
|
||||
}
|
||||
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
||||
// Recursive functions should be marked when used from another function.
|
||||
if (CurContext == Function) return;
|
||||
|
||||
// Implicit instantiation of function templates and member functions of
|
||||
// class templates.
|
||||
if (Function->isImplicitlyInstantiable()) {
|
||||
bool AlreadyInstantiated = false;
|
||||
if (FunctionTemplateSpecializationInfo *SpecInfo
|
||||
= Function->getTemplateSpecializationInfo()) {
|
||||
if (SpecInfo->getPointOfInstantiation().isInvalid())
|
||||
SpecInfo->setPointOfInstantiation(Loc);
|
||||
else if (SpecInfo->getTemplateSpecializationKind()
|
||||
== TSK_ImplicitInstantiation)
|
||||
AlreadyInstantiated = true;
|
||||
} else if (MemberSpecializationInfo *MSInfo
|
||||
= Function->getMemberSpecializationInfo()) {
|
||||
if (MSInfo->getPointOfInstantiation().isInvalid())
|
||||
MSInfo->setPointOfInstantiation(Loc);
|
||||
else if (MSInfo->getTemplateSpecializationKind()
|
||||
== TSK_ImplicitInstantiation)
|
||||
AlreadyInstantiated = true;
|
||||
}
|
||||
// Recursive functions should be marked when used from another function.
|
||||
// FIXME: Is this really right?
|
||||
if (CurContext == Func) return;
|
||||
|
||||
if (!AlreadyInstantiated) {
|
||||
if (isa<CXXRecordDecl>(Function->getDeclContext()) &&
|
||||
cast<CXXRecordDecl>(Function->getDeclContext())->isLocalClass())
|
||||
PendingLocalImplicitInstantiations.push_back(std::make_pair(Function,
|
||||
Loc));
|
||||
else if (Function->getTemplateInstantiationPattern()->isConstexpr())
|
||||
// Do not defer instantiations of constexpr functions, to avoid the
|
||||
// expression evaluator needing to call back into Sema if it sees a
|
||||
// call to such a function.
|
||||
InstantiateFunctionDefinition(Loc, Function);
|
||||
else
|
||||
PendingInstantiations.push_back(std::make_pair(Function, Loc));
|
||||
}
|
||||
} else {
|
||||
// Walk redefinitions, as some of them may be instantiable.
|
||||
for (FunctionDecl::redecl_iterator i(Function->redecls_begin()),
|
||||
e(Function->redecls_end()); i != e; ++i) {
|
||||
if (!i->isUsed(false) && i->isImplicitlyInstantiable())
|
||||
MarkDeclarationReferenced(Loc, *i);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of used but undefined functions.
|
||||
if (!Function->isPure() && !Function->hasBody() &&
|
||||
Function->getLinkage() != ExternalLinkage) {
|
||||
SourceLocation &old = UndefinedInternals[Function->getCanonicalDecl()];
|
||||
if (old.isInvalid()) old = Loc;
|
||||
}
|
||||
|
||||
Function->setUsed(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
||||
// Implicit instantiation of static data members of class templates.
|
||||
if (Var->isStaticDataMember() &&
|
||||
Var->getInstantiatedFromStaticDataMember()) {
|
||||
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
|
||||
assert(MSInfo && "Missing member specialization information?");
|
||||
if (MSInfo->getPointOfInstantiation().isInvalid() &&
|
||||
MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
|
||||
// Implicit instantiation of function templates and member functions of
|
||||
// class templates.
|
||||
if (Func->isImplicitlyInstantiable()) {
|
||||
bool AlreadyInstantiated = false;
|
||||
if (FunctionTemplateSpecializationInfo *SpecInfo
|
||||
= Func->getTemplateSpecializationInfo()) {
|
||||
if (SpecInfo->getPointOfInstantiation().isInvalid())
|
||||
SpecInfo->setPointOfInstantiation(Loc);
|
||||
else if (SpecInfo->getTemplateSpecializationKind()
|
||||
== TSK_ImplicitInstantiation)
|
||||
AlreadyInstantiated = true;
|
||||
} else if (MemberSpecializationInfo *MSInfo
|
||||
= Func->getMemberSpecializationInfo()) {
|
||||
if (MSInfo->getPointOfInstantiation().isInvalid())
|
||||
MSInfo->setPointOfInstantiation(Loc);
|
||||
// This is a modification of an existing AST node. Notify listeners.
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->StaticDataMemberInstantiated(Var);
|
||||
if (Var->isUsableInConstantExpressions())
|
||||
// Do not defer instantiations of variables which could be used in a
|
||||
// constant expression.
|
||||
InstantiateStaticDataMemberDefinition(Loc, Var);
|
||||
else
|
||||
PendingInstantiations.push_back(std::make_pair(Var, Loc));
|
||||
}
|
||||
else if (MSInfo->getTemplateSpecializationKind()
|
||||
== TSK_ImplicitInstantiation)
|
||||
AlreadyInstantiated = true;
|
||||
}
|
||||
|
||||
// Keep track of used but undefined variables. We make a hole in
|
||||
// the warning for static const data members with in-line
|
||||
// initializers.
|
||||
// FIXME: The hole we make for static const data members is too wide!
|
||||
// We need to implement the C++11 rules for odr-used.
|
||||
if (Var->hasDefinition() == VarDecl::DeclarationOnly
|
||||
&& Var->getLinkage() != ExternalLinkage
|
||||
&& !(Var->isStaticDataMember() && Var->hasInit())) {
|
||||
SourceLocation &old = UndefinedInternals[Var->getCanonicalDecl()];
|
||||
if (old.isInvalid()) old = Loc;
|
||||
if (!AlreadyInstantiated) {
|
||||
if (isa<CXXRecordDecl>(Func->getDeclContext()) &&
|
||||
cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass())
|
||||
PendingLocalImplicitInstantiations.push_back(std::make_pair(Func,
|
||||
Loc));
|
||||
else if (Func->getTemplateInstantiationPattern()->isConstexpr())
|
||||
// Do not defer instantiations of constexpr functions, to avoid the
|
||||
// expression evaluator needing to call back into Sema if it sees a
|
||||
// call to such a function.
|
||||
InstantiateFunctionDefinition(Loc, Func);
|
||||
else
|
||||
PendingInstantiations.push_back(std::make_pair(Func, Loc));
|
||||
}
|
||||
} else {
|
||||
// Walk redefinitions, as some of them may be instantiable.
|
||||
for (FunctionDecl::redecl_iterator i(Func->redecls_begin()),
|
||||
e(Func->redecls_end()); i != e; ++i) {
|
||||
if (!i->isUsed(false) && i->isImplicitlyInstantiable())
|
||||
MarkFunctionReferenced(Loc, *i);
|
||||
}
|
||||
|
||||
D->setUsed(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep track of used but undefined functions.
|
||||
if (!Func->isPure() && !Func->hasBody() &&
|
||||
Func->getLinkage() != ExternalLinkage) {
|
||||
SourceLocation &old = UndefinedInternals[Func->getCanonicalDecl()];
|
||||
if (old.isInvalid()) old = Loc;
|
||||
}
|
||||
|
||||
Func->setUsed(true);
|
||||
}
|
||||
|
||||
/// \brief Mark a variable referenced, and check whether it is odr-used
|
||||
/// (C++ [basic.def.odr]p2, C99 6.9p3). Note that this should not be
|
||||
/// used directly for normal expressions referring to VarDecl.
|
||||
void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {
|
||||
Var->setReferenced();
|
||||
|
||||
if (Var->isUsed(false))
|
||||
return;
|
||||
|
||||
if (!IsPotentiallyEvaluatedContext(*this))
|
||||
return;
|
||||
|
||||
// Implicit instantiation of static data members of class templates.
|
||||
if (Var->isStaticDataMember() &&
|
||||
Var->getInstantiatedFromStaticDataMember()) {
|
||||
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
|
||||
assert(MSInfo && "Missing member specialization information?");
|
||||
if (MSInfo->getPointOfInstantiation().isInvalid() &&
|
||||
MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
|
||||
MSInfo->setPointOfInstantiation(Loc);
|
||||
// This is a modification of an existing AST node. Notify listeners.
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->StaticDataMemberInstantiated(Var);
|
||||
if (Var->isUsableInConstantExpressions())
|
||||
// Do not defer instantiations of variables which could be used in a
|
||||
// constant expression.
|
||||
InstantiateStaticDataMemberDefinition(Loc, Var);
|
||||
else
|
||||
PendingInstantiations.push_back(std::make_pair(Var, Loc));
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of used but undefined variables. We make a hole in
|
||||
// the warning for static const data members with in-line
|
||||
// initializers.
|
||||
// FIXME: The hole we make for static const data members is too wide!
|
||||
// We need to implement the C++11 rules for odr-used.
|
||||
if (Var->hasDefinition() == VarDecl::DeclarationOnly
|
||||
&& Var->getLinkage() != ExternalLinkage
|
||||
&& !(Var->isStaticDataMember() && Var->hasInit())) {
|
||||
SourceLocation &old = UndefinedInternals[Var->getCanonicalDecl()];
|
||||
if (old.isInvalid()) old = Loc;
|
||||
}
|
||||
|
||||
Var->setUsed(true);
|
||||
}
|
||||
|
||||
static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
|
||||
Decl *D, Expr *E) {
|
||||
// TODO: Add special handling for variables
|
||||
SemaRef.MarkAnyDeclReferenced(Loc, D);
|
||||
}
|
||||
|
||||
/// \brief Perform reference-marking and odr-use handling for a
|
||||
/// BlockDeclRefExpr.
|
||||
void Sema::MarkBlockDeclRefReferenced(BlockDeclRefExpr *E) {
|
||||
MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E);
|
||||
}
|
||||
|
||||
/// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
|
||||
void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
|
||||
MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E);
|
||||
}
|
||||
|
||||
/// \brief Perform reference-marking and odr-use handling for a MemberExpr.
|
||||
void Sema::MarkMemberReferenced(MemberExpr *E) {
|
||||
MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E);
|
||||
}
|
||||
|
||||
/// \brief Perform marking for a reference to an aribitrary declaration. It
|
||||
/// marks the declaration referenced, and performs odr-use checking for functions
|
||||
/// and variables. This method should not be used when building an normal
|
||||
/// expression which refers to a variable.
|
||||
void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D) {
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(D))
|
||||
MarkVariableReferenced(Loc, VD);
|
||||
else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
|
||||
MarkFunctionReferenced(Loc, FD);
|
||||
else
|
||||
D->setReferenced();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -9666,7 +9706,7 @@ namespace {
|
|||
bool MarkReferencedDecls::TraverseTemplateArgument(
|
||||
const TemplateArgument &Arg) {
|
||||
if (Arg.getKind() == TemplateArgument::Declaration) {
|
||||
S.MarkDeclarationReferenced(Loc, Arg.getAsDecl());
|
||||
S.MarkAnyDeclReferenced(Loc, Arg.getAsDecl());
|
||||
}
|
||||
|
||||
return Inherited::TraverseTemplateArgument(Arg);
|
||||
|
@ -9699,37 +9739,37 @@ namespace {
|
|||
explicit EvaluatedExprMarker(Sema &S) : Inherited(S.Context), S(S) { }
|
||||
|
||||
void VisitDeclRefExpr(DeclRefExpr *E) {
|
||||
S.MarkDeclarationReferenced(E->getLocation(), E->getDecl());
|
||||
S.MarkDeclRefReferenced(E);
|
||||
}
|
||||
|
||||
void VisitMemberExpr(MemberExpr *E) {
|
||||
S.MarkDeclarationReferenced(E->getMemberLoc(), E->getMemberDecl());
|
||||
S.MarkMemberReferenced(E);
|
||||
Inherited::VisitMemberExpr(E);
|
||||
}
|
||||
|
||||
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
||||
S.MarkDeclarationReferenced(E->getLocStart(),
|
||||
S.MarkFunctionReferenced(E->getLocStart(),
|
||||
const_cast<CXXDestructorDecl*>(E->getTemporary()->getDestructor()));
|
||||
Visit(E->getSubExpr());
|
||||
}
|
||||
|
||||
void VisitCXXNewExpr(CXXNewExpr *E) {
|
||||
if (E->getConstructor())
|
||||
S.MarkDeclarationReferenced(E->getLocStart(), E->getConstructor());
|
||||
S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor());
|
||||
if (E->getOperatorNew())
|
||||
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorNew());
|
||||
S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew());
|
||||
if (E->getOperatorDelete())
|
||||
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete());
|
||||
S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
|
||||
Inherited::VisitCXXNewExpr(E);
|
||||
}
|
||||
|
||||
void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
||||
if (E->getOperatorDelete())
|
||||
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete());
|
||||
S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
|
||||
QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType());
|
||||
if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
|
||||
S.MarkDeclarationReferenced(E->getLocStart(),
|
||||
S.MarkFunctionReferenced(E->getLocStart(),
|
||||
S.LookupDestructor(Record));
|
||||
}
|
||||
|
||||
|
@ -9737,12 +9777,12 @@ namespace {
|
|||
}
|
||||
|
||||
void VisitCXXConstructExpr(CXXConstructExpr *E) {
|
||||
S.MarkDeclarationReferenced(E->getLocStart(), E->getConstructor());
|
||||
S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor());
|
||||
Inherited::VisitCXXConstructExpr(E);
|
||||
}
|
||||
|
||||
void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
|
||||
S.MarkDeclarationReferenced(E->getLocation(), E->getDecl());
|
||||
S.MarkBlockDeclRefReferenced(E);
|
||||
}
|
||||
|
||||
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
||||
|
|
|
@ -645,7 +645,7 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
|
|||
if (!Destructor)
|
||||
return Owned(E);
|
||||
|
||||
MarkDeclarationReferenced(E->getExprLoc(), Destructor);
|
||||
MarkFunctionReferenced(E->getExprLoc(), Destructor);
|
||||
CheckDestructorAccess(E->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_exception) << Ty);
|
||||
return Owned(E);
|
||||
|
@ -1188,16 +1188,16 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
|
|||
|
||||
// Mark the new and delete operators as referenced.
|
||||
if (OperatorNew)
|
||||
MarkDeclarationReferenced(StartLoc, OperatorNew);
|
||||
MarkFunctionReferenced(StartLoc, OperatorNew);
|
||||
if (OperatorDelete)
|
||||
MarkDeclarationReferenced(StartLoc, OperatorDelete);
|
||||
MarkFunctionReferenced(StartLoc, OperatorDelete);
|
||||
|
||||
// C++0x [expr.new]p17:
|
||||
// If the new expression creates an array of objects of class type,
|
||||
// access and ambiguity control are done for the destructor.
|
||||
if (ArraySize && Constructor) {
|
||||
if (CXXDestructorDecl *dtor = LookupDestructor(Constructor->getParent())) {
|
||||
MarkDeclarationReferenced(StartLoc, dtor);
|
||||
MarkFunctionReferenced(StartLoc, dtor);
|
||||
CheckDestructorAccess(StartLoc, dtor,
|
||||
PDiag(diag::err_access_dtor)
|
||||
<< Context.getBaseElementType(AllocType));
|
||||
|
@ -1517,7 +1517,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
|
|||
case OR_Success: {
|
||||
// Got one!
|
||||
FunctionDecl *FnDecl = Best->Function;
|
||||
MarkDeclarationReferenced(StartLoc, FnDecl);
|
||||
MarkFunctionReferenced(StartLoc, FnDecl);
|
||||
// The first argument is size_t, and the first parameter must be size_t,
|
||||
// too. This is checked on declaration and can be assumed. (It can't be
|
||||
// asserted on, though, since invalid decls are left in there.)
|
||||
|
@ -1956,7 +1956,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|||
|
||||
if (!PointeeRD->hasTrivialDestructor())
|
||||
if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
|
||||
MarkDeclarationReferenced(StartLoc,
|
||||
MarkFunctionReferenced(StartLoc,
|
||||
const_cast<CXXDestructorDecl*>(Dtor));
|
||||
DiagnoseUseOfDecl(Dtor, StartLoc);
|
||||
}
|
||||
|
@ -2005,7 +2005,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|||
return ExprError();
|
||||
}
|
||||
|
||||
MarkDeclarationReferenced(StartLoc, OperatorDelete);
|
||||
MarkFunctionReferenced(StartLoc, OperatorDelete);
|
||||
|
||||
// Check access and ambiguity of operator delete and destructor.
|
||||
if (PointeeRD) {
|
||||
|
@ -2049,7 +2049,7 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
|
|||
ConditionVar->getType().getNonReferenceType(),
|
||||
VK_LValue));
|
||||
|
||||
MarkDeclarationReferenced(ConditionVar->getLocation(), ConditionVar);
|
||||
MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));
|
||||
|
||||
if (ConvertToBoolean) {
|
||||
Condition = CheckBooleanCondition(Condition.take(), StmtLoc);
|
||||
|
@ -3609,7 +3609,7 @@ static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS
|
|||
break;
|
||||
RHS = move(RHSRes);
|
||||
if (Best->Function)
|
||||
Self.MarkDeclarationReferenced(QuestionLoc, Best->Function);
|
||||
Self.MarkFunctionReferenced(QuestionLoc, Best->Function);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4210,7 +4210,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
|
|||
|
||||
CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
|
||||
if (Destructor) {
|
||||
MarkDeclarationReferenced(E->getExprLoc(), Destructor);
|
||||
MarkFunctionReferenced(E->getExprLoc(), Destructor);
|
||||
CheckDestructorAccess(E->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_temp)
|
||||
<< E->getType());
|
||||
|
@ -4687,7 +4687,7 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
|
|||
ExprValueKind VK = Expr::getValueKindForType(ResultType);
|
||||
ResultType = ResultType.getNonLValueExprType(Context);
|
||||
|
||||
MarkDeclarationReferenced(Exp.get()->getLocStart(), Method);
|
||||
MarkFunctionReferenced(Exp.get()->getLocStart(), Method);
|
||||
CXXMemberCallExpr *CE =
|
||||
new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, VK,
|
||||
Exp.get()->getLocEnd());
|
||||
|
|
|
@ -776,7 +776,8 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
|
|||
}
|
||||
|
||||
/// \brief Build a MemberExpr AST node.
|
||||
static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
|
||||
static MemberExpr *BuildMemberExpr(Sema &SemaRef,
|
||||
ASTContext &C, Expr *Base, bool isArrow,
|
||||
const CXXScopeSpec &SS,
|
||||
SourceLocation TemplateKWLoc,
|
||||
ValueDecl *Member,
|
||||
|
@ -786,9 +787,12 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
|
|||
ExprValueKind VK, ExprObjectKind OK,
|
||||
const TemplateArgumentListInfo *TemplateArgs = 0) {
|
||||
assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue");
|
||||
return MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C),
|
||||
TemplateKWLoc, Member, FoundDecl, MemberNameInfo,
|
||||
TemplateArgs, Ty, VK, OK);
|
||||
MemberExpr *E =
|
||||
MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C),
|
||||
TemplateKWLoc, Member, FoundDecl, MemberNameInfo,
|
||||
TemplateArgs, Ty, VK, OK);
|
||||
SemaRef.MarkMemberReferenced(E);
|
||||
return E;
|
||||
}
|
||||
|
||||
ExprResult
|
||||
|
@ -908,9 +912,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
|
|||
BaseExpr, OpLoc);
|
||||
|
||||
if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
|
||||
MarkDeclarationReferenced(MemberLoc, Var);
|
||||
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
|
||||
Var, FoundDecl, MemberNameInfo,
|
||||
return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
|
||||
TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
|
||||
Var->getType().getNonReferenceType(),
|
||||
VK_LValue, OK_Ordinary));
|
||||
}
|
||||
|
@ -926,17 +929,16 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
|
|||
type = MemberFn->getType();
|
||||
}
|
||||
|
||||
MarkDeclarationReferenced(MemberLoc, MemberDecl);
|
||||
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
|
||||
MemberFn, FoundDecl, MemberNameInfo,
|
||||
type, valueKind, OK_Ordinary));
|
||||
return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
|
||||
TemplateKWLoc, MemberFn, FoundDecl,
|
||||
MemberNameInfo, type, valueKind,
|
||||
OK_Ordinary));
|
||||
}
|
||||
assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
|
||||
|
||||
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
|
||||
MarkDeclarationReferenced(MemberLoc, MemberDecl);
|
||||
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
|
||||
Enum, FoundDecl, MemberNameInfo,
|
||||
return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
|
||||
TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
|
||||
Enum->getType(), VK_RValue, OK_Ordinary));
|
||||
}
|
||||
|
||||
|
@ -1540,13 +1542,12 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
|
|||
MemberType = S.Context.getQualifiedType(MemberType, Combined);
|
||||
}
|
||||
|
||||
S.MarkDeclarationReferenced(MemberNameInfo.getLoc(), Field);
|
||||
ExprResult Base =
|
||||
S.PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
|
||||
FoundDecl, Field);
|
||||
if (Base.isInvalid())
|
||||
return ExprError();
|
||||
return S.Owned(BuildMemberExpr(S.Context, Base.take(), IsArrow, SS,
|
||||
return S.Owned(BuildMemberExpr(S, S.Context, Base.take(), IsArrow, SS,
|
||||
/*TemplateKWLoc=*/SourceLocation(),
|
||||
Field, FoundDecl, MemberNameInfo,
|
||||
MemberType, VK, OK));
|
||||
|
|
|
@ -3156,7 +3156,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
|
|||
|
||||
// This is the overload that will actually be used for the initialization, so
|
||||
// mark it as used.
|
||||
S.MarkDeclarationReferenced(DeclLoc, Function);
|
||||
S.MarkFunctionReferenced(DeclLoc, Function);
|
||||
|
||||
// Compute the returned type of the conversion.
|
||||
if (isa<CXXConversionDecl>(Function))
|
||||
|
@ -3679,7 +3679,7 @@ static void TryUserDefinedConversion(Sema &S,
|
|||
}
|
||||
|
||||
FunctionDecl *Function = Best->Function;
|
||||
S.MarkDeclarationReferenced(DeclLoc, Function);
|
||||
S.MarkFunctionReferenced(DeclLoc, Function);
|
||||
bool HadMultipleCandidates = (CandidateSet.size() > 1);
|
||||
|
||||
if (isa<CXXConstructorDecl>(Function)) {
|
||||
|
@ -4388,7 +4388,7 @@ static ExprResult CopyObject(Sema &S,
|
|||
return S.Owned(CurInitExpr);
|
||||
}
|
||||
|
||||
S.MarkDeclarationReferenced(Loc, Constructor);
|
||||
S.MarkFunctionReferenced(Loc, Constructor);
|
||||
|
||||
// Determine the arguments required to actually perform the
|
||||
// constructor call (we might have derived-to-base conversions, or
|
||||
|
@ -4531,7 +4531,7 @@ PerformConstructorInitialization(Sema &S,
|
|||
// An explicitly-constructed temporary, e.g., X(1, 2).
|
||||
unsigned NumExprs = ConstructorArgs.size();
|
||||
Expr **Exprs = (Expr **)ConstructorArgs.take();
|
||||
S.MarkDeclarationReferenced(Loc, Constructor);
|
||||
S.MarkFunctionReferenced(Loc, Constructor);
|
||||
S.DiagnoseUseOfDecl(Constructor, Loc);
|
||||
|
||||
TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
|
||||
|
@ -4899,7 +4899,7 @@ InitializationSequence::Perform(Sema &S,
|
|||
= S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
|
||||
S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor,
|
||||
S.PDiag(diag::err_access_dtor_temp) << T);
|
||||
S.MarkDeclarationReferenced(CurInit.get()->getLocStart(), Destructor);
|
||||
S.MarkFunctionReferenced(CurInit.get()->getLocStart(), Destructor);
|
||||
S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2893,7 +2893,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
// Record the standard conversion we used and the conversion function.
|
||||
if (CXXConstructorDecl *Constructor
|
||||
= dyn_cast<CXXConstructorDecl>(Best->Function)) {
|
||||
S.MarkDeclarationReferenced(From->getLocStart(), Constructor);
|
||||
S.MarkFunctionReferenced(From->getLocStart(), Constructor);
|
||||
|
||||
// C++ [over.ics.user]p1:
|
||||
// If the user-defined conversion is specified by a
|
||||
|
@ -2923,7 +2923,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
}
|
||||
if (CXXConversionDecl *Conversion
|
||||
= dyn_cast<CXXConversionDecl>(Best->Function)) {
|
||||
S.MarkDeclarationReferenced(From->getLocStart(), Conversion);
|
||||
S.MarkFunctionReferenced(From->getLocStart(), Conversion);
|
||||
|
||||
// C++ [over.ics.user]p1:
|
||||
//
|
||||
|
@ -3793,7 +3793,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
|
|||
return false;
|
||||
|
||||
if (Best->Function)
|
||||
S.MarkDeclarationReferenced(DeclLoc, Best->Function);
|
||||
S.MarkFunctionReferenced(DeclLoc, Best->Function);
|
||||
ICS.setUserDefined();
|
||||
ICS.UserDefined.Before = Best->Conversions[0].Standard;
|
||||
ICS.UserDefined.After = Best->FinalConversion;
|
||||
|
@ -8817,7 +8817,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
|
|||
Fn = Resolver.getMatchingFunctionDecl();
|
||||
assert(Fn);
|
||||
FoundResult = *Resolver.getMatchingFunctionAccessPair();
|
||||
MarkDeclarationReferenced(AddressOfExpr->getLocStart(), Fn);
|
||||
MarkFunctionReferenced(AddressOfExpr->getLocStart(), Fn);
|
||||
if (Complain)
|
||||
CheckAddressOfMemberAccess(AddressOfExpr, FoundResult);
|
||||
}
|
||||
|
@ -9380,7 +9380,7 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
|
|||
switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
|
||||
case OR_Success: {
|
||||
FunctionDecl *FDecl = Best->Function;
|
||||
MarkDeclarationReferenced(Fn->getExprLoc(), FDecl);
|
||||
MarkFunctionReferenced(Fn->getExprLoc(), FDecl);
|
||||
CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(FDecl, ULE->getNameLoc());
|
||||
Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
|
||||
|
@ -9534,7 +9534,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
|
|||
// We matched an overloaded operator. Build a call to that
|
||||
// operator.
|
||||
|
||||
MarkDeclarationReferenced(OpLoc, FnDecl);
|
||||
MarkFunctionReferenced(OpLoc, FnDecl);
|
||||
|
||||
// Convert the arguments.
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
|
||||
|
@ -9755,7 +9755,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
|||
// We matched an overloaded operator. Build a call to that
|
||||
// operator.
|
||||
|
||||
MarkDeclarationReferenced(OpLoc, FnDecl);
|
||||
MarkFunctionReferenced(OpLoc, FnDecl);
|
||||
|
||||
// Convert the arguments.
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
|
||||
|
@ -9962,7 +9962,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
|
|||
// We matched an overloaded operator. Build a call to that
|
||||
// operator.
|
||||
|
||||
MarkDeclarationReferenced(LLoc, FnDecl);
|
||||
MarkFunctionReferenced(LLoc, FnDecl);
|
||||
|
||||
CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(Best->FoundDecl, LLoc);
|
||||
|
@ -10211,7 +10211,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
|
|||
Best)) {
|
||||
case OR_Success:
|
||||
Method = cast<CXXMethodDecl>(Best->Function);
|
||||
MarkDeclarationReferenced(UnresExpr->getMemberLoc(), Method);
|
||||
MarkFunctionReferenced(UnresExpr->getMemberLoc(), Method);
|
||||
FoundDecl = Best->FoundDecl;
|
||||
CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc());
|
||||
|
@ -10476,7 +10476,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
|
|||
RParenLoc);
|
||||
}
|
||||
|
||||
MarkDeclarationReferenced(LParenLoc, Best->Function);
|
||||
MarkFunctionReferenced(LParenLoc, Best->Function);
|
||||
CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
|
||||
|
||||
|
@ -10666,7 +10666,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
|
|||
return ExprError();
|
||||
}
|
||||
|
||||
MarkDeclarationReferenced(OpLoc, Best->Function);
|
||||
MarkFunctionReferenced(OpLoc, Best->Function);
|
||||
CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
|
||||
DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
|
||||
|
||||
|
|
|
@ -3630,7 +3630,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
|
|||
|
||||
// Create the template argument.
|
||||
Converted = TemplateArgument(Entity->getCanonicalDecl());
|
||||
S.MarkDeclarationReferenced(Arg->getLocStart(), Entity);
|
||||
S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -5949,7 +5949,7 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
|
|||
|
||||
// Mark it referenced in the new context regardless.
|
||||
// FIXME: this is a bit instantiation-specific.
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocation(), ND);
|
||||
SemaRef.MarkDeclRefReferenced(E);
|
||||
|
||||
return SemaRef.Owned(E);
|
||||
}
|
||||
|
@ -6293,7 +6293,8 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
|
|||
|
||||
// Mark it referenced in the new context regardless.
|
||||
// FIXME: this is a bit instantiation-specific.
|
||||
SemaRef.MarkDeclarationReferenced(E->getMemberLoc(), Member);
|
||||
SemaRef.MarkMemberReferenced(E);
|
||||
|
||||
return SemaRef.Owned(E);
|
||||
}
|
||||
|
||||
|
@ -7117,11 +7118,11 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
|
|||
// Mark any declarations we need as referenced.
|
||||
// FIXME: instantiation-specific.
|
||||
if (Constructor)
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
|
||||
if (OperatorNew)
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorNew);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew);
|
||||
if (OperatorDelete)
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
|
||||
|
||||
if (E->isArray() && Constructor &&
|
||||
!E->getAllocatedType()->isDependentType()) {
|
||||
|
@ -7130,7 +7131,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
|
|||
if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
|
||||
if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), Destructor);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), Destructor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7202,15 +7203,15 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
|
|||
// Mark any declarations we need as referenced.
|
||||
// FIXME: instantiation-specific.
|
||||
if (OperatorDelete)
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
|
||||
|
||||
if (!E->getArgument()->isTypeDependent()) {
|
||||
QualType Destroyed = SemaRef.Context.getBaseElementType(
|
||||
E->getDestroyedType());
|
||||
if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(),
|
||||
SemaRef.LookupDestructor(Record));
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(),
|
||||
SemaRef.LookupDestructor(Record));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7540,7 +7541,7 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
|
|||
!ArgumentChanged) {
|
||||
// Mark the constructor as referenced.
|
||||
// FIXME: Instantiation-specific
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
|
||||
return SemaRef.Owned(E);
|
||||
}
|
||||
|
||||
|
@ -7601,7 +7602,7 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
|
|||
Constructor == E->getConstructor() &&
|
||||
!ArgumentChanged) {
|
||||
// FIXME: Instantiation-specific
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor);
|
||||
SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
|
||||
return SemaRef.MaybeBindToTemporary(E);
|
||||
}
|
||||
|
||||
|
@ -8253,7 +8254,7 @@ TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
|
|||
ND == E->getDecl()) {
|
||||
// Mark it referenced in the new context regardless.
|
||||
// FIXME: this is a bit instantiation-specific.
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocation(), ND);
|
||||
SemaRef.MarkBlockDeclRefReferenced(E);
|
||||
|
||||
return SemaRef.Owned(E);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue