Giter Club home page Giter Club logo

gccrs's Introduction

C/C++ CI GCC Bootstrap Build Build Docker image Docker Pulls project chat Bors enabled justforfunnoreally.dev badge

GCC Rust

GCC Rust

Please note, the compiler is in a very early stage and not usable yet for compiling real Rust programs.

gccrs is a full alternative implementation of the Rust language ontop of GCC with the goal to become fully upstream with the GNU toolchain.

The origin of this project was a community effort several years ago where Rust was still at version 0.9; the language was subject to so much change that it became difficult for a community effort to play catch up. Now that the language is stable, it is an excellent time to create alternative compilers. The developers of the project are keen “Rustaceans” with a desire to give back to the Rust community and to learn what GCC is capable of when it comes to a modern language.

Build Farm Status

FAQ

Please find the answers to frequently asked questions over on: https://github.com/Rust-GCC/gccrs/wiki/Frequently-Asked-Questions

Development Environment

Building

Fetch dependencies for Ubuntu:

$ apt install build-essential libgmp3-dev libmpfr-dev libmpc-dev flex bison autogen gcc-multilib dejagnu

Clone the repository

$ git clone https://github.com/Rust-GCC/gccrs

Linux

It is important to remember that GNU toolchain projects are designed to be built outside of their source directory which is why a build directory is created.

$ mkdir gccrs-build
$ cd gccrs-build
$ ../gccrs/configure --prefix=$HOME/gccrs-install --disable-bootstrap --enable-multilib --enable-languages=rust
$ make

MacOS

The path of header dir and sysroot should be specified when you configure the project.

$ mkdir mac-build
$ cd mac-build
$ ../gccrs/configure --prefix=$HOME/gccrs-install --disable-bootstrap --enable-multilib --enable-languages=rust --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
$ make

Alternatively, a docker environment is available for ARM-based Mac contributors.

Please visit gccrs-workspace.

The image is based on Ubuntu ARM and comes with dependencies all fetched.

Running GCC Rust

Running the compiler itself without make install we can simply invoke the compiler proper:

$ ./gcc/crab1 test.rs -frust-debug -frust-dump-ast-pretty -Warray-bounds -dumpbase test.rs -mtune=generic -march=x86-64 -O0 -version -fdump-tree-gimple -o test.s -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -frust-incomplete-and-experimental-compiler-do-not-use

To invoke the compiler driver (gccrs) we need to:

$ make install

Then invoke the compiler from the installation directory:

$ $HOME/gccrs-install/bin/gccrs -g -O2 -c test.rs -o test.o -frust-incomplete-and-experimental-compiler-do-not-use
$ $HOME/gccrs-install/bin/gccrs -o test test.o

You can also setup your shell to automatically find the installed compiler. For example for bash, add the following in your $HOME/.bashrc:

export PATH=$HOME/gccrs-install/bin:$PATH

Testsuite

Invoke the full testsuite from the build directory (gccrs-build in the previous commands):

$ make check-rust

Invoke a subset of the testsuite. For example, to only run tests that are currently known/expected to fail:

$ make check-rust RUNTESTFLAGS="xfail.exp"

There are the following sets of tests:

  • compile.exp : compilation tests
  • execute.exp : execution tests
  • xfail.exp : tests that are currently known/expected to fail

Invoke only a specific test :

$ make check-rust RUNTESTFLAGS="--all compile.exp=continue1.rs"

Logs (with corresponding commands) can be found in : gccrs-build/gcc/testsuite/rust/rust.log.

See GCC Testing documentation for more details.

Test cases are located within gcc/testsuite/rust/. Please contribute your specific test cases referencing any issues on Github.

Debugging

Enabling internal checks

GCC has several internal checks that can be enabled during configuration. In the case of gccrs, you can enable the following:

$ ../gccrs/configure --prefix=$HOME/gccrs-install --disable-bootstrap --enable-multilib --enable-languages=rust --enable-checking=gimple,tree,types

GDB

You can directly invoke gdb on the crab1 compiler process (you can find the exact command adding --verbose to your gccrs invocation):

$ gccrs test.rs -O0 -S -o arithmetic_expressions1.s --verbose
...
 /some/path/../../crab1 test.rs -quiet -dumpbase arithmetic_expressions1.rs -dumpbase-ext .rs
 -mtune=generic -march=x86-64 -O0 -w -version -fdiagnostics-color=never -fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-urls=never -fdiagnostics-path-format=separate-events -o test.s -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu
...
$ gdb --args  /some/path/../../crab1 test.rs -quiet -dumpbase arithmetic_expressions1.rs -dumpbase-ext .rs
 -mtune=generic -march=x86-64 -O0 -w -version -fdiagnostics-color=never -fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-urls=never -fdiagnostics-path-format=separate-events -o test.s -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu

Or simply add the -wrapper gdb,--args option. This will call each subcommand in gdb and you simply have to break/debug in crab1:

$ gccrs test.rs -O0 -S -o arithmetic_expressions1.s -wrapper gdb,--args

Docker image

There is a docker image hosted over on:

https://hub.docker.com/repository/docker/philberty/gccrs

$ docker pull philberty/gccrs

Or you can build your own image:

$ docker build . -t gccrs-dev

If you want to build an object file:

$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp \
    gccrs-dev:latest gccrs -g -O2 -c \
    gcc/testsuite/rust/compile/torture/type_infer1.rs -o type_infer1.o

If you want to build an executable file:

$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp \
    gccrs-dev:latest gccrs -g -O2 \
    gcc/testsuite/rust/compile/torture/type_infer1.rs -o type_infer1

To emit assembly :

$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp \
    gccrs-dev:latest gccrs -g -O2 \
    gcc/testsuite/rust/compile/torture/type_infer1.rs -S -o type_infer1.s

To emit Rust front end debug output, you may add options like -frust-debug, -frust-dump-all.

Contributing

If you want to contribute to GCC Rust, you can find more information in CONTRIBUTING.md.

Please be aware this project is designed to be pushed upstream to GCC when we reach some milestones, and this means we require copyright assignment or the Developer's Certificate of Origin sign-off. Please see the Contributing to GCC guide or Developer's Certificate of Origin (DCO) Sign-off guide.

Not all contributions must be code; we would love to see new test cases or bugs and issues to be reported. Feel free to add any comments on open PRs

Continuous Integration

When submitting (or updating) a GitHub Pull Request, several automated checks are run. Generally, a "green status" is necessary before merge.

Compiler Diagnostics

That is, here, diagnostics emitted by the "initial" compiler used to build GCC/Rust.

If building a native toolchain, GCC by default does a 3-stage bootstrap build (https://gcc.gnu.org/install/configure.html). In addition to making sure that GCC is able to reproduce itself bit-by-bit, this also means that stages 2+ are built with -Werror (turning most warning into error diagnostics; see --enable-werror, possibly enabled by default). This helps to catch a good number of bugs, because it enforces that GCC compiles without compiler diagnostics; it's a requirement for upstream patch submission (https://gcc.gnu.org/contribute.html#testing).

GCC generally is only expected to be "warning-clean" without --disable-bootstrap (that is, default --enable-bootstrap for a native build), and not for the initial stage where it's using the "initial" compiler -- otherwise we're at the mercy of whatever "initial" compiler we're using. Doing a --disable-bootstrap build is much faster, of course, so we're often doing that: for example, per the instructions above, or in the standard CI. With that, we're missing out on the aspect that enforces that GCC compiles without compiler diagnostics.

To encounter that, the default CI has a check for new warnings step that verifies in the CI --disable-bootstrap build configuration that no new warnings are introduced. If that step fails, it usually points out a new warning you've introduced erroneously, and should address. Occasionally it means that simply the .github/bors_log_expected_warnings file needs to be updated, for example if due to any kind of "environmental changes" (for example, CI "initial" compiler changes). Unless diligently reproducing the CI configuration (in particular "initial" compiler, GCC version), it's not really feasible to reproduce this check locally. If in doubt, do a local --enable-bootstrap build, or submit your changes, and wait for the CI system's results.

Community

We can be found on all usual Rust channels such as Zulip, but we also have our own channels:

gccrs's People

Contributors

aldyh avatar arnaudcharlet avatar bors[bot] avatar cohenarthur avatar davidmalcolm avatar edschonberg avatar hjl-tools avatar hpataxisdotcom avatar iains avatar jakubjelinek avatar jamborm avatar jicama avatar jsm28 avatar jwakely avatar marxin avatar mpolacek avatar msebor avatar p-e-p avatar philberty avatar ptroja avatar rguenth avatar rorth avatar rsandifo avatar rsandifo-arm avatar segher avatar tob2 avatar tschwinge avatar ubizjak avatar urnathan avatar zhongjuzhe 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

gccrs's Issues

arrays

This ticket is to track the implementation of arrays there is an already open PR #51

Name Resolution Dump

We need a name resolution dump to help with debugging:

  • Add command line switch
  • Design format of output/copy rustc
  • Add entry point to dump
  • Dump to file

Unit type support

Rust uses a builtin akin to void in other languages this is a core data structure

The IR design, type checking, and pre-optimizing

The current Rust compiler contains two IRs before GENERIC:

  • HIR for type-checking
  • MIR for borrow-checking and some pre-optimizing.

My previous experiences are more about functional programming language's compiler. That's relatively easier for coding, since there's pattern matching, and there're fewer side-effects (or even no) so that the optimizing is pretty easy: find the correct pattern, and inline the function or closure, then execute the rewriting rules. This process can cover many common optimizing, say, constant-fold, dead-variable-elimination, and dead-function-elimination, etc. For Rust, I think they're doing similar rewriting, but I need more researches.

The Rust compiler is written in Rust, so there's pattern matching. I guess we have to write more code for the tree node matching. After all, pattern matching is just syntax sugar, which expands more code that we have to write in C++.

I'm not sure if we can follow the exact design of HIR and MIR, since C++ may not be possible to cover the expressiveness exactly so that it's better to design a similar IR for taking advantage of C++ features. I'm just guessing, and I need more researches for the conclusion.

So I think the plan could be:

  • Implementing HIR according to Rust's design
  • Type-checking in HIR
  • Implementing MIR
  • HIR->MIR
  • Borrow-checking
  • Other pre-optimizing
  • MIR->GENERIC

That's a rough plan, there're more things, including memory management, library interfaces, exceptions handling, etc. But I'm not sure where to put them in the pipeline. So I just listed them.

Comments?

Link error on x86_64-pc-cygwin

Link error on x86_64-pc-cygwin occurs.

Is configure option wrong?
Or gcc's bug?

$ cat hello.rs
fn main() {
    println!("Hello, world!");
}

$ TMPDIR=/tmp /tmp/gcc-rust/usr/local/bin/gccrs.exe -v hello.rs
Using built-in specs.
COLLECT_GCC=/tmp/gcc-rust/usr/local/bin/gccrs
COLLECT_LTO_WRAPPER=/tmp/gcc-rust/usr/local/bin/../libexec/gcc/x86_64-pc-cygwin/10.0.0/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: ./configure --disable-bootstrap --enable-multilib --enable-languages=c,c++,rust
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 10.0.0 20191127 (experimental) (GCC)
COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /tmp/gcc-rust/usr/local/bin/../libexec/gcc/x86_64-pc-cygwin/10.0.0/rust1.exe hello.rs -quiet -dumpbase hello.rs -mtune=generic -march=x86-64 -auxbase hello -version -L/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0 -L/tmp/gcc-rust/usr/local/bin/../lib/gcc -L/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/../../.. -o /tmp/ccr9IdMy.s
GNU Rust (GCC) version 10.0.0 20191127 (experimental) (x86_64-pc-cygwin)
        compiled by GNU C version 9.3.0, GMP version 6.2.0, MPFR version 4.0.2-p6, MPC version 1.1.0, isl version isl-0.22.1-GMP

GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
GNU Rust (GCC) version 10.0.0 20191127 (experimental) (x86_64-pc-cygwin)
        compiled by GNU C version 9.3.0, GMP version 6.2.0, MPFR version 4.0.2-p6, MPC version 1.1.0, isl version isl-0.22.1-GMP

GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Preparing to parse files.
about to parse expr (in expr without block method)
beginning null denotation identifier handling
current peek token when starting path pratt parse: '!'
current token (just about to return path to null denotation): '!'
finished null denotation identifier path parsing - next is branching
new delim token tree parsing begun
ast token created with str 'Hello, world!'
finished parsing new delim token tree - peeked token is now ';' while t is ')'
successfully parsed macro invocation (via partial)
finished parsing null denotation
null denotation is not null - going on to left denotation
initial rbp: '0', initial lbp: '0' (for ';')
successfully parsed expr in parse_expr - returning
successfully parsed expr (in expr without block method)
about to call the impl for clone expr without block
expr to expr without block conversion didn't error
expr to expr without block conversion was successful; returning
SUCCESSFULLY PARSED CRATE
ran register_plugins (with no body)
SUCCESSFULLY REGISTERED PLUGINS
started injection
finished injection
SUCCESSFULLY FINISHED INJECTION
started expansion
finished expansion
SUCCESSFULLY FINISHED EXPANSION
started name resolution
finished name resolution
SUCCESSFULLY FINISHED RESOLUTION
COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -o /tmp/ccpwggue.o /tmp/ccr9IdMy.s
COMPILER_PATH=/tmp/gcc-rust/usr/local/bin/../libexec/gcc/x86_64-pc-cygwin/10.0.0/:/tmp/gcc-rust/usr/local/bin/../libexec/gcc/
LIBRARY_PATH=/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/:/tmp/gcc-rust/usr/local/bin/../lib/gcc/:/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /tmp/gcc-rust/usr/local/bin/../libexec/gcc/x86_64-pc-cygwin/10.0.0/collect2.exe -plugin /tmp/gcc-rust/usr/local/bin/../libexec/gcc/x86_64-pc-cygwin/10.0.0/cyglto_plugin-0.dll -plugin-opt=/tmp/gcc-rust/usr/local/bin/../libexec/gcc/x86_64-pc-cygwin/10.0.0/lto-wrapper.exe -plugin-opt=-fresolution=/tmp/ccHmliAY.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lcygwin -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -m i386pep --wrap _Znwm --wrap _Znam --wrap _ZdlPv --wrap _ZdaPv --wrap _ZnwmRKSt9nothrow_t --wrap _ZnamRKSt9nothrow_t --wrap _ZdlPvRKSt9nothrow_t --wrap _ZdaPvRKSt9nothrow_t -Bdynamic --dll-search-prefix=cyg --tsaware /lib/../lib/crt0.o /tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/crtbegin.o -L/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0 -L/tmp/gcc-rust/usr/local/bin/../lib/gcc -L/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/../../.. /tmp/ccpwggue.o -lgcc_s -lgcc -lcygwin -ladvapi32 -lshell32 -luser32 -lkernel32 -lgcc_s -lgcc /lib/../lib/default-manifest.o /tmp/gcc-rust/usr/local/bin/../lib/gcc/x86_64-pc-cygwin/10.0.0/crtend.o
/usr/bin/ld: /lib/../lib/libcygwin.a(libcmain.o): in function `main':
/usr/src/debug/cygwin-3.1.4-1/winsup/cygwin/lib/libcmain.c:37: undefined reference to `WinMain'
/usr/src/debug/cygwin-3.1.4-1/winsup/cygwin/lib/libcmain.c:37:(.text.startup+0x7f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status

$ TMPDIR=/tmp /tmp/gcc-rust/usr/local/bin/gccrs.exe -c hello.rs
$ objdump -t hello.o | grep __main
$

String literals

We should add support to compile raw str strings to GIMPLE.

let x = "mystring"

Enhance AST dump

I'm working on an experimental branch to enhance -frust-dump-parse which is a little inspired by gccgo's AST dump.
For example:

 fn abc(x:u32, y:u32) -> u32 {
    return x+y;
 }
 
 fn main() {
     println!("Hello World!");
 }

The dumped result looks like this:

Crate: 
 inner attributes: none
 items: 
  
u32 abc(x : u32, y : u32)
 {
 BlockExpr: 
 outer attributes: none
 inner attributes: none
 statements: 
  ExprStmtWithoutBlock: return ArithmeticOrLogicalExpr: x + y
 final expression: none
 }

  
void main()
 {
 BlockExpr: 
 outer attributes: none
 inner attributes: none
 statements: 
  ExprStmtWithoutBlock: println!("Hello World!")
 final expression: none
 }

The branch is nala/enhance/ast-dump

Comments are welcome.

Enum Compilation

We should be able to compile the enum data structure this may avoid the match control flow for now.

Mark W has done most of the leg work for this one over on: https://code.wildebeest.org/git/user/mjw/gccrs/commit/?h=enum-type

Resolution Design

I think it's better to separate type and name resolution, fortunately, if we do it now, it's just a little change. Here're the steps:

  1. Create Resolution class inherited from AST::ASTVisitor, and move static bool ResolveNamesAndTypes into it.
  2. Separate TypeResolution and NameResolution class inherited from Resolution class.
  3. Put them in different files.

This is better for maintenance and working parallelly.
And the name resolution will distinct names from different namespaces, like values, macros, so it's an important prerequisite for the rest of the work.

If it's OK, then I can raise PR for it.

What do you think? @philberty @SimplyTheOther

Remove token trees in HIR

Assuming that (unexpanded) attributes and macros don't exist in the HIR, tokens shouldn't be required either, I don't think. The AST Token is only used for storing the token data in macro invocations or attributes. Maybe a note of this could be made or something instead of actual deletion at this point, just in case it turns out that tokens are in fact needed.

Originally posted by @SimplyTheOther in #64 (comment)

Check for GCC -Warray-bounds checking that LLVM has

example:

int main(int argc, char **argv) {

    int array[5] = {1,2,3,4,5};
    int x = array[10];
    
    return 0;
}

Compiling with GCC-master:

philbert@philbert-beast {~/workspace/gccrs-build} $ gcc -g -O0 -Wall test.c -o test
test.c: In function ‘main’:
test.c:4:9: warning: unused variable ‘x’ [-Wunused-variable]
    4 |     int x = array[10];
      |         ^

Compiling with clang:

philbert@philbert-beast {~/workspace/gccrs-build} $ clang -g -O0 -Wall test.c -o test
test.c:4:9: warning: unused variable 'x' [-Wunused-variable]
    int x = array[10];
        ^
test.c:4:13: warning: array index 10 is past the end of the array (which contains 5 elements) [-Warray-bounds]
    int x = array[10];
            ^     ~~
test.c:3:5: note: array 'array' declared here
    int array[5] = {1,2,3,4,5};
    ^
2 warnings generated.

Remove rust-ast-containers.h

This file is similar to the last one in that it should also be removed, for similar reasons. This was also a failed "first attempt" at an AST layout that should be unused in the current codebase.

Originally posted by @SimplyTheOther in #96 (comment)

Function Calls are parsed as StructExpr

When there is a statement such as:

let x = test(1);

This is parsed as:

Outer attributes: none
 let x = outer attributes: none
  StructExpr:          
   PathInExpr:      
   test(1)                            
   inner attributes:none

I am unsure if this is intentional of not but we can work around this if its intended.

Macro expansion

The macro expansion happens before the resolution.

This issue is opened for the record of pipeline in kanban.

The missing features in rustc but described in RFCs

I'm here to list the features described in RFCs but haven't implemented them in rustc. We'll follow rustc at present, and let them be enhancements in the future.

  • Forward referencing. According to RFC 1560, names should be able to be used before they are declared, which is the so=called forward referencing.

  • Macro invocation with curly-braces as a statement #22

HIR to GIMPLE crash when compiling forward decl

When we are processing the HIR into gimple there is a crash when we call a function that has not been compiled yet.

    let mut an_integer = 5;
    an_integer = test(1) + 3;

    let call_test = test(1);
}

fn test(x: i32) -> i32 {
    return x + 1;
}

The resolution and type resolution correctly setup all mappings required to compile the main function and then compile the test function on request but there is a core in this code.

The indentation of the code

I'm going to try a bigger contribution, however, I realized that we don't have a unified indentation standard. It's better to have an auto-indentation configuration. Here I have a clang-format, anyone can use their preferred auto-indentation tool without bothering to do it manually. The modern IDE/editor can recognize it and auto-indent.

---
Language:        Cpp
# BasedOnStyle:  LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands:   true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
  AfterClass:      false
  AfterControlStatement: false
  AfterEnum:       false
  AfterFunction:   false
  AfterNamespace:  false
  AfterObjCDeclaration: false
  AfterStruct:     false
  AfterUnion:      false
  BeforeCatch:     false
  BeforeElse:      false
  IndentBraces:    false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit:     120
CommentPragmas:  '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat:   false
ExperimentalAutoDetectBinPacking: false
ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
    Priority:        2
  - Regex:           '^(<|"(gtest|isl|json)/)'
    Priority:        3
  - Regex:           '.*'
    Priority:        1
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth:     2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments:  true
SortIncludes:    true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: Always
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles:  false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard:        Cpp11
TabWidth:        2

Comments?

Scoping rules

We should respect the basic lexical scoping of rust code. This will need extended later for lifetimes/generics etc.

OpenMP, OpenACC

Hi
This looks cool.

I only have a stupid question, really (apologies): can you mix up rust with openmp/openacc directives? Could you give an example?

Thanks!

Hello World

To fully implement Hello World properly we need to finish all of macro expansion. Though we can hack a primitive implementation of println as an interim solution to help with added more useful test cases to progress other parts of the compiler.

Shadowing rules

Shadowing of declarations need to be respected for core data structures such as:

let mut x;
x = 4;
let mut x;
x = true;

mutability

We should respect the mut keyword on declarations such as:

let mut x;
x = 1;
x = 2;

Name resolution

The resolution rules are not well documented in Rust doc, the rustc relies on librustc_resolve.

I'm going to list all the rules here (or wiki) for the reference.

Macro invocation with curly-braces as a statement

This issue is related to 0378-expr-macros

  • Treat all macro invocations with parentheses, (), or square brackets, [], as expressions.
  • Curly braces or a semicolon following the invocation to invoke a macro as a statement

However, it seems that macro_invoce!{x} doesn't work for nightly rustc:

macro_rules! maybe_return { ($e:expr) => ($e); }

fn frob(x: i32) -> i32{
    maybe_return! {x}
    // should return -1 
    -1
}

The result is:

error[E0308]: mismatched types
 --> ma.rs:4:20
  |
4 |     maybe_return! {x}
  |                    ^- help: consider using a semicolon here
  |                    |
  |                    expected `()`, found `i32`

I may incorrectly understand the RFC description, anyway, I leave it here for a placeholder.

Our curent parser doesn't recogonize it too:

i32 frob(x : i32)
BlockExpr:
{
 outer attributes: none
 inner attributes: none
 statements: none
 final expression: 
ArithmeticOrLogicalExpr: MacroInvocation: maybe_return!{x} - 1
}

Literals

LiteralExpr need to be compiled as part of expressions etc.

size data type

We need to support the size data type the array index expression code is using the i32 data type for the index but this should be size.

Please create also a fork of cargo.

I know it might have to be done on a separate project, but currently cargo will only use rustc for dependencies and even use clang for C bindings (currently no way to compile C bindings using gcc).

No need for HIR CFGs

gcc/rust/hir/tree/rust-hir-cond-compilation.h

from: #64 (comment)

This entire file is probably not required at the moment. The current implementation of the cfg attribute expansion just works with the Meta[InsertThingHere] data structures in the AST rather than using these separate configuration ones. As such, nothing would be converted to this HIR as nothing in the AST is stored in this manner.

Parser failed to handle CopiedArray

test.rs:8:36: error: expecting ‘;’ but ‘]’ found
8 | let mut array: [i32; 3] = [0; 3];
| ^
test.rs:8:5: error: failed to parse statement or expression without block in block expression
8 | let mut array: [i32; 3] = [0; 3];
| ^
test.rs:8:36: error: unrecognised token ‘]’ for start of item
8 | let mut array: [i32; 3] = [0; 3];
| ^
test.rs:8:36: error: failed to parse item in crate

Structs Compilation

We should be able to compile structs such as:

    one: i32,
    two: i32,
}

fn main() {
    let struct_test = Foo { one: 1, two: 2 };
}

The optmizing of directory

First, it's not a hurry issue.

As I mentioned in another issue, gcc front-end is unnecessarily to be part of gcc source code, we can maintain gcc/rust as a standalone project, and users may make a link to gcc/rust so that gcc can detect it automatically.

If we do so, then we don't have to consider rebase upstream code anymore.

However, if we just remove redundant parts by git rm, all the history is still kept in git database, and users will still clone the repo slowly. Not so perfect, but still better than keeping everything.

I've no idea about it, maybe we should ignore this issue at present?

GCC Rich Locations

This relates to something I had thought about doing, but not in enough detail to open an enhancement issue. gcc supports something called "rich locations" in which three actual locations are encoded - a "start" location, a "caret" location, and an "end" location - basically like a location range with a specified value highlighted.

I couldn't find the page that I thought I originally read this in, but here's a quote from here:

As of GCC 6, ordinary locations changed from supporting just a point in the user’s source code to supporting three points: the caret location, plus a start and a finish:

      a = foo && bar;
          ~~~~^~~~~~
          |   |    |
          |   |    finish
          |   caret
          start

Instead of accessing start_location and end_location separately, these could be integrated into a single location value. There's also the technicality that the current definition of get_closing_locus() technically gets the beginning location of the last statement rather than the end location of the block (i.e. the right curly bracket), assuming that this would be the preferred behaviour.

The lexer would have to be modified to reflect this rich location system, and the parser and AST probably would have to be too (i.e. make a new location from the "start" location from one token and the "end" location of a different one). Also, the backend-independent Location abstraction would have to be modified to support this.

Originally posted by @SimplyTheOther in #90 (comment)

Type Resolution Dump

Type resolution dumps will be critical in debugging the rust front-end. The format we have right now is pretty poor:

$ cat gccrs.type-resolution.dump 
impl <Foo{0:Int:i32:(Ref: 60 TyRef: 8[8,26,])} HIRID: 35 RF:35 TF:129 - [28, ]> {
    fn baz <fn (ref self & Foo{0:Int:i32:(Ref: 60 TyRef: 8[8,26,])},) -> () HIRID: 66 RF:66 TF:66 - []>
    {
        ;
    }

}

fn static_dispatch <fn<T REF: 70> (t & T REF: 70,) -> () HIRID: 81 RF:81 TF:81 - []>
{
    ;
}

fn dynamic_dispatch <fn (t & dyn [Bar],) -> () HIRID: 94 RF:122 TF:94 - [94, ]>
{
    ;
}

fn main <fn () -> () HIRID: 127 RF:127 TF:127 - []>
{
    let a:<Foo{0:Int:i32:(Ref: 26 TyRef: 8[8,])} HIRID: 95 RF:100 TF:129 - [28, 95, 96, 98, 100, ]>;
    a:<Foo{0:Int:i32:(Ref: 26 TyRef: 8[8,])} HIRID: 96 RF:100 TF:129 - [28, 95, 96, 98, 100, ]> = ;
    ;
    let b:<& dyn [Bar] HIRID: 115 RF:116 TF:114 - [114, 116, 118, ]>;
    b:<& dyn [Bar] HIRID: 116 RF:116 TF:114 - [114, ]> = ;
    ;
}

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.