From: Chris Lattner Date: Sat, 21 Jun 2008 20:20:39 +0000 (+0000) Subject: "This moves built-in Objective-C types up the scope chains to where they can be repla... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ee1f9c0142e0c374f32fc86312630cd901247cf;p=clang "This moves built-in Objective-C types up the scope chains to where they can be replaced by versions included from the runtime library's headers." This makes it ok to use @"foo" without a declaration for NSConstantString. Patch by David Chisnall! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52593 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 78cc5d85af..3296bf3550 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -45,17 +45,6 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { CurContext = Context.getTranslationUnitDecl(); if (!PP.getLangOptions().ObjC1) return; - TypedefType *t; - - // Add the built-in ObjC types. - t = cast(Context.getObjCIdType().getTypePtr()); - PushOnScopeChains(t->getDecl(), TUScope); - t = cast(Context.getObjCClassType().getTypePtr()); - PushOnScopeChains(t->getDecl(), TUScope); - ObjCInterfaceType *it = cast(Context.getObjCProtoType()); - ObjCInterfaceDecl *IDecl = it->getDecl(); - PushOnScopeChains(IDecl, TUScope); - // Synthesize "typedef struct objc_selector *SEL;" RecordDecl *SelTag = RecordDecl::Create(Context, TagDecl::TK_struct, CurContext, SourceLocation(), @@ -70,6 +59,40 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { SelT, 0); PushOnScopeChains(SelTypedef, TUScope); Context.setObjCSelType(SelTypedef); + + RecordDecl *ClassTag = RecordDecl::Create(Context, TagDecl::TK_struct, + CurContext, + SourceLocation(), + &Context.Idents.get("objc_class"), + 0); + QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag)); + TypedefDecl *ClassTypedef = + TypedefDecl::Create(Context, CurContext, SourceLocation(), + &Context.Idents.get("Class"), ClassT, 0); + PushOnScopeChains(ClassTag, TUScope); + PushOnScopeChains(ClassTypedef, TUScope); + Context.setObjCClassType(ClassTypedef); + // Synthesize "@class Protocol; + ObjCInterfaceDecl *ProtocolDecl = + ObjCInterfaceDecl::Create(Context, SourceLocation(), 0, + &Context.Idents.get("Protocol"), + SourceLocation(), true); + Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl)); + PushOnScopeChains(ProtocolDecl, TUScope); + + // Synthesize "typedef struct objc_object { Class isa; } *id;" + RecordDecl *ObjectTag = + RecordDecl::Create(Context, TagDecl::TK_struct, CurContext, + SourceLocation(), + &Context.Idents.get("objc_object"), 0); + QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag)); + PushOnScopeChains(ObjectTag, TUScope); + TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext, + SourceLocation(), + &Context.Idents.get("id"), + ObjT, 0); + PushOnScopeChains(IdTypedef, TUScope); + Context.setObjCIdType(IdTypedef); } Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) @@ -92,46 +115,6 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) KnownFunctionIDs[id_vsprintf] = &IT.get("vsprintf"); KnownFunctionIDs[id_vprintf] = &IT.get("vprintf"); - // FIXME: Move this initialization up to Sema::ActOnTranslationUnitScope() - // and make sure the decls get inserted into TUScope! - // FIXME: And make sure they don't leak! - if (PP.getLangOptions().ObjC1) { - TranslationUnitDecl *TUDecl = Context.getTranslationUnitDecl(); - - // Synthesize "typedef struct objc_class *Class;" - RecordDecl *ClassTag = RecordDecl::Create(Context, TagDecl::TK_struct, - TUDecl, - SourceLocation(), - &IT.get("objc_class"), 0); - QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag)); - TypedefDecl *ClassTypedef = - TypedefDecl::Create(Context, TUDecl, SourceLocation(), - &Context.Idents.get("Class"), ClassT, 0); - Context.setObjCClassType(ClassTypedef); - - // Synthesize "@class Protocol; - ObjCInterfaceDecl *ProtocolDecl = - ObjCInterfaceDecl::Create(Context, SourceLocation(), 0, - &Context.Idents.get("Protocol"), - SourceLocation(), true); - Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl)); - - // Synthesize "typedef struct objc_object { Class isa; } *id;" - RecordDecl *ObjectTag = - RecordDecl::Create(Context, TagDecl::TK_struct, TUDecl, - SourceLocation(), - &IT.get("objc_object"), 0); - FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), - &Context.Idents.get("isa"), - Context.getObjCClassType()); - ObjectTag->defineBody(&IsaDecl, 1); - QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag)); - TypedefDecl *IdTypedef = TypedefDecl::Create(Context, TUDecl, - SourceLocation(), - &Context.Idents.get("id"), - ObjT, 0); - Context.setObjCIdType(IdTypedef); - } TUScope = 0; } diff --git a/test/CodeGen/empty-union-init.c b/test/CodeGen/empty-union-init.c index 6b8def9a64..82ff84d0de 100644 --- a/test/CodeGen/empty-union-init.c +++ b/test/CodeGen/empty-union-init.c @@ -1,4 +1,5 @@ // RUN: clang -emit-llvm < %s -o - +// PR2419 struct Mem { union { diff --git a/test/Sema/objc-string.m b/test/Sema/objc-string.m index c73948292d..d1d797348d 100644 --- a/test/Sema/objc-string.m +++ b/test/Sema/objc-string.m @@ -1,11 +1,15 @@ // RUN: clang %s -verify -fsyntax-only +// RUN: clang %s -verify -fsyntax-only -DDECLAREIT +// a declaration of NSConstantString is not required. +#ifdef DECLAREIT @interface NSConstantString; @end +#endif -NSConstantString *s = @"123"; // simple -NSConstantString *t = @"123" @"456"; // concat -NSConstantString *u = @"123" @ blah; // expected-error: {{unexpected token}} +id s = @"123"; // simple +id t = @"123" @"456"; // concat +id u = @"123" @ blah; // expected-error: {{unexpected token}}