diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/AST/Type.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 42 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 29 | 
8 files changed, 76 insertions, 23 deletions
| diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 75c58880486..f8129969b7b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -884,11 +884,13 @@ QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {  /// 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 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,      (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); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 8baf4196bf6..a62ebad3651 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -64,9 +64,8 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {    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, diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 5de44762c39..87b91ae2ea9 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -705,15 +705,18 @@ const char *BuiltinType::getName() const {  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, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 27133d683c9..6bcb90b8ae6 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1213,6 +1213,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D) {  ///         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 @@ void Parser::ParseParenDeclarator(Declarator &D) {  ///           '=' 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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,        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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,    // 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 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,    // 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); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index f6d7037ad12..7ab9d869c2d 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1116,7 +1116,7 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {    } 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. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4c36b09af80..c83c4def467 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1820,7 +1820,7 @@ ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,    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. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9b1543f7901..6fd1c5cc2fd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -402,7 +402,9 @@ Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,        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()); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index a12ec3ad7c8..7bcd1e5765f 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -409,7 +409,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {          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 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {            ArgTys.push_back(ArgTy);          }          T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(), -                                    FTI.isVariadic); +                                    FTI.isVariadic, FTI.TypeQuals);        }        break;      } @@ -491,6 +491,31 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {      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!) | 

