[PATCH] D36702: Make Parser::Consume*Token methods public.
marsupial added a comment. Ping. https://reviews.llvm.org/D36702 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36701: Use Token::isOneOf method in Parser.
marsupial added a comment. Ping. https://reviews.llvm.org/D36701 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36701: Use Token::isOneOf method in Parser.
This revision was automatically updated to reflect the committed changes. Closed by commit rL325352: Use Token::isOneOf method in Parser. (authored by marsupial, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D36701?vs=111034&id=134629#toc Repository: rL LLVM https://reviews.llvm.org/D36701 Files: cfe/trunk/include/clang/Parse/Parser.h Index: cfe/trunk/include/clang/Parse/Parser.h === --- cfe/trunk/include/clang/Parse/Parser.h +++ cfe/trunk/include/clang/Parse/Parser.h @@ -379,15 +379,15 @@ /// isTokenParen - Return true if the cur token is '(' or ')'. bool isTokenParen() const { -return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren; +return Tok.isOneOf(tok::l_paren, tok::r_paren); } /// isTokenBracket - Return true if the cur token is '[' or ']'. bool isTokenBracket() const { -return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square; +return Tok.isOneOf(tok::l_square, tok::r_square); } /// isTokenBrace - Return true if the cur token is '{' or '}'. bool isTokenBrace() const { -return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace; +return Tok.isOneOf(tok::l_brace, tok::r_brace); } /// isTokenStringLiteral - True if this token is a string-literal. bool isTokenStringLiteral() const { Index: cfe/trunk/include/clang/Parse/Parser.h === --- cfe/trunk/include/clang/Parse/Parser.h +++ cfe/trunk/include/clang/Parse/Parser.h @@ -379,15 +379,15 @@ /// isTokenParen - Return true if the cur token is '(' or ')'. bool isTokenParen() const { -return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren; +return Tok.isOneOf(tok::l_paren, tok::r_paren); } /// isTokenBracket - Return true if the cur token is '[' or ']'. bool isTokenBracket() const { -return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square; +return Tok.isOneOf(tok::l_square, tok::r_square); } /// isTokenBrace - Return true if the cur token is '{' or '}'. bool isTokenBrace() const { -return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace; +return Tok.isOneOf(tok::l_brace, tok::r_brace); } /// isTokenStringLiteral - True if this token is a string-literal. bool isTokenStringLiteral() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33659: Extend DynamicLibrary class to be usable without loading permanently.
marsupial created this revision. https://reviews.llvm.org/D33659 Files: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp === --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -53,8 +53,8 @@ i != e; ++i) { // Get access to the plugin. std::string err; -DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); -if (!lib.isValid()) { +DynamicLibrary *lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); +if (!lib) { diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err; continue; } Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp === --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -53,8 +53,8 @@ i != e; ++i) { // Get access to the plugin. std::string err; -DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); -if (!lib.isValid()) { +DynamicLibrary *lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); +if (!lib) { diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err; continue; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
This revision was automatically updated to reflect the committed changes. Closed by commit rC327528: Expand clang-interpreter with example of throwing in and from the JIT for… (authored by marsupial, committed by ). Repository: rC Clang https://reviews.llvm.org/D35103 Files: examples/clang-interpreter/CMakeLists.txt examples/clang-interpreter/Invoke.cpp examples/clang-interpreter/Invoke.h examples/clang-interpreter/Manager.cpp examples/clang-interpreter/Manager.h examples/clang-interpreter/README.txt examples/clang-interpreter/Test.cxx examples/clang-interpreter/main.cpp Index: examples/clang-interpreter/Invoke.cpp === --- examples/clang-interpreter/Invoke.cpp +++ examples/clang-interpreter/Invoke.cpp @@ -0,0 +1,31 @@ +//==-- examples/clang-interpreter/Invoke.cpp - Clang C Interpreter Example -==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "Invoke.h" + +#include +#include + +namespace interpreter { + +int TryIt(llvm::ExecutionEngine *EE, llvm::Function *EntryFn, + const std::vector &Args, char *const *EnvP, + Invoker Invoke) { + int Res = -1; + try { +Res = Invoke(EE, EntryFn, Args, EnvP); + } catch (const std::exception &E) { +std::cout << "Caught '" << E.what() << "'\n"; + } catch (...) { +std::cout << "Unknown exception\n"; + } + return Res; +} + +} Index: examples/clang-interpreter/README.txt === --- examples/clang-interpreter/README.txt +++ examples/clang-interpreter/README.txt @@ -1,4 +1,4 @@ -This is an example of Clang based interpreter, for executing standalone C +This is an example of Clang based interpreter, for executing standalone C/C++ programs. It demonstrates the following features: @@ -12,6 +12,9 @@ 4. Use the LLVM JIT functionality to execute the final module. + 5. Intercepting a Win64 library call to allow throwing and catching exceptions +in and from the JIT. + The implementation has many limitations and is not designed to be a full fledged -C interpreter. It is designed to demonstrate a simple but functional use of the +interpreter. It is designed to demonstrate a simple but functional use of the Clang compiler libraries. Index: examples/clang-interpreter/Manager.cpp === --- examples/clang-interpreter/Manager.cpp +++ examples/clang-interpreter/Manager.cpp @@ -0,0 +1,328 @@ +//==-- examples/clang-interpreter/Manager.cpp - Clang C Interpreter Example -=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "Manager.h" + +#ifdef CLANG_INTERPRETER_WIN_EXCEPTIONS +#include "llvm/Support/DynamicLibrary.h" + +#define WIN32_LEAN_AND_MEAN +#define NOGDI +#define NOMINMAX +#include +#endif + +namespace interpreter { + +using namespace llvm; + +void SingleSectionMemoryManager::Block::Reset(uint8_t *Ptr, uintptr_t Size) { + assert(Ptr != nullptr && "Bad allocation"); + Addr = Ptr; + End = Ptr ? Ptr + Size : nullptr; +} + +uint8_t *SingleSectionMemoryManager::Block::Next(uintptr_t Size, + unsigned Alignment) { + uintptr_t Out = (uintptr_t)Addr; + + // Align the out pointer properly + if (!Alignment) +Alignment = 16; + Out = (Out + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + + // RuntimeDyld should have called reserveAllocationSpace with an amount that + // will fit all required alignemnts...but assert on this to make sure. + assert((Out + Size) <= (uintptr_t)End && "Out of bounds"); + + // Set the next Addr to deliver at the end of this one. + Addr = (uint8_t *)(Out + Size); + return (uint8_t *)Out; +} + +uint8_t *SingleSectionMemoryManager::allocateCodeSection(uintptr_t Size, + unsigned Align, + unsigned ID, + StringRef Name) { + return Code.Next(Size, Align); +} + +uint8_t *SingleSectionMemoryManager::allocateDataSection( +uintptr_t Size, unsigned Align, unsigned ID, StringRef Name, bool RO) { + return RO ? ROData.Next(Size, Align) : RWData.Next(Size, Align); +} + +void SingleSectionMemoryManager::reserveAllocationSpace( +uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t ROSize, uint32_t ROAlign, +uintptr_t RWSize, uint32_t RWAlign) { + // FIXME: Ideally this should be one contiguous block, with Code, ROData, + // and RWData poi
[PATCH] D44508: Remove unnecessary include from Driver.cpp
marsupial added a comment. Shouldn't the Translation Unit be responsible for knowing what it needs rather than hoping it's already been used somewhere up the chain. Perhaps std::unique_ptr and std::make_pair are too low level and one can assume, but https://reviews.llvm.org/D44509 seems like a possibly overzealous application? Repository: rL LLVM https://reviews.llvm.org/D44508 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44555: clang-interpreter example cmake fix
marsupial accepted this revision. marsupial added a comment. This revision is now accepted and ready to land. Sorry 'bout that... (CMake and quoting make dull boys) Repository: rC Clang https://reviews.llvm.org/D44555 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44643: [Lex] Change HeaderSearchOptions arguments to std::string.
marsupial updated this revision to Diff 138982. https://reviews.llvm.org/D44643 Files: include/clang/Lex/HeaderSearchOptions.h Index: include/clang/Lex/HeaderSearchOptions.h === --- include/clang/Lex/HeaderSearchOptions.h +++ include/clang/Lex/HeaderSearchOptions.h @@ -203,34 +203,35 @@ unsigned ModulesHashContent : 1; - HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), -ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), -UseBuiltinIncludes(true), UseStandardSystemIncludes(true), -UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), + HeaderSearchOptions(std::string _Sysroot = "/") + : Sysroot(std::move(_Sysroot)), ModuleFormat("raw"), +DisableModuleHash(false), ImplicitModuleMaps(false), +ModuleMapFileHomeIsCwd(false), UseBuiltinIncludes(true), +UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), +UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), ModulesValidateSystemHeaders(false), UseDebugInfo(false), ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. - void AddPath(StringRef Path, frontend::IncludeDirGroup Group, + void AddPath(std::string Path, frontend::IncludeDirGroup Group, bool IsFramework, bool IgnoreSysRoot) { -UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot); +UserEntries.emplace_back(std::move(Path), Group, IsFramework, IgnoreSysRoot); } /// AddSystemHeaderPrefix - Override whether \#include directives naming a /// path starting with \p Prefix should be considered as naming a system /// header. - void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { -SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader); + void AddSystemHeaderPrefix(std::string Prefix, bool IsSystemHeader) { +SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader); } - void AddVFSOverlayFile(StringRef Name) { -VFSOverlayFiles.push_back(Name); + void AddVFSOverlayFile(std::string Name) { +VFSOverlayFiles.emplace_back(std::move(Name)); } - void AddPrebuiltModulePath(StringRef Name) { -PrebuiltModulePaths.push_back(Name); + void AddPrebuiltModulePath(std::string Name) { +PrebuiltModulePaths.emplace_back(std::move(Name)); } }; Index: include/clang/Lex/HeaderSearchOptions.h === --- include/clang/Lex/HeaderSearchOptions.h +++ include/clang/Lex/HeaderSearchOptions.h @@ -203,34 +203,35 @@ unsigned ModulesHashContent : 1; - HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), -ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), -UseBuiltinIncludes(true), UseStandardSystemIncludes(true), -UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), + HeaderSearchOptions(std::string _Sysroot = "/") + : Sysroot(std::move(_Sysroot)), ModuleFormat("raw"), +DisableModuleHash(false), ImplicitModuleMaps(false), +ModuleMapFileHomeIsCwd(false), UseBuiltinIncludes(true), +UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), +UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), ModulesValidateSystemHeaders(false), UseDebugInfo(false), ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. - void AddPath(StringRef Path, frontend::IncludeDirGroup Group, + void AddPath(std::string Path, frontend::IncludeDirGroup Group, bool IsFramework, bool IgnoreSysRoot) { -UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot); +UserEntries.emplace_back(std::move(Path), Group, IsFramework, IgnoreSysRoot); } /// AddSystemHeaderPrefix - Override whether \#include directives naming a /// path starting with \p Prefix should be considered as naming a system /// header. - void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { -SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader); + void AddSystemHeaderPrefix(std::string Prefix, bool IsSystemHeader) { +SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader); } - void AddVFSOverlayFile(StringRef Name) { -VFSOverlayFiles.push_back(Name); + void AddVFSOverlayFile(std::string Name) { +VFSOverlayFiles.emplace_back(std::move(Name)); } - void AddPrebuiltModulePath(StringRef Name) { -PrebuiltModulePaths.push_back(Name); + void AddPrebuiltModulePath(std::string Name) { +PrebuiltModulePaths.emplace_back(std::move(Name)); } }; _
[PATCH] D44643: [Lex] Change HeaderSearchOptions arguments to std::string.
marsupial created this revision. marsupial added reviewers: eugene, boris. marsupial added a project: clang. marsupial updated this revision to Diff 138982. Arguments passed to HeaderSearchOptions methods are stored as std::strings, having them converted to a StringRef at the call site can result in unnecessary conversions and copies. https://reviews.llvm.org/D44643 Files: include/clang/Lex/HeaderSearchOptions.h Index: include/clang/Lex/HeaderSearchOptions.h === --- include/clang/Lex/HeaderSearchOptions.h +++ include/clang/Lex/HeaderSearchOptions.h @@ -203,34 +203,35 @@ unsigned ModulesHashContent : 1; - HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), -ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), -UseBuiltinIncludes(true), UseStandardSystemIncludes(true), -UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), + HeaderSearchOptions(std::string _Sysroot = "/") + : Sysroot(std::move(_Sysroot)), ModuleFormat("raw"), +DisableModuleHash(false), ImplicitModuleMaps(false), +ModuleMapFileHomeIsCwd(false), UseBuiltinIncludes(true), +UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), +UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), ModulesValidateSystemHeaders(false), UseDebugInfo(false), ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. - void AddPath(StringRef Path, frontend::IncludeDirGroup Group, + void AddPath(std::string Path, frontend::IncludeDirGroup Group, bool IsFramework, bool IgnoreSysRoot) { -UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot); +UserEntries.emplace_back(std::move(Path), Group, IsFramework, IgnoreSysRoot); } /// AddSystemHeaderPrefix - Override whether \#include directives naming a /// path starting with \p Prefix should be considered as naming a system /// header. - void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { -SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader); + void AddSystemHeaderPrefix(std::string Prefix, bool IsSystemHeader) { +SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader); } - void AddVFSOverlayFile(StringRef Name) { -VFSOverlayFiles.push_back(Name); + void AddVFSOverlayFile(std::string Name) { +VFSOverlayFiles.emplace_back(std::move(Name)); } - void AddPrebuiltModulePath(StringRef Name) { -PrebuiltModulePaths.push_back(Name); + void AddPrebuiltModulePath(std::string Name) { +PrebuiltModulePaths.emplace_back(std::move(Name)); } }; Index: include/clang/Lex/HeaderSearchOptions.h === --- include/clang/Lex/HeaderSearchOptions.h +++ include/clang/Lex/HeaderSearchOptions.h @@ -203,34 +203,35 @@ unsigned ModulesHashContent : 1; - HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), -ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), -UseBuiltinIncludes(true), UseStandardSystemIncludes(true), -UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), + HeaderSearchOptions(std::string _Sysroot = "/") + : Sysroot(std::move(_Sysroot)), ModuleFormat("raw"), +DisableModuleHash(false), ImplicitModuleMaps(false), +ModuleMapFileHomeIsCwd(false), UseBuiltinIncludes(true), +UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), +UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), ModulesValidateSystemHeaders(false), UseDebugInfo(false), ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. - void AddPath(StringRef Path, frontend::IncludeDirGroup Group, + void AddPath(std::string Path, frontend::IncludeDirGroup Group, bool IsFramework, bool IgnoreSysRoot) { -UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot); +UserEntries.emplace_back(std::move(Path), Group, IsFramework, IgnoreSysRoot); } /// AddSystemHeaderPrefix - Override whether \#include directives naming a /// path starting with \p Prefix should be considered as naming a system /// header. - void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { -SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader); + void AddSystemHeaderPrefix(std::string Prefix, bool IsSystemHeader) { +SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader); } - void AddVFSOverlayFile(StringRef Name) { -VFSOverlayFiles.push_back(Name); + void AddVFSOverlayFile(std::strin
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
marsupial updated this revision to Diff 108676. marsupial added a comment. Use include guards, not pragma once and remove commented CMake debug lines. https://reviews.llvm.org/D35103 Files: examples/clang-interpreter/CMakeLists.txt examples/clang-interpreter/Invoke.cpp examples/clang-interpreter/Invoke.h examples/clang-interpreter/Manager.cpp examples/clang-interpreter/Manager.h examples/clang-interpreter/README.txt examples/clang-interpreter/Test.cxx examples/clang-interpreter/main.cpp Index: examples/clang-interpreter/main.cpp === --- examples/clang-interpreter/main.cpp +++ examples/clang-interpreter/main.cpp @@ -7,6 +7,9 @@ // //===--===// +#include "Invoke.h" +#include "Manager.h" + #include "clang/CodeGen/CodeGenAction.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/Compilation.h" @@ -26,73 +29,61 @@ #include "llvm/Support/Path.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" -#include + using namespace clang; using namespace clang::driver; +namespace interpreter { + +static llvm::ExecutionEngine * +createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) { + llvm::EngineBuilder EB(std::move(M)); + EB.setErrorStr(ErrorStr); + EB.setMemoryManager(llvm::make_unique()); + llvm::ExecutionEngine *EE = EB.create(); + EE->finalizeObject(); + return EE; +} + +// Invoked from a try/catch block in invoke.cpp. +// +static int Invoke(llvm::ExecutionEngine *EE, llvm::Function *EntryFn, + const std::vector &Args, char *const *EnvP) { + return EE->runFunctionAsMain(EntryFn, Args, EnvP); +} + // This function isn't referenced outside its translation unit, but it // can't use the "static" keyword because its address is used for // GetMainExecutable (since some platforms don't support taking the // address of main, and some platforms can't implement GetMainExecutable // without being given the address of a function in the main executable). -std::string GetExecutablePath(const char *Argv0) { - // This just needs to be some symbol in the binary; C++ doesn't - // allow taking the address of ::main however. - void *MainAddr = (void*) (intptr_t) GetExecutablePath; +std::string GetExecutablePath(const char *Argv0, void *MainAddr) { return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); } -static llvm::ExecutionEngine * -createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) { - return llvm::EngineBuilder(std::move(M)) - .setEngineKind(llvm::EngineKind::Either) - .setErrorStr(ErrorStr) - .create(); -} - -static int Execute(std::unique_ptr Mod, char *const *envp) { - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); - - llvm::Module &M = *Mod; - std::string Error; - std::unique_ptr EE( - createExecutionEngine(std::move(Mod), &Error)); - if (!EE) { -llvm::errs() << "unable to make execution engine: " << Error << "\n"; -return 255; - } - - llvm::Function *EntryFn = M.getFunction("main"); - if (!EntryFn) { -llvm::errs() << "'main' function not found in module.\n"; -return 255; - } - - // FIXME: Support passing arguments. - std::vector Args; - Args.push_back(M.getModuleIdentifier()); - - EE->finalizeObject(); - return EE->runFunctionAsMain(EntryFn, Args, envp); -} +} // namespace interpreter int main(int argc, const char **argv, char * const *envp) { - void *MainAddr = (void*) (intptr_t) GetExecutablePath; - std::string Path = GetExecutablePath(argv[0]); + // This just needs to be some symbol in the binary; C++ doesn't + // allow taking the address of ::main however. + void *MainAddr = (void*) (intptr_t) interpreter::GetExecutablePath; + std::string Path = interpreter::GetExecutablePath(argv[0], MainAddr); IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); - // Use ELF on windows for now. - std::string TripleStr = llvm::sys::getProcessTriple(); + const std::string TripleStr = llvm::sys::getProcessTriple(); llvm::Triple T(TripleStr); + + // Use ELF on Windows-32 and MingW for now. +#ifndef CLANG_INTERPRETER_COFF_FORMAT if (T.isOSBinFormatCOFF()) T.setObjectFormat(llvm::Triple::ELF); - +#endif + Driver TheDriver(Path, T.str(), Diags); TheDriver.setTitle("clang interpreter"); TheDriver.setCheckInputsExist(false); @@ -163,12 +154,36 @@ if (!Clang.ExecuteAction(*Act)) return 1; + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmPrinter(); + int Res = 255; - if (std::unique_ptr Module = Act->takeModule()) -Res = Execute(std::move(Module), envp); + if (std::unique_ptr Module = Act->takeModule()) { +llvm::Func
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
marsupial marked 3 inline comments as done. marsupial added a comment. Done, thanks. Would it be possible to look at https://reviews.llvm.org/D30709 as this depends on that. (ELF does not like Windows exceptions). https://reviews.llvm.org/D35103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36701: Use Token::isOneOf method in Parser.
marsupial created this revision. Easier to read and possibly optimize. https://reviews.llvm.org/D36701 Files: include/clang/Parse/Parser.h Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -355,15 +355,15 @@ /// isTokenParen - Return true if the cur token is '(' or ')'. bool isTokenParen() const { -return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren; +return Tok.isOneOf(tok::l_paren, tok::r_paren); } /// isTokenBracket - Return true if the cur token is '[' or ']'. bool isTokenBracket() const { -return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square; +return Tok.isOneOf(tok::l_square, tok::r_square); } /// isTokenBrace - Return true if the cur token is '{' or '}'. bool isTokenBrace() const { -return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace; +return Tok.isOneOf(tok::l_brace, tok::r_brace); } /// isTokenStringLiteral - True if this token is a string-literal. bool isTokenStringLiteral() const { Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -355,15 +355,15 @@ /// isTokenParen - Return true if the cur token is '(' or ')'. bool isTokenParen() const { -return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren; +return Tok.isOneOf(tok::l_paren, tok::r_paren); } /// isTokenBracket - Return true if the cur token is '[' or ']'. bool isTokenBracket() const { -return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square; +return Tok.isOneOf(tok::l_square, tok::r_square); } /// isTokenBrace - Return true if the cur token is '{' or '}'. bool isTokenBrace() const { -return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace; +return Tok.isOneOf(tok::l_brace, tok::r_brace); } /// isTokenStringLiteral - True if this token is a string-literal. bool isTokenStringLiteral() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36702: Make Parser::Consume*Token methods public.
marsupial created this revision. The fix in r303372 exposed a problem when using **Parser::ConsumeToken** from client code in DEBUG. **ConsumeToken** will assert for all **isTokenSpecial()** cases, but there is no way to call the proper method. The isToken methods are just convenient. https://reviews.llvm.org/D36702 Files: include/clang/Parse/Parser.h Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -348,11 +348,6 @@ return Actions.getNullabilityKeyword(nullability); } -private: - //======// - // Low-Level token peeking and consumption methods. - // - /// isTokenParen - Return true if the cur token is '(' or ')'. bool isTokenParen() const { return Tok.isOneOf(tok::l_paren, tok::r_paren); @@ -375,19 +370,6 @@ isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation(); } - /// \brief Returns true if the current token is '=' or is a type of '='. - /// For typos, give a fixit to '=' - bool isTokenEqualOrEqualTypo(); - - /// \brief Return the current token to the token stream and make the given - /// token the current token. - void UnconsumeToken(Token &Consumed) { - Token Next = Tok; - PP.EnterToken(Consumed); - PP.Lex(Tok); - PP.EnterToken(Next); - } - /// ConsumeAnyToken - Dispatch to the right Consume* method based on the /// current token type. This should only be used in cases where the type of /// the token really isn't known, e.g. in error recovery. @@ -481,6 +463,24 @@ return PrevTokLocation; } +private: + //======// + // Low-Level token peeking and consumption methods. + // + + /// \brief Returns true if the current token is '=' or is a type of '='. + /// For typos, give a fixit to '=' + bool isTokenEqualOrEqualTypo(); + + /// \brief Return the current token to the token stream and make the given + /// token the current token. + void UnconsumeToken(Token &Consumed) { + Token Next = Tok; + PP.EnterToken(Consumed); + PP.Lex(Tok); + PP.EnterToken(Next); + } + ///\ brief When we are consuming a code-completion token without having /// matched specific position in the grammar, provide code-completion results /// based on context. Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -348,11 +348,6 @@ return Actions.getNullabilityKeyword(nullability); } -private: - //======// - // Low-Level token peeking and consumption methods. - // - /// isTokenParen - Return true if the cur token is '(' or ')'. bool isTokenParen() const { return Tok.isOneOf(tok::l_paren, tok::r_paren); @@ -375,19 +370,6 @@ isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation(); } - /// \brief Returns true if the current token is '=' or is a type of '='. - /// For typos, give a fixit to '=' - bool isTokenEqualOrEqualTypo(); - - /// \brief Return the current token to the token stream and make the given - /// token the current token. - void UnconsumeToken(Token &Consumed) { - Token Next = Tok; - PP.EnterToken(Consumed); - PP.Lex(Tok); - PP.EnterToken(Next); - } - /// ConsumeAnyToken - Dispatch to the right Consume* method based on the /// current token type. This should only be used in cases where the type of /// the token really isn't known, e.g. in error recovery. @@ -481,6 +463,24 @@ return PrevTokLocation; } +private: + //======// + // Low-Level token peeking and consumption methods. + // + + /// \brief Returns true if the current token is '=' or is a type of '='. + /// For typos, give a fixit to '=' + bool isTokenEqualOrEqualTypo(); + + /// \brief Return the current token to the token stream and make the given + /// token the current token. + void UnconsumeToken(Token &Consumed) { + Token Next = Tok; + PP.EnterToken(Consumed); + PP.Lex(Tok); + PP.EnterToken(Next); + } + ///\ brief When we are consuming a code-completion token without having /// matched specific position in the grammar, provide code-completion results /// based on context. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29923: PPCallbacks::MacroUndefined, change signature and add test.
marsupial added a comment. ping https://reviews.llvm.org/D29923 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33659: Extend DynamicLibrary class to be usable without loading permanently.
marsupial updated this revision to Diff 105466. https://reviews.llvm.org/D33659 Files: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp === --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -53,23 +53,23 @@ i != e; ++i) { // Get access to the plugin. std::string err; -DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); -if (!lib.isValid()) { +DynamicLibrary *lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); +if (!lib) { diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err; continue; } // See if it's compatible with this build of clang. const char *pluginAPIVersion = - (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString"); + (const char *) lib->getAddressOfSymbol("clang_analyzerAPIVersionString"); if (!isCompatibleAPIVersion(pluginAPIVersion)) { warnIncompatible(diags, *i, pluginAPIVersion); continue; } // Register its checkers. RegisterCheckersFn registerPluginCheckers = - (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol( + (RegisterCheckersFn) (intptr_t) lib->getAddressOfSymbol( "clang_registerCheckers"); if (registerPluginCheckers) registerPluginCheckers(*this); Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp === --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -53,23 +53,23 @@ i != e; ++i) { // Get access to the plugin. std::string err; -DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); -if (!lib.isValid()) { +DynamicLibrary *lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err); +if (!lib) { diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err; continue; } // See if it's compatible with this build of clang. const char *pluginAPIVersion = - (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString"); + (const char *) lib->getAddressOfSymbol("clang_analyzerAPIVersionString"); if (!isCompatibleAPIVersion(pluginAPIVersion)) { warnIncompatible(diags, *i, pluginAPIVersion); continue; } // Register its checkers. RegisterCheckersFn registerPluginCheckers = - (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol( + (RegisterCheckersFn) (intptr_t) lib->getAddressOfSymbol( "clang_registerCheckers"); if (registerPluginCheckers) registerPluginCheckers(*this); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33659: Extend DynamicLibrary class to be usable without loading permanently.
marsupial added a comment. ping https://reviews.llvm.org/D33659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
marsupial created this revision. Herald added a subscriber: mgorny. Getting this to work is not particularly obvious, and having it as an example should be helpful. Portions of this could be placed into LLVM, but as a whole it seems necessary to do this a higher level. https://reviews.llvm.org/D35103 Files: examples/clang-interpreter/CMakeLists.txt examples/clang-interpreter/Invoke.cpp examples/clang-interpreter/Invoke.h examples/clang-interpreter/Manager.cpp examples/clang-interpreter/Manager.h examples/clang-interpreter/README.txt examples/clang-interpreter/Test.cxx examples/clang-interpreter/main.cpp Index: examples/clang-interpreter/main.cpp === --- examples/clang-interpreter/main.cpp +++ examples/clang-interpreter/main.cpp @@ -7,6 +7,9 @@ // //===--===// +#include "Invoke.h" +#include "Manager.h" + #include "clang/CodeGen/CodeGenAction.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/Compilation.h" @@ -26,73 +29,61 @@ #include "llvm/Support/Path.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" -#include + using namespace clang; using namespace clang::driver; +namespace interpreter { + +static llvm::ExecutionEngine * +createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) { + llvm::EngineBuilder EB(std::move(M)); + EB.setErrorStr(ErrorStr); + EB.setMemoryManager(llvm::make_unique()); + llvm::ExecutionEngine *EE = EB.create(); + EE->finalizeObject(); + return EE; +} + +// Invoked from a try/catch block in invoke.cpp. +// +static int Invoke(llvm::ExecutionEngine *EE, llvm::Function *EntryFn, + const std::vector &Args, char *const *EnvP) { + return EE->runFunctionAsMain(EntryFn, Args, EnvP); +} + // This function isn't referenced outside its translation unit, but it // can't use the "static" keyword because its address is used for // GetMainExecutable (since some platforms don't support taking the // address of main, and some platforms can't implement GetMainExecutable // without being given the address of a function in the main executable). -std::string GetExecutablePath(const char *Argv0) { - // This just needs to be some symbol in the binary; C++ doesn't - // allow taking the address of ::main however. - void *MainAddr = (void*) (intptr_t) GetExecutablePath; +std::string GetExecutablePath(const char *Argv0, void *MainAddr) { return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); } -static llvm::ExecutionEngine * -createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) { - return llvm::EngineBuilder(std::move(M)) - .setEngineKind(llvm::EngineKind::Either) - .setErrorStr(ErrorStr) - .create(); -} - -static int Execute(std::unique_ptr Mod, char *const *envp) { - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); - - llvm::Module &M = *Mod; - std::string Error; - std::unique_ptr EE( - createExecutionEngine(std::move(Mod), &Error)); - if (!EE) { -llvm::errs() << "unable to make execution engine: " << Error << "\n"; -return 255; - } - - llvm::Function *EntryFn = M.getFunction("main"); - if (!EntryFn) { -llvm::errs() << "'main' function not found in module.\n"; -return 255; - } - - // FIXME: Support passing arguments. - std::vector Args; - Args.push_back(M.getModuleIdentifier()); - - EE->finalizeObject(); - return EE->runFunctionAsMain(EntryFn, Args, envp); -} +} // namespace interpreter int main(int argc, const char **argv, char * const *envp) { - void *MainAddr = (void*) (intptr_t) GetExecutablePath; - std::string Path = GetExecutablePath(argv[0]); + // This just needs to be some symbol in the binary; C++ doesn't + // allow taking the address of ::main however. + void *MainAddr = (void*) (intptr_t) interpreter::GetExecutablePath; + std::string Path = interpreter::GetExecutablePath(argv[0], MainAddr); IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); - // Use ELF on windows for now. - std::string TripleStr = llvm::sys::getProcessTriple(); + const std::string TripleStr = llvm::sys::getProcessTriple(); llvm::Triple T(TripleStr); + + // Use ELF on Windows-32 for now. +#if defined(_WIN32) && !defined(_WIN64) if (T.isOSBinFormatCOFF()) T.setObjectFormat(llvm::Triple::ELF); - +#endif + Driver TheDriver(Path, T.str(), Diags); TheDriver.setTitle("clang interpreter"); TheDriver.setCheckInputsExist(false); @@ -163,12 +154,36 @@ if (!Clang.ExecuteAction(*Act)) return 1; + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmPrinter(); + int Res = 255; - if (std::unique_ptr Module = Act->takeModule())
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
marsupial updated this revision to Diff 106548. marsupial added a comment. Blocked Win64 SEH for MingW entirely. Theoretically it should be possible to throw a SEH from within mingw, but but I'm thinking clang may be generating exception handlers for the gcc runtime in that case. I'll leave it up to someone with interest in such a mixture to figure that tout. https://reviews.llvm.org/D35103 Files: examples/clang-interpreter/CMakeLists.txt examples/clang-interpreter/Invoke.cpp examples/clang-interpreter/Invoke.h examples/clang-interpreter/Manager.cpp examples/clang-interpreter/Manager.h examples/clang-interpreter/README.txt examples/clang-interpreter/Test.cxx examples/clang-interpreter/main.cpp Index: examples/clang-interpreter/main.cpp === --- examples/clang-interpreter/main.cpp +++ examples/clang-interpreter/main.cpp @@ -7,6 +7,9 @@ // //===--===// +#include "Invoke.h" +#include "Manager.h" + #include "clang/CodeGen/CodeGenAction.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/Compilation.h" @@ -26,73 +29,61 @@ #include "llvm/Support/Path.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" -#include + using namespace clang; using namespace clang::driver; +namespace interpreter { + +static llvm::ExecutionEngine * +createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) { + llvm::EngineBuilder EB(std::move(M)); + EB.setErrorStr(ErrorStr); + EB.setMemoryManager(llvm::make_unique()); + llvm::ExecutionEngine *EE = EB.create(); + EE->finalizeObject(); + return EE; +} + +// Invoked from a try/catch block in invoke.cpp. +// +static int Invoke(llvm::ExecutionEngine *EE, llvm::Function *EntryFn, + const std::vector &Args, char *const *EnvP) { + return EE->runFunctionAsMain(EntryFn, Args, EnvP); +} + // This function isn't referenced outside its translation unit, but it // can't use the "static" keyword because its address is used for // GetMainExecutable (since some platforms don't support taking the // address of main, and some platforms can't implement GetMainExecutable // without being given the address of a function in the main executable). -std::string GetExecutablePath(const char *Argv0) { - // This just needs to be some symbol in the binary; C++ doesn't - // allow taking the address of ::main however. - void *MainAddr = (void*) (intptr_t) GetExecutablePath; +std::string GetExecutablePath(const char *Argv0, void *MainAddr) { return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); } -static llvm::ExecutionEngine * -createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) { - return llvm::EngineBuilder(std::move(M)) - .setEngineKind(llvm::EngineKind::Either) - .setErrorStr(ErrorStr) - .create(); -} - -static int Execute(std::unique_ptr Mod, char *const *envp) { - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); - - llvm::Module &M = *Mod; - std::string Error; - std::unique_ptr EE( - createExecutionEngine(std::move(Mod), &Error)); - if (!EE) { -llvm::errs() << "unable to make execution engine: " << Error << "\n"; -return 255; - } - - llvm::Function *EntryFn = M.getFunction("main"); - if (!EntryFn) { -llvm::errs() << "'main' function not found in module.\n"; -return 255; - } - - // FIXME: Support passing arguments. - std::vector Args; - Args.push_back(M.getModuleIdentifier()); - - EE->finalizeObject(); - return EE->runFunctionAsMain(EntryFn, Args, envp); -} +} // namespace interpreter int main(int argc, const char **argv, char * const *envp) { - void *MainAddr = (void*) (intptr_t) GetExecutablePath; - std::string Path = GetExecutablePath(argv[0]); + // This just needs to be some symbol in the binary; C++ doesn't + // allow taking the address of ::main however. + void *MainAddr = (void*) (intptr_t) interpreter::GetExecutablePath; + std::string Path = interpreter::GetExecutablePath(argv[0], MainAddr); IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); - // Use ELF on windows for now. - std::string TripleStr = llvm::sys::getProcessTriple(); + const std::string TripleStr = llvm::sys::getProcessTriple(); llvm::Triple T(TripleStr); + + // Use ELF on Windows-32 and MingW for now. +#ifndef CLANG_INTERPRETER_COFF_FORMAT if (T.isOSBinFormatCOFF()) T.setObjectFormat(llvm::Triple::ELF); - +#endif + Driver TheDriver(Path, T.str(), Diags); TheDriver.setTitle("clang interpreter"); TheDriver.setCheckInputsExist(false); @@ -163,12 +154,36 @@ if (!Clang.ExecuteAction(*Act)) return 1; + llvm::InitializeNativeTarget(); + llvm::Initial
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
marsupial marked 3 inline comments as done. marsupial added a comment. Done, and changed to 'windows.h', but blocked mingw from even attempting SEH for now. https://reviews.llvm.org/D35103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.
marsupial added a comment. Ping. https://reviews.llvm.org/D35103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30107: Make DynamicLibrary::getPermanentLibrary on Windows have a defined ordering.
marsupial created this revision. This is mostly affecting usage of the JIT... When using DynamicLibrary::getPermanentLibrary(0,0) to get a list of the loaded libs, on Windows this is currently stored in a set which makes iteration unordered / undefined. Additionally there is a problem as newer Windows are using ucrt.dll for a lot of stdlib functions which cause a disagreement between the JIT and native code as to what the address and implementation of that function is: JIT: putenv_s("TEST", "VALUE") calls msvcrt.dll, putenv_s JIT: getenv("TEST") -> "VALUE" calls msvcrt.dll, getenv BIN: getenv("TEST") -> NULL // calls ucrt.dll, getenv The patch simply changes the way modules are loaded and stored to how Windows says they were. Searches for symbols in reverse order so newer modules will override older ones. And always tries to give priority to the process' symbols (what dlsym does I believe) https://reviews.llvm.org/D30107 Files: lib/Support/Windows/DynamicLibrary.inc Index: lib/Support/Windows/DynamicLibrary.inc === --- lib/Support/Windows/DynamicLibrary.inc +++ lib/Support/Windows/DynamicLibrary.inc @@ -12,16 +12,18 @@ //===--===// #include "WindowsSupport.h" +#include "llvm/ADT/iterator_range.h" #ifdef __MINGW32__ #include #else - #include + #include #endif #ifdef _MSC_VER #include #endif +#include namespace llvm { using namespace sys; @@ -31,25 +33,9 @@ //=== and must not be UNIX code. //===--===// -typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID); -static fpEnumerateLoadedModules fEnumerateLoadedModules; -static DenseSet *OpenedHandles; - -static bool loadDebugHelp(void) { - HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll"); - if (hLib) { -fEnumerateLoadedModules = (fpEnumerateLoadedModules) - ::GetProcAddress(hLib, "EnumerateLoadedModules64"); - } - return fEnumerateLoadedModules != 0; -} - -static BOOL CALLBACK -ELM_Callback(PCSTR ModuleName, DWORD64 ModuleBase, - ULONG ModuleSize, PVOID UserContext) { - OpenedHandles->insert((HMODULE)ModuleBase); - return TRUE; -} +typedef std::vector ModuleHandles; +static std::unique_ptr OpenedHandles; +static bool KeepFront; DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, std::string *errMsg) { @@ -57,20 +43,58 @@ if (!filename) { // When no file is specified, enumerate all DLLs and EXEs in the process. -if (OpenedHandles == 0) - OpenedHandles = new DenseSet(); -if (!fEnumerateLoadedModules) { - if (!loadDebugHelp()) { -assert(false && "These APIs should always be available"); +#ifdef _WIN64 +const DWORD Flags = LIST_MODULES_64BIT; +#else +const DWORD Flags = LIST_MODULES_32BIT; +#endif + +DWORD Bytes; +HMODULE Self = (HMODULE)GetCurrentProcess(); +if (!EnumProcessModulesEx(Self, nullptr, 0, &Bytes, Flags)) { + MakeErrMsg(errMsg, "EnumProcessModulesEx failure"); + return DynamicLibrary(); +} + +// Get the most recent list in case any modules added between calls. +ModuleHandles Current; +do { + assert(Bytes && ((Bytes % sizeof(HMODULE)) == 0) && + "Should have at least one module and be aligned"); + Current.resize(Bytes / sizeof(HMODULE)); + if (!EnumProcessModulesEx(Self, Current.data(), Bytes, &Bytes, Flags)) { +MakeErrMsg(errMsg, "EnumProcessModulesEx failure"); return DynamicLibrary(); } +} while (Bytes != (Current.size() * sizeof(HMODULE))); + +#ifndef NDEBUG +if (OpenedHandles) { + auto Begin = Current.begin(), End = Current.end(); + for (HMODULE Mod : *OpenedHandles) { +assert((std::find(Begin, End, Mod) != End) && + "Module in older list that is not in newer one"); + } } +#endif + +// Keep current process handle at top of list +if (Current.size() > 1) { + Self = Current.front(); + memmove(Current.data(), Current.data()+1, Bytes - sizeof(HMODULE)); + Current.back() = Self; +} +KeepFront = true; + +if (!OpenedHandles) + OpenedHandles.reset(new ModuleHandles(std::move(Current))); +else + OpenedHandles->swap(Current); -fEnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); // Dummy library that represents "search all handles". // This is mostly to ensure that the return value still shows up as "valid". -return DynamicLibrary(&OpenedHandles); +return DynamicLibrary(OpenedHandles.get()); } SmallVector filenameUnicode; @@ -79,7 +103,7 @@ MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16"); return DynamicLibrary(); } - + HMODULE a_handle = LoadLibraryW(filenameUnic
[PATCH] D29923: Send UndefMacroDirective to MacroDefined callback
marsupial added a comment. ping https://reviews.llvm.org/D29923 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29923: Add test for PPCallbacks::MacroUndefined
marsupial updated this revision to Diff 91563. marsupial retitled this revision from "Send UndefMacroDirective to MacroDefined callback" to "Add test for PPCallbacks::MacroUndefined". marsupial edited the summary of this revision. https://reviews.llvm.org/D29923 Files: unittests/Basic/SourceManagerTest.cpp Index: unittests/Basic/SourceManagerTest.cpp === --- unittests/Basic/SourceManagerTest.cpp +++ unittests/Basic/SourceManagerTest.cpp @@ -246,12 +246,18 @@ namespace { struct MacroAction { + enum Kind { kDefinition, kUnDefinition, kExpansion}; + SourceLocation Loc; std::string Name; - bool isDefinition; // if false, it is expansion. - - MacroAction(SourceLocation Loc, StringRef Name, bool isDefinition) -: Loc(Loc), Name(Name), isDefinition(isDefinition) { } + unsigned MAKind : 2; + + MacroAction(SourceLocation Loc, StringRef Name, unsigned K) +: Loc(Loc), Name(Name), MAKind(K) { } + + bool isExpansion() const { return MAKind == kExpansion; } + bool isDefinition() const { return MAKind == kDefinition; } + bool isUnDefinition() const { return MAKind == kUnDefinition; } }; class MacroTracker : public PPCallbacks { @@ -264,21 +270,29 @@ const MacroDirective *MD) override { Macros.push_back(MacroAction(MD->getLocation(), MacroNameTok.getIdentifierInfo()->getName(), - true)); + MacroAction::kDefinition)); + } + void MacroUndefined(const Token &MacroNameTok, + const MacroDefinition &MD) override { +Macros.push_back(MacroAction(MD.getMacroInfo()->getDefinitionLoc(), + MacroNameTok.getIdentifierInfo()->getName(), + MacroAction::kUnDefinition)); } void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { Macros.push_back(MacroAction(MacroNameTok.getLocation(), MacroNameTok.getIdentifierInfo()->getName(), - false)); + MacroAction::kExpansion)); } }; } TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) { const char *header = -"#define MACRO_IN_INCLUDE 0\n"; +"#define MACRO_IN_INCLUDE 0\n" +"#define MACRO_DEFINED\n" +"#undef MACRO_DEFINED\n"; const char *main = "#define M(x) x\n" @@ -323,42 +337,50 @@ // Make sure we got the tokens that we expected. ASSERT_EQ(0U, toks.size()); - ASSERT_EQ(9U, Macros.size()); + ASSERT_EQ(13U, Macros.size()); // #define M(x) x - ASSERT_TRUE(Macros[0].isDefinition); + ASSERT_TRUE(Macros[0].isDefinition()); ASSERT_EQ("M", Macros[0].Name); // #define INC "/test-header.h" - ASSERT_TRUE(Macros[1].isDefinition); + ASSERT_TRUE(Macros[1].isDefinition()); ASSERT_EQ("INC", Macros[1].Name); // M expansion in #include M(INC) - ASSERT_FALSE(Macros[2].isDefinition); + ASSERT_FALSE(Macros[2].isDefinition()); ASSERT_EQ("M", Macros[2].Name); // INC expansion in #include M(INC) - ASSERT_FALSE(Macros[3].isDefinition); + ASSERT_TRUE(Macros[3].isExpansion()); ASSERT_EQ("INC", Macros[3].Name); // #define MACRO_IN_INCLUDE 0 - ASSERT_TRUE(Macros[4].isDefinition); + ASSERT_TRUE(Macros[4].isDefinition()); ASSERT_EQ("MACRO_IN_INCLUDE", Macros[4].Name); + // #define MACRO_DEFINED + ASSERT_TRUE(Macros[5].isDefinition()); + ASSERT_FALSE(Macros[5].isUnDefinition()); + ASSERT_EQ("MACRO_DEFINED", Macros[5].Name); + // #undef MACRO_DEFINED + ASSERT_FALSE(Macros[6].isDefinition()); + ASSERT_TRUE(Macros[6].isUnDefinition()); + ASSERT_EQ("MACRO_DEFINED", Macros[6].Name); // #define INC2 - ASSERT_TRUE(Macros[5].isDefinition); - ASSERT_EQ("INC2", Macros[5].Name); + ASSERT_TRUE(Macros[7].isDefinition()); + ASSERT_EQ("INC2", Macros[7].Name); // M expansion in #include M(INC2) - ASSERT_FALSE(Macros[6].isDefinition); - ASSERT_EQ("M", Macros[6].Name); + ASSERT_FALSE(Macros[8].isDefinition()); + ASSERT_EQ("M", Macros[8].Name); // INC2 expansion in #include M(INC2) - ASSERT_FALSE(Macros[7].isDefinition); - ASSERT_EQ("INC2", Macros[7].Name); + ASSERT_TRUE(Macros[9].isExpansion()); + ASSERT_EQ("INC2", Macros[9].Name); // #define MACRO_IN_INCLUDE 0 - ASSERT_TRUE(Macros[8].isDefinition); - ASSERT_EQ("MACRO_IN_INCLUDE", Macros[8].Name); + ASSERT_TRUE(Macros[10].isDefinition()); + ASSERT_EQ("MACRO_IN_INCLUDE", Macros[10].Name); // The INC expansion in #include M(INC) comes before the first // MACRO_IN_INCLUDE definition of the included file. EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[3].Loc, Macros[4].Loc)); // The INC2 expansion in #include M(INC2) comes before the second // MACRO_IN_INCLUDE definition of the included file. - EXPECT_TRUE(SourceMgr.isBeforeIn
[PATCH] D29923: PPCallbacks::MacroUndefined, change signature and add test.
marsupial updated this revision to Diff 91627. marsupial retitled this revision from "Add test for PPCallbacks::MacroUndefined" to "PPCallbacks::MacroUndefined, change signature and add test.". marsupial edited the summary of this revision. Herald added a subscriber: nemanjai. https://reviews.llvm.org/D29923 Files: include/clang/Lex/PPCallbacks.h include/clang/Lex/PreprocessingRecord.h lib/Frontend/PrintPreprocessedOutput.cpp lib/Lex/PPDirectives.cpp lib/Lex/PreprocessingRecord.cpp tools/libclang/Indexing.cpp unittests/Basic/SourceManagerTest.cpp Index: unittests/Basic/SourceManagerTest.cpp === --- unittests/Basic/SourceManagerTest.cpp +++ unittests/Basic/SourceManagerTest.cpp @@ -246,12 +246,18 @@ namespace { struct MacroAction { + enum Kind { kExpansion, kDefinition, kUnDefinition}; + SourceLocation Loc; std::string Name; - bool isDefinition; // if false, it is expansion. - - MacroAction(SourceLocation Loc, StringRef Name, bool isDefinition) -: Loc(Loc), Name(Name), isDefinition(isDefinition) { } + unsigned MAKind : 3; + + MacroAction(SourceLocation Loc, StringRef Name, unsigned K) +: Loc(Loc), Name(Name), MAKind(K) { } + + bool isExpansion() const { return MAKind == kExpansion; } + bool isDefinition() const { return MAKind & kDefinition; } + bool isUnDefinition() const { return MAKind & kUnDefinition; } }; class MacroTracker : public PPCallbacks { @@ -264,21 +270,33 @@ const MacroDirective *MD) override { Macros.push_back(MacroAction(MD->getLocation(), MacroNameTok.getIdentifierInfo()->getName(), - true)); + MacroAction::kDefinition)); + } + void MacroUndefined(const Token &MacroNameTok, + const MacroDefinition &MD, + const MacroDirective *UD) override { +Macros.push_back( +MacroAction(UD ? UD->getLocation() : SourceLocation(), +MacroNameTok.getIdentifierInfo()->getName(), +UD ? MacroAction::kDefinition | MacroAction::kUnDefinition + : MacroAction::kUnDefinition)); } void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { Macros.push_back(MacroAction(MacroNameTok.getLocation(), MacroNameTok.getIdentifierInfo()->getName(), - false)); + MacroAction::kExpansion)); } }; } TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) { const char *header = -"#define MACRO_IN_INCLUDE 0\n"; +"#define MACRO_IN_INCLUDE 0\n" +"#define MACRO_DEFINED\n" +"#undef MACRO_DEFINED\n" +"#undef MACRO_UNDEFINED\n"; const char *main = "#define M(x) x\n" @@ -323,42 +341,54 @@ // Make sure we got the tokens that we expected. ASSERT_EQ(0U, toks.size()); - ASSERT_EQ(9U, Macros.size()); + ASSERT_EQ(15U, Macros.size()); // #define M(x) x - ASSERT_TRUE(Macros[0].isDefinition); + ASSERT_TRUE(Macros[0].isDefinition()); ASSERT_EQ("M", Macros[0].Name); // #define INC "/test-header.h" - ASSERT_TRUE(Macros[1].isDefinition); + ASSERT_TRUE(Macros[1].isDefinition()); ASSERT_EQ("INC", Macros[1].Name); // M expansion in #include M(INC) - ASSERT_FALSE(Macros[2].isDefinition); + ASSERT_FALSE(Macros[2].isDefinition()); ASSERT_EQ("M", Macros[2].Name); // INC expansion in #include M(INC) - ASSERT_FALSE(Macros[3].isDefinition); + ASSERT_TRUE(Macros[3].isExpansion()); ASSERT_EQ("INC", Macros[3].Name); // #define MACRO_IN_INCLUDE 0 - ASSERT_TRUE(Macros[4].isDefinition); + ASSERT_TRUE(Macros[4].isDefinition()); ASSERT_EQ("MACRO_IN_INCLUDE", Macros[4].Name); + // #define MACRO_DEFINED + ASSERT_TRUE(Macros[5].isDefinition()); + ASSERT_FALSE(Macros[5].isUnDefinition()); + ASSERT_EQ("MACRO_DEFINED", Macros[5].Name); + // #undef MACRO_DEFINED + ASSERT_TRUE(Macros[6].isDefinition()); + ASSERT_TRUE(Macros[6].isUnDefinition()); + ASSERT_EQ("MACRO_DEFINED", Macros[6].Name); + // #undef MACRO_UNDEFINED + ASSERT_FALSE(Macros[7].isDefinition()); + ASSERT_TRUE(Macros[7].isUnDefinition()); + ASSERT_EQ("MACRO_UNDEFINED", Macros[7].Name); // #define INC2 - ASSERT_TRUE(Macros[5].isDefinition); - ASSERT_EQ("INC2", Macros[5].Name); + ASSERT_TRUE(Macros[8].isDefinition()); + ASSERT_EQ("INC2", Macros[8].Name); // M expansion in #include M(INC2) - ASSERT_FALSE(Macros[6].isDefinition); - ASSERT_EQ("M", Macros[6].Name); + ASSERT_FALSE(Macros[9].isDefinition()); + ASSERT_EQ("M", Macros[9].Name); // INC2 expansion in #include M(INC2) - ASSERT_FALSE(Macros[7].isDefinition); - ASSERT_EQ("INC2", Macros[7].Name); + ASSERT_TRUE(Macros[10].isExpansion()); + ASSERT_EQ("INC2", Macros[10].Name); // #de
[PATCH] D29923: PPCallbacks::MacroUndefined, change signature and add test.
This revision was automatically updated to reflect the committed changes. Closed by commit rL301449: PPCallbacks::MacroUndefined, change signature and add test. (authored by marsupial). Changed prior to commit: https://reviews.llvm.org/D29923?vs=91627&id=96808#toc Repository: rL LLVM https://reviews.llvm.org/D29923 Files: cfe/trunk/include/clang/Lex/PPCallbacks.h cfe/trunk/include/clang/Lex/PreprocessingRecord.h cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp cfe/trunk/lib/Lex/PPDirectives.cpp cfe/trunk/lib/Lex/PreprocessingRecord.cpp cfe/trunk/tools/libclang/Indexing.cpp cfe/trunk/unittests/Basic/SourceManagerTest.cpp Index: cfe/trunk/include/clang/Lex/PreprocessingRecord.h === --- cfe/trunk/include/clang/Lex/PreprocessingRecord.h +++ cfe/trunk/include/clang/Lex/PreprocessingRecord.h @@ -488,7 +488,8 @@ void MacroExpands(const Token &Id, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override; void MacroDefined(const Token &Id, const MacroDirective *MD) override; -void MacroUndefined(const Token &Id, const MacroDefinition &MD) override; +void MacroUndefined(const Token &Id, const MacroDefinition &MD, +const MacroDirective *Undef) override; void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, Index: cfe/trunk/include/clang/Lex/PPCallbacks.h === --- cfe/trunk/include/clang/Lex/PPCallbacks.h +++ cfe/trunk/include/clang/Lex/PPCallbacks.h @@ -247,10 +247,14 @@ } /// \brief Hook called whenever a macro \#undef is seen. + /// \param Token The active Token + /// \param MD A MacroDefinition for the named macro. + /// \param Undef New MacroDirective if the macro was defined, null otherwise. /// /// MD is released immediately following this callback. virtual void MacroUndefined(const Token &MacroNameTok, - const MacroDefinition &MD) { + const MacroDefinition &MD, + const MacroDirective *Undef) { } /// \brief Hook called whenever the 'defined' operator is seen. @@ -439,15 +443,17 @@ Second->MacroExpands(MacroNameTok, MD, Range, Args); } - void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override { + void MacroDefined(const Token &MacroNameTok, +const MacroDirective *MD) override { First->MacroDefined(MacroNameTok, MD); Second->MacroDefined(MacroNameTok, MD); } void MacroUndefined(const Token &MacroNameTok, - const MacroDefinition &MD) override { -First->MacroUndefined(MacroNameTok, MD); -Second->MacroUndefined(MacroNameTok, MD); + const MacroDefinition &MD, + const MacroDirective *Undef) override { +First->MacroUndefined(MacroNameTok, MD, Undef); +Second->MacroUndefined(MacroNameTok, MD, Undef); } void Defined(const Token &MacroNameTok, const MacroDefinition &MD, Index: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp === --- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp +++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp @@ -172,7 +172,8 @@ /// MacroUndefined - This hook is called whenever a macro #undef is seen. void MacroUndefined(const Token &MacroNameTok, - const MacroDefinition &MD) override; + const MacroDefinition &MD, + const MacroDirective *Undef) override; }; } // end anonymous namespace @@ -389,7 +390,8 @@ } void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok, - const MacroDefinition &MD) { + const MacroDefinition &MD, + const MacroDirective *Undef) { // Only print out macro definitions in -dD mode. if (!DumpDefines) return; Index: cfe/trunk/lib/Lex/PreprocessingRecord.cpp === --- cfe/trunk/lib/Lex/PreprocessingRecord.cpp +++ cfe/trunk/lib/Lex/PreprocessingRecord.cpp @@ -422,7 +422,8 @@ } void PreprocessingRecord::MacroUndefined(const Token &Id, - const MacroDefinition &MD) { + const MacroDefinition &MD, + const MacroDirective *Undef) { MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); }); } Index: cfe/trunk/lib/Lex/PPDirectives.cpp === --- cfe/trunk/lib/Lex/PPDirecti