• 基于 libclang 编译 C 文件的坑( error: unknown type name 'uint8_t' )


    本文是 在 Mac 平台 基于 libclang 编译 cpp 或者 c 文件 出现一个 报错。记录 解决问题的过程,以及 解决问题过程中 所使用的方式方法。

    我这里编译的 是 从一个工程中 单独拎出来的 cpp 文件, 头文件导入 直接 简单粗暴的指定了工程的根目录(埋下了祸根!)。

    现象:

    /** 遍历文件语法树 */
    + (void)_visitASTWithFile:(NSString *)file
                   searchPath:(NSString *)searchPath
                      visitor:(CXCursorVisitor)visitor
                   clientData:(CXClientData)clientData
    {
        if (file.length == 0) return;
    
        bool isCpp = [file hasSuffix:@".cpp"] || [file hasSuffix:@".c"];
        bool isOcpp = [file hasSuffix:@".h"] || [file hasSuffix:@".mm"] || [file hasSuffix:@".m"];
        
        // 创建index
        CXIndex index = clang_createIndex(1, 1);
        
        NSMutableArray *cmd_arr = [[NSMutableArray alloc] init];
        [cmd_arr addObject:@"-v"];  // 回显 命令行参数
        [cmd_arr addObject:@"-c"];  // -c 指定是 编译成 .o 文件
        if (isCpp){
            [cmd_arr addObject:@"-x"];    // -x 指定语言
            [cmd_arr addObject:@"c++"];
        }
        if (isOcpp){
            [cmd_arr addObject:@"ObjC++"];  // 或者 ObjC
        }
        [cmd_arr addObject:@"-arch"];   //-arch x86_64
    //    [cmd_arr addObject:@"i386"];
        [cmd_arr addObject:@"x86_64"];
    
        [cmd_arr addObject:@"-isysroot"];
        [cmd_arr addObject:@"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk"];
        
        // 搜索路径
        if (searchPath.length > 0) {
            NSString*str = [NSMutableString stringWithFormat:@"-I%@", searchPath];
            [cmd_arr addObject:str];
    
            NSFileManager *mgr = [NSFileManager defaultManager];
            NSArray *subpaths = [mgr subpathsAtPath:searchPath];
            BOOL isdir = NO;
            for (NSString *subpath in subpaths) {
                NSString *path = [searchPath stringByAppendingPathComponent:subpath];
                [mgr fileExistsAtPath:path isDirectory:&isdir];
                if (isdir){
                    NSString*str = [NSMutableString stringWithFormat:@"-I%@", path];
                    [cmd_arr addObject:str];
                }
                isdir = NO;
            }
        }
        
        // 将最终的 参数 写入文件
        NSError *error = nil;
        NSString *cmd_str = [cmd_arr componentsJoinedByString:@" "];
        NSString *outputpath = @"/Users/xxxxx/Documents/testDir/cmd.txt";
        [cmd_str writeToFile:outputpath atomically:YES encoding:NSUTF8StringEncoding error:&error];
        
        unsigned argIndex = 0;
        const char **args = (const char **)malloc(sizeof(char *) * cmd_arr.count);
        for (NSString *cmd in cmd_arr) {
            args[argIndex++] = cmd.UTF8String;
        }
    
        // 解析语法树,返回根节点TranslationUnit
        CXTranslationUnit tu = clang_parseTranslationUnit(index, file.UTF8String,
                                                          args,
                                                          (unsigned)cmd_arr.count,
                                                          NULL, 0, CXTranslationUnit_None);
        free(args);
        if (!tu){
            clang_disposeIndex(index);
            return;
        }
        
        // 访问语法树
        clang_visitChildren(clang_getTranslationUnitCursor(tu),
                            visitor, clientData);
        
        // 销毁
        clang_disposeTranslationUnit(tu);
        clang_disposeIndex(index);
    }

     一直报错:

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/sys/resource.h:202:2: error: unknown type name 'uint8_t'
    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/sys/resource.h:203:2: error: unknown type name 'uint32_t'
    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/sys/resource.h:204:2: error: unknown type name 'uint64_t'

    注意 此时 我的 xxxx.cpp 文件中 并不包含任何  uint8_t  相关代码

    查找问题:

     我 直接使用 mac 平台 Xcode 的 clang 直接编译目标文件

    clang -c xxxxx.cpp

    是能够正常编译的。没有报错。

    1、 为 Mac 的 clang 和 代码中的 libclang 各自 添加 -v 参数  比较 回显的 命令行参数差异, 仍然没有找到解决问题的线索。(因为数量庞大 爬了挺久的坑)

    2、网上搜的 方案都是 所 需要 修改 usr/local/include 路径,认为是系统升级导致 clang 环境 头文件 被破坏了。我这里 命令行 clang 是能够正常编译 肯定不是这个问题。

    3、别人提供的思路。 我重新弄了个 C 文件, 仍然通过 libclang 来编译,  错误依旧。然后就有点懵。这里又 爬了很久的坑 不知道为什么! 知道 跟 stdint.h 相关 但是 下面的代码我去掉这个头文件仍然报错!

    编译的是下面这个文件, 此文件内容来自互联网

    #include <stdint.h>  
    #include <stdio.h>
    #include <stdlib.h>
    
    int main( int argc, char **argv )
    {
        uint64_t u64 = 3;
        int32_t  i32 = 141;
    
        printf( "u64 = %lu\n", u64 );
        printf( "i32 = %d\n", i32 );
    
        return 0;
    }

     后来无意中  觉得 这是一个单独的文件 所以编译参数 去掉了搜索路径 也就是上面代码中的 searchPath 部分   发现 上面的那个错误消失了!!!

    4、进一步 减小搜索路径的范围 最终确认 问题!  因为我指定的搜索路径 是 递归查找,它的子目录中 包含了一个 stdint.h。  内容如下:

    #ifndef _MSC_STDINT_H_ // [
    #define _MSC_STDINT_H_
    
    #include "CCPlatformConfig.h"
    #if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
    
    #ifndef _MSC_VER // [
    #error "Use this header only with Microsoft Visual C++ compilers!"
    #endif // _MSC_VER ]
    
    #if _MSC_VER > 1000
    #pragma once
    #endif
    
    #include <limits.h>
     ...

    而我 当前平台是 Mac。  导致  stdint.h  无法包含进来。

    找到问题就 把 win 搜索路径排除就好了。

    这个坑 也是 蛋疼。记录下 也可以为类似问题 提供个思路。

    这里贴一下  Mac 下 clang 的 参数列表。

    CLANG(1)                                                Clang                                                CLANG(1)
        
    NAME
           clang - the Clang C, C++, and Objective-C compiler
    
    SYNOPSIS
           clang [options] filename ...
    
    DESCRIPTION
           clang  is a C, C++, and Objective-C compiler which encompasses preprocessing, parsing, optimization, code gen-
           eration, assembly, and linking.  Depending on which high-level mode setting is passed, Clang will stop  before
           doing a full link.  While Clang is highly integrated, it is important to understand the stages of compilation,
           to understand how to invoke it.  These stages are:
    
           Driver The clang executable is actually a small driver which controls the overall  execution  of  other  tools
                  such as the compiler, assembler and linker.  Typically you do not need to interact with the driver, but
                  you transparently use it to run the other tools.
    
           Preprocessing
                  This stage handles tokenization of the input source file, macro expansion, #include expansion and  han-
                  dling  of  other preprocessor directives.  The output of this stage is typically called a ".i" (for C),
                  ".ii" (for C++), ".mi" (for Objective-C), or ".mii" (for Objective-C++) file.
    
           Parsing and Semantic Analysis
                  This stage parses the input file, translating preprocessor tokens into a parse tree.  Once in the  form
                  of  a  parse  tree, it applies semantic analysis to compute types for expressions as well and determine
                  whether the code is well formed. This stage is responsible for generating most of the compiler warnings
                  as well as parse errors. The output of this stage is an "Abstract Syntax Tree" (AST).
    
           Code Generation and Optimization
                  This  stage  translates  an AST into low-level intermediate code (known as "LLVM IR") and ultimately to
                  machine code.  This phase is responsible for optimizing the generated code and handling target-specific
                  code generation.  The output of this stage is typically called a ".s" file or "assembly" file.
    
                  Clang  also  supports  the  use of an integrated assembler, in which the code generator produces object
                  files directly. This avoids the overhead of generating the ".s" file and of calling the  target  assem-
                  bler.
    
           Assembler
                  This stage runs the target assembler to translate the output of the compiler into a target object file.
                  The output of this stage is typically called a ".o" file or "object" file.
    
           Linker This stage runs the target linker to merge multiple object files into an executable or dynamic library.
                  The output of this stage is typically called an "a.out", ".dylib" or ".so" file.
    
           Clang Static Analyzer
    
           The  Clang  Static  Analyzer is a tool that scans source code to try to find bugs through code analysis.  This
           tool uses many parts of Clang and is built into the same driver.  Please see <https://clang-analyzer.llvm.org>
           for more details on how to use the static analyzer.
    
    OPTIONS
       Stage Selection Options
           -E     Run the preprocessor stage.
    
           -fsyntax-only
                  Run the preprocessor, parser and type checking stages.
    
           -S     Run  the  previous  stages  as well as LLVM generation and optimization stages and target-specific code
                  generation, producing an assembly file.
    
           -c     Run all of the above, plus the assembler, generating a target ".o" object file.
    
           no stage selection option
                  If no stage selection option is specified, all stages above are run, and the linker is run  to  combine
                  the results into an executable or shared library.
    
       Language Selection and Mode Options
           -x <language>
                  Treat subsequent input files as having type language.
    
           -std=<standard>
                  Specify the language standard to compile for.
    
                  Supported values for the C language are:
                     c89
                     c90
                     iso9899:1990
    
                         ISO C 1990
                     iso9899:199409
    
                         ISO C 1990 with amendment 1
                     gnu89
                     gnu90
    
                         ISO C 1990 with GNU extensions
                     c99
                     iso9899:1999
    
                         ISO C 1999
                     gnu99
    
                         ISO C 1999 with GNU extensions
                     c11
                     iso9899:2011
    
                         ISO C 2011
                     gnu11
    
                         ISO C 2011 with GNU extensions
                     c17
                     iso9899:2017
    
                         ISO C 2017
                     gnu17
    
                         ISO C 2017 with GNU extensions
    
                  The default C language standard is gnu17, except on PS4, where it is gnu99.
    
                  Supported values for the C++ language are:
                     c++98
                     c++03
    
                         ISO C++ 1998 with amendments
                     gnu++98
                     gnu++03
    
                         ISO C++ 1998 with amendments and GNU extensions
                     c++11
    
                         ISO C++ 2011 with amendments
                     gnu++11
    
                         ISO C++ 2011 with amendments and GNU extensions
                     c++14
    
                         ISO C++ 2014 with amendments
                     gnu++14
    
                         ISO C++ 2014 with amendments and GNU extensions
                     c++17
    
                         ISO C++ 2017 with amendments
                     gnu++17
    
                         ISO C++ 2017 with amendments and GNU extensions
                     c++2a
    
                         Working draft for ISO C++ 2020
                     gnu++2a
    
                         Working draft for ISO C++ 2020 with GNU extensions
    
                  The default C++ language standard is gnu++14.
    
                  Supported values for the OpenCL language are:
                     cl1.0
    
                         OpenCL 1.0
                     cl1.1
    
                         OpenCL 1.1
                     cl1.2
    
                         OpenCL 1.2
                     cl2.0
    
                         OpenCL 2.0
    
                  The default OpenCL language standard is cl1.0.
    
                  Supported values for the CUDA language are:
                     cuda
    
                         NVIDIA CUDA(tm)
    
           -stdlib=<library>
                  Specify  the C++ standard library to use; supported options are libstdc++ and libc++. If not specified,
                  platform default will be used.
    
           -rtlib=<library>
                  Specify the compiler runtime library to use; supported options are libgcc and compiler-rt. If not spec-
                  ified, platform default will be used.
    
           -ansi  Same as -std=c89.
    
           -ObjC, -ObjC++
                  Treat source input files as Objective-C and Object-C++ inputs respectively.
    
           -trigraphs
                  Enable trigraphs.
    
           -ffreestanding
                  Indicate  that  the file should be compiled for a freestanding, not a hosted, environment. Note that it
                  is assumed that a freestanding environment will additionally provide memcpy, memmove, memset and memcmp
                  implementations, as these are needed for efficient codegen for many programs.
    
           -fno-builtin
                  Disable special handling and optimizations of builtin functions like strlen() and malloc().
    
           -fmath-errno
                  Indicate that math functions should be treated as updating errno.
    
           -fpascal-strings
                  Enable support for Pascal-style strings with "\pfoo".
    
           -fms-extensions
                  Enable support for Microsoft extensions.
    
           -fmsc-version=
                  Set _MSC_VER. Defaults to 1300 on Windows. Not set otherwise.
    
           -fborland-extensions
                  Enable support for Borland extensions.
    
           -fwritable-strings
                  Make  all  string  literals default to writable.  This disables uniquing of strings and other optimiza-
                  tions.
    
           -flax-vector-conversions, -flax-vector-conversions=<kind>, -fno-lax-vector-conversions
                  Allow loose type checking rules for implicit vector conversions.  Possible values of <kind>:
    
                  o none: allow no implicit conversions between vectors
    
                  o integer: allow implicit bitcasts between integer vectors of the same overall bit-width
    
                  o all: allow implicit bitcasts between any vectors of the same overall bit-width
    
                  <kind> defaults to integer if unspecified.
    
           -fblocks
                  Enable the "Blocks" language feature.
    
           -fobjc-abi-version=version
                  Select the Objective-C ABI version  to  use.  Available  versions  are  1  (legacy  "fragile"  ABI),  2
                  (non-fragile ABI 1), and 3 (non-fragile ABI 2).
    
           -fobjc-nonfragile-abi-version=<version>
                  Select  the Objective-C non-fragile ABI version to use by default. This will only be used as the Objec-
                  tive-C ABI when the non-fragile ABI is enabled (either via -fobjc-nonfragile-abi, or because it is  the
                  platform default).
    
           -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi
                  Enable  use  of the Objective-C non-fragile ABI. On platforms for which this is the default ABI, it can
                  be disabled with -fno-objc-nonfragile-abi.
    
       Target Selection Options
           Clang fully supports cross compilation as an inherent part of its design.  Depending on how  your  version  of
           Clang is configured, it may have support for a number of cross compilers, or may only support a native target.
    
           -arch <architecture>
                  Specify the architecture to build for.
    
           -mmacosx-version-min=<version>
                  When building for macOS, specify the minimum version supported by your application.
    
           -miphoneos-version-min
                  When building for iPhone OS, specify the minimum version supported by your application.
    
           --print-supported-cpus
                  Print out a list of supported processors for the given target  (specified  through  --target=<architec-
                  ture> or -arch <architecture>). If no target is specified, the system default target will be used.
    
           -mcpu=?, -mtune=?
                  Aliases of --print-supported-cpus
    
           -march=<cpu>
                  Specify that Clang should generate code for a specific processor family member and later.  For example,
                  if you specify -march=i486, the compiler is allowed to generate instructions that are valid on i486 and
                  later processors, but which may not exist on earlier ones.
    
       Code Generation Options
           -O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
                  Specify which optimization level to use:
                     -O0 Means "no optimization": this level compiles the fastest and generates the most debuggable code.
    
                     -O1 Somewhere between -O0 and -O2.
    
                     -O2 Moderate level of optimization which enables most optimizations.
    
                     -O3 Like -O2, except that it enables optimizations that take longer to perform or that may  generate
                     larger code (in an attempt to make the program run faster).
    
                     -Ofast  Enables  all  the  optimizations from -O3 along with other aggressive optimizations that may
                     violate strict compliance with language standards.
    
                     -Os Like -O2 with extra optimizations to reduce code size.
    
                     -Oz Like -Os (and thus -O2), but reduces code size further.
    
                     -Og Like -O1. In future versions, this option might disable  different  optimizations  in  order  to
                     improve debuggability.
    
                     -O Equivalent to -O1.
    
                     -O4 and higher
                         Currently equivalent to -O3
    
           -g, -gline-tables-only, -gmodules
                  Control debug information output.  Note that Clang debug information works best at -O0.  When more than
                  one option starting with -g is specified, the last one wins:
                     -g Generate debug information.
    
                     -gline-tables-only Generate only line table debug information. This allows  for  symbolicated  back-
                     traces  with inlining information, but does not include any information about variables, their loca-
                     tions or types.
    
                     -gmodules Generate debug information that contains external references to  types  defined  in  Clang
                     modules  or  precompiled  headers  instead  of  emitting redundant debug type information into every
                     object file.  This option transparently switches the Clang module format to object  file  containers
                     that  hold the Clang module together with the debug information.  When compiling a program that uses
                     Clang modules or precompiled headers, this option produces complete debug  information  with  faster
                     compile times and much smaller object files.
    
                     This  option  should  not  be used when building static libraries for distribution to other machines
                     because the debug info will contain references to the module cache on the machine the  object  files
                     in the library were built on.
    
           -fstandalone-debug -fno-standalone-debug
                  Clang  supports  a  number of optimizations to reduce the size of debug information in the binary. They
                  work based on the assumption that the debug type information can be spread out over  multiple  compila-
                  tion units.  For instance, Clang will not emit type definitions for types that are not needed by a mod-
                  ule and could be replaced with a forward declaration.  Further, Clang will only emit type  info  for  a
                  dynamic C++ class in the module that contains the vtable for the class.
    
                  The  -fstandalone-debug  option  turns  off  these  optimizations.   This  is  useful when working with
                  3rd-party libraries that don't come with debug information.  This is the default on Darwin.  Note  that
                  Clang will never emit type information for types that are not referenced at all by the program.
    
           -fexceptions
                  Enable  generation  of  unwind  information. This allows exceptions to be thrown through Clang compiled
                  stack frames.  This is on by default in x86-64.
    
           -ftrapv
                  Generate code to catch integer overflow errors.  Signed integer overflow is undefined in C.  With  this
                  flag, extra code is generated to detect this and abort when it happens.
    
           -fvisibility
                  This flag sets the default visibility level.
    
           -fcommon, -fno-common
                  This  flag  specifies  that variables without initializers get common linkage.  It can be disabled with
                  -fno-common.
    
           -ftls-model=<model>
                  Set the default thread-local storage (TLS) model to use for thread-local variables. Valid  values  are:
                  "global-dynamic",  "local-dynamic",  "initial-exec"  and "local-exec". The default is "global-dynamic".
                  The default model can be overridden with the tls_model attribute. The compiler will  try  to  choose  a
                  more efficient model if possible.
    
           -flto, -flto=full, -flto=thin, -emit-llvm
                  Generate  output  files  in  LLVM formats, suitable for link time optimization.  When used with -S this
                  generates LLVM intermediate language assembly files,  otherwise  this  generates  LLVM  bitcode  format
                  object files (which may be passed to the linker depending on the stage selection options).
    
                  The  default  for -flto is "full", in which the LLVM bitcode is suitable for monolithic Link Time Opti-
                  mization (LTO), where the linker merges all such modules into a single combined  module  for  optimiza-
                  tion. With "thin", ThinLTO compilation is invoked instead.
    
                  NOTE:
                     On Darwin, when using -flto along with -g and compiling and linking in separate steps, you also need
                     to pass -Wl,-object_path_lto,<lto-filename>.o at the linking step to instruct the ld64 linker not to
                     delete the temporary object file generated during Link Time Optimization (this flag is automatically
                     passed to the linker by Clang if compilation and linking are done in a  single  step).  This  allows
                     debugging the executable as well as generating the .dSYM bundle using dsymutil(1).
    
       Driver Options
           -###   Print (but do not run) the commands to run for this compilation.
    
           --help Display available options.
    
           -Qunused-arguments
                  Do not emit any warnings for unused driver arguments.
    
           -Wa,<args>
                  Pass the comma separated arguments in args to the assembler.
    
           -Wl,<args>
                  Pass the comma separated arguments in args to the linker.
    
           -Wp,<args>
                  Pass the comma separated arguments in args to the preprocessor.
    
           -Xanalyzer <arg>
                  Pass arg to the static analyzer.
    
           -Xassembler <arg>
                  Pass arg to the assembler.
    
           -Xlinker <arg>
                  Pass arg to the linker.
    
           -Xpreprocessor <arg>
                  Pass arg to the preprocessor.
    
           -o <file>
                  Write output to file.
    
           -print-file-name=<file>
                  Print the full library path of file.
    
           -print-libgcc-file-name
                  Print  the  library  path  for  the  currently  used  compiler  runtime  library  ("libgcc.a"  or "lib-
                  clang_rt.builtins.*.a").
    
           -print-prog-name=<name>
                  Print the full program path of name.
    
           -print-search-dirs
                  Print the paths used for finding libraries and programs.
    
           -save-temps
                  Save intermediate compilation results.
    
           -save-stats, -save-stats=cwd, -save-stats=obj
                  Save  internal  code  generation  (LLVM)  statistics  to  a  file   in   the   current   directory   (-
                  -save-stats/"-save-stats=cwd") or the directory of the output file ("-save-state=obj").
    
           -integrated-as, -no-integrated-as
                  Used  to  enable and disable, respectively, the use of the integrated assembler. Whether the integrated
                  assembler is on by default is target dependent.
    
           -time  Time individual commands.
    
           -ftime-report
                  Print timing summary of each stage of compilation.
    
           -v     Show commands to run and use verbose output.
    
       Diagnostics Options
           -fshow-column,    -fshow-source-location,    -fcaret-diagnostics,     -fdiagnostics-fixit-info,     -fdiagnos-
           tics-parseable-fixits,     -fdiagnostics-print-source-range-info,     -fprint-source-range-info,    -fdiagnos-
           tics-show-option, -fmessage-length
                  These options control how Clang prints out information about diagnostics (errors and warnings).  Please
                  see the Clang User's Manual for more information.
    
       Preprocessor Options
           -D<macroname>=<value>
                  Adds  an  implicit  #define  into the predefines buffer which is read before the source file is prepro-
                  cessed.
    
           -U<macroname>
                  Adds an implicit #undef into the predefines buffer which is read before  the  source  file  is  prepro-
                  cessed.
    
           -include <filename>
                  Adds  an  implicit  #include into the predefines buffer which is read before the source file is prepro-
                  cessed.
    
           -I<directory>
                  Add the specified directory to the search path for include files.
    
           -F<directory>
                  Add the specified directory to the search path for framework include files.
    
           -nostdinc
                  Do not search the standard system directories or compiler builtin directories for include files.
    
           -nostdlibinc
                  Do not search the standard system directories for include files, but do search compiler builtin include
                  directories.
    
           -nobuiltininc
                  Do not search clang's builtin directory for include files.
    
    ENVIRONMENT
           TMPDIR, TEMP, TMP
                  These  environment variables are checked, in order, for the location to write temporary files used dur-
    CLANG(1)                                                Clang                                                CLANG(1)
    
    
    
    NAME
           clang - the Clang C, C++, and Objective-C compiler
    
    SYNOPSIS
           clang [options] filename ...
    
    DESCRIPTION
           clang  is a C, C++, and Objective-C compiler which encompasses preprocessing, parsing, optimization, code gen-
           eration, assembly, and linking.  Depending on which high-level mode setting is passed, Clang will stop  before
           doing a full link.  While Clang is highly integrated, it is important to understand the stages of compilation,
           to understand how to invoke it.  These stages are:
    
           Driver The clang executable is actually a small driver which controls the overall  execution  of  other  tools
                  such as the compiler, assembler and linker.  Typically you do not need to interact with the driver, but
                  you transparently use it to run the other tools.
    
           Preprocessing
                  This stage handles tokenization of the input source file, macro expansion, #include expansion and  han-
                  dling  of  other preprocessor directives.  The output of this stage is typically called a ".i" (for C),
                  ".ii" (for C++), ".mi" (for Objective-C), or ".mii" (for Objective-C++) file.
    
           Parsing and Semantic Analysis
                  This stage parses the input file, translating preprocessor tokens into a parse tree.  Once in the  form
                  of  a  parse  tree, it applies semantic analysis to compute types for expressions as well and determine
                  whether the code is well formed. This stage is responsible for generating most of the compiler warnings
                  as well as parse errors. The output of this stage is an "Abstract Syntax Tree" (AST).
    
           Code Generation and Optimization
    :
  • 相关阅读:
    继承
    iOS 适配暗黑模式
    【C++ STL】容器的选择
    纳税相关
    SwiftUI状态绑定:@State
    python 中各种容器可以容纳的数据类型
    open GL 在使用材质属性glMaterial设置物体颜色效果时,使用shader和使用固定管线后颜色区别
    做为一名测试工程师,你经常会用到或听到的那些工具
    推荐一款技术人必备的接口测试神器:Apifox
    测试管理工具推荐
  • 原文地址:https://www.cnblogs.com/lesten/p/16361379.html
Copyright © 2020-2023  润新知