clang  3.9.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() || Var->isInline()) &&
77  !(Var->isStaticDataMember() && Var->hasInit())) {
78  SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
79  if (old.isInvalid())
80  old = Loc;
81  }
82  QualType CaptureType, DeclRefType;
84  /*EllipsisLoc*/ SourceLocation(),
85  /*BuildAndDiagnose*/ true,
86  CaptureType, DeclRefType,
87  FunctionScopeIndexToStopAt);
88 
89  Var->markUsed(SemaRef.Context);
90 }
91 
92 /// Return a DLL attribute from the declaration.
94  assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
95  "A declaration cannot be both dllimport and dllexport.");
96  if (auto *Import = D->getAttr<DLLImportAttr>())
97  return Import;
98  if (auto *Export = D->getAttr<DLLExportAttr>())
99  return Export;
100  return nullptr;
101 }
102 
105  typedef llvm::StringMap<TypoResultList> TypoResultsMap;
106  typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
107 
108 public:
110  const DeclarationNameInfo &TypoName,
111  Sema::LookupNameKind LookupKind,
112  Scope *S, CXXScopeSpec *SS,
113  std::unique_ptr<CorrectionCandidateCallback> CCC,
114  DeclContext *MemberContext,
115  bool EnteringContext)
116  : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0),
117  SavedTCIndex(0), SemaRef(SemaRef), S(S),
118  SS(SS ? llvm::make_unique<CXXScopeSpec>(*SS) : nullptr),
119  CorrectionValidator(std::move(CCC)), MemberContext(MemberContext),
120  Result(SemaRef, TypoName, LookupKind),
121  Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
122  EnteringContext(EnteringContext), SearchNamespaces(false) {
123  Result.suppressDiagnostics();
124  // Arrange for ValidatedCorrections[0] to always be an empty correction.
125  ValidatedCorrections.push_back(TypoCorrection());
126  }
127 
128  bool includeHiddenDecls() const override { return true; }
129 
130  // Methods for adding potential corrections to the consumer.
131  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
132  bool InBaseClass) override;
133  void FoundName(StringRef Name);
134  void addKeywordResult(StringRef Keyword);
135  void addCorrection(TypoCorrection Correction);
136 
137  bool empty() const {
138  return CorrectionResults.empty() && ValidatedCorrections.size() == 1;
139  }
140 
141  /// \brief Return the list of TypoCorrections for the given identifier from
142  /// the set of corrections that have the closest edit distance, if any.
144  return CorrectionResults.begin()->second[Name];
145  }
146 
147  /// \brief Return the edit distance of the corrections that have the
148  /// closest/best edit distance from the original typop.
149  unsigned getBestEditDistance(bool Normalized) {
150  if (CorrectionResults.empty())
152 
153  unsigned BestED = CorrectionResults.begin()->first;
154  return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
155  }
156 
157  /// \brief Set-up method to add to the consumer the set of namespaces to use
158  /// in performing corrections to nested name specifiers. This method also
159  /// implicitly adds all of the known classes in the current AST context to the
160  /// to the consumer for correcting nested name specifiers.
161  void
162  addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
163 
164  /// \brief Return the next typo correction that passes all internal filters
165  /// and is deemed valid by the consumer's CorrectionCandidateCallback,
166  /// starting with the corrections that have the closest edit distance. An
167  /// empty TypoCorrection is returned once no more viable corrections remain
168  /// in the consumer.
170 
171  /// \brief Get the last correction returned by getNextCorrection().
173  return CurrentTCIndex < ValidatedCorrections.size()
174  ? ValidatedCorrections[CurrentTCIndex]
175  : ValidatedCorrections[0]; // The empty correction.
176  }
177 
178  /// \brief Return the next typo correction like getNextCorrection, but keep
179  /// the internal state pointed to the current correction (i.e. the next time
180  /// getNextCorrection is called, it will return the same correction returned
181  /// by peekNextcorrection).
183  auto Current = CurrentTCIndex;
184  const TypoCorrection &TC = getNextCorrection();
185  CurrentTCIndex = Current;
186  return TC;
187  }
188 
189  /// \brief Reset the consumer's position in the stream of viable corrections
190  /// (i.e. getNextCorrection() will return each of the previously returned
191  /// corrections in order before returning any new corrections).
193  CurrentTCIndex = 0;
194  }
195 
196  /// \brief Return whether the end of the stream of corrections has been
197  /// reached.
198  bool finished() {
199  return CorrectionResults.empty() &&
200  CurrentTCIndex >= ValidatedCorrections.size();
201  }
202 
203  /// \brief Save the current position in the correction stream (overwriting any
204  /// previously saved position).
206  SavedTCIndex = CurrentTCIndex;
207  }
208 
209  /// \brief Restore the saved position in the correction stream.
211  CurrentTCIndex = SavedTCIndex;
212  }
213 
214  ASTContext &getContext() const { return SemaRef.Context; }
215  const LookupResult &getLookupResult() const { return Result; }
216 
217  bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; }
218  const CXXScopeSpec *getSS() const { return SS.get(); }
219  Scope *getScope() const { return S; }
221  return CorrectionValidator.get();
222  }
223 
224 private:
225  class NamespaceSpecifierSet {
226  struct SpecifierInfo {
227  DeclContext* DeclCtx;
228  NestedNameSpecifier* NameSpecifier;
229  unsigned EditDistance;
230  };
231 
232  typedef SmallVector<DeclContext*, 4> DeclContextList;
233  typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
234 
236  DeclContextList CurContextChain;
237  std::string CurNameSpecifier;
238  SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
239  SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
240 
241  std::map<unsigned, SpecifierInfoList> DistanceMap;
242 
243  /// \brief Helper for building the list of DeclContexts between the current
244  /// context and the top of the translation unit
245  static DeclContextList buildContextChain(DeclContext *Start);
246 
247  unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
248  NestedNameSpecifier *&NNS);
249 
250  public:
251  NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
252  CXXScopeSpec *CurScopeSpec);
253 
254  /// \brief Add the DeclContext (a namespace or record) to the set, computing
255  /// the corresponding NestedNameSpecifier and its distance in the process.
256  void addNameSpecifier(DeclContext *Ctx);
257 
258  /// \brief Provides flat iteration over specifiers, sorted by distance.
259  class iterator
260  : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
261  SpecifierInfo> {
262  /// Always points to the last element in the distance map.
264  /// Iterator on the distance map.
266  /// Iterator on an element in the distance map.
268 
269  public:
270  iterator(NamespaceSpecifierSet &Set, bool IsAtEnd)
271  : OuterBack(std::prev(Set.DistanceMap.end())),
272  Outer(Set.DistanceMap.begin()),
273  Inner(!IsAtEnd ? Outer->second.begin() : OuterBack->second.end()) {
274  assert(!Set.DistanceMap.empty());
275  }
276 
278  ++Inner;
279  if (Inner == Outer->second.end() && Outer != OuterBack) {
280  ++Outer;
281  Inner = Outer->second.begin();
282  }
283  return *this;
284  }
285 
286  SpecifierInfo &operator*() { return *Inner; }
287  bool operator==(const iterator &RHS) const { return Inner == RHS.Inner; }
288  };
289 
290  iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
291  iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
292  };
293 
294  void addName(StringRef Name, NamedDecl *ND,
295  NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
296 
297  /// \brief Find any visible decls for the given typo correction candidate.
298  /// If none are found, it to the set of candidates for which qualified lookups
299  /// will be performed to find possible nested name specifier changes.
300  bool resolveCorrection(TypoCorrection &Candidate);
301 
302  /// \brief Perform qualified lookups on the queued set of typo correction
303  /// candidates and add the nested name specifier changes to each candidate if
304  /// a lookup succeeds (at which point the candidate will be returned to the
305  /// main pool of potential corrections).
306  void performQualifiedLookups();
307 
308  /// \brief The name written that is a typo in the source.
309  IdentifierInfo *Typo;
310 
311  /// \brief The results found that have the smallest edit distance
312  /// found (so far) with the typo name.
313  ///
314  /// The pointer value being set to the current DeclContext indicates
315  /// whether there is a keyword with this name.
316  TypoEditDistanceMap CorrectionResults;
317 
318  SmallVector<TypoCorrection, 4> ValidatedCorrections;
319  size_t CurrentTCIndex;
320  size_t SavedTCIndex;
321 
322  Sema &SemaRef;
323  Scope *S;
324  std::unique_ptr<CXXScopeSpec> SS;
325  std::unique_ptr<CorrectionCandidateCallback> CorrectionValidator;
326  DeclContext *MemberContext;
327  LookupResult Result;
328  NamespaceSpecifierSet Namespaces;
329  SmallVector<TypoCorrection, 2> QualifiedResults;
330  bool EnteringContext;
331  bool SearchNamespaces;
332 };
333 
334 inline Sema::TypoExprState::TypoExprState() {}
335 
336 inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT {
337  *this = std::move(other);
338 }
339 
340 inline Sema::TypoExprState &Sema::TypoExprState::operator=(
341  Sema::TypoExprState &&other) LLVM_NOEXCEPT {
342  Consumer = std::move(other.Consumer);
343  DiagHandler = std::move(other.DiagHandler);
344  RecoveryHandler = std::move(other.RecoveryHandler);
345  return *this;
346 }
347 
348 } // end namespace clang
349 
350 #endif
Defines the clang::ASTContext interface.
void MarkVarDeclODRUsed(VarDecl *Var, SourceLocation Loc, Sema &SemaRef, const unsigned *const FunctionScopeIndexToStopAt)
Definition: SemaInternal.h:70
A (possibly-)qualified type.
Definition: Type.h:598
Simple class containing the result of Sema::CorrectTypo.
CorrectionCandidateCallback * getCorrectionValidator() const
Definition: SemaInternal.h:220
TypoResultList & operator[](StringRef Name)
Return the list of TypoCorrections for the given identifier from the set of corrections that have the...
Definition: SemaInternal.h:143
void saveCurrentPosition()
Save the current position in the correction stream (overwriting any previously saved position)...
Definition: SemaInternal.h:205
Consumes visible declarations found when searching for all visible names within a given scope or cont...
Definition: Sema/Lookup.h:742
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:2090
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:768
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:198
llvm::MapVector< NamedDecl *, SourceLocation > UndefinedButUsed
UndefinedInternals - all the used, undefined objects which require a definition in this translation u...
Definition: Sema.h:980
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:13552
iterator begin() const
Definition: Type.h:4235
void addKeywordResult(StringRef Keyword)
bool FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI)
Definition: SemaInternal.h:37
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
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
Represents the results of name lookup.
Definition: Sema/Lookup.h:30
const CXXScopeSpec * getSS() const
Definition: SemaInternal.h:218
bool FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI)
Definition: SemaInternal.h:30
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
static unsigned NormalizeEditDistance(unsigned ED)
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:63
iterator end() const
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:263
void restoreSavedPosition()
Restore the saved position in the correction stream.
Definition: SemaInternal.h:210
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
Definition: DeclSpec.h:1247
ASTContext * Context
friend class ASTContext
Definition: Type.h:4178
LookupNameKind
Describes the kind of name lookup to perform.
Definition: Sema.h:2701
bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context)
Definition: SemaInternal.h:44
PartialDiagnostic::StorageAllocator & getDiagAllocator()
Definition: ASTContext.h:584
void addCorrection(TypoCorrection Correction)
bool isExternallyVisible() const
Definition: Decl.h:348
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
Definition: Decl.cpp:2213
const LookupResult & getLookupResult() const
Definition: SemaInternal.h:215
VarDecl * getCanonicalDecl() override
Definition: Decl.cpp:1908
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:109
const Expr * getAnyInitializer() const
getAnyInitializer - Get the initializer for this variable, no matter which declaration it is attached...
Definition: Decl.h:1129
#define false
Definition: stdbool.h:33
Encodes a location in the source.
const TemplateArgument * iterator
Definition: Type.h:4233
void FoundName(StringRef Name)
InheritableAttr * getDLLAttr(Decl *D)
Return a DLL attribute from the declaration.
Definition: SemaInternal.h:93
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This declaration is only a declaration.
Definition: Decl.h:1069
Represents a template argument.
Definition: TemplateBase.h:40
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1135
unsigned isVariadic
isVariadic - If this function has a prototype, and if that proto ends with ',...)', this is true.
Definition: DeclSpec.h:1213
ASTContext & getContext() const
Definition: SemaInternal.h:214
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
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:182
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1058
iterator(NamespaceSpecifierSet &Set, bool IsAtEnd)
Definition: SemaInternal.h:270
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
Provides flat iteration over specifiers, sorted by distance.
Definition: SemaInternal.h:259
FormatToken * Current
bool includeHiddenDecls() const override
Determine whether hidden declarations (from unimported modules) should be given to this consumer...
Definition: SemaInternal.h:128
bool isInline() const
Whether this variable is (C++1z) inline.
Definition: Decl.h:1258
const TypoCorrection & getCurrentCorrection()
Get the last correction returned by getNextCorrection().
Definition: SemaInternal.h:172
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:149
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Sema/Lookup.h:566
void resetCorrectionStream()
Reset the consumer's position in the stream of viable corrections (i.e.
Definition: SemaInternal.h:192
ASTContext & Context
Definition: Sema.h:299
NamedDecl - This represents a decl with a name.
Definition: Decl.h:213
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
Definition: Decl.cpp:2017
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
Definition: DeclSpec.h:1286
bool hasInit() const
Definition: Decl.cpp:2040