diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 15 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 67 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 10 |
4 files changed, 39 insertions, 59 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 384164167db..44ff94e3584 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4142,21 +4142,6 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { } QualType ASTContext::getAdjustedParameterType(QualType T) const { - // In ARC, infer a lifetime qualifier for appropriate parameter types. - if (getLangOpts().ObjCAutoRefCount && - T.getObjCLifetime() == Qualifiers::OCL_None && - T->isObjCLifetimeType()) { - // Special cases for arrays: - // - if it's const, use __unsafe_unretained - // - otherwise, it's an error - Qualifiers::ObjCLifetime lifetime; - if (T->isArrayType()) - lifetime = Qualifiers::OCL_ExplicitNone; - else - lifetime = T->getObjCARCImplicitLifetime(); - T = getLifetimeQualifiedType(T, lifetime); - } - // C99 6.7.5.3p7: // A declaration of a parameter as "array of type" shall be // adjusted to "qualified pointer to type", where the type diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 2c5233bce67..c32df11b667 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1781,10 +1781,8 @@ bool TypeOfExprType::isSugared() const { } QualType TypeOfExprType::desugar() const { - if (isSugared()) { - Expr *E = getUnderlyingExpr(); - return E->getType(); - } + if (isSugared()) + return getUnderlyingExpr()->getType(); return QualType(this, 0); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1db768b28a6..e6a89461b45 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5897,40 +5897,23 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << DeclSpec::getSpecifierName(TSCS); // Do not allow returning a objc interface by-value. - bool NeedsAdjustment = false; - const FunctionType *FT = R->castAs<FunctionType>(); - QualType ResultTy = FT->getResultType(); - if (ResultTy->isObjCObjectType()) { + if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) { Diag(D.getIdentifierLoc(), - diag::err_object_cannot_be_passed_returned_by_value) << 0 << ResultTy - << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*"); - ResultTy = Context.getObjCObjectPointerType(ResultTy); - NeedsAdjustment = true; - } - - // Adjust parameter types from the type as written. - SmallVector<QualType, 16> AdjustedParms; - const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT); - if (FPT) { - for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), - E = FPT->arg_type_end(); I != E; ++I) { - AdjustedParms.push_back(Context.getAdjustedParameterType(*I)); - if (AdjustedParms.back() != *I) - NeedsAdjustment = true; - } - } + diag::err_object_cannot_be_passed_returned_by_value) << 0 + << R->getAs<FunctionType>()->getResultType() + << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*"); - // Skip the type recreation if it isn't needed, for performance and to avoid - // prematurely desugaring things like typedefs and __typeofs. - if (NeedsAdjustment) { - if (FPT) { + QualType T = R->getAs<FunctionType>()->getResultType(); + T = Context.getObjCObjectPointerType(T); + if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(R)) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - R = Context.getFunctionType(ResultTy, AdjustedParms, EPI); - } else { - assert(isa<FunctionNoProtoType>(FT)); - FunctionType::ExtInfo EI = FT->getExtInfo(); - R = Context.getFunctionNoProtoType(ResultTy, EI); + R = Context.getFunctionType(T, + ArrayRef<QualType>(FPT->arg_type_begin(), + FPT->getNumArgs()), + EPI); } + else if (isa<FunctionNoProtoType>(R)) + R = Context.getFunctionNoProtoType(T); } bool isFriend = false; @@ -8515,15 +8498,27 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, VarDecl::StorageClass StorageClass) { - // Diagnose non-const parameter arrays of ARC types. + // In ARC, infer a lifetime qualifier for appropriate parameter types. if (getLangOpts().ObjCAutoRefCount && T.getObjCLifetime() == Qualifiers::OCL_None && - T->isObjCLifetimeType() && - T->isArrayType() && - !T.isConstQualified()) { - DelayedDiagnostics.add( - sema::DelayedDiagnostic::makeForbiddenType( + T->isObjCLifetimeType()) { + + Qualifiers::ObjCLifetime lifetime; + + // Special cases for arrays: + // - if it's const, use __unsafe_unretained + // - otherwise, it's an error + if (T->isArrayType()) { + if (!T.isConstQualified()) { + DelayedDiagnostics.add( + sema::DelayedDiagnostic::makeForbiddenType( NameLoc, diag::err_arc_array_param_no_ownership, T, false)); + } + lifetime = Qualifiers::OCL_ExplicitNone; + } else { + lifetime = T->getObjCARCImplicitLifetime(); + } + T = Context.getLifetimeQualifiedType(T, lifetime); } ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 977294bd461..e27d627d3ff 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1674,7 +1674,7 @@ QualType Sema::BuildFunctionType(QualType T, bool Invalid = false; for (unsigned Idx = 0, Cnt = ParamTypes.size(); Idx < Cnt; ++Idx) { // FIXME: Loc is too inprecise here, should use proper locations for args. - QualType ParamType = ParamTypes[Idx]; + QualType ParamType = Context.getAdjustedParameterType(ParamTypes[Idx]); if (ParamType->isVoidType()) { Diag(Loc, diag::err_param_with_void_type); Invalid = true; @@ -2798,11 +2798,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) { ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param); - // Get the type as written. It will be adjusted later in - // ActOnFunctionDeclarator(). - QualType ArgTy = Param->getTypeSourceInfo()->getType(); + QualType ArgTy = Param->getType(); assert(!ArgTy.isNull() && "Couldn't parse type?"); + // Adjust the parameter type. + assert((ArgTy == Context.getAdjustedParameterType(ArgTy)) && + "Unadjusted type?"); + // Look for 'void'. void is allowed only as a single argument to a // function with no other parameters (C99 6.7.5.3p10). We record // int(void) as a FunctionProtoType with an empty argument list. |