diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-03 17:28:16 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-03 17:28:16 +0000 |
commit | df90325d4c0a65ee64d2dae3ed9b5b34f7418533 (patch) | |
tree | e1a885aadfd80632f5bd70d4bd2d37e715e35a79 /lib/Frontend | |
parent | fd035e6496665b1f1197868e21cb0a4594e8db6e (diff) | |
download | FreeBSD-src-df90325d4c0a65ee64d2dae3ed9b5b34f7418533.zip FreeBSD-src-df90325d4c0a65ee64d2dae3ed9b5b34f7418533.tar.gz |
Update clang to 97654.
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 76 | ||||
-rw-r--r-- | lib/Frontend/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Frontend/CacheTokens.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/CodeGenAction.cpp (renamed from lib/Frontend/Backend.cpp) | 114 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 42 | ||||
-rw-r--r-- | lib/Frontend/InitHeaderSearch.cpp | 4 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 25 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/PrintPreprocessedOutput.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 392 | ||||
-rw-r--r-- | lib/Frontend/TextDiagnosticPrinter.cpp | 10 |
15 files changed, 527 insertions, 182 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index a0c4889..ef14df1 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -36,11 +36,11 @@ using namespace clang; ASTUnit::ASTUnit(bool _MainFileIsAST) - : tempFile(false), MainFileIsAST(_MainFileIsAST) { + : MainFileIsAST(_MainFileIsAST) { } ASTUnit::~ASTUnit() { - if (tempFile) - llvm::sys::Path(getPCHFileName()).eraseFromDisk(); + for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) + TemporaryFiles[I].eraseFromDisk(); } namespace { @@ -90,8 +90,46 @@ public: } }; +class StoredDiagnosticClient : public DiagnosticClient { + llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags; + +public: + explicit StoredDiagnosticClient( + llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) + : StoredDiags(StoredDiags) { } + + virtual void HandleDiagnostic(Diagnostic::Level Level, + const DiagnosticInfo &Info); +}; + +/// \brief RAII object that optionally captures diagnostics, if +/// there is no diagnostic client to capture them already. +class CaptureDroppedDiagnostics { + Diagnostic &Diags; + StoredDiagnosticClient Client; + DiagnosticClient *PreviousClient; + +public: + CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, + llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) + : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient()) + { + if (RequestCapture || Diags.getClient() == 0) + Diags.setClient(&Client); + } + + ~CaptureDroppedDiagnostics() { + Diags.setClient(PreviousClient); + } +}; + } // anonymous namespace +void StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level, + const DiagnosticInfo &Info) { + StoredDiags.push_back(StoredDiagnostic(Level, Info)); +} + const std::string &ASTUnit::getOriginalSourceFileName() { return OriginalSourceFile; } @@ -105,11 +143,16 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, Diagnostic &Diags, bool OnlyLocalDecls, RemappedFile *RemappedFiles, - unsigned NumRemappedFiles) { + unsigned NumRemappedFiles, + bool CaptureDiagnostics) { llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); AST->OnlyLocalDecls = OnlyLocalDecls; AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); + // If requested, capture diagnostics in the ASTUnit. + CaptureDroppedDiagnostics Capture(CaptureDiagnostics, Diags, + AST->Diagnostics); + for (unsigned I = 0; I != NumRemappedFiles; ++I) { // Create the file entry for the file that we're mapping from. const FileEntry *FromFile @@ -119,6 +162,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, if (!FromFile) { Diags.Report(diag::err_fe_remap_missing_from_file) << RemappedFiles[I].first; + delete RemappedFiles[I].second; continue; } @@ -231,7 +275,8 @@ public: ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, Diagnostic &Diags, - bool OnlyLocalDecls) { + bool OnlyLocalDecls, + bool CaptureDiagnostics) { // Create the compiler instance to use for building the AST. CompilerInstance Clang; llvm::OwningPtr<ASTUnit> AST; @@ -245,8 +290,13 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, // Create the target instance. Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), Clang.getTargetOpts())); - if (!Clang.hasTarget()) - goto error; + if (!Clang.hasTarget()) { + Clang.takeSourceManager(); + Clang.takeFileManager(); + Clang.takeDiagnosticClient(); + Clang.takeDiagnostics(); + return 0; + } // Inform the target of the language options. // @@ -261,10 +311,14 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, // Create the AST unit. AST.reset(new ASTUnit(false)); - AST->OnlyLocalDecls = OnlyLocalDecls; AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; + // Capture any diagnostics that would otherwise be dropped. + CaptureDroppedDiagnostics Capture(CaptureDiagnostics, + Clang.getDiagnostics(), + AST->Diagnostics); + // Create a file manager object to provide access to and cache the filesystem. Clang.setFileManager(&AST->getFileManager()); @@ -312,7 +366,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, llvm::StringRef ResourceFilesPath, bool OnlyLocalDecls, RemappedFile *RemappedFiles, - unsigned NumRemappedFiles) { + unsigned NumRemappedFiles, + bool CaptureDiagnostics) { llvm::SmallVector<const char *, 16> Args; Args.push_back("<clang>"); // FIXME: Remove dummy argument. Args.insert(Args.end(), ArgBegin, ArgEnd); @@ -363,5 +418,6 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; CI->getFrontendOpts().DisableFree = true; - return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls); + return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls, + CaptureDiagnostics); } diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt index 1d0b5c1..b69ad97 100644 --- a/lib/Frontend/CMakeLists.txt +++ b/lib/Frontend/CMakeLists.txt @@ -5,8 +5,8 @@ add_clang_library(clangFrontend ASTMerge.cpp ASTUnit.cpp AnalysisConsumer.cpp - Backend.cpp CacheTokens.cpp + CodeGenAction.cpp CompilerInstance.cpp CompilerInvocation.cpp DeclXML.cpp diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp index 7326937..09b5b45 100644 --- a/lib/Frontend/CacheTokens.cpp +++ b/lib/Frontend/CacheTokens.cpp @@ -190,12 +190,7 @@ class PTHWriter { void Emit16(uint32_t V) { ::Emit16(Out, V); } - void Emit24(uint32_t V) { - Out << (unsigned char)(V); - Out << (unsigned char)(V >> 8); - Out << (unsigned char)(V >> 16); - assert((V >> 24) == 0); - } + void Emit24(uint32_t V) { ::Emit24(Out, V); } void Emit32(uint32_t V) { ::Emit32(Out, V); } diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/CodeGenAction.cpp index f5291a9..b1795a3 100644 --- a/lib/Frontend/Backend.cpp +++ b/lib/Frontend/CodeGenAction.cpp @@ -1,4 +1,4 @@ -//===--- Backend.cpp - Interface to LLVM backend technologies -------------===// +//===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/CodeGenAction.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclGroup.h" @@ -15,6 +15,8 @@ #include "clang/Basic/TargetOptions.h" #include "clang/CodeGen/CodeGenOptions.h" #include "clang/CodeGen/ModuleBuilder.h" +#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/Module.h" #include "llvm/PassManager.h" @@ -37,6 +39,14 @@ using namespace clang; using namespace llvm; namespace { + enum BackendAction { + Backend_EmitAssembly, ///< Emit native assembly files + Backend_EmitBC, ///< Emit LLVM bitcode files + Backend_EmitLL, ///< Emit human-readable LLVM assembly + Backend_EmitNothing, ///< Don't emit anything (benchmarking mode) + Backend_EmitObj ///< Emit native object files + }; + class BackendConsumer : public ASTConsumer { Diagnostic &Diags; BackendAction Action; @@ -52,7 +62,7 @@ namespace { llvm::OwningPtr<CodeGenerator> Gen; - llvm::Module *TheModule; + llvm::OwningPtr<llvm::Module> TheModule; llvm::TargetData *TheTargetData; mutable FunctionPassManager *CodeGenPasses; @@ -87,7 +97,7 @@ namespace { LLVMIRGeneration("LLVM IR Generation Time"), CodeGenerationTime("Code Generation Time"), Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)), - TheModule(0), TheTargetData(0), + TheTargetData(0), CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) { if (AsmOutStream) @@ -99,12 +109,13 @@ namespace { ~BackendConsumer() { delete TheTargetData; - delete TheModule; delete CodeGenPasses; delete PerModulePasses; delete PerFunctionPasses; } + llvm::Module *takeModule() { return TheModule.take(); } + virtual void Initialize(ASTContext &Ctx) { Context = &Ctx; @@ -113,7 +124,7 @@ namespace { Gen->Initialize(Ctx); - TheModule = Gen->GetModule(); + TheModule.reset(Gen->GetModule()); TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription()); if (llvm::TimePassesIsEnabled) @@ -169,7 +180,7 @@ namespace { FunctionPassManager *BackendConsumer::getCodeGenPasses() const { if (!CodeGenPasses) { - CodeGenPasses = new FunctionPassManager(TheModule); + CodeGenPasses = new FunctionPassManager(&*TheModule); CodeGenPasses->add(new TargetData(*TheTargetData)); } @@ -187,7 +198,7 @@ PassManager *BackendConsumer::getPerModulePasses() const { FunctionPassManager *BackendConsumer::getPerFunctionPasses() const { if (!PerFunctionPasses) { - PerFunctionPasses = new FunctionPassManager(TheModule); + PerFunctionPasses = new FunctionPassManager(&*TheModule); PerFunctionPasses->add(new TargetData(*TheTargetData)); } @@ -303,12 +314,21 @@ bool BackendConsumer::AddEmitPasses() { case 3: OptLevel = CodeGenOpt::Aggressive; break; } + // Request that addPassesToEmitFile run the Verifier after running + // passes which modify the IR. +#ifndef NDEBUG + bool DisableVerify = false; +#else + bool DisableVerify = true; +#endif + // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile; if (Action == Backend_EmitObj) CGFT = TargetMachine::CGFT_ObjectFile; - if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel)) { + if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel, + DisableVerify)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); return false; } @@ -381,11 +401,12 @@ void BackendConsumer::EmitAssembly() { if (!M) { // The module has been released by IR gen on failures, do not // double free. - TheModule = 0; + TheModule.take(); return; } - assert(TheModule == M && "Unexpected module change during IR generation"); + assert(TheModule.get() == M && + "Unexpected module change during IR generation"); CreatePasses(); if (!AddEmitPasses()) @@ -419,15 +440,64 @@ void BackendConsumer::EmitAssembly() { } } -ASTConsumer *clang::CreateBackendConsumer(BackendAction Action, - Diagnostic &Diags, - const LangOptions &LangOpts, - const CodeGenOptions &CodeGenOpts, - const TargetOptions &TargetOpts, - bool TimePasses, - const std::string& InFile, - llvm::raw_ostream* OS, - LLVMContext& C) { - return new BackendConsumer(Action, Diags, LangOpts, CodeGenOpts, - TargetOpts, TimePasses, InFile, OS, C); +// + +CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {} + +CodeGenAction::~CodeGenAction() {} + +void CodeGenAction::EndSourceFileAction() { + // If the consumer creation failed, do nothing. + if (!getCompilerInstance().hasASTConsumer()) + return; + + // Steal the module from the consumer. + BackendConsumer *Consumer = static_cast<BackendConsumer*>( + &getCompilerInstance().getASTConsumer()); + + TheModule.reset(Consumer->takeModule()); +} + +llvm::Module *CodeGenAction::takeModule() { + return TheModule.take(); } + +ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + BackendAction BA = static_cast<BackendAction>(Act); + llvm::OwningPtr<llvm::raw_ostream> OS; + switch (BA) { + case Backend_EmitAssembly: + OS.reset(CI.createDefaultOutputFile(false, InFile, "s")); + break; + case Backend_EmitLL: + OS.reset(CI.createDefaultOutputFile(false, InFile, "ll")); + break; + case Backend_EmitBC: + OS.reset(CI.createDefaultOutputFile(true, InFile, "bc")); + break; + case Backend_EmitNothing: + break; + case Backend_EmitObj: + OS.reset(CI.createDefaultOutputFile(true, InFile, "o")); + break; + } + if (BA != Backend_EmitNothing && !OS) + return 0; + + return new BackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(), + CI.getCodeGenOpts(), CI.getTargetOpts(), + CI.getFrontendOpts().ShowTimers, InFile, OS.take(), + CI.getLLVMContext()); +} + +EmitAssemblyAction::EmitAssemblyAction() + : CodeGenAction(Backend_EmitAssembly) {} + +EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {} + +EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {} + +EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {} + +EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {} diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 917cbd7..1831ca5 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -102,7 +102,7 @@ namespace { void BinaryDiagnosticSerializer::HandleDiagnostic(Diagnostic::Level DiagLevel, const DiagnosticInfo &Info) { - Info.Serialize(DiagLevel, OS); + StoredDiagnostic(DiagLevel, Info).Serialize(OS); } static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index a193ac8..64a42bc 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -180,6 +180,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, Res.push_back("-mrelocation-model"); Res.push_back(Opts.RelocationModel); } + if (Opts.CXXCtorDtorAliases) + Res.push_back("-mconstructor-aliases"); if (!Opts.VerifyModule) Res.push_back("-disable-llvm-verifier"); } @@ -789,6 +791,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.SoftFloat = Args.hasArg(OPT_msoft_float); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic"); + Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 1c958a7..1e210b4 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -159,48 +159,6 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, return new ASTConsumer(); } -CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {} - -ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile) { - BackendAction BA = static_cast<BackendAction>(Act); - llvm::OwningPtr<llvm::raw_ostream> OS; - switch (BA) { - case Backend_EmitAssembly: - OS.reset(CI.createDefaultOutputFile(false, InFile, "s")); - break; - case Backend_EmitLL: - OS.reset(CI.createDefaultOutputFile(false, InFile, "ll")); - break; - case Backend_EmitBC: - OS.reset(CI.createDefaultOutputFile(true, InFile, "bc")); - break; - case Backend_EmitNothing: - break; - case Backend_EmitObj: - OS.reset(CI.createDefaultOutputFile(true, InFile, "o")); - break; - } - if (BA != Backend_EmitNothing && !OS) - return 0; - - return CreateBackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(), - CI.getCodeGenOpts(), CI.getTargetOpts(), - CI.getFrontendOpts().ShowTimers, InFile, - OS.take(), CI.getLLVMContext()); -} - -EmitAssemblyAction::EmitAssemblyAction() - : CodeGenAction(Backend_EmitAssembly) {} - -EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {} - -EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {} - -EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {} - -EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {} - //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 2e0b4bd..34cb9ec 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -489,8 +489,10 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3", "i686-pc-linux-gnu", "", "", triple); // Debian sid - AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2", + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "x86_64-linux-gnu", "32", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", + "i486-linux-gnu", "64", "", triple); // Ubuntu 7.10 - Gutsy Gibbon AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.3", "i486-linux-gnu", "", "", triple); diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index b7ab3d8..8bcd3a8 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -439,6 +439,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, if (!FromFile) { Diags.Report(diag::err_fe_remap_missing_from_file) << Remap->first; + delete Remap->second; continue; } @@ -477,7 +478,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, = llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr); if (!Buffer) { Diags.Report(diag::err_fe_error_opening) - << Remap->second << ErrorStr; + << Remap->second << ErrorStr; continue; } diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 625997c..356bd07 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -39,6 +39,7 @@ namespace { void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *TU); void VisitNamedDecl(NamedDecl *ND); + void VisitNamespaceDecl(NamespaceDecl *D); void VisitTypeDecl(TypeDecl *TD); void VisitTypedefDecl(TypedefDecl *TD); void VisitTagDecl(TagDecl *TD); @@ -96,6 +97,18 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) { ND->setDeclName(Reader.ReadDeclarationName(Record, Idx)); } +void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { + VisitNamedDecl(D); + D->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + D->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + D->setNextNamespace( + cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++]))); + D->setOriginalNamespace( + cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++]))); + D->setAnonymousNamespace( + cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++]))); +} + void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) { VisitNamedDecl(TD); TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr()); @@ -235,7 +248,6 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { IVars.reserve(NumIvars); for (unsigned I = 0; I != NumIvars; ++I) IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++]))); - ID->setIVarList(IVars.data(), NumIvars, *Reader.getContext()); ID->setCategoryList( cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++]))); ID->setForwardDecl(Record[Idx++]); @@ -517,6 +529,10 @@ Attr *PCHReader::ReadAttributes() { SIMPLE_ATTR(GNUInline); SIMPLE_ATTR(Hiding); + case Attr::IBActionKind: + New = ::new (*Context) IBActionAttr(); + break; + case Attr::IBOutletKind: New = ::new (*Context) IBOutletAttr(); break; @@ -546,7 +562,9 @@ Attr *PCHReader::ReadAttributes() { SIMPLE_ATTR(ObjCException); SIMPLE_ATTR(ObjCNSObject); + SIMPLE_ATTR(CFReturnsNotRetained); SIMPLE_ATTR(CFReturnsRetained); + SIMPLE_ATTR(NSReturnsNotRetained); SIMPLE_ATTR(NSReturnsRetained); SIMPLE_ATTR(Overloadable); SIMPLE_ATTR(Override); @@ -568,6 +586,7 @@ Attr *PCHReader::ReadAttributes() { SIMPLE_ATTR(WarnUnusedResult); SIMPLE_ATTR(Weak); + SIMPLE_ATTR(WeakRef); SIMPLE_ATTR(WeakImport); } @@ -738,6 +757,10 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { case pch::DECL_BLOCK: D = BlockDecl::Create(*Context, 0, SourceLocation()); break; + + case pch::DECL_NAMESPACE: + D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0); + break; } assert(D && "Unknown declaration reading PCH file"); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4c99dbe..93af754 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1852,12 +1852,13 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) { case Attr::GNUInline: case Attr::Hiding: + case Attr::IBActionKind: case Attr::IBOutletKind: case Attr::Malloc: case Attr::NoDebug: + case Attr::NoInline: case Attr::NoReturn: case Attr::NoThrow: - case Attr::NoInline: break; case Attr::NonNull: { @@ -1867,10 +1868,12 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) { break; } - case Attr::ObjCException: - case Attr::ObjCNSObject: + case Attr::CFReturnsNotRetained: case Attr::CFReturnsRetained: + case Attr::NSReturnsNotRetained: case Attr::NSReturnsRetained: + case Attr::ObjCException: + case Attr::ObjCNSObject: case Attr::Overloadable: case Attr::Override: break; @@ -1913,6 +1916,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) { case Attr::WarnUnusedResult: case Attr::Weak: + case Attr::WeakRef: case Attr::WeakImport: break; } @@ -2332,4 +2336,3 @@ void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) { break; } } - diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index d105382..e776d32 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -42,6 +42,7 @@ namespace { void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *D); void VisitNamedDecl(NamedDecl *D); + void VisitNamespaceDecl(NamespaceDecl *D); void VisitTypeDecl(TypeDecl *D); void VisitTypedefDecl(TypedefDecl *D); void VisitTagDecl(TagDecl *D); @@ -99,6 +100,16 @@ void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) { Writer.AddDeclarationName(D->getDeclName(), Record); } +void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { + VisitNamedDecl(D); + Writer.AddSourceLocation(D->getLBracLoc(), Record); + Writer.AddSourceLocation(D->getRBracLoc(), Record); + Writer.AddDeclRef(D->getNextNamespace(), Record); + Writer.AddDeclRef(D->getOriginalNamespace(), Record); + Writer.AddDeclRef(D->getAnonymousNamespace(), Record); + Code = pch::DECL_NAMESPACE; +} + void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) { VisitNamedDecl(D); Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record); diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 43deaee..774372c 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -67,12 +67,7 @@ static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, if (I->hasLeadingSpace()) OS << ' '; - // Make sure we have enough space in the spelling buffer. - if (I->getLength() > SpellingBuffer.size()) - SpellingBuffer.resize(I->getLength()); - const char *Buffer = SpellingBuffer.data(); - unsigned SpellingLen = PP.getSpelling(*I, Buffer); - OS.write(Buffer, SpellingLen); + OS << PP.getSpelling(*I, SpellingBuffer); } } diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 9dade66..a13bccb 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -26,6 +26,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/DenseSet.h" + using namespace clang; using llvm::utostr; @@ -120,8 +121,10 @@ namespace { // Block expressions. llvm::SmallVector<BlockExpr *, 32> Blocks; + llvm::SmallVector<int, 32> InnerDeclRefsCount; + llvm::SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs; + llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs; - llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs; // Block related declarations. llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls; @@ -253,6 +256,8 @@ namespace { void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); void RewriteImplementationDecl(Decl *Dcl); void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr); + void RewriteTypeIntoString(QualType T, std::string &ResultStr, + const FunctionType *&FPRetType); void RewriteByRefString(std::string &ResultStr, const std::string &Name, ValueDecl *VD); void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); @@ -301,8 +306,12 @@ namespace { Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, SourceLocation OrigEnd); CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, - Expr **args, unsigned nargs); - Stmt *SynthMessageExpr(ObjCMessageExpr *Exp); + Expr **args, unsigned nargs, + SourceLocation StartLoc=SourceLocation(), + SourceLocation EndLoc=SourceLocation()); + Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, + SourceLocation StartLoc=SourceLocation(), + SourceLocation EndLoc=SourceLocation()); Stmt *RewriteBreakStmt(BreakStmt *S); Stmt *RewriteContinueStmt(ContinueStmt *S); void SynthCountByEnumWithState(std::string &buf); @@ -342,7 +351,7 @@ namespace { std::string &Result); void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl, std::string &Result); - void SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl, + void SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl, ObjCIvarDecl *ivar, std::string &Result); void RewriteImplementations(); @@ -379,8 +388,10 @@ namespace { void RewriteRecordBody(RecordDecl *RD); void CollectBlockDeclRefInfo(BlockExpr *Exp); - void GetBlockCallExprs(Stmt *S); void GetBlockDeclRefExprs(Stmt *S); + void GetInnerBlockDeclRefExprs(Stmt *S, + llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs, + llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts); // We avoid calling Type::isBlockPointerType(), since it operates on the // canonical type. We only care if the top-level type is a closure pointer. @@ -412,7 +423,8 @@ namespace { void RewriteCastExpr(CStyleCastExpr *CE); FunctionDecl *SynthBlockInitFunctionDecl(const char *name); - Stmt *SynthBlockInitExpr(BlockExpr *Exp); + Stmt *SynthBlockInitExpr(BlockExpr *Exp, + const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs); void QuoteDoublequotes(std::string &From, std::string &To) { for (unsigned i = 0; i < From.length(); i++) { @@ -547,7 +559,7 @@ void RewriteObjC::Initialize(ASTContext &context) { Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; } else - Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; + Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend"; Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper"; @@ -606,7 +618,8 @@ void RewriteObjC::Initialize(ASTContext &context) { Preamble += "};\n"; Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; - Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_assign(void *, const void *, const int);\n"; + Preamble += "extern \"C\" __declspec(dllexport) " + "void _Block_object_assign(void *, const void *, const int);\n"; Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; @@ -627,6 +640,9 @@ void RewriteObjC::Initialize(ASTContext &context) { Preamble += "#define __block\n"; Preamble += "#define __weak\n"; } + // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long + // as this avoids warning in any 64bit/32bit compilation model. + Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; } @@ -750,6 +766,8 @@ static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl, void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, ObjCImplementationDecl *IMD, ObjCCategoryImplDecl *CID) { + static bool objcGetPropertyDefined = false; + static bool objcSetPropertyDefined = false; SourceLocation startLoc = PID->getLocStart(); InsertText(startLoc, "// "); const char *startBuf = SM->getCharacterData(startLoc); @@ -769,15 +787,55 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, if (!OID) return; - + unsigned Attributes = PD->getPropertyAttributes(); + bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && + (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | + ObjCPropertyDecl::OBJC_PR_copy)); std::string Getr; + if (GenGetProperty && !objcGetPropertyDefined) { + objcGetPropertyDefined = true; + // FIXME. Is this attribute correct in all cases? + Getr = "\nextern \"C\" __declspec(dllimport) " + "id objc_getProperty(id, SEL, long, bool);\n"; + } RewriteObjCMethodDecl(PD->getGetterMethodDecl(), Getr); Getr += "{ "; // Synthesize an explicit cast to gain access to the ivar. - // FIXME: deal with code generation implications for various property - // attributes (copy, retain, nonatomic). // See objc-act.c:objc_synthesize_new_getter() for details. - Getr += "return " + getIvarAccessString(ClassDecl, OID); + if (GenGetProperty) { + // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) + Getr += "typedef "; + const FunctionType *FPRetType = 0; + RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, + FPRetType); + Getr += " _TYPE"; + if (FPRetType) { + Getr += ")"; // close the precedence "scope" for "*". + + // Now, emit the argument types (if any). + if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) { + Getr += "("; + for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { + if (i) Getr += ", "; + std::string ParamStr = FT->getArgType(i).getAsString(); + Getr += ParamStr; + } + if (FT->isVariadic()) { + if (FT->getNumArgs()) Getr += ", "; + Getr += "..."; + } + Getr += ")"; + } else + Getr += "()"; + } + Getr += ";\n"; + Getr += "return (_TYPE)"; + Getr += "objc_getProperty(self, _cmd, "; + SynthesizeIvarOffsetComputation(ClassDecl, OID, Getr); + Getr += ", 1)"; + } + else + Getr += "return " + getIvarAccessString(ClassDecl, OID); Getr += "; }"; InsertText(onePastSemiLoc, Getr); if (PD->isReadOnly()) @@ -785,14 +843,38 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, // Generate the 'setter' function. std::string Setr; + bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | + ObjCPropertyDecl::OBJC_PR_copy); + if (GenSetProperty && !objcSetPropertyDefined) { + objcSetPropertyDefined = true; + // FIXME. Is this attribute correct in all cases? + Setr = "\nextern \"C\" __declspec(dllimport) " + "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; + } + RewriteObjCMethodDecl(PD->getSetterMethodDecl(), Setr); Setr += "{ "; // Synthesize an explicit cast to initialize the ivar. - // FIXME: deal with code generation implications for various property - // attributes (copy, retain, nonatomic). // See objc-act.c:objc_synthesize_new_setter() for details. - Setr += getIvarAccessString(ClassDecl, OID) + " = "; - Setr += PD->getNameAsCString(); + if (GenSetProperty) { + Setr += "objc_setProperty (self, _cmd, "; + SynthesizeIvarOffsetComputation(ClassDecl, OID, Setr); + Setr += ", (id)"; + Setr += PD->getNameAsCString(); + Setr += ", "; + if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) + Setr += "0, "; + else + Setr += "1, "; + if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) + Setr += "1)"; + else + Setr += "0)"; + } + else { + Setr += getIvarAccessString(ClassDecl, OID) + " = "; + Setr += PD->getNameAsCString(); + } Setr += "; }"; InsertText(onePastSemiLoc, Setr); } @@ -929,18 +1011,15 @@ void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) { ReplaceText(LocStart, 0, "// "); } -void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD, - std::string &ResultStr) { - //fprintf(stderr,"In RewriteObjCMethodDecl\n"); - const FunctionType *FPRetType = 0; - ResultStr += "\nstatic "; - if (OMD->getResultType()->isObjCQualifiedIdType()) +void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, + const FunctionType *&FPRetType) { + if (T->isObjCQualifiedIdType()) ResultStr += "id"; - else if (OMD->getResultType()->isFunctionPointerType() || - OMD->getResultType()->isBlockPointerType()) { + else if (T->isFunctionPointerType() || + T->isBlockPointerType()) { // needs special handling, since pointer-to-functions have special // syntax (where a decaration models use). - QualType retType = OMD->getResultType(); + QualType retType = T; QualType PointeeTy; if (const PointerType* PT = retType->getAs<PointerType>()) PointeeTy = PT->getPointeeType(); @@ -951,7 +1030,15 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD, ResultStr += "(*"; } } else - ResultStr += OMD->getResultType().getAsString(); + ResultStr += T.getAsString(); +} + +void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD, + std::string &ResultStr) { + //fprintf(stderr,"In RewriteObjCMethodDecl\n"); + const FunctionType *FPRetType = 0; + ResultStr += "\nstatic "; + RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType); ResultStr += " "; // Unique method name @@ -1952,7 +2039,8 @@ Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { } CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( - FunctionDecl *FD, Expr **args, unsigned nargs) { + FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc, + SourceLocation EndLoc) { // Get the type, we will need to reference it in a couple spots. QualType msgSendType = FD->getType(); @@ -1968,8 +2056,10 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( const FunctionType *FT = msgSendType->getAs<FunctionType>(); - return new (Context) CallExpr(*Context, ICE, args, nargs, FT->getResultType(), - SourceLocation()); + CallExpr *Exp = + new (Context) CallExpr(*Context, ICE, args, nargs, FT->getResultType(), + EndLoc); + return Exp; } static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, @@ -2165,8 +2255,10 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() { llvm::SmallVector<QualType, 16> ArgTys; ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(), - &ArgTys[0], ArgTys.size(), - false /*isVariadic*/, 0); + &ArgTys[0], ArgTys.size(), + false /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SelGetUidIdent, getFuncType, 0, @@ -2196,6 +2288,36 @@ static void RewriteBlockPointerType(std::string& Str, QualType Type) { } } +// FIXME. Consolidate this routine with RewriteBlockPointerType. +static void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD) { + QualType Type = VD->getType(); + std::string TypeString(Type.getAsString()); + const char *argPtr = TypeString.c_str(); + int paren = 0; + while (*argPtr) { + switch (*argPtr) { + case '(': + Str += *argPtr; + paren++; + break; + case ')': + Str += *argPtr; + paren--; + break; + case '^': + Str += '*'; + if (paren == 1) + Str += VD->getNameAsString(); + break; + default: + Str += *argPtr; + break; + } + argPtr++; + } +} + + void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); @@ -2231,7 +2353,9 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - false, 0); + false, 0, + false, false, 0, 0, false, + CC_Default); SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2250,7 +2374,9 @@ void RewriteObjC::SynthMsgSendFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/, 0); + true /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2272,7 +2398,9 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/, 0); + true /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2291,7 +2419,9 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/, 0); + true /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2315,7 +2445,9 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/, 0); + true /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2334,7 +2466,9 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->DoubleTy, &ArgTys[0], ArgTys.size(), - true /*isVariadic*/, 0); + true /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2348,7 +2482,9 @@ void RewriteObjC::SynthGetClassFunctionDecl() { ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - false /*isVariadic*/, 0); + false /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getClassIdent, getClassType, 0, @@ -2362,7 +2498,9 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() { ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - false /*isVariadic*/, 0); + false /*isVariadic*/, 0, + false, false, 0, 0, false, + CC_Default); GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getClassIdent, getClassType, 0, @@ -2485,7 +2623,9 @@ QualType RewriteObjC::getConstantStringStructType() { return Context->getTagDeclType(ConstantStringDecl); } -Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { +Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, + SourceLocation StartLoc, + SourceLocation EndLoc) { if (!SelGetUidFunctionDecl) SynthSelGetUidFunctionDecl(); if (!MsgSendFunctionDecl) @@ -2551,7 +2691,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { false, argType, SourceLocation())); CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, &ClsExprs[0], - ClsExprs.size()); + ClsExprs.size(), + StartLoc, + EndLoc); // To turn off a warning, type-cast to 'id' InitExprs.push_back( // set 'super class', using objc_getClass(). NoTypeInfoCStyleCastExpr(Context, @@ -2606,7 +2748,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { SourceLocation())); CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, &ClsExprs[0], - ClsExprs.size()); + ClsExprs.size(), + StartLoc, EndLoc); MsgExprs.push_back(Cls); } } else { // instance message. @@ -2636,7 +2779,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { false, argType, SourceLocation())); CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, &ClsExprs[0], - ClsExprs.size()); + ClsExprs.size(), + StartLoc, EndLoc); // To turn off a warning, type-cast to 'id' InitExprs.push_back( // set 'super class', using objc_getClass(). @@ -2695,7 +2839,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { Exp->getSelector().getAsString().size(), false, argType, SourceLocation())); CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - &SelExprs[0], SelExprs.size()); + &SelExprs[0], SelExprs.size(), + StartLoc, + EndLoc); MsgExprs.push_back(SelExp); // Now push any user supplied arguments. @@ -2752,6 +2898,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { } returnType = OMD->getResultType()->isObjCQualifiedIdType() ? Context->getObjCIdType() : OMD->getResultType(); + if (isTopLevelBlockPointerType(returnType)) { + const BlockPointerType *BPT = returnType->getAs<BlockPointerType>(); + returnType = Context->getPointerType(BPT->getPointeeType()); + } } else { returnType = Context->getObjCIdType(); } @@ -2774,18 +2924,20 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { QualType castType = Context->getFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), // If we don't have a method decl, force a variadic cast. - Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0); + Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0, + false, false, 0, 0, false, + CC_Default); castType = Context->getPointerType(castType); cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown, cast); // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast); + ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); const FunctionType *FT = msgSendType->getAs<FunctionType>(); CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], MsgExprs.size(), - FT->getResultType(), SourceLocation()); + FT->getResultType(), EndLoc); Stmt *ReplacingStmt = CE; if (MsgSendStretFlavor) { // We have the method which returns a struct/union. Must also generate @@ -2803,7 +2955,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // Now do the "normal" pointer to function cast. castType = Context->getFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), - Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0); + Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0, + false, false, 0, 0, false, + CC_Default); castType = Context->getPointerType(castType); cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown, cast); @@ -2846,7 +3000,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { } Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { - Stmt *ReplacingStmt = SynthMessageExpr(Exp); + Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), + Exp->getLocEnd()); // Now do the actual rewrite. ReplaceStmt(Exp, ReplacingStmt); @@ -3430,7 +3585,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, /// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of /// ivar offset. -void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl, +void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl, ObjCIvarDecl *ivar, std::string &Result) { if (ivar->isBitField()) { @@ -3504,12 +3659,12 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, ObjCInterfaceDecl::ivar_iterator IVI, IVE; llvm::SmallVector<ObjCIvarDecl *, 8> IVars; if (!IDecl->ivar_empty()) { - for (ObjCImplementationDecl::ivar_iterator + for (ObjCInterfaceDecl::ivar_iterator IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end(); IV != IVEnd; ++IV) IVars.push_back(*IV); - IVI = IVars.begin(); - IVE = IVars.end(); + IVI = IDecl->ivar_begin(); + IVE = IDecl->ivar_end(); } else { IVI = CDecl->ivar_begin(); IVE = CDecl->ivar_end(); @@ -3728,9 +3883,7 @@ void RewriteObjC::RewriteImplementations() { void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string &Result) { int ClsDefCount = ClassImplementation.size(); int CatDefCount = CategoryImplementation.size(); - - // This is needed for determining instance variable offsets. - Result += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long) &((TYPE *)0)->MEMBER)\n"; + // For each implemented class, write out all its meta data. for (int i = 0; i < ClsDefCount; i++) RewriteObjCClassMetaData(ClassImplementation[i], Result); @@ -3888,7 +4041,6 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), E = BlockByCopyDecls.end(); I != E; ++I) { S += " "; - std::string Name = (*I)->getNameAsString(); // Handle nested closure invocation. For example: // // void (^myImportedClosure)(void); @@ -3899,11 +4051,19 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, // myImportedClosure(); // import and invoke the closure // }; // - if (isTopLevelBlockPointerType((*I)->getType())) - S += "struct __block_impl *"; - else + if (isTopLevelBlockPointerType((*I)->getType())) { + RewriteBlockPointerTypeVariable(S, (*I)); + S += " = ("; + RewriteBlockPointerType(S, (*I)->getType()); + S += ")"; + S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; + } + else { + std::string Name = (*I)->getNameAsString(); (*I)->getType().getAsStringInternal(Name, Context->PrintingPolicy); - S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; + S += Name + " = __cself->" + + (*I)->getNameAsString() + "; // bound by copy\n"; + } } std::string RewrittenStr = RewrittenBlockExprs[CE]; const char *cstr = RewrittenStr.c_str(); @@ -4107,9 +4267,23 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); // Insert closures that were part of the function. - for (unsigned i = 0; i < Blocks.size(); i++) { - + for (unsigned i = 0, count=0; i < Blocks.size(); i++) { CollectBlockDeclRefInfo(Blocks[i]); + // Need to copy-in the inner copied-in variables not actually used in this + // block. + for (int j = 0; j < InnerDeclRefsCount[i]; j++) { + BlockDeclRefExpr *Exp = InnerDeclRefs[count++]; + ValueDecl *VD = Exp->getDecl(); + BlockDeclRefs.push_back(Exp); + if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) { + BlockByCopyDeclsPtrSet.insert(VD); + BlockByCopyDecls.push_back(VD); + } + if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) { + BlockByRefDeclsPtrSet.insert(VD); + BlockByRefDecls.push_back(VD); + } + } std::string ImplTag = "__" + std::string(FunName) + "_block_impl_" + utostr(i); std::string DescTag = "__" + std::string(FunName) + "_block_desc_" + utostr(i); @@ -4135,10 +4309,11 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, BlockByRefDeclsPtrSet.clear(); BlockByCopyDecls.clear(); BlockByCopyDeclsPtrSet.clear(); - BlockCallExprs.clear(); ImportedBlockDecls.clear(); } Blocks.clear(); + InnerDeclRefsCount.clear(); + InnerDeclRefs.clear(); RewrittenBlockExprs.clear(); } @@ -4186,21 +4361,30 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { return; } -void RewriteObjC::GetBlockCallExprs(Stmt *S) { +void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, + llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs, + llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E; ++CI) if (*CI) { - if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) - GetBlockCallExprs(CBE->getBody()); + if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { + InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); + GetInnerBlockDeclRefExprs(CBE->getBody(), + InnerBlockDeclRefs, + InnerContexts); + } else - GetBlockCallExprs(*CI); - } + GetInnerBlockDeclRefExprs(*CI, + InnerBlockDeclRefs, + InnerContexts); - if (CallExpr *CE = dyn_cast<CallExpr>(S)) { - if (CE->getCallee()->getType()->isBlockPointerType()) { - BlockCallExprs[dyn_cast<BlockDeclRefExpr>(CE->getCallee())] = CE; } - } + // Handle specific things. + if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) + if (!isa<FunctionDecl>(CDRE->getDecl()) && + !InnerContexts.count(CDRE->getDecl()->getDeclContext())) + InnerBlockDeclRefs.push_back(CDRE); + return; } @@ -4269,7 +4453,9 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { } // Now do the pointer to function cast. QualType PtrToFuncCastType = Context->getFunctionType(Exp->getType(), - &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0); + &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0, + false, false, 0, 0, + false, CC_Default); PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); @@ -4379,7 +4565,7 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); std::string TypeAsString = "("; - TypeAsString += QT.getAsString(); + RewriteBlockPointerType(TypeAsString, QT); TypeAsString += ")"; ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); return; @@ -4605,6 +4791,10 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { int flag = 0; int isa = 0; SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); + if (DeclLoc.isInvalid()) + // If type location is missing, it is because of missing type (a warning). + // Use variable's location which is good for this case. + DeclLoc = ND->getLocation(); const char *startBuf = SM->getCharacterData(DeclLoc); SourceLocation X = ND->getLocEnd(); X = SM->getInstantiationLoc(X); @@ -4758,10 +4948,8 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { for (unsigned i = 0; i < BlockDeclRefs.size(); i++) if (BlockDeclRefs[i]->isByRef() || BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || - BlockDeclRefs[i]->getType()->isBlockPointerType()) { - GetBlockCallExprs(BlockDeclRefs[i]); + BlockDeclRefs[i]->getType()->isBlockPointerType()) ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); - } } } @@ -4773,10 +4961,43 @@ FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) { false); } -Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) { +Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, + const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) { Blocks.push_back(Exp); CollectBlockDeclRefInfo(Exp); + + // Add inner imported variables now used in current block. + int countOfInnerDecls = 0; + if (!InnerBlockDeclRefs.empty()) { + for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { + BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i]; + ValueDecl *VD = Exp->getDecl(); + if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) { + // We need to save the copied-in variables in nested + // blocks because it is needed at the end for some of the API generations. + // See SynthesizeBlockLiterals routine. + InnerDeclRefs.push_back(Exp); countOfInnerDecls++; + BlockDeclRefs.push_back(Exp); + BlockByCopyDeclsPtrSet.insert(VD); + BlockByCopyDecls.push_back(VD); + } + if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) { + InnerDeclRefs.push_back(Exp); countOfInnerDecls++; + BlockDeclRefs.push_back(Exp); + BlockByRefDeclsPtrSet.insert(VD); + BlockByRefDecls.push_back(VD); + } + } + // Find any imported blocks...they will need special attention. + for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) + if (InnerBlockDeclRefs[i]->isByRef() || + InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || + InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) + ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); + } + InnerDeclRefsCount.push_back(countOfInnerDecls); + std::string FuncName; if (CurFunctionDef) @@ -4955,6 +5176,11 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { } if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { + llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs; + llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; + InnerContexts.insert(BE->getBlockDecl()); + GetInnerBlockDeclRefExprs(BE->getBody(), + InnerBlockDeclRefs, InnerContexts); // Rewrite the block body in place. RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); @@ -4962,7 +5188,8 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); RewrittenBlockExprs[BE] = Str; - Stmt *blockTranscribed = SynthBlockInitExpr(BE); + Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); + //blockTranscribed->dump(); ReplaceStmt(S, blockTranscribed); return blockTranscribed; @@ -5281,11 +5508,6 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { RewriteBlockPointerDecl(TD); else if (TD->getUnderlyingType()->isFunctionPointerType()) CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); - else if (TD->getUnderlyingType()->isRecordType()) { - RecordDecl *RD = TD->getUnderlyingType()->getAs<RecordType>()->getDecl(); - if (RD->isDefinition()) - RewriteRecordBody(RD); - } return; } if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) { diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index 9ec5ffe..d2aa548 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -31,7 +31,7 @@ static const enum llvm::raw_ostream::Colors warningColor = llvm::raw_ostream::MAGENTA; static const enum llvm::raw_ostream::Colors errorColor = llvm::raw_ostream::RED; static const enum llvm::raw_ostream::Colors fatalColor = llvm::raw_ostream::RED; -// used for changing only the bold attribute +// Used for changing only the bold attribute. static const enum llvm::raw_ostream::Colors savedColor = llvm::raw_ostream::SAVEDCOLOR; @@ -682,6 +682,9 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // file+line+column number prefix is. uint64_t StartOfLocationInfo = OS.tell(); + if (!Prefix.empty()) + OS << Prefix << ": "; + // If the location is specified, print out a file/line/col and include trace // if enabled. if (Info.getLocation().isValid()) { @@ -786,12 +789,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, llvm::SmallString<100> OutStr; Info.FormatDiagnostic(OutStr); - if (DiagOpts->ShowOptionNames) + if (DiagOpts->ShowOptionNames) { if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) { OutStr += " [-W"; OutStr += Opt; OutStr += ']'; + } else if (Diagnostic::isBuiltinExtensionDiag(Info.getID())) { + OutStr += " [-pedantic]"; } + } if (DiagOpts->ShowColors) { // Print warnings, errors and fatal errors in bold, no color |