Changeset 2fa5bd2 for src


Ignore:
Timestamp:
Dec 12, 2019, 10:04:15 AM (5 years ago)
Author:
Dmitry Kobets <dkobets@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
e752e4e
Parents:
aca6a54c (diff), 2cd949b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into vector-generic

Location:
src
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    raca6a54c r2fa5bd2  
    887887                auto expr = visitBaseExpr( node,
    888888                        new AsmExpr(
    889                                 get<Expression>().accept1(node->inout),
     889                                new std::string(node->inout),
    890890                                get<Expression>().accept1(node->constraint),
    891891                                get<Expression>().accept1(node->operand)
     
    22582258                        new ast::AsmExpr(
    22592259                                old->location,
    2260                                 GET_ACCEPT_1(inout, Expr),
     2260                                old->inout,
    22612261                                GET_ACCEPT_1(constraint, Expr),
    22622262                                GET_ACCEPT_1(operand, Expr)
  • src/AST/Expr.hpp

    raca6a54c r2fa5bd2  
    556556class AsmExpr final : public Expr {
    557557public:
    558         ptr<Expr> inout;
     558        std::string inout;
    559559        ptr<Expr> constraint;
    560560        ptr<Expr> operand;
    561561
    562         AsmExpr( const CodeLocation & loc, const Expr * io, const Expr * con, const Expr * op )
     562        AsmExpr( const CodeLocation & loc, const std::string & io, const Expr * con, const Expr * op )
    563563        : Expr( loc ), inout( io ), constraint( con ), operand( op ) {}
    564564
  • src/AST/Pass.impl.hpp

    raca6a54c r2fa5bd2  
    13001300                        maybe_accept( node, &AsmExpr::result );
    13011301                }
    1302                 maybe_accept( node, &AsmExpr::inout      );
    13031302                maybe_accept( node, &AsmExpr::constraint );
    13041303                maybe_accept( node, &AsmExpr::operand    );
  • src/AST/Print.cpp

    raca6a54c r2fa5bd2  
    10111011                os << "Asm Expression:" << endl;
    10121012                ++indent;
    1013                 if ( node->inout ) node->inout->accept( *this );
     1013                if ( !node->inout.empty() ) os << "[" << node->inout << "] ";
    10141014                if ( node->constraint ) node->constraint->accept( *this );
    10151015                if ( node->operand ) node->operand->accept( *this );
  • src/CodeGen/CodeGenerator.cc

    raca6a54c r2fa5bd2  
    786786
    787787        void CodeGenerator::postvisit( AsmExpr * asmExpr ) {
    788                 if ( asmExpr->get_inout() ) {
     788                if ( !asmExpr->inout.empty() ) {
    789789                        output << "[ ";
    790                         asmExpr->get_inout()->accept( *visitor );
     790                        output << asmExpr->inout;
    791791                        output << " ] ";
    792792                } // if
    793                 asmExpr->get_constraint()->accept( *visitor );
     793                asmExpr->constraint->accept( *visitor );
    794794                output << " ( ";
    795                 asmExpr->get_operand()->accept( *visitor );
     795                asmExpr->operand->accept( *visitor );
    796796                output << " )";
    797797        }
  • src/Common/PassVisitor.impl.h

    raca6a54c r2fa5bd2  
    24522452
    24532453        indexerScopedAccept( node->result    , *this );
    2454         maybeAccept_impl   ( node->inout     , *this );
    24552454        maybeAccept_impl   ( node->constraint, *this );
    24562455        maybeAccept_impl   ( node->operand   , *this );
     
    24642463
    24652464        indexerScopedAccept( node->result    , *this );
    2466         maybeAccept_impl   ( node->inout     , *this );
    24672465        maybeAccept_impl   ( node->constraint, *this );
    24682466        maybeAccept_impl   ( node->operand   , *this );
     
    24772475        indexerScopedMutate( node->env       , *this );
    24782476        indexerScopedMutate( node->result    , *this );
    2479         maybeMutate_impl   ( node->inout     , *this );
    24802477        maybeMutate_impl   ( node->constraint, *this );
    24812478        maybeMutate_impl   ( node->operand   , *this );
  • src/Common/SemanticError.cc

    raca6a54c r2fa5bd2  
    149149// Helpers
    150150namespace ErrorHelpers {
     151        Colors colors = Colors::Auto;
     152
     153        static inline bool with_colors() {
     154                return colors == Colors::Auto ? isatty( STDERR_FILENO ) : bool(colors);
     155        }
     156
    151157        const std::string & error_str() {
    152                 static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
     158                static std::string str = with_colors() ? "\e[31merror:\e[39m " : "error: ";
    153159                return str;
    154160        }
    155161
    156162        const std::string & warning_str() {
    157                 static std::string str = isatty( STDERR_FILENO ) ? "\e[95mwarning:\e[39m " : "warning: ";
     163                static std::string str = with_colors() ? "\e[95mwarning:\e[39m " : "warning: ";
    158164                return str;
    159165        }
    160166
    161167        const std::string & bold_ttycode() {
    162                 static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
     168                static std::string str = with_colors() ? "\e[1m" : "";
    163169                return str;
    164170        }
    165171
    166172        const std::string & reset_font_ttycode() {
    167                 static std::string str = isatty( STDERR_FILENO ) ? "\e[0m" : "";
     173                static std::string str = with_colors() ? "\e[0m" : "";
    168174                return str;
    169175        }
  • src/Common/SemanticError.h

    raca6a54c r2fa5bd2  
    9797// Helpers
    9898namespace ErrorHelpers {
     99        enum class Colors {
     100                Never = false,
     101                Always = true,
     102                Auto,
     103        };
     104
     105        extern Colors colors;
     106
    99107        const std::string & error_str();
    100108        const std::string & warning_str();
  • src/Concurrency/Keywords.cc

    raca6a54c r2fa5bd2  
    5959
    6060                Declaration * postmutate( StructDecl * decl );
     61                DeclarationWithType * postmutate( FunctionDecl * decl );
    6162
    6263                void handle( StructDecl * );
     
    7778                KeywordCastExpr::Target cast_target;
    7879
    79                 StructDecl* type_decl = nullptr;
     80                StructDecl   * type_decl = nullptr;
     81                FunctionDecl * dtor_decl = nullptr;
    8082        };
    8183
     
    9799                        "__thrd",
    98100                        "get_thread",
    99                         "thread keyword requires threads to be in scope, add #include <thread.hfa>",
     101                        "thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
    100102                        true,
    101103                        KeywordCastExpr::Thread
     
    129131                        "__cor",
    130132                        "get_coroutine",
    131                         "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>",
     133                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
    132134                        true,
    133135                        KeywordCastExpr::Coroutine
     
    161163                        "__mon",
    162164                        "get_monitor",
    163                         "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>",
     165                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
    164166                        false,
    165167                        KeywordCastExpr::Monitor
     
    284286        }
    285287
     288        DeclarationWithType * ConcurrentSueKeyword::postmutate( FunctionDecl * decl ) {
     289                if( !type_decl ) return decl;
     290                if( !CodeGen::isDestructor( decl->name ) ) return decl;
     291
     292                auto params = decl->type->parameters;
     293                if( params.size() != 1 ) return decl;
     294
     295                auto type = dynamic_cast<ReferenceType*>( params.front()->get_type() );
     296                if( !type ) return decl;
     297
     298                auto stype = dynamic_cast<StructInstType*>( type->base );
     299                if( !stype ) return decl;
     300                if( stype->baseStruct != type_decl ) return decl;
     301
     302                if( !dtor_decl ) dtor_decl = decl;
     303                return decl;
     304        }
     305
    286306        Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) {
    287307                if ( cast_target == cast->target ) {
    288308                        // convert (thread &)t to (thread_desc &)*get_thread(t), etc.
    289309                        if( !type_decl ) SemanticError( cast, context_error );
    290                         Expression * arg = cast->arg;
    291                         cast->arg = nullptr;
    292                         delete cast;
    293                         return new CastExpr(
    294                                 UntypedExpr::createDeref(
    295                                         new UntypedExpr( new NameExpr( getter_name ), { arg } )
    296                                 ),
    297                                 new ReferenceType(
    298                                         noQualifiers,
    299                                         new StructInstType( noQualifiers, type_decl ) )
    300                                 );
     310                        if( !dtor_decl ) SemanticError( cast, context_error );
     311                        assert( cast->result == nullptr );
     312                        cast->set_result( new ReferenceType( noQualifiers, new StructInstType( noQualifiers, type_decl ) ) );
     313                        cast->concrete_target.field  = field_name;
     314                        cast->concrete_target.getter = getter_name;
    301315                }
    302316                return cast;
     
    308322
    309323                if( !type_decl ) SemanticError( decl, context_error );
     324                if( !dtor_decl ) SemanticError( decl, context_error );
    310325
    311326                FunctionDecl * func = forwardDeclare( decl );
  • src/ControlStruct/MLEMutator.cc

    raca6a54c r2fa5bd2  
    231231
    232232        Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
     233                // only generate these when needed
     234                if( !e.isContUsed() && !e.isBreakUsed() ) return bodyLoop;
     235
    233236                // ensure loop body is a block
    234                 CompoundStmt *newBody;
    235                 if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
    236                         newBody = new CompoundStmt();
    237                         newBody->get_kids().push_back( bodyLoop );
    238                 } // if
    239 
    240                 // only generate these when needed
     237                CompoundStmt * newBody = new CompoundStmt();
     238                newBody->get_kids().push_back( bodyLoop );
    241239
    242240                if ( e.isContUsed() ) {
  • src/GenPoly/Lvalue.cc

    raca6a54c r2fa5bd2  
    6060                }
    6161
    62                 struct ReferenceConversions final : public WithStmtsToAdd {
     62                struct ReferenceConversions final : public WithStmtsToAdd, public WithGuards {
    6363                        Expression * postmutate( CastExpr * castExpr );
    6464                        Expression * postmutate( AddressExpr * addrExpr );
     
    7171
    7272                struct FixIntrinsicResult final : public WithGuards {
     73                        enum {
     74                                NoSkip,
     75                                Skip,
     76                                SkipInProgress
     77                        } skip = NoSkip;
     78
     79                        void premutate( AsmExpr * ) { GuardValue( skip ); skip = Skip; }
     80                        void premutate( ApplicationExpr * ) { GuardValue( skip ); skip = (skip == Skip) ? SkipInProgress : NoSkip; }
     81
     82
    7383                        Expression * postmutate( ApplicationExpr * appExpr );
    7484                        void premutate( FunctionDecl * funcDecl );
     
    162172
    163173                Expression * FixIntrinsicResult::postmutate( ApplicationExpr * appExpr ) {
    164                         if ( isIntrinsicReference( appExpr ) ) {
     174                        if ( skip != SkipInProgress && isIntrinsicReference( appExpr ) ) {
    165175                                // eliminate reference types from intrinsic applications - now they return lvalues
    166176                                ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result );
  • src/Parser/parser.yy

    raca6a54c r2fa5bd2  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  4 21:48:23 2019
    13 // Update Count     : 4364
     12// Last Modified On : Sat Dec  7 10:43:44 2019
     13// Update Count     : 4394
    1414//
    1515
     
    211211} // forCtrl
    212212
     213KeywordCastExpr::Target Aggregate2Target( DeclarationNode::Aggregate aggr ) {
     214        KeywordCastExpr::Target target;
     215        switch ( aggr ) {
     216          case DeclarationNode::Coroutine: target = KeywordCastExpr::Coroutine; break;
     217          case DeclarationNode::Monitor: target = KeywordCastExpr::Monitor; break;
     218          case DeclarationNode::Thread: target = KeywordCastExpr::Thread; break;
     219          default: abort();
     220        } // switch
     221        return target;
     222} // Aggregate2Target
     223
    213224
    214225bool forall = false, yyy = false;                                               // aggregate have one or more forall qualifiers ?
     
    365376%type<decl> abstract_parameter_declaration
    366377
    367 %type<aggKey> aggregate_key
     378%type<aggKey> aggregate_key aggregate_data aggregate_control
    368379%type<decl> aggregate_type aggregate_type_nobody
    369380
     
    650661        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    651662                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     663        | postfix_expression '.' aggregate_control
     664                { $$ = new ExpressionNode( build_keyword_cast( Aggregate2Target( $3 ), $1 ) ); }
    652665        | postfix_expression ARROW identifier
    653666                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     
    793806        | '(' type_no_function ')' cast_expression
    794807                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    795                 // keyword cast cannot be grouped because of reduction in aggregate_key
    796         | '(' GENERATOR '&' ')' cast_expression                         // CFA
    797                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    798         | '(' COROUTINE '&' ')' cast_expression                         // CFA
    799                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    800         | '(' THREAD '&' ')' cast_expression                            // CFA
    801                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Thread, $5 ) ); }
    802         | '(' MONITOR '&' ')' cast_expression                           // CFA
    803                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Monitor, $5 ) ); }
     808        | '(' aggregate_control '&' ')' cast_expression         // CFA
     809                { $$ = new ExpressionNode( build_keyword_cast( Aggregate2Target( $2 ), $5 ) ); }
    804810                // VIRTUAL cannot be opt because of look ahead issues
    805811        | '(' VIRTUAL ')' cast_expression                                       // CFA
     
    14231429asm_operand:                                                                                    // GCC
    14241430        string_literal '(' constant_expression ')'
    1425                 { $$ = new ExpressionNode( new AsmExpr( maybeMoveBuild< Expression >( (ExpressionNode *)nullptr ), $1, maybeMoveBuild< Expression >( $3 ) ) ); }
    1426         | '[' constant_expression ']' string_literal '(' constant_expression ')'
    1427                 { $$ = new ExpressionNode( new AsmExpr( maybeMoveBuild< Expression >( $2 ), $4, maybeMoveBuild< Expression >( $6 ) ) ); }
     1431                { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild< Expression >( $3 ) ) ); }
     1432        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
     1433                { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild< Expression >( $6 ) ) ); }
    14281434        ;
    14291435
     
    20592065
    20602066aggregate_key:
     2067        aggregate_data
     2068        | aggregate_control
     2069        ;
     2070
     2071aggregate_data:
    20612072        STRUCT
    20622073                { yyy = true; $$ = DeclarationNode::Struct; }
    20632074        | UNION
    20642075                { yyy = true; $$ = DeclarationNode::Union; }
    2065         | EXCEPTION
     2076        | EXCEPTION                                                                                     // CFA
    20662077                { yyy = true; $$ = DeclarationNode::Exception; }
    2067         | GENERATOR
     2078        ;
     2079
     2080aggregate_control:                                                                              // CFA
     2081        GENERATOR
    20682082                { yyy = true; $$ = DeclarationNode::Coroutine; }
    20692083        | COROUTINE
     
    20962110                        distInl( $3 );
    20972111                }
     2112        | INLINE aggregate_control ';'                                          // CFA
     2113                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    20982114        | typedef_declaration ';'                                                       // CFA
    20992115        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
  • src/ResolvExpr/AlternativeFinder.cc

    raca6a54c r2fa5bd2  
    6969                void postvisit( CastExpr * castExpr );
    7070                void postvisit( VirtualCastExpr * castExpr );
     71                void postvisit( KeywordCastExpr * castExpr );
    7172                void postvisit( UntypedMemberExpr * memberExpr );
    7273                void postvisit( MemberExpr * memberExpr );
     
    12551256        }
    12561257
     1258        void AlternativeFinder::Finder::postvisit( KeywordCastExpr * castExpr ) {
     1259                assertf( castExpr->get_result(), "Cast target should have been set in Validate." );
     1260                auto ref = dynamic_cast<ReferenceType*>(castExpr->get_result());
     1261                assert(ref);
     1262                auto inst = dynamic_cast<StructInstType*>(ref->base);
     1263                assert(inst);
     1264                auto target = inst->baseStruct;
     1265
     1266                AlternativeFinder finder( indexer, env );
     1267
     1268                auto pick_alternatives = [target, this](AltList & found, bool expect_ref) {
     1269                        for(auto & alt : found) {
     1270                                Type * expr = alt.expr->get_result();
     1271                                if(expect_ref) {
     1272                                        auto res = dynamic_cast<ReferenceType*>(expr);
     1273                                        if(!res) { continue; }
     1274                                        expr = res->base;
     1275                                }
     1276
     1277                                if(auto insttype = dynamic_cast<TypeInstType*>(expr)) {
     1278                                        auto td = alt.env.lookup(insttype->name);
     1279                                        if(!td) { continue; }
     1280                                        expr = td->type;
     1281                                }
     1282
     1283                                if(auto base = dynamic_cast<StructInstType*>(expr)) {
     1284                                        if(base->baseStruct == target) {
     1285                                                alternatives.push_back(
     1286                                                        std::move(alt)
     1287                                                );
     1288                                        }
     1289                                }
     1290                        }
     1291                };
     1292
     1293                try {
     1294                        // Attempt 1 : turn (thread&)X into (thread_desc&)X.__thrd
     1295                        // Clone is purely for memory management
     1296                        std::unique_ptr<Expression> tech1 { new UntypedMemberExpr(new NameExpr(castExpr->concrete_target.field), castExpr->arg->clone()) };
     1297
     1298                        // don't prune here, since it's guaranteed all alternatives will have the same type
     1299                        finder.findWithoutPrune( tech1.get() );
     1300                        pick_alternatives(finder.alternatives, false);
     1301
     1302                        return;
     1303                } catch(SemanticErrorException & ) {}
     1304
     1305                // Fallback : turn (thread&)X into (thread_desc&)get_thread(X)
     1306                std::unique_ptr<Expression> fallback { UntypedExpr::createDeref( new UntypedExpr(new NameExpr(castExpr->concrete_target.getter), { castExpr->arg->clone() })) };
     1307                // don't prune here, since it's guaranteed all alternatives will have the same type
     1308                finder.findWithoutPrune( fallback.get() );
     1309
     1310                pick_alternatives(finder.alternatives, true);
     1311
     1312                // Whatever happens here, we have no more fallbacks
     1313        }
     1314
    12571315        namespace {
    12581316                /// Gets name from untyped member expression (member must be NameExpr)
  • src/ResolvExpr/Resolver.cc

    raca6a54c r2fa5bd2  
    485485                visit_children = false;
    486486                findVoidExpression( asmExpr->operand, indexer );
    487                 if ( asmExpr->get_inout() ) {
    488                         findVoidExpression( asmExpr->inout, indexer );
    489                 } // if
    490487        }
    491488
     
    13651362                asmExpr = ast::mutate_field(
    13661363                        asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
    1367 
    1368                 if ( asmExpr->inout ) {
    1369                         asmExpr = ast::mutate_field(
    1370                                 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
    1371                 }
    13721364
    13731365                return asmExpr;
  • src/SynTree/Expression.cc

    raca6a54c r2fa5bd2  
    527527}
    528528
    529 AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
     529AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( other.inout ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
    530530
    531531
    532532void AsmExpr::print( std::ostream & os, Indenter indent ) const {
    533533        os << "Asm Expression: " << std::endl;
    534         if ( inout ) inout->print( os, indent+1 );
     534        if ( !inout.empty() ) os <<  "[" << inout << "] ";
    535535        if ( constraint ) constraint->print( os, indent+1 );
    536536        if ( operand ) operand->print( os, indent+1 );
  • src/SynTree/Expression.h

    raca6a54c r2fa5bd2  
    231231        enum Target {
    232232                Coroutine, Thread, Monitor, NUMBER_OF_TARGETS
    233         } target;
     233        };
     234        struct Concrete {
     235                std::string field;
     236                std::string getter;
     237        };
     238        Target target;
     239        Concrete concrete_target;
    234240
    235241        KeywordCastExpr( Expression * arg, Target target );
     
    575581class AsmExpr : public Expression {
    576582  public:
    577         Expression * inout;
     583        std::string inout;
    578584        Expression * constraint;
    579585        Expression * operand;
    580586
    581         AsmExpr( Expression * inout, Expression * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
     587        AsmExpr( const std::string * _inout, Expression * constraint, Expression * operand ) : inout( _inout ? *_inout : "" ), constraint( constraint ), operand( operand ) { delete _inout; }
    582588        AsmExpr( const AsmExpr & other );
    583         virtual ~AsmExpr() { delete inout; delete constraint; delete operand; };
    584 
    585         Expression * get_inout() const { return inout; }
    586         void set_inout( Expression * newValue ) { inout = newValue; }
    587 
    588         Expression * get_constraint() const { return constraint; }
    589         void set_constraint( Expression * newValue ) { constraint = newValue; }
    590 
    591         Expression * get_operand() const { return operand; }
    592         void set_operand( Expression * newValue ) { operand = newValue; }
     589        virtual ~AsmExpr() { delete constraint; delete operand; };
    593590
    594591        virtual AsmExpr * clone() const override { return new AsmExpr( * this ); }
  • src/cfa.make

    raca6a54c r2fa5bd2  
    44LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
    55        $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
    6         $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
    7         $(AM_CFLAGS) $(CFLAGS)
     6        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(AM_CFLAGS) $(CFAFLAGS) $(CFLAGS)
    87
    98AM_V_CFA = $(am__v_CFA_@AM_V@)
  • src/main.cc

    raca6a54c r2fa5bd2  
    407407
    408408
    409 static const char optstring[] = ":hlLmNnpP:S:twW:D:";
     409static const char optstring[] = ":c:ghlLmNnpP:S:twW:D:";
    410410
    411411enum { PreludeDir = 128 };
    412412static struct option long_opts[] = {
     413        { "colors", required_argument, nullptr, 'c' },
     414        { "gdb", no_argument, nullptr, 'g' },
    413415        { "help", no_argument, nullptr, 'h' },
    414416        { "libcfa", no_argument, nullptr, 'l' },
     
    422424        { "statistics", required_argument, nullptr, 'S' },
    423425        { "tree", no_argument, nullptr, 't' },
    424         { "gdb", no_argument, nullptr, 'g' },
    425426        { "", no_argument, nullptr, 0 },                                        // -w
    426427        { "", no_argument, nullptr, 0 },                                        // -W
     
    430431
    431432static const char * description[] = {
    432         "print help message",                                                           // -h
    433         "generate libcfa.c",                                                            // -l
    434         "generate line marks",                                                          // -L
    435         "do not replace main",                                                          // -m
    436         "do not generate line marks",                                           // -N
    437         "do not read prelude",                                                          // -n
     433        "diagnostic color: never, always, or auto.",          // -c
     434        "wait for gdb to attach",                             // -g
     435        "print help message",                                 // -h
     436        "generate libcfa.c",                                  // -l
     437        "generate line marks",                                // -L
     438        "do not replace main",                                // -m
     439        "do not generate line marks",                         // -N
     440        "do not read prelude",                                // -n
    438441        "generate prototypes for prelude functions",            // -p
    439         "print",                                                                                        // -P
     442        "print",                                              // -P
    440443        "<directory> prelude directory for debug/nodebug",      // no flag
    441444        "<option-list> enable profiling information:\n          counters,heap,time,all,none", // -S
    442         "building cfa standard lib",                                                                    // -t
    443         "wait for gdb to attach",                                                                       // -g
    444         "",                                                                                                     // -w
    445         "",                                                                                                     // -W
    446         "",                                                                                                     // -D
     445        "building cfa standard lib",                          // -t
     446        "",                                                   // -w
     447        "",                                                   // -W
     448        "",                                                   // -D
    447449}; // description
    448450
     
    512514        while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) {
    513515                switch ( c ) {
     516                  case 'c':                                                                             // diagnostic colors
     517                        if ( strcmp( optarg, "always" ) == 0 ) {
     518                                ErrorHelpers::colors = ErrorHelpers::Colors::Always;
     519                        } else if ( strcmp( optarg, "never" ) == 0 ) {
     520                                ErrorHelpers::colors = ErrorHelpers::Colors::Never;
     521                        } else if ( strcmp( optarg, "auto" ) == 0 ) {
     522                                ErrorHelpers::colors = ErrorHelpers::Colors::Auto;
     523                        } // if
     524                        break;
    514525                  case 'h':                                                                             // help message
    515526                        usage( argv );                                                          // no return
Note: See TracChangeset for help on using the changeset viewer.