diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 23 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 22 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 31 |
4 files changed, 68 insertions, 10 deletions
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); |