Make sure methods with no return type default to "id".
This fixes a crasher in Sema::MatchTwoMethodDeclarations(), identified by selector-overload.m (just added).
Added Action::ActOnTranslationUnitScope() and renamed Action::PopScope to ActOnPopScope.
Added a Translation Unit Scope instance variable to Sema (will be very useful to ObjC-related actions, since ObjC declarations are always file-scoped).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42817 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp
index 1a01270..125b0cb 100644
--- a/Sema/Sema.cpp
+++ b/Sema/Sema.cpp
@@ -19,6 +19,10 @@
using namespace clang;
+void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+ TUScope = S;
+}
+
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
: PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {
diff --git a/Sema/Sema.h b/Sema/Sema.h
index e2ec394..6c2b41e 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -113,6 +113,9 @@
/// This list is populated upon the creation of a Sema object.
IdentifierInfo* KnownFunctionIDs[ id_num_known_functions ];
+ /// Translation Unit Scope - useful to many Objective-C actions that need
+ /// to lookup file scope declarations (like classes, protocols, etc.).
+ Scope *TUScope;
public:
Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup);
@@ -161,7 +164,10 @@
virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
virtual DeclTy *ActOnFunctionDefBody(DeclTy *Decl, StmtTy *Body);
- virtual void PopScope(SourceLocation Loc, Scope *S);
+
+ /// Scope actions.
+ virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
+ virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index d85ee6b..ba6c7d0 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -34,7 +34,7 @@
return 0;
}
-void Sema::PopScope(SourceLocation Loc, Scope *S) {
+void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
if (S->decl_empty()) return;
assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
@@ -1782,7 +1782,18 @@
VarDecl::None, 0);
Params.push_back(Param);
}
- QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+ QualType resultDeclType;
+
+ if (ReturnType)
+ resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+ else { // get the type for "id".
+ IdentifierInfo *IdIdent = &Context.Idents.get("id");
+ ScopedDecl *IdDecl = LookupScopedDecl(IdIdent, Decl::IDNS_Ordinary,
+ SourceLocation(), TUScope);
+ TypedefDecl *IdTypedef = dyn_cast_or_null<TypedefDecl>(IdDecl);
+ assert(IdTypedef && "ActOnMethodDeclaration(): Couldn't find 'id' type");
+ resultDeclType = IdTypedef->getUnderlyingType();
+ }
ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, Sel,
resultDeclType, 0, -1, AttrList,
MethodType == tok::minus,