diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-11 18:57:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-11 18:57:04 +0000 |
commit | e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9 (patch) | |
tree | f2c07c503173ba2db46c9bbb18fe94d09c02cb28 | |
parent | da0895d003dff3e9c57ca899fc2a3a2b397edb2e (diff) |
change the interface to ActOnMethodDeclaration to pass down argument
information in a little struct instead of individually. While we're
at it, add per-argument loc info and attribute info.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68871 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Action.h | 18 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 33 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 26 |
4 files changed, 46 insertions, 33 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index f8be3ff79a..70c21f0a34 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1405,6 +1405,18 @@ public: IdentifierInfo *propertyIvar) { // name of the ivar return DeclPtrTy(); } + + struct ObjCArgInfo { + IdentifierInfo *Name; + SourceLocation NameLoc; + // The Type is null if no type was specified, and the DeclSpec is invalid + // in this case. + TypeTy *Type; + ObjCDeclSpec DeclSpec; + + /// ArgAttrs - Attribute list for this argument. + AttributeList *ArgAttrs; + }; // ActOnMethodDeclaration - called for all method declarations. virtual DeclPtrTy ActOnMethodDeclaration( @@ -1415,11 +1427,9 @@ public: ObjCDeclSpec &ReturnQT, // for return type's in inout etc. TypeTy *ReturnType, // the method return type. Selector Sel, // a unique name for the method. - ObjCDeclSpec *ArgQT, // for arguments' in inout etc. - TypeTy **ArgTypes, // non-zero when Sel.getNumArgs() > 0 - IdentifierInfo **ArgNames, // non-zero when Sel.getNumArgs() > 0 + ObjCArgInfo *ArgInfo, // ArgInfo: Has 'Sel.getNumArgs()' entries. llvm::SmallVectorImpl<Declarator> &Cdecls, // c-style args - AttributeList *AttrList, // optional + AttributeList *MethodAttrList, // optional // tok::objc_not_keyword, tok::objc_optional, tok::objc_required tok::ObjCKeywordKind impKind, bool isVariadic = false) { diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 42ec857251..239d35f806 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -699,18 +699,15 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, - 0, 0, 0, CargNames, + 0, CargNames, MethodAttrs, MethodImplKind); } llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; - llvm::SmallVector<Action::TypeTy *, 12> KeyTypes; - llvm::SmallVector<ObjCDeclSpec, 12> ArgTypeQuals; - llvm::SmallVector<IdentifierInfo *, 12> ArgNames; + llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos; - Action::TypeTy *TypeInfo; while (1) { - KeyIdents.push_back(SelIdent); + Action::ObjCArgInfo ArgInfo; // Each iteration parses a single keyword argument. if (Tok.isNot(tok::colon)) { @@ -718,25 +715,28 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, break; } ConsumeToken(); // Eat the ':'. - ObjCDeclSpec DSType; - if (Tok.is(tok::l_paren)) // Parse the argument type. - TypeInfo = ParseObjCTypeName(DSType); - else - TypeInfo = 0; - KeyTypes.push_back(TypeInfo); - ArgTypeQuals.push_back(DSType); + ArgInfo.Type = 0; + if (Tok.is(tok::l_paren)) // Parse the argument type if present. + ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec); + // If attributes exist before the argument name, parse them. + ArgInfo.ArgAttrs = 0; if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) - ParseAttributes(); // FIXME: pass attributes through. + ArgInfo.ArgAttrs = ParseAttributes(); if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing argument name. break; } - ArgNames.push_back(Tok.getIdentifierInfo()); + + ArgInfo.Name = Tok.getIdentifierInfo(); + ArgInfo.NameLoc = Tok.getLocation(); ConsumeToken(); // Eat the identifier. + ArgInfos.push_back(ArgInfo); + KeyIdents.push_back(SelIdent); + // Check for another keyword selector. SourceLocation Loc; SelIdent = ParseObjCSelectorPiece(Loc); @@ -773,8 +773,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, &KeyIdents[0]); return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, - &ArgTypeQuals[0], &KeyTypes[0], - &ArgNames[0], CargNames, + &ArgInfos[0], CargNames, MethodAttrs, MethodImplKind, isVariadic); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 09ef84d4e2..8138379af7 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2125,7 +2125,7 @@ public: Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). - ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames, + ObjCArgInfo *ArgInfo, llvm::SmallVectorImpl<Declarator> &Cdecls, AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind, bool isVariadic = false); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index a73b440577..d12fe63df1 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1394,12 +1394,14 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). - ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames, + ObjCArgInfo *ArgInfo, llvm::SmallVectorImpl<Declarator> &Cdecls, AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind, bool isVariadic) { Decl *ClassDecl = classDecl.getAs<Decl>(); + // FIXME: Param attributes. + // Make sure we can establish a context for the method. if (!ClassDecl) { Diag(MethodLoc, diag::error_missing_method_context); @@ -1435,38 +1437,40 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( // FIXME: arg->AttrList must be stored too! QualType argType, originalArgType; - if (ArgTypes[i]) { - argType = QualType::getFromOpaquePtr(ArgTypes[i]); + if (ArgInfo[i].Type == 0) { + argType = Context.getObjCIdType(); + } else { + argType = QualType::getFromOpaquePtr(ArgInfo[i].Type); // Perform the default array/function conversions (C99 6.7.5.3p[7,8]). if (argType->isArrayType()) { // (char *[]) -> (char **) originalArgType = argType; argType = Context.getArrayDecayedType(argType); - } - else if (argType->isFunctionType()) + } else if (argType->isFunctionType()) argType = Context.getPointerType(argType); else if (argType->isObjCInterfaceType()) { - // FIXME! provide more precise location for the parameter + // FIXME: improve message to include type! Diag(MethodLoc, diag::err_object_cannot_be_by_value) << "passed"; ObjCMethod->setInvalidDecl(); return DeclPtrTy(); } - } else - argType = Context.getObjCIdType(); + } + ParmVarDecl* Param; if (originalArgType.isNull()) Param = ParmVarDecl::Create(Context, ObjCMethod, SourceLocation(/*FIXME*/), - ArgNames[i], argType, + ArgInfo[i].Name, argType, VarDecl::None, 0); else Param = OriginalParmVarDecl::Create(Context, ObjCMethod, SourceLocation(/*FIXME*/), - ArgNames[i], argType, originalArgType, + ArgInfo[i].Name, argType, + originalArgType, VarDecl::None, 0); Param->setObjCDeclQualifier( - CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier())); + CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); Params.push_back(Param); } |