diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -104,10 +104,22 @@ /// The kind of input, atm it contains language InputKind kind_; + /// Is this input file in fixed-form format? This is simply derived from the + /// file extension and should not be altered by consumers. For input from + /// stdin this is never modified. + bool isFixedForm_ = false; + public: FrontendInputFile() = default; FrontendInputFile(llvm::StringRef file, InputKind kind) - : file_(file.str()), kind_(kind) {} + : file_(file.str()), kind_(kind) { + + // Based on the extension, decide whether this is a fixed or free form + // file. + auto pathDotIndex{file.rfind(".")}; + std::string pathSuffix{file.substr(pathDotIndex + 1)}; + isFixedForm_ = isFixedFormSuffix(pathSuffix); + } FrontendInputFile(const llvm::MemoryBuffer *buffer, InputKind kind) : buffer_(buffer), kind_(kind) {} @@ -116,6 +128,7 @@ bool IsEmpty() const { return file_.empty() && buffer_ == nullptr; } bool IsFile() const { return !IsBuffer(); } bool IsBuffer() const { return buffer_ != nullptr; } + bool IsFixedForm() const { return isFixedForm_; } llvm::StringRef file() const { assert(IsFile()); diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp --- a/flang/lib/Frontend/CompilerInstance.cpp +++ b/flang/lib/Frontend/CompilerInstance.cpp @@ -138,16 +138,22 @@ } bool CompilerInstance::ExecuteAction(FrontendAction &act) { + auto &invoc = this->invocation(); + // Set some sane defaults for the frontend. - // TODO: Instead of defaults we should be setting these options based on the - // user input. - this->invocation().SetDefaultFortranOpts(); - // Set the fortran options to user-based input. - this->invocation().setFortranOpts(); + invoc.SetDefaultFortranOpts(); + // Update the fortran options based on user-based input. + invoc.setFortranOpts(); - // Connect Input to a CompileInstance + // Run the frontend action `act` for every input file. for (const FrontendInputFile &fif : frontendOpts().inputs_) { if (act.BeginSourceFile(*this, fif)) { + // Switch between fixed and free form format based on the input file + // extension. Ideally we should have all Fortran options set before + // entering this loop (i.e. processing any input files). However, we + // can't decide between fixed and free form based on the file extension + // earlier than this. + invoc.fortranOpts().isFixedForm = fif.IsFixedForm(); if (llvm::Error err = act.Execute()) { consumeError(std::move(err)); } diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp --- a/flang/lib/Frontend/FrontendAction.cpp +++ b/flang/lib/Frontend/FrontendAction.cpp @@ -53,12 +53,6 @@ Fortran::parser::Options parserOptions = this->instance().invocation().fortranOpts(); - // Set the fixed form flag based on the file extension - auto pathDotIndex{currentInputPath.rfind(".")}; - if (pathDotIndex != std::string::npos) { - std::string pathSuffix{currentInputPath.substr(pathDotIndex + 1)}; - parserOptions.isFixedForm = isFixedFormSuffix(pathSuffix); - } // Prescan. In case of failure, report and return. ci.parsing().Prescan(currentInputPath, parserOptions);