clang-tools  7.0.0
Representation.cpp
Go to the documentation of this file.
1 ///===-- Representation.cpp - ClangDoc Representation -----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the merging of different types of infos. The data in the
11 // calling Info is preserved during a merge unless that field is empty or
12 // default. In that case, the data from the parameter Info is used to replace
13 // the empty or default data.
14 //
15 // For most fields, the first decl seen provides the data. Exceptions to this
16 // include the location and description fields, which are collections of data on
17 // all decls related to a given definition. All other fields are ignored in new
18 // decls unless the first seen decl didn't, for whatever reason, incorporate
19 // data on that field (e.g. a forward declared class wouldn't have information
20 // on members on the forward declaration, but would have the class name).
21 //
22 //===----------------------------------------------------------------------===//
23 #include "Representation.h"
24 #include "llvm/Support/Error.h"
25 
26 namespace clang {
27 namespace doc {
28 
29 static const SymbolID EmptySID = SymbolID();
30 
31 template <typename T>
32 std::unique_ptr<Info> reduce(std::vector<std::unique_ptr<Info>> &Values) {
33  std::unique_ptr<Info> Merged = llvm::make_unique<T>();
34  T *Tmp = static_cast<T *>(Merged.get());
35  for (auto &I : Values)
36  Tmp->merge(std::move(*static_cast<T *>(I.get())));
37  return Merged;
38 }
39 
40 // Dispatch function.
41 llvm::Expected<std::unique_ptr<Info>>
42 mergeInfos(std::vector<std::unique_ptr<Info>> &Values) {
43  if (Values.empty())
44  return llvm::make_error<llvm::StringError>("No info values to merge.\n",
45  llvm::inconvertibleErrorCode());
46 
47  switch (Values[0]->IT) {
49  return reduce<NamespaceInfo>(Values);
51  return reduce<RecordInfo>(Values);
52  case InfoType::IT_enum:
53  return reduce<EnumInfo>(Values);
55  return reduce<FunctionInfo>(Values);
56  default:
57  return llvm::make_error<llvm::StringError>("Unexpected info type.\n",
58  llvm::inconvertibleErrorCode());
59  }
60 }
61 
62 void Info::mergeBase(Info &&Other) {
63  assert(mergeable(Other));
64  if (USR == EmptySID)
65  USR = Other.USR;
66  if (Name == "")
67  Name = Other.Name;
68  if (Namespace.empty())
69  Namespace = std::move(Other.Namespace);
70  // Unconditionally extend the description, since each decl may have a comment.
71  std::move(Other.Description.begin(), Other.Description.end(),
72  std::back_inserter(Description));
73 }
74 
75 bool Info::mergeable(const Info &Other) {
76  return IT == Other.IT && (USR == EmptySID || USR == Other.USR);
77 }
78 
80  assert(mergeable(Other));
81  if (!DefLoc)
82  DefLoc = std::move(Other.DefLoc);
83  // Unconditionally extend the list of locations, since we want all of them.
84  std::move(Other.Loc.begin(), Other.Loc.end(), std::back_inserter(Loc));
85  mergeBase(std::move(Other));
86 }
87 
89  assert(mergeable(Other));
90  mergeBase(std::move(Other));
91 }
92 
94  assert(mergeable(Other));
95  if (!TagType)
96  TagType = Other.TagType;
97  if (Members.empty())
98  Members = std::move(Other.Members);
99  if (Parents.empty())
100  Parents = std::move(Other.Parents);
101  if (VirtualParents.empty())
102  VirtualParents = std::move(Other.VirtualParents);
103  SymbolInfo::merge(std::move(Other));
104 }
105 
106 void EnumInfo::merge(EnumInfo &&Other) {
107  assert(mergeable(Other));
108  if (!Scoped)
109  Scoped = Other.Scoped;
110  if (Members.empty())
111  Members = std::move(Other.Members);
112  SymbolInfo::merge(std::move(Other));
113 }
114 
116  assert(mergeable(Other));
117  if (!IsMethod)
118  IsMethod = Other.IsMethod;
119  if (!Access)
120  Access = Other.Access;
121  if (ReturnType.Type.USR == EmptySID && ReturnType.Type.Name == "")
122  ReturnType = std::move(Other.ReturnType);
123  if (Parent.USR == EmptySID && Parent.Name == "")
124  Parent = std::move(Other.Parent);
125  if (Params.empty())
126  Params = std::move(Other.Params);
127  SymbolInfo::merge(std::move(Other));
128 }
129 
130 } // namespace doc
131 } // namespace clang
SourceLocation Loc
&#39;#&#39; location in the include directive
llvm::SmallVector< Reference, 4 > Namespace
static const SymbolID EmptySID
std::unique_ptr< Info > reduce(std::vector< std::unique_ptr< Info >> &Values)
void merge(NamespaceInfo &&I)
void merge(EnumInfo &&I)
bool mergeable(const Info &Other)
std::vector< CommentInfo > Description
llvm::Expected< std::unique_ptr< Info > > mergeInfos(std::vector< std::unique_ptr< Info >> &Values)
SmallString< 16 > Name
A base struct for Infos.
std::string ReturnType
void merge(SymbolInfo &&I)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void merge(FunctionInfo &&I)
const InfoType IT
std::array< uint8_t, 20 > SymbolID
void merge(RecordInfo &&I)
void mergeBase(Info &&I)