とりあえず日記

VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ(いまここ🍄)

久しぶりにclang-interpreterを試してみた

何年も前にC++interpreterであるclang-interpreterを試した記事を書きました。
http://d.hatena.ne.jp/ohtorii/20110716/1310783800
秀丸エディタからclang-interpreterを呼び出してみた - とりあえず日記


当時は、STLWindowsのヘッダファイルを扱うことが出来ない状況でした。
あれからClang/LLVMも相当バージョンアップされてるので、
気まぐれで久しぶりにビルドして動作を試してみました。

結果

相変わらず、STLWindowsのヘッダファイルを扱えないです。
まあ、clang-interpreterはサンプルという位置づけなので真面目に実装されていないのかもしれません。

環境

LLVM 5.0.1
Microsoft Visual Studio Community 2017 Version 15.5.7

ビルド手順

VisualStudio2017でビルドしてclang-interpreter.exeを作ります。
(Clang/LLVMのマニュアルに従えば簡単に実行ファイルを作れます、なのでビルド手順は省略します。)

動かしてみた。(printf)

//sample_0.cpp
include<stdio.h>

int main(int argc, char*argv[]){
	for(int i=0; i!=4 ; ++i){
		printf("i=%d\n",i);
	}
	return 0;
}
> clang-interpreter.exe sample_0.cpp
i=0
i=1
i=2
i=3

おっ、正しく動いています。

動かしてみた。(file i/o)

//sample_1.cpp
#include<stdio.h>

int main(int argc, char*argv[]){
	FILE* fp=fopen("out.txt","wt");
	fprintf(fp,"%s\n","hello clang");
	fprintf(fp,"%s\n","こんにちわ、clang");
	fclose(fp);
	return 0;
}
> clang-interpreter.exe sample_1.cpp
sample_1.cpp:4:11: warning: 'fopen' is deprecated: This function or variable may
      be unsafe. Consider using fopen_s instead. To disable deprecation, use
      _CRT_SECURE_NO_WARNINGS. See online help for details.
      [-Wdeprecated-declarations]
        FILE* fp=fopen("out.txt","wt");
                 ^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\ucrt\stdio.h:206:20: note:
      'fopen' has been explicitly marked deprecated here
    _Check_return_ _CRT_INSECURE_DEPRECATE(fopen_s)
                   ^
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\vcruntime.h:255:55: note:
      expanded from macro '_CRT_INSECURE_DEPRECATE'
        #define _CRT_INSECURE_DEPRECATE(_Replacement) _CRT_DEPRECATE_TEXT(    \
                                                      ^
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\vcruntime.h:245:47: note:
      expanded from macro '_CRT_DEPRECATE_TEXT'
#define _CRT_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))
                                              ^
1 warning generated.
> type out.txt
hello clang
こんにちわ、clang

fopen関数じゃなくてfopen_s関数を使えと警告されましたが正しい結果を得られました。

動かしてみた。(class)

//sample_2.cpp
#include<stdio.h>

template<class T>
class add{
public:
	add(T v) : m_base(v){
	}
	T operator()(T v)const{
		return v + m_base;
	};
private:
	T	m_base;
};

int main(int argc, char*argv[]){
	add<int>	obj(10);
	printf("value=%d\n", obj(20));
	return 0;
}
> clang-interpreter.exe sample_2.cpp
value=30

こちらも、ちゃんと動いています。

動かしてみた。(Global ctor/dtor)

//sample_3.cpp
#include<stdio.h>

class foo{
public:
	foo(){
		printf("ctor\n");
	}
	~foo(){
		printf("dtor\n");
	}
};

foo g;	//  <------- Global ctor/dtor.

int main(int argc, char*argv[]){
	printf("Enter main.\n");
	return 0;
}
> clang-interpreter.exe sample_3.cpp

LLVM ERROR: Undefined temporary symbol

エラーです。

動かしてみた。(STL)

//sample_4.cpp
#include<vector>
int main(int argc, char*argv[]){
	std::vector<int> v;
}
> clang-interpreter.exe sample_4.cpp
LLVM ERROR: Undefined temporary symbol

またまた、エラーです。

動かしてみた。(windows.h)

//sample_5.cpp
#include<windows.h>
int main(int argc, char*argv[]){
    DWORD t=MessageBox(NULL,"foo","bar", MB_OK);
    return 0;
}
>clang-interpreter.exe sample_5.cpp
In file included from sample_5.cpp:1:
In file included from C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um\windows.h:171:
In file included from C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\shared\windef.h:24:
In file included from C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\shared\minwindef.h:182:
C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um\winnt.h:959:5: error:
      MS-style inline assembly is not available: Unable to find target for this
      triple (no targets are registered)
    __asm    {
    ^
C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um\winnt.h:975:5: error:
      MS-style inline assembly is not available: Unable to find target for this
      triple (no targets are registered)
    __asm {
    ^
C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um\winnt.h:991:5: error:
      MS-style inline assembly is not available: Unable to find target for this
      triple (no targets are registered)
    __asm    {
    ^
3 errors generated.

__asm構文で怒られました。

試したこと

幾つかエラーが発生したので回避できないかソースコードをいじくって試行錯誤してみました。
雰囲気でソースコードを変更しているので期待する動作は得られませんでした。

対象のソースコード
\llvm\tools\clang\examples\clang-interpreter\main.cpp


試行錯誤した痕跡。

#if 0 /* Original */
  // FIXME: This is a hack to try to force the driver to do something we can
  // recognize. We need to extend the driver library to support this use model
  // (basically, exactly one input, and the operation mode is hard wired).
  SmallVector<const char *, 16> Args(argv, argv + argc);
  Args.push_back("-fsyntax-only");
#else /* Modify */
  SmallVector<const char *, 256> Args(argv, argv + argc);
  Args.push_back("-fsyntax-only");
  Args.push_back("-fms-compatibility-version=19.00");
  Args.push_back("-fms-compatibility");
  Args.push_back("-fms-extensions");
  //Args.push_back("-fmsc-version=1912");
  //Args.push_back("--target=x86_64-windows-msvc");    //Clash.
  //Args.push_back("--target=i686-windows-msvc");      //LLVM ERROR: Program used external function '___stdio_common_vfprintf' which could not be resolved!
  //Args.push_back("--target=i686-pc-win32");          //LLVM ERROR: Program used external function '___stdio_common_vfprintf' which could not be resolved!
  //Args.push_back("--target=x86_64-pc-windows-msvc"); //Crash.
  //Args.push_back("--target=x86_64");                 //sample_0.cpp:1:9: fatal error: 'stdio.h' file not found
  //Args.push_back("--target=");
#endif

最後に

元々、深入りするつもりもないのでこの辺にしておきます。