Code Monkey home page Code Monkey logo

facebook-clang-plugins's Introduction

Deprecation Warning

This repo is deprecated. Development has moved to the Infer repo.

Facebook Clang Plugins

This repository aims to share some useful clang plugins developed at Facebook. They are mostly used by infer.

It contains frontend plugins to the clang compiler to process the syntax of source files directly to accomplish more general tasks; specifically, we have developed a clang-to-ocaml bridge to make code analyses easier.

Structure of the repository

  • libtooling : frontend plugins (currently a clang-to-json AST exporter),

  • clang-ocaml : OCaml libraries to process the JSON output of frontend plugins,

Quick start

The current version of the plugins requires recent version of the clang compiler, re-compiled from source. Clang source which is used by this project can be found in clang/src/

General instructions to compile clang can be found here: http://clang.llvm.org/get_started.html

To compile and use the required version of clang, please run ./clang/setup.sh. Using this script should make the variable CLANG_PREFIX unnecessary to compile the plugin.

Caveat:

  • Because of the nature of C++, clang and the plugins need to be compiled with the exact same C++ libraries.
  • Also, the default stripping command of clang in release mode breaks plugins.

Once the target compiler is installed, make test should run the unit tests.

OCaml users may also run:

make -C clang-ocaml test  #requires proper ocaml libraries, see included clang-ocaml/README

Additional configuration options are available in Makefile.config.

Licence

The plugins are MIT-licensed.

facebook-clang-plugins's People

Contributors

amar1729 avatar artempyanykh avatar aytey avatar da319 avatar ddino avatar dulmarod avatar ezgicicek avatar flarnie avatar geoffviola avatar hansonw avatar jberdine avatar jeremydubreil avatar jvillard avatar katiejots avatar ma2bd avatar martinoluca avatar martintrojer avatar mbouaziz avatar milend avatar skcho avatar tarikozket avatar vsilyaev avatar xvilka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

facebook-clang-plugins's Issues

fatal error: 'clang/Analysis/AnalysisContext.h'

I built clang using clang/setup.sh and then tried "make". In "analyzer/ObjCARCQualifierChecker.cpp" there is an import of "clang/Analysis/AnalysisContext.h". This file is simply not present in "clang/install/include/clang/Analysis". The folder does exist, but the file is not present there.

I've tried this on both Fedora and MacOS Sierra, but the file is not present in the .tar.gz file either, so its not a platform issue, just a missing file or wrong clang version in the .tar.gz.

"make" output:

[elijah@localhost facebook-clang-plugins]$ make
make -C analyzer all
make[1]: Entering directory '/home/elijah/RuntimeConverter/other/facebook-clang-plugins/analyzer'
clang++ -std=c++14 -fPIC -g -I../clang/install/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -Wno-uninitialized -Wno-missing-field-initializers -Wno-vla-extension -Wno-c99-extensions -O3 -DNDEBUG -c ObjCARCQualifierChecker.cpp -o build/ObjCARCQualifierChecker.o
ObjCARCQualifierChecker.cpp:19:10: fatal error: 'clang/Analysis/AnalysisContext.h' file not found
#include "clang/Analysis/AnalysisContext.h"

Compatibility with Xcode toolchain

I am able to use the plugin (PrintTopDeclarations) on simple Objective-C programs. However, when trying to load the .dylib file and use it as part of a project which is built using Xcode toolchain, it results in build errors. This seems to be an issue because the plugin is built using custom clang versus the project using Xcode clang. This is also likely related to this question.

Do you have any suggestions on how to generate the dylib using the Xcode clang without using the provided sources from the clang directory in the current repo?

Integrate AST exporter JSON plugin in the official clang repository?

Have you considered adding the ASTExporter.cpp in the clang repository itself?
Right now it is pretty tedious to install facebook-clang-plugins because it requires to recompile your own clang,
and to install it, and to override existing one. Wouldn't it be simpler if the plugin was already in clang
so we could just call the regular clang binary?

Potentially already fixed: `"!!DUMMY!!"` appearing in the dumped AST

Hello,

I am currently working with two versions of Infer:

  • Infer version v0.17.0 (the "official" release from Github)
  • Infer version v0.17.0-fbe1c92 (a version I built from git)

However, I think that this is a facebook-clang-plugins issue, rather than an Infer issue.

Behind the scenes, I believe that the official release of Infer is using:

  • clang version 8.0.0 (tags/RELEASE_800/final)

while my development release is using:

  • clang version 9.0.0 (tags/RELEASE_900/final)

I then have the following script:

#!/bin/bash

set -eu

cat << EOF > test.c
void foo(int x)
{
    if (x);
}
EOF

infer -g -- gcc -c test.c

bash test.c.ast.sh

# EOF

which attempts to dump the AST.

When using the "official" release of Infer, the generated output contains things like the following:

({ "pointer": 1, "source_range": ({ }, { }), "!!DUMMY!!": unit },

that is, it has a dictionary entry with a key of "!!DUMMY!!" and an (unquoted) value of unit.

However, when using the development version of Infer, I do not see these "!!DUMMY!!" (which is great!).

Is this an older bug that is fixed in later versions of Infer?

ast_exporter generates warning for "stdarg.h" include

The exporter seems to work just fine, but it gives a warning about "stdarg.h" which is part of the c standard library. I also tried using compilation database and no change (but warnings go a way about missing compilation database).

[elijah@localhost build]$ ./ast_exporter_bin a.cc > /dev/null
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "a.cc"
No compilation database found in /home/elijah/RuntimeConverter/other/facebook-clang-plugins/libtooling/build or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
/home/elijah/RuntimeConverter/other/facebook-clang-plugins/libtooling/build/a.cc:1:10: fatal error: 'stdarg.h' file not found
#include <stdarg.h>
^~~~~~~~~~
1 error generated.
Error while processing /home/elijah/RuntimeConverter/other/facebook-clang-plugins/libtooling/build/a.cc.

a.cc

#include <stdarg.h>

int main(int argc, const char* argv[]){
return 0;
}

CMake

cmake_minimum_required(VERSION 3.10)
project(aaa C)

set(CMAKE_C_STANDARD 99)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(aaa a.c)

"clang_ast.atd" does not work with adtj for Java generation

This is does not seem to be an issue with "facebook-clang-plugins" itself, but "clang_ast.atd" does not work with adtj for Java generation.

I've opened a ticket with ATD (ahrefs/atd#179). I am using atdj 2.0.0.

Is there a workaround for Java generation such as using an older version of clang_ast.atd? Does Facebook only use atd with ocaml?

Command used: atdj clang_ast.atd

clang_ast.atd.txt

Basic documentation on how to get an OCaml AST dumper of a c++ program

I could not find any documentation on how to install and use facebook-clang-plugins and its ocaml library
to get a simple AST dump of a c++ program.

Let's say I have this simple c++ program:

void main() {
return 1 + 2;
}

Which OCaml program do I need to write to access its AST from OCaml?

Should `facebook-clang-plugins` allow for CMake `CMAKE_BUILD_TYPE` to be configurable?

At a very quick glance, there are quite a few issues that are related to not being able to build Infer due to running out of space:

Despite having 70 GiB free on one my VMs, I can't install facebook-clang-plugins (i.e., the build succeeds, but copying the artefacts in to the destination folder fails).

I "fixed" this by using MinSizeRel over Release for CMAKE_BUILD_TYPE.

Is this something that's reasonable to allow to be configurable? Should ./clang/setup.sh take a parameter (e.g., --cmake-build-type <string>) that allows you to select a particular build type?

Happy to do this work, but I only want to "polish" it if it is something that (as an idea) is acceptable to merge.

clang-ocaml make: Error: Unbound value Clang_ast_j.read_decl

When running make -C clang-ocaml:

ocamlfind ocamlopt -package unix,atdgen,atdgen-runtime,camlzip -I build -safe-string -o build/clang_ast_converter.cmx -c clang_ast_converter.ml
File "clang_ast_converter.ml", line 11, characters 41-62:
Error: Unbound value Clang_ast_j.read_decl
make: *** [Makefile:42: build/clang_ast_converter.cmx] Error 2

I am using Fedora Linux 28
ocaml --version
4.06.0
opam --version
2.0.0~rc

On Mac OS X (mohave + macports) there is a slightly different error:

Elijahs-Mac-Pro:facebook-clang-plugins elijah$ make -C clang-ocaml/
ocamlfind ocamlopt -package unix,atdgen,atdgen-runtime,camlzip -I build -safe-string -o build/clang_ast_t.cmi -c build/clang_ast_t.mli
File "build/clang_ast_t.mli", line 29, characters 0-4:
Error: Syntax error
make: *** [build/clang_ast_t.cmi] Error 2

I would try with HomeBrew, but versions 4.05.0/2.0.0 look to be the latest for OCAML and OPAM.

Unbound record field sl_file

Running make -C clang-ocaml test results in the following error when compiling the file yojson_utils_test.ml:

make -C clang-ocaml test
make: Entering directory '/home/caleb/Documents/deepdecompilerproject/facebook-clang-plugins/clang-ocaml'
ocamldep -native -I build clang_ast_main_test.ml clang_ast_yojson_validator.ml clang_ast_visit.ml utils_test.ml yojson_utils.ml clang_ast_types.ml process.ml clang_ast_converter.ml clang_ast_named_decl_printer.ml clang_ast_proj_test.ml utils.ml yojson_utils_test.ml process_test.ml clang_ast_main.ml yojson_utils.mli process.mli utils.mli build/clang_ast_t.mli build/clang_ast_t.ml build/clang_ast_j.mli build/clang_ast_j.ml build/clang_ast_v.mli build/clang_ast_v.ml build/clang_ast_proj.mli build/clang_ast_proj.ml | sed -e 's/\([a-zA-Z0-9_]*\.cm.\)/build\/\1/g' | sed -e 's/build\/build\//build\//g' > .depend
ocamlfind ocamlopt -package unix,atdgen,atdgen-runtime,camlzip -I build -safe-string -o build/yojson_utils_test.cmx -c yojson_utils_test.ml
File "yojson_utils_test.ml", line 11, characters 12-19:
Error: Unbound record field sl_file
make: *** [Makefile:40: build/yojson_utils_test.cmx] Error 2
make: Leaving directory '/home/caleb/Documents/deepdecompilerproject/facebook-clang-plugins/clang-ocaml'

Attempting to add a qualifier to the sl_file field does not resolve the issue (ie, prepending Clang_ast_t.) does not resolve the issue (same error)

I was able to compile the .depend makefile target (not the depend target as the readme suggests), as well as the Clang compiler and libtooling (and all the libtooling tests passed).

System:
Ubuntu 19.10
OCaml version 4.05.0
camlzip 1.10
yojson 1.7.0
atd 2.0.0
atdgen 2.0.0

Package in findlib / OPAM?

Hey there,

We would like to use this package in our OCaml project. We are happy to package it up as an OPAM package, but need advice on creating a META file. Can the Makefile do this? I usually rely on the build system (e.g. Oasis, Dune, etc.) to do this for me.

Any tips?

Building the plugin

Hi,

I am trying to follow the instructions in the README. While ./clang/setup.sh has been successful, I am unable to do a make test subsequently (CLANG_PREFIX points to the correct install directory within the repo). I get the following on a make test:

/Applications/Xcode.9.2.0.9C40b.app/Contents/Developer/usr/bin/make -C analyzer all make[1]: *** No rule to make target build/PluginMain.o', needed by build/FacebookAnalyzerPlugin.dylib'. Stop. make: *** [all] Error 2

What needs to be done? I tried a cmake on the analyzer directory which doesn't help either.

Thanks,
M.

PS: Also, is there a mailing list to ask questions regarding the plugins?

Does not compile with glibc 2.26

Hi,

I think something had to be updated since stored clang source code does not compile against glibc 2.26.

/tmp/clang-setup.KfT0vO/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc:290:22: error: variable has incomplete type 'struct sigaltstack'
/tmp/clang-setup.KfT0vO/llvm/projects/libcxx/include/__locale:39:11: fatal error: 'xlocale.h' file not found

It is known problem:

`llvm_clang_compiler-rt_libcxx_libcxxabi_openmp-9.0.0` is not compatible with `glibc 2.31`

As reported here:

It seems that LLVM 9.0.0 is not compatible with glibc 2.31:

This particular commit that fixed it:

which looks like it was in llvmorg-10.0.0-rc1 (which means it is in the full release of LLVM 10.0.0).

A suggested "work around" is here:

(search for "Fix a problem introduced by Glibc-2.31 if you are using compiler-rt").

Compilation errors.

Hello. During compilation (for Infer), see the following error: (Arch Linux, gcc 5.2.0)

In file included from /usr/lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/type_traits:35:
/usr/lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/c++0x_warning.h:32:2: error: This file requires compiler and library
support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler
options.

error This file requires compiler and library support for the \

^
In file included from PluginMain.cpp:11:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/StaticAnalyzer/Core/Checker.h:17:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/Analysis/ProgramPoint.h:18:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/Analysis/AnalysisContext.h:18:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/AST/Decl.h:17:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/AST/APValue.h:17:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/Basic/LLVM.h:22:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/Casting.h:19:
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:55:25: error: no type named 'remove_reference'
in namespace 'std'
typedef typename std::remove_reference::type UnderlyingT;
~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:55:41: error: expected member name or ';' after
declaration specifiers
typedef typename std::remove_reference::type UnderlyingT;

/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:59:13: error: no member named 'is_class' in
      namespace 'std'
      !std::is_class<UnderlyingT>::value && // Filter conversion operators.
       ~~~~~^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:59:22: error: use of undeclared identifier
      'UnderlyingT'
      !std::is_class<UnderlyingT>::value && // Filter conversion operators.
                     ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:59:34: error: no member named 'value' in the
      global namespace; did you mean simply 'value'?
      !std::is_class<UnderlyingT>::value && // Filter conversion operators.
                                 ^~~~~~~
                                 value                                                                                                                
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:58:21: note: 'value' declared here
  static const bool value =
                    ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:60:13: error: no member named 'is_pointer' in
      namespace 'std'
      !std::is_pointer<UnderlyingT>::value &&
       ~~~~~^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:60:24: error: use of undeclared identifier
      'UnderlyingT'
      !std::is_pointer<UnderlyingT>::value &&
                       ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:60:36: error: no member named 'value' in the
      global namespace; did you mean simply 'value'?
      !std::is_pointer<UnderlyingT>::value &&
                                   ^~~~~~~
                                   value                                                                                                              
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:58:21: note: 'value' declared here
  static const bool value =
                    ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:61:13: error: no member named
      'is_floating_point' in namespace 'std'
      !std::is_floating_point<UnderlyingT>::value &&
       ~~~~~^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:61:31: error: use of undeclared identifier
      'UnderlyingT'
      !std::is_floating_point<UnderlyingT>::value &&
                              ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:61:43: error: no member named 'value' in the
      global namespace; did you mean simply 'value'?
      !std::is_floating_point<UnderlyingT>::value &&
                                          ^~~~~~~
                                          value
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:58:21: note: 'value' declared here
  static const bool value =
                    ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:62:12: error: no member named 'is_convertible'
      in namespace 'std'
      std::is_convertible<UnderlyingT, unsigned long long>::value;
      ~~~~~^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:62:27: error: use of undeclared identifier
      'UnderlyingT'
      std::is_convertible<UnderlyingT, unsigned long long>::value;
                          ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:62:40: error: expected member name or ';' after
      declaration specifiers
      std::is_convertible<UnderlyingT, unsigned long long>::value;
                                       ^
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:62:39: error: expected ';' at end of
      declaration list
      std::is_convertible<UnderlyingT, unsigned long long>::value;
                                      ^
                                      ;
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:71:22: error: no type named 'enable_if' in
      namespace 'std'
    T, typename std::enable_if<std::is_pointer<T>::value>::type> {
       ~~~~~~~~~~~~~~^~~~~~~~~
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/type_traits.h:82:22: error: no type named 'enable_if' in
      namespace 'std'
    T, typename std::enable_if<std::is_pointer<T>::value>::type> {
       ~~~~~~~~~~~~~~^~~~~~~~~
In file included from PluginMain.cpp:11:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/StaticAnalyzer/Core/Checker.h:17:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/Analysis/ProgramPoint.h:18:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/Analysis/AnalysisContext.h:18:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/AST/Decl.h:17:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/AST/APValue.h:17:
In file included from /home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/clang/Basic/LLVM.h:22:
/home/yaroslav/infer/src/infer-0.2.0/../facebook-clang-plugin/clang/include/llvm/Support/Casting.h:63:29: error: no type named 'enable_if' in
      namespace 'std'
    To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
              ~~~~~~~~~~~~~~^~~~~~~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
../Makefile.rules:9: error performance objectives for the recipe «build/PluginMain.o»
make[1]: *** [build/PluginMain.o] Error 1
make[1]: leave from «/home/yaroslav/infer/src/facebook-clang-plugin/analyzer»

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.