[Sema] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 325659
This commit is contained in:
Eugene Zelenko 2018-02-21 01:45:26 +00:00
parent e6143904b9
commit 9fbf64139e
7 changed files with 485 additions and 250 deletions

View File

@ -1,4 +1,4 @@
//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- C++ -*-===// //===- DelayedDiagnostic.h - Delayed declarator diagnostics -----*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// //
/// \file /// \file
/// \brief Defines the classes clang::DelayedDiagnostic and /// \brief Defines the classes clang::DelayedDiagnostic and
/// clang::AccessedEntity. /// clang::AccessedEntity.
@ -16,15 +16,33 @@
/// diagnostics -- notably deprecation and access control -- are suppressed /// diagnostics -- notably deprecation and access control -- are suppressed
/// based on semantic properties of the parsed declaration that aren't known /// based on semantic properties of the parsed declaration that aren't known
/// until it is fully parsed. /// until it is fully parsed.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H #ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
#define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H #define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h" #include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstddef>
#include <utility>
namespace clang { namespace clang {
class ObjCInterfaceDecl;
class ObjCPropertyDecl;
namespace sema { namespace sema {
/// A declaration being accessed, together with information about how /// A declaration being accessed, together with information about how
@ -39,16 +57,14 @@ public:
/// The target is the base class. /// The target is the base class.
enum BaseNonce { Base }; enum BaseNonce { Base };
bool isMemberAccess() const { return IsMember; }
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator, AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
MemberNonce _, MemberNonce _,
CXXRecordDecl *NamingClass, CXXRecordDecl *NamingClass,
DeclAccessPair FoundDecl, DeclAccessPair FoundDecl,
QualType BaseObjectType) QualType BaseObjectType)
: Access(FoundDecl.getAccess()), IsMember(true), : Access(FoundDecl.getAccess()), IsMember(true),
Target(FoundDecl.getDecl()), NamingClass(NamingClass), Target(FoundDecl.getDecl()), NamingClass(NamingClass),
BaseObjectType(BaseObjectType), Diag(0, Allocator) { BaseObjectType(BaseObjectType), Diag(0, Allocator) {
} }
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator, AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
@ -56,11 +72,10 @@ public:
CXXRecordDecl *BaseClass, CXXRecordDecl *BaseClass,
CXXRecordDecl *DerivedClass, CXXRecordDecl *DerivedClass,
AccessSpecifier Access) AccessSpecifier Access)
: Access(Access), IsMember(false), : Access(Access), IsMember(false), Target(BaseClass),
Target(BaseClass), NamingClass(DerivedClass), Diag(0, Allocator) {}
NamingClass(DerivedClass),
Diag(0, Allocator) { bool isMemberAccess() const { return IsMember; }
}
bool isQuiet() const { return Diag.getDiagID() == 0; } bool isQuiet() const { return Diag.getDiagID() == 0; }
@ -216,7 +231,6 @@ public:
} }
private: private:
struct AD { struct AD {
const NamedDecl *ReferringDecl; const NamedDecl *ReferringDecl;
const NamedDecl *OffendingDecl; const NamedDecl *OffendingDecl;
@ -248,20 +262,17 @@ class DelayedDiagnosticPool {
const DelayedDiagnosticPool *Parent; const DelayedDiagnosticPool *Parent;
SmallVector<DelayedDiagnostic, 4> Diagnostics; SmallVector<DelayedDiagnostic, 4> Diagnostics;
DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete;
void operator=(const DelayedDiagnosticPool &) = delete;
public: public:
DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {} DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}
~DelayedDiagnosticPool() {
for (SmallVectorImpl<DelayedDiagnostic>::iterator DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete;
i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i) DelayedDiagnosticPool &operator=(const DelayedDiagnosticPool &) = delete;
i->Destroy();
}
DelayedDiagnosticPool(DelayedDiagnosticPool &&Other) DelayedDiagnosticPool(DelayedDiagnosticPool &&Other)
: Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) { : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) {
Other.Diagnostics.clear(); Other.Diagnostics.clear();
} }
DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) { DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) {
Parent = Other.Parent; Parent = Other.Parent;
Diagnostics = std::move(Other.Diagnostics); Diagnostics = std::move(Other.Diagnostics);
@ -269,6 +280,12 @@ public:
return *this; return *this;
} }
~DelayedDiagnosticPool() {
for (SmallVectorImpl<DelayedDiagnostic>::iterator
i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
i->Destroy();
}
const DelayedDiagnosticPool *getParent() const { return Parent; } const DelayedDiagnosticPool *getParent() const { return Parent; }
/// Does this pool, or any of its ancestors, contain any diagnostics? /// Does this pool, or any of its ancestors, contain any diagnostics?
@ -293,13 +310,14 @@ public:
pool.Diagnostics.clear(); pool.Diagnostics.clear();
} }
typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator; using pool_iterator = SmallVectorImpl<DelayedDiagnostic>::const_iterator;
pool_iterator pool_begin() const { return Diagnostics.begin(); } pool_iterator pool_begin() const { return Diagnostics.begin(); }
pool_iterator pool_end() const { return Diagnostics.end(); } pool_iterator pool_end() const { return Diagnostics.end(); }
bool pool_empty() const { return Diagnostics.empty(); } bool pool_empty() const { return Diagnostics.empty(); }
}; };
} } // namespace clang
/// Add a diagnostic to the current delay pool. /// Add a diagnostic to the current delay pool.
inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) { inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
@ -307,7 +325,6 @@ inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
CurPool->add(diag); CurPool->add(diag);
} }
} // namespace clang
} #endif // LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
#endif

View File

@ -15,16 +15,20 @@
#ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H #ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
#define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H #define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
namespace clang { namespace clang {
class ASTContext;
class Decl; class Decl;
class DeclContext;
class DeclarationName; class DeclarationName;
class ExternalPreprocessorSource; class DeclContext;
class IdentifierInfo;
class LangOptions;
class NamedDecl; class NamedDecl;
class Preprocessor; class Preprocessor;
class Scope; class Scope;
@ -33,17 +37,16 @@ class Scope;
/// scopes. It manages the shadowing chains of declaration names and /// scopes. It manages the shadowing chains of declaration names and
/// implements efficient decl lookup based on a declaration name. /// implements efficient decl lookup based on a declaration name.
class IdentifierResolver { class IdentifierResolver {
/// IdDeclInfo - Keeps track of information about decls associated /// IdDeclInfo - Keeps track of information about decls associated
/// to a particular declaration name. IdDeclInfos are lazily /// to a particular declaration name. IdDeclInfos are lazily
/// constructed and assigned to a declaration name the first time a /// constructed and assigned to a declaration name the first time a
/// decl with that declaration name is shadowed in some scope. /// decl with that declaration name is shadowed in some scope.
class IdDeclInfo { class IdDeclInfo {
public: public:
typedef SmallVector<NamedDecl*, 2> DeclsTy; using DeclsTy = SmallVector<NamedDecl *, 2>;
inline DeclsTy::iterator decls_begin() { return Decls.begin(); } DeclsTy::iterator decls_begin() { return Decls.begin(); }
inline DeclsTy::iterator decls_end() { return Decls.end(); } DeclsTy::iterator decls_end() { return Decls.end(); }
void AddDecl(NamedDecl *D) { Decls.push_back(D); } void AddDecl(NamedDecl *D) { Decls.push_back(D); }
@ -61,30 +64,32 @@ class IdentifierResolver {
}; };
public: public:
/// iterator - Iterate over the decls of a specified declaration name. /// iterator - Iterate over the decls of a specified declaration name.
/// It will walk or not the parent declaration contexts depending on how /// It will walk or not the parent declaration contexts depending on how
/// it was instantiated. /// it was instantiated.
class iterator { class iterator {
public: public:
typedef NamedDecl * value_type; friend class IdentifierResolver;
typedef NamedDecl * reference;
typedef NamedDecl * pointer; using value_type = NamedDecl *;
typedef std::input_iterator_tag iterator_category; using reference = NamedDecl *;
typedef std::ptrdiff_t difference_type; using pointer = NamedDecl *;
using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t;
/// Ptr - There are 2 forms that 'Ptr' represents: /// Ptr - There are 2 forms that 'Ptr' represents:
/// 1) A single NamedDecl. (Ptr & 0x1 == 0) /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
/// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
/// same declaration context. (Ptr & 0x1 == 0x1) /// same declaration context. (Ptr & 0x1 == 0x1)
uintptr_t Ptr; uintptr_t Ptr = 0;
typedef IdDeclInfo::DeclsTy::iterator BaseIter; using BaseIter = IdDeclInfo::DeclsTy::iterator;
/// A single NamedDecl. (Ptr & 0x1 == 0) /// A single NamedDecl. (Ptr & 0x1 == 0)
iterator(NamedDecl *D) { iterator(NamedDecl *D) {
Ptr = reinterpret_cast<uintptr_t>(D); Ptr = reinterpret_cast<uintptr_t>(D);
assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
} }
/// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
/// contexts depending on 'LookInParentCtx'. /// contexts depending on 'LookInParentCtx'.
iterator(BaseIter I) { iterator(BaseIter I) {
@ -98,11 +103,10 @@ public:
return reinterpret_cast<BaseIter>(Ptr & ~0x1); return reinterpret_cast<BaseIter>(Ptr & ~0x1);
} }
friend class IdentifierResolver;
void incrementSlowCase(); void incrementSlowCase();
public: public:
iterator() : Ptr(0) {} iterator() = default;
NamedDecl *operator*() const { NamedDecl *operator*() const {
if (isIterator()) if (isIterator())
@ -128,6 +132,9 @@ public:
} }
}; };
explicit IdentifierResolver(Preprocessor &PP);
~IdentifierResolver();
/// begin - Returns an iterator for decls with the name 'Name'. /// begin - Returns an iterator for decls with the name 'Name'.
iterator begin(DeclarationName Name); iterator begin(DeclarationName Name);
@ -170,9 +177,6 @@ public:
/// \returns true if the declaration was added, false otherwise. /// \returns true if the declaration was added, false otherwise.
bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name); bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
explicit IdentifierResolver(Preprocessor &PP);
~IdentifierResolver();
private: private:
const LangOptions &LangOpt; const LangOptions &LangOpt;
Preprocessor &PP; Preprocessor &PP;
@ -193,11 +197,10 @@ private:
assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1 assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
&& "Ptr not a IdDeclInfo* !"); && "Ptr not a IdDeclInfo* !");
return reinterpret_cast<IdDeclInfo*>( return reinterpret_cast<IdDeclInfo*>(
reinterpret_cast<uintptr_t>(Ptr) & ~0x1 reinterpret_cast<uintptr_t>(Ptr) & ~0x1);
);
} }
}; };
} // end namespace clang } // namespace clang
#endif #endif // LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H

View File

@ -1,4 +1,4 @@
//===--- Initialization.h - Semantic Analysis for Initializers --*- C++ -*-===// //===- Initialization.h - Semantic Analysis for Initializers ----*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -10,32 +10,41 @@
// This file provides supporting data types for initialization of objects. // This file provides supporting data types for initialization of objects.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H #ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
#define LLVM_CLANG_SEMA_INITIALIZATION_H #define LLVM_CLANG_SEMA_INITIALIZATION_H
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h" #include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h" #include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Overload.h" #include "clang/Sema/Overload.h"
#include "clang/Sema/Ownership.h" #include "clang/Sema/Ownership.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include <cassert> #include <cassert>
#include <cstdint>
#include <string>
namespace clang { namespace clang {
class APValue;
class CXXBaseSpecifier; class CXXBaseSpecifier;
class DeclaratorDecl; class CXXConstructorDecl;
class DeclaratorInfo;
class FieldDecl;
class FunctionDecl;
class ParmVarDecl;
class Sema;
class TypeLoc;
class VarDecl;
class ObjCMethodDecl; class ObjCMethodDecl;
class Sema;
/// \brief Describes an entity that is being initialized. /// \brief Describes an entity that is being initialized.
class InitializedEntity { class InitializedEntity {
public: public:
@ -43,51 +52,69 @@ public:
enum EntityKind { enum EntityKind {
/// \brief The entity being initialized is a variable. /// \brief The entity being initialized is a variable.
EK_Variable, EK_Variable,
/// \brief The entity being initialized is a function parameter. /// \brief The entity being initialized is a function parameter.
EK_Parameter, EK_Parameter,
/// \brief The entity being initialized is the result of a function call. /// \brief The entity being initialized is the result of a function call.
EK_Result, EK_Result,
/// \brief The entity being initialized is an exception object that /// \brief The entity being initialized is an exception object that
/// is being thrown. /// is being thrown.
EK_Exception, EK_Exception,
/// \brief The entity being initialized is a non-static data member /// \brief The entity being initialized is a non-static data member
/// subobject. /// subobject.
EK_Member, EK_Member,
/// \brief The entity being initialized is an element of an array. /// \brief The entity being initialized is an element of an array.
EK_ArrayElement, EK_ArrayElement,
/// \brief The entity being initialized is an object (or array of /// \brief The entity being initialized is an object (or array of
/// objects) allocated via new. /// objects) allocated via new.
EK_New, EK_New,
/// \brief The entity being initialized is a temporary object. /// \brief The entity being initialized is a temporary object.
EK_Temporary, EK_Temporary,
/// \brief The entity being initialized is a base member subobject. /// \brief The entity being initialized is a base member subobject.
EK_Base, EK_Base,
/// \brief The initialization is being done by a delegating constructor. /// \brief The initialization is being done by a delegating constructor.
EK_Delegating, EK_Delegating,
/// \brief The entity being initialized is an element of a vector. /// \brief The entity being initialized is an element of a vector.
/// or vector. /// or vector.
EK_VectorElement, EK_VectorElement,
/// \brief The entity being initialized is a field of block descriptor for /// \brief The entity being initialized is a field of block descriptor for
/// the copied-in c++ object. /// the copied-in c++ object.
EK_BlockElement, EK_BlockElement,
/// The entity being initialized is a field of block descriptor for the /// The entity being initialized is a field of block descriptor for the
/// copied-in lambda object that's used in the lambda to block conversion. /// copied-in lambda object that's used in the lambda to block conversion.
EK_LambdaToBlockConversionBlockElement, EK_LambdaToBlockConversionBlockElement,
/// \brief The entity being initialized is the real or imaginary part of a /// \brief The entity being initialized is the real or imaginary part of a
/// complex number. /// complex number.
EK_ComplexElement, EK_ComplexElement,
/// \brief The entity being initialized is the field that captures a /// \brief The entity being initialized is the field that captures a
/// variable in a lambda. /// variable in a lambda.
EK_LambdaCapture, EK_LambdaCapture,
/// \brief The entity being initialized is the initializer for a compound /// \brief The entity being initialized is the initializer for a compound
/// literal. /// literal.
EK_CompoundLiteralInit, EK_CompoundLiteralInit,
/// \brief The entity being implicitly initialized back to the formal /// \brief The entity being implicitly initialized back to the formal
/// result type. /// result type.
EK_RelatedResult, EK_RelatedResult,
/// \brief The entity being initialized is a function parameter; function /// \brief The entity being initialized is a function parameter; function
/// is member of group of audited CF APIs. /// is member of group of audited CF APIs.
EK_Parameter_CF_Audited, EK_Parameter_CF_Audited,
/// \brief The entity being initialized is a structured binding of a /// \brief The entity being initialized is a structured binding of a
/// decomposition declaration. /// decomposition declaration.
EK_Binding, EK_Binding,
@ -103,13 +130,13 @@ private:
/// \brief If non-NULL, the parent entity in which this /// \brief If non-NULL, the parent entity in which this
/// initialization occurs. /// initialization occurs.
const InitializedEntity *Parent; const InitializedEntity *Parent = nullptr;
/// \brief The type of the object or reference being initialized. /// \brief The type of the object or reference being initialized.
QualType Type; QualType Type;
/// \brief The mangling number for the next reference temporary to be created. /// \brief The mangling number for the next reference temporary to be created.
mutable unsigned ManglingNumber; mutable unsigned ManglingNumber = 0;
struct LN { struct LN {
/// \brief When Kind == EK_Result, EK_Exception, EK_New, the /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
@ -172,20 +199,18 @@ private:
struct C Capture; struct C Capture;
}; };
InitializedEntity() : ManglingNumber(0) {} InitializedEntity() = default;
/// \brief Create the initialization entity for a variable. /// \brief Create the initialization entity for a variable.
InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable) InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
: Kind(EK), Parent(nullptr), Type(Var->getType()), : Kind(EK), Type(Var->getType()), Variable{Var, false} {}
ManglingNumber(0), Variable{Var, false} { }
/// \brief Create the initialization entity for the result of a /// \brief Create the initialization entity for the result of a
/// function, throwing an object, performing an explicit cast, or /// function, throwing an object, performing an explicit cast, or
/// initializing a parameter for which there is no declaration. /// initializing a parameter for which there is no declaration.
InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type, InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
bool NRVO = false) bool NRVO = false)
: Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0) : Kind(Kind), Type(Type) {
{
LocAndNRVO.Location = Loc.getRawEncoding(); LocAndNRVO.Location = Loc.getRawEncoding();
LocAndNRVO.NRVO = NRVO; LocAndNRVO.NRVO = NRVO;
} }
@ -193,9 +218,8 @@ private:
/// \brief Create the initialization entity for a member subobject. /// \brief Create the initialization entity for a member subobject.
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent, InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
bool Implicit) bool Implicit)
: Kind(EK_Member), Parent(Parent), Type(Member->getType()), : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
ManglingNumber(0), Variable{Member, Implicit} { Variable{Member, Implicit} {}
}
/// \brief Create the initialization entity for an array element. /// \brief Create the initialization entity for an array element.
InitializedEntity(ASTContext &Context, unsigned Index, InitializedEntity(ASTContext &Context, unsigned Index,
@ -203,9 +227,7 @@ private:
/// \brief Create the initialization entity for a lambda capture. /// \brief Create the initialization entity for a lambda capture.
InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
: Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType), : Kind(EK_LambdaCapture), Type(FieldType) {
ManglingNumber(0)
{
Capture.VarID = VarID; Capture.VarID = VarID;
Capture.Location = Loc.getRawEncoding(); Capture.Location = Loc.getRawEncoding();
} }
@ -307,7 +329,6 @@ public:
return Result; return Result;
} }
/// \brief Create the initialization entity for a base class subobject. /// \brief Create the initialization entity for a base class subobject.
static InitializedEntity static InitializedEntity
InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base, InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base,
@ -362,7 +383,6 @@ public:
return Result; return Result;
} }
/// \brief Determine the kind of initialization. /// \brief Determine the kind of initialization.
EntityKind getKind() const { return Kind; } EntityKind getKind() const { return Kind; }
@ -401,6 +421,7 @@ public:
return (getKind() == EK_Parameter || return (getKind() == EK_Parameter ||
getKind() == EK_Parameter_CF_Audited); getKind() == EK_Parameter_CF_Audited);
} }
/// \brief Determine whether this initialization consumes the /// \brief Determine whether this initialization consumes the
/// parameter. /// parameter.
bool isParameterConsumed() const { bool isParameterConsumed() const {
@ -453,6 +474,7 @@ public:
getKind() == EK_ComplexElement); getKind() == EK_ComplexElement);
return Index; return Index;
} }
/// \brief If this is already the initializer for an array or vector /// \brief If this is already the initializer for an array or vector
/// element, sets the element index. /// element, sets the element index.
void setElementIndex(unsigned Index) { void setElementIndex(unsigned Index) {
@ -460,11 +482,13 @@ public:
getKind() == EK_ComplexElement); getKind() == EK_ComplexElement);
this->Index = Index; this->Index = Index;
} }
/// \brief For a lambda capture, return the capture's name. /// \brief For a lambda capture, return the capture's name.
StringRef getCapturedVarName() const { StringRef getCapturedVarName() const {
assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
return Capture.VarID->getName(); return Capture.VarID->getName();
} }
/// \brief Determine the location of the capture when initializing /// \brief Determine the location of the capture when initializing
/// field from a captured variable in a lambda. /// field from a captured variable in a lambda.
SourceLocation getCaptureLoc() const { SourceLocation getCaptureLoc() const {
@ -493,22 +517,42 @@ class InitializationKind {
public: public:
/// \brief The kind of initialization being performed. /// \brief The kind of initialization being performed.
enum InitKind { enum InitKind {
IK_Direct, ///< Direct initialization /// Direct initialization
IK_DirectList, ///< Direct list-initialization IK_Direct,
IK_Copy, ///< Copy initialization
IK_Default, ///< Default initialization /// Direct list-initialization
IK_Value ///< Value initialization IK_DirectList,
/// Copy initialization
IK_Copy,
/// Default initialization
IK_Default,
/// Value initialization
IK_Value
}; };
private: private:
/// \brief The context of the initialization. /// \brief The context of the initialization.
enum InitContext { enum InitContext {
IC_Normal, ///< Normal context /// Normal context
IC_ExplicitConvs, ///< Normal context, but allows explicit conversion funcs IC_Normal,
IC_Implicit, ///< Implicit context (value initialization)
IC_StaticCast, ///< Static cast context /// Normal context, but allows explicit conversion functionss
IC_CStyleCast, ///< C-style cast context IC_ExplicitConvs,
IC_FunctionalCast ///< Functional cast context
/// Implicit context (value initialization)
IC_Implicit,
/// Static cast context
IC_StaticCast,
/// C-style cast context
IC_CStyleCast,
/// Functional cast context
IC_FunctionalCast
}; };
/// \brief The kind of initialization being performed. /// \brief The kind of initialization being performed.
@ -522,8 +566,7 @@ private:
InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1, InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1,
SourceLocation Loc2, SourceLocation Loc3) SourceLocation Loc2, SourceLocation Loc3)
: Kind(Kind), Context(Context) : Kind(Kind), Context(Context) {
{
Locations[0] = Loc1; Locations[0] = Loc1;
Locations[1] = Loc2; Locations[1] = Loc2;
Locations[2] = Loc3; Locations[2] = Loc3;
@ -711,86 +754,123 @@ public:
/// \brief Resolve the address of an overloaded function to a specific /// \brief Resolve the address of an overloaded function to a specific
/// function declaration. /// function declaration.
SK_ResolveAddressOfOverloadedFunction, SK_ResolveAddressOfOverloadedFunction,
/// \brief Perform a derived-to-base cast, producing an rvalue. /// \brief Perform a derived-to-base cast, producing an rvalue.
SK_CastDerivedToBaseRValue, SK_CastDerivedToBaseRValue,
/// \brief Perform a derived-to-base cast, producing an xvalue. /// \brief Perform a derived-to-base cast, producing an xvalue.
SK_CastDerivedToBaseXValue, SK_CastDerivedToBaseXValue,
/// \brief Perform a derived-to-base cast, producing an lvalue. /// \brief Perform a derived-to-base cast, producing an lvalue.
SK_CastDerivedToBaseLValue, SK_CastDerivedToBaseLValue,
/// \brief Reference binding to an lvalue. /// \brief Reference binding to an lvalue.
SK_BindReference, SK_BindReference,
/// \brief Reference binding to a temporary. /// \brief Reference binding to a temporary.
SK_BindReferenceToTemporary, SK_BindReferenceToTemporary,
/// \brief An optional copy of a temporary object to another /// \brief An optional copy of a temporary object to another
/// temporary object, which is permitted (but not required) by /// temporary object, which is permitted (but not required) by
/// C++98/03 but not C++0x. /// C++98/03 but not C++0x.
SK_ExtraneousCopyToTemporary, SK_ExtraneousCopyToTemporary,
/// \brief Direct-initialization from a reference-related object in the /// \brief Direct-initialization from a reference-related object in the
/// final stage of class copy-initialization. /// final stage of class copy-initialization.
SK_FinalCopy, SK_FinalCopy,
/// \brief Perform a user-defined conversion, either via a conversion /// \brief Perform a user-defined conversion, either via a conversion
/// function or via a constructor. /// function or via a constructor.
SK_UserConversion, SK_UserConversion,
/// \brief Perform a qualification conversion, producing an rvalue. /// \brief Perform a qualification conversion, producing an rvalue.
SK_QualificationConversionRValue, SK_QualificationConversionRValue,
/// \brief Perform a qualification conversion, producing an xvalue. /// \brief Perform a qualification conversion, producing an xvalue.
SK_QualificationConversionXValue, SK_QualificationConversionXValue,
/// \brief Perform a qualification conversion, producing an lvalue. /// \brief Perform a qualification conversion, producing an lvalue.
SK_QualificationConversionLValue, SK_QualificationConversionLValue,
/// \brief Perform a conversion adding _Atomic to a type. /// \brief Perform a conversion adding _Atomic to a type.
SK_AtomicConversion, SK_AtomicConversion,
/// \brief Perform a load from a glvalue, producing an rvalue. /// \brief Perform a load from a glvalue, producing an rvalue.
SK_LValueToRValue, SK_LValueToRValue,
/// \brief Perform an implicit conversion sequence. /// \brief Perform an implicit conversion sequence.
SK_ConversionSequence, SK_ConversionSequence,
/// \brief Perform an implicit conversion sequence without narrowing. /// \brief Perform an implicit conversion sequence without narrowing.
SK_ConversionSequenceNoNarrowing, SK_ConversionSequenceNoNarrowing,
/// \brief Perform list-initialization without a constructor. /// \brief Perform list-initialization without a constructor.
SK_ListInitialization, SK_ListInitialization,
/// \brief Unwrap the single-element initializer list for a reference. /// \brief Unwrap the single-element initializer list for a reference.
SK_UnwrapInitList, SK_UnwrapInitList,
/// \brief Rewrap the single-element initializer list for a reference. /// \brief Rewrap the single-element initializer list for a reference.
SK_RewrapInitList, SK_RewrapInitList,
/// \brief Perform initialization via a constructor. /// \brief Perform initialization via a constructor.
SK_ConstructorInitialization, SK_ConstructorInitialization,
/// \brief Perform initialization via a constructor, taking arguments from /// \brief Perform initialization via a constructor, taking arguments from
/// a single InitListExpr. /// a single InitListExpr.
SK_ConstructorInitializationFromList, SK_ConstructorInitializationFromList,
/// \brief Zero-initialize the object /// \brief Zero-initialize the object
SK_ZeroInitialization, SK_ZeroInitialization,
/// \brief C assignment /// \brief C assignment
SK_CAssignment, SK_CAssignment,
/// \brief Initialization by string /// \brief Initialization by string
SK_StringInit, SK_StringInit,
/// \brief An initialization that "converts" an Objective-C object /// \brief An initialization that "converts" an Objective-C object
/// (not a point to an object) to another Objective-C object type. /// (not a point to an object) to another Objective-C object type.
SK_ObjCObjectConversion, SK_ObjCObjectConversion,
/// \brief Array indexing for initialization by elementwise copy. /// \brief Array indexing for initialization by elementwise copy.
SK_ArrayLoopIndex, SK_ArrayLoopIndex,
/// \brief Array initialization by elementwise copy. /// \brief Array initialization by elementwise copy.
SK_ArrayLoopInit, SK_ArrayLoopInit,
/// \brief Array initialization (from an array rvalue). /// \brief Array initialization (from an array rvalue).
SK_ArrayInit, SK_ArrayInit,
/// \brief Array initialization (from an array rvalue) as a GNU extension. /// \brief Array initialization (from an array rvalue) as a GNU extension.
SK_GNUArrayInit, SK_GNUArrayInit,
/// \brief Array initialization from a parenthesized initializer list. /// \brief Array initialization from a parenthesized initializer list.
/// This is a GNU C++ extension. /// This is a GNU C++ extension.
SK_ParenthesizedArrayInit, SK_ParenthesizedArrayInit,
/// \brief Pass an object by indirect copy-and-restore. /// \brief Pass an object by indirect copy-and-restore.
SK_PassByIndirectCopyRestore, SK_PassByIndirectCopyRestore,
/// \brief Pass an object by indirect restore. /// \brief Pass an object by indirect restore.
SK_PassByIndirectRestore, SK_PassByIndirectRestore,
/// \brief Produce an Objective-C object pointer. /// \brief Produce an Objective-C object pointer.
SK_ProduceObjCObject, SK_ProduceObjCObject,
/// \brief Construct a std::initializer_list from an initializer list. /// \brief Construct a std::initializer_list from an initializer list.
SK_StdInitializerList, SK_StdInitializerList,
/// \brief Perform initialization via a constructor taking a single /// \brief Perform initialization via a constructor taking a single
/// std::initializer_list argument. /// std::initializer_list argument.
SK_StdInitializerListConstructorCall, SK_StdInitializerListConstructorCall,
/// \brief Initialize an OpenCL sampler from an integer. /// \brief Initialize an OpenCL sampler from an integer.
SK_OCLSamplerInit, SK_OCLSamplerInit,
/// \brief Initialize queue_t from 0. /// \brief Initialize queue_t from 0.
SK_OCLZeroQueue, SK_OCLZeroQueue,
/// \brief Passing zero to a function where OpenCL event_t is expected. /// \brief Passing zero to a function where OpenCL event_t is expected.
SK_OCLZeroEvent SK_OCLZeroEvent
}; };
@ -847,79 +927,113 @@ public:
enum FailureKind { enum FailureKind {
/// \brief Too many initializers provided for a reference. /// \brief Too many initializers provided for a reference.
FK_TooManyInitsForReference, FK_TooManyInitsForReference,
/// \brief Reference initialized from a parenthesized initializer list. /// \brief Reference initialized from a parenthesized initializer list.
FK_ParenthesizedListInitForReference, FK_ParenthesizedListInitForReference,
/// \brief Array must be initialized with an initializer list. /// \brief Array must be initialized with an initializer list.
FK_ArrayNeedsInitList, FK_ArrayNeedsInitList,
/// \brief Array must be initialized with an initializer list or a /// \brief Array must be initialized with an initializer list or a
/// string literal. /// string literal.
FK_ArrayNeedsInitListOrStringLiteral, FK_ArrayNeedsInitListOrStringLiteral,
/// \brief Array must be initialized with an initializer list or a /// \brief Array must be initialized with an initializer list or a
/// wide string literal. /// wide string literal.
FK_ArrayNeedsInitListOrWideStringLiteral, FK_ArrayNeedsInitListOrWideStringLiteral,
/// \brief Initializing a wide char array with narrow string literal. /// \brief Initializing a wide char array with narrow string literal.
FK_NarrowStringIntoWideCharArray, FK_NarrowStringIntoWideCharArray,
/// \brief Initializing char array with wide string literal. /// \brief Initializing char array with wide string literal.
FK_WideStringIntoCharArray, FK_WideStringIntoCharArray,
/// \brief Initializing wide char array with incompatible wide string /// \brief Initializing wide char array with incompatible wide string
/// literal. /// literal.
FK_IncompatWideStringIntoWideChar, FK_IncompatWideStringIntoWideChar,
/// \brief Array type mismatch. /// \brief Array type mismatch.
FK_ArrayTypeMismatch, FK_ArrayTypeMismatch,
/// \brief Non-constant array initializer /// \brief Non-constant array initializer
FK_NonConstantArrayInit, FK_NonConstantArrayInit,
/// \brief Cannot resolve the address of an overloaded function. /// \brief Cannot resolve the address of an overloaded function.
FK_AddressOfOverloadFailed, FK_AddressOfOverloadFailed,
/// \brief Overloading due to reference initialization failed. /// \brief Overloading due to reference initialization failed.
FK_ReferenceInitOverloadFailed, FK_ReferenceInitOverloadFailed,
/// \brief Non-const lvalue reference binding to a temporary. /// \brief Non-const lvalue reference binding to a temporary.
FK_NonConstLValueReferenceBindingToTemporary, FK_NonConstLValueReferenceBindingToTemporary,
/// \brief Non-const lvalue reference binding to a bit-field. /// \brief Non-const lvalue reference binding to a bit-field.
FK_NonConstLValueReferenceBindingToBitfield, FK_NonConstLValueReferenceBindingToBitfield,
/// \brief Non-const lvalue reference binding to a vector element. /// \brief Non-const lvalue reference binding to a vector element.
FK_NonConstLValueReferenceBindingToVectorElement, FK_NonConstLValueReferenceBindingToVectorElement,
/// \brief Non-const lvalue reference binding to an lvalue of unrelated /// \brief Non-const lvalue reference binding to an lvalue of unrelated
/// type. /// type.
FK_NonConstLValueReferenceBindingToUnrelated, FK_NonConstLValueReferenceBindingToUnrelated,
/// \brief Rvalue reference binding to an lvalue. /// \brief Rvalue reference binding to an lvalue.
FK_RValueReferenceBindingToLValue, FK_RValueReferenceBindingToLValue,
/// \brief Reference binding drops qualifiers. /// \brief Reference binding drops qualifiers.
FK_ReferenceInitDropsQualifiers, FK_ReferenceInitDropsQualifiers,
/// \brief Reference binding failed. /// \brief Reference binding failed.
FK_ReferenceInitFailed, FK_ReferenceInitFailed,
/// \brief Implicit conversion failed. /// \brief Implicit conversion failed.
FK_ConversionFailed, FK_ConversionFailed,
/// \brief Implicit conversion failed. /// \brief Implicit conversion failed.
FK_ConversionFromPropertyFailed, FK_ConversionFromPropertyFailed,
/// \brief Too many initializers for scalar /// \brief Too many initializers for scalar
FK_TooManyInitsForScalar, FK_TooManyInitsForScalar,
/// \brief Scalar initialized from a parenthesized initializer list. /// \brief Scalar initialized from a parenthesized initializer list.
FK_ParenthesizedListInitForScalar, FK_ParenthesizedListInitForScalar,
/// \brief Reference initialization from an initializer list /// \brief Reference initialization from an initializer list
FK_ReferenceBindingToInitList, FK_ReferenceBindingToInitList,
/// \brief Initialization of some unused destination type with an /// \brief Initialization of some unused destination type with an
/// initializer list. /// initializer list.
FK_InitListBadDestinationType, FK_InitListBadDestinationType,
/// \brief Overloading for a user-defined conversion failed. /// \brief Overloading for a user-defined conversion failed.
FK_UserConversionOverloadFailed, FK_UserConversionOverloadFailed,
/// \brief Overloading for initialization by constructor failed. /// \brief Overloading for initialization by constructor failed.
FK_ConstructorOverloadFailed, FK_ConstructorOverloadFailed,
/// \brief Overloading for list-initialization by constructor failed. /// \brief Overloading for list-initialization by constructor failed.
FK_ListConstructorOverloadFailed, FK_ListConstructorOverloadFailed,
/// \brief Default-initialization of a 'const' object. /// \brief Default-initialization of a 'const' object.
FK_DefaultInitOfConst, FK_DefaultInitOfConst,
/// \brief Initialization of an incomplete type. /// \brief Initialization of an incomplete type.
FK_Incomplete, FK_Incomplete,
/// \brief Variable-length array must not have an initializer. /// \brief Variable-length array must not have an initializer.
FK_VariableLengthArrayHasInitializer, FK_VariableLengthArrayHasInitializer,
/// \brief List initialization failed at some point. /// \brief List initialization failed at some point.
FK_ListInitializationFailed, FK_ListInitializationFailed,
/// \brief Initializer has a placeholder type which cannot be /// \brief Initializer has a placeholder type which cannot be
/// resolved by initialization. /// resolved by initialization.
FK_PlaceholderType, FK_PlaceholderType,
/// \brief Trying to take the address of a function that doesn't support /// \brief Trying to take the address of a function that doesn't support
/// having its address taken. /// having its address taken.
FK_AddressOfUnaddressableFunction, FK_AddressOfUnaddressableFunction,
/// \brief List-copy-initialization chose an explicit constructor. /// \brief List-copy-initialization chose an explicit constructor.
FK_ExplicitConstructor, FK_ExplicitConstructor,
}; };
@ -951,7 +1065,6 @@ public:
} }
private: private:
/// \brief Prints a follow-up note that highlights the location of /// \brief Prints a follow-up note that highlights the location of
/// the initialized entity, if it's remote. /// the initialized entity, if it's remote.
void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity); void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
@ -1036,11 +1149,13 @@ public:
/// \brief Determine whether the initialization sequence is invalid. /// \brief Determine whether the initialization sequence is invalid.
bool Failed() const { return SequenceKind == FailedSequence; } bool Failed() const { return SequenceKind == FailedSequence; }
typedef SmallVectorImpl<Step>::const_iterator step_iterator; using step_iterator = SmallVectorImpl<Step>::const_iterator;
step_iterator step_begin() const { return Steps.begin(); } step_iterator step_begin() const { return Steps.begin(); }
step_iterator step_end() const { return Steps.end(); } step_iterator step_end() const { return Steps.end(); }
typedef llvm::iterator_range<step_iterator> step_range; using step_range = llvm::iterator_range<step_iterator>;
step_range steps() const { return {step_begin(), step_end()}; } step_range steps() const { return {step_begin(), step_end()}; }
/// \brief Determine whether this initialization is a direct reference /// \brief Determine whether this initialization is a direct reference
@ -1245,6 +1360,6 @@ public:
void dump() const; void dump() const;
}; };
} // end namespace clang } // namespace clang
#endif // LLVM_CLANG_SEMA_INITIALIZATION_H #endif // LLVM_CLANG_SEMA_INITIALIZATION_H

View File

@ -1,4 +1,4 @@
//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===// //===- Lookup.h - Classes for name lookup -----------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -15,13 +15,28 @@
#ifndef LLVM_CLANG_SEMA_LOOKUP_H #ifndef LLVM_CLANG_SEMA_LOOKUP_H
#define LLVM_CLANG_SEMA_LOOKUP_H #define LLVM_CLANG_SEMA_LOOKUP_H
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h" #include "clang/Sema/Sema.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <utility>
namespace clang { namespace clang {
class CXXBasePaths;
/// @brief Represents the results of name lookup. /// @brief Represents the results of name lookup.
/// ///
/// An instance of the LookupResult class captures the results of a /// An instance of the LookupResult class captures the results of a
@ -126,25 +141,15 @@ public:
Temporary Temporary
}; };
typedef UnresolvedSetImpl::iterator iterator; using iterator = UnresolvedSetImpl::iterator;
LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo, LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo,
Sema::LookupNameKind LookupKind, Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
: ResultKind(NotFound), : SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind),
Paths(nullptr), Redecl(Redecl != Sema::NotForRedeclaration),
NamingClass(nullptr), ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
SemaPtr(&SemaRef), Diagnose(Redecl == Sema::NotForRedeclaration) {
NameInfo(NameInfo),
LookupKind(LookupKind),
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
HideTags(true),
Diagnose(Redecl == Sema::NotForRedeclaration),
AllowHidden(false),
Shadowed(false)
{
configure(); configure();
} }
@ -154,20 +159,10 @@ public:
LookupResult(Sema &SemaRef, DeclarationName Name, LookupResult(Sema &SemaRef, DeclarationName Name,
SourceLocation NameLoc, Sema::LookupNameKind LookupKind, SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
: ResultKind(NotFound), : SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind),
Paths(nullptr), Redecl(Redecl != Sema::NotForRedeclaration),
NamingClass(nullptr), ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
SemaPtr(&SemaRef), Diagnose(Redecl == Sema::NotForRedeclaration) {
NameInfo(Name, NameLoc),
LookupKind(LookupKind),
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
HideTags(true),
Diagnose(Redecl == Sema::NotForRedeclaration),
AllowHidden(false),
Shadowed(false)
{
configure(); configure();
} }
@ -175,20 +170,10 @@ public:
/// using the information from another result. Diagnostics are always /// using the information from another result. Diagnostics are always
/// disabled. /// disabled.
LookupResult(TemporaryToken _, const LookupResult &Other) LookupResult(TemporaryToken _, const LookupResult &Other)
: ResultKind(NotFound), : SemaPtr(Other.SemaPtr), NameInfo(Other.NameInfo),
Paths(nullptr), LookupKind(Other.LookupKind), IDNS(Other.IDNS), Redecl(Other.Redecl),
NamingClass(nullptr), ExternalRedecl(Other.ExternalRedecl), HideTags(Other.HideTags),
SemaPtr(Other.SemaPtr), AllowHidden(Other.AllowHidden) {}
NameInfo(Other.NameInfo),
LookupKind(Other.LookupKind),
IDNS(Other.IDNS),
Redecl(Other.Redecl),
ExternalRedecl(Other.ExternalRedecl),
HideTags(Other.HideTags),
Diagnose(false),
AllowHidden(Other.AllowHidden),
Shadowed(false)
{}
// FIXME: Remove these deleted methods once the default build includes // FIXME: Remove these deleted methods once the default build includes
// -Wdeprecated. // -Wdeprecated.
@ -213,6 +198,7 @@ public:
Other.Paths = nullptr; Other.Paths = nullptr;
Other.Diagnose = false; Other.Diagnose = false;
} }
LookupResult &operator=(LookupResult &&Other) { LookupResult &operator=(LookupResult &&Other) {
ResultKind = std::move(Other.ResultKind); ResultKind = std::move(Other.ResultKind);
Ambiguity = std::move(Other.Ambiguity); Ambiguity = std::move(Other.Ambiguity);
@ -618,15 +604,14 @@ public:
/// filtering out results. The results returned are possibly /// filtering out results. The results returned are possibly
/// sugared. /// sugared.
class Filter { class Filter {
friend class LookupResult;
LookupResult &Results; LookupResult &Results;
LookupResult::iterator I; LookupResult::iterator I;
bool Changed; bool Changed = false;
bool CalledDone; bool CalledDone = false;
friend class LookupResult; Filter(LookupResult &Results) : Results(Results), I(Results.begin()) {}
Filter(LookupResult &Results)
: Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
{}
public: public:
Filter(Filter &&F) Filter(Filter &&F)
@ -634,6 +619,7 @@ public:
CalledDone(F.CalledDone) { CalledDone(F.CalledDone) {
F.CalledDone = true; F.CalledDone = true;
} }
~Filter() { ~Filter() {
assert(CalledDone && assert(CalledDone &&
"LookupResult::Filter destroyed without done() call"); "LookupResult::Filter destroyed without done() call");
@ -722,11 +708,11 @@ private:
static void deletePaths(CXXBasePaths *); static void deletePaths(CXXBasePaths *);
// Results. // Results.
LookupResultKind ResultKind; LookupResultKind ResultKind = NotFound;
AmbiguityKind Ambiguity; // ill-defined unless ambiguous AmbiguityKind Ambiguity; // ill-defined unless ambiguous
UnresolvedSet<8> Decls; UnresolvedSet<8> Decls;
CXXBasePaths *Paths; CXXBasePaths *Paths = nullptr;
CXXRecordDecl *NamingClass; CXXRecordDecl *NamingClass = nullptr;
QualType BaseObjectType; QualType BaseObjectType;
// Parameters. // Parameters.
@ -734,24 +720,24 @@ private:
DeclarationNameInfo NameInfo; DeclarationNameInfo NameInfo;
SourceRange NameContextRange; SourceRange NameContextRange;
Sema::LookupNameKind LookupKind; Sema::LookupNameKind LookupKind;
unsigned IDNS; // set by configure() unsigned IDNS = 0; // set by configure()
bool Redecl; bool Redecl;
bool ExternalRedecl; bool ExternalRedecl;
/// \brief True if tag declarations should be hidden if non-tags /// \brief True if tag declarations should be hidden if non-tags
/// are present /// are present
bool HideTags; bool HideTags = true;
bool Diagnose; bool Diagnose = false;
/// \brief True if we should allow hidden declarations to be 'visible'. /// \brief True if we should allow hidden declarations to be 'visible'.
bool AllowHidden; bool AllowHidden = false;
/// \brief True if the found declarations were shadowed by some other /// \brief True if the found declarations were shadowed by some other
/// declaration that we skipped. This only happens when \c LookupKind /// declaration that we skipped. This only happens when \c LookupKind
/// is \c LookupRedeclarationWithLinkage. /// is \c LookupRedeclarationWithLinkage.
bool Shadowed; bool Shadowed = false;
}; };
/// \brief Consumes visible declarations found when searching for /// \brief Consumes visible declarations found when searching for
@ -813,13 +799,13 @@ public:
Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
} }
typedef llvm::mapped_iterator<decltype(Decls)::iterator, select_second> using iterator =
iterator; llvm::mapped_iterator<decltype(Decls)::iterator, select_second>;
iterator begin() { return iterator(Decls.begin(), select_second()); } iterator begin() { return iterator(Decls.begin(), select_second()); }
iterator end() { return iterator(Decls.end(), select_second()); } iterator end() { return iterator(Decls.end(), select_second()); }
}; };
} } // namespace clang
#endif #endif // LLVM_CLANG_SEMA_LOOKUP_H

View File

@ -1,4 +1,4 @@
//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===// //===- Overload.h - C++ Overloading -----------------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -16,32 +16,51 @@
#define LLVM_CLANG_SEMA_OVERLOAD_H #define LLVM_CLANG_SEMA_OVERLOAD_H
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h" #include "clang/AST/Expr.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h" #include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AlignOf.h" #include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <utility>
namespace clang { namespace clang {
class ASTContext;
class CXXConstructorDecl; class APValue;
class CXXConversionDecl; class ASTContext;
class FunctionDecl; class Sema;
class Sema;
/// OverloadingResult - Capture the result of performing overload /// OverloadingResult - Capture the result of performing overload
/// resolution. /// resolution.
enum OverloadingResult { enum OverloadingResult {
OR_Success, ///< Overload resolution succeeded. /// Overload resolution succeeded.
OR_No_Viable_Function, ///< No viable function found. OR_Success,
OR_Ambiguous, ///< Ambiguous candidates found.
OR_Deleted ///< Succeeded, but refers to a deleted function. /// No viable function found.
OR_No_Viable_Function,
/// Ambiguous candidates found.
OR_Ambiguous,
/// Succeeded, but refers to a deleted function.
OR_Deleted
}; };
enum OverloadCandidateDisplayKind { enum OverloadCandidateDisplayKind {
@ -58,36 +77,92 @@ namespace clang {
/// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
/// better conversion kinds have smaller values. /// better conversion kinds have smaller values.
enum ImplicitConversionKind { enum ImplicitConversionKind {
ICK_Identity = 0, ///< Identity conversion (no conversion) /// Identity conversion (no conversion)
ICK_Lvalue_To_Rvalue, ///< Lvalue-to-rvalue conversion (C++ 4.1) ICK_Identity = 0,
ICK_Array_To_Pointer, ///< Array-to-pointer conversion (C++ 4.2)
ICK_Function_To_Pointer, ///< Function-to-pointer (C++ 4.3) /// Lvalue-to-rvalue conversion (C++ 4.1)
ICK_Function_Conversion, ///< Function pointer conversion (C++17 4.13) ICK_Lvalue_To_Rvalue,
ICK_Qualification, ///< Qualification conversions (C++ 4.4)
ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5) /// Array-to-pointer conversion (C++ 4.2)
ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6) ICK_Array_To_Pointer,
ICK_Complex_Promotion, ///< Complex promotions (Clang extension)
ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7) /// Function-to-pointer (C++ 4.3)
ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8) ICK_Function_To_Pointer,
ICK_Complex_Conversion, ///< Complex conversions (C99 6.3.1.6)
ICK_Floating_Integral, ///< Floating-integral conversions (C++ 4.9) /// Function pointer conversion (C++17 4.13)
ICK_Pointer_Conversion, ///< Pointer conversions (C++ 4.10) ICK_Function_Conversion,
ICK_Pointer_Member, ///< Pointer-to-member conversions (C++ 4.11)
ICK_Boolean_Conversion, ///< Boolean conversions (C++ 4.12) /// Qualification conversions (C++ 4.4)
ICK_Compatible_Conversion, ///< Conversions between compatible types in C99 ICK_Qualification,
ICK_Derived_To_Base, ///< Derived-to-base (C++ [over.best.ics])
ICK_Vector_Conversion, ///< Vector conversions /// Integral promotions (C++ 4.5)
ICK_Vector_Splat, ///< A vector splat from an arithmetic type ICK_Integral_Promotion,
ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7)
ICK_Block_Pointer_Conversion, ///< Block Pointer conversions /// Floating point promotions (C++ 4.6)
ICK_TransparentUnionConversion, ///< Transparent Union Conversions ICK_Floating_Promotion,
ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion
ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10) /// Complex promotions (Clang extension)
ICK_Zero_Queue_Conversion, ///< Zero constant to queue ICK_Complex_Promotion,
ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++
ICK_Incompatible_Pointer_Conversion, ///< C-only conversion between pointers /// Integral conversions (C++ 4.7)
/// with incompatible types ICK_Integral_Conversion,
ICK_Num_Conversion_Kinds, ///< The number of conversion kinds
/// Floating point conversions (C++ 4.8)
ICK_Floating_Conversion,
/// Complex conversions (C99 6.3.1.6)
ICK_Complex_Conversion,
/// Floating-integral conversions (C++ 4.9)
ICK_Floating_Integral,
/// Pointer conversions (C++ 4.10)
ICK_Pointer_Conversion,
/// Pointer-to-member conversions (C++ 4.11)
ICK_Pointer_Member,
/// Boolean conversions (C++ 4.12)
ICK_Boolean_Conversion,
/// Conversions between compatible types in C99
ICK_Compatible_Conversion,
/// Derived-to-base (C++ [over.best.ics])
ICK_Derived_To_Base,
/// Vector conversions
ICK_Vector_Conversion,
/// A vector splat from an arithmetic type
ICK_Vector_Splat,
/// Complex-real conversions (C99 6.3.1.7)
ICK_Complex_Real,
/// Block Pointer conversions
ICK_Block_Pointer_Conversion,
/// Transparent Union Conversions
ICK_TransparentUnionConversion,
/// Objective-C ARC writeback conversion
ICK_Writeback_Conversion,
/// Zero constant to event (OpenCL1.2 6.12.10)
ICK_Zero_Event_Conversion,
/// Zero constant to queue
ICK_Zero_Queue_Conversion,
/// Conversions allowed in C, but not C++
ICK_C_Only_Conversion,
/// C-only conversion between pointers with incompatible types
ICK_Incompatible_Pointer_Conversion,
/// The number of conversion kinds
ICK_Num_Conversion_Kinds,
}; };
/// ImplicitConversionRank - The rank of an implicit conversion /// ImplicitConversionRank - The rank of an implicit conversion
@ -95,16 +170,30 @@ namespace clang {
/// 13.3.3.1.1) and are listed such that better conversion ranks /// 13.3.3.1.1) and are listed such that better conversion ranks
/// have smaller values. /// have smaller values.
enum ImplicitConversionRank { enum ImplicitConversionRank {
ICR_Exact_Match = 0, ///< Exact Match /// Exact Match
ICR_Promotion, ///< Promotion ICR_Exact_Match = 0,
ICR_Conversion, ///< Conversion
ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening /// Promotion
ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion ICR_Promotion,
ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion
ICR_C_Conversion, ///< Conversion only allowed in the C standard. /// Conversion
/// (e.g. void* to char*) ICR_Conversion,
ICR_C_Conversion_Extension ///< Conversion not allowed by the C standard,
/// but that we accept as an extension anyway. /// OpenCL Scalar Widening
ICR_OCL_Scalar_Widening,
/// Complex <-> Real conversion
ICR_Complex_Real_Conversion,
/// ObjC ARC writeback conversion
ICR_Writeback_Conversion,
/// Conversion only allowed in the C standard (e.g. void* to char*).
ICR_C_Conversion,
/// Conversion not allowed by the C standard, but that we accept as an
/// extension anyway.
ICR_C_Conversion_Extension
}; };
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind); ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
@ -213,10 +302,12 @@ namespace clang {
DeclAccessPair FoundCopyConstructor; DeclAccessPair FoundCopyConstructor;
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
void setToType(unsigned Idx, QualType T) { void setToType(unsigned Idx, QualType T) {
assert(Idx < 3 && "To type index is out of range"); assert(Idx < 3 && "To type index is out of range");
ToTypePtrs[Idx] = T.getAsOpaquePtr(); ToTypePtrs[Idx] = T.getAsOpaquePtr();
} }
void setAllToTypes(QualType T) { void setAllToTypes(QualType T) {
ToTypePtrs[0] = T.getAsOpaquePtr(); ToTypePtrs[0] = T.getAsOpaquePtr();
ToTypePtrs[1] = ToTypePtrs[0]; ToTypePtrs[1] = ToTypePtrs[0];
@ -226,6 +317,7 @@ namespace clang {
QualType getFromType() const { QualType getFromType() const {
return QualType::getFromOpaquePtr(FromTypePtr); return QualType::getFromOpaquePtr(FromTypePtr);
} }
QualType getToType(unsigned Idx) const { QualType getToType(unsigned Idx) const {
assert(Idx < 3 && "To type index is out of range"); assert(Idx < 3 && "To type index is out of range");
return QualType::getFromOpaquePtr(ToTypePtrs[Idx]); return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
@ -294,7 +386,8 @@ namespace clang {
/// Represents an ambiguous user-defined conversion sequence. /// Represents an ambiguous user-defined conversion sequence.
struct AmbiguousConversionSequence { struct AmbiguousConversionSequence {
typedef SmallVector<std::pair<NamedDecl*, FunctionDecl*>, 4> ConversionSet; using ConversionSet =
SmallVector<std::pair<NamedDecl *, FunctionDecl *>, 4>;
void *FromTypePtr; void *FromTypePtr;
void *ToTypePtr; void *ToTypePtr;
@ -303,9 +396,11 @@ namespace clang {
QualType getFromType() const { QualType getFromType() const {
return QualType::getFromOpaquePtr(FromTypePtr); return QualType::getFromOpaquePtr(FromTypePtr);
} }
QualType getToType() const { QualType getToType() const {
return QualType::getFromOpaquePtr(ToTypePtr); return QualType::getFromOpaquePtr(ToTypePtr);
} }
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); } void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
@ -321,11 +416,13 @@ namespace clang {
conversions().push_back(std::make_pair(Found, D)); conversions().push_back(std::make_pair(Found, D));
} }
typedef ConversionSet::iterator iterator; using iterator = ConversionSet::iterator;
iterator begin() { return conversions().begin(); } iterator begin() { return conversions().begin(); }
iterator end() { return conversions().end(); } iterator end() { return conversions().end(); }
typedef ConversionSet::const_iterator const_iterator; using const_iterator = ConversionSet::const_iterator;
const_iterator begin() const { return conversions().begin(); } const_iterator begin() const { return conversions().begin(); }
const_iterator end() const { return conversions().end(); } const_iterator end() const { return conversions().end(); }
@ -362,6 +459,7 @@ namespace clang {
init(K, From->getType(), To); init(K, From->getType(), To);
FromExpr = From; FromExpr = From;
} }
void init(FailureKind K, QualType From, QualType To) { void init(FailureKind K, QualType From, QualType To) {
Kind = K; Kind = K;
FromExpr = nullptr; FromExpr = nullptr;
@ -376,6 +474,7 @@ namespace clang {
FromExpr = E; FromExpr = E;
setFromType(E->getType()); setFromType(E->getType());
} }
void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); } void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); } void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
}; };
@ -442,13 +541,10 @@ namespace clang {
: ConversionKind(Uninitialized), StdInitializerListElement(false) { : ConversionKind(Uninitialized), StdInitializerListElement(false) {
Standard.setAsIdentityConversion(); Standard.setAsIdentityConversion();
} }
~ImplicitConversionSequence() {
destruct();
}
ImplicitConversionSequence(const ImplicitConversionSequence &Other) ImplicitConversionSequence(const ImplicitConversionSequence &Other)
: ConversionKind(Other.ConversionKind), : ConversionKind(Other.ConversionKind),
StdInitializerListElement(Other.StdInitializerListElement) StdInitializerListElement(Other.StdInitializerListElement) {
{
switch (ConversionKind) { switch (ConversionKind) {
case Uninitialized: break; case Uninitialized: break;
case StandardConversion: Standard = Other.Standard; break; case StandardConversion: Standard = Other.Standard; break;
@ -460,12 +556,16 @@ namespace clang {
} }
ImplicitConversionSequence & ImplicitConversionSequence &
operator=(const ImplicitConversionSequence &Other) { operator=(const ImplicitConversionSequence &Other) {
destruct(); destruct();
new (this) ImplicitConversionSequence(Other); new (this) ImplicitConversionSequence(Other);
return *this; return *this;
} }
~ImplicitConversionSequence() {
destruct();
}
Kind getKind() const { Kind getKind() const {
assert(isInitialized() && "querying uninitialized conversion"); assert(isInitialized() && "querying uninitialized conversion");
return Kind(ConversionKind); return Kind(ConversionKind);
@ -526,6 +626,7 @@ namespace clang {
void setStandard() { setKind(StandardConversion); } void setStandard() { setKind(StandardConversion); }
void setEllipsis() { setKind(EllipsisConversion); } void setEllipsis() { setKind(EllipsisConversion); }
void setUserDefined() { setKind(UserDefinedConversion); } void setUserDefined() { setKind(UserDefinedConversion); }
void setAmbiguous() { void setAmbiguous() {
if (ConversionKind == AmbiguousConversion) return; if (ConversionKind == AmbiguousConversion) return;
ConversionKind = AmbiguousConversion; ConversionKind = AmbiguousConversion;
@ -621,8 +722,8 @@ namespace clang {
/// A list of implicit conversion sequences for the arguments of an /// A list of implicit conversion sequences for the arguments of an
/// OverloadCandidate. /// OverloadCandidate.
typedef llvm::MutableArrayRef<ImplicitConversionSequence> using ConversionSequenceList =
ConversionSequenceList; llvm::MutableArrayRef<ImplicitConversionSequence>;
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3). /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
struct OverloadCandidate { struct OverloadCandidate {
@ -730,16 +831,19 @@ namespace clang {
enum CandidateSetKind { enum CandidateSetKind {
/// Normal lookup. /// Normal lookup.
CSK_Normal, CSK_Normal,
/// C++ [over.match.oper]: /// C++ [over.match.oper]:
/// Lookup of operator function candidates in a call using operator /// Lookup of operator function candidates in a call using operator
/// syntax. Candidates that have no parameters of class type will be /// syntax. Candidates that have no parameters of class type will be
/// skipped unless there is a parameter of (reference to) enum type and /// skipped unless there is a parameter of (reference to) enum type and
/// the corresponding argument is of the same enum type. /// the corresponding argument is of the same enum type.
CSK_Operator, CSK_Operator,
/// C++ [over.match.copy]: /// C++ [over.match.copy]:
/// Copy-initialization of an object of class type by user-defined /// Copy-initialization of an object of class type by user-defined
/// conversion. /// conversion.
CSK_InitByUserDefinedConversion, CSK_InitByUserDefinedConversion,
/// C++ [over.match.ctor], [over.match.list] /// C++ [over.match.ctor], [over.match.list]
/// Initialization of an object of class type by constructor, /// Initialization of an object of class type by constructor,
/// using either a parenthesized or braced list of arguments. /// using either a parenthesized or braced list of arguments.
@ -759,7 +863,7 @@ namespace clang {
constexpr static unsigned NumInlineBytes = constexpr static unsigned NumInlineBytes =
24 * sizeof(ImplicitConversionSequence); 24 * sizeof(ImplicitConversionSequence);
unsigned NumInlineBytesUsed; unsigned NumInlineBytesUsed = 0;
llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace; llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
/// If we have space, allocates from inline storage. Otherwise, allocates /// If we have space, allocates from inline storage. Otherwise, allocates
@ -788,14 +892,13 @@ namespace clang {
return reinterpret_cast<T *>(FreeSpaceStart); return reinterpret_cast<T *>(FreeSpaceStart);
} }
OverloadCandidateSet(const OverloadCandidateSet &) = delete;
void operator=(const OverloadCandidateSet &) = delete;
void destroyCandidates(); void destroyCandidates();
public: public:
OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK) OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
: Loc(Loc), Kind(CSK), NumInlineBytesUsed(0) {} : Loc(Loc), Kind(CSK) {}
OverloadCandidateSet(const OverloadCandidateSet &) = delete;
OverloadCandidateSet &operator=(const OverloadCandidateSet &) = delete;
~OverloadCandidateSet() { destroyCandidates(); } ~OverloadCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; } SourceLocation getLocation() const { return Loc; }
@ -810,7 +913,8 @@ namespace clang {
/// \brief Clear out all of the candidates. /// \brief Clear out all of the candidates.
void clear(CandidateSetKind CSK); void clear(CandidateSetKind CSK);
typedef SmallVectorImpl<OverloadCandidate>::iterator iterator; using iterator = SmallVectorImpl<OverloadCandidate>::iterator;
iterator begin() { return Candidates.begin(); } iterator begin() { return Candidates.begin(); }
iterator end() { return Candidates.end(); } iterator end() { return Candidates.end(); }
@ -869,8 +973,10 @@ namespace clang {
DeclAccessPair FoundDecl; DeclAccessPair FoundDecl;
CXXConstructorDecl *Constructor; CXXConstructorDecl *Constructor;
FunctionTemplateDecl *ConstructorTmpl; FunctionTemplateDecl *ConstructorTmpl;
explicit operator bool() const { return Constructor; } explicit operator bool() const { return Constructor; }
}; };
// FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload // FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload
// that takes one of these. // that takes one of these.
inline ConstructorInfo getConstructorInfo(NamedDecl *ND) { inline ConstructorInfo getConstructorInfo(NamedDecl *ND) {
@ -888,6 +994,7 @@ namespace clang {
Info.Constructor = dyn_cast<CXXConstructorDecl>(D); Info.Constructor = dyn_cast<CXXConstructorDecl>(D);
return Info; return Info;
} }
} // end namespace clang
} // namespace clang
#endif // LLVM_CLANG_SEMA_OVERLOAD_H #endif // LLVM_CLANG_SEMA_OVERLOAD_H

View File

@ -1,4 +1,4 @@
//===--- DelayedDiagnostic.cpp - Delayed declarator diagnostics -*- C++ -*-===// //===- DelayedDiagnostic.cpp - Delayed declarator diagnostics -------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -14,8 +14,10 @@
// This file also defines AccessedEntity. // This file also defines AccessedEntity.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/DelayedDiagnostic.h"
#include <string.h> #include <cstring>
using namespace clang; using namespace clang;
using namespace sema; using namespace sema;
@ -37,7 +39,7 @@ DelayedDiagnostic::makeAvailability(AvailabilityResult AR,
DD.AvailabilityData.UnknownObjCClass = UnknownObjCClass; DD.AvailabilityData.UnknownObjCClass = UnknownObjCClass;
DD.AvailabilityData.ObjCProperty = ObjCProperty; DD.AvailabilityData.ObjCProperty = ObjCProperty;
char *MessageData = nullptr; char *MessageData = nullptr;
if (Msg.size()) { if (!Msg.empty()) {
MessageData = new char [Msg.size()]; MessageData = new char [Msg.size()];
memcpy(MessageData, Msg.data(), Msg.size()); memcpy(MessageData, Msg.data(), Msg.size());
} }

View File

@ -1,4 +1,4 @@
//===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===// //===- IdentifierResolver.cpp - Lexical Scope Name lookup -----------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -14,10 +14,16 @@
#include "clang/Sema/IdentifierResolver.h" #include "clang/Sema/IdentifierResolver.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h" #include "clang/Basic/LangOptions.h"
#include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/Preprocessor.h" #include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Scope.h" #include "clang/Sema/Scope.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
using namespace clang; using namespace clang;
@ -35,17 +41,17 @@ class IdentifierResolver::IdDeclInfoMap {
/// impossible to add something to a pre-C++0x STL container without /// impossible to add something to a pre-C++0x STL container without
/// a completely unnecessary copy. /// a completely unnecessary copy.
struct IdDeclInfoPool { struct IdDeclInfoPool {
IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
IdDeclInfoPool *Next; IdDeclInfoPool *Next;
IdDeclInfo Pool[POOL_SIZE]; IdDeclInfo Pool[POOL_SIZE];
IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
}; };
IdDeclInfoPool *CurPool; IdDeclInfoPool *CurPool = nullptr;
unsigned int CurIndex; unsigned int CurIndex = POOL_SIZE;
public: public:
IdDeclInfoMap() : CurPool(nullptr), CurIndex(POOL_SIZE) {} IdDeclInfoMap() = default;
~IdDeclInfoMap() { ~IdDeclInfoMap() {
IdDeclInfoPool *Cur = CurPool; IdDeclInfoPool *Cur = CurPool;
@ -60,7 +66,6 @@ public:
IdDeclInfo &operator[](DeclarationName Name); IdDeclInfo &operator[](DeclarationName Name);
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// IdDeclInfo Implementation // IdDeclInfo Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -83,9 +88,7 @@ void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
IdentifierResolver::IdentifierResolver(Preprocessor &PP) IdentifierResolver::IdentifierResolver(Preprocessor &PP)
: LangOpt(PP.getLangOpts()), PP(PP), : LangOpt(PP.getLangOpts()), PP(PP), IdDeclInfos(new IdDeclInfoMap) {}
IdDeclInfos(new IdDeclInfoMap) {
}
IdentifierResolver::~IdentifierResolver() { IdentifierResolver::~IdentifierResolver() {
delete IdDeclInfos; delete IdDeclInfos;
@ -245,12 +248,14 @@ IdentifierResolver::begin(DeclarationName Name) {
} }
namespace { namespace {
enum DeclMatchKind {
DMK_Different, enum DeclMatchKind {
DMK_Replace, DMK_Different,
DMK_Ignore DMK_Replace,
}; DMK_Ignore
} };
} // namespace
/// \brief Compare two declarations to see whether they are different or, /// \brief Compare two declarations to see whether they are different or,
/// if they are the same, whether the new declaration should replace the /// if they are the same, whether the new declaration should replace the