aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h34
-rw-r--r--include/clang/Basic/Builtins.def10
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--include/clang/Frontend/PCHBitCodes.h6
-rw-r--r--lib/AST/ASTContext.cpp23
-rw-r--r--lib/Frontend/PCHReader.cpp22
-rw-r--r--lib/Frontend/PCHWriter.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp31
8 files changed, 116 insertions, 14 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7768ba49d5..c7faefc17f 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -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.
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index b2d31f2215..0ac2fab8a0 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -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)
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 03d552dd43..b7e940457f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 926ba224f4..15f5518210 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -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.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index f7e1e3fdff..ce58eeef44 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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)
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index f21fc62522..8665705f68 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -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
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 13f564d012..69247d3e85 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -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
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9b6de12bb2..d3fe31e738 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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);