aboutsummaryrefslogtreecommitdiff
path: root/Parse/ParseObjc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Parse/ParseObjc.cpp')
-rw-r--r--Parse/ParseObjc.cpp130
1 files changed, 90 insertions, 40 deletions
diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp
index eddbb4a254..16434cdcdd 100644
--- a/Parse/ParseObjc.cpp
+++ b/Parse/ParseObjc.cpp
@@ -463,6 +463,52 @@ Parser::TypeTy *Parser::ParseObjCTypeName() {
return Ty;
}
+static SelectorInfo *ObjcGetUnarySelectorInfo(
+ IdentifierInfo *unarySel,
+ llvm::FoldingSet<SelectorInfo> &SelTab)
+{
+ // Unique selector, to guarantee there is one per name.
+ llvm::SmallVector<IdentifierInfo *, 1> IIV;
+ llvm::FoldingSetNodeID ID;
+
+ IIV.push_back(unarySel);
+ SelectorInfo::Profile(ID, &IIV[0], 0);
+
+ void *InsertPos = 0;
+ if (SelectorInfo *SI = SelTab.FindNodeOrInsertPos(ID, InsertPos))
+ return SI;
+
+ // SelectorInfo objects are not allocated with new because they have a
+ // variable size array (for parameter types) at the end of them.
+ SelectorInfo *SI =
+ (SelectorInfo*)malloc(sizeof(SelectorInfo) + sizeof(IdentifierInfo *));
+ new (SI) SelectorInfo(IIV[0]);
+ SelTab.InsertNode(SI, InsertPos);
+ return SI;
+}
+
+static SelectorInfo *ObjcGetKeywordSelectorInfo(
+ llvm::SmallVectorImpl<IdentifierInfo *> &IIV,
+ llvm::FoldingSet<SelectorInfo> &SelTab)
+{
+ // Unique selector, to guarantee there is one per name.
+ llvm::FoldingSetNodeID ID;
+ SelectorInfo::Profile(ID, &IIV[0], IIV.size());
+
+ void *InsertPos = 0;
+ if (SelectorInfo *SI = SelTab.FindNodeOrInsertPos(ID, InsertPos))
+ return SI;
+
+ // SelectorInfo objects are not allocated with new because they have a
+ // variable size array (for parameter types) at the end of them.
+ SelectorInfo *SI =
+ (SelectorInfo*)malloc(sizeof(SelectorInfo) +
+ IIV.size()*sizeof(IdentifierInfo *));
+ new (SI) SelectorInfo(IIV.size(), &IIV[0]);
+ SelTab.InsertNode(SI, InsertPos);
+ return SI;
+}
+
/// objc-method-decl:
/// objc-selector
/// objc-keyword-selector objc-parmlist[opt]
@@ -491,9 +537,10 @@ Parser::TypeTy *Parser::ParseObjCTypeName() {
/// objc-keyword-attributes: [OBJC2]
/// __attribute__((unused))
///
-Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc,
- tok::ObjCKeywordKind MethodImplKind) {
-
+Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType,
+ SourceLocation mLoc,
+ tok::ObjCKeywordKind MethodImplKind)
+{
TypeTy *ReturnType = 0;
AttributeList *methodAttrs = 0;
@@ -502,38 +549,39 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation
ReturnType = ParseObjCTypeName();
IdentifierInfo *selIdent = ParseObjCSelector();
- llvm::SmallVector<ObjcKeywordDecl, 12> KeyInfo;
-
+ llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+ llvm::SmallVector<Action::TypeTy *, 12> KeyTypes;
+ llvm::SmallVector<IdentifierInfo *, 12> ArgNames;
+
if (Tok.getKind() == tok::colon) {
+ Action::TypeTy *TypeInfo;
while (1) {
- ObjcKeywordDecl KeyInfoDecl;
- KeyInfoDecl.SelectorName = selIdent;
+ KeyIdents.push_back(selIdent);
// Each iteration parses a single keyword argument.
if (Tok.getKind() != tok::colon) {
Diag(Tok, diag::err_expected_colon);
break;
}
- KeyInfoDecl.ColonLoc = ConsumeToken(); // Eat the ':'.
+ ConsumeToken(); // Eat the ':'.
if (Tok.getKind() == tok::l_paren) // Parse the argument type.
- KeyInfoDecl.TypeInfo = ParseObjCTypeName();
-
+ TypeInfo = ParseObjCTypeName();
+ else
+ TypeInfo = 0;
+ KeyTypes.push_back(TypeInfo);
+
// If attributes exist before the argument name, parse them.
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
- KeyInfoDecl.AttrList = ParseAttributes();
+ ParseAttributes(); // FIXME: pass attributes through.
if (Tok.getKind() != tok::identifier) {
Diag(Tok, diag::err_expected_ident); // missing argument name.
break;
}
- KeyInfoDecl.ArgumentName = Tok.getIdentifierInfo();
+ ArgNames.push_back(Tok.getIdentifierInfo());
ConsumeToken(); // Eat the identifier.
- // Rather than call out to the actions, package up the info locally,
- // like we do for Declarator.
- KeyInfo.push_back(KeyInfoDecl);
-
// Check for another keyword selector.
selIdent = ParseObjCSelector();
if (!selIdent && Tok.getKind() != tok::colon)
@@ -558,9 +606,11 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation
// If attributes exist after the method, parse them.
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
methodAttrs = ParseAttributes();
- return Actions.ObjcBuildMethodDeclaration(mLoc, mType,
- ReturnType,
- &KeyInfo[0], KeyInfo.size(),
+
+ SelectorInfo *SI = ObjcGetKeywordSelectorInfo(KeyIdents,
+ PP.getSelectorTable());
+ return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, SI,
+ &KeyTypes[0], &ArgNames[0],
methodAttrs, MethodImplKind);
} else if (!selIdent) {
Diag(Tok, diag::err_expected_ident); // missing selector name.
@@ -569,9 +619,9 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
methodAttrs = ParseAttributes();
- return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType,
- selIdent, methodAttrs,
- MethodImplKind);
+ SelectorInfo *SI = ObjcGetUnarySelectorInfo(selIdent, PP.getSelectorTable());
+ return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, SI,
+ 0, 0, methodAttrs, MethodImplKind);
}
/// objc-protocol-refs:
@@ -1107,19 +1157,21 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
}
// Parse objc-selector
IdentifierInfo *selIdent = ParseObjCSelector();
- llvm::SmallVector<ObjcKeywordMessage, 12> KeyInfo;
+
+ llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+ llvm::SmallVector<Action::ExprTy *, 12> KeyExprs;
+
if (Tok.getKind() == tok::colon) {
while (1) {
// Each iteration parses a single keyword argument.
- ObjcKeywordMessage KeyInfoMess;
- KeyInfoMess.SelectorName = selIdent;
+ KeyIdents.push_back(selIdent);
if (Tok.getKind() != tok::colon) {
Diag(Tok, diag::err_expected_colon);
SkipUntil(tok::semi);
return true;
}
- KeyInfoMess.ColonLoc = ConsumeToken(); // Eat the ':'.
+ ConsumeToken(); // Eat the ':'.
/// Parse the expression after ':'
ExprResult Res = ParseAssignmentExpression();
if (Res.isInvalid) {
@@ -1127,11 +1179,7 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
return Res;
}
// We have a valid expression.
- KeyInfoMess.KeywordExpr = Res.Val;
-
- // Rather than call out to the actions, package up the info locally,
- // like we do for Declarator.
- KeyInfo.push_back(KeyInfoMess);
+ KeyExprs.push_back(Res.Val);
// Check for another keyword selector.
selIdent = ParseObjCSelector();
@@ -1157,20 +1205,22 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
}
SourceLocation RBracloc = ConsumeBracket(); // consume ']'
- if (KeyInfo.size()) {
+ if (KeyIdents.size()) {
+ SelectorInfo *SI = ObjcGetKeywordSelectorInfo(KeyIdents,
+ PP.getSelectorTable());
// We've just parsed a keyword message.
if (ReceiverName)
- return Actions.ActOnKeywordMessage(ReceiverName,
- &KeyInfo[0], KeyInfo.size(),
- LBracloc, RBracloc);
- return Actions.ActOnKeywordMessage(ReceiverExpr,
- &KeyInfo[0], KeyInfo.size(),
- LBracloc, RBracloc);
+ return Actions.ActOnClassMessage(ReceiverName, SI, LBracloc, RBracloc,
+ &KeyExprs[0]);
+ return Actions.ActOnInstanceMessage(ReceiverExpr, SI, LBracloc, RBracloc,
+ &KeyExprs[0]);
}
+ SelectorInfo *SI = ObjcGetUnarySelectorInfo(selIdent, PP.getSelectorTable());
+
// We've just parsed a unary message (a message with no arguments).
if (ReceiverName)
- return Actions.ActOnUnaryMessage(ReceiverName, selIdent, LBracloc,RBracloc);
- return Actions.ActOnUnaryMessage(ReceiverExpr, selIdent, LBracloc,RBracloc);
+ return Actions.ActOnClassMessage(ReceiverName, SI, LBracloc, RBracloc, 0);
+ return Actions.ActOnInstanceMessage(ReceiverExpr, SI, LBracloc, RBracloc, 0);
}
Parser::ExprResult Parser::ParseObjCStringLiteral() {