summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2013-09-11 01:37:41 +0000
committerAaron Ballman <aaron@aaronballman.com>2013-09-11 01:37:41 +0000
commitc12aaff2cbe5c24ce9bb1a4fc6f52f4c84eb1716 (patch)
treeee30942e931134bf1b05dd23e20bd30a8bf4356a /clang/lib
parentcffd45b2e15c5a549f254fd038911e52eee7ef33 (diff)
downloadbcm5719-llvm-c12aaff2cbe5c24ce9bb1a4fc6f52f4c84eb1716.tar.gz
bcm5719-llvm-c12aaff2cbe5c24ce9bb1a4fc6f52f4c84eb1716.zip
The cleanup attribute no longer uses an unresolved, simple identifier as its argument. Instead, it takes an expression that is fully resolved.
llvm-svn: 190476
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp58
1 files changed, 30 insertions, 28 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 78640d62df4..47b130888f9 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2831,40 +2831,44 @@ static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
}
static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- if (!Attr.isArgIdent(0)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
- << Attr.getName() << 1;
- return;
- }
-
VarDecl *VD = dyn_cast<VarDecl>(D);
-
if (!VD || !VD->hasLocalStorage()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
return;
}
- IdentifierLoc *IL = Attr.getArgAsIdent(0);
-
- // Look up the function
- // FIXME: Lookup probably isn't looking in the right place
- NamedDecl *CleanupDecl
- = S.LookupSingleName(S.TUScope, IL->Ident, IL->Loc,
- Sema::LookupOrdinaryName);
- if (!CleanupDecl) {
- S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_found) << IL->Ident;
- return;
- }
+ Expr *E = Attr.getArgAsExpr(0);
+ SourceLocation Loc = E->getExprLoc();
+ FunctionDecl *FD = 0;
+ DeclarationNameInfo NI;
+
+ // gcc only allows for simple identifiers. Since we support more than gcc, we
+ // will warn the user.
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (DRE->hasQualifier())
+ S.Diag(Loc, diag::warn_cleanup_ext);
+ FD = dyn_cast<FunctionDecl>(DRE->getDecl());
+ NI = DRE->getNameInfo();
+ if (!FD) {
+ S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
+ << NI.getName();
+ return;
+ }
+ } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
+ if (ULE->hasExplicitTemplateArgs())
+ S.Diag(Loc, diag::warn_cleanup_ext);
- FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
- if (!FD) {
- S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_function) << IL->Ident;
+ // This will diagnose the case where the function cannot be found.
+ FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
+ NI = ULE->getNameInfo();
+ } else {
+ S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
return;
}
if (FD->getNumParams() != 1) {
- S.Diag(IL->Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
- << IL->Ident;
+ S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
+ << NI.getName();
return;
}
@@ -2874,16 +2878,14 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
QualType ParamTy = FD->getParamDecl(0)->getType();
if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
ParamTy, Ty) != Sema::Compatible) {
- S.Diag(IL->Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) <<
- IL->Ident << ParamTy << Ty;
+ S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
+ << NI.getName() << ParamTy << Ty;
return;
}
D->addAttr(::new (S.Context)
CleanupAttr(Attr.getRange(), S.Context, FD,
Attr.getAttributeSpellingListIndex()));
- S.MarkFunctionReferenced(IL->Loc, FD);
- S.DiagnoseUseOfDecl(FD, IL->Loc);
}
/// Handle __attribute__((format_arg((idx)))) attribute based on
OpenPOWER on IntegriCloud