23
23
#include " clang/AST/Expr.h"
24
24
#include " clang/AST/PreorderAST.h"
25
25
#include " clang/AST/Stmt.h"
26
+ #include " clang/Basic/SourceManager.h"
26
27
27
28
using namespace clang ;
28
29
using Result = Lexicographic::Result;
@@ -109,6 +110,46 @@ static Result ComparePointers(T *P1, T *P2, bool &ordered) {
109
110
return Result::LessThan;
110
111
}
111
112
113
+ // \brief Order two source locations based on the lexicographic
114
+ // ordering of filenames if the two source locationsi are in
115
+ // different source files, and based on line/column numbers if
116
+ // the two source locations are in the same source file.
117
+ Result
118
+ Lexicographic::CompareLoc (const SourceLocation *SL1,
119
+ const SourceLocation *SL2) const {
120
+ if (SL1 && SL2) {
121
+ if (SL1 == SL2)
122
+ return Result::Equal;
123
+ const SourceManager *SM = &Context.getSourceManager ();
124
+ if (!SM) {
125
+ llvm_unreachable (" unexpected null SourceManager" );
126
+ return Result::LessThan;
127
+ }
128
+ const SourceLocation SLoc1 = SM->getSpellingLoc (*SL1);
129
+ const SourceLocation SLoc2 = SM->getSpellingLoc (*SL2);
130
+ const PresumedLoc PLoc1 = SM->getPresumedLoc (SLoc1);
131
+ const PresumedLoc PLoc2 = SM->getPresumedLoc (SLoc2);
132
+ if (PLoc1.isInvalid () || PLoc2.isInvalid ()) {
133
+ llvm_unreachable (" unexpected invalid source locations" );
134
+ return Result::LessThan;
135
+ }
136
+ Result Cmp = TranslateInt (strcmp (PLoc1.getFilename (), PLoc2.getFilename ()));
137
+ if (Cmp != Result::Equal)
138
+ return Cmp;
139
+
140
+ Cmp = TranslateInt ((int )PLoc1.getLine () - (int )PLoc2.getLine ());
141
+ if (Cmp != Result::Equal)
142
+ return Cmp;
143
+
144
+ Cmp = TranslateInt ((int )PLoc1.getColumn () - (int )PLoc2.getColumn ());
145
+ if (Cmp != Result::Equal)
146
+ return Cmp;
147
+ }
148
+
149
+ llvm_unreachable (" unexpected source locations" );
150
+ return Result::LessThan;
151
+ }
152
+
112
153
Result
113
154
Lexicographic::CompareScope (const DeclContext *DC1, const DeclContext *DC2) const {
114
155
DC1 = DC1->getPrimaryContext ();
@@ -123,7 +164,11 @@ Lexicographic::CompareScope(const DeclContext *DC1, const DeclContext *DC2) cons
123
164
124
165
switch (DC1->getDeclKind ()) {
125
166
case Decl::TranslationUnit: return Result::Equal;
126
- case Decl::Captured: return Result::Equal;
167
+ case Decl::Captured: {
168
+ const CapturedDecl *CD1 = dyn_cast<CapturedDecl>(DC1);
169
+ const CapturedDecl *CD2 = dyn_cast<CapturedDecl>(DC2);
170
+ return CompareDecl (CD1, CD2);
171
+ }
127
172
case Decl::Function:
128
173
case Decl::Enum:
129
174
case Decl::Record: {
@@ -137,6 +182,20 @@ Lexicographic::CompareScope(const DeclContext *DC1, const DeclContext *DC2) cons
137
182
}
138
183
}
139
184
185
+ Result
186
+ Lexicographic::CompareDecl (const CapturedDecl *CD1,
187
+ const CapturedDecl *CD2) const {
188
+ Stmt *SList1 = CD1->getBody ();
189
+ Stmt *SList2 = CD2->getBody ();
190
+ if (SList1 && SList2) {
191
+ const SourceLocation SL1 = SList1->getSourceRange ().getBegin ();
192
+ const SourceLocation SL2 = SList2->getSourceRange ().getBegin ();
193
+ return CompareLoc (&SL1, &SL2);
194
+ }
195
+ llvm_unreachable (" unexpected captured scope type" );
196
+ return Result::LessThan;
197
+ }
198
+
140
199
Result
141
200
Lexicographic::CompareDecl (const NamedDecl *D1Arg, const NamedDecl *D2Arg) const {
142
201
const NamedDecl *D1 = dyn_cast<NamedDecl>(D1Arg->getCanonicalDecl ());
0 commit comments