blob: bf34a247caff4c503297619f2d8ac012f6bc6162 [file] [log] [blame]
peter klauslerdd9923b2018-02-16 19:42:171#ifndef FORTRAN_PARSER_PREPROCESSOR_H_
2#define FORTRAN_PARSER_PREPROCESSOR_H_
peter klausler90cd9ba2018-01-30 19:54:313
4// A Fortran-aware preprocessing module used by the prescanner to implement
5// preprocessing directives and macro replacement. Intended to be efficient
6// enough to always run on all source files even when no preprocessing is
peter klausler783d5622018-02-13 20:50:477// performed, so that special compiler command options &/or source file name
peter klausler90cd9ba2018-01-30 19:54:318// extensions for preprocessing will not be necessary.
9
peter klausler09865ff2018-02-09 22:04:1110#include "provenance.h"
peter klausler783d5622018-02-13 20:50:4711#include "token-sequence.h"
peter klausler90cd9ba2018-01-30 19:54:3112#include <list>
peter klausler16c6f532018-02-05 22:29:2613#include <stack>
peter klausler90cd9ba2018-01-30 19:54:3114#include <string>
15#include <unordered_map>
16#include <vector>
17
18namespace Fortran {
peter klausler0ba1a142018-02-07 20:04:4219namespace parser {
peter klausler90cd9ba2018-01-30 19:54:3120
peter klausler90cd9ba2018-01-30 19:54:3121class Prescanner;
22
peter klausler90cd9ba2018-01-30 19:54:3123// Defines a macro
24class Definition {
peter klauslerbdea10d2018-02-05 20:54:3625public:
peter klausler90cd9ba2018-01-30 19:54:3126 Definition(const TokenSequence &, size_t firstToken, size_t tokens);
27 Definition(const std::vector<std::string> &argNames, const TokenSequence &,
peter klausler16c6f532018-02-05 22:29:2628 size_t firstToken, size_t tokens, bool isVariadic = false);
peter klausler97a7c502018-02-12 22:43:1629 Definition(const std::string &predefined, AllSources *);
peter klausler90cd9ba2018-01-30 19:54:3130
31 bool isFunctionLike() const { return isFunctionLike_; }
32 size_t argumentCount() const { return argumentCount_; }
33 bool isVariadic() const { return isVariadic_; }
34 bool isDisabled() const { return isDisabled_; }
peter klauslerad7125f2018-02-01 23:01:2335 bool isPredefined() const { return isPredefined_; }
peter klausler90cd9ba2018-01-30 19:54:3136 const TokenSequence &replacement() const { return replacement_; }
37
38 bool set_isDisabled(bool disable);
39
peter klausler03aecfc2018-02-16 19:14:1140 TokenSequence Apply(const std::vector<TokenSequence> &args, AllSources *);
peter klausler90cd9ba2018-01-30 19:54:3141
peter klauslerbdea10d2018-02-05 20:54:3642private:
peter klausler90cd9ba2018-01-30 19:54:3143 static TokenSequence Tokenize(const std::vector<std::string> &argNames,
peter klausler16c6f532018-02-05 22:29:2644 const TokenSequence &token, size_t firstToken, size_t tokens);
peter klausler90cd9ba2018-01-30 19:54:3145
46 bool isFunctionLike_{false};
47 size_t argumentCount_{0};
48 bool isVariadic_{false};
49 bool isDisabled_{false};
peter klauslerad7125f2018-02-01 23:01:2350 bool isPredefined_{false};
peter klausler90cd9ba2018-01-30 19:54:3151 TokenSequence replacement_;
52};
53
54// Preprocessing state
55class Preprocessor {
peter klauslerbdea10d2018-02-05 20:54:3656public:
peter klausler5b61bea2018-02-13 20:24:5457 explicit Preprocessor(AllSources *);
peter klausler90cd9ba2018-01-30 19:54:3158
peter klausler0983fbc2018-03-16 23:13:4959 void Define(std::string macro, std::string value);
60 void Undefine(std::string macro);
61
peter klausler90cd9ba2018-01-30 19:54:3162 // When the input contains macros to be replaced, the new token sequence
63 // is appended to the output and the returned value is true. When
64 // no macro replacement is necessary, the output is unmodified and the
65 // return value is false.
peter klausler5b61bea2018-02-13 20:24:5466 bool MacroReplacement(
67 const TokenSequence &, const Prescanner &, TokenSequence *);
peter klausler90cd9ba2018-01-30 19:54:3168
peter klausler0983fbc2018-03-16 23:13:4969 // Implements a preprocessor directive.
70 void Directive(const TokenSequence &, Prescanner *);
peter klausler90cd9ba2018-01-30 19:54:3171
peter klauslerbdea10d2018-02-05 20:54:3672private:
peter klausler93cf3ae2018-02-01 20:08:0273 enum class IsElseActive { No, Yes };
74 enum class CanDeadElseAppear { No, Yes };
peter klauslerad7125f2018-02-01 23:01:2375
peter klauslerf4a85282018-02-27 22:02:1076 ContiguousChars SaveTokenAsName(const ContiguousChars &);
77 bool IsNameDefined(const ContiguousChars &);
peter klausler5b61bea2018-02-13 20:24:5478 TokenSequence ReplaceMacros(const TokenSequence &, const Prescanner &);
peter klausler0983fbc2018-03-16 23:13:4979 void SkipDisabledConditionalCode(
peter klausler3b544af2018-02-20 17:57:3080 const std::string &, IsElseActive, Prescanner *);
peter klausler16c6f532018-02-05 22:29:2681 bool IsIfPredicateTrue(
peter klausler5b61bea2018-02-13 20:24:5482 const TokenSequence &expr, size_t first, size_t exprTokens, Prescanner *);
peter klausler93cf3ae2018-02-01 20:08:0283
peter klausler5b61bea2018-02-13 20:24:5484 AllSources *allSources_;
peter klausler90cd9ba2018-01-30 19:54:3185 std::list<std::string> names_;
peter klauslerf4a85282018-02-27 22:02:1086 std::unordered_map<ContiguousChars, Definition> definitions_;
peter klausler93cf3ae2018-02-01 20:08:0287 std::stack<CanDeadElseAppear> ifStack_;
peter klausler90cd9ba2018-01-30 19:54:3188};
peter klausler0ba1a142018-02-07 20:04:4289} // namespace parser
peter klausler90cd9ba2018-01-30 19:54:3190} // namespace Fortran
peter klauslerdd9923b2018-02-16 19:42:1791#endif // FORTRAN_PARSER_PREPROCESSOR_H_