1453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor//===--- LayoutOverrideSource.h --Override Record Layouts -----------------===//
2453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor//
3453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor//                     The LLVM Compiler Infrastructure
4453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor//
5453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor// This file is distributed under the University of Illinois Open Source
6453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor// License. See LICENSE.TXT for details.
7453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor//
8453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor//===----------------------------------------------------------------------===//
9453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
10453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#ifndef LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
11453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#define LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
12453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
13453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#include "clang/AST/ExternalASTSource.h"
14cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko#include "clang/Basic/LLVM.h"
15453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#include "llvm/ADT/StringMap.h"
16453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#include "llvm/ADT/StringRef.h"
17453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
18453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregornamespace clang {
19453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  /// \brief An external AST source that overrides the layout of
20453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  /// a specified set of record types.
21453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  ///
22453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  /// This class is used only for testing the ability of external AST sources
23453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  /// to override the layout of record types. Its input is the output format
24453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  /// of the command-line argument -fdump-record-layouts.
25453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  class LayoutOverrideSource : public ExternalASTSource {
26453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// \brief The layout of a given record.
27453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    struct Layout {
28453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor      /// \brief The size of the record.
29453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor      uint64_t Size;
30453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
31453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor      /// \brief The alignment of the record.
32453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor      uint64_t Align;
33453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
34453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor      /// \brief The offsets of the fields, in source order.
35cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko      SmallVector<uint64_t, 8> FieldOffsets;
36453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    };
37453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
38453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// \brief The set of layouts that will be overridden.
39453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    llvm::StringMap<Layout> Layouts;
40453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
41453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  public:
42453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// \brief Create a new AST source that overrides the layout of some
43453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// set of record types.
44453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    ///
45453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// The file is the result of passing -fdump-record-layouts to a file.
46cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    explicit LayoutOverrideSource(StringRef Filename);
47453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
48453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// \brief If this particular record type has an overridden layout,
49453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// return that layout.
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool
51453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    layoutRecordType(const RecordDecl *Record,
52453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor       uint64_t &Size, uint64_t &Alignment,
53453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor       llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
54453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor       llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       llvm::DenseMap<const CXXRecordDecl *,
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      CharUnits> &VirtualBaseOffsets) override;
57453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
58453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    /// \brief Dump the overridden layouts.
59453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor    void dump();
60453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor  };
61453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor}
62453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor
63453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor#endif
64