summaryrefslogtreecommitdiff
path: root/include/clang/AST/Decl.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r--include/clang/AST/Decl.h964
1 files changed, 566 insertions, 398 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 04a832e552a4a..dde94599636f0 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -76,14 +76,14 @@ class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
-/// \brief A container of type source information.
+/// A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
/// TL.getStartLoc().print(OS, SrcMgr);
/// @endcode
-class TypeSourceInfo {
+class alignas(8) TypeSourceInfo {
// Contains a memory block after the class, used for type source information,
// allocated by ASTContext.
friend class ASTContext;
@@ -93,17 +93,17 @@ class TypeSourceInfo {
TypeSourceInfo(QualType ty) : Ty(ty) {}
public:
- /// \brief Return the type wrapped by this type source info.
+ /// Return the type wrapped by this type source info.
QualType getType() const { return Ty; }
- /// \brief Return the TypeLoc wrapper for the type source info.
+ /// Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
- /// \brief Override the type stored in this TypeSourceInfo. Use with caution!
+ /// Override the type stored in this TypeSourceInfo. Use with caution!
void overrideType(QualType T) { Ty = T; }
};
-/// TranslationUnitDecl - The top declaration context.
+/// The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
@@ -134,7 +134,7 @@ public:
}
};
-/// \brief Represents a `#pragma comment` line. Always a child of
+/// Represents a `#pragma comment` line. Always a child of
/// TranslationUnitDecl.
class PragmaCommentDecl final
: public Decl,
@@ -168,7 +168,7 @@ public:
static bool classofKind(Kind K) { return K == PragmaComment; }
};
-/// \brief Represents a `#pragma detect_mismatch` line. Always a child of
+/// Represents a `#pragma detect_mismatch` line. Always a child of
/// TranslationUnitDecl.
class PragmaDetectMismatchDecl final
: public Decl,
@@ -201,7 +201,7 @@ public:
static bool classofKind(Kind K) { return K == PragmaDetectMismatch; }
};
-/// \brief Declaration context for names declared as extern "C" in C++. This
+/// Declaration context for names declared as extern "C" in C++. This
/// is neither the semantic nor lexical context for such declarations, but is
/// used to check for conflicts with other extern "C" declarations. Example:
///
@@ -240,10 +240,13 @@ public:
}
};
-/// NamedDecl - This represents a decl with a name. Many decls have names such
+/// This represents a decl that may have a name. Many decls have names such
/// as ObjCMethodDecl, but not \@class, etc.
+///
+/// Note that not every NamedDecl is actually named (e.g., a struct might
+/// be anonymous), and not every name is an identifier.
class NamedDecl : public Decl {
- /// Name - The name of this declaration, which is typically a normal
+ /// The name of this declaration, which is typically a normal
/// identifier but may also be a special kind of name (C++
/// constructor, Objective-C selector, etc.)
DeclarationName Name;
@@ -258,13 +261,15 @@ protected:
: Decl(DK, DC, L), Name(N) {}
public:
- /// getIdentifier - Get the identifier that names this declaration,
- /// if there is one. This will return NULL if this declaration has
- /// no name (e.g., for an unnamed class) or if the name is a special
- /// name (C++ constructor, Objective-C selector, etc.).
+ /// Get the identifier that names this declaration, if there is one.
+ ///
+ /// This will return NULL if this declaration has no name (e.g., for
+ /// an unnamed class) or if the name is a special name (C++ constructor,
+ /// Objective-C selector, etc.).
IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
- /// getName - Get the name of identifier for this declaration as a StringRef.
+ /// Get the name of identifier for this declaration as a StringRef.
+ ///
/// This requires that the declaration have a name and that it be a simple
/// identifier.
StringRef getName() const {
@@ -272,11 +277,12 @@ public:
return getIdentifier() ? getIdentifier()->getName() : "";
}
- /// getNameAsString - Get a human-readable name for the declaration, even if
- /// it is one of the special kinds of names (C++ constructor, Objective-C
- /// selector, etc). Creating this name requires expensive string
- /// manipulation, so it should be called only when performance doesn't matter.
- /// For simple declarations, getNameAsCString() should suffice.
+ /// Get a human-readable name for the declaration, even if it is one of the
+ /// special kinds of names (C++ constructor, Objective-C selector, etc).
+ ///
+ /// Creating this name requires expensive string manipulation, so it should
+ /// be called only when performance doesn't matter. For simple declarations,
+ /// getNameAsCString() should suffice.
//
// FIXME: This function should be renamed to indicate that it is not just an
// alternate form of getName(), and clients should move as appropriate.
@@ -286,17 +292,19 @@ public:
virtual void printName(raw_ostream &os) const;
- /// getDeclName - Get the actual, stored name of the declaration,
- /// which may be a special name.
+ /// Get the actual, stored name of the declaration, which may be a special
+ /// name.
DeclarationName getDeclName() const { return Name; }
- /// \brief Set the name of this declaration.
+ /// Set the name of this declaration.
void setDeclName(DeclarationName N) { Name = N; }
- /// printQualifiedName - Returns human-readable qualified name for
- /// declaration, like A::B::i, for i being member of namespace A::B.
- /// If declaration is not member of context which can be named (record,
- /// namespace), it will return same result as printName().
+ /// Returns a human-readable qualified name for this declaration, like
+ /// A::B::i, for i being member of namespace A::B.
+ ///
+ /// If the declaration is not a member of context which can be named (record,
+ /// namespace), it will return the same result as printName().
+ ///
/// Creating this name is expensive, so it should be called only when
/// performance doesn't matter.
void printQualifiedName(raw_ostream &OS) const;
@@ -315,25 +323,25 @@ public:
const PrintingPolicy &Policy,
bool Qualified) const;
- /// \brief Determine whether this declaration, if
- /// known to be well-formed within its context, will replace the
- /// declaration OldD if introduced into scope. A declaration will
- /// replace another declaration if, for example, it is a
- /// redeclaration of the same variable or function, but not if it is
- /// a declaration of a different kind (function vs. class) or an
- /// overloaded function.
+ /// Determine whether this declaration, if known to be well-formed within
+ /// its context, will replace the declaration OldD if introduced into scope.
+ ///
+ /// A declaration will replace another declaration if, for example, it is
+ /// a redeclaration of the same variable or function, but not if it is a
+ /// declaration of a different kind (function vs. class) or an overloaded
+ /// function.
///
/// \param IsKnownNewer \c true if this declaration is known to be newer
/// than \p OldD (for instance, if this declaration is newly-created).
bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
- /// \brief Determine whether this declaration has linkage.
+ /// Determine whether this declaration has linkage.
bool hasLinkage() const;
using Decl::isModulePrivate;
using Decl::setModulePrivate;
- /// \brief Determine whether this declaration is a C++ class member.
+ /// Determine whether this declaration is a C++ class member.
bool isCXXClassMember() const {
const DeclContext *DC = getDeclContext();
@@ -346,23 +354,24 @@ public:
return DC->isRecord();
}
- /// \brief Determine whether the given declaration is an instance member of
+ /// Determine whether the given declaration is an instance member of
/// a C++ class.
bool isCXXInstanceMember() const;
- /// \brief Determine what kind of linkage this entity has.
+ /// Determine what kind of linkage this entity has.
+ ///
/// This is not the linkage as defined by the standard or the codegen notion
/// of linkage. It is just an implementation detail that is used to compute
/// those.
Linkage getLinkageInternal() const;
- /// \brief Get the linkage from a semantic point of view. Entities in
+ /// Get the linkage from a semantic point of view. Entities in
/// anonymous namespaces are external (in c++98).
Linkage getFormalLinkage() const {
return clang::getFormalLinkage(getLinkageInternal());
}
- /// \brief True if this decl has external linkage.
+ /// True if this decl has external linkage.
bool hasExternalFormalLinkage() const {
return isExternalFormalLinkage(getLinkageInternal());
}
@@ -377,12 +386,12 @@ public:
return isExternallyVisible() && !getOwningModuleForLinkage();
}
- /// \brief Determines the visibility of this entity.
+ /// Determines the visibility of this entity.
Visibility getVisibility() const {
return getLinkageAndVisibility().getVisibility();
}
- /// \brief Determines the linkage and visibility of this entity.
+ /// Determines the linkage and visibility of this entity.
LinkageInfo getLinkageAndVisibility() const;
/// Kinds of explicit visibility.
@@ -398,16 +407,16 @@ public:
VisibilityForValue
};
- /// \brief If visibility was explicitly specified for this
+ /// If visibility was explicitly specified for this
/// declaration, return that visibility.
Optional<Visibility>
getExplicitVisibility(ExplicitVisibilityKind kind) const;
- /// \brief True if the computed linkage is valid. Used for consistency
+ /// True if the computed linkage is valid. Used for consistency
/// checking. Should always return true.
bool isLinkageValid() const;
- /// \brief True if something has required us to compute the linkage
+ /// True if something has required us to compute the linkage
/// of this declaration.
///
/// Language features which can retroactively change linkage (like a
@@ -417,7 +426,7 @@ public:
return hasCachedLinkage();
}
- /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
+ /// Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
// Fast-path the common case.
@@ -451,7 +460,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
return OS;
}
-/// LabelDecl - Represents the declaration of a label. Labels also have a
+/// Represents the declaration of a label. Labels also have a
/// corresponding LabelStmt, which indicates the position that the label was
/// defined at. For normal labels, the location of the decl is the same as the
/// location of the statement. For GNU local labels (__label__), the decl
@@ -461,7 +470,7 @@ class LabelDecl : public NamedDecl {
StringRef MSAsmName;
bool MSAsmNameResolved = false;
- /// LocStart - For normal labels, this is the same as the main declaration
+ /// For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
/// this is the location of the __label__ keyword.
SourceLocation LocStart;
@@ -501,18 +510,18 @@ public:
static bool classofKind(Kind K) { return K == Label; }
};
-/// NamespaceDecl - Represent a C++ namespace.
+/// Represent a C++ namespace.
class NamespaceDecl : public NamedDecl, public DeclContext,
public Redeclarable<NamespaceDecl>
{
- /// LocStart - The starting location of the source range, pointing
+ /// The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
- /// RBraceLoc - The ending location of the source range.
+ /// The ending location of the source range.
SourceLocation RBraceLoc;
- /// \brief A pointer to either the anonymous namespace that lives just inside
+ /// A pointer to either the anonymous namespace that lives just inside
/// this namespace or to the first namespace in the chain (the latter case
/// only when this is not the first in the chain), along with a
/// boolean value indicating whether this is an inline namespace.
@@ -549,7 +558,7 @@ public:
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
- /// \brief Returns true if this is an anonymous namespace declaration.
+ /// Returns true if this is an anonymous namespace declaration.
///
/// For example:
/// \code
@@ -562,28 +571,28 @@ public:
return !getIdentifier();
}
- /// \brief Returns true if this is an inline namespace declaration.
+ /// Returns true if this is an inline namespace declaration.
bool isInline() const {
return AnonOrFirstNamespaceAndInline.getInt();
}
- /// \brief Set whether this is an inline namespace declaration.
+ /// Set whether this is an inline namespace declaration.
void setInline(bool Inline) {
AnonOrFirstNamespaceAndInline.setInt(Inline);
}
- /// \brief Get the original (first) namespace declaration.
+ /// Get the original (first) namespace declaration.
NamespaceDecl *getOriginalNamespace();
- /// \brief Get the original (first) namespace declaration.
+ /// Get the original (first) namespace declaration.
const NamespaceDecl *getOriginalNamespace() const;
- /// \brief Return true if this declaration is an original (first) declaration
+ /// Return true if this declaration is an original (first) declaration
/// of the namespace. This is false for non-original (subsequent) namespace
/// declarations and anonymous namespaces.
bool isOriginalNamespace() const;
- /// \brief Retrieve the anonymous namespace nested inside this namespace,
+ /// Retrieve the anonymous namespace nested inside this namespace,
/// if any.
NamespaceDecl *getAnonymousNamespace() const {
return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
@@ -621,7 +630,7 @@ public:
}
};
-/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// Represent the declaration of a variable (in which case it is
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
class ValueDecl : public NamedDecl {
@@ -638,7 +647,7 @@ public:
QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; }
- /// \brief Determine whether this symbol is weakly-imported,
+ /// Determine whether this symbol is weakly-imported,
/// or declared with the weak or weak-ref attr.
bool isWeak() const;
@@ -647,18 +656,18 @@ public:
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
};
-/// QualifierInfo - A struct with extended info about a syntactic
+/// A struct with extended info about a syntactic
/// name qualifier, to be used for the case of out-of-line declarations.
struct QualifierInfo {
NestedNameSpecifierLoc QualifierLoc;
- /// NumTemplParamLists - The number of "outer" template parameter lists.
+ /// The number of "outer" template parameter lists.
/// The count includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
/// case of an explicit specialization) a final "template <>".
unsigned NumTemplParamLists = 0;
- /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
+ /// A new-allocated array of size NumTemplParamLists,
/// containing pointers to the "outer" template parameter lists.
/// It includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
@@ -669,13 +678,12 @@ struct QualifierInfo {
QualifierInfo(const QualifierInfo &) = delete;
QualifierInfo& operator=(const QualifierInfo &) = delete;
- /// setTemplateParameterListsInfo - Sets info about "outer" template
- /// parameter lists.
+ /// Sets info about "outer" template parameter lists.
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
};
-/// \brief Represents a ValueDecl that came out of a declarator.
+/// Represents a ValueDecl that came out of a declarator.
/// Contains type source information through TypeSourceInfo.
class DeclaratorDecl : public ValueDecl {
// A struct representing both a TInfo and a syntactic qualifier,
@@ -686,7 +694,7 @@ class DeclaratorDecl : public ValueDecl {
llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
- /// InnerLocStart - The start of the source range for this declaration,
+ /// The start of the source range for this declaration,
/// ignoring outer template declarations.
SourceLocation InnerLocStart;
@@ -717,13 +725,12 @@ public:
DeclInfo = TI;
}
- /// getInnerLocStart - Return SourceLocation representing start of source
- /// range ignoring outer template declarations.
+ /// Return start of source range ignoring outer template declarations.
SourceLocation getInnerLocStart() const { return InnerLocStart; }
void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
- /// getOuterLocStart - Return SourceLocation representing start of source
- /// range taking into account any outer template declarations.
+ /// Return start of source range taking into account any outer template
+ /// declarations.
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -732,14 +739,14 @@ public:
return getOuterLocStart();
}
- /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+ /// Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
: nullptr;
}
- /// \brief Retrieve the nested-name-specifier (with source-location
+ /// Retrieve the nested-name-specifier (with source-location
/// information) that qualifies the name of this declaration, if it was
/// present in the source.
NestedNameSpecifierLoc getQualifierLoc() const {
@@ -770,25 +777,25 @@ public:
}
};
-/// \brief Structure used to store a statement, the constant value to
+/// Structure used to store a statement, the constant value to
/// which it was evaluated (if any), and whether or not the statement
/// is an integral constant expression (if known).
struct EvaluatedStmt {
- /// \brief Whether this statement was already evaluated.
+ /// Whether this statement was already evaluated.
bool WasEvaluated : 1;
- /// \brief Whether this statement is being evaluated.
+ /// Whether this statement is being evaluated.
bool IsEvaluating : 1;
- /// \brief Whether we already checked whether this statement was an
+ /// Whether we already checked whether this statement was an
/// integral constant expression.
bool CheckedICE : 1;
- /// \brief Whether we are checking whether this statement is an
+ /// Whether we are checking whether this statement is an
/// integral constant expression.
bool CheckingICE : 1;
- /// \brief Whether this statement is an integral constant expression,
+ /// Whether this statement is an integral constant expression,
/// or in C++11, whether the statement is a constant expression. Only
/// valid if CheckedICE is true.
bool IsICE : 1;
@@ -801,11 +808,10 @@ struct EvaluatedStmt {
};
-/// VarDecl - An instance of this class is created to represent a variable
-/// declaration or definition.
+/// Represents a variable declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- /// \brief Initialization styles.
+ /// Initialization styles.
enum InitializationStyle {
/// C-style initialization with assignment
CInit,
@@ -817,7 +823,7 @@ public:
ListInit
};
- /// \brief Kinds of thread-local storage.
+ /// Kinds of thread-local storage.
enum TLSKind {
/// Not a TLS variable.
TLS_None,
@@ -829,8 +835,7 @@ public:
TLS_Dynamic
};
- /// getStorageClassSpecifierString - Return the string used to
- /// specify the storage class \p SC.
+ /// Return the string used to specify the storage class \p SC.
///
/// It is illegal to call this function with SC == None.
static const char *getStorageClassSpecifierString(StorageClass SC);
@@ -845,7 +850,7 @@ protected:
// allocated in trailing space when necessary.
using InitType = llvm::PointerUnion<Stmt *, EvaluatedStmt *>;
- /// \brief The initializer for this variable or, for a ParmVarDecl, the
+ /// The initializer for this variable or, for a ParmVarDecl, the
/// C++ default argument.
mutable InitType Init;
@@ -915,41 +920,44 @@ protected:
unsigned : NumVarDeclBits;
// FIXME: We need something similar to CXXRecordDecl::DefinitionData.
- /// \brief Whether this variable is a definition which was demoted due to
+ /// Whether this variable is a definition which was demoted due to
/// module merge.
unsigned IsThisDeclarationADemotedDefinition : 1;
- /// \brief Whether this variable is the exception variable in a C++ catch
+ /// Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
- /// \brief Whether this local variable could be allocated in the return
+ /// Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization
/// (NRVO).
unsigned NRVOVariable : 1;
- /// \brief Whether this variable is the for-range-declaration in a C++0x
+ /// Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
unsigned CXXForRangeDecl : 1;
- /// \brief Whether this variable is an ARC pseudo-__strong
+ /// Whether this variable is the for-in loop declaration in Objective-C.
+ unsigned ObjCForDecl : 1;
+
+ /// Whether this variable is an ARC pseudo-__strong
/// variable; see isARCPseudoStrong() for details.
unsigned ARCPseudoStrong : 1;
- /// \brief Whether this variable is (C++1z) inline.
+ /// Whether this variable is (C++1z) inline.
unsigned IsInline : 1;
- /// \brief Whether this variable has (C++1z) inline explicitly specified.
+ /// Whether this variable has (C++1z) inline explicitly specified.
unsigned IsInlineSpecified : 1;
- /// \brief Whether this variable is (C++0x) constexpr.
+ /// Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
- /// \brief Whether this variable is the implicit variable for a lambda
+ /// Whether this variable is the implicit variable for a lambda
/// init-capture.
unsigned IsInitCapture : 1;
- /// \brief Whether this local extern variable's previous declaration was
+ /// Whether this local extern variable's previous declaration was
/// declared in the same block scope. This controls whether we should merge
/// the type of this declaration with its previous declaration.
unsigned PreviousDeclInSameBlockScope : 1;
@@ -1004,7 +1012,7 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
- /// \brief Returns the storage class as written in the source. For the
+ /// Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const {
return (StorageClass) VarDeclBits.SClass;
@@ -1020,8 +1028,8 @@ public:
}
TLSKind getTLSKind() const;
- /// hasLocalStorage - Returns true if a variable with function scope
- /// is a non-static local variable.
+ /// Returns true if a variable with function scope is a non-static local
+ /// variable.
bool hasLocalStorage() const {
if (getStorageClass() == SC_None) {
// OpenCL v1.2 s6.5.3: The __constant or constant address space name is
@@ -1044,8 +1052,8 @@ public:
return getStorageClass() >= SC_Auto;
}
- /// isStaticLocal - Returns true if a variable with function scope is a
- /// static local variable.
+ /// Returns true if a variable with function scope is a static local
+ /// variable.
bool isStaticLocal() const {
return (getStorageClass() == SC_Static ||
// C++11 [dcl.stc]p4
@@ -1053,43 +1061,42 @@ public:
&& !isFileVarDecl();
}
- /// \brief Returns true if a variable has extern or __private_extern__
+ /// Returns true if a variable has extern or __private_extern__
/// storage.
bool hasExternalStorage() const {
return getStorageClass() == SC_Extern ||
getStorageClass() == SC_PrivateExtern;
}
- /// \brief Returns true for all variables that do not have local storage.
+ /// Returns true for all variables that do not have local storage.
///
/// This includes all global variables as well as static variables declared
/// within a function.
bool hasGlobalStorage() const { return !hasLocalStorage(); }
- /// \brief Get the storage duration of this variable, per C++ [basic.stc].
+ /// Get the storage duration of this variable, per C++ [basic.stc].
StorageDuration getStorageDuration() const {
return hasLocalStorage() ? SD_Automatic :
getTSCSpec() ? SD_Thread : SD_Static;
}
- /// \brief Compute the language linkage.
+ /// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
- /// \brief Determines whether this variable is a variable with
- /// external, C linkage.
+ /// Determines whether this variable is a variable with external, C linkage.
bool isExternC() const;
- /// \brief Determines whether this variable's context is, or is nested within,
+ /// Determines whether this variable's context is, or is nested within,
/// a C++ extern "C" linkage spec.
bool isInExternCContext() const;
- /// \brief Determines whether this variable's context is, or is nested within,
+ /// Determines whether this variable's context is, or is nested within,
/// a C++ extern "C++" linkage spec.
bool isInExternCXXContext() const;
- /// isLocalVarDecl - Returns true for local variable declarations
- /// other than parameters. Note that this includes static variables
- /// inside of functions. It also includes variables inside blocks.
+ /// Returns true for local variable declarations other than parameters.
+ /// Note that this includes static variables inside of functions. It also
+ /// includes variables inside blocks.
///
/// void foo() { int x; static int y; extern int z; }
bool isLocalVarDecl() const {
@@ -1100,13 +1107,12 @@ public:
return false;
}
- /// \brief Similar to isLocalVarDecl but also includes parameters.
+ /// Similar to isLocalVarDecl but also includes parameters.
bool isLocalVarDeclOrParm() const {
return isLocalVarDecl() || getKind() == Decl::ParmVar;
}
- /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
- /// excludes variables declared in blocks.
+ /// Similar to isLocalVarDecl, but excludes variables declared in blocks.
bool isFunctionOrMethodVarDecl() const {
if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
@@ -1114,7 +1120,7 @@ public:
return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
}
- /// \brief Determines whether this is a static data member.
+ /// Determines whether this is a static data member.
///
/// This will only be true in C++, and applies to, e.g., the
/// variable 'x' in:
@@ -1144,7 +1150,7 @@ public:
Definition
};
- /// \brief Check whether this declaration is a definition. If this could be
+ /// Check whether this declaration is a definition. If this could be
/// a tentative definition (in C), don't check whether there's an overriding
/// definition.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
@@ -1152,21 +1158,20 @@ public:
return isThisDeclarationADefinition(getASTContext());
}
- /// \brief Check whether this variable is defined in this
- /// translation unit.
+ /// Check whether this variable is defined in this translation unit.
DefinitionKind hasDefinition(ASTContext &) const;
DefinitionKind hasDefinition() const {
return hasDefinition(getASTContext());
}
- /// \brief Get the tentative definition that acts as the real definition in
- /// a TU. Returns null if there is a proper definition available.
+ /// Get the tentative definition that acts as the real definition in a TU.
+ /// Returns null if there is a proper definition available.
VarDecl *getActingDefinition();
const VarDecl *getActingDefinition() const {
return const_cast<VarDecl*>(this)->getActingDefinition();
}
- /// \brief Get the real (not just tentative) definition for this declaration.
+ /// Get the real (not just tentative) definition for this declaration.
VarDecl *getDefinition(ASTContext &);
const VarDecl *getDefinition(ASTContext &C) const {
return const_cast<VarDecl*>(this)->getDefinition(C);
@@ -1178,11 +1183,11 @@ public:
return const_cast<VarDecl*>(this)->getDefinition();
}
- /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
bool isOutOfLine() const override;
- /// isFileVarDecl - Returns true for file scoped variable declaration.
+ /// Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
Kind K = getKind();
if (K == ParmVar || K == ImplicitParam)
@@ -1197,14 +1202,14 @@ public:
return false;
}
- /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// Get the initializer for this variable, no matter which
/// declaration it is attached to.
const Expr *getAnyInitializer() const {
const VarDecl *D;
return getAnyInitializer(D);
}
- /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// Get the initializer for this variable, no matter which
/// declaration it is attached to. Also get that declaration.
const Expr *getAnyInitializer(const VarDecl *&D) const;
@@ -1214,12 +1219,12 @@ public:
}
Expr *getInit();
- /// \brief Retrieve the address of the initializer expression.
+ /// Retrieve the address of the initializer expression.
Stmt **getInitAddress();
void setInit(Expr *I);
- /// \brief Determine whether this variable's value can be used in a
+ /// Determine whether this variable's value can be used in a
/// constant expression, according to the relevant language standard.
/// This only checks properties of the declaration, and does not check
/// whether the initializer is in fact a constant expression.
@@ -1227,30 +1232,30 @@ public:
EvaluatedStmt *ensureEvaluatedStmt() const;
- /// \brief Attempt to evaluate the value of the initializer attached to this
+ /// Attempt to evaluate the value of the initializer attached to this
/// declaration, and produce notes explaining why it cannot be evaluated or is
/// not a constant expression. Returns a pointer to the value if evaluation
/// succeeded, 0 otherwise.
APValue *evaluateValue() const;
APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
- /// \brief Return the already-evaluated value of this variable's
+ /// Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
/// to untyped APValue if the value could not be evaluated.
APValue *getEvaluatedValue() const;
- /// \brief Determines whether it is already known whether the
+ /// Determines whether it is already known whether the
/// initializer is an integral constant expression or not.
bool isInitKnownICE() const;
- /// \brief Determines whether the initializer is an integral constant
+ /// Determines whether the initializer is an integral constant
/// expression, or in C++11, whether the initializer is a constant
/// expression.
///
/// \pre isInitKnownICE()
bool isInitICE() const;
- /// \brief Determine whether the value of the initializer attached to this
+ /// Determine whether the value of the initializer attached to this
/// declaration is an integral constant expression.
bool checkInitIsICE() const;
@@ -1258,7 +1263,7 @@ public:
VarDeclBits.InitStyle = Style;
}
- /// \brief The style of initialization for this declaration.
+ /// The style of initialization for this declaration.
///
/// C-style initialization is "int x = 1;". Call-style initialization is
/// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
@@ -1272,18 +1277,18 @@ public:
return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
}
- /// \brief Whether the initializer is a direct-initializer (list or call).
+ /// Whether the initializer is a direct-initializer (list or call).
bool isDirectInit() const {
return getInitStyle() != CInit;
}
- /// \brief If this definition should pretend to be a declaration.
+ /// If this definition should pretend to be a declaration.
bool isThisDeclarationADemotedDefinition() const {
return isa<ParmVarDecl>(this) ? false :
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition;
}
- /// \brief This is a definition which should be demoted to a declaration.
+ /// This is a definition which should be demoted to a declaration.
///
/// In some cases (mostly module merging) we can end up with two visible
/// definitions one of which needs to be demoted to a declaration to keep
@@ -1294,7 +1299,7 @@ public:
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
}
- /// \brief Determine whether this variable is the exception variable in a
+ /// Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C \@catch statement.
bool isExceptionVariable() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar;
@@ -1304,7 +1309,7 @@ public:
NonParmVarDeclBits.ExceptionVar = EV;
}
- /// \brief Determine whether this local variable can be used with the named
+ /// Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
///
/// The named return value optimization (NRVO) works by marking certain
@@ -1322,7 +1327,7 @@ public:
NonParmVarDeclBits.NRVOVariable = NRVO;
}
- /// \brief Determine whether this variable is the for-range-declaration in
+ /// Determine whether this variable is the for-range-declaration in
/// a C++0x for-range statement.
bool isCXXForRangeDecl() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl;
@@ -1332,7 +1337,17 @@ public:
NonParmVarDeclBits.CXXForRangeDecl = FRD;
}
- /// \brief Determine whether this variable is an ARC pseudo-__strong
+ /// Determine whether this variable is a for-loop declaration for a
+ /// for-in statement in Objective-C.
+ bool isObjCForDecl() const {
+ return NonParmVarDeclBits.ObjCForDecl;
+ }
+
+ void setObjCForDecl(bool FRD) {
+ NonParmVarDeclBits.ObjCForDecl = FRD;
+ }
+
+ /// Determine whether this variable is an ARC pseudo-__strong
/// variable. A pseudo-__strong variable has a __strong-qualified
/// type but does not actually retain the object written into it.
/// Generally such variables are also 'const' for safety.
@@ -1392,41 +1407,41 @@ public:
NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
}
- /// \brief Retrieve the variable declaration from which this variable could
+ /// Retrieve the variable declaration from which this variable could
/// be instantiated, if it is an instantiation (rather than a non-template).
VarDecl *getTemplateInstantiationPattern() const;
- /// \brief If this variable is an instantiated static data member of a
+ /// If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
VarDecl *getInstantiatedFromStaticDataMember() const;
- /// \brief If this variable is an instantiation of a variable template or a
+ /// If this variable is an instantiation of a variable template or a
/// static data member of a class template, determine what kind of
/// template specialization or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief If this variable is an instantiation of a variable template or a
+ /// If this variable is an instantiation of a variable template or a
/// static data member of a class template, determine its point of
/// instantiation.
SourceLocation getPointOfInstantiation() const;
- /// \brief If this variable is an instantiation of a static data member of a
+ /// If this variable is an instantiation of a static data member of a
/// class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const;
- /// \brief For a static data member that was instantiated from a static
+ /// For a static data member that was instantiated from a static
/// data member of a class template, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief Specify that this variable is an instantiation of the
+ /// Specify that this variable is an instantiation of the
/// static data member VD.
void setInstantiationOfStaticDataMember(VarDecl *VD,
TemplateSpecializationKind TSK);
- /// \brief Retrieves the variable template that is described by this
+ /// Retrieves the variable template that is described by this
/// variable declaration.
///
/// Every variable template is represented as a VarTemplateDecl and a
@@ -1441,6 +1456,11 @@ public:
void setDescribedVarTemplate(VarTemplateDecl *Template);
+ // Is this variable known to have a definition somewhere in the complete
+ // program? This may be true even if the declaration has internal linkage and
+ // has no definition within this source file.
+ bool isKnownToBeDefined() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
@@ -1509,7 +1529,7 @@ public:
static bool classofKind(Kind K) { return K == ImplicitParam; }
};
-/// ParmVarDecl - Represents a parameter to a function.
+/// Represents a parameter to a function.
class ParmVarDecl : public VarDecl {
public:
enum { MaxFunctionScopeDepth = 255 };
@@ -1598,7 +1618,7 @@ public:
void setDefaultArg(Expr *defarg);
- /// \brief Retrieve the source range that covers the entire default
+ /// Retrieve the source range that covers the entire default
/// argument.
SourceRange getDefaultArgRange() const;
void setUninstantiatedDefaultArg(Expr *arg);
@@ -1607,14 +1627,13 @@ public:
return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg();
}
- /// hasDefaultArg - Determines whether this parameter has a default argument,
+ /// Determines whether this parameter has a default argument,
/// either parsed or not.
bool hasDefaultArg() const;
- /// hasUnparsedDefaultArg - Determines whether this parameter has a
- /// default argument that has not yet been parsed. This will occur
- /// during the processing of a C++ class whose member functions have
- /// default arguments, e.g.,
+ /// Determines whether this parameter has a default argument that has not
+ /// yet been parsed. This will occur during the processing of a C++ class
+ /// whose member functions have default arguments, e.g.,
/// @code
/// class X {
/// public:
@@ -1629,11 +1648,10 @@ public:
return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated;
}
- /// setUnparsedDefaultArg - Specify that this parameter has an
- /// unparsed default argument. The argument will be replaced with a
- /// real default argument via setDefaultArg when the class
- /// definition enclosing the function declaration that owns this
- /// default argument is completed.
+ /// Specify that this parameter has an unparsed default argument.
+ /// The argument will be replaced with a real default argument via
+ /// setDefaultArg when the class definition enclosing the function
+ /// declaration that owns this default argument is completed.
void setUnparsedDefaultArg() {
ParmVarDeclBits.DefaultArgKind = DAK_Unparsed;
}
@@ -1648,11 +1666,11 @@ public:
QualType getOriginalType() const;
- /// \brief Determine whether this parameter is actually a function
+ /// Determine whether this parameter is actually a function
/// parameter pack.
bool isParameterPack() const;
- /// setOwningFunction - Sets the function declaration that owns this
+ /// Sets the function declaration that owns this
/// ParmVarDecl. Since ParmVarDecls are often created before the
/// FunctionDecls that own them, this routine is required to update
/// the DeclContext appropriately.
@@ -1683,8 +1701,7 @@ private:
unsigned getParameterIndexLarge() const;
};
-/// An instance of this class is created to represent a function declaration or
-/// definition.
+/// Represents a function declaration or definition.
///
/// Since a given function can be declared several times in a program,
/// there may be several FunctionDecls that correspond to that
@@ -1697,7 +1714,7 @@ private:
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
- /// \brief The kind of templated function a FunctionDecl can be.
+ /// The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
TK_NonTemplate,
TK_FunctionTemplate,
@@ -1707,7 +1724,7 @@ public:
};
private:
- /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+ /// A new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
ParmVarDecl **ParamInfo = nullptr;
@@ -1732,6 +1749,12 @@ private:
unsigned HasWrittenPrototype : 1;
unsigned IsDeleted : 1;
unsigned IsTrivial : 1; // sunk from CXXMethodDecl
+
+ /// This flag indicates whether this function is trivial for the purpose of
+ /// calls. This is meaningful only when this function is a copy/move
+ /// constructor or a destructor.
+ unsigned IsTrivialForCall : 1;
+
unsigned IsDefaulted : 1; // sunk from CXXMethoDecl
unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
unsigned HasImplicitReturnZero : 1;
@@ -1739,10 +1762,10 @@ private:
unsigned IsConstexpr : 1;
unsigned InstantiationIsPending : 1;
- /// \brief Indicates if the function uses __try.
+ /// Indicates if the function uses __try.
unsigned UsesSEHTry : 1;
- /// \brief Indicates if the function was a definition but its body was
+ /// Indicates if the function was a definition but its body was
/// skipped.
unsigned HasSkippedBody : 1;
@@ -1750,6 +1773,10 @@ private:
/// parsing it.
unsigned WillHaveBody : 1;
+ /// Indicates that this function is a multiversioned function using attribute
+ /// 'target'.
+ unsigned IsMultiVersion : 1;
+
protected:
/// [C++17] Only used by CXXDeductionGuideDecl. Declared here to avoid
/// increasing the size of CXXDeductionGuideDecl by the size of an unsigned
@@ -1764,7 +1791,7 @@ private:
unsigned HasODRHash : 1;
unsigned ODRHash;
- /// \brief End part of this FunctionDecl's source range.
+ /// End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
/// dealing with a function definition deserialized from a PCH/AST file,
@@ -1773,7 +1800,7 @@ private:
/// EndRangeLoc.
SourceLocation EndRangeLoc;
- /// \brief The template or declaration that this declaration
+ /// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
/// For non-templates, this value will be NULL. For function
@@ -1795,7 +1822,7 @@ private:
/// the DeclaratorDecl base class.
DeclarationNameLoc DNLoc;
- /// \brief Specify that this function declaration is actually a function
+ /// Specify that this function declaration is actually a function
/// template specialization.
///
/// \param C the ASTContext.
@@ -1824,7 +1851,7 @@ private:
const TemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation PointOfInstantiation);
- /// \brief Specify that this record is an instantiation of the
+ /// Specify that this record is an instantiation of the
/// member function FD.
void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
TemplateSpecializationKind TSK);
@@ -1842,13 +1869,14 @@ protected:
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsExplicitSpecified(false), IsVirtualAsWritten(false), IsPure(false),
HasInheritedPrototype(false), HasWrittenPrototype(true),
- IsDeleted(false), IsTrivial(false), IsDefaulted(false),
+ IsDeleted(false), IsTrivial(false), IsTrivialForCall(false),
+ IsDefaulted(false),
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false),
- WillHaveBody(false), IsCopyDeductionCandidate(false), HasODRHash(false),
- ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()),
- DNLoc(NameInfo.getInfo()) {}
+ WillHaveBody(false), IsMultiVersion(false),
+ IsCopyDeductionCandidate(false), HasODRHash(false), ODRHash(0),
+ EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {}
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -1915,11 +1943,25 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
- /// \brief Returns true if the function has a body (definition). The
- /// function body might be in any of the (re-)declarations of this
- /// function. The variant that accepts a FunctionDecl pointer will
- /// set that function declaration to the actual declaration
- /// containing the body (if there is one).
+ // Function definitions.
+ //
+ // A function declaration may be:
+ // - a non defining declaration,
+ // - a definition. A function may be defined because:
+ // - it has a body, or will have it in the case of late parsing.
+ // - it has an uninstantiated body. The body does not exist because the
+ // function is not used yet, but the declaration is considered a
+ // definition and does not allow other definition of this function.
+ // - it does not have a user specified body, but it does not allow
+ // redefinition, because it is deleted/defaulted or is defined through
+ // some other mechanism (alias, ifunc).
+
+ /// Returns true if the function has a body.
+ ///
+ /// The function body might be in any of the (re-)declarations of this
+ /// function. The variant that accepts a FunctionDecl pointer will set that
+ /// function declaration to the actual declaration containing the body (if
+ /// there is one).
bool hasBody(const FunctionDecl *&Definition) const;
bool hasBody() const override {
@@ -1931,9 +1973,11 @@ public:
/// specific codegen.
bool hasTrivialBody() const;
- /// Returns true if the function is defined at all, including a deleted
- /// definition. Except for the behavior when the function is deleted, behaves
- /// like hasBody.
+ /// Returns true if the function has a definition that does not need to be
+ /// instantiated.
+ ///
+ /// The variant that accepts a FunctionDecl pointer will set that function
+ /// declaration to the declaration that is a definition (if there is one).
bool isDefined(const FunctionDecl *&Definition) const;
virtual bool isDefined() const {
@@ -1941,7 +1985,7 @@ public:
return isDefined(Definition);
}
- /// \brief Get the definition for this declaration.
+ /// Get the definition for this declaration.
FunctionDecl *getDefinition() {
const FunctionDecl *Definition;
if (isDefined(Definition))
@@ -1975,8 +2019,7 @@ public:
IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
}
- /// Returns whether this specific declaration of the function has a body -
- /// that is, if it is a non-deleted definition.
+ /// Returns whether this specific declaration of the function has a body.
bool doesThisDeclarationHaveABody() const {
return Body || IsLateTemplateParsed;
}
@@ -2007,6 +2050,9 @@ public:
bool isTrivial() const { return IsTrivial; }
void setTrivial(bool IT) { IsTrivial = IT; }
+ bool isTrivialForCall() const { return IsTrivialForCall; }
+ void setTrivialForCall(bool IT) { IsTrivialForCall = IT; }
+
/// Whether this function is defaulted per C++0x. Only valid for
/// special member functions.
bool isDefaulted() const { return IsDefaulted; }
@@ -2023,7 +2069,7 @@ public:
bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
- /// \brief Whether this function has a prototype, either because one
+ /// Whether this function has a prototype, either because one
/// was explicitly written or because it was "inherited" by merging
/// a declaration without a prototype with a declaration that has a
/// prototype.
@@ -2033,7 +2079,7 @@ public:
bool hasWrittenPrototype() const { return HasWrittenPrototype; }
- /// \brief Whether this function inherited its prototype from a
+ /// Whether this function inherited its prototype from a
/// previous declaration.
bool hasInheritedPrototype() const { return HasInheritedPrototype; }
void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
@@ -2042,7 +2088,7 @@ public:
bool isConstexpr() const { return IsConstexpr; }
void setConstexpr(bool IC) { IsConstexpr = IC; }
- /// \brief Whether the instantiation of this function is pending.
+ /// Whether the instantiation of this function is pending.
/// This bit is set when the decision to instantiate this function is made
/// and unset if and when the function body is created. That leaves out
/// cases where instantiation did not happen because the template definition
@@ -2051,11 +2097,11 @@ public:
bool instantiationIsPending() const { return InstantiationIsPending; }
void setInstantiationIsPending(bool IC) { InstantiationIsPending = IC; }
- /// \brief Indicates the function uses __try.
+ /// Indicates the function uses __try.
bool usesSEHTry() const { return UsesSEHTry; }
void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }
- /// \brief Whether this function has been deleted.
+ /// Whether this function has been deleted.
///
/// A function that is "deleted" (via the C++0x "= delete" syntax)
/// acts like a normal function, except that it cannot actually be
@@ -2078,15 +2124,15 @@ public:
bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
- /// \brief Determines whether this function is "main", which is the
+ /// Determines whether this function is "main", which is the
/// entry point into an executable program.
bool isMain() const;
- /// \brief Determines whether this function is a MSVCRT user defined entry
+ /// Determines whether this function is a MSVCRT user defined entry
/// point.
bool isMSVCRTEntryPoint() const;
- /// \brief Determines whether this operator new or delete is one
+ /// Determines whether this operator new or delete is one
/// of the reserved global placement operators:
/// void *operator new(size_t, void *);
/// void *operator new[](size_t, void *);
@@ -2101,7 +2147,7 @@ public:
/// This function must be an allocation or deallocation function.
bool isReservedGlobalPlacementOperator() const;
- /// \brief Determines whether this function is one of the replaceable
+ /// Determines whether this function is one of the replaceable
/// global allocation functions:
/// void *operator new(size_t);
/// void *operator new(size_t, const std::nothrow_t &) noexcept;
@@ -2121,32 +2167,32 @@ public:
/// true through IsAligned.
bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;
- /// \brief Determine whether this is a destroying operator delete.
+ /// Determine whether this is a destroying operator delete.
bool isDestroyingOperatorDelete() const;
/// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
- /// \brief Determines whether this function is a function with
+ /// Determines whether this function is a function with
/// external, C linkage.
bool isExternC() const;
- /// \brief Determines whether this function's context is, or is nested within,
+ /// Determines whether this function's context is, or is nested within,
/// a C++ extern "C" linkage spec.
bool isInExternCContext() const;
- /// \brief Determines whether this function's context is, or is nested within,
+ /// Determines whether this function's context is, or is nested within,
/// a C++ extern "C++" linkage spec.
bool isInExternCXXContext() const;
- /// \brief Determines whether this is a global function.
+ /// Determines whether this is a global function.
bool isGlobal() const;
- /// \brief Determines whether this function is known to be 'noreturn', through
+ /// Determines whether this function is known to be 'noreturn', through
/// an attribute on its declaration or its type.
bool isNoReturn() const;
- /// \brief True if the function was a definition but its body was skipped.
+ /// True if the function was a definition but its body was skipped.
bool hasSkippedBody() const { return HasSkippedBody; }
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
@@ -2154,6 +2200,22 @@ public:
bool willHaveBody() const { return WillHaveBody; }
void setWillHaveBody(bool V = true) { WillHaveBody = V; }
+ /// True if this function is considered a multiversioned function.
+ bool isMultiVersion() const { return getCanonicalDecl()->IsMultiVersion; }
+
+ /// Sets the multiversion state for this declaration and all of its
+ /// redeclarations.
+ void setIsMultiVersion(bool V = true) {
+ getCanonicalDecl()->IsMultiVersion = V;
+ }
+
+ /// True if this function is a multiversioned dispatch function as a part of
+ /// the cpu_specific/cpu_dispatch functionality.
+ bool isCPUDispatchMultiVersion() const;
+ /// True if this function is a multiversioned processor specific function as a
+ /// part of the cpu_specific/cpu_dispatch functionality.
+ bool isCPUSpecificMultiVersion() const;
+
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
@@ -2209,34 +2271,34 @@ public:
return getType()->getAs<FunctionType>()->getReturnType();
}
- /// \brief Attempt to compute an informative source range covering the
+ /// Attempt to compute an informative source range covering the
/// function return type. This may omit qualifiers and other information with
/// limited representation in the AST.
SourceRange getReturnTypeSourceRange() const;
- /// \brief Attempt to compute an informative source range covering the
+ /// Attempt to compute an informative source range covering the
/// function exception specification, if any.
SourceRange getExceptionSpecSourceRange() const;
- /// \brief Determine the type of an expression that calls this function.
+ /// Determine the type of an expression that calls this function.
QualType getCallResultType() const {
assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
}
- /// \brief Returns the WarnUnusedResultAttr that is either declared on this
+ /// Returns the WarnUnusedResultAttr that is either declared on this
/// function, or its return type declaration.
const Attr *getUnusedResultAttr() const;
- /// \brief Returns true if this function or its return type has the
+ /// Returns true if this function or its return type has the
/// warn_unused_result attribute.
bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
- /// \brief Returns the storage class as written in the source. For the
+ /// Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const { return StorageClass(SClass); }
- /// \brief Determine whether the "inline" keyword was specified for this
+ /// Determine whether the "inline" keyword was specified for this
/// function.
bool isInlineSpecified() const { return IsInlineSpecified; }
@@ -2251,7 +2313,7 @@ public:
IsInline = true;
}
- /// \brief Determine whether this function should be inlined, because it is
+ /// Determine whether this function should be inlined, because it is
/// either marked "inline" or "constexpr" or is a member function of a class
/// that was defined in the class body.
bool isInlined() const { return IsInline; }
@@ -2262,8 +2324,8 @@ public:
bool doesDeclarationForceExternallyVisibleDefinition() const;
- /// isOverloadedOperator - Whether this function declaration
- /// represents an C++ overloaded operator, e.g., "operator+".
+ /// Whether this function declaration represents an C++ overloaded
+ /// operator, e.g., "operator+".
bool isOverloadedOperator() const {
return getOverloadedOperator() != OO_None;
}
@@ -2272,7 +2334,7 @@ public:
const IdentifierInfo *getLiteralIdentifier() const;
- /// \brief If this function is an instantiation of a member function
+ /// If this function is an instantiation of a member function
/// of a class template specialization, retrieves the function from
/// which it was instantiated.
///
@@ -2295,22 +2357,22 @@ public:
/// declaration returned by getInstantiatedFromMemberFunction().
FunctionDecl *getInstantiatedFromMemberFunction() const;
- /// \brief What kind of templated function this is.
+ /// What kind of templated function this is.
TemplatedKind getTemplatedKind() const;
- /// \brief If this function is an instantiation of a member function of a
+ /// If this function is an instantiation of a member function of a
/// class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const;
- /// \brief Specify that this record is an instantiation of the
+ /// Specify that this record is an instantiation of the
/// member function FD.
void setInstantiationOfMemberFunction(FunctionDecl *FD,
TemplateSpecializationKind TSK) {
setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
}
- /// \brief Retrieves the function template that is described by this
+ /// Retrieves the function template that is described by this
/// function declaration.
///
/// Every function template is represented as a FunctionTemplateDecl
@@ -2326,50 +2388,50 @@ public:
void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);
- /// \brief Determine whether this function is a function template
+ /// Determine whether this function is a function template
/// specialization.
bool isFunctionTemplateSpecialization() const {
return getPrimaryTemplate() != nullptr;
}
- /// \brief Retrieve the class scope template pattern that this function
+ /// Retrieve the class scope template pattern that this function
/// template specialization is instantiated from.
FunctionDecl *getClassScopeSpecializationPattern() const;
- /// \brief If this function is actually a function template specialization,
+ /// If this function is actually a function template specialization,
/// retrieve information about this function template specialization.
/// Otherwise, returns NULL.
FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const;
- /// \brief Determines whether this function is a function template
+ /// Determines whether this function is a function template
/// specialization or a member of a class template specialization that can
/// be implicitly instantiated.
bool isImplicitlyInstantiable() const;
- /// \brief Determines if the given function was instantiated from a
+ /// Determines if the given function was instantiated from a
/// function template.
bool isTemplateInstantiation() const;
- /// \brief Retrieve the function declaration from which this function could
+ /// Retrieve the function declaration from which this function could
/// be instantiated, if it is an instantiation (rather than a non-template
/// or a specialization, for example).
FunctionDecl *getTemplateInstantiationPattern() const;
- /// \brief Retrieve the primary template that this function template
+ /// Retrieve the primary template that this function template
/// specialization either specializes or was instantiated from.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
FunctionTemplateDecl *getPrimaryTemplate() const;
- /// \brief Retrieve the template arguments used to produce this function
+ /// Retrieve the template arguments used to produce this function
/// template specialization from the primary template.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
const TemplateArgumentList *getTemplateSpecializationArgs() const;
- /// \brief Retrieve the template argument list as written in the sources,
+ /// Retrieve the template argument list as written in the sources,
/// if any.
///
/// If this function declaration is not a function template specialization
@@ -2379,7 +2441,7 @@ public:
const ASTTemplateArgumentListInfo*
getTemplateSpecializationArgsAsWritten() const;
- /// \brief Specify that this function declaration is actually a function
+ /// Specify that this function declaration is actually a function
/// template specialization.
///
/// \param Template the function template that this function template
@@ -2409,7 +2471,7 @@ public:
PointOfInstantiation);
}
- /// \brief Specifies that this function declaration is actually a
+ /// Specifies that this function declaration is actually a
/// dependent function template specialization.
void setDependentTemplateSpecialization(ASTContext &Context,
const UnresolvedSetImpl &Templates,
@@ -2418,16 +2480,16 @@ public:
DependentFunctionTemplateSpecializationInfo *
getDependentSpecializationInfo() const;
- /// \brief Determine what kind of template instantiation this function
+ /// Determine what kind of template instantiation this function
/// represents.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief Determine what kind of template instantiation this function
+ /// Determine what kind of template instantiation this function
/// represents.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief Retrieve the (first) point of instantiation of a function template
+ /// Retrieve the (first) point of instantiation of a function template
/// specialization or a member of a class template specialization.
///
/// \returns the first point of instantiation, if this function was
@@ -2435,20 +2497,24 @@ public:
/// location.
SourceLocation getPointOfInstantiation() const;
- /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
bool isOutOfLine() const override;
- /// \brief Identify a memory copying or setting function.
+ /// Identify a memory copying or setting function.
/// If the given function is a memory copy or setting function, returns
/// the corresponding Builtin ID. If the function is not a memory function,
/// returns 0.
unsigned getMemoryFunctionKind() const;
- /// \brief Returns ODRHash of the function. This value is calculated and
+ /// Returns ODRHash of the function. This value is calculated and
/// stored on first call, then the stored value returned on the other calls.
unsigned getODRHash();
+ /// Returns cached ODRHash of the function. This must have been previously
+ /// computed and stored.
+ unsigned getODRHash() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
@@ -2462,8 +2528,7 @@ public:
}
};
-/// FieldDecl - An instance of this class is created by Sema::ActOnField to
-/// represent a member of a struct/union/class.
+/// Represents a member of a struct/union/class.
class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
unsigned BitField : 1;
unsigned Mutable : 1;
@@ -2499,7 +2564,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
Expr *BitWidth;
};
- /// \brief Storage for either the bit-width, the in-class initializer, or
+ /// Storage for either the bit-width, the in-class initializer, or
/// both (via InitAndBitWidth), or the captured variable length array bound.
///
/// If the storage kind is ISK_InClassCopyInit or
@@ -2534,20 +2599,20 @@ public:
static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// getFieldIndex - Returns the index of this field within its record,
+ /// Returns the index of this field within its record,
/// as appropriate for passing to ASTRecordLayout::getFieldOffset.
unsigned getFieldIndex() const;
- /// isMutable - Determines whether this field is mutable (C++ only).
+ /// Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
- /// \brief Determines whether this field is a bitfield.
+ /// Determines whether this field is a bitfield.
bool isBitField() const { return BitField; }
- /// @brief Determines whether this is an unnamed bitfield.
+ /// Determines whether this is an unnamed bitfield.
bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
- /// isAnonymousStructOrUnion - Determines whether this field is a
+ /// Determines whether this field is a
/// representative for an anonymous struct or union. Such fields are
/// unnamed and are implicitly generated by the implementation to
/// store the data for the anonymous union or struct.
@@ -2564,7 +2629,7 @@ public:
unsigned getBitWidthValue(const ASTContext &Ctx) const;
- /// setBitWidth - Set the bit-field width for this member.
+ /// Set the bit-field width for this member.
// Note: used by some clients (i.e., do not remove it).
void setBitWidth(Expr *Width) {
assert(!hasCapturedVLAType() && !BitField &&
@@ -2578,7 +2643,7 @@ public:
BitField = true;
}
- /// removeBitWidth - Remove the bit-field width from this member.
+ /// Remove the bit-field width from this member.
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
@@ -2586,6 +2651,11 @@ public:
BitField = false;
}
+ /// Is this a zero-length bit-field? Such bit-fields aren't really bit-fields
+ /// at all and instead act as a separator between contiguous runs of other
+ /// bit-fields.
+ bool isZeroLengthBitField(const ASTContext &Ctx) const;
+
/// Get the kind of (C++11) default member initializer that this field has.
InClassInitStyle getInClassInitStyle() const {
InitStorageKind storageKind = InitStorage.getInt();
@@ -2610,8 +2680,7 @@ public:
return static_cast<Expr*>(Ptr);
}
- /// setInClassInitializer - Set the C++11 in-class initializer for this
- /// member.
+ /// Set the C++11 in-class initializer for this member.
void setInClassInitializer(Expr *Init) {
assert(hasInClassInitializer() && !getInClassInitializer());
if (BitField)
@@ -2620,30 +2689,29 @@ public:
InitStorage.setPointer(Init);
}
- /// removeInClassInitializer - Remove the C++11 in-class initializer from this
- /// member.
+ /// Remove the C++11 in-class initializer from this member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit);
}
- /// \brief Determine whether this member captures the variable length array
+ /// Determine whether this member captures the variable length array
/// type.
bool hasCapturedVLAType() const {
return InitStorage.getInt() == ISK_CapturedVLAType;
}
- /// \brief Get the captured variable length array type.
+ /// Get the captured variable length array type.
const VariableArrayType *getCapturedVLAType() const {
return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
InitStorage.getPointer())
: nullptr;
}
- /// \brief Set the captured variable length array type for this field.
+ /// Set the captured variable length array type for this field.
void setCapturedVLAType(const VariableArrayType *VLAType);
- /// getParent - Returns the parent of this field declaration, which
+ /// Returns the parent of this field declaration, which
/// is the struct in which this field is defined.
const RecordDecl *getParent() const {
return cast<RecordDecl>(getDeclContext());
@@ -2664,7 +2732,7 @@ public:
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
};
-/// EnumConstantDecl - An instance of this object exists for each enum constant
+/// An instance of this object exists for each enum constant
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
/// TagType for the X EnumDecl.
@@ -2705,9 +2773,8 @@ public:
static bool classofKind(Kind K) { return K == EnumConstant; }
};
-/// IndirectFieldDecl - An instance of this class is created to represent a
-/// field injected from an anonymous union/struct into the parent scope.
-/// IndirectFieldDecl are always implicit.
+/// Represents a field injected from an anonymous union/struct into the parent
+/// scope. These are always implicit.
class IndirectFieldDecl : public ValueDecl,
public Mergeable<IndirectFieldDecl> {
NamedDecl **Chaining;
@@ -2756,17 +2823,17 @@ public:
static bool classofKind(Kind K) { return K == IndirectField; }
};
-/// TypeDecl - Represents a declaration of a type.
+/// Represents a declaration of a type.
class TypeDecl : public NamedDecl {
friend class ASTContext;
- /// TypeForDecl - This indicates the Type object that represents
+ /// This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
/// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
mutable const Type *TypeForDecl = nullptr;
- /// LocStart - The start of the source range for this declaration.
+ /// The start of the source range for this declaration.
SourceLocation LocStart;
void anchor() override;
@@ -2800,13 +2867,16 @@ public:
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- using ModedTInfo = std::pair<TypeSourceInfo *, QualType>;
- llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *> MaybeModedTInfo;
+ struct alignas(8) ModedTInfo {
+ TypeSourceInfo *first;
+ QualType second;
+ };
- // FIXME: This can be packed into the bitfields in Decl.
- /// If 0, we have not computed IsTransparentTag.
- /// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
- mutable unsigned CacheIsTransparentTag : 2;
+ /// If int part is 0, we have not computed IsTransparentTag.
+ /// Otherwise, IsTransparentTag is (getInt() >> 1).
+ mutable llvm::PointerIntPair<
+ llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *>, 2>
+ MaybeModedTInfo;
void anchor() override;
@@ -2815,7 +2885,7 @@ protected:
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
- MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
+ MaybeModedTInfo(TInfo, 0) {}
using redeclarable_base = Redeclarable<TypedefNameDecl>;
@@ -2842,26 +2912,29 @@ public:
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
- bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); }
+ bool isModed() const {
+ return MaybeModedTInfo.getPointer().is<ModedTInfo *>();
+ }
TypeSourceInfo *getTypeSourceInfo() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->first
- : MaybeModedTInfo.get<TypeSourceInfo*>();
+ return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->first
+ : MaybeModedTInfo.getPointer().get<TypeSourceInfo *>();
}
QualType getUnderlyingType() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->second
- : MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
+ return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->second
+ : MaybeModedTInfo.getPointer()
+ .get<TypeSourceInfo *>()
+ ->getType();
}
void setTypeSourceInfo(TypeSourceInfo *newType) {
- MaybeModedTInfo = newType;
+ MaybeModedTInfo.setPointer(newType);
}
void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
- MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
+ MaybeModedTInfo.setPointer(new (getASTContext(), 8)
+ ModedTInfo({unmodedTSI, modedTy}));
}
/// Retrieves the canonical declaration of this typedef-name.
@@ -2878,8 +2951,8 @@ public:
/// Determines if this typedef shares a name and spelling location with its
/// underlying tag type, as is the case with the NS_ENUM macro.
bool isTransparentTag() const {
- if (CacheIsTransparentTag)
- return CacheIsTransparentTag & 0x2;
+ if (MaybeModedTInfo.getInt())
+ return MaybeModedTInfo.getInt() & 0x2;
return isTransparentTagSlow();
}
@@ -2893,7 +2966,7 @@ private:
bool isTransparentTagSlow() const;
};
-/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
+/// Represents the declaration of a typedef-name via the 'typedef'
/// type specifier.
class TypedefDecl : public TypedefNameDecl {
TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
@@ -2913,7 +2986,7 @@ public:
static bool classofKind(Kind K) { return K == Typedef; }
};
-/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
+/// Represents the declaration of a typedef-name via a C++11
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
/// The template for which this is the pattern, if any.
@@ -2940,7 +3013,7 @@ public:
static bool classofKind(Kind K) { return K == TypeAlias; }
};
-/// TagDecl - Represents the declaration of a struct/union/class/enum.
+/// Represents the declaration of a struct/union/class/enum.
class TagDecl
: public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
public:
@@ -2949,25 +3022,24 @@ public:
private:
// FIXME: This can be packed into the bitfields in Decl.
- /// TagDeclKind - The TagKind enum.
+ /// The TagKind enum.
unsigned TagDeclKind : 3;
- /// IsCompleteDefinition - True if this is a definition ("struct foo
- /// {};"), false if it is a declaration ("struct foo;"). It is not
- /// a definition until the definition has been fully processed.
+ /// True if this is a definition ("struct foo {};"), false if it is a
+ /// declaration ("struct foo;"). It is not considered a definition
+ /// until the definition has been fully processed.
unsigned IsCompleteDefinition : 1;
protected:
- /// IsBeingDefined - True if this is currently being defined.
+ /// True if this is currently being defined.
unsigned IsBeingDefined : 1;
private:
- /// IsEmbeddedInDeclarator - True if this tag declaration is
- /// "embedded" (i.e., defined or declared for the very first time)
- /// in the syntax of a declarator.
+ /// True if this tag declaration is "embedded" (i.e., defined or declared
+ /// for the very first time) in the syntax of a declarator.
unsigned IsEmbeddedInDeclarator : 1;
- /// \brief True if this tag is free standing, e.g. "struct foo;".
+ /// True if this tag is free standing, e.g. "struct foo;".
unsigned IsFreeStanding : 1;
protected:
@@ -2975,21 +3047,21 @@ protected:
unsigned NumPositiveBits : 8;
unsigned NumNegativeBits : 8;
- /// IsScoped - True if this tag declaration is a scoped enumeration. Only
+ /// True if this tag declaration is a scoped enumeration. Only
/// possible in C++11 mode.
unsigned IsScoped : 1;
- /// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
+ /// If this tag declaration is a scoped enum,
/// then this is true if the scoped enum was declared using the class
/// tag, false if it was declared with the struct tag. No meaning is
/// associated if this tag declaration is not a scoped enum.
unsigned IsScopedUsingClassTag : 1;
- /// IsFixed - True if this is an enumeration with fixed underlying type. Only
+ /// True if this is an enumeration with fixed underlying type. Only
/// possible in C++11, Microsoft extensions, or Objective C mode.
unsigned IsFixed : 1;
- /// \brief Indicates whether it is possible for declarations of this kind
+ /// Indicates whether it is possible for declarations of this kind
/// to have an out-of-date definition.
///
/// This option is only enabled when modules are enabled.
@@ -3006,7 +3078,7 @@ private:
// to be used for the (uncommon) case of out-of-line declarations.
using ExtInfo = QualifierInfo;
- /// \brief If the (out-of-line) tag declaration name
+ /// If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
/// otherwise, if the tag declaration is anonymous and it is part of
/// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
@@ -3050,7 +3122,7 @@ protected:
return getMostRecentDecl();
}
- /// @brief Completes the definition of this tag declaration.
+ /// Completes the definition of this tag declaration.
///
/// This is a helper function for derived classes.
void completeDefinition();
@@ -3072,11 +3144,11 @@ public:
SourceRange getBraceRange() const { return BraceRange; }
void setBraceRange(SourceRange R) { BraceRange = R; }
- /// getInnerLocStart - Return SourceLocation representing start of source
+ /// Return SourceLocation representing start of source
/// range ignoring outer template declarations.
SourceLocation getInnerLocStart() const { return getLocStart(); }
- /// getOuterLocStart - Return SourceLocation representing start of source
+ /// Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -3086,25 +3158,24 @@ public:
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
- /// isThisDeclarationADefinition() - Return true if this declaration
- /// is a completion definition of the type. Provided for consistency.
+ /// Return true if this declaration is a completion definition of the type.
+ /// Provided for consistency.
bool isThisDeclarationADefinition() const {
return isCompleteDefinition();
}
- /// isCompleteDefinition - Return true if this decl has its body
- /// fully specified.
+ /// Return true if this decl has its body fully specified.
bool isCompleteDefinition() const {
return IsCompleteDefinition;
}
- /// \brief Return true if this complete decl is
+ /// Return true if this complete decl is
/// required to be complete for some existing use.
bool isCompleteDefinitionRequired() const {
return IsCompleteDefinitionRequired;
}
- /// isBeingDefined - Return true if this decl is currently being defined.
+ /// Return true if this decl is currently being defined.
bool isBeingDefined() const {
return IsBeingDefined;
}
@@ -3121,19 +3192,19 @@ public:
IsFreeStanding = isFreeStanding;
}
- /// \brief Whether this declaration declares a type that is
+ /// Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
bool isDependentType() const { return isDependentContext(); }
- /// @brief Starts the definition of this tag declaration.
+ /// Starts the definition of this tag declaration.
///
/// This method should be invoked at the beginning of the definition
/// of this tag declaration. It will set the tag type into a state
/// where it is in the process of being defined.
void startDefinition();
- /// getDefinition - Returns the TagDecl that actually defines this
+ /// Returns the TagDecl that actually defines this
/// struct/union/class/enum. When determining whether or not a
/// struct/union/class/enum has a definition, one should use this
/// method as opposed to 'isDefinition'. 'isDefinition' indicates
@@ -3191,14 +3262,14 @@ public:
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
- /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+ /// Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
: nullptr;
}
- /// \brief Retrieve the nested-name-specifier (with source-location
+ /// Retrieve the nested-name-specifier (with source-location
/// information) that qualifies the name of this declaration, if it was
/// present in the source.
NestedNameSpecifierLoc getQualifierLoc() const {
@@ -3233,11 +3304,11 @@ public:
}
};
-/// EnumDecl - Represents an enum. In C++11, enums can be forward-declared
+/// Represents an enum. In C++11, enums can be forward-declared
/// with a fixed underlying type, and in C we allow them to be forward-declared
/// with no underlying type as an extension.
class EnumDecl : public TagDecl {
- /// IntegerType - This represent the integer type that the enum corresponds
+ /// This represent the integer type that the enum corresponds
/// to for code generation purposes. Note that the enumerator constants may
/// have a different type than this does.
///
@@ -3253,17 +3324,21 @@ class EnumDecl : public TagDecl {
/// extra pointer when TypeSourceInfo is needed.
llvm::PointerUnion<const Type *, TypeSourceInfo *> IntegerType;
- /// PromotionType - The integer type that values of this type should
+ /// The integer type that values of this type should
/// promote to. In C, enumerators are generally of an integer type
/// directly, but gcc-style large enumerators (and all enumerators
/// in C++) are of the enum type instead.
QualType PromotionType;
- /// \brief If this enumeration is an instantiation of a member enumeration
+ /// If this enumeration is an instantiation of a member enumeration
/// of a class template specialization, this is the member specialization
/// information.
MemberSpecializationInfo *SpecializationInfo = nullptr;
+ /// Store the ODRHash after first calculation.
+ unsigned HasODRHash : 1;
+ unsigned ODRHash;
+
EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
@@ -3275,6 +3350,8 @@ class EnumDecl : public TagDecl {
IsScoped = Scoped;
IsScopedUsingClassTag = ScopedUsingClassTag;
IsFixed = Fixed;
+ HasODRHash = false;
+ ODRHash = 0;
}
void anchor() override;
@@ -3317,9 +3394,9 @@ public:
bool IsFixed);
static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// completeDefinition - When created, the EnumDecl corresponds to a
+ /// When created, the EnumDecl corresponds to a
/// forward-declared enum. This method is used to mark the
- /// declaration as being defined; it's enumerators have already been
+ /// declaration as being defined; its enumerators have already been
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
void completeDefinition(QualType NewType,
@@ -3327,8 +3404,7 @@ public:
unsigned NumPositiveBits,
unsigned NumNegativeBits);
- // enumerator_iterator - Iterates through the enumerators of this
- // enumeration.
+ // Iterates through the enumerators of this enumeration.
using enumerator_iterator = specific_decl_iterator<EnumConstantDecl>;
using enumerator_range =
llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>;
@@ -3351,14 +3427,13 @@ public:
return enumerator_iterator(E->decls_end());
}
- /// getPromotionType - Return the integer type that enumerators
- /// should promote to.
+ /// Return the integer type that enumerators should promote to.
QualType getPromotionType() const { return PromotionType; }
- /// \brief Set the promotion type.
+ /// Set the promotion type.
void setPromotionType(QualType T) { PromotionType = T; }
- /// getIntegerType - Return the integer type this enum decl corresponds to.
+ /// Return the integer type this enum decl corresponds to.
/// This returns a null QualType for an enum forward definition with no fixed
/// underlying type.
QualType getIntegerType() const {
@@ -3369,23 +3444,23 @@ public:
return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
}
- /// \brief Set the underlying integer type.
+ /// Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
- /// \brief Set the underlying integer type source info.
+ /// Set the underlying integer type source info.
void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
- /// \brief Return the type source info for the underlying integer type,
+ /// Return the type source info for the underlying integer type,
/// if no type source info exists, return 0.
TypeSourceInfo *getIntegerTypeSourceInfo() const {
return IntegerType.dyn_cast<TypeSourceInfo*>();
}
- /// \brief Retrieve the source range that covers the underlying type if
+ /// Retrieve the source range that covers the underlying type if
/// specified.
SourceRange getIntegerTypeRange() const LLVM_READONLY;
- /// \brief Returns the width in bits required to store all the
+ /// Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
return NumPositiveBits;
@@ -3395,7 +3470,7 @@ public:
assert(NumPositiveBits == Num && "can't store this bitcount");
}
- /// \brief Returns the width in bits required to store all the
+ /// Returns the width in bits required to store all the
/// negative enumerators of this enum. These widths include
/// the rightmost leading 1; that is:
///
@@ -3411,25 +3486,29 @@ public:
NumNegativeBits = Num;
}
- /// \brief Returns true if this is a C++11 scoped enumeration.
+ /// Returns true if this is a C++11 scoped enumeration.
bool isScoped() const {
return IsScoped;
}
- /// \brief Returns true if this is a C++11 scoped enumeration.
+ /// Returns true if this is a C++11 scoped enumeration.
bool isScopedUsingClassTag() const {
return IsScopedUsingClassTag;
}
- /// \brief Returns true if this is an Objective-C, C++11, or
+ /// Returns true if this is an Objective-C, C++11, or
/// Microsoft-style enumeration with a fixed underlying type.
bool isFixed() const {
return IsFixed;
}
- /// \brief Returns true if this can be considered a complete type.
+ unsigned getODRHash();
+
+ /// Returns true if this can be considered a complete type.
bool isComplete() const {
- return isCompleteDefinition() || isFixed();
+ // IntegerType is set for fixed type enums and non-fixed but implicitly
+ // int-sized Microsoft enums.
+ return isCompleteDefinition() || IntegerType;
}
/// Returns true if this enum is either annotated with
@@ -3444,33 +3523,33 @@ public:
/// enum_extensibility(open).
bool isClosedNonFlag() const;
- /// \brief Retrieve the enum definition from which this enumeration could
+ /// Retrieve the enum definition from which this enumeration could
/// be instantiated, if it is an instantiation (rather than a non-template).
EnumDecl *getTemplateInstantiationPattern() const;
- /// \brief Returns the enumeration (declared within the template)
+ /// Returns the enumeration (declared within the template)
/// from which this enumeration type was instantiated, or NULL if
/// this enumeration was not instantiated from any template.
EnumDecl *getInstantiatedFromMemberEnum() const;
- /// \brief If this enumeration is a member of a specialization of a
+ /// If this enumeration is a member of a specialization of a
/// templated class, determine what kind of template specialization
/// or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief For an enumeration member that was instantiated from a member
+ /// For an enumeration member that was instantiated from a member
/// enumeration of a templated class, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief If this enumeration is an instantiation of a member enumeration of
+ /// If this enumeration is an instantiation of a member enumeration of
/// a class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const {
return SpecializationInfo;
}
- /// \brief Specify that this enumeration is an instantiation of the
+ /// Specify that this enumeration is an instantiation of the
/// member enumeration ED.
void setInstantiationOfMemberEnum(EnumDecl *ED,
TemplateSpecializationKind TSK) {
@@ -3481,36 +3560,74 @@ public:
static bool classofKind(Kind K) { return K == Enum; }
};
-/// RecordDecl - Represents a struct/union/class. For example:
+/// Represents a struct/union/class. For example:
/// struct X; // Forward declaration, no "body".
/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
/// This decl will be marked invalid if *any* members are invalid.
class RecordDecl : public TagDecl {
+public:
+ /// Enum that represents the different ways arguments are passed to and
+ /// returned from function calls. This takes into account the target-specific
+ /// and version-specific rules along with the rules determined by the
+ /// language.
+ enum ArgPassingKind : unsigned {
+ /// The argument of this type can be passed directly in registers.
+ APK_CanPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are not forced to be passed
+ /// indirectly. This value is used only in C++. This value is required by
+ /// C++ because, in uncommon situations, it is possible for a class to have
+ /// only trivial copy/move constructors even when one of its subobjects has
+ /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
+ /// constructor in the derived class is deleted).
+ APK_CannotPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are forced to be passed
+ /// indirectly.
+ APK_CanNeverPassInRegs
+ };
+
+private:
friend class DeclContext;
// FIXME: This can be packed into the bitfields in Decl.
- /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
+ /// This is true if this struct ends with a flexible
/// array member (e.g. int X[]) or if this union contains a struct that does.
/// If so, this cannot be contained in arrays or other structs as a member.
- bool HasFlexibleArrayMember : 1;
+ unsigned HasFlexibleArrayMember : 1;
- /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
- /// or union.
- bool AnonymousStructOrUnion : 1;
+ /// Whether this is the type of an anonymous struct or union.
+ unsigned AnonymousStructOrUnion : 1;
- /// HasObjectMember - This is true if this struct has at least one member
+ /// This is true if this struct has at least one member
/// containing an Objective-C object pointer type.
- bool HasObjectMember : 1;
-
- /// HasVolatileMember - This is true if struct has at least one member of
+ unsigned HasObjectMember : 1;
+
+ /// This is true if struct has at least one member of
/// 'volatile' type.
- bool HasVolatileMember : 1;
+ unsigned HasVolatileMember : 1;
- /// \brief Whether the field declarations of this record have been loaded
+ /// Whether the field declarations of this record have been loaded
/// from external storage. To avoid unnecessary deserialization of
/// methods/nested types we allow deserialization of just the fields
/// when needed.
- mutable bool LoadedFieldsFromExternalStorage : 1;
+ mutable unsigned LoadedFieldsFromExternalStorage : 1;
+
+ /// Basic properties of non-trivial C structs.
+ unsigned NonTrivialToPrimitiveDefaultInitialize : 1;
+ unsigned NonTrivialToPrimitiveCopy : 1;
+ unsigned NonTrivialToPrimitiveDestroy : 1;
+
+ /// Indicates whether this struct is destroyed in the callee.
+ ///
+ /// Please note that MSVC won't merge adjacent bitfields if they don't have
+ /// the same type.
+ unsigned ParamDestroyedInCallee : 1;
+
+ /// Represents the way this type is passed to a function.
+ unsigned ArgPassingRestrictions : 2;
protected:
RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
@@ -3541,10 +3658,9 @@ public:
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
- /// isAnonymousStructOrUnion - Whether this is an anonymous struct
- /// or union. To be an anonymous struct or union, it must have been
- /// declared without a name and there must be no objects of this
- /// type declared, e.g.,
+ /// Whether this is an anonymous struct or union. To be an anonymous
+ /// struct or union, it must have been declared without a name and
+ /// there must be no objects of this type declared, e.g.,
/// @code
/// union { int i; float f; };
/// @endcode
@@ -3571,7 +3687,55 @@ public:
LoadedFieldsFromExternalStorage = val;
}
- /// \brief Determines whether this declaration represents the
+ /// Functions to query basic properties of non-trivial C structs.
+ bool isNonTrivialToPrimitiveDefaultInitialize() const {
+ return NonTrivialToPrimitiveDefaultInitialize;
+ }
+
+ void setNonTrivialToPrimitiveDefaultInitialize(bool V) {
+ NonTrivialToPrimitiveDefaultInitialize = V;
+ }
+
+ bool isNonTrivialToPrimitiveCopy() const {
+ return NonTrivialToPrimitiveCopy;
+ }
+
+ void setNonTrivialToPrimitiveCopy(bool V) {
+ NonTrivialToPrimitiveCopy = V;
+ }
+
+ bool isNonTrivialToPrimitiveDestroy() const {
+ return NonTrivialToPrimitiveDestroy;
+ }
+
+ void setNonTrivialToPrimitiveDestroy(bool V) {
+ NonTrivialToPrimitiveDestroy = V;
+ }
+
+ /// Determine whether this class can be passed in registers. In C++ mode,
+ /// it must have at least one trivial, non-deleted copy or move constructor.
+ /// FIXME: This should be set as part of completeDefinition.
+ bool canPassInRegisters() const {
+ return getArgPassingRestrictions() == APK_CanPassInRegs;
+ }
+
+ ArgPassingKind getArgPassingRestrictions() const {
+ return static_cast<ArgPassingKind>(ArgPassingRestrictions);
+ }
+
+ void setArgPassingRestrictions(ArgPassingKind Kind) {
+ ArgPassingRestrictions = static_cast<uint8_t>(Kind);
+ }
+
+ bool isParamDestroyedInCallee() const {
+ return ParamDestroyedInCallee;
+ }
+
+ void setParamDestroyedInCallee(bool V) {
+ ParamDestroyedInCallee = V;
+ }
+
+ /// Determines whether this declaration represents the
/// injected class name.
///
/// The injected class name in C++ is the name of the class that
@@ -3586,19 +3750,19 @@ public:
/// \endcode
bool isInjectedClassName() const;
- /// \brief Determine whether this record is a class describing a lambda
+ /// Determine whether this record is a class describing a lambda
/// function object.
bool isLambda() const;
- /// \brief Determine whether this record is a record for captured variables in
+ /// Determine whether this record is a record for captured variables in
/// CapturedStmt construct.
bool isCapturedRecord() const;
- /// \brief Mark the record as a record for captured variables in CapturedStmt
+ /// Mark the record as a record for captured variables in CapturedStmt
/// construct.
void setCapturedRecord();
- /// getDefinition - Returns the RecordDecl that actually defines
+ /// Returns the RecordDecl that actually defines
/// this struct/union/class. When determining whether or not a
/// struct/union/class is completely defined, one should use this
/// method as opposed to 'isCompleteDefinition'.
@@ -3623,14 +3787,12 @@ public:
return field_iterator(decl_iterator());
}
- // field_empty - Whether there are any fields (non-static data
- // members) in this record.
+ // Whether there are any fields (non-static data members) in this record.
bool field_empty() const {
return field_begin() == field_end();
}
- /// completeDefinition - Notes that the definition of this type is
- /// now complete.
+ /// Note that the definition of this type is now complete.
virtual void completeDefinition();
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3638,12 +3800,12 @@ public:
return K >= firstRecord && K <= lastRecord;
}
- /// \brief Get whether or not this is an ms_struct which can
+ /// Get whether or not this is an ms_struct which can
/// be turned on with an attribute, pragma, or -mms-bitfields
/// commandline option.
bool isMsStruct(const ASTContext &C) const;
- /// \brief Whether we are allowed to insert extra padding between fields.
+ /// Whether we are allowed to insert extra padding between fields.
/// These padding are added to help AddressSanitizer detect
/// intra-object-overflow bugs.
bool mayInsertExtraPadding(bool EmitRemark = false) const;
@@ -3653,7 +3815,7 @@ public:
const FieldDecl *findFirstNamedDataMember() const;
private:
- /// \brief Deserialize just the fields.
+ /// Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
};
@@ -3689,7 +3851,7 @@ public:
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
-/// BlockDecl - This represents a block literal declaration, which is like an
+/// Pepresents a block literal declaration, which is like an
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
class BlockDecl : public Decl, public DeclContext {
@@ -3739,7 +3901,11 @@ private:
bool BlockMissingReturnType : 1;
bool IsConversionFromLambda : 1;
- /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal
+ /// A bit that indicates this block is passed directly to a function as a
+ /// non-escaping parameter.
+ bool DoesNotEscape : 1;
+
+ /// A new[]'d array of pointers to ParmVarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
ParmVarDecl **ParamInfo = nullptr;
@@ -3758,7 +3924,7 @@ protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
: Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false),
CapturesCXXThis(false), BlockMissingReturnType(true),
- IsConversionFromLambda(false) {}
+ IsConversionFromLambda(false), DoesNotEscape(false) {}
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3808,11 +3974,11 @@ public:
void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
- /// hasCaptures - True if this block (or its nested blocks) captures
+ /// True if this block (or its nested blocks) captures
/// anything of local storage from its enclosing scopes.
bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; }
- /// getNumCaptures - Returns the number of captured variables.
+ /// Returns the number of captured variables.
/// Does not include an entry for 'this'.
unsigned getNumCaptures() const { return NumCaptures; }
@@ -3830,6 +3996,9 @@ public:
bool isConversionFromLambda() const { return IsConversionFromLambda; }
void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
+ bool doesNotEscape() const { return DoesNotEscape; }
+ void setDoesNotEscape() { DoesNotEscape = true; }
+
bool capturesVariable(const VarDecl *var) const;
void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
@@ -3861,8 +4030,7 @@ public:
}
};
-/// \brief This represents the body of a CapturedStmt, and serves as its
-/// DeclContext.
+/// Represents the body of a CapturedStmt, and serves as its DeclContext.
class CapturedDecl final
: public Decl,
public DeclContext,
@@ -3873,13 +4041,13 @@ protected:
}
private:
- /// \brief The number of parameters to the outlined function.
+ /// The number of parameters to the outlined function.
unsigned NumParams;
- /// \brief The position of context parameter in list of parameters.
+ /// The position of context parameter in list of parameters.
unsigned ContextParam;
- /// \brief The body of the outlined function.
+ /// The body of the outlined function.
llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
explicit CapturedDecl(DeclContext *DC, unsigned NumParams);
@@ -3927,7 +4095,7 @@ public:
return {getParams(), getNumParams()};
}
- /// \brief Retrieve the parameter containing captured variables.
+ /// Retrieve the parameter containing captured variables.
ImplicitParamDecl *getContextParam() const {
assert(ContextParam < NumParams);
return getParam(ContextParam);
@@ -3942,9 +4110,9 @@ public:
using param_iterator = ImplicitParamDecl *const *;
using param_range = llvm::iterator_range<param_iterator>;
- /// \brief Retrieve an iterator pointing to the first parameter decl.
+ /// Retrieve an iterator pointing to the first parameter decl.
param_iterator param_begin() const { return getParams(); }
- /// \brief Retrieve an iterator one past the last parameter decl.
+ /// Retrieve an iterator one past the last parameter decl.
param_iterator param_end() const { return getParams() + NumParams; }
// Implement isa/cast/dyncast/etc.
@@ -3958,7 +4126,7 @@ public:
}
};
-/// \brief Describes a module import declaration, which makes the contents
+/// Describes a module import declaration, which makes the contents
/// of the named module visible in the current translation unit.
///
/// An import declaration imports the named module (or submodule). For example:
@@ -3975,7 +4143,7 @@ class ImportDecl final : public Decl,
friend class ASTReader;
friend TrailingObjects;
- /// \brief The imported module, along with a bit that indicates whether
+ /// The imported module, along with a bit that indicates whether
/// we have source-location information for each identifier in the module
/// name.
///
@@ -3983,7 +4151,7 @@ class ImportDecl final : public Decl,
/// end of the import declaration.
llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
- /// \brief The next import in the list of imports local to the translation
+ /// The next import in the list of imports local to the translation
/// unit being parsed (not loaded from an AST file).
ImportDecl *NextLocalImport = nullptr;
@@ -3996,25 +4164,25 @@ class ImportDecl final : public Decl,
ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {}
public:
- /// \brief Create a new module import declaration.
+ /// Create a new module import declaration.
static ImportDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs);
- /// \brief Create a new module import declaration for an implicitly-generated
+ /// Create a new module import declaration for an implicitly-generated
/// import.
static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
SourceLocation EndLoc);
- /// \brief Create a new, deserialized module import declaration.
+ /// Create a new, deserialized module import declaration.
static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumLocations);
- /// \brief Retrieve the module that was imported by the import declaration.
+ /// Retrieve the module that was imported by the import declaration.
Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
- /// \brief Retrieves the locations of each of the identifiers that make up
+ /// Retrieves the locations of each of the identifiers that make up
/// the complete module name in the import declaration.
///
/// This will return an empty array if the locations of the individual
@@ -4027,7 +4195,7 @@ public:
static bool classofKind(Kind K) { return K == Import; }
};
-/// \brief Represents a C++ Modules TS module export declaration.
+/// Represents a C++ Modules TS module export declaration.
///
/// For example:
/// \code
@@ -4039,7 +4207,7 @@ class ExportDecl final : public Decl, public DeclContext {
private:
friend class ASTDeclReader;
- /// \brief The source location for the right brace (if valid).
+ /// The source location for the right brace (if valid).
SourceLocation RBraceLoc;
ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
@@ -4077,7 +4245,7 @@ public:
}
};
-/// \brief Represents an empty-declaration.
+/// Represents an empty-declaration.
class EmptyDecl : public Decl {
EmptyDecl(DeclContext *DC, SourceLocation L) : Decl(Empty, DC, L) {}
@@ -4111,7 +4279,7 @@ template<typename decl_type>
void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// Note: This routine is implemented here because we need both NamedDecl
// and Redeclarable to be defined.
- assert(RedeclLink.NextIsLatest() &&
+ assert(RedeclLink.isFirst() &&
"setPreviousDecl on a decl already in a redeclaration chain");
if (PrevDecl) {
@@ -4119,7 +4287,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// redeclaration, or we can build invalid chains. If the most recent
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
First = PrevDecl->getFirstDecl();
- assert(First->RedeclLink.NextIsLatest() && "Expected first");
+ assert(First->RedeclLink.isFirst() && "Expected first");
decl_type *MostRecent = First->getNextRedeclaration();
RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
@@ -4142,7 +4310,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// Inline function definitions.
-/// \brief Check if the given decl is complete.
+/// Check if the given decl is complete.
///
/// We use this function to break a cycle between the inline definitions in
/// Type.h and Decl.h.
@@ -4150,7 +4318,7 @@ inline bool IsEnumDeclComplete(EnumDecl *ED) {
return ED->isComplete();
}
-/// \brief Check if the given decl is scoped.
+/// Check if the given decl is scoped.
///
/// We use this function to break a cycle between the inline definitions in
/// Type.h and Decl.h.