forked from OSchip/llvm-project
objc_gc wants a pointer type, not a function type; give it a more appropriate
diagnostic. Also, these attributes are commonly written with macros which we actually pre-define, so instead of expanding the macro location, refer to the instantiation location and name it using the macro loc. llvm-svn: 127219
This commit is contained in:
parent
d126c8cc5a
commit
ed14ad24e0
|
@ -1115,7 +1115,9 @@ def err_attribute_wrong_decl_type : Error<
|
|||
"classes and virtual methods|functions, methods, and parameters|"
|
||||
"classes|virtual methods|class members|variables|methods}1">;
|
||||
def warn_function_attribute_wrong_type : Warning<
|
||||
"%0 only applies to function types; type here is %1">;
|
||||
"'%0' only applies to function types; type here is %1">;
|
||||
def warn_pointer_attribute_wrong_type : Warning<
|
||||
"'%0' only applies to pointer types; type here is %1">;
|
||||
def warn_gnu_inline_attribute_requires_inline : Warning<
|
||||
"'gnu_inline' attribute requires function to be marked 'inline',"
|
||||
" attribute ignored">;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "clang/AST/Expr.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
@ -70,6 +71,42 @@ static bool isOmittedBlockReturnType(const Declarator &D) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// diagnoseBadTypeAttribute - Diagnoses a type attribute which
|
||||
/// doesn't apply to the given type.
|
||||
static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
|
||||
QualType type) {
|
||||
bool useInstantiationLoc = false;
|
||||
|
||||
unsigned diagID = 0;
|
||||
switch (attr.getKind()) {
|
||||
case AttributeList::AT_objc_gc:
|
||||
diagID = diag::warn_pointer_attribute_wrong_type;
|
||||
useInstantiationLoc = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Assume everything else was a function attribute.
|
||||
diagID = diag::warn_function_attribute_wrong_type;
|
||||
break;
|
||||
}
|
||||
|
||||
SourceLocation loc = attr.getLoc();
|
||||
llvm::StringRef name = attr.getName()->getName();
|
||||
|
||||
// The GC attributes are usually written with macros; special-case them.
|
||||
if (useInstantiationLoc && loc.isMacroID() && attr.getParameterName()) {
|
||||
SourceLocation instLoc = S.getSourceManager().getInstantiationLoc(loc);
|
||||
llvm::StringRef macro = S.getPreprocessor().getSpelling(instLoc);
|
||||
if ((macro == "__strong" && attr.getParameterName()->isStr("strong")) ||
|
||||
(macro == "__weak" && attr.getParameterName()->isStr("weak"))) {
|
||||
loc = instLoc;
|
||||
name = macro;
|
||||
}
|
||||
}
|
||||
|
||||
S.Diag(loc, diagID) << name << type;
|
||||
}
|
||||
|
||||
// objc_gc applies to Objective-C pointers or, otherwise, to the
|
||||
// smallest available pointer type (i.e. 'void*' in 'void**').
|
||||
#define OBJC_POINTER_TYPE_ATTRS_CASELIST \
|
||||
|
@ -162,11 +199,8 @@ namespace {
|
|||
void diagnoseIgnoredTypeAttrs(QualType type) const {
|
||||
for (llvm::SmallVectorImpl<AttributeList*>::const_iterator
|
||||
i = ignoredTypeAttrs.begin(), e = ignoredTypeAttrs.end();
|
||||
i != e; ++i) {
|
||||
AttributeList &attr = **i;
|
||||
getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type)
|
||||
<< attr.getName() << type;
|
||||
}
|
||||
i != e; ++i)
|
||||
diagnoseBadTypeAttribute(getSema(), **i, type);
|
||||
}
|
||||
|
||||
~TypeProcessingState() {
|
||||
|
@ -287,9 +321,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
|
|||
}
|
||||
}
|
||||
error:
|
||||
|
||||
state.getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type)
|
||||
<< attr.getName() << type;
|
||||
|
||||
diagnoseBadTypeAttribute(state.getSema(), attr, type);
|
||||
}
|
||||
|
||||
/// Distribute an objc_gc type attribute that was written on the
|
||||
|
@ -374,8 +407,7 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state,
|
|||
}
|
||||
}
|
||||
|
||||
state.getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type)
|
||||
<< attr.getName() << type;
|
||||
diagnoseBadTypeAttribute(state.getSema(), attr, type);
|
||||
}
|
||||
|
||||
/// Try to distribute a function type attribute to the innermost
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
|
||||
static id __attribute((objc_gc(weak))) a;
|
||||
static id __attribute((objc_gc(strong))) b;
|
||||
|
||||
|
@ -6,3 +6,7 @@ static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute req
|
|||
static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
|
||||
static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute takes one argument}}
|
||||
static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}}
|
||||
|
||||
static int __attribute__((objc_gc(weak))) g; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}}
|
||||
|
||||
static __weak int h; // expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}
|
||||
|
|
Loading…
Reference in New Issue