[cfe-commits] r102710 - in /cfe/trunk: include/clang/Parse/AttributeList.h lib/Parse/AttributeList.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaType.cpp
Abramo Bagnara
abramo.bagnara at gmail.com
Fri Apr 30 06:10:51 PDT 2010
Author: abramo
Date: Fri Apr 30 08:10:51 2010
New Revision: 102710
URL: http://llvm.org/viewvc/llvm-project?rev=102710&view=rev
Log:
Add calling convention related attributes to related declaration. Mark attributes invalid on type related checking so to add them to declarations only when everything is ok.
Modified:
cfe/trunk/include/clang/Parse/AttributeList.h
cfe/trunk/lib/Parse/AttributeList.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/Parse/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/AttributeList.h?rev=102710&r1=102709&r2=102710&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/AttributeList.h (original)
+++ cfe/trunk/include/clang/Parse/AttributeList.h Fri Apr 30 08:10:51 2010
@@ -41,6 +41,7 @@
unsigned NumArgs;
AttributeList *Next;
bool DeclspecAttribute, CXX0XAttribute;
+ mutable bool Invalid; /// True if already diagnosed as invalid.
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
void operator=(const AttributeList &); // DO NOT IMPLEMENT
public:
@@ -128,6 +129,9 @@
bool isDeclspecAttribute() const { return DeclspecAttribute; }
bool isCXX0XAttribute() const { return CXX0XAttribute; }
+ bool isInvalid() const { return Invalid; }
+ void setInvalid(bool b = true) const { Invalid = b; }
+
Kind getKind() const { return getKind(getName()); }
static Kind getKind(const IdentifierInfo *Name);
Modified: cfe/trunk/lib/Parse/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/AttributeList.cpp?rev=102710&r1=102709&r2=102710&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/AttributeList.cpp (original)
+++ cfe/trunk/lib/Parse/AttributeList.cpp Fri Apr 30 08:10:51 2010
@@ -23,7 +23,7 @@
AttributeList *n, bool declspec, bool cxx0x)
: AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
- DeclspecAttribute(declspec), CXX0XAttribute(cxx0x) {
+ DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
if (numArgs == 0)
Args = 0;
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=102710&r1=102709&r2=102710&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Apr 30 08:10:51 2010
@@ -467,11 +467,10 @@
}
static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
- Sema &S, bool EmitDiagnostics) {
+ Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
- if (EmitDiagnostics)
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return false;
}
@@ -479,11 +478,10 @@
ValueDecl *VD = dyn_cast<ValueDecl>(d);
if (VD == 0 || (!VD->getType()->isBlockPointerType()
&& !VD->getType()->isFunctionPointerType())) {
- if (EmitDiagnostics)
- S.Diag(Attr.getLoc(),
- Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
- : diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << 0 /*function*/;
+ S.Diag(Attr.getLoc(),
+ Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+ : diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << 0 /*function*/;
return false;
}
}
@@ -492,17 +490,14 @@
}
static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- /*
- Do check for well-formedness, but do not emit diagnostics:
- it was already emitted by Sema::ProcessFnAttr().
- */
- if (HandleCommonNoReturnAttr(d, Attr, S, /*EmitDiagnostic=*/false))
- d->addAttr(::new (S.Context) NoReturnAttr());
+ /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
+ assert(Attr.isInvalid() == false);
+ d->addAttr(::new (S.Context) NoReturnAttr());
}
static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
- if (HandleCommonNoReturnAttr(d, Attr, S, true))
+ if (HandleCommonNoReturnAttr(d, Attr, S))
d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
}
@@ -1647,6 +1642,27 @@
d->addAttr(::new (S.Context) GNUInlineAttr());
}
+static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ // Diagnostic is emitted elsewhere: here we store the (valid) Attr
+ // in the Decl node for syntactic reasoning, e.g., pretty-printing.
+ assert(Attr.isInvalid() == false);
+
+ switch (Attr.getKind()) {
+ case AttributeList::AT_fastcall:
+ d->addAttr(::new (S.Context) FastCallAttr());
+ return;
+ case AttributeList::AT_stdcall:
+ d->addAttr(::new (S.Context) StdCallAttr());
+ return;
+ case AttributeList::AT_cdecl:
+ d->addAttr(::new (S.Context) CDeclAttr());
+ return;
+ default:
+ llvm_unreachable("unexpected attribute kind");
+ return;
+ }
+}
+
static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 1) {
@@ -1847,6 +1863,9 @@
/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
static void ProcessDeclAttribute(Scope *scope, Decl *D,
const AttributeList &Attr, Sema &S) {
+ if (Attr.isInvalid())
+ return;
+
if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
// FIXME: Try to deal with other __declspec attributes!
return;
@@ -1931,7 +1950,7 @@
case AttributeList::AT_stdcall:
case AttributeList::AT_cdecl:
case AttributeList::AT_fastcall:
- // These are all treated as type attributes.
+ HandleCallConvAttr(D, Attr, S);
break;
default:
// Ask target about the attribute.
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=102710&r1=102709&r2=102710&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Apr 30 08:10:51 2010
@@ -81,9 +81,12 @@
DelayedAttributeSet &Attrs) {
for (DelayedAttributeSet::iterator I = Attrs.begin(),
E = Attrs.end(); I != E; ++I)
- if (ProcessFnAttr(S, Type, *I->first))
+ if (ProcessFnAttr(S, Type, *I->first)) {
S.Diag(I->first->getLoc(), diag::warn_function_attribute_wrong_type)
<< I->first->getName() << I->second;
+ // Avoid any further processing of this attribute.
+ I->first->setInvalid();
+ }
Attrs.clear();
}
@@ -92,6 +95,8 @@
E = Attrs.end(); I != E; ++I) {
S.Diag(I->first->getLoc(), diag::warn_function_attribute_wrong_type)
<< I->first->getName() << I->second;
+ // Avoid any further processing of this attribute.
+ I->first->setInvalid();
}
Attrs.clear();
}
@@ -1687,12 +1692,14 @@
// for two or more different address spaces."
if (Type.getAddressSpace()) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
+ Attr.setInvalid();
return;
}
// Check the attribute arguments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ Attr.setInvalid();
return;
}
Expr *ASArgExpr = static_cast<Expr *>(Attr.getArg(0));
@@ -1700,6 +1707,7 @@
if (!ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_not_int)
<< ASArgExpr->getSourceRange();
+ Attr.setInvalid();
return;
}
@@ -1708,6 +1716,7 @@
if (addrSpace.isNegative()) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_negative)
<< ASArgExpr->getSourceRange();
+ Attr.setInvalid();
return;
}
addrSpace.setIsSigned(false);
@@ -1717,6 +1726,7 @@
if (addrSpace > max) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
<< Qualifiers::MaxAddressSpace << ASArgExpr->getSourceRange();
+ Attr.setInvalid();
return;
}
@@ -1730,6 +1740,7 @@
const AttributeList &Attr, Sema &S) {
if (Type.getObjCGCAttr() != Qualifiers::GCNone) {
S.Diag(Attr.getLoc(), diag::err_attribute_multiple_objc_gc);
+ Attr.setInvalid();
return;
}
@@ -1737,11 +1748,13 @@
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
<< "objc_gc" << 1;
+ Attr.setInvalid();
return;
}
Qualifiers::GC GCAttr;
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ Attr.setInvalid();
return;
}
if (Attr.getParameterName()->isStr("weak"))
@@ -1751,6 +1764,7 @@
else {
S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
<< "objc_gc" << Attr.getParameterName();
+ Attr.setInvalid();
return;
}
@@ -1764,6 +1778,7 @@
// Complain immediately if the arg count is wrong.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ Attr.setInvalid();
return false;
}
@@ -1805,6 +1820,7 @@
// Otherwise, a calling convention.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ Attr.setInvalid();
return false;
}
@@ -1827,13 +1843,17 @@
CallingConv CCOld = Fn->getCallConv();
if (S.Context.getCanonicalCallConv(CC) ==
- S.Context.getCanonicalCallConv(CCOld)) return false;
+ S.Context.getCanonicalCallConv(CCOld)) {
+ Attr.setInvalid();
+ return false;
+ }
if (CCOld != CC_Default) {
// Should we diagnose reapplications of the same convention?
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< FunctionType::getNameForCallConv(CC)
<< FunctionType::getNameForCallConv(CCOld);
+ Attr.setInvalid();
return false;
}
@@ -1842,6 +1862,7 @@
if (isa<FunctionNoProtoType>(Fn)) {
S.Diag(Attr.getLoc(), diag::err_cconv_knr)
<< FunctionType::getNameForCallConv(CC);
+ Attr.setInvalid();
return false;
}
@@ -1849,6 +1870,7 @@
if (FnP->isVariadic()) {
S.Diag(Attr.getLoc(), diag::err_cconv_varargs)
<< FunctionType::getNameForCallConv(CC);
+ Attr.setInvalid();
return false;
}
}
@@ -1868,6 +1890,7 @@
// Check the attribute arugments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ Attr.setInvalid();
return;
}
Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
@@ -1875,12 +1898,14 @@
if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
<< "vector_size" << sizeExpr->getSourceRange();
+ Attr.setInvalid();
return;
}
// the base type must be integer or float, and can't already be a vector.
if (CurType->isVectorType() ||
(!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
+ Attr.setInvalid();
return;
}
unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
@@ -1891,11 +1916,13 @@
if (vectorSize % typeSize) {
S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
<< sizeExpr->getSourceRange();
+ Attr.setInvalid();
return;
}
if (vectorSize == 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
<< sizeExpr->getSourceRange();
+ Attr.setInvalid();
return;
}
@@ -1912,6 +1939,10 @@
// type, but others can be present in the type specifiers even though they
// apply to the decl. Here we apply type attributes and ignore the rest.
for (; AL; AL = AL->getNext()) {
+ // Skip attributes that were marked to be invalid.
+ if (AL->isInvalid())
+ continue;
+
// If this is an attribute we can handle, do so now,
// otherwise, add it to the FnAttrs list for rechaining.
switch (AL->getKind()) {
More information about the cfe-commits
mailing list