summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-06-08 17:28:56 +0000
committerReid Kleckner <reid@kleckner.net>2013-06-08 17:28:56 +0000
commit4c124ffd5b05cf6a5c77a966a5e0b0df91274c1b (patch)
treedae935e3c824a870373e1e7a8b86f8d53c61bf08 /clang/lib/Sema/SemaDecl.cpp
parent7dae9ce02132c1472db3e8a0cde56412ba39324c (diff)
downloadbcm5719-llvm-4c124ffd5b05cf6a5c77a966a5e0b0df91274c1b.tar.gz
bcm5719-llvm-4c124ffd5b05cf6a5c77a966a5e0b0df91274c1b.zip
[Sema] Make FunctionType's TSI use unadjusted argument types
This helps preserve the type-as-written in the AST, which we need for MSVC mangling. In particular, we need to preserve the types of array parameters in function pointer types. The essence of this change is: - QualType ArgTy = Param->getType(); + QualType ArgTy = Param->getTypeSourceInfo()->getType(); ... followed by the adjustment in ActOnFunctionDeclarator(). Differential Revision: http://llvm-reviews.chandlerc.com/D883 llvm-svn: 183614
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp67
1 files changed, 36 insertions, 31 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e6a89461b45..1db768b28a6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5897,23 +5897,40 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
<< DeclSpec::getSpecifierName(TSCS);
// Do not allow returning a objc interface by-value.
- if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) {
+ bool NeedsAdjustment = false;
+ const FunctionType *FT = R->castAs<FunctionType>();
+ QualType ResultTy = FT->getResultType();
+ if (ResultTy->isObjCObjectType()) {
Diag(D.getIdentifierLoc(),
- diag::err_object_cannot_be_passed_returned_by_value) << 0
- << R->getAs<FunctionType>()->getResultType()
- << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*");
+ diag::err_object_cannot_be_passed_returned_by_value) << 0 << ResultTy
+ << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*");
+ ResultTy = Context.getObjCObjectPointerType(ResultTy);
+ NeedsAdjustment = true;
+ }
- QualType T = R->getAs<FunctionType>()->getResultType();
- T = Context.getObjCObjectPointerType(T);
- if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(R)) {
+ // 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;
+ }
+ }
+
+ // 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) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- R = Context.getFunctionType(T,
- ArrayRef<QualType>(FPT->arg_type_begin(),
- FPT->getNumArgs()),
- EPI);
+ R = Context.getFunctionType(ResultTy, AdjustedParms, EPI);
+ } else {
+ assert(isa<FunctionNoProtoType>(FT));
+ FunctionType::ExtInfo EI = FT->getExtInfo();
+ R = Context.getFunctionNoProtoType(ResultTy, EI);
}
- else if (isa<FunctionNoProtoType>(R))
- R = Context.getFunctionNoProtoType(T);
}
bool isFriend = false;
@@ -8498,27 +8515,15 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
SourceLocation NameLoc, IdentifierInfo *Name,
QualType T, TypeSourceInfo *TSInfo,
VarDecl::StorageClass StorageClass) {
- // In ARC, infer a lifetime qualifier for appropriate parameter types.
+ // Diagnose non-const parameter arrays of ARC types.
if (getLangOpts().ObjCAutoRefCount &&
T.getObjCLifetime() == Qualifiers::OCL_None &&
- 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(
+ T->isObjCLifetimeType() &&
+ T->isArrayType() &&
+ !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,
OpenPOWER on IntegriCloud