123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- //===--- MacroExpander.h - Format C++ code ----------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file
- /// This file contains the main building blocks of macro support in
- /// clang-format.
- ///
- /// In order to not violate the requirement that clang-format can format files
- /// in isolation, clang-format's macro support uses expansions users provide
- /// as part of clang-format's style configuration.
- ///
- /// Macro definitions are of the form "MACRO(p1, p2)=p1 + p2", but only support
- /// one level of expansion (\see MacroExpander for a full description of what
- /// is supported).
- ///
- /// As part of parsing, clang-format uses the MacroExpander to expand the
- /// spelled token streams into expanded token streams when it encounters a
- /// macro call. The UnwrappedLineParser continues to parse UnwrappedLines
- /// from the expanded token stream.
- /// After the expanded unwrapped lines are parsed, the MacroUnexpander matches
- /// the spelled token stream into unwrapped lines that best resemble the
- /// structure of the expanded unwrapped lines.
- ///
- /// When formatting, clang-format formats the expanded unwrapped lines first,
- /// determining the token types. Next, it formats the spelled unwrapped lines,
- /// keeping the token types fixed, while allowing other formatting decisions
- /// to change.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef CLANG_LIB_FORMAT_MACROS_H
- #define CLANG_LIB_FORMAT_MACROS_H
- #include <string>
- #include <unordered_map>
- #include <vector>
- #include "Encoding.h"
- #include "FormatToken.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringRef.h"
- namespace llvm {
- class MemoryBuffer;
- } // namespace llvm
- namespace clang {
- class IdentifierTable;
- class SourceManager;
- namespace format {
- struct FormatStyle;
- /// Takes a set of macro definitions as strings and allows expanding calls to
- /// those macros.
- ///
- /// For example:
- /// Definition: A(x, y)=x + y
- /// Call : A(int a = 1, 2)
- /// Expansion : int a = 1 + 2
- ///
- /// Expansion does not check arity of the definition.
- /// If fewer arguments than expected are provided, the remaining parameters
- /// are considered empty:
- /// Call : A(a)
- /// Expansion: a +
- /// If more arguments than expected are provided, they will be discarded.
- ///
- /// The expander does not support:
- /// - recursive expansion
- /// - stringification
- /// - concatenation
- /// - variadic macros
- ///
- /// Furthermore, only a single expansion of each macro argument is supported,
- /// so that we cannot get conflicting formatting decisions from different
- /// expansions.
- /// Definition: A(x)=x+x
- /// Call : A(id)
- /// Expansion : id+x
- ///
- class MacroExpander {
- public:
- using ArgsList = llvm::ArrayRef<llvm::SmallVector<FormatToken *, 8>>;
- /// Construct a macro expander from a set of macro definitions.
- /// Macro definitions must be encoded as UTF-8.
- ///
- /// Each entry in \p Macros must conform to the following simple
- /// macro-definition language:
- /// <definition> ::= <id> <expansion> | <id> "(" <params> ")" <expansion>
- /// <params> ::= <id-list> | ""
- /// <id-list> ::= <id> | <id> "," <params>
- /// <expansion> ::= "=" <tail> | <eof>
- /// <tail> ::= <tok> <tail> | <eof>
- ///
- /// Macros that cannot be parsed will be silently discarded.
- ///
- MacroExpander(const std::vector<std::string> &Macros,
- clang::SourceManager &SourceMgr, const FormatStyle &Style,
- llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
- IdentifierTable &IdentTable);
- ~MacroExpander();
- /// Returns whether a macro \p Name is defined.
- bool defined(llvm::StringRef Name) const;
- /// Returns whether the macro has no arguments and should not consume
- /// subsequent parentheses.
- bool objectLike(llvm::StringRef Name) const;
- /// Returns the expanded stream of format tokens for \p ID, where
- /// each element in \p Args is a positional argument to the macro call.
- llvm::SmallVector<FormatToken *, 8> expand(FormatToken *ID,
- ArgsList Args) const;
- private:
- struct Definition;
- class DefinitionParser;
- void parseDefinition(const std::string &Macro);
- clang::SourceManager &SourceMgr;
- const FormatStyle &Style;
- llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator;
- IdentifierTable &IdentTable;
- std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
- llvm::StringMap<Definition> Definitions;
- };
- } // namespace format
- } // namespace clang
- #endif
|