From: Steve Naroff Date: Wed, 10 Oct 2007 23:24:43 +0000 (+0000) Subject: Refinements to Sema::GetObjcIdType()... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e21b573bbfa7f53de694b81455d0627b7a3b6554;p=clang Refinements to Sema::GetObjcIdType()... - Cache the typedef, not the type (avoids importing AST/Type.h). - Emit an error if "id" cannot be found. - Comment the routine and add a FIXME to reconsider how we emulate GCC's new fangled behavior. This isn't a priority for now, since almost no code depends on having "id" built-in. - Add a test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42845 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp index f34aa6362f..9487ed01ac 100644 --- a/Sema/Sema.cpp +++ b/Sema/Sema.cpp @@ -23,17 +23,25 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { TUScope = S; } -QualType Sema::GetObjcIdType() { +/// GetObjcIdType - The following method assumes that "id" is imported +/// via . This is the way GCC worked for almost 20 years. +/// In GCC 4.0, "id" is now a built-in type. Unfortunately, typedefs *cannot* be +/// redefined (even if they are identical). To allow a built-in types to coexist +/// with , GCC has a special hack on decls (DECL_IN_SYSTEM_HEADER). +/// For now, we will *not* install id as a built-in. FIXME: reconsider this. +QualType Sema::GetObjcIdType(SourceLocation Loc) { assert(TUScope && "GetObjcIdType(): Top-level scope is null"); - if (ObjcIdType.isNull()) { + if (!ObjcIdTypedef) { IdentifierInfo *IdIdent = &Context.Idents.get("id"); ScopedDecl *IdDecl = LookupScopedDecl(IdIdent, Decl::IDNS_Ordinary, SourceLocation(), TUScope); - TypedefDecl *IdTypedef = dyn_cast_or_null(IdDecl); - assert(IdTypedef && "GetObjcIdType(): Couldn't find 'id' type"); - ObjcIdType = Context.getTypedefType(IdTypedef); + ObjcIdTypedef = dyn_cast_or_null(IdDecl); + if (!ObjcIdTypedef) { + Diag(Loc, diag::err_missing_id_definition); + return QualType(); + } } - return ObjcIdType; + return Context.getTypedefType(ObjcIdTypedef); } @@ -56,7 +64,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector &prevInGroup) KnownFunctionIDs[ id_vprintf ] = &IT.get("vprintf"); TUScope = 0; - ObjcIdType = QualType(); + ObjcIdTypedef = 0; } void Sema::DeleteExpr(ExprTy *E) { diff --git a/Sema/Sema.h b/Sema/Sema.h index 0ac513e2de..0eb803e260 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -19,7 +19,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" -#include "clang/AST/Type.h" #include #include @@ -119,8 +118,8 @@ class Sema : public Action { /// For example, user-defined classes, built-in "id" type, etc. Scope *TUScope; - /// ObjcIdType - built-in type for "id". - QualType ObjcIdType; + /// ObjcIdTypedef - built-in typedef for "id". + TypedefDecl *ObjcIdTypedef; public: Sema(Preprocessor &pp, ASTContext &ctxt, std::vector &prevInGroup); @@ -257,7 +256,7 @@ private: const ObjcMethodDecl *PrevMethod); /// GetObjcIdType - Getter for the build-in "id" type. - QualType GetObjcIdType(); + QualType GetObjcIdType(SourceLocation Loc = SourceLocation()); //===--------------------------------------------------------------------===// // Statement Parsing Callbacks: SemaStmt.cpp. diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index eb1b15839d..1d15d7b485 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1779,7 +1779,7 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(SourceLocation MethodLoc, if (ArgTypes[i]) argType = QualType::getFromOpaquePtr(ArgTypes[i]); else - argType = GetObjcIdType(); + argType = GetObjcIdType(MethodLoc); ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i], argType, VarDecl::None, 0); Params.push_back(Param); @@ -1789,7 +1789,7 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(SourceLocation MethodLoc, if (ReturnType) resultDeclType = QualType::getFromOpaquePtr(ReturnType); else // get the type for "id". - resultDeclType = GetObjcIdType(); + resultDeclType = GetObjcIdType(MethodLoc); ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, Sel, resultDeclType, 0, -1, AttrList, diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index c7f4908c0d..b5cf88f72c 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -739,7 +739,6 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; - compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index b71a6a655c..adc2425917 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -444,6 +444,8 @@ DIAG(err_previous_declaration, ERROR, "previous declaration is here") DIAG(err_undeclared_protocol, ERROR, "cannot find protocol declaration for '%0'") +DIAG(err_missing_id_definition, ERROR, + "cannot find definition of 'id'") //===----------------------------------------------------------------------===// diff --git a/test/Sema/id_not_builtin.m b/test/Sema/id_not_builtin.m new file mode 100644 index 0000000000..81988fad2e --- /dev/null +++ b/test/Sema/id_not_builtin.m @@ -0,0 +1,9 @@ +// RUN: clang %s -parse-ast -verify + +id obj; // expected-error{{expected '=', ',', ';', 'asm', or '__attribute__' after declarator}} + +@interface Foo + +- defaultToId; // expected-error{{cannot find definition of 'id'}} + +@end