[cfe-commits] r58120 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/DeclSpec.h lib/AST/ASTContext.cpp lib/AST/DeclCXX.cpp lib/AST/Type.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaType.cpp test/SemaCXX/function-type-qual.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Fri Oct 24 14:46:40 PDT 2008


Author: akirtzidis
Date: Fri Oct 24 16:46:40 2008
New Revision: 58120

URL: http://llvm.org/viewvc/llvm-project?rev=58120&view=rev
Log:
-Add support for cv-qualifiers after function declarators.
-Add withConst/withVolatile/withRestrict methods to QualType class, that return the QualType plus the respective qualifier.

Added:
    cfe/trunk/test/SemaCXX/function-type-qual.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Oct 24 16:46:40 2008
@@ -208,7 +208,8 @@
   /// getFunctionType - Return a normal function type with a typed argument
   /// list.  isVariadic indicates whether the argument list includes '...'.
   QualType getFunctionType(QualType ResultTy, const QualType *ArgArray,
-                           unsigned NumArgs, bool isVariadic);
+                           unsigned NumArgs, bool isVariadic,
+                           unsigned TypeQuals = 0);
 
   /// getTypeDeclType - Return the unique reference to the type for
   /// the specified type declaration.

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Oct 24 16:46:40 2008
@@ -230,6 +230,10 @@
   /// Should only be called for instance methods.
   QualType getThisType(ASTContext &C) const;
 
+  unsigned getTypeQualifiers() const {
+    return getType()->getAsFunctionTypeProto()->getTypeQuals();
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == CXXMethod; }
   static bool classof(const CXXMethodDecl *D) { return true; }

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Oct 24 16:46:40 2008
@@ -157,6 +157,10 @@
   QualType getWithAdditionalQualifiers(unsigned TQs) const {
     return QualType(getTypePtr(), TQs|getCVRQualifiers());
   }
+
+  QualType withConst() const { return getWithAdditionalQualifiers(Const); }
+  QualType withVolatile() const { return getWithAdditionalQualifiers(Volatile);}
+  QualType withRestrict() const { return getWithAdditionalQualifiers(Restrict);}
   
   QualType getUnqualifiedType() const;
   bool isMoreQualifiedThan(QualType Other) const;
@@ -917,13 +921,25 @@
   /// SubClassData - This field is owned by the subclass, put here to pack
   /// tightly with the ivars in Type.
   bool SubClassData : 1;
+
+  /// TypeQuals - Used only by FunctionTypeProto, put here to pack with the
+  /// other bitfields.
+  /// The qualifiers are part of FunctionTypeProto because...
+  ///
+  /// C++ 8.3.5p4: The return type, the parameter type list and the
+  /// cv-qualifier-seq, [...], are part of the function type.
+  ///
+  unsigned TypeQuals : 3;
   
   // The type returned by the function.
   QualType ResultType;
 protected:
-  FunctionType(TypeClass tc, QualType res, bool SubclassInfo,QualType Canonical)
-    : Type(tc, Canonical), SubClassData(SubclassInfo), ResultType(res) {}
+  FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
+               unsigned typeQuals, QualType Canonical)
+    : Type(tc, Canonical),
+      SubClassData(SubclassInfo), TypeQuals(typeQuals), ResultType(res) {}
   bool getSubClassData() const { return SubClassData; }
+  unsigned getTypeQuals() const { return TypeQuals; }
 public:
   
   QualType getResultType() const { return ResultType; }
@@ -940,7 +956,7 @@
 /// no information available about its arguments.
 class FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode {
   FunctionTypeNoProto(QualType Result, QualType Canonical)
-    : FunctionType(FunctionNoProto, Result, false, Canonical) {}
+    : FunctionType(FunctionNoProto, Result, false, 0, Canonical) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
   // No additional state past what FunctionType provides.
@@ -970,8 +986,8 @@
 /// arguments, not as having a single void argument.
 class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
   FunctionTypeProto(QualType Result, const QualType *ArgArray, unsigned numArgs,
-                    bool isVariadic, QualType Canonical)
-    : FunctionType(FunctionProto, Result, isVariadic, Canonical),
+                    bool isVariadic, unsigned typeQuals, QualType Canonical)
+    : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical),
       NumArgs(numArgs) {
     // Fill in the trailing argument array.
     QualType *ArgInfo = reinterpret_cast<QualType *>(this+1);;
@@ -996,6 +1012,7 @@
   }
     
   bool isVariadic() const { return getSubClassData(); }
+  unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
   
   typedef const QualType *arg_type_iterator;
   arg_type_iterator arg_type_begin() const {
@@ -1013,7 +1030,7 @@
   void Profile(llvm::FoldingSetNodeID &ID);
   static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
                       arg_type_iterator ArgTys, unsigned NumArgs,
-                      bool isVariadic);
+                      bool isVariadic, unsigned TypeQuals);
 
 protected:  
   virtual void EmitImpl(llvm::Serializer& S) const;

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Oct 24 16:46:40 2008
@@ -1041,6 +1041,11 @@
      "invalid use of 'this' outside of a nonstatic member function")
 DIAG(err_invalid_member_use_in_static_method, ERROR,
      "invalid use of member '%0' in static member function")
+DIAG(err_invalid_qualified_function_type, ERROR,
+     "type qualifier is not allowed on this function")
+DIAG(err_invalid_qualified_typedef_function_type_use, ERROR,
+     "a qualified function type cannot be used to declare a nonmember function "
+     "or a static member function")
 DIAG(err_invalid_non_static_member_use, ERROR,
      "invalid use of nonstatic data member '%0'")
 DIAG(err_invalid_incomplete_type_use, ERROR,

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Fri Oct 24 16:46:40 2008
@@ -442,6 +442,10 @@
     /// with ',...)', this is true.
     bool isVariadic : 1;
 
+    /// The type qualifiers: const/volatile/restrict.
+    /// The qualifier bitmask values are the same as in QualType. 
+    unsigned TypeQuals : 3;
+
     /// NumArgs - This is the number of formal arguments provided for the
     /// declarator.
     unsigned NumArgs;
@@ -528,12 +532,13 @@
   /// getFunction - Return a DeclaratorChunk for a function.
   static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
                                      ParamInfo *ArgInfo, unsigned NumArgs,
-                                     SourceLocation Loc) {
+                                     unsigned TypeQuals, SourceLocation Loc) {
     DeclaratorChunk I;
     I.Kind             = Function;
     I.Loc              = Loc;
     I.Fun.hasPrototype = hasProto;
     I.Fun.isVariadic   = isVariadic;
+    I.Fun.TypeQuals    = TypeQuals;
     I.Fun.NumArgs      = NumArgs;
     I.Fun.ArgInfo      = 0;
     

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Oct 24 16:46:40 2008
@@ -884,11 +884,13 @@
 /// getFunctionType - Return a normal function type with a typed argument
 /// list.  isVariadic indicates whether the argument list includes '...'.
 QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
-                                     unsigned NumArgs, bool isVariadic) {
+                                     unsigned NumArgs, bool isVariadic,
+                                     unsigned TypeQuals) {
   // Unique functions, to guarantee there is only one function of a particular
   // structure.
   llvm::FoldingSetNodeID ID;
-  FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
+  FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
+                             TypeQuals);
 
   void *InsertPos = 0;
   if (FunctionTypeProto *FTP = 
@@ -925,7 +927,7 @@
     (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) + 
                                NumArgs*sizeof(QualType));
   new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
-                              Canonical);
+                              TypeQuals, Canonical);
   Types.push_back(FTP);
   FunctionTypeProtos.InsertNode(FTP, InsertPos);
   return QualType(FTP, 0);

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Oct 24 16:46:40 2008
@@ -64,9 +64,8 @@
   assert(isInstance() && "No 'this' for static methods!");
   QualType ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(
                                             cast<CXXRecordDecl>(getParent())));
-  QualType ThisTy = C.getPointerType(ClassTy);
-  ThisTy.addConst();
-  return ThisTy;
+  ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
+  return C.getPointerType(ClassTy).withConst();
 }
 
 CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Oct 24 16:46:40 2008
@@ -705,15 +705,18 @@
 
 void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
                                 arg_type_iterator ArgTys,
-                                unsigned NumArgs, bool isVariadic) {
+                                unsigned NumArgs, bool isVariadic,
+                                unsigned TypeQuals) {
   ID.AddPointer(Result.getAsOpaquePtr());
   for (unsigned i = 0; i != NumArgs; ++i)
     ID.AddPointer(ArgTys[i].getAsOpaquePtr());
   ID.AddInteger(isVariadic);
+  ID.AddInteger(TypeQuals);
 }
 
 void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
-  Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
+  Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
+          getTypeQuals());
 }
 
 void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Oct 24 16:46:40 2008
@@ -1213,6 +1213,8 @@
 ///         direct-declarator '(' identifier-list[opt] ')'
 /// [GNU]   direct-declarator '(' parameter-forward-declarations
 ///                    parameter-type-list[opt] ')'
+/// [C++]   direct-declarator '(' parameter-declaration-clause ')'
+///                    cv-qualifier-seq[opt] exception-specification[opt]
 ///
 void Parser::ParseDirectDeclarator(Declarator &D) {
   // Parse the first direct-declarator seen.
@@ -1371,6 +1373,9 @@
 ///           '=' assignment-expression
 /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
 ///
+/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
+/// and "exception-specification[opt]"(TODO).
+///
 void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
                                      AttributeList *AttrList,
                                      bool RequiresArg) {
@@ -1383,20 +1388,29 @@
       Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
       delete AttrList;
     }
-    
+
+    ConsumeParen();  // Eat the closing ')'.
+
+    // cv-qualifier-seq[opt].
+    DeclSpec DS;
+    if (getLang().CPlusPlus) {
+      ParseTypeQualifierListOpt(DS);
+      // FIXME: Parse exception-specification[opt].
+    }
+
     // Remember that we parsed a function type, and remember the attributes.
     // int() -> no prototype, no '...'.
-    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/ false,
+    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
                                                /*variadic*/ false,
-                                               /*arglist*/ 0, 0, LParenLoc));
-    
-    ConsumeParen();  // Eat the closing ')'.
+                                               /*arglist*/ 0, 0,
+                                               DS.getTypeQualifiers(),
+                                               LParenLoc));
     return;
   } 
   
   // Alternatively, this parameter list may be an identifier list form for a
   // K&R-style function:  void foo(a,b,c)
-  if (Tok.is(tok::identifier) &&
+  if (!getLang().CPlusPlus && Tok.is(tok::identifier) &&
       // K&R identifier lists can't have typedefs as identifiers, per
       // C99 6.7.5.3p11.
       !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
@@ -1508,13 +1522,21 @@
   // Leave prototype scope.
   ExitScope();
   
+  // If we have the closing ')', eat it.
+  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  // cv-qualifier-seq[opt].
+  DeclSpec DS;
+  if (getLang().CPlusPlus) {
+    ParseTypeQualifierListOpt(DS);
+    // FIXME: Parse exception-specification[opt].
+  }
+
   // Remember that we parsed a function type, and remember the attributes.
   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
                                              &ParamInfo[0], ParamInfo.size(),
+                                             DS.getTypeQualifiers(),
                                              LParenLoc));
-  
-  // If we have the closing ')', eat it and we're done.
-  MatchRHSPunctuation(tok::r_paren, LParenLoc);
 }
 
 /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
@@ -1581,7 +1603,7 @@
   // has no prototype.
   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
                                              &ParamInfo[0], ParamInfo.size(),
-                                             LParenLoc));
+                                             /*TypeQuals*/0, LParenLoc));
   
   // If we have the closing ')', eat it and we're done.
   MatchRHSPunctuation(tok::r_paren, LParenLoc);

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri Oct 24 16:46:40 2008
@@ -1116,7 +1116,7 @@
   } else {
     // Otherwise, pretend we saw (void).
     ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
-                                                       0, 0, CaretLoc));
+                                                       0, 0, 0, CaretLoc));
   }
 
   // Inform sema that we are starting a block.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 24 16:46:40 2008
@@ -1820,7 +1820,7 @@
   Error = Error; // Silence warning.
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, Loc));
+  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, 0, Loc));
   D.SetIdentifier(&II, Loc);
   
   // Insert this function into translation-unit scope.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct 24 16:46:40 2008
@@ -402,7 +402,9 @@
       if (FD->isInvalidDecl())
         return true;
 
-      return new DeclRefExpr(FD, FD->getType(), Loc);
+      // FIXME: Handle 'mutable'.
+      return new DeclRefExpr(FD,
+        FD->getType().getWithAdditionalQualifiers(MD->getTypeQualifiers()),Loc);
     }
 
     return Diag(Loc, diag::err_invalid_non_static_member_use, FD->getName());

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=58120&r1=58119&r2=58120&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Oct 24 16:46:40 2008
@@ -409,7 +409,7 @@
         if (getLangOptions().CPlusPlus) {
           // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the
           // function takes no arguments.
-          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic);
+          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic,FTI.TypeQuals);
         } else {
           // Simple void foo(), where the incoming T is the result type.
           T = Context.getFunctionTypeNoProto(T);
@@ -482,7 +482,7 @@
           ArgTys.push_back(ArgTy);
         }
         T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
-                                    FTI.isVariadic);
+                                    FTI.isVariadic, FTI.TypeQuals);
       }
       break;
     }
@@ -491,6 +491,31 @@
     if (const AttributeList *AL = DeclType.getAttrs())
       ProcessTypeAttributeList(T, AL);
   }
+
+  if (getLangOptions().CPlusPlus && T->isFunctionType()) {
+    const FunctionTypeProto *FnTy = T->getAsFunctionTypeProto();
+    assert(FnTy && "Why oh why is there not a FunctionTypeProto here ?");
+
+    // C++ 8.3.5p4: A cv-qualifier-seq shall only be part of the function type
+    // for a nonstatic member function, the function type to which a pointer
+    // to member refers, or the top-level function type of a function typedef
+    // declaration.
+    if (FnTy->getTypeQuals() != 0 &&
+        D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
+        (D.getContext() != Declarator::MemberContext ||
+         D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
+
+      if (D.isFunctionDeclarator())
+        Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type);
+      else
+        Diag(D.getIdentifierLoc(),
+             diag::err_invalid_qualified_typedef_function_type_use);
+
+      // Strip the cv-quals from the type.
+      T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
+                                  FnTy->getNumArgs(), FnTy->isVariadic());
+    }
+  }
   
   // If there were any type attributes applied to the decl itself (not the
   // type, apply the type attribute to the type!)

Added: cfe/trunk/test/SemaCXX/function-type-qual.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-type-qual.cpp?rev=58120&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/function-type-qual.cpp (added)
+++ cfe/trunk/test/SemaCXX/function-type-qual.cpp Fri Oct 24 16:46:40 2008
@@ -0,0 +1,23 @@
+// RUN: clang -fsyntax-only -verify %s 
+
+void f() const; // expected-error {{type qualifier is not allowed on this function}}
+
+typedef void cfn() const; 
+cfn f2; // expected-error {{a qualified function type cannot be used to declare a nonmember function or a static member function}}
+
+class C {
+  void f() const;
+  cfn f2;
+  static void f3() const; // expected-error {{type qualifier is not allowed on this function}}
+  static cfn f4; // expected-error {{a qualified function type cannot be used to declare a nonmember function or a static member function}}
+
+  void m1() {
+    x = 0;
+  }
+
+  void m2() const {
+    x = 0; // expected-error {{read-only variable is not assignable}}
+  }
+
+  int x;
+};





More information about the cfe-commits mailing list