-//===--- Scope.h - Scope interface ------------------------------*- C++ -*-===//
+//===- Scope.h - Scope interface --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#ifndef LLVM_CLANG_SEMA_SCOPE_H
#define LLVM_CLANG_SEMA_SCOPE_H
-#include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include <cassert>
namespace llvm {
class raw_ostream;
-}
+} // namespace llvm
namespace clang {
class Decl;
+class DeclContext;
class UsingDirectiveDecl;
class VarDecl;
/// Scope - A scope is a transient data structure that is used while parsing the
/// program. It assists with resolving identifiers to the appropriate
/// declaration.
-///
class Scope {
public:
/// ScopeFlags - These are bitfields that are or'd together when creating a
/// We are between inheritance colon and the real class/struct definition scope.
ClassInheritanceScope = 0x800000,
};
+
private:
/// The parent scope for this scope. This is null for the translation-unit
/// scope.
/// popped, these declarations are removed from the IdentifierTable's notion
/// of current declaration. It is up to the current Action implementation to
/// implement these semantics.
- typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy;
+ using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
DeclSetTy DeclsInScope;
/// The DeclContext with which this scope is associated. For
/// entity of a function scope is a function, etc.
DeclContext *Entity;
- typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
+ using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
UsingDirectivesTy UsingDirectives;
/// \brief Used to determine if errors occurred in this scope.
public:
Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
- : ErrorTrap(Diag) {
+ : ErrorTrap(Diag) {
Init(Parent, ScopeFlags);
}
/// getFlags - Return the flags for this scope.
- ///
unsigned getFlags() const { return Flags; }
+
void setFlags(unsigned F) { setFlags(getParent(), F); }
/// isBlockScope - Return true if this scope correspond to a closure.
bool isBlockScope() const { return Flags & BlockScope; }
/// getParent - Return the scope that this is nested in.
- ///
const Scope *getParent() const { return AnyParent; }
Scope *getParent() { return AnyParent; }
/// getFnParent - Return the closest scope that is a function body.
- ///
const Scope *getFnParent() const { return FnParent; }
Scope *getFnParent() { return FnParent; }
return PrototypeIndex++;
}
- typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
+ using decl_range = llvm::iterator_range<DeclSetTy::iterator>;
+
decl_range decls() const {
return decl_range(DeclsInScope.begin(), DeclsInScope.end());
}
+
bool decl_empty() const { return DeclsInScope.empty(); }
void AddDecl(Decl *D) {
return false;
}
-
/// isTemplateParamScope - Return true if this scope is a C++
/// template parameter scope.
bool isTemplateParamScope() const {
UsingDirectives.push_back(UDir);
}
- typedef llvm::iterator_range<UsingDirectivesTy::iterator>
- using_directives_range;
+ using using_directives_range =
+ llvm::iterator_range<UsingDirectivesTy::iterator>;
using_directives_range using_directives() {
return using_directives_range(UsingDirectives.begin(),
}
void setNoNRVO() {
- NRVO.setInt(1);
+ NRVO.setInt(true);
NRVO.setPointer(nullptr);
}
void mergeNRVOIntoParent();
/// Init - This is used by the parser to implement scope caching.
- ///
void Init(Scope *parent, unsigned flags);
/// \brief Sets up the specified scope flags and adjusts the scope state
/// variables accordingly.
- ///
void AddFlags(unsigned Flags);
void dumpImpl(raw_ostream &OS) const;
void dump() const;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_SCOPE_H
-//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
+//===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CapturedStmt.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/CleanupInfo.h"
-#include "clang/Sema/Ownership.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
+#include <cassert>
+#include <utility>
namespace clang {
-class Decl;
class BlockDecl;
class CapturedDecl;
class CXXMethodDecl;
-class FieldDecl;
-class ObjCPropertyDecl;
-class IdentifierInfo;
+class CXXRecordDecl;
class ImplicitParamDecl;
-class LabelDecl;
+class NamedDecl;
+class ObjCIvarRefExpr;
+class ObjCMessageExpr;
+class ObjCPropertyDecl;
+class ObjCPropertyRefExpr;
+class ParmVarDecl;
+class RecordDecl;
class ReturnStmt;
class Scope;
+class Stmt;
class SwitchStmt;
-class TemplateTypeParmDecl;
class TemplateParameterList;
+class TemplateTypeParmDecl;
class VarDecl;
-class ObjCIvarRefExpr;
-class ObjCPropertyRefExpr;
-class ObjCMessageExpr;
namespace sema {
/// parsed.
class CompoundScopeInfo {
public:
- CompoundScopeInfo(bool IsStmtExpr)
- : HasEmptyLoopBodies(false), IsStmtExpr(IsStmtExpr) { }
-
/// \brief Whether this compound stamement contains `for' or `while' loops
/// with empty bodies.
- bool HasEmptyLoopBodies;
+ bool HasEmptyLoopBodies = false;
/// \brief Whether this compound statement corresponds to a GNU statement
/// expression.
bool IsStmtExpr;
+ CompoundScopeInfo(bool IsStmtExpr) : IsStmtExpr(IsStmtExpr) {}
+
void setHasEmptyLoopBodies() {
HasEmptyLoopBodies = true;
}
PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
const Stmt *stmt)
- : PD(PD), Loc(Loc), stmt(stmt) {}
+ : PD(PD), Loc(Loc), stmt(stmt) {}
};
/// \brief Retains information about a function, method, or block that is
public:
/// \brief What kind of scope we are describing.
- ///
ScopeKind Kind : 3;
/// \brief Whether this function contains a VLA, \@try, try, C++
/// True when this is a method marked as a designated initializer.
bool ObjCIsDesignatedInit : 1;
+
/// This starts true for a method marked as designated initializer and will
/// be set to false if there is an invocation to a designated initializer of
/// the super class.
/// initializer within a class that has at least one initializer marked as a
/// designated initializer.
bool ObjCIsSecondaryInit : 1;
+
/// This starts true for a secondary initializer method and will be set to
/// false if there is an invocation of an initializer on 'self'.
bool ObjCWarnForNoInitDelegation : 1;
/// \brief A list of parameters which have the nonnull attribute and are
/// modified in the function.
- llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams;
+ llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
public:
/// Represents a simple identification of a weak object.
/// identify the object in memory.
///
/// \sa isExactProfile()
- typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
+ using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>;
BaseInfoTy Base;
/// The "property" decl, as described in the class documentation.
///
/// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
/// case of "implicit" properties (regular methods accessed via dot syntax).
- const NamedDecl *Property;
+ const NamedDecl *Property = nullptr;
/// Used to find the proper base profile for a given base expression.
static BaseInfoTy getBaseInfo(const Expr *BaseE);
static inline WeakObjectProfileTy getEmptyKey() {
return WeakObjectProfileTy();
}
+
static inline WeakObjectProfileTy getTombstoneKey() {
return WeakObjectProfileTy::getSentinel();
}
static unsigned getHashValue(const WeakObjectProfileTy &Val) {
- typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
+ using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
+
return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
Val.Property));
}
/// Part of the implementation of -Wrepeated-use-of-weak.
class WeakUseTy {
llvm::PointerIntPair<const Expr *, 1, bool> Rep;
+
public:
WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
/// Used to collect uses of a particular weak object in a function body.
///
/// Part of the implementation of -Wrepeated-use-of-weak.
- typedef SmallVector<WeakUseTy, 4> WeakUseVector;
+ using WeakUseVector = SmallVector<WeakUseTy, 4>;
/// Used to collect all uses of weak objects in a function body.
///
/// Part of the implementation of -Wrepeated-use-of-weak.
- typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
- WeakObjectProfileTy::DenseMapInfo>
- WeakObjectUseMap;
+ using WeakObjectUseMap =
+ llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
+ WeakObjectProfileTy::DenseMapInfo>;
private:
/// Used to collect all uses of weak objects in this function body.
FunctionScopeInfo(const FunctionScopeInfo&) = default;
public:
+ FunctionScopeInfo(DiagnosticsEngine &Diag)
+ : Kind(SK_Function), HasBranchProtectedScope(false),
+ HasBranchIntoScope(false), HasIndirectGoto(false),
+ HasDroppedStmt(false), HasOMPDeclareReductionCombiner(false),
+ HasFallthroughStmt(false), HasPotentialAvailabilityViolations(false),
+ ObjCShouldCallSuper(false), ObjCIsDesignatedInit(false),
+ ObjCWarnForNoDesignatedInitChain(false), ObjCIsSecondaryInit(false),
+ ObjCWarnForNoInitDelegation(false), NeedsCoroutineSuspends(true),
+ ErrorTrap(Diag) {}
+
+ virtual ~FunctionScopeInfo();
+
/// Record that a weak object was accessed.
///
/// Part of the implementation of -Wrepeated-use-of-weak.
CoroutineSuspends.second = Final;
}
- FunctionScopeInfo(DiagnosticsEngine &Diag)
- : Kind(SK_Function),
- HasBranchProtectedScope(false),
- HasBranchIntoScope(false),
- HasIndirectGoto(false),
- HasDroppedStmt(false),
- HasOMPDeclareReductionCombiner(false),
- HasFallthroughStmt(false),
- HasPotentialAvailabilityViolations(false),
- ObjCShouldCallSuper(false),
- ObjCIsDesignatedInit(false),
- ObjCWarnForNoDesignatedInitChain(false),
- ObjCIsSecondaryInit(false),
- ObjCWarnForNoInitDelegation(false),
- NeedsCoroutineSuspends(true),
- ErrorTrap(Diag) { }
-
- virtual ~FunctionScopeInfo();
-
/// \brief Clear out the information in this function scope, making it
/// suitable for reuse.
void Clear();
IsNestedCapture = 0x1,
IsThisCaptured = 0x2
};
+
/// The variable being captured (if we are not capturing 'this') and whether
/// this is a nested capture, and whether we are capturing 'this'
llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
+
/// Expression to initialize a field of the given type, and the kind of
/// capture (if this is a capture and not an init-capture). The expression
/// is only required if we are capturing ByVal and the variable's type has
/// \brief Whether an explicit capture has been odr-used in the body of the
/// lambda.
- bool ODRUsed;
+ bool ODRUsed = false;
/// \brief Whether an explicit capture has been non-odr-used in the body of
/// the lambda.
- bool NonODRUsed;
+ bool NonODRUsed = false;
public:
Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
InitExprAndCaptureKind(
Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
: Cap_ByCopy),
- Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType),
- ODRUsed(false), NonODRUsed(false) {}
+ Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
enum IsThisCapture { ThisCapture };
Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
: VarAndNestedAndThis(
nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
- Loc(Loc), EllipsisLoc(), CaptureType(CaptureType), ODRUsed(false),
- NonODRUsed(false) {}
+ Loc(Loc), CaptureType(CaptureType) {}
bool isThisCapture() const {
return VarAndNestedAndThis.getInt() & IsThisCaptured;
}
+
bool isVariableCapture() const {
return !isThisCapture() && !isVLATypeCapture();
}
+
bool isCopyCapture() const {
return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
}
+
bool isReferenceCapture() const {
return InitExprAndCaptureKind.getInt() == Cap_ByRef;
}
+
bool isBlockCapture() const {
return InitExprAndCaptureKind.getInt() == Cap_Block;
}
+
bool isVLATypeCapture() const {
return InitExprAndCaptureKind.getInt() == Cap_VLA;
}
+
bool isNested() const {
return VarAndNestedAndThis.getInt() & IsNestedCapture;
}
+
bool isODRUsed() const { return ODRUsed; }
bool isNonODRUsed() const { return NonODRUsed; }
void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
};
CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
- : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
- HasImplicitReturnType(false)
- {}
+ : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
/// CaptureMap - A map of captured variables to (index+1) into Captures.
llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
/// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
/// zero if 'this' is not captured.
- unsigned CXXThisCaptureIndex;
+ unsigned CXXThisCaptureIndex = 0;
/// Captures - The captures.
SmallVector<Capture, 4> Captures;
/// \brief - Whether the target type of return statements in this context
/// is deduced (e.g. a lambda or block with omitted return type).
- bool HasImplicitReturnType;
+ bool HasImplicitReturnType = false;
/// ReturnType - The target type of return statements in this context,
/// or null if unknown.
QualType FunctionType;
BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
- : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
- TheScope(BlockScope)
- {
+ : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
+ TheScope(BlockScope) {
Kind = SK_Block;
}
public:
/// \brief The CapturedDecl for this statement.
CapturedDecl *TheCapturedDecl;
+
/// \brief The captured record type.
RecordDecl *TheRecordDecl;
+
/// \brief This is the enclosing scope of the captured region.
Scope *TheScope;
+
/// \brief The implicit parameter for the captured variables.
ImplicitParamDecl *ContextParam;
+
/// \brief The kind of captured region.
unsigned short CapRegionKind;
+
unsigned short OpenMPLevel;
CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
RecordDecl *RD, ImplicitParamDecl *Context,
CapturedRegionKind K, unsigned OpenMPLevel)
- : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
- TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
- ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel)
- {
+ : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
+ TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
+ ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) {
Kind = SK_CapturedRegion;
}
class LambdaScopeInfo final : public CapturingScopeInfo {
public:
/// \brief The class that describes the lambda.
- CXXRecordDecl *Lambda;
+ CXXRecordDecl *Lambda = nullptr;
/// \brief The lambda's compiler-generated \c operator().
- CXXMethodDecl *CallOperator;
+ CXXMethodDecl *CallOperator = nullptr;
/// \brief Source range covering the lambda introducer [...].
SourceRange IntroducerRange;
/// \brief The number of captures in the \c Captures list that are
/// explicit captures.
- unsigned NumExplicitCaptures;
+ unsigned NumExplicitCaptures = 0;
/// \brief Whether this is a mutable lambda.
- bool Mutable;
+ bool Mutable = false;
/// \brief Whether the (empty) parameter list is explicit.
- bool ExplicitParams;
+ bool ExplicitParams = false;
/// \brief Whether any of the capture expressions requires cleanups.
CleanupInfo Cleanup;
/// \brief Whether the lambda contains an unexpanded parameter pack.
- bool ContainsUnexpandedParameterPack;
+ bool ContainsUnexpandedParameterPack = false;
/// \brief If this is a generic lambda, use this as the depth of
/// each 'auto' parameter, during initial AST construction.
- unsigned AutoTemplateParameterDepth;
+ unsigned AutoTemplateParameterDepth = 0;
/// \brief Store the list of the auto parameters for a generic lambda.
/// If this is a generic lambda, store the list of the auto
/// If this is a generic lambda, and the template parameter
/// list has been created (from the AutoTemplateParams) then
/// store a reference to it (cache it to avoid reconstructing it).
- TemplateParameterList *GLTemplateParameterList;
+ TemplateParameterList *GLTemplateParameterList = nullptr;
/// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs
/// or MemberExprs) that refer to local variables in a generic lambda
/// will truly be odr-used (i.e. need to be captured) by that nested lambda,
/// until its instantiation. But we still need to capture it in the
/// enclosing lambda if all intervening lambdas can capture the variable.
-
llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
/// \brief Contains all variable-referring-expressions that refer
SourceLocation PotentialThisCaptureLocation;
LambdaScopeInfo(DiagnosticsEngine &Diag)
- : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
- CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
- ExplicitParams(false), Cleanup{},
- ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0),
- GLTemplateParameterList(nullptr) {
+ : CapturingScopeInfo(Diag, ImpCap_None) {
Kind = SK_Lambda;
}
return !AutoTemplateParams.empty() || GLTemplateParameterList;
}
- ///
/// \brief Add a variable that might potentially be captured by the
/// lambda and therefore the enclosing lambdas.
///
void addPotentialThisCapture(SourceLocation Loc) {
PotentialThisCaptureLocation = Loc;
}
+
bool hasPotentialThisCapture() const {
return PotentialThisCaptureLocation.isValid();
}
/// seemingly harmless change elsewhere in Sema could cause us to start or stop
/// building such a node. So we need a rule that anyone can implement and get
/// exactly the same result".
- ///
void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
assert(isa<DeclRefExpr>(CapturingVarExpr)
|| isa<MemberExpr>(CapturingVarExpr));
};
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
- : Base(nullptr, false), Property(nullptr) {}
+ : Base(nullptr, false) {}
FunctionScopeInfo::WeakObjectProfileTy
FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
CXXThisCaptureIndex = Captures.size();
}
-} // end namespace sema
-} // end namespace clang
+} // namespace sema
+
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_SCOPEINFO_H
-//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
+//===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
+//===----------------------------------------------------------------------===//
//
-// This file provides types used in the semantic analysis of C++ templates.
+// This file provides types used in the semantic analysis of C++ templates.
//
-//===----------------------------------------------------------------------===/
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
#define LLVM_CLANG_SEMA_TEMPLATE_H
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Sema/Sema.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <utility>
namespace clang {
+
+class ASTContext;
+class BindingDecl;
+class CXXMethodDecl;
+class Decl;
+class DeclaratorDecl;
+class DeclContext;
+class EnumDecl;
+class FunctionDecl;
+class NamedDecl;
+class ParmVarDecl;
+class TagDecl;
+class TypedefNameDecl;
+class TypeSourceInfo;
+class VarDecl;
+
/// \brief Data structure that captures multiple levels of template argument
/// lists for use in template instantiation.
///
/// template argument list (17) at depth 1.
class MultiLevelTemplateArgumentList {
/// \brief The template argument list at a certain template depth
- typedef ArrayRef<TemplateArgument> ArgList;
+ using ArgList = ArrayRef<TemplateArgument>;
/// \brief The template argument lists, stored from the innermost template
/// argument list (first) to the outermost template argument list (last).
public:
/// \brief Construct an empty set of template argument lists.
- MultiLevelTemplateArgumentList() { }
+ MultiLevelTemplateArgumentList() = default;
/// \brief Construct a single-level template argument list.
explicit
}
/// \brief Retrieve the innermost template argument list.
- const ArgList &getInnermost() const {
+ const ArgList &getInnermost() const {
return TemplateArgumentLists.front();
}
};
enum TPOC {
/// \brief Partial ordering of function templates for a function call.
TPOC_Call,
+
/// \brief Partial ordering of function templates for a call to a
/// conversion function.
TPOC_Conversion,
+
/// \brief Partial ordering of function templates in other contexts, e.g.,
/// taking the address of a function template or matching a function
/// template specialization to a function template.
// making Sema.h declare things as enums).
class TemplatePartialOrderingContext {
TPOC Value;
+
public:
TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
+
operator TPOC() const { return Value; }
};
class DeducedTemplateArgument : public TemplateArgument {
/// \brief For a non-type template argument, whether the value was
/// deduced from an array bound.
- bool DeducedFromArrayBound;
+ bool DeducedFromArrayBound = false;
public:
- DeducedTemplateArgument()
- : TemplateArgument(), DeducedFromArrayBound(false) { }
+ DeducedTemplateArgument() = default;
DeducedTemplateArgument(const TemplateArgument &Arg,
bool DeducedFromArrayBound = false)
- : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
+ : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
/// \brief Construct an integral non-type template argument that
/// has been deduced, possibly from an array bound.
const llvm::APSInt &Value,
QualType ValueType,
bool DeducedFromArrayBound)
- : TemplateArgument(Ctx, Value, ValueType),
- DeducedFromArrayBound(DeducedFromArrayBound) { }
+ : TemplateArgument(Ctx, Value, ValueType),
+ DeducedFromArrayBound(DeducedFromArrayBound) {}
/// \brief For a non-type template argument, determine whether the
/// template argument was deduced from an array bound.
class LocalInstantiationScope {
public:
/// \brief A set of declarations.
- typedef SmallVector<ParmVarDecl *, 4> DeclArgumentPack;
+ using DeclArgumentPack = SmallVector<ParmVarDecl *, 4>;
private:
/// \brief Reference to the semantic analysis that is performing
/// this template instantiation.
Sema &SemaRef;
- typedef llvm::SmallDenseMap<
- const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
- LocalDeclsMap;
+ using LocalDeclsMap =
+ llvm::SmallDenseMap<const Decl *,
+ llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
/// \brief A mapping from local declarations that occur
/// within a template to their instantiations.
LocalInstantiationScope *Outer;
/// \brief Whether we have already exited this scope.
- bool Exited;
+ bool Exited = false;
/// \brief Whether to combine this scope with the outer scope, such that
/// lookup will search our outer scope.
/// \brief If non-NULL, the template parameter pack that has been
/// partially substituted per C++0x [temp.arg.explicit]p9.
- NamedDecl *PartiallySubstitutedPack;
+ NamedDecl *PartiallySubstitutedPack = nullptr;
/// \brief If \c PartiallySubstitutedPack is non-null, the set of
/// explicitly-specified template arguments in that pack.
/// ArgsInPartiallySubstitutedPack.
unsigned NumArgsInPartiallySubstitutedPack;
- // This class is non-copyable
- LocalInstantiationScope(
- const LocalInstantiationScope &) = delete;
- void operator=(const LocalInstantiationScope &) = delete;
-
public:
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
- : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
- Exited(false), CombineWithOuterScope(CombineWithOuterScope),
- PartiallySubstitutedPack(nullptr)
- {
+ : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
+ CombineWithOuterScope(CombineWithOuterScope) {
SemaRef.CurrentInstantiationScope = this;
}
+ LocalInstantiationScope(const LocalInstantiationScope &) = delete;
+ LocalInstantiationScope &
+ operator=(const LocalInstantiationScope &) = delete;
+
~LocalInstantiationScope() {
Exit();
}
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
DeclContext *Owner;
const MultiLevelTemplateArgumentList &TemplateArgs;
- Sema::LateInstantiatedAttrVec* LateAttrs;
- LocalInstantiationScope *StartingScope;
+ Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
+ LocalInstantiationScope *StartingScope = nullptr;
/// \brief A list of out-of-line class template partial
/// specializations that will need to be instantiated after the
public:
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs)
- : SemaRef(SemaRef),
- SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
- Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
- StartingScope(nullptr) {}
+ : SemaRef(SemaRef),
+ SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
+ Owner(Owner), TemplateArgs(TemplateArgs) {}
// Define all the decl visitors using DeclNodes.inc
#define DECL(DERIVED, BASE) \
LocalInstantiationScope *getStartingScope() const { return StartingScope; }
- typedef
- SmallVectorImpl<std::pair<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *> >
- ::iterator
- delayed_partial_spec_iterator;
+ using delayed_partial_spec_iterator = SmallVectorImpl<std::pair<
+ ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator;
- typedef SmallVectorImpl<std::pair<
- VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
- delayed_var_partial_spec_iterator;
+ using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair<
+ VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator;
/// \brief Return an iterator to the beginning of the set of
/// "delayed" partial specializations, which must be passed to
Decl *instantiateUnresolvedUsingDecl(T *D,
bool InstantiatingPackElement = false);
};
-}
+
+} // namespace clang
#endif // LLVM_CLANG_SEMA_TEMPLATE_H
-//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/
+//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
//
-// This file provides types used with Sema's template argument deduction
+//===----------------------------------------------------------------------===//
+//
+// This file provides types used with Sema's template argument deduction
// routines.
//
-//===----------------------------------------------------------------------===/
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
+#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <cstddef>
+#include <utility>
namespace clang {
+class Decl;
struct DeducedPack;
-class TemplateArgumentList;
class Sema;
namespace sema {
/// TemplateDeductionResult value.
class TemplateDeductionInfo {
/// \brief The deduced template argument list.
- ///
- TemplateArgumentList *Deduced;
+ TemplateArgumentList *Deduced = nullptr;
/// \brief The source location at which template argument
/// deduction is occurring.
SourceLocation Loc;
/// \brief Have we suppressed an error during deduction?
- bool HasSFINAEDiagnostic;
+ bool HasSFINAEDiagnostic = false;
/// \brief The template parameter depth for which we're performing deduction.
unsigned DeducedDepth;
/// SFINAE while performing template argument deduction.
SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
- TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
- void operator=(const TemplateDeductionInfo &) = delete;
-
public:
TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
- : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
- DeducedDepth(DeducedDepth), CallArgIndex(0) {}
+ : Loc(Loc), DeducedDepth(DeducedDepth) {}
+ TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
+ TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
/// \brief Returns the location at which template argument is
/// occurring.
}
/// \brief Iterator over the set of suppressed diagnostics.
- typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
- diag_iterator;
+ using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator;
/// \brief Returns an iterator at the beginning of the sequence of suppressed
/// diagnostics.
///
/// TDK_DeducedMismatch: this is the index of the argument that had a
/// different argument type from its substituted parameter type.
- unsigned CallArgIndex;
+ unsigned CallArgIndex = 0;
/// \brief Information on packs that we're currently expanding.
///
SmallVector<DeducedPack *, 8> PendingDeducedPacks;
};
-} // end namespace sema
+} // namespace sema
/// A structure used to record information about a failed
/// template argument deduction, for diagnosis.
class TemplateSpecCandidateSet {
SmallVector<TemplateSpecCandidate, 16> Candidates;
SourceLocation Loc;
+
// Stores whether we're taking the address of these candidates. This helps us
// produce better error messages when dealing with the pass_object_size
// attribute on parameters.
bool ForTakingAddress;
- TemplateSpecCandidateSet(
- const TemplateSpecCandidateSet &) = delete;
- void operator=(const TemplateSpecCandidateSet &) = delete;
-
void destroyCandidates();
public:
TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
: Loc(Loc), ForTakingAddress(ForTakingAddress) {}
+ TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
+ TemplateSpecCandidateSet &
+ operator=(const TemplateSpecCandidateSet &) = delete;
~TemplateSpecCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; }
/// TODO: This may be unnecessary.
void clear();
- typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
+ using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator;
+
iterator begin() { return Candidates.begin(); }
iterator end() { return Candidates.end(); }
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
-//===--- TypoCorrection.h - Class for typo correction results ---*- C++ -*-===//
+//===- TypoCorrection.h - Class for typo correction results -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H
#define LLVM_CLANG_SEMA_TYPOCORRECTION_H
-#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include <cstddef>
+#include <limits>
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
+class DeclContext;
+class IdentifierInfo;
+class LangOptions;
+class MemberExpr;
+class NestedNameSpecifier;
+class Sema;
+
/// @brief Simple class containing the result of Sema::CorrectTypo
class TypoCorrection {
public:
// "Distance" for unusable corrections
- static const unsigned InvalidDistance = ~0U;
+ static const unsigned InvalidDistance = std::numeric_limits<unsigned>::max();
+
// The largest distance still considered valid (larger edit distances are
// mapped to InvalidDistance by getEditDistance).
static const unsigned MaximumDistance = 10000U;
NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
unsigned QualifierDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(QualifierDistance),
- CallbackDistance(0), ForceSpecifierReplacement(false),
- RequiresImport(false) {
+ CharDistance(CharDistance), QualifierDistance(QualifierDistance) {
if (NameDecl)
CorrectionDecls.push_back(NameDecl);
}
TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
unsigned CharDistance = 0)
: CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
- ForceSpecifierReplacement(false), RequiresImport(false) {
+ CharDistance(CharDistance) {
if (Name)
CorrectionDecls.push_back(Name);
}
TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
unsigned CharDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
- ForceSpecifierReplacement(false), RequiresImport(false) {}
+ CharDistance(CharDistance) {}
- TypoCorrection()
- : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0),
- CallbackDistance(0), ForceSpecifierReplacement(false),
- RequiresImport(false) {}
+ TypoCorrection() = default;
/// \brief Gets the DeclarationName of the typo correction
DeclarationName getCorrection() const { return CorrectionName; }
+
IdentifierInfo *getCorrectionAsIdentifierInfo() const {
return CorrectionName.getAsIdentifierInfo();
}
NestedNameSpecifier *getCorrectionSpecifier() const {
return CorrectionNameSpec;
}
+
void setCorrectionSpecifier(NestedNameSpecifier *NNS) {
CorrectionNameSpec = NNS;
ForceSpecifierReplacement = (NNS != nullptr);
void addCorrectionDecl(NamedDecl *CDecl);
std::string getAsString(const LangOptions &LO) const;
+
std::string getQuoted(const LangOptions &LO) const {
return "'" + getAsString(LO) + "'";
}
return CorrectionRange;
}
- typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator;
+ using decl_iterator = SmallVectorImpl<NamedDecl *>::iterator;
+
decl_iterator begin() {
return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
}
+
decl_iterator end() { return CorrectionDecls.end(); }
- typedef SmallVectorImpl<NamedDecl *>::const_iterator const_decl_iterator;
+
+ using const_decl_iterator = SmallVectorImpl<NamedDecl *>::const_iterator;
+
const_decl_iterator begin() const {
return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
}
+
const_decl_iterator end() const { return CorrectionDecls.end(); }
/// \brief Returns whether this typo correction is correcting to a
// Results.
DeclarationName CorrectionName;
- NestedNameSpecifier *CorrectionNameSpec;
+ NestedNameSpecifier *CorrectionNameSpec = nullptr;
SmallVector<NamedDecl *, 1> CorrectionDecls;
- unsigned CharDistance;
- unsigned QualifierDistance;
- unsigned CallbackDistance;
+ unsigned CharDistance = 0;
+ unsigned QualifierDistance = 0;
+ unsigned CallbackDistance = 0;
SourceRange CorrectionRange;
- bool ForceSpecifierReplacement;
- bool RequiresImport;
+ bool ForceSpecifierReplacement = false;
+ bool RequiresImport = false;
std::vector<PartialDiagnostic> ExtraDiagnostics;
};
explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr,
NestedNameSpecifier *TypoNNS = nullptr)
- : WantTypeSpecifiers(true), WantExpressionKeywords(true),
- WantCXXNamedCasts(true), WantFunctionLikeCasts(true),
- WantRemainingKeywords(true), WantObjCSuper(false),
- IsObjCIvarLookup(false), IsAddressOfOperand(false), Typo(Typo),
- TypoNNS(TypoNNS) {}
+ : Typo(Typo), TypoNNS(TypoNNS) {}
- virtual ~CorrectionCandidateCallback() {}
+ virtual ~CorrectionCandidateCallback() = default;
/// \brief Simple predicate used by the default RankCandidate to
/// determine whether to return an edit distance of 0 or InvalidDistance.
// Flags for context-dependent keywords. WantFunctionLikeCasts is only
// used/meaningful when WantCXXNamedCasts is false.
// TODO: Expand these to apply to non-keywords or possibly remove them.
- bool WantTypeSpecifiers;
- bool WantExpressionKeywords;
- bool WantCXXNamedCasts;
- bool WantFunctionLikeCasts;
- bool WantRemainingKeywords;
- bool WantObjCSuper;
+ bool WantTypeSpecifiers = true;
+ bool WantExpressionKeywords = true;
+ bool WantCXXNamedCasts = true;
+ bool WantFunctionLikeCasts = true;
+ bool WantRemainingKeywords = true;
+ bool WantObjCSuper = false;
// Temporary hack for the one case where a CorrectTypoContext enum is used
// when looking up results.
- bool IsObjCIvarLookup;
- bool IsAddressOfOperand;
+ bool IsObjCIvarLookup = false;
+ bool IsAddressOfOperand = false;
protected:
bool MatchesTypo(const TypoCorrection &candidate) {
bool ValidateCandidate(const TypoCorrection &candidate) override;
- private:
+private:
unsigned NumArgs;
bool HasExplicitTemplateArgs;
DeclContext *CurContext;
}
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_TYPOCORRECTION_H
#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OpenCLOptions.h"
class ASTDeserializationListener;
class ASTReader;
class ASTRecordReader;
-class CXXBaseSpecifier;
-class CXXConstructorDecl;
-class CXXCtorInitializer;
class CXXTemporary;
class Decl;
class DeclaratorDecl;
class MemoryBufferCache;
class NamedDecl;
class NamespaceDecl;
-class NestedNameSpecifier;
class ObjCCategoryDecl;
class ObjCInterfaceDecl;
class PCHContainerReader;
public:
PCHValidator(Preprocessor &PP, ASTReader &Reader)
- : PP(PP), Reader(Reader) {}
+ : PP(PP), Reader(Reader) {}
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
bool AllowCompatibleDifferences) override;
Preprocessor &PP;
public:
- SimpleASTReaderListener(Preprocessor &PP)
- : PP(PP) {}
+ SimpleASTReaderListener(Preprocessor &PP) : PP(PP) {}
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
std::string &SuggestedPredefines) override;
FileDeclsInfo() = default;
FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
- : Mod(Mod), Decls(Decls) {}
+ : Mod(Mod), Decls(Decls) {}
};
/// \brief Map from a FileID to the file-level declarations that it contains.
/// added to the global preprocessing entity ID to produce a local ID.
GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap;
- typedef ContinuousRangeMap<unsigned, ModuleFile *, 4>
- GlobalSkippedRangeMapType;
+ using GlobalSkippedRangeMapType =
+ ContinuousRangeMap<unsigned, ModuleFile *, 4>;
/// \brief Mapping from global skipped range base IDs to the module in which
/// the skipped ranges reside.
SourceLocation ImportLoc;
ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc)
- : ID(ID), ImportLoc(ImportLoc) {}
+ : ID(ID), ImportLoc(ImportLoc) {}
};
private:
public:
ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader)
- : Reader(reader), PrevKind(Reader.ReadingKind) {
+ : Reader(reader), PrevKind(Reader.ReadingKind) {
Reader.ReadingKind = newKind;
}
public:
ProcessingUpdatesRAIIObj(ASTReader &reader)
- : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) {
+ : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) {
Reader.ProcessingUpdateRecords = true;
}
ImportedModule(ModuleFile *Mod,
ModuleFile *ImportedBy,
SourceLocation ImportLoc)
- : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {}
+ : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {}
};
ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
ModuleFile *F;
uint64_t Offset;
- RecordLocation(ModuleFile *M, uint64_t O)
- : F(M), Offset(O) {}
+ RecordLocation(ModuleFile *M, uint64_t O) : F(M), Offset(O) {}
};
QualType readTypeRecord(unsigned Index);
/// was read from the given AST file.
QualType readType(ModuleFile &F, const RecordData &Record, unsigned &Idx) {
if (Idx >= Record.size())
- return QualType();
+ return {};
return getLocalType(F, Record[Idx++]);
}
/// then restores it when destroyed.
struct SavedStreamPosition {
explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
- : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
+ : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
~SavedStreamPosition() {
Cursor.JumpToBit(Offset);
-//===------- SemaTemplateDeduction.cpp - Template Argument Deduction ------===/
+//===- SemaTemplateDeduction.cpp - Template Argument Deduction ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
//
-// This file implements C++ template argument deduction.
+//===----------------------------------------------------------------------===//
//
-//===----------------------------------------------------------------------===/
+// This file implements C++ template argument deduction.
+//
+//===----------------------------------------------------------------------===//
#include "clang/Sema/TemplateDeduction.h"
#include "TreeTransform.h"
+#include "TypeLocBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
-#include "clang/AST/DeclObjC.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/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TypeOrdering.h"
-#include "clang/Sema/DeclSpec.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Sema/Ownership.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
+#include <cassert>
+#include <tuple>
+#include <utility>
namespace clang {
- using namespace sema;
+
/// \brief Various flags that control template argument deduction.
///
/// These flags can be bitwise-OR'd together.
/// strictest results for template argument deduction (as used for, e.g.,
/// matching class template partial specializations).
TDF_None = 0,
+
/// \brief Within template argument deduction from a function call, we are
/// matching with a parameter type for which the original parameter was
/// a reference.
TDF_ParamWithReferenceType = 0x1,
+
/// \brief Within template argument deduction from a function call, we
/// are matching in a case where we ignore cv-qualifiers.
TDF_IgnoreQualifiers = 0x02,
+
/// \brief Within template argument deduction from a function call,
/// we are matching in a case where we can perform template argument
/// deduction from a template-id of a derived class of the argument type.
TDF_DerivedClass = 0x04,
+
/// \brief Allow non-dependent types to differ, e.g., when performing
/// template argument deduction from a function call where conversions
/// may apply.
TDF_SkipNonDependent = 0x08,
+
/// \brief Whether we are performing template argument deduction for
/// parameters and arguments in a top-level template argument
TDF_TopLevelParameterTypeList = 0x10,
+
/// \brief Within template argument deduction from overload resolution per
/// C++ [over.over] allow matching function types that are compatible in
/// terms of noreturn and default calling convention adjustments, or
}
using namespace clang;
+using namespace sema;
/// \brief Compare two APSInts, extending and switching the sign as
/// necessary to compare their values regardless of underlying type.
getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) {
// If we are within an alias template, the expression may have undergone
// any number of parameter substitutions already.
- while (1) {
+ while (true) {
if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E))
E = IC->getSubExpr();
else if (SubstNonTypeTemplateParmExpr *Subst =
// All other combinations are incompatible.
return DeducedTemplateArgument();
- case TemplateArgument::Pack:
+ case TemplateArgument::Pack: {
if (Y.getKind() != TemplateArgument::Pack ||
X.pack_size() != Y.pack_size())
return DeducedTemplateArgument();
TemplateArgument::CreatePackCopy(Context, NewPack),
X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());
}
+ }
llvm_unreachable("Invalid TemplateArgument Kind!");
}
/// A pack that we're currently deducing.
struct clang::DeducedPack {
- DeducedPack(unsigned Index) : Index(Index), Outer(nullptr) {}
-
// The index of the pack.
unsigned Index;
SmallVector<DeducedTemplateArgument, 4> New;
// The outer deduction for this pack, if any.
- DeducedPack *Outer;
+ DeducedPack *Outer = nullptr;
+
+ DeducedPack(unsigned Index) : Index(Index) {}
};
namespace {
+
/// A scope in which we're performing pack deduction.
class PackDeductionScope {
public:
SmallVector<DeducedPack, 2> Packs;
};
+
} // namespace
/// \brief Deduce the template arguments by comparing the list of parameter
case Type::Enum:
case Type::ObjCObject:
case Type::ObjCInterface:
- case Type::ObjCObjectPointer: {
+ case Type::ObjCObjectPointer:
if (TDF & TDF_SkipNonDependent)
return Sema::TDK_Success;
}
return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch;
- }
// _Complex T [placeholder extension]
case Type::Complex:
return Sema::TDK_Success;
}
- case Type::InjectedClassName: {
+ case Type::InjectedClassName:
// Treat a template's injected-class-name as if the template
// specialization type had been used.
Param = cast<InjectedClassNameType>(Param)
assert(isa<TemplateSpecializationType>(Param) &&
"injected class name is not a template specialization type");
LLVM_FALLTHROUGH;
- }
// template-name<T> (where template-name refers to a class template)
// template-name<i>
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Expression: {
+ case TemplateArgument::Expression:
if (NonTypeTemplateParmDecl *NTTP
= getDeducedParameterFromExpr(Info, Param.getAsExpr())) {
if (Arg.getKind() == TemplateArgument::Integral)
// Can't deduce anything, but that's okay.
return Sema::TDK_Success;
- }
+
case TemplateArgument::Pack:
llvm_unreachable("Argument packs should be expanded by the caller!");
}
llvm_unreachable("Invalid TemplateArgument Kind!");
}
-
/// \brief Convert the given deduced template argument and add it to the set of
/// fully-converted template arguments.
static bool
// We may need to deduce the return type of the function now.
if (S.getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/ false))
- return QualType();
+ return {};
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
if (Method->isInstance()) {
// An instance method that's referenced in a form that doesn't
// look like a member pointer is just invalid.
- if (!R.HasFormOfMemberPointer) return QualType();
+ if (!R.HasFormOfMemberPointer)
+ return {};
return S.Context.getMemberPointerType(Fn->getType(),
S.Context.getTypeDeclType(Method->getParent()).getTypePtr());
S.resolveAddressOfOnlyViableOverloadCandidate(Arg, DAP))
return GetTypeOfFunction(S, R, Viable);
- return QualType();
+ return {};
}
// Gather the explicit template arguments, if any.
// function templates, the parameter is treated as a
// non-deduced context.
if (!Ovl->hasExplicitTemplateArgs())
- return QualType();
+ return {};
// Otherwise, see if we can resolve a function type
FunctionDecl *Specialization = nullptr;
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
ArgType, Info, Deduced, TDF);
if (Result) continue;
- if (!Match.isNull()) return QualType();
+ if (!Match.isNull())
+ return {};
Match = ArgType;
}
}
namespace {
+
/// Substitute the 'auto' specifier or deduced template specialization type
/// specifier within a type for a given replacement type.
class SubstituteDeducedTypeTransform :
public TreeTransform<SubstituteDeducedTypeTransform> {
QualType Replacement;
bool UseTypeSugar;
+
public:
SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement,
bool UseTypeSugar = true)
return TransformType(TLB, TL);
}
};
-}
+
+} // namespace
Sema::DeduceAutoResult
Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result,
// Skip through any implicit casts we added while type-checking, and any
// substitutions performed by template alias expansion.
- while (1) {
+ while (true) {
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
E = ICE->getSubExpr();
else if (const SubstNonTypeTemplateParmExpr *Subst =