]> granicus.if.org Git - clang/commitdiff
Make longjmp a real builtin.
authorMike Stump <mrs@apple.com>
Tue, 28 Jul 2009 02:25:19 +0000 (02:25 +0000)
committerMike Stump <mrs@apple.com>
Tue, 28 Jul 2009 02:25:19 +0000 (02:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77291 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/Basic/Builtins.def
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Frontend/PCHBitCodes.h
lib/AST/ASTContext.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
lib/Sema/SemaDecl.cpp

index 7768ba49d558a95ec52ce9c878fa7e6a44effef3..c7faefc17fe6d53c0e47ce0a183136dab5a6b23a 100644 (file)
@@ -130,6 +130,12 @@ class ASTContext {
   /// \brief The type for the C FILE type.
   TypeDecl *FILEDecl;
   
+  /// \brief The type for the C FILE type.
+  TypeDecl *jmp_bufDecl;
+  
+  /// \brief The type for the C FILE type.
+  TypeDecl *sigjmp_bufDecl;
+  
   /// \brief Keeps track of all declaration attributes. 
   ///
   /// Since so few decls have attrs, we keep them in a hash map instead of
@@ -499,6 +505,28 @@ public:
       return getTypeDeclType(FILEDecl);
     return QualType();
   }
+
+  /// \brief Set the type for the C jmp_buf type.
+  void setjmp_bufDecl(TypeDecl *jmp_bufDecl)
+    { this->jmp_bufDecl = jmp_bufDecl; }
+  
+  /// \brief Retrieve the C jmp_buf type.
+  QualType getjmp_bufType() { 
+    if (jmp_bufDecl) 
+      return getTypeDeclType(jmp_bufDecl);
+    return QualType();
+  }
+
+  /// \brief Set the type for the C sigjmp_buf type.
+  void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl)
+    { this->sigjmp_bufDecl = sigjmp_bufDecl; }
+  
+  /// \brief Retrieve the C sigjmp_buf type.
+  QualType getsigjmp_bufType() { 
+    if (sigjmp_bufDecl) 
+      return getTypeDeclType(sigjmp_bufDecl);
+    return QualType();
+  }
                        
   /// getObjCEncodingForType - Emit the ObjC type encoding for the
   /// given type into \arg S. If \arg NameFields is specified then
@@ -558,8 +586,10 @@ public:
                                         const IdentifierInfo *Name);
 
   enum GetBuiltinTypeError {
-    GE_None,        //< No error
-    GE_Missing_FILE //< Missing the FILE type from <stdio.h>
+    GE_None,              //< No error
+    GE_Missing_FILE,      //< Missing the FILE type from <stdio.h>
+    GE_Missing_jmp_buf,   //< Missing the jmp_buf type from <setjmp.h>
+    GE_Missing_sigjmp_buf //< Missing the sigjmp_buf type from <setjmp.h>
   };
   
   /// GetBuiltinType - Return the type for the specified builtin.
index b2d31f221512cdaa7b2f34191bdafe04b902429c..0ac2fab8a03a056dc8848779e4cc0bd212b2a7e2 100644 (file)
@@ -36,6 +36,8 @@
 //  A -> "reference" to __builtin_va_list
 //  V -> Vector, following num elements and a base type.
 //  P -> FILE
+//  J -> jmp_buf
+//  SJ -> sigjmp_buf
 //  . -> "...".  This may only occur at the end of the function list.
 //
 // Types maybe prefixed with the following modifiers:
@@ -338,7 +340,6 @@ BUILTIN(__sync_fetch_and_umax, "UiUi*Ui", "n")
 LIBBUILTIN(calloc, "v*zz",        "f",     "stdlib.h")
 LIBBUILTIN(exit, "vi",            "fr",    "stdlib.h")
 LIBBUILTIN(_Exit, "vi",           "fr",    "stdlib.h")
-LIBBUILTIN(_exit, "vi",           "fr",    "unistd.h")
 LIBBUILTIN(malloc, "v*z",         "f",     "stdlib.h")
 LIBBUILTIN(realloc, "v*v*z",      "f",     "stdlib.h")
 // C99 string.h
@@ -369,6 +370,8 @@ LIBBUILTIN(vprintf, "icC*a",      "fP:0:", "stdio.h")
 LIBBUILTIN(vfprintf, "i.",        "fP:1:", "stdio.h")
 LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h")
 LIBBUILTIN(vsprintf, "ic*cC*a",   "fP:1:", "stdio.h")
+// C99
+LIBBUILTIN(longjmp, "vJi",        "fr",    "setjmp.h")
 
 // Non-C library functions
 // FIXME: Non-C-standard stuff shouldn't be builtins in non-GNU mode!
@@ -381,6 +384,11 @@ LIBBUILTIN(strndup, "c*cC*z",     "f",     "string.h")
 // POSIX strings.h
 LIBBUILTIN(index, "c*cC*i",       "f",     "strings.h")
 LIBBUILTIN(rindex, "c*cC*i",      "f",     "strings.h")
+// POSIX unistd.h
+LIBBUILTIN(_exit, "vi",           "fr",    "unistd.h")
+// POSIX setjmp.h
+LIBBUILTIN(_longjmp, "vJi",       "fr",    "setjmp.h")
+LIBBUILTIN(siglongjmp, "vSJi",    "fr",    "setjmp.h")
 
 // FIXME: This type isn't very correct, it should be
 //   id objc_msgSend(id, SEL)
index 03d552dd433c8f75a43b4fe2928aab9d24d562a4..b7e940457fb257c3c3b5dfb4f7e886a1f668e28e 100644 (file)
@@ -120,6 +120,8 @@ def note_please_include_header : Note<
 def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
 def err_implicit_decl_requires_stdio : Error<
   "implicit declaration of '%0' requires inclusion of the header <stdio.h>">;
+def err_implicit_decl_requires_setjmp : Error<
+  "implicit declaration of '%0' requires inclusion of the header <setjmp.h>">;
 def warn_redecl_library_builtin : Warning<
   "incompatible redeclaration of library function %0">;
 def err_builtin_definition : Error<"definition of builtin function %0">;
index 926ba224f42095e66dfdf87ec9da955611025045..15f551821045e78876c17263a37ade56ba406a18 100644 (file)
@@ -423,7 +423,11 @@ namespace clang {
       /// \brief Objective-C fast enumeration state type
       SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6,
       /// \brief C FILE typedef type
-      SPECIAL_TYPE_FILE                        = 7
+      SPECIAL_TYPE_FILE                        = 7,
+      /// \brief C jmp_buf typedef type
+      SPECIAL_TYPE_jmp_buf                     = 8,
+      /// \brief C sigjmp_buf typedef type
+      SPECIAL_TYPE_sigjmp_buf                  = 9
     };
 
     /// \brief Record codes for each kind of declaration.
index f7e1e3fdffd3bf76ce911b7f7c78f6af2ae5efa6..ce58eeef449a68c451de10c87323fc933ec2f374 100644 (file)
@@ -38,8 +38,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
                        Builtin::Context &builtins,
                        bool FreeMem, unsigned size_reserve) : 
   GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0), 
-  ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0),
-  SourceMgr(SM), LangOpts(LOpts), 
+  ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0),
+  sigjmp_bufDecl(0), SourceMgr(SM), LangOpts(LOpts), 
   LoadedExternalComments(false), FreeMemory(FreeMem), Target(t), 
   Idents(idents), Selectors(sels),
   BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {  
@@ -3913,6 +3913,25 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
       break;
     }
   }
+  case 'J': {
+    if (Signed) {
+      Type = Context.getsigjmp_bufType();
+      if (Type.isNull()) {
+        Error = ASTContext::GE_Missing_sigjmp_buf;
+        return QualType();
+      } else {
+        break;
+      }
+    } else {
+      Type = Context.getjmp_bufType();
+      if (Type.isNull()) {
+        Error = ASTContext::GE_Missing_jmp_buf;
+        return QualType();
+      } else {
+        break;
+      }
+    }
+  }
   }
   
   if (!AllowTypeModifiers)
index f21fc6252245cc55c98d0f2920b1d86dc83e8d01..8665705f68575aac70357a6bb0a7ec2446175c70 100644 (file)
@@ -1540,6 +1540,28 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {
       Context->setFILEDecl(Tag->getDecl());
     }
   }
+  if (unsigned Jmp_buf = SpecialTypes[pch::SPECIAL_TYPE_jmp_buf]) {
+    QualType Jmp_bufType = GetType(Jmp_buf);
+    assert(!Jmp_bufType.isNull() && "jmp_bug type is NULL");
+    if (const TypedefType *Typedef = Jmp_bufType->getAsTypedefType())
+      Context->setjmp_bufDecl(Typedef->getDecl());
+    else {
+      const TagType *Tag = Jmp_bufType->getAsTagType();
+      assert(Tag && "Invalid jmp_bug type in PCH file");
+      Context->setjmp_bufDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned Sigjmp_buf = SpecialTypes[pch::SPECIAL_TYPE_sigjmp_buf]) {
+    QualType Sigjmp_bufType = GetType(Sigjmp_buf);
+    assert(!Sigjmp_bufType.isNull() && "sigjmp_buf type is NULL");
+    if (const TypedefType *Typedef = Sigjmp_bufType->getAsTypedefType())
+      Context->setsigjmp_bufDecl(Typedef->getDecl());
+    else {
+      const TagType *Tag = Sigjmp_bufType->getAsTagType();
+      assert(Tag && "Invalid sigjmp_buf type in PCH file");
+      Context->setsigjmp_bufDecl(Tag->getDecl());
+    }
+  }
 }
 
 /// \brief Retrieve the name of the original source file name
index 13f564d012b02b4644eacc7da48088a57360f959..69247d3e859e39ce9921d780e2c6c484f7211cf1 100644 (file)
@@ -1840,6 +1840,8 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   AddTypeRef(Context.getRawCFConstantStringType(), Record);
   AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
   AddTypeRef(Context.getFILEType(), Record);
+  AddTypeRef(Context.getjmp_bufType(), Record);
+  AddTypeRef(Context.getsigjmp_bufType(), Record);
   Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
   
   // Keep writing types and declarations until all types and
index 9b6de12bb24ad54a297d28aa59e8a050c58e4913..d3fe31e738e34d6d2318ec872f5c662c79575ae0 100644 (file)
@@ -453,6 +453,18 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
       Diag(Loc, diag::err_implicit_decl_requires_stdio)
         << Context.BuiltinInfo.GetName(BID);
     return 0;
+
+  case ASTContext::GE_Missing_jmp_buf:
+    if (ForRedeclaration)
+      Diag(Loc, diag::err_implicit_decl_requires_setjmp)
+        << Context.BuiltinInfo.GetName(BID);
+    return 0;
+
+  case ASTContext::GE_Missing_sigjmp_buf:
+    if (ForRedeclaration)
+      Diag(Loc, diag::err_implicit_decl_requires_setjmp)
+        << Context.BuiltinInfo.GetName(BID);
+    return 0;
   }
 
   if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
@@ -1851,10 +1863,15 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   // If this is the C FILE type, notify the AST context.
   if (IdentifierInfo *II = NewTD->getIdentifier())
     if (!NewTD->isInvalidDecl() &&
-        NewTD->getDeclContext()->getLookupContext()->isTranslationUnit() &&        
-        II->isStr("FILE"))
-      Context.setFILEDecl(NewTD);
-  
+        NewTD->getDeclContext()->getLookupContext()->isTranslationUnit()) {
+      if (II->isStr("FILE"))
+        Context.setFILEDecl(NewTD);
+      else if (II->isStr("jmp_buf"))
+        Context.setjmp_bufDecl(NewTD);
+      else if (II->isStr("sigjmp_buf"))
+        Context.setsigjmp_bufDecl(NewTD);
+    }
+
   return NewTD;
 }
 
@@ -3711,9 +3728,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
     if (!FD->getAttr<FormatAttr>())
       FD->addAttr(::new (Context) FormatAttr("printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
-  } else if ((Name->isStr("longjmp") || Name->isStr("_longjmp"))
-             && !FD->hasAttr<NoReturnAttr>())
-    FD->addAttr(::new (Context) NoReturnAttr());
+  }
 }
 
 TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T) {
@@ -4148,7 +4163,7 @@ CreateNewDecl:
   // If this is the C FILE type, notify the AST context.
   if (IdentifierInfo *II = New->getIdentifier())
     if (!New->isInvalidDecl() &&
-        New->getDeclContext()->getLookupContext()->isTranslationUnit() &&        
+        New->getDeclContext()->getLookupContext()->isTranslationUnit() &&
         II->isStr("FILE"))
       Context.setFILEDecl(New);