clang  3.7.0
SemaInternal.h
Go to the documentation of this file.
1 //===--- SemaInternal.h - Internal Sema Interfaces --------------*- 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 provides common API and #includes for the internal
11 // implementation of Sema.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_SEMA_SEMAINTERNAL_H
16 #define LLVM_CLANG_SEMA_SEMAINTERNAL_H
17 
18 #include "clang/AST/ASTContext.h"
19 #include "clang/Sema/Lookup.h"
20 #include "clang/Sema/Sema.h"
22 
23 namespace clang {
24 
25 inline PartialDiagnostic Sema::PDiag(unsigned DiagID) {
26  return PartialDiagnostic(DiagID, Context.getDiagAllocator());
27 }
28 
29 inline bool
31  return FTI.NumParams == 1 && !FTI.isVariadic &&
32  FTI.Params[0].Ident == nullptr && FTI.Params[0].Param &&
33  cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType();
34 }
35 
36 inline bool
38  // Assume FTI is well-formed.
39  return FTI.NumParams && !FTIHasSingleVoidParameter(FTI);
40 }
41 
42 // This requires the variable to be non-dependent and the initializer
43 // to not be value dependent.
45  const VarDecl *DefVD = nullptr;
46  return !isa<ParmVarDecl>(Var) &&
47  Var->isUsableInConstantExpressions(Context) &&
48  Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
49 }
50 
51 // Helper function to check whether D's attributes match current CUDA mode.
52 // Decls with mismatched attributes and related diagnostics may have to be
53 // ignored during this CUDA compilation pass.
54 inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) {
55  if (!LangOpts.CUDA || !D)
56  return true;
57  bool isDeviceSideDecl = D->hasAttr<CUDADeviceAttr>() ||
58  D->hasAttr<CUDASharedAttr>() ||
59  D->hasAttr<CUDAGlobalAttr>();
60  return isDeviceSideDecl == LangOpts.CUDAIsDevice;
61 }
62 
63 // Directly mark a variable odr-used. Given a choice, prefer to use
64 // MarkVariableReferenced since it does additional checks and then
65 // calls MarkVarDeclODRUsed.
66 // If the variable must be captured:
67 // - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
68 // - else capture it in the DeclContext that maps to the
69 // *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
70 inline void MarkVarDeclODRUsed(VarDecl *Var,
71  SourceLocation Loc, Sema &SemaRef,
72  const unsigned *const FunctionScopeIndexToStopAt) {
73  // Keep track of used but undefined variables.
74  // FIXME: We shouldn't suppress this warning for static data members.
75  if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
76  !Var->isExternallyVisible() &&
77  !(Var->isStaticDataMember() && Var->hasInit())) {
78  SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
79  if (old.isInvalid()) old = Loc;
80  }
81  QualType CaptureType, DeclRefType;
83  /*EllipsisLoc*/ SourceLocation(),
84  /*BuildAndDiagnose*/ true,
85  CaptureType, DeclRefType,
86  FunctionScopeIndexToStopAt);
87 
88  Var->markUsed(SemaRef.Context);
89 }
90 
91 /// Return a DLL attribute from the declaration.
93  assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
94  "A declaration cannot be both dllimport and dllexport.");
95  if (auto *Import = D->getAttr<DLLImportAttr>())
96  return Import;
97  if (auto *Export = D->getAttr<DLLExportAttr>())
98  return Export;
99  return nullptr;
100 }
101 
104  typedef llvm::StringMap<TypoResultList> TypoResultsMap;
105  typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
106 
107 public:
109  const DeclarationNameInfo &TypoName,
110  Sema::LookupNameKind LookupKind,
111  Scope *S, CXXScopeSpec *SS,
112  std::unique_ptr<CorrectionCandidateCallback> CCC,
113  DeclContext *MemberContext,
114  bool EnteringContext)
115  : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0),
116  SavedTCIndex(0), SemaRef(SemaRef), S(S),
117  SS(SS ? llvm::make_unique<CXXScopeSpec>(*SS) : nullptr),
118  CorrectionValidator(std::move(CCC)), MemberContext(MemberContext),
119  Result(SemaRef, TypoName, LookupKind),
120  Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
121  EnteringContext(EnteringContext), SearchNamespaces(false) {
122  Result.suppressDiagnostics();
123  // Arrange for ValidatedCorrections[0] to always be an empty correction.
124  ValidatedCorrections.push_back(TypoCorrection());
125  }
126 
127  bool includeHiddenDecls() const override { return true; }
128 
129  // Methods for adding potential corrections to the consumer.
130  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
131  bool InBaseClass) override;
132  void FoundName(StringRef Name);
133  void addKeywordResult(StringRef Keyword);
134  void addCorrection(TypoCorrection Correction);
135 
136  bool empty() const {
137  return CorrectionResults.empty() && ValidatedCorrections.size() == 1;
138  }
139 
140  /// \brief Return the list of TypoCorrections for the given identifier from
141  /// the set of corrections that have the closest edit distance, if any.
142  TypoResultList &operator[](StringRef Name) {
143  return CorrectionResults.begin()->second[Name];
144  }
145 
146  /// \brief Return the edit distance of the corrections that have the
147  /// closest/best edit distance from the original typop.
148  unsigned getBestEditDistance(bool Normalized) {
149  if (CorrectionResults.empty())
150  return (std::numeric_limits<unsigned>::max)();
151 
152  unsigned BestED = CorrectionResults.begin()->first;
153  return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
154  }
155 
156  /// \brief Set-up method to add to the consumer the set of namespaces to use
157  /// in performing corrections to nested name specifiers. This method also
158  /// implicitly adds all of the known classes in the current AST context to the
159  /// to the consumer for correcting nested name specifiers.
160  void
161  addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
162 
163  /// \brief Return the next typo correction that passes all internal filters
164  /// and is deemed valid by the consumer's CorrectionCandidateCallback,
165  /// starting with the corrections that have the closest edit distance. An
166  /// empty TypoCorrection is returned once no more viable corrections remain
167  /// in the consumer.
169 
170  /// \brief Get the last correction returned by getNextCorrection().
172  return CurrentTCIndex < ValidatedCorrections.size()
173  ? ValidatedCorrections[CurrentTCIndex]
174  : ValidatedCorrections[0]; // The empty correction.
175  }
176 
177  /// \brief Return the next typo correction like getNextCorrection, but keep
178  /// the internal state pointed to the current correction (i.e. the next time
179  /// getNextCorrection is called, it will return the same correction returned
180  /// by peekNextcorrection).
182  auto Current = CurrentTCIndex;
183  const TypoCorrection &TC = getNextCorrection();
184  CurrentTCIndex = Current;
185  return TC;
186  }
187 
188  /// \brief Reset the consumer's position in the stream of viable corrections
189  /// (i.e. getNextCorrection() will return each of the previously returned
190  /// corrections in order before returning any new corrections).
192  CurrentTCIndex = 0;
193  }
194 
195  /// \brief Return whether the end of the stream of corrections has been
196  /// reached.
197  bool finished() {
198  return CorrectionResults.empty() &&
199  CurrentTCIndex >= ValidatedCorrections.size();
200  }
201 
202  /// \brief Save the current position in the correction stream (overwriting any
203  /// previously saved position).
205  SavedTCIndex = CurrentTCIndex;
206  }
207 
208  /// \brief Restore the saved position in the correction stream.
210  CurrentTCIndex = SavedTCIndex;
211  }
212 
213  ASTContext &getContext() const { return SemaRef.Context; }
214  const LookupResult &getLookupResult() const { return Result; }
215 
216  bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; }
217  const CXXScopeSpec *getSS() const { return SS.get(); }
218  Scope *getScope() const { return S; }
219 
220 private:
221  class NamespaceSpecifierSet {
222  struct SpecifierInfo {
223  DeclContext* DeclCtx;
224  NestedNameSpecifier* NameSpecifier;
225  unsigned EditDistance;
226  };
227 
228  typedef SmallVector<DeclContext*, 4> DeclContextList;
229  typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
230 
231  ASTContext &Context;
232  DeclContextList CurContextChain;
233  std::string CurNameSpecifier;
234  SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
235  SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
236 
237  std::map<unsigned, SpecifierInfoList> DistanceMap;
238 
239  /// \brief Helper for building the list of DeclContexts between the current
240  /// context and the top of the translation unit
241  static DeclContextList buildContextChain(DeclContext *Start);
242 
243  unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
244  NestedNameSpecifier *&NNS);
245 
246  public:
247  NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
248  CXXScopeSpec *CurScopeSpec);
249 
250  /// \brief Add the DeclContext (a namespace or record) to the set, computing
251  /// the corresponding NestedNameSpecifier and its distance in the process.
252  void addNameSpecifier(DeclContext *Ctx);
253 
254  /// \brief Provides flat iteration over specifiers, sorted by distance.
255  class iterator
256  : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
257  SpecifierInfo> {
258  /// Always points to the last element in the distance map.
259  const std::map<unsigned, SpecifierInfoList>::iterator OuterBack;
260  /// Iterator on the distance map.
261  std::map<unsigned, SpecifierInfoList>::iterator Outer;
262  /// Iterator on an element in the distance map.
263  SpecifierInfoList::iterator Inner;
264 
265  public:
266  iterator(NamespaceSpecifierSet &Set, bool IsAtEnd)
267  : OuterBack(std::prev(Set.DistanceMap.end())),
268  Outer(Set.DistanceMap.begin()),
269  Inner(!IsAtEnd ? Outer->second.begin() : OuterBack->second.end()) {
270  assert(!Set.DistanceMap.empty());
271  }
272 
274  ++Inner;
275  if (Inner == Outer->second.end() && Outer != OuterBack) {
276  ++Outer;
277  Inner = Outer->second.begin();
278  }
279  return *this;
280  }
281 
282  SpecifierInfo &operator*() { return *Inner; }
283  bool operator==(const iterator &RHS) const { return Inner == RHS.Inner; }
284  };
285 
286  iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
287  iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
288  };
289 
290  void addName(StringRef Name, NamedDecl *ND,
291  NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
292 
293  /// \brief Find any visible decls for the given typo correction candidate.
294  /// If none are found, it to the set of candidates for which qualified lookups
295  /// will be performed to find possible nested name specifier changes.
296  bool resolveCorrection(TypoCorrection &Candidate);
297 
298  /// \brief Perform qualified lookups on the queued set of typo correction
299  /// candidates and add the nested name specifier changes to each candidate if
300  /// a lookup succeeds (at which point the candidate will be returned to the
301  /// main pool of potential corrections).
302  void performQualifiedLookups();
303 
304  /// \brief The name written that is a typo in the source.
305  IdentifierInfo *Typo;
306 
307  /// \brief The results found that have the smallest edit distance
308  /// found (so far) with the typo name.
309  ///
310  /// The pointer value being set to the current DeclContext indicates
311  /// whether there is a keyword with this name.
312  TypoEditDistanceMap CorrectionResults;
313 
314  SmallVector<TypoCorrection, 4> ValidatedCorrections;
315  size_t CurrentTCIndex;
316  size_t SavedTCIndex;
317 
318  Sema &SemaRef;
319  Scope *S;
320  std::unique_ptr<CXXScopeSpec> SS;
321  std::unique_ptr<CorrectionCandidateCallback> CorrectionValidator;
322  DeclContext *MemberContext;
323  LookupResult Result;
324  NamespaceSpecifierSet Namespaces;
325  SmallVector<TypoCorrection, 2> QualifiedResults;
326  bool EnteringContext;
327  bool SearchNamespaces;
328 };
329 
330 inline Sema::TypoExprState::TypoExprState() {}
331 
332 inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT {
333  *this = std::move(other);
334 }
335 
336 inline Sema::TypoExprState &Sema::TypoExprState::operator=(
337  Sema::TypoExprState &&other) LLVM_NOEXCEPT {
338  Consumer = std::move(other.Consumer);
339  DiagHandler = std::move(other.DiagHandler);
340  RecoveryHandler = std::move(other.RecoveryHandler);
341  return *this;
342 }
343 
344 } // end namespace clang
345 
346 #endif
Defines the clang::ASTContext interface.
void MarkVarDeclODRUsed(VarDecl *Var, SourceLocation Loc, Sema &SemaRef, const unsigned *const FunctionScopeIndexToStopAt)
Definition: SemaInternal.h:70
Simple class containing the result of Sema::CorrectTypo.
TypoResultList & operator[](StringRef Name)
Return the list of TypoCorrections for the given identifier from the set of corrections that have the...
Definition: SemaInternal.h:142
void saveCurrentPosition()
Save the current position in the correction stream (overwriting any previously saved position)...
Definition: SemaInternal.h:204
Consumes visible declarations found when searching for all visible names within a given scope or cont...
Definition: Lookup.h:693
bool isUsableInConstantExpressions(ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
Definition: Decl.cpp:2056
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:25
bool finished()
Return whether the end of the stream of corrections has been reached.
Definition: SemaInternal.h:197
bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
Definition: SemaExpr.cpp:12765
void addKeywordResult(StringRef Keyword)
bool FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI)
Definition: SemaInternal.h:37
bool hasAttr() const
Definition: DeclBase.h:487
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, bool InBaseClass) override
Invoked each time Sema::LookupVisibleDecls() finds a declaration visible from the current scope or co...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
T * getAttr() const
Definition: DeclBase.h:484
Represents the results of name lookup.
Definition: Lookup.h:30
const CXXScopeSpec * getSS() const
Definition: SemaInternal.h:217
bool FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI)
Definition: SemaInternal.h:30
static unsigned NormalizeEditDistance(unsigned ED)
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:68
const TypoCorrection & getNextCorrection()
Return the next typo correction that passes all internal filters and is deemed valid by the consumer'...
bool isInvalid() const
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:258
void restoreSavedPosition()
Restore the saved position in the correction stream.
Definition: SemaInternal.h:209
ASTContext * Context
LookupNameKind
Describes the kind of name lookup to perform.
Definition: Sema.h:2578
bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context)
Definition: SemaInternal.h:44
llvm::DenseMap< NamedDecl *, SourceLocation > UndefinedButUsed
Definition: Sema.h:938
PartialDiagnostic::StorageAllocator & getDiagAllocator()
Definition: ASTContext.h:514
void addCorrection(TypoCorrection Correction)
bool isExternallyVisible() const
Definition: Decl.h:279
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
Definition: Decl.cpp:2159
const LookupResult & getLookupResult() const
Definition: SemaInternal.h:214
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:1893
TypoCorrectionConsumer(Sema &SemaRef, const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, std::unique_ptr< CorrectionCandidateCallback > CCC, DeclContext *MemberContext, bool EnteringContext)
Definition: SemaInternal.h:108
const Expr * getAnyInitializer() const
Definition: Decl.h:1056
#define false
Definition: stdbool.h:33
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
void FoundName(StringRef Name)
InheritableAttr * getDLLAttr(Decl *D)
Return a DLL attribute from the declaration.
Definition: SemaInternal.h:92
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This declaration is only a declaration.
Definition: Decl.h:993
bool hasInit() const
Definition: Decl.h:1065
ASTContext & getContext() const
Definition: SemaInternal.h:213
bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D)
Definition: SemaInternal.h:54
const TypoCorrection & peekNextCorrection()
Return the next typo correction like getNextCorrection, but keep the internal state pointed to the cu...
Definition: SemaInternal.h:181
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:982
iterator(NamespaceSpecifierSet &Set, bool IsAtEnd)
Definition: SemaInternal.h:266
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:316
Provides flat iteration over specifiers, sorted by distance.
Definition: SemaInternal.h:255
FormatToken * Current
bool includeHiddenDecls() const override
Determine whether hidden declarations (from unimported modules) should be given to this consumer...
Definition: SemaInternal.h:127
const TypoCorrection & getCurrentCorrection()
Get the last correction returned by getNextCorrection().
Definition: SemaInternal.h:171
void addNamespaces(const llvm::MapVector< NamespaceDecl *, bool > &KnownNamespaces)
Set-up method to add to the consumer the set of namespaces to use in performing corrections to nested...
unsigned getBestEditDistance(bool Normalized)
Return the edit distance of the corrections that have the closest/best edit distance from the origina...
Definition: SemaInternal.h:148
void suppressDiagnostics()
Definition: Lookup.h:522
void resetCorrectionStream()
Reset the consumer's position in the stream of viable corrections (i.e. getNextCorrection() will retu...
Definition: SemaInternal.h:191
ASTContext & Context
Definition: Sema.h:295
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
Definition: Decl.cpp:1996