Home | History | Annotate | Line # | Download | only in AST
      1 //===- ASTImporter.h - Importing ASTs from other Contexts -------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 //  This file defines the ASTImporter class which imports AST nodes from one
     10 //  context into another context.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_AST_ASTIMPORTER_H
     15 #define LLVM_CLANG_AST_ASTIMPORTER_H
     16 
     17 #include "clang/AST/APValue.h"
     18 #include "clang/AST/DeclBase.h"
     19 #include "clang/AST/DeclarationName.h"
     20 #include "clang/AST/ExprCXX.h"
     21 #include "clang/AST/NestedNameSpecifier.h"
     22 #include "clang/AST/TemplateName.h"
     23 #include "clang/AST/Type.h"
     24 #include "clang/Basic/Diagnostic.h"
     25 #include "clang/Basic/IdentifierTable.h"
     26 #include "clang/Basic/LLVM.h"
     27 #include "clang/Basic/SourceLocation.h"
     28 #include "llvm/ADT/DenseMap.h"
     29 #include "llvm/ADT/DenseSet.h"
     30 #include "llvm/ADT/Optional.h"
     31 #include "llvm/ADT/SmallVector.h"
     32 #include "llvm/Support/Error.h"
     33 #include <utility>
     34 
     35 namespace clang {
     36 
     37 class ASTContext;
     38 class ASTImporterSharedState;
     39 class Attr;
     40 class CXXBaseSpecifier;
     41 class CXXCtorInitializer;
     42 class Decl;
     43 class DeclContext;
     44 class Expr;
     45 class FileManager;
     46 class NamedDecl;
     47 class Stmt;
     48 class TagDecl;
     49 class TranslationUnitDecl;
     50 class TypeSourceInfo;
     51 
     52   class ImportError : public llvm::ErrorInfo<ImportError> {
     53   public:
     54     /// \brief Kind of error when importing an AST component.
     55     enum ErrorKind {
     56         NameConflict, /// Naming ambiguity (likely ODR violation).
     57         UnsupportedConstruct, /// Not supported node or case.
     58         Unknown /// Other error.
     59     };
     60 
     61     ErrorKind Error;
     62 
     63     static char ID;
     64 
     65     ImportError() : Error(Unknown) {}
     66     ImportError(const ImportError &Other) : Error(Other.Error) {}
     67     ImportError &operator=(const ImportError &Other) {
     68       Error = Other.Error;
     69       return *this;
     70     }
     71     ImportError(ErrorKind Error) : Error(Error) { }
     72 
     73     std::string toString() const;
     74 
     75     void log(raw_ostream &OS) const override;
     76     std::error_code convertToErrorCode() const override;
     77   };
     78 
     79   // \brief Returns with a list of declarations started from the canonical decl
     80   // then followed by subsequent decls in the translation unit.
     81   // This gives a canonical list for each entry in the redecl chain.
     82   // `Decl::redecls()` gives a list of decls which always start from the
     83   // previous decl and the next item is actually the previous item in the order
     84   // of source locations.  Thus, `Decl::redecls()` gives different lists for
     85   // the different entries in a given redecl chain.
     86   llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);
     87 
     88   /// Imports selected nodes from one AST context into another context,
     89   /// merging AST nodes where appropriate.
     90   class ASTImporter {
     91     friend class ASTNodeImporter;
     92   public:
     93     using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
     94     using ImportedCXXBaseSpecifierMap =
     95         llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
     96 
     97     enum class ODRHandlingType { Conservative, Liberal };
     98 
     99     // An ImportPath is the list of the AST nodes which we visit during an
    100     // Import call.
    101     // If node `A` depends on node `B` then the path contains an `A`->`B` edge.
    102     // From the call stack of the import functions we can read the very same
    103     // path.
    104     //
    105     // Now imagine the following AST, where the `->` represents dependency in
    106     // therms of the import.
    107     // ```
    108     // A->B->C->D
    109     //    `->E
    110     // ```
    111     // We would like to import A.
    112     // The import behaves like a DFS, so we will visit the nodes in this order:
    113     // ABCDE.
    114     // During the visitation we will have the following ImportPaths:
    115     // ```
    116     // A
    117     // AB
    118     // ABC
    119     // ABCD
    120     // ABC
    121     // AB
    122     // ABE
    123     // AB
    124     // A
    125     // ```
    126     // If during the visit of E there is an error then we set an error for E,
    127     // then as the call stack shrinks for B, then for A:
    128     // ```
    129     // A
    130     // AB
    131     // ABC
    132     // ABCD
    133     // ABC
    134     // AB
    135     // ABE // Error! Set an error to E
    136     // AB  // Set an error to B
    137     // A   // Set an error to A
    138     // ```
    139     // However, during the import we could import C and D without any error and
    140     // they are independent from A,B and E.
    141     // We must not set up an error for C and D.
    142     // So, at the end of the import we have an entry in `ImportDeclErrors` for
    143     // A,B,E but not for C,D.
    144     //
    145     // Now what happens if there is a cycle in the import path?
    146     // Let's consider this AST:
    147     // ```
    148     // A->B->C->A
    149     //    `->E
    150     // ```
    151     // During the visitation we will have the below ImportPaths and if during
    152     // the visit of E there is an error then we will set up an error for E,B,A.
    153     // But what's up with C?
    154     // ```
    155     // A
    156     // AB
    157     // ABC
    158     // ABCA
    159     // ABC
    160     // AB
    161     // ABE // Error! Set an error to E
    162     // AB  // Set an error to B
    163     // A   // Set an error to A
    164     // ```
    165     // This time we know that both B and C are dependent on A.
    166     // This means we must set up an error for C too.
    167     // As the call stack reverses back we get to A and we must set up an error
    168     // to all nodes which depend on A (this includes C).
    169     // But C is no longer on the import path, it just had been previously.
    170     // Such situation can happen only if during the visitation we had a cycle.
    171     // If we didn't have any cycle, then the normal way of passing an Error
    172     // object through the call stack could handle the situation.
    173     // This is why we must track cycles during the import process for each
    174     // visited declaration.
    175     class ImportPathTy {
    176     public:
    177       using VecTy = llvm::SmallVector<Decl *, 32>;
    178 
    179       void push(Decl *D) {
    180         Nodes.push_back(D);
    181         ++Aux[D];
    182       }
    183 
    184       void pop() {
    185         if (Nodes.empty())
    186           return;
    187         --Aux[Nodes.back()];
    188         Nodes.pop_back();
    189       }
    190 
    191       /// Returns true if the last element can be found earlier in the path.
    192       bool hasCycleAtBack() const {
    193         auto Pos = Aux.find(Nodes.back());
    194         return Pos != Aux.end() && Pos->second > 1;
    195       }
    196 
    197       using Cycle = llvm::iterator_range<VecTy::const_reverse_iterator>;
    198       Cycle getCycleAtBack() const {
    199         assert(Nodes.size() >= 2);
    200         return Cycle(Nodes.rbegin(),
    201                      std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) +
    202                          1);
    203       }
    204 
    205       /// Returns the copy of the cycle.
    206       VecTy copyCycleAtBack() const {
    207         auto R = getCycleAtBack();
    208         return VecTy(R.begin(), R.end());
    209       }
    210 
    211     private:
    212       // All nodes of the path.
    213       VecTy Nodes;
    214       // Auxiliary container to be able to answer "Do we have a cycle ending
    215       // at last element?" as fast as possible.
    216       // We count each Decl's occurrence over the path.
    217       llvm::SmallDenseMap<Decl *, int, 32> Aux;
    218     };
    219 
    220   private:
    221     std::shared_ptr<ASTImporterSharedState> SharedState = nullptr;
    222 
    223     /// The path which we go through during the import of a given AST node.
    224     ImportPathTy ImportPath;
    225     /// Sometimes we have to save some part of an import path, so later we can
    226     /// set up properties to the saved nodes.
    227     /// We may have several of these import paths associated to one Decl.
    228     using SavedImportPathsForOneDecl =
    229         llvm::SmallVector<ImportPathTy::VecTy, 32>;
    230     using SavedImportPathsTy =
    231         llvm::SmallDenseMap<Decl *, SavedImportPathsForOneDecl, 32>;
    232     SavedImportPathsTy SavedImportPaths;
    233 
    234     /// The contexts we're importing to and from.
    235     ASTContext &ToContext, &FromContext;
    236 
    237     /// The file managers we're importing to and from.
    238     FileManager &ToFileManager, &FromFileManager;
    239 
    240     /// Whether to perform a minimal import.
    241     bool Minimal;
    242 
    243     ODRHandlingType ODRHandling;
    244 
    245     /// Whether the last diagnostic came from the "from" context.
    246     bool LastDiagFromFrom = false;
    247 
    248     /// Mapping from the already-imported types in the "from" context
    249     /// to the corresponding types in the "to" context.
    250     llvm::DenseMap<const Type *, const Type *> ImportedTypes;
    251 
    252     /// Mapping from the already-imported declarations in the "from"
    253     /// context to the corresponding declarations in the "to" context.
    254     llvm::DenseMap<Decl *, Decl *> ImportedDecls;
    255 
    256     /// Mapping from the already-imported declarations in the "from"
    257     /// context to the error status of the import of that declaration.
    258     /// This map contains only the declarations that were not correctly
    259     /// imported. The same declaration may or may not be included in
    260     /// ImportedDecls. This map is updated continuously during imports and never
    261     /// cleared (like ImportedDecls).
    262     llvm::DenseMap<Decl *, ImportError> ImportDeclErrors;
    263 
    264     /// Mapping from the already-imported declarations in the "to"
    265     /// context to the corresponding declarations in the "from" context.
    266     llvm::DenseMap<Decl *, Decl *> ImportedFromDecls;
    267 
    268     /// Mapping from the already-imported statements in the "from"
    269     /// context to the corresponding statements in the "to" context.
    270     llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
    271 
    272     /// Mapping from the already-imported FileIDs in the "from" source
    273     /// manager to the corresponding FileIDs in the "to" source manager.
    274     llvm::DenseMap<FileID, FileID> ImportedFileIDs;
    275 
    276     /// Mapping from the already-imported CXXBasesSpecifier in
    277     ///  the "from" source manager to the corresponding CXXBasesSpecifier
    278     ///  in the "to" source manager.
    279     ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
    280 
    281     /// Declaration (from, to) pairs that are known not to be equivalent
    282     /// (which we have already complained about).
    283     NonEquivalentDeclSet NonEquivalentDecls;
    284 
    285     using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
    286     FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
    287 
    288     void AddToLookupTable(Decl *ToD);
    289 
    290   protected:
    291     /// Can be overwritten by subclasses to implement their own import logic.
    292     /// The overwritten method should call this method if it didn't import the
    293     /// decl on its own.
    294     virtual Expected<Decl *> ImportImpl(Decl *From);
    295 
    296     /// Used only in unittests to verify the behaviour of the error handling.
    297     virtual bool returnWithErrorInTest() { return false; };
    298 
    299   public:
    300 
    301     /// \param ToContext The context we'll be importing into.
    302     ///
    303     /// \param ToFileManager The file manager we'll be importing into.
    304     ///
    305     /// \param FromContext The context we'll be importing from.
    306     ///
    307     /// \param FromFileManager The file manager we'll be importing into.
    308     ///
    309     /// \param MinimalImport If true, the importer will attempt to import
    310     /// as little as it can, e.g., by importing declarations as forward
    311     /// declarations that can be completed at a later point.
    312     ///
    313     /// \param SharedState The importer specific lookup table which may be
    314     /// shared amongst several ASTImporter objects.
    315     /// If not set then the original C/C++ lookup is used.
    316     ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
    317                 ASTContext &FromContext, FileManager &FromFileManager,
    318                 bool MinimalImport,
    319                 std::shared_ptr<ASTImporterSharedState> SharedState = nullptr);
    320 
    321     virtual ~ASTImporter();
    322 
    323     /// Whether the importer will perform a minimal import, creating
    324     /// to-be-completed forward declarations when possible.
    325     bool isMinimalImport() const { return Minimal; }
    326 
    327     void setODRHandling(ODRHandlingType T) { ODRHandling = T; }
    328 
    329     /// \brief Import the given object, returns the result.
    330     ///
    331     /// \param To Import the object into this variable.
    332     /// \param From Object to import.
    333     /// \return Error information (success or error).
    334     template <typename ImportT>
    335     LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
    336       auto ToOrErr = Import(From);
    337       if (ToOrErr)
    338         To = *ToOrErr;
    339       return ToOrErr.takeError();
    340     }
    341 
    342     /// Import cleanup objects owned by ExprWithCleanup.
    343     llvm::Expected<ExprWithCleanups::CleanupObject>
    344     Import(ExprWithCleanups::CleanupObject From);
    345 
    346     /// Import the given type from the "from" context into the "to"
    347     /// context.
    348     ///
    349     /// \returns The equivalent type in the "to" context, or the import error.
    350     llvm::Expected<const Type *> Import(const Type *FromT);
    351 
    352     /// Import the given qualified type from the "from" context into the "to"
    353     /// context. A null type is imported as a null type (no error).
    354     ///
    355     /// \returns The equivalent type in the "to" context, or the import error.
    356     llvm::Expected<QualType> Import(QualType FromT);
    357 
    358     /// Import the given type source information from the
    359     /// "from" context into the "to" context.
    360     ///
    361     /// \returns The equivalent type source information in the "to"
    362     /// context, or the import error.
    363     llvm::Expected<TypeSourceInfo *> Import(TypeSourceInfo *FromTSI);
    364 
    365     /// Import the given attribute from the "from" context into the
    366     /// "to" context.
    367     ///
    368     /// \returns The equivalent attribute in the "to" context, or the import
    369     /// error.
    370     llvm::Expected<Attr *> Import(const Attr *FromAttr);
    371 
    372     /// Import the given declaration from the "from" context into the
    373     /// "to" context.
    374     ///
    375     /// \returns The equivalent declaration in the "to" context, or the import
    376     /// error.
    377     llvm::Expected<Decl *> Import(Decl *FromD);
    378     llvm::Expected<const Decl *> Import(const Decl *FromD) {
    379       return Import(const_cast<Decl *>(FromD));
    380     }
    381 
    382     /// Return the copy of the given declaration in the "to" context if
    383     /// it has already been imported from the "from" context.  Otherwise return
    384     /// nullptr.
    385     Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
    386 
    387     /// Return the translation unit from where the declaration was
    388     /// imported. If it does not exist nullptr is returned.
    389     TranslationUnitDecl *GetFromTU(Decl *ToD);
    390 
    391     /// Return the declaration in the "from" context from which the declaration
    392     /// in the "to" context was imported. If it was not imported or of the wrong
    393     /// type a null value is returned.
    394     template <typename DeclT>
    395     llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
    396       auto FromI = ImportedFromDecls.find(ToD);
    397       if (FromI == ImportedFromDecls.end())
    398         return {};
    399       auto *FromD = dyn_cast<DeclT>(FromI->second);
    400       if (!FromD)
    401         return {};
    402       return FromD;
    403     }
    404 
    405     /// Import the given declaration context from the "from"
    406     /// AST context into the "to" AST context.
    407     ///
    408     /// \returns the equivalent declaration context in the "to"
    409     /// context, or error value.
    410     llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);
    411 
    412     /// Import the given expression from the "from" context into the
    413     /// "to" context.
    414     ///
    415     /// \returns The equivalent expression in the "to" context, or the import
    416     /// error.
    417     llvm::Expected<Expr *> Import(Expr *FromE);
    418 
    419     /// Import the given statement from the "from" context into the
    420     /// "to" context.
    421     ///
    422     /// \returns The equivalent statement in the "to" context, or the import
    423     /// error.
    424     llvm::Expected<Stmt *> Import(Stmt *FromS);
    425 
    426     /// Import the given nested-name-specifier from the "from"
    427     /// context into the "to" context.
    428     ///
    429     /// \returns The equivalent nested-name-specifier in the "to"
    430     /// context, or the import error.
    431     llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS);
    432 
    433     /// Import the given nested-name-specifier-loc from the "from"
    434     /// context into the "to" context.
    435     ///
    436     /// \returns The equivalent nested-name-specifier-loc in the "to"
    437     /// context, or the import error.
    438     llvm::Expected<NestedNameSpecifierLoc>
    439     Import(NestedNameSpecifierLoc FromNNS);
    440 
    441     /// Import the given template name from the "from" context into the
    442     /// "to" context, or the import error.
    443     llvm::Expected<TemplateName> Import(TemplateName From);
    444 
    445     /// Import the given source location from the "from" context into
    446     /// the "to" context.
    447     ///
    448     /// \returns The equivalent source location in the "to" context, or the
    449     /// import error.
    450     llvm::Expected<SourceLocation> Import(SourceLocation FromLoc);
    451 
    452     /// Import the given source range from the "from" context into
    453     /// the "to" context.
    454     ///
    455     /// \returns The equivalent source range in the "to" context, or the import
    456     /// error.
    457     llvm::Expected<SourceRange> Import(SourceRange FromRange);
    458 
    459     /// Import the given declaration name from the "from"
    460     /// context into the "to" context.
    461     ///
    462     /// \returns The equivalent declaration name in the "to" context, or the
    463     /// import error.
    464     llvm::Expected<DeclarationName> Import(DeclarationName FromName);
    465 
    466     /// Import the given identifier from the "from" context
    467     /// into the "to" context.
    468     ///
    469     /// \returns The equivalent identifier in the "to" context. Note: It
    470     /// returns nullptr only if the FromId was nullptr.
    471     IdentifierInfo *Import(const IdentifierInfo *FromId);
    472 
    473     /// Import the given Objective-C selector from the "from"
    474     /// context into the "to" context.
    475     ///
    476     /// \returns The equivalent selector in the "to" context, or the import
    477     /// error.
    478     llvm::Expected<Selector> Import(Selector FromSel);
    479 
    480     /// Import the given file ID from the "from" context into the
    481     /// "to" context.
    482     ///
    483     /// \returns The equivalent file ID in the source manager of the "to"
    484     /// context, or the import error.
    485     llvm::Expected<FileID> Import(FileID, bool IsBuiltin = false);
    486 
    487     /// Import the given C++ constructor initializer from the "from"
    488     /// context into the "to" context.
    489     ///
    490     /// \returns The equivalent initializer in the "to" context, or the import
    491     /// error.
    492     llvm::Expected<CXXCtorInitializer *> Import(CXXCtorInitializer *FromInit);
    493 
    494     /// Import the given CXXBaseSpecifier from the "from" context into
    495     /// the "to" context.
    496     ///
    497     /// \returns The equivalent CXXBaseSpecifier in the source manager of the
    498     /// "to" context, or the import error.
    499     llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec);
    500 
    501     /// Import the given APValue from the "from" context into
    502     /// the "to" context.
    503     ///
    504     /// \return the equivalent APValue in the "to" context or the import
    505     /// error.
    506     llvm::Expected<APValue> Import(const APValue &FromValue);
    507 
    508     /// Import the definition of the given declaration, including all of
    509     /// the declarations it contains.
    510     LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From);
    511 
    512     /// Cope with a name conflict when importing a declaration into the
    513     /// given context.
    514     ///
    515     /// This routine is invoked whenever there is a name conflict while
    516     /// importing a declaration. The returned name will become the name of the
    517     /// imported declaration. By default, the returned name is the same as the
    518     /// original name, leaving the conflict unresolve such that name lookup
    519     /// for this name is likely to find an ambiguity later.
    520     ///
    521     /// Subclasses may override this routine to resolve the conflict, e.g., by
    522     /// renaming the declaration being imported.
    523     ///
    524     /// \param Name the name of the declaration being imported, which conflicts
    525     /// with other declarations.
    526     ///
    527     /// \param DC the declaration context (in the "to" AST context) in which
    528     /// the name is being imported.
    529     ///
    530     /// \param IDNS the identifier namespace in which the name will be found.
    531     ///
    532     /// \param Decls the set of declarations with the same name as the
    533     /// declaration being imported.
    534     ///
    535     /// \param NumDecls the number of conflicting declarations in \p Decls.
    536     ///
    537     /// \returns the name that the newly-imported declaration should have. Or
    538     /// an error if we can't handle the name conflict.
    539     virtual Expected<DeclarationName>
    540     HandleNameConflict(DeclarationName Name, DeclContext *DC, unsigned IDNS,
    541                        NamedDecl **Decls, unsigned NumDecls);
    542 
    543     /// Retrieve the context that AST nodes are being imported into.
    544     ASTContext &getToContext() const { return ToContext; }
    545 
    546     /// Retrieve the context that AST nodes are being imported from.
    547     ASTContext &getFromContext() const { return FromContext; }
    548 
    549     /// Retrieve the file manager that AST nodes are being imported into.
    550     FileManager &getToFileManager() const { return ToFileManager; }
    551 
    552     /// Retrieve the file manager that AST nodes are being imported from.
    553     FileManager &getFromFileManager() const { return FromFileManager; }
    554 
    555     /// Report a diagnostic in the "to" context.
    556     DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
    557 
    558     /// Report a diagnostic in the "from" context.
    559     DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
    560 
    561     /// Return the set of declarations that we know are not equivalent.
    562     NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
    563 
    564     /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
    565     /// Mark the Decl as complete, filling it in as much as possible.
    566     ///
    567     /// \param D A declaration in the "to" context.
    568     virtual void CompleteDecl(Decl* D);
    569 
    570     /// Subclasses can override this function to observe all of the \c From ->
    571     /// \c To declaration mappings as they are imported.
    572     virtual void Imported(Decl *From, Decl *To) {}
    573 
    574     void RegisterImportedDecl(Decl *FromD, Decl *ToD);
    575 
    576     /// Store and assign the imported declaration to its counterpart.
    577     /// It may happen that several decls from the 'from' context are mapped to
    578     /// the same decl in the 'to' context.
    579     Decl *MapImported(Decl *From, Decl *To);
    580 
    581     /// Called by StructuralEquivalenceContext.  If a RecordDecl is
    582     /// being compared to another RecordDecl as part of import, completing the
    583     /// other RecordDecl may trigger importation of the first RecordDecl. This
    584     /// happens especially for anonymous structs.  If the original of the second
    585     /// RecordDecl can be found, we can complete it without the need for
    586     /// importation, eliminating this loop.
    587     virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
    588 
    589     /// Return if import of the given declaration has failed and if yes
    590     /// the kind of the problem. This gives the first error encountered with
    591     /// the node.
    592     llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *FromD) const;
    593 
    594     /// Mark (newly) imported declaration with error.
    595     void setImportDeclError(Decl *From, ImportError Error);
    596 
    597     /// Determine whether the given types are structurally
    598     /// equivalent.
    599     bool IsStructurallyEquivalent(QualType From, QualType To,
    600                                   bool Complain = true);
    601 
    602     /// Determine the index of a field in its parent record.
    603     /// F should be a field (or indirect field) declaration.
    604     /// \returns The index of the field in its parent context (starting from 0).
    605     /// On error `None` is returned (parent context is non-record).
    606     static llvm::Optional<unsigned> getFieldIndex(Decl *F);
    607   };
    608 
    609 } // namespace clang
    610 
    611 #endif // LLVM_CLANG_AST_ASTIMPORTER_H
    612