[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