diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-12 07:48:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-12 07:48:19 +0000 |
commit | cb27b0f70d2017295776afafe3616e0bcd74ab51 (patch) | |
tree | cb5d84e5272f84f5fba89d178bbdc36bf4d88a42 /lib/Sema/SemaDecl.cpp | |
parent | 1e46136c5222ad040fd783ca7ee6b2215f0b89d6 (diff) |
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101029 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 81 |
1 files changed, 43 insertions, 38 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7475ae4fbe..8e0e369af8 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4118,55 +4118,23 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { } } - // Parameters can not be abstract class types. - // For record types, this is done by the AbstractClassUsageDiagnoser once - // the class has been completely parsed. - if (!CurContext->isRecord() && - RequireNonAbstractType(D.getIdentifierLoc(), parmDeclType, - diag::err_abstract_type_in_decl, - AbstractParamType)) - D.setInvalidType(true); - - QualType T = adjustParameterType(parmDeclType); - // Temporarily put parameter variables in the translation unit, not // the enclosing context. This prevents them from accidentally // looking like class members in C++. - DeclContext *DC = Context.getTranslationUnitDecl(); - - ParmVarDecl *New - = ParmVarDecl::Create(Context, DC, D.getIdentifierLoc(), II, - T, TInfo, StorageClass, 0); + ParmVarDecl *New = CheckParameter(Context.getTranslationUnitDecl(), + TInfo, parmDeclType, II, + D.getIdentifierLoc(), StorageClass); if (D.isInvalidType()) - New->setInvalidDecl(); - - // Parameter declarators cannot be interface types. All ObjC objects are - // passed by reference. - if (T->isObjCInterfaceType()) { - Diag(D.getIdentifierLoc(), - diag::err_object_cannot_be_passed_returned_by_value) << 1 << T; - New->setInvalidDecl(); - } - + New->setInvalidDecl(); + // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1). if (D.getCXXScopeSpec().isSet()) { Diag(D.getIdentifierLoc(), diag::err_qualified_param_declarator) << D.getCXXScopeSpec().getRange(); New->setInvalidDecl(); } - - // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage - // duration shall not be qualified by an address-space qualifier." - // Since all parameters have automatic store duration, they can not have - // an address space. - if (T.getAddressSpace() != 0) { - Diag(D.getIdentifierLoc(), - diag::err_arg_with_address_space); - New->setInvalidDecl(); - } - - + // Add the parameter declaration into this scope. S->AddDecl(DeclPtrTy::make(New)); if (II) @@ -4180,6 +4148,43 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { return DeclPtrTy::make(New); } +ParmVarDecl *Sema::CheckParameter(DeclContext *DC, + TypeSourceInfo *TSInfo, QualType T, + IdentifierInfo *Name, + SourceLocation NameLoc, + VarDecl::StorageClass StorageClass) { + ParmVarDecl *New = ParmVarDecl::Create(Context, DC, NameLoc, Name, + adjustParameterType(T), TSInfo, + StorageClass, 0); + + // Parameters can not be abstract class types. + // For record types, this is done by the AbstractClassUsageDiagnoser once + // the class has been completely parsed. + if (!CurContext->isRecord() && + RequireNonAbstractType(NameLoc, T, diag::err_abstract_type_in_decl, + AbstractParamType)) + New->setInvalidDecl(); + + // Parameter declarators cannot be interface types. All ObjC objects are + // passed by reference. + if (T->isObjCInterfaceType()) { + Diag(NameLoc, + diag::err_object_cannot_be_passed_returned_by_value) << 1 << T; + New->setInvalidDecl(); + } + + // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage + // duration shall not be qualified by an address-space qualifier." + // Since all parameters have automatic store duration, they can not have + // an address space. + if (T.getAddressSpace() != 0) { + Diag(NameLoc, diag::err_arg_with_address_space); + New->setInvalidDecl(); + } + + return New; +} + void Sema::ActOnObjCCatchParam(DeclPtrTy D) { ParmVarDecl *Param = cast<ParmVarDecl>(D.getAs<Decl>()); Param->setDeclContext(CurContext); |