diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Type.cpp | 4 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 50 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 1 |
8 files changed, 86 insertions, 17 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index d8939cc123..36d501577c 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1112,7 +1112,8 @@ llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) { FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, unsigned numArgs, QualType canonical, const ExtProtoInfo &epi) - : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, canonical, + : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, + epi.RefQualifier, canonical, result->isDependentType(), result->isVariablyModifiedType(), result->containsUnexpandedParameterPack(), @@ -1162,6 +1163,7 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, ID.AddPointer(ArgTys[i].getAsOpaquePtr()); ID.AddBoolean(epi.Variadic); ID.AddInteger(epi.TypeQuals); + ID.AddInteger(epi.RefQualifier); if (epi.HasExceptionSpec) { ID.AddBoolean(epi.HasAnyExceptionSpec); for (unsigned i = 0; i != epi.NumExceptions; ++i) diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 8a740d4ad8..c0ce1f25bf 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -354,6 +354,21 @@ void TypePrinter::printFunctionProto(const FunctionProtoType *T, S += " __attribute__((regparm (" + llvm::utostr_32(Info.getRegParm()) + ")))"; + AppendTypeQualList(S, T->getTypeQuals()); + + switch (T->getRefQualifier()) { + case RQ_None: + break; + + case RQ_LValue: + S += " &"; + break; + + case RQ_RValue: + S += " &&"; + break; + } + if (T->hasExceptionSpec()) { S += " throw("; if (T->hasAnyExceptionSpec()) @@ -370,8 +385,6 @@ void TypePrinter::printFunctionProto(const FunctionProtoType *T, S += ")"; } - AppendTypeQualList(S, T->getTypeQuals()); - print(T->getResultType(), S); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d5dea78230..78d9a5b959 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3023,6 +3023,15 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, D.setInvalidType(); } + // C++0x [class.ctor]p4: + // A constructor shall not be declared with a ref-qualifier. + if (FTI.hasRefQualifier()) { + Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_constructor) + << FTI.RefQualifierIsLValueRef + << FixItHint::CreateRemoval(FTI.getRefQualifierLoc()); + D.setInvalidType(); + } + // Rebuild the function type "R" without any type qualifiers (in // case any of the errors above fired) and with "void" as the // return type, since constructors don't have return types. @@ -3032,7 +3041,8 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); EPI.TypeQuals = 0; - + EPI.RefQualifier = RQ_None; + return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(), Proto->getNumArgs(), EPI); } @@ -3173,6 +3183,15 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, D.setInvalidType(); } + // C++0x [class.dtor]p2: + // A destructor shall not be declared with a ref-qualifier. + if (FTI.hasRefQualifier()) { + Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_destructor) + << FTI.RefQualifierIsLValueRef + << FixItHint::CreateRemoval(FTI.getRefQualifierLoc()); + D.setInvalidType(); + } + // Make sure we don't have any parameters. if (FTI.NumArgs > 0 && !FTIHasSingleVoidArgument(FTI)) { Diag(D.getIdentifierLoc(), diag::err_destructor_with_params); @@ -3199,6 +3218,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); EPI.Variadic = false; EPI.TypeQuals = 0; + EPI.RefQualifier = RQ_None; return Context.getFunctionType(Context.VoidTy, 0, 0, EPI); } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 00d92bc6b5..70e9973946 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2106,6 +2106,7 @@ Sema::SubstituteExplicitTemplateArguments( ParamTypes.data(), ParamTypes.size(), Proto->isVariadic(), Proto->getTypeQuals(), + Proto->getRefQualifier(), Function->getLocation(), Function->getDeclName(), Proto->getExtInfo()); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index b663f58f03..64d5c428f3 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1269,6 +1269,7 @@ QualType Sema::BuildFunctionType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, bool Variadic, unsigned Quals, + RefQualifierKind RefQualifier, SourceLocation Loc, DeclarationName Entity, FunctionType::ExtInfo Info) { if (T->isArrayType() || T->isFunctionType()) { @@ -1294,6 +1295,7 @@ QualType Sema::BuildFunctionType(QualType T, FunctionProtoType::ExtProtoInfo EPI; EPI.Variadic = Variadic; EPI.TypeQuals = Quals; + EPI.RefQualifier = RefQualifier; EPI.ExtInfo = Info; return Context.getFunctionType(T, ParamTypes, NumParamTypes, EPI); @@ -1722,7 +1724,10 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, FunctionProtoType::ExtProtoInfo EPI; EPI.Variadic = FTI.isVariadic; EPI.TypeQuals = FTI.TypeQuals; - + EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None + : FTI.RefQualifierIsLValueRef? RQ_LValue + : RQ_RValue; + // Otherwise, we have a function with an argument list that is // potentially variadic. llvm::SmallVector<QualType, 16> ArgTys; @@ -1876,21 +1881,44 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, FreeFunction = (DC && !DC->isRecord()); } - if (FnTy->getTypeQuals() != 0 && + // C++0x [dcl.fct]p6: + // A ref-qualifier shall only be part of the function type for a + // non-static 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 || FnTy->getRefQualifier()) && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && (FreeFunction || 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) - << FreeFunction; - - // Strip the cv-quals from the type. + if (FnTy->getTypeQuals() != 0) { + if (D.isFunctionDeclarator()) + Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type); + else + Diag(D.getIdentifierLoc(), + diag::err_invalid_qualified_typedef_function_type_use) + << FreeFunction; + } + + if (FnTy->getRefQualifier()) { + if (D.isFunctionDeclarator()) { + SourceLocation Loc + = D.getTypeObject(D.getNumTypeObjects()-1).Fun.getRefQualifierLoc(); + Diag(Loc, diag::err_invalid_ref_qualifier_function_type) + << (FnTy->getRefQualifier() == RQ_LValue) + << FixItHint::CreateRemoval(Loc); + } else { + Diag(D.getIdentifierLoc(), + diag::err_invalid_ref_qualifier_typedef_function_type_use) + << FreeFunction + << (FnTy->getRefQualifier() == RQ_LValue); + } + } + + // Strip the cv-quals and ref-qualifier from the type. FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo(); EPI.TypeQuals = 0; - + EPI.RefQualifier = RQ_None; + T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), FnTy->getNumArgs(), EPI); } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 04c45b8da7..3f8d3e5ec4 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -633,6 +633,7 @@ public: QualType *ParamTypes, unsigned NumParamTypes, bool Variadic, unsigned Quals, + RefQualifierKind RefQualifier, const FunctionType::ExtInfo &Info); /// \brief Build a new unprototyped function type. @@ -3796,6 +3797,7 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, ParamTypes.size(), T->isVariadic(), T->getTypeQuals(), + T->getRefQualifier(), T->getExtInfo()); if (Result.isNull()) return QualType(); @@ -7178,7 +7180,7 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { ParamTypes.data(), ParamTypes.size(), BD->isVariadic(), - 0, + 0, RQ_None, BExprFunctionType->getExtInfo()); CurBlock->FunctionType = FunctionType; @@ -7373,9 +7375,10 @@ QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T, unsigned NumParamTypes, bool Variadic, unsigned Quals, + RefQualifierKind RefQualifier, const FunctionType::ExtInfo &Info) { return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic, - Quals, + Quals, RefQualifier, getDerived().getBaseLocation(), getDerived().getBaseEntity(), Info); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index a722df707e..b569f4b621 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2873,6 +2873,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { EPI.Variadic = Record[Idx++]; EPI.TypeQuals = Record[Idx++]; + EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]); EPI.HasExceptionSpec = Record[Idx++]; EPI.HasAnyExceptionSpec = Record[Idx++]; EPI.NumExceptions = Record[Idx++]; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 1e296e8514..e90640711f 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -176,6 +176,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { Writer.AddTypeRef(T->getArgType(I), Record); Record.push_back(T->isVariadic()); Record.push_back(T->getTypeQuals()); + Record.push_back(static_cast<unsigned>(T->getRefQualifier())); Record.push_back(T->hasExceptionSpec()); Record.push_back(T->hasAnyExceptionSpec()); Record.push_back(T->getNumExceptions()); |