Esempio n. 1
0
        //is this const or not
        public static void PushTypeQualifier(string qualifier)
        {
            var spec = new CDeclarationSpecifier();

            spec.SpeciferType = CDeclarationSpecifierType.Const;
            spec.ConstType    = constTypeFromString(qualifier);
            PushDeclSpec(spec);
        }
Esempio n. 2
0
        internal static void PushTypeDefName(string p)
        {
            var declspec = new CDeclarationSpecifier();

            declspec.SpeciferType = CDeclarationSpecifierType.Name;
            declspec.name         = p;
            PushDeclSpec(declspec);
        }
Esempio n. 3
0
        //enum decl is a specifier
        //the only case where this is not also a definition, is in function prototypes (enum name x), and other weird places. this is one of the cruftyer parts of c
        public static void PushEnumDeclaration(string idString)
        {
            var spec = new CDeclarationSpecifier();

            spec.SpeciferType = CDeclarationSpecifierType.Type;
            spec.type         = CType.DeclareEnum(idString);
            PushDeclSpec(spec);
        }
Esempio n. 4
0
        //void, arithmetic type, typedefed name
        public static void PushTypeSpecifier(string typeName)
        {
            var spec = new CDeclarationSpecifier();

            spec.SpeciferType = CDeclarationSpecifierType.Type;
            spec.type         = CType.CTypeFromName(typeName);
            PushDeclSpec(spec);
        }
Esempio n. 5
0
        //declaration specifiers

        //storage specifers
        //http://en.cppreference.com/w/c/language/storage_duration
        public static void PushStorageClassSpecifier(string specifier)
        {
            var spec = new CDeclarationSpecifier();

            spec.SpeciferType = CDeclarationSpecifierType.Storage;
            spec.StorageClass = StorageClassFromString(specifier);
            PushDeclSpec(spec);
        }
Esempio n. 6
0
        //exit function scope
        public static void EndFunctionDefinition(int numSpecifiers)
        {
            CIdentifier.ExitFunctionScope();

            List <CDeclarationSpecifier> specs = new List <CDeclarationSpecifier>();

            for (int i = 0; i < numSpecifiers; i++)
            {
                specs.Add(PopDeclSpec());
            }

            CDeclarationSpecifier typeSpec     = specs.First(spec => spec.SpeciferType == CDeclarationSpecifierType.Type);
            CDeclarationSpecifier storageClass = specs.FirstOrDefault(spec => spec.SpeciferType == CDeclarationSpecifierType.Storage);

            CDeclarator paramDecl = PopDeclarator();

            CIdentifier.DefineFunction(paramDecl.TypeModifier.ModifyType(typeSpec.type), paramDecl.Identifer, storageClass == null ? CStorageClass.Ignore : storageClass.StorageClass);
        }
Esempio n. 7
0
        //paramaters

        //define param in function scope or function prototype scope
        public static void ParamaterDeclaration(int numSpecifiers)
        {
            List <CDeclarationSpecifier> specs = new List <CDeclarationSpecifier>();

            for (int i = 0; i < numSpecifiers; i++)
            {
                specs.Add(PopDeclSpec());
            }

            CDeclarationSpecifier typeSpec = specs.First(spec => spec.SpeciferType == CDeclarationSpecifierType.Type);

            //ignore const and register specifiers on params

            CDeclarator declarator = PopDeclarator();

            CParamater param = CIdentifier.CreateFunctionParameter(
                declarator.Identifer,
                declarator.TypeModifier != null ? declarator.TypeModifier.ModifyType(typeSpec.type) : typeSpec.type
                );

            PushParam(param);
        }
Esempio n. 8
0
 private static void PushDeclSpec(CDeclarationSpecifier declSpec)
 {
     declSpecs.Push(declSpec);
 }
Esempio n. 9
0
        //storage and linkage
        //http://en.cppreference.com/w/c/language/storage_duration

        /*
         * Every object has a property called storage duration, which limits the object lifetime. There are four kinds of storage duration in C:
         *
         * automatic storage duration.
         * The storage is allocated when the block in which the object was declared is entered and
         * deallocated when it is exited by any means (goto, return, reaching the end). If the block is entered recursively, a new allocation is performed for every recursion level. All function parameters and non-static block-scope objects have this storage duration.
         *
         * static storage duration.
         * The storage duration is the entire execution of the program,
         * and the value stored in the object is initialized only once, prior to main function.
         * All objects declared static and all objects with either internal or external linkage have this storage duration.
         *
         * thread storage duration. NOT SUPPORTED
         *
         * allocated storage duration.
         * The storage is allocated and deallocated on request, using dynamic memory allocation functions.
         *
         * Linkage
         * Linkage refers to the ability of an identifier (variable or function) to be referred to in other scopes.
         * If a variable or function with the same identifier is declared in several scopes,
         * but cannot be referred to from all of them, then several instances of the variable are generated.
         *
         * The following linkages are recognized:
         *
         * no linkage.
         * The identifier can be referred to only from the scope it is in.
         * All function parameters and all non-extern block-scope variables (including the ones declared static) have this linkage.
         *
         * internal linkage.
         * The identifier can be referred to from all scopes in the current translation unit.
         * All static identifiers (both functions and variables) have this linkage.
         *
         * external linkage.
         * The identifier can be referred to from any other translation units in the entire program.
         * All non-static functions, all extern variables (unless earlier declared static), and all file-scope non-static variables have this linkage.
         *
         * Names at file scope that are const and not extern have external linkage in C
         *
         * Storage-class specifiers specify one of the following combinations of storage duration and linkage
         * auto - automatic duration and no linkage (on stack)
         * register - NOT SUPPORTED
         * static - static duration and internal linkage (unless at block scope) (in data or rodata segment)
         * extern - static duration and external linkage (unless already declared internal) (on heap)
         *
         * If no storage-class specifier is provided, the defaults are:
         * extern for all functions
         * extern for objects at file scope
         * auto for objects at block scope
         *
         * For any struct or union declared with a storage-class specifier,
         * the storage duration (but not linkage) applies to their members, recursively.
         *
         * Function declarations at block scope can use extern or none at all.
         * Function declarations at file scope can use extern or static.
         */

        //scope
        //http://en.cppreference.com/w/c/language/scope

        /*Each identifier that appears in a C program is visible (that is, may be used) only in some possibly discontiguous portion of the source code called its scope.
         * Within a scope, an identifier may designate more than one entity only if the entities are in different name spaces.
         * C has four kinds of scopes:
         *  block scope
         *  file scope
         *  function scope
         *  function prototype scope
         *
         * Nested scopes
         * If two different entities named by the same identifier are in scope at the same time,
         * and the scopes are nested,
         * the declaration that appears in the inner scope hides the declaration that appears in the outer scope
         *
         * Block Scope
         * The scope of any identifier declared inside a compound statement,
         * including function bodies,
         * or in any expression, declaration, or statement appearing in
         * if, switch, for, while, or do-while statement,
         * or within the parameter list of a function definition
         * begins at the point of declaration and ends at the end of the block or statement in which it was declared.
         *
         * File scope
         * The scope of any identifier declared outside of any block or parameter list begins at the point of declaration and ends at the end of the translation unit (file).
         * File-scope identifiers have external linkage and static storage duration by default.
         *
         * Function scope
         * A label (and only a label) declared inside a function is in scope everywhere in that function, in all nested blocks, before and after its own declaration.
         *
         * Function prototype scope
         * The scope of a name introduced in the parameter list of a function declaration ends at the end of the function declarator.
         */

        //declarations
        //http://en.cppreference.com/w/c/language/declarations
        //A declaration is a C language construct that introduces one or more identifiers into the program and specifies their meaning and properties.
        //Declarations may appear in any scope. Each declaration ends with a semicolon (just like a statement) and consists of two distinct parts:

        /*
         * specifiers-and-qualifiers	-	whitespace-separated list of, in any order,
         *  exactly one type specifier:
         *      void
         *      the name of an arithmetic type
         *      the name of an atomic type
         *      a name earlier introduced by a typedef declaration
         *      struct, union, or enum specifier
         *  zero or one storage-class specifiers:
         *      typedef,
         *      auto,
         *      static,
         *      extern
         *  optional const
         *
         *  declarators-and-initializers	-	comma-separated list of declarators
         *  (each declarator provides additional type information and/or the identifier to declare).
         *  Declarators may be accompanied by initializers.
         */
        public static void Declaration(int numSpecifier, int numDeclarators)
        {
            List <CDeclarationSpecifier> specifiers = new List <CDeclarationSpecifier>();

            for (int i = 0; i < numSpecifier; i++)
            {
                specifiers.Add(PopDeclSpec());
            }

            //TODO hanldle unsigned, signed, long, typedef name
            IEnumerable <CDeclarationSpecifier> typeSpecs = specifiers.Where(spec => spec.SpeciferType == CDeclarationSpecifierType.Type);

            CType resolvedType = CType.ResolveTypeFromSpecifers(typeSpecs);

            IEnumerable <CDeclarationSpecifier> typeDefNames = specifiers.Where(spec => spec.SpeciferType == CDeclarationSpecifierType.Name);

            CDeclarationSpecifier storageClass   = specifiers.FirstOrDefault(spec => spec.SpeciferType == CDeclarationSpecifierType.Storage);
            CDeclarationSpecifier constQualifier = specifiers.FirstOrDefault(spec => spec.SpeciferType == CDeclarationSpecifierType.Const);

            List <CDeclarator> declarators = new List <CDeclarator>();

            for (int i = 0; i < numDeclarators; i++)
            {
                declarators.Add(PopDeclarator());
            }

            List <CIdentifier> declared = new List <CIdentifier>();

            foreach (CDeclarator declarator in declarators)
            {
                CIdentifier id = CIdentifier.CreateIdentifierInCurrentScope(declarator.Identifer, declarator.TypeModifier != null ?  declarator.TypeModifier.ModifyType(resolvedType) : resolvedType, storageClass == null ? CStorageClass.Ignore : storageClass.StorageClass, constQualifier == null ? CConstType.Ignore : constQualifier.ConstType);

                if (declarator.Init != null)
                {
                    id.Init = declarator.Init;
                }

                declared.Add(id);
            }

            if (declared.Count == 0)
            {
                if (storageClass != null && storageClass.StorageClass == CStorageClass.Typedef)
                {
                    //this is a typedef
                    foreach (var defSpec in typeDefNames)
                    {
                        CType.TypeDef(defSpec.name, resolvedType);
                    }
                }
                else
                {
                    //this is a declaration without a declarator
                    var name = typeDefNames.First();

                    CIdentifier id = CIdentifier.CreateIdentifierInCurrentScope(name.name, resolvedType, storageClass == null ? CStorageClass.Ignore : storageClass.StorageClass, constQualifier == null ? CConstType.Ignore : constQualifier.ConstType);

                    declared.Add(id);
                }
            }

            PushDecl(new CDeclaration(declared));
        }