summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp58
1 files changed, 55 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index de568193119..692502bbbe8 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -627,6 +627,7 @@ DeclRefExpr *
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
bool TypeDependent, bool ValueDependent,
const CXXScopeSpec *SS) {
+ MarkDeclarationReferenced(Loc, D);
if (SS && !SS->isEmpty()) {
return new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent,
ValueDependent, SS->getRange(),
@@ -721,6 +722,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
// BaseObject is an anonymous struct/union variable (and is,
// therefore, not part of another non-anonymous record).
if (BaseObjectExpr) BaseObjectExpr->Destroy(Context);
+ MarkDeclarationReferenced(Loc, BaseObject);
BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(),
SourceLocation());
ExtraQuals
@@ -777,6 +779,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
= MemberType.getCVRQualifiers() | ExtraQuals;
MemberType = MemberType.getQualifiedType(combinedQualifiers);
}
+ MarkDeclarationReferenced(Loc, *FI);
Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI,
OpLoc, MemberType);
BaseObjectIsPointer = false;
@@ -876,6 +879,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// turn this into Self->ivar, just return a BareIVarExpr or something.
IdentifierInfo &II = Context.Idents.get("self");
OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false);
+ MarkDeclarationReferenced(Loc, IV);
return Owned(new (Context)
ObjCIvarRefExpr(IV, IV->getType(), Loc,
SelfExpr.takeAs<Expr>(), true, true));
@@ -1025,6 +1029,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// Build the implicit member access expression.
Expr *This = new (Context) CXXThisExpr(SourceLocation(),
MD->getThisType(Context));
+ MarkDeclarationReferenced(Loc, D);
return Owned(new (Context) MemberExpr(This, true, D,
Loc, MemberType));
}
@@ -1125,6 +1130,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// as they do not get snapshotted.
//
if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) {
+ MarkDeclarationReferenced(Loc, VD);
QualType ExprTy = VD->getType().getNonReferenceType();
// The BlocksAttr indicates the variable is bound by-reference.
if (VD->getAttr<BlocksAttr>(Context))
@@ -1579,7 +1585,7 @@ Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, Best)) {
+ switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
@@ -1689,7 +1695,7 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, Best)) {
+ switch (BestViableFunction(CandidateSet, LLoc, Best)) {
case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
@@ -5258,7 +5264,7 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
BSI->isVariadic, 0);
// FIXME: Check that return/parameter types are complete/non-abstract
-
+ DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end());
BlockTy = Context.getBlockPointerType(BlockTy);
// If needed, diagnose invalid gotos and switches in the block.
@@ -5425,3 +5431,49 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){
*Result = EvalResult.Val.getInt();
return false;
}
+
+
+/// \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?");
+
+ // Mark a parameter declaration "used", regardless of whether we're in a
+ // template or not.
+ if (isa<ParmVarDecl>(D))
+ D->setUsed(true);
+
+ // Do not mark anything as "used" within a dependent context; wait for
+ // an instantiation.
+ if (CurContext->isDependentContext())
+ return;
+
+ // If we are in an unevaluated operand, don't mark any definitions as used.
+ if (InUnevaluatedOperand)
+ return;
+
+ // Note that this declaration has been used.
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ // FIXME: implicit template instantiation
+ // FIXME: keep track of references to static functions
+ (void)Function;
+ Function->setUsed(true);
+ return;
+ }
+
+ if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ (void)Var;
+ // FIXME: implicit template instantiation
+ // FIXME: keep track of references to static data?
+ D->setUsed(true);
+ }
+}
+
OpenPOWER on IntegriCloud