summaryrefslogtreecommitdiffstats
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.h852
1 files changed, 542 insertions, 310 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index a02a2ce..11696db 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -22,6 +22,7 @@
#include "clang/Basic/Linkage.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
class CXXTemporary;
@@ -40,7 +41,8 @@ class DependentFunctionTemplateSpecializationInfo;
class TypeLoc;
class UnresolvedSetImpl;
class LabelStmt;
-
+class Module;
+
/// \brief A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
@@ -66,6 +68,7 @@ public:
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
+ virtual void anchor();
ASTContext &Ctx;
/// The (most recently entered) anonymous namespace for this
@@ -98,11 +101,15 @@ public:
/// NamedDecl - This represents a decl with a name. Many decls have names such
/// as ObjCMethodDecl, but not @class, etc.
class NamedDecl : public Decl {
+ virtual void anchor();
/// Name - 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;
+private:
+ NamedDecl *getUnderlyingDeclImpl();
+
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
: Decl(DK, DC, L), Name(N) { }
@@ -182,15 +189,11 @@ public:
/// \brief Determine whether this declaration has linkage.
bool hasLinkage() const;
- /// \brief Whether this declaration was marked as being private to the
- /// module in which it was defined.
- bool isModulePrivate() const { return ModulePrivate; }
+ using Decl::isModulePrivate;
+ using Decl::setModulePrivate;
- /// \brief Specify whether this declaration was marked as being private
- /// to the module in which it was defined.
- void setModulePrivate(bool MP = true) {
- ModulePrivate = MP;
- }
+ /// \brief Determine whether this declaration is hidden from name lookup.
+ bool isHidden() const { return Hidden; }
/// \brief Determine whether this declaration is a C++ class member.
bool isCXXClassMember() const {
@@ -206,8 +209,8 @@ public:
return DC->isRecord();
}
- /// \brief Given that this declaration is a C++ class member,
- /// determine whether it's an instance member of its class.
+ /// \brief Determine whether the given declaration is an instance member of
+ /// a C++ class.
bool isCXXInstanceMember() const;
class LinkageInfo {
@@ -249,26 +252,52 @@ public:
setLinkage(minLinkage(linkage(), L));
}
void mergeLinkage(LinkageInfo Other) {
- setLinkage(minLinkage(linkage(), Other.linkage()));
+ mergeLinkage(Other.linkage());
}
- void mergeVisibility(Visibility V) {
- setVisibility(minVisibility(visibility(), V));
- }
- void mergeVisibility(Visibility V, bool E) {
+ // Merge the visibility V giving preference to explicit ones.
+ // This is used, for example, when merging the visibility of a class
+ // down to one of its members. If the member has no explicit visibility,
+ // the class visibility wins.
+ void mergeVisibility(Visibility V, bool E = false) {
+ // If one has explicit visibility and the other doesn't, keep the
+ // explicit one.
+ if (visibilityExplicit() && !E)
+ return;
+ if (!visibilityExplicit() && E)
+ setVisibility(V, E);
+
+ // If both are explicit or both are implicit, keep the minimum.
setVisibility(minVisibility(visibility(), V), visibilityExplicit() || E);
}
+ // Merge the visibility V, keeping the most restrictive one.
+ // This is used for cases like merging the visibility of a template
+ // argument to an instantiation. If we already have a hidden class,
+ // no argument should give it default visibility.
+ void mergeVisibilityWithMin(Visibility V, bool E = false) {
+ // Never increase the visibility
+ if (visibility() < V)
+ return;
+
+ // If this visibility is explicit, keep it.
+ if (visibilityExplicit() && !E)
+ return;
+ setVisibility(V, E);
+ }
void mergeVisibility(LinkageInfo Other) {
mergeVisibility(Other.visibility(), Other.visibilityExplicit());
}
+ void mergeVisibilityWithMin(LinkageInfo Other) {
+ mergeVisibilityWithMin(Other.visibility(), Other.visibilityExplicit());
+ }
void merge(LinkageInfo Other) {
mergeLinkage(Other);
mergeVisibility(Other);
}
- void merge(std::pair<Linkage,Visibility> LV) {
- mergeLinkage(LV.first);
- mergeVisibility(LV.second);
+ void mergeWithMin(LinkageInfo Other) {
+ mergeLinkage(Other);
+ mergeVisibilityWithMin(Other);
}
friend LinkageInfo merge(LinkageInfo L, LinkageInfo R) {
@@ -281,7 +310,9 @@ public:
Linkage getLinkage() const;
/// \brief Determines the visibility of this entity.
- Visibility getVisibility() const { return getLinkageAndVisibility().visibility(); }
+ Visibility getVisibility() const {
+ return getLinkageAndVisibility().visibility();
+ }
/// \brief Determines the linkage and visibility of this entity.
LinkageInfo getLinkageAndVisibility() const;
@@ -291,12 +322,19 @@ public:
llvm::Optional<Visibility> getExplicitVisibility() const;
/// \brief Clear the linkage cache in response to a change
- /// to the declaration.
+ /// to the declaration.
void ClearLinkageCache();
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
- NamedDecl *getUnderlyingDecl();
+ NamedDecl *getUnderlyingDecl() {
+ // Fast-path the common case.
+ if (this->getKind() != UsingShadow &&
+ this->getKind() != ObjCCompatibleAlias)
+ return this;
+
+ return getUnderlyingDeclImpl();
+ }
const NamedDecl *getUnderlyingDecl() const {
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
@@ -317,6 +355,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
/// location of the statement. For GNU local labels (__label__), the decl
/// location is where the __label__ is.
class LabelDecl : public NamedDecl {
+ virtual void anchor();
LabelStmt *TheStmt;
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
@@ -333,14 +372,15 @@ public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II,
SourceLocation GnuLabelL);
-
+ static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
LabelStmt *getStmt() const { return TheStmt; }
void setStmt(LabelStmt *T) { TheStmt = T; }
bool isGnuLocal() const { return LocStart != getLocation(); }
void setLocStart(SourceLocation L) { LocStart = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LocStart, getLocation());
}
@@ -349,10 +389,12 @@ public:
static bool classof(const LabelDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Label; }
};
-
+
/// NamespaceDecl - Represent a C++ namespace.
-class NamespaceDecl : public NamedDecl, public DeclContext {
- bool IsInline : 1;
+class NamespaceDecl : public NamedDecl, public DeclContext,
+ public Redeclarable<NamespaceDecl>
+{
+ virtual void anchor();
/// LocStart - The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
@@ -360,41 +402,40 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
/// RBraceLoc - The ending location of the source range.
SourceLocation RBraceLoc;
- // For extended namespace definitions:
- //
- // namespace A { int x; }
- // namespace A { int y; }
- //
- // there will be one NamespaceDecl for each declaration.
- // NextNamespace points to the next extended declaration.
- // OrigNamespace points to the original namespace declaration.
- // OrigNamespace of the first namespace decl points to its anonymous namespace
- LazyDeclPtr NextNamespace;
-
- /// \brief A pointer to either the original namespace definition for
- /// this namespace (if the boolean value is false) or the anonymous
- /// namespace that lives just inside this namespace (if the boolean
- /// value is true).
- ///
- /// We can combine these two notions because the anonymous namespace
- /// must only be stored in one of the namespace declarations (so all
- /// of the namespace declarations can find it). We therefore choose
- /// the original namespace declaration, since all of the namespace
- /// declarations have a link directly to it; the original namespace
- /// declaration itself only needs to know that it is the original
- /// namespace declaration (which the boolean indicates).
- llvm::PointerIntPair<NamespaceDecl *, 1, bool> OrigOrAnonNamespace;
-
- NamespaceDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id)
- : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
- IsInline(false), LocStart(StartLoc), RBraceLoc(),
- NextNamespace(), OrigOrAnonNamespace(0, true) { }
+ /// \brief 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.
+ llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
+ NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ NamespaceDecl *PrevDecl);
+
+ typedef Redeclarable<NamespaceDecl> redeclarable_base;
+ virtual NamespaceDecl *getNextRedeclaration() {
+ return RedeclLink.getNext();
+ }
+ virtual NamespaceDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual NamespaceDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
+
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id);
+ bool Inline, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ NamespaceDecl *PrevDecl);
+
+ static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
/// \brief Returns true if this is an anonymous namespace declaration.
///
@@ -411,67 +452,60 @@ public:
/// \brief Returns true if this is an inline namespace declaration.
bool isInline() const {
- return IsInline;
+ return AnonOrFirstNamespaceAndInline.getInt();
}
/// \brief Set whether this is an inline namespace declaration.
void setInline(bool Inline) {
- IsInline = Inline;
+ AnonOrFirstNamespaceAndInline.setInt(Inline);
}
- /// \brief Return the next extended namespace declaration or null if there
- /// is none.
- NamespaceDecl *getNextNamespace();
- const NamespaceDecl *getNextNamespace() const {
- return const_cast<NamespaceDecl *>(this)->getNextNamespace();
- }
+ /// \brief Get the original (first) namespace declaration.
+ NamespaceDecl *getOriginalNamespace() {
+ if (isFirstDeclaration())
+ return this;
- /// \brief Set the next extended namespace declaration.
- void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
+ return AnonOrFirstNamespaceAndInline.getPointer();
+ }
/// \brief Get the original (first) namespace declaration.
- NamespaceDecl *getOriginalNamespace() const {
- if (OrigOrAnonNamespace.getInt())
- return const_cast<NamespaceDecl *>(this);
+ const NamespaceDecl *getOriginalNamespace() const {
+ if (isFirstDeclaration())
+ return this;
- return OrigOrAnonNamespace.getPointer();
+ return AnonOrFirstNamespaceAndInline.getPointer();
}
/// \brief 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 {
- return getOriginalNamespace() == this;
- }
-
- /// \brief Set the original (first) namespace declaration.
- void setOriginalNamespace(NamespaceDecl *ND) {
- if (ND != this) {
- OrigOrAnonNamespace.setPointer(ND);
- OrigOrAnonNamespace.setInt(false);
- }
+ return isFirstDeclaration();
}
+ /// \brief Retrieve the anonymous namespace nested inside this namespace,
+ /// if any.
NamespaceDecl *getAnonymousNamespace() const {
- return getOriginalNamespace()->OrigOrAnonNamespace.getPointer();
+ return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
}
void setAnonymousNamespace(NamespaceDecl *D) {
- assert(!D || D->isAnonymousNamespace());
- assert(!D || D->getParent()->getRedeclContext() == this);
- getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
+ getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D);
}
- virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); }
- const NamespaceDecl *getCanonicalDecl() const {
- return getOriginalNamespace();
+ /// Retrieves the canonical declaration of this namespace.
+ NamespaceDecl *getCanonicalDecl() {
+ return getOriginalNamespace();
}
-
- virtual SourceRange getSourceRange() const {
+ const NamespaceDecl *getCanonicalDecl() const {
+ return getOriginalNamespace();
+ }
+
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LocStart, RBraceLoc);
}
- SourceLocation getLocStart() const { return LocStart; }
+ SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setLocStart(SourceLocation L) { LocStart = L; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
@@ -486,7 +520,7 @@ public:
static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
}
-
+
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
@@ -495,6 +529,7 @@ public:
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
class ValueDecl : public NamedDecl {
+ virtual void anchor();
QualType DeclType;
protected:
@@ -505,6 +540,12 @@ public:
QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; }
+ /// \brief Determine whether this symbol is weakly-imported,
+ /// or declared with the weak or weak-ref attr.
+ bool isWeak() const {
+ return hasAttr<WeakAttr>() || hasAttr<WeakRefAttr>() || isWeakImported();
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ValueDecl *D) { return true; }
@@ -537,7 +578,7 @@ struct QualifierInfo {
void setTemplateParameterListsInfo(ASTContext &Context,
unsigned NumTPLists,
TemplateParameterList **TPLists);
-
+
private:
// Copy constructor and copy assignment are disabled.
QualifierInfo(const QualifierInfo&);
@@ -592,7 +633,10 @@ public:
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getOuterLocStart();
+ }
/// \brief Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
@@ -600,15 +644,15 @@ public:
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
: 0;
}
-
- /// \brief Retrieve the nested-name-specifier (with source-location
- /// information) that qualifies the name of this declaration, if it was
+
+ /// \brief 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 {
return hasExtInfo() ? getExtInfo()->QualifierLoc
: NestedNameSpecifierLoc();
}
-
+
void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
unsigned getNumTemplateParameterLists() const {
@@ -655,8 +699,9 @@ struct EvaluatedStmt {
/// integral constant expression.
bool CheckingICE : 1;
- /// \brief Whether this statement is an integral constant
- /// expression. Only valid if CheckedICE is true.
+ /// \brief 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;
Stmt *Value;
@@ -675,6 +720,13 @@ public:
/// It is illegal to call this function with SC == None.
static const char *getStorageClassSpecifierString(StorageClass SC);
+ /// \brief Initialization styles.
+ enum InitializationStyle {
+ CInit, ///< C-style initialization with assignment
+ CallInit, ///< Call-style initialization (C++98)
+ ListInit ///< Direct list-initialization (C++11)
+ };
+
protected:
/// \brief Placeholder type used in Init to denote an unparsed C++ default
/// argument.
@@ -700,14 +752,15 @@ private:
unsigned SClass : 3;
unsigned SClassAsWritten : 3;
unsigned ThreadSpecified : 1;
- unsigned HasCXXDirectInit : 1;
+ unsigned InitStyle : 2;
/// \brief 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
- /// slot of its function, enabling the named return value optimization (NRVO).
+ /// 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
@@ -721,14 +774,14 @@ private:
/// \brief Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
};
- enum { NumVarDeclBits = 13 };
+ enum { NumVarDeclBits = 14 };
friend class ASTDeclReader;
friend class StmtIteratorBase;
-
+
protected:
enum { NumParameterIndexBits = 8 };
-
+
class ParmVarDeclBitfields {
friend class ParmVarDecl;
friend class ASTDeclReader;
@@ -749,7 +802,7 @@ protected:
/// Otherwise, the number of function parameter scopes enclosing
/// the function parameter scope in which this parameter was
/// declared.
- unsigned ScopeDepthOrObjCQuals : 8;
+ unsigned ScopeDepthOrObjCQuals : 7;
/// The number of parameters preceding this parameter in the
/// function parameter scope in which it was declared.
@@ -777,22 +830,28 @@ protected:
typedef Redeclarable<VarDecl> redeclarable_base;
virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+ virtual VarDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual VarDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
- redecl_iterator redecls_begin() const {
- return redeclarable_base::redecls_begin();
- }
- redecl_iterator redecls_end() const {
- return redeclarable_base::redecls_end();
- }
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten);
- virtual SourceRange getSourceRange() const;
+ static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
StorageClass getStorageClass() const {
return (StorageClass) VarDeclBits.SClass;
@@ -823,12 +882,12 @@ public:
return getStorageClass() >= SC_Auto;
}
- /// isStaticLocal - Returns true if a variable with function scope is a
+ /// isStaticLocal - Returns true if a variable with function scope is a
/// static local variable.
bool isStaticLocal() const {
return getStorageClass() == SC_Static && !isFileVarDecl();
}
-
+
/// hasExternStorage - Returns true if a variable has extern or
/// __private_extern__ storage.
bool hasExternalStorage() const {
@@ -896,11 +955,17 @@ public:
/// \brief 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() const;
+ DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
+ DefinitionKind isThisDeclarationADefinition() const {
+ return isThisDeclarationADefinition(getASTContext());
+ }
/// \brief Check whether this variable is defined in this
/// translation unit.
- DefinitionKind hasDefinition() const;
+ 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.
@@ -914,26 +979,32 @@ public:
bool isTentativeDefinitionNow() const;
/// \brief Get the real (not just tentative) definition for this declaration.
- VarDecl *getDefinition();
+ VarDecl *getDefinition(ASTContext &);
+ const VarDecl *getDefinition(ASTContext &C) const {
+ return const_cast<VarDecl*>(this)->getDefinition(C);
+ }
+ VarDecl *getDefinition() {
+ return getDefinition(getASTContext());
+ }
const VarDecl *getDefinition() const {
return const_cast<VarDecl*>(this)->getDefinition();
}
- /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
virtual bool isOutOfLine() const;
/// \brief If this is a static data member, find its out-of-line definition.
VarDecl *getOutOfLineDefinition();
-
+
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
return false;
-
+
if (getDeclContext()->getRedeclContext()->isFileContext())
return true;
-
+
if (isStaticDataMember())
return true;
@@ -996,7 +1067,7 @@ public:
void setInit(Expr *I);
/// \brief Determine whether this variable is a reference that
- /// extends the lifetime of its temporary initializer.
+ /// extends the lifetime of its temporary initializer.
///
/// A reference extends the lifetime of its temporary initializer if
/// it's initializer is an rvalue that would normally go out of scope
@@ -1009,41 +1080,21 @@ public:
/// \endcode
bool extendsLifetimeOfTemporary() const;
- EvaluatedStmt *EnsureEvaluatedStmt() const {
- EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
- if (!Eval) {
- Stmt *S = Init.get<Stmt *>();
- Eval = new (getASTContext()) EvaluatedStmt;
- Eval->Value = S;
- Init = Eval;
- }
- return Eval;
- }
-
- /// \brief Check whether we are in the process of checking whether the
- /// initializer can be evaluated.
- bool isEvaluatingValue() const {
- if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
- return Eval->IsEvaluating;
-
- return false;
- }
+ /// \brief 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.
+ bool isUsableInConstantExpressions(ASTContext &C) const;
- /// \brief Note that we now are checking whether the initializer can be
- /// evaluated.
- void setEvaluatingValue() const {
- EvaluatedStmt *Eval = EnsureEvaluatedStmt();
- Eval->IsEvaluating = true;
- }
+ EvaluatedStmt *ensureEvaluatedStmt() const;
- /// \brief Note that constant evaluation has computed the given
- /// value for this variable's initializer.
- void setEvaluatedValue(const APValue &Value) const {
- EvaluatedStmt *Eval = EnsureEvaluatedStmt();
- Eval->IsEvaluating = false;
- Eval->WasEvaluated = true;
- Eval->Evaluated = Value;
- }
+ /// \brief 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(
+ llvm::SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
/// \brief Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
@@ -1065,8 +1116,9 @@ public:
return false;
}
- /// \brief Determines whether the initializer is an integral
- /// constant expression.
+ /// \brief 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 {
@@ -1075,41 +1127,31 @@ public:
return Init.get<EvaluatedStmt *>()->IsICE;
}
- /// \brief Check whether we are in the process of checking the initializer
- /// is an integral constant expression.
- bool isCheckingICE() const {
- if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
- return Eval->CheckingICE;
-
- return false;
- }
+ /// \brief Determine whether the value of the initializer attached to this
+ /// declaration is an integral constant expression.
+ bool checkInitIsICE() const;
- /// \brief Note that we now are checking whether the initializer is an
- /// integral constant expression.
- void setCheckingICE() const {
- EvaluatedStmt *Eval = EnsureEvaluatedStmt();
- Eval->CheckingICE = true;
+ void setInitStyle(InitializationStyle Style) {
+ VarDeclBits.InitStyle = Style;
}
- /// \brief Note that we now know whether the initializer is an
- /// integral constant expression.
- void setInitKnownICE(bool IsICE) const {
- EvaluatedStmt *Eval = EnsureEvaluatedStmt();
- Eval->CheckingICE = false;
- Eval->CheckedICE = true;
- Eval->IsICE = IsICE;
+ /// \brief 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
+ /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
+ /// expression for class types. List-style initialization is C++11 syntax,
+ /// e.g. "int x{1};". Clients can distinguish between different forms of
+ /// initialization by checking this value. In particular, "int x = {1};" is
+ /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
+ /// Init expression in all three cases is an InitListExpr.
+ InitializationStyle getInitStyle() const {
+ return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
}
- void setCXXDirectInitializer(bool T) { VarDeclBits.HasCXXDirectInit = T; }
-
- /// hasCXXDirectInitializer - If true, the initializer was a direct
- /// initializer, e.g: "int x(1);". The Init expression will be the expression
- /// inside the parens or a "ClassType(a,b,c)" class constructor expression for
- /// class types. Clients can distinguish between "int x(1);" and "int x=1;"
- /// by checking hasCXXDirectInitializer.
- ///
- bool hasCXXDirectInitializer() const {
- return VarDeclBits.HasCXXDirectInit;
+ /// \brief Whether the initializer is a direct-initializer (list or call).
+ bool isDirectInit() const {
+ return getInitStyle() != CInit;
}
/// \brief Determine whether this variable is the exception variable in a
@@ -1118,7 +1160,7 @@ public:
return VarDeclBits.ExceptionVar;
}
void setExceptionVariable(bool EV) { VarDeclBits.ExceptionVar = EV; }
-
+
/// \brief Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
///
@@ -1143,7 +1185,7 @@ public:
/// Generally such variables are also 'const' for safety.
bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; }
-
+
/// Whether this variable is (C++0x) constexpr.
bool isConstexpr() const { return VarDeclBits.IsConstexpr; }
void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; }
@@ -1153,15 +1195,15 @@ public:
/// from which it was instantiated.
VarDecl *getInstantiatedFromStaticDataMember() const;
- /// \brief If this variable is a static data member, determine what kind of
+ /// \brief If this variable is a static data member, determine what kind of
/// template specialization or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
-
+
/// \brief 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
/// data member of a class template, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
@@ -1174,11 +1216,14 @@ public:
};
class ImplicitParamDecl : public VarDecl {
+ virtual void anchor();
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T);
+ static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
IdentifierInfo *Id, QualType Type)
: VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
@@ -1218,8 +1263,10 @@ public:
StorageClass S, StorageClass SCAsWritten,
Expr *DefArg);
- virtual SourceRange getSourceRange() const;
+ static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
+
void setObjCMethodScopeInfo(unsigned parameterIndex) {
ParmVarDeclBits.IsObjCMethodParam = true;
setParameterIndex(parameterIndex);
@@ -1229,7 +1276,8 @@ public:
assert(!ParmVarDeclBits.IsObjCMethodParam);
ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
- assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!");
+ assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth
+ && "truncation!");
setParameterIndex(parameterIndex);
}
@@ -1276,20 +1324,14 @@ public:
const Expr *getDefaultArg() const {
return const_cast<ParmVarDecl *>(this)->getDefaultArg();
}
-
+
void setDefaultArg(Expr *defarg) {
Init = reinterpret_cast<Stmt *>(defarg);
}
- unsigned getNumDefaultArgTemporaries() const;
- CXXTemporary *getDefaultArgTemporary(unsigned i);
- const CXXTemporary *getDefaultArgTemporary(unsigned i) const {
- return const_cast<ParmVarDecl *>(this)->getDefaultArgTemporary(i);
- }
-
/// \brief Retrieve the source range that covers the entire default
/// argument.
- SourceRange getDefaultArgRange() const;
+ SourceRange getDefaultArgRange() const;
void setUninstantiatedDefaultArg(Expr *arg) {
Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg);
}
@@ -1351,7 +1393,7 @@ public:
/// \brief Determine whether this parameter is actually a function
/// parameter pack.
bool isParameterPack() const;
-
+
/// setOwningFunction - 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
@@ -1362,7 +1404,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ParmVarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ParmVar; }
-
+
private:
enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
@@ -1371,7 +1413,7 @@ private:
setParameterIndexLarge(parameterIndex);
return;
}
-
+
ParmVarDeclBits.ParameterIndex = parameterIndex;
assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
}
@@ -1379,7 +1421,7 @@ private:
unsigned d = ParmVarDeclBits.ParameterIndex;
return d == ParameterIndexSentinel ? getParameterIndexLarge() : d;
}
-
+
void setParameterIndexLarge(unsigned parameterIndex);
unsigned getParameterIndexLarge() const;
};
@@ -1394,7 +1436,7 @@ private:
/// FunctionDecl (e.g., the translation unit); this FunctionDecl
/// contains all of the information known about the function. Other,
/// previous declarations of the function are available via the
-/// getPreviousDeclaration() chain.
+/// getPreviousDecl() chain.
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
@@ -1415,6 +1457,11 @@ private:
/// no formals.
ParmVarDecl **ParamInfo;
+ /// DeclsInPrototypeScope - Array of pointers to NamedDecls for
+ /// decls defined in the function prototype that are not parameters. E.g.
+ /// 'enum Y' in 'void f(enum Y {AA} x) {}'.
+ llvm::ArrayRef<NamedDecl*> DeclsInPrototypeScope;
+
LazyDeclStmtPtr Body;
// FIXME: This can be packed into the bitfields in Decl.
@@ -1456,7 +1503,7 @@ private:
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
- llvm::PointerUnion4<FunctionTemplateDecl *,
+ llvm::PointerUnion4<FunctionTemplateDecl *,
MemberSpecializationInfo *,
FunctionTemplateSpecializationInfo *,
DependentFunctionTemplateSpecializationInfo *>
@@ -1486,7 +1533,7 @@ private:
/// \param TemplateArgsAsWritten location info of template arguments.
///
/// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
+ /// specialization was first instantiated.
void setFunctionTemplateSpecialization(ASTContext &C,
FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
@@ -1524,15 +1571,19 @@ protected:
typedef Redeclarable<FunctionDecl> redeclarable_base;
virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+ virtual FunctionDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual FunctionDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
- redecl_iterator redecls_begin() const {
- return redeclarable_base::redecls_begin();
- }
- redecl_iterator redecls_end() const {
- return redeclarable_base::redecls_end();
- }
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation NLoc,
@@ -1560,6 +1611,8 @@ public:
bool hasWrittenPrototype = true,
bool isConstexprSpecified = false);
+ static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
@@ -1570,7 +1623,7 @@ public:
void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const 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
@@ -1656,7 +1709,7 @@ public:
void setTrivial(bool IT) { IsTrivial = IT; }
/// Whether this function is defaulted per C++0x. Only valid for
- /// special member functions.
+ /// special member functions.
bool isDefaulted() const { return IsDefaulted; }
void setDefaulted(bool D = true) { IsDefaulted = D; }
@@ -1774,6 +1827,11 @@ public:
setParams(getASTContext(), NewParamInfo);
}
+ const llvm::ArrayRef<NamedDecl*> &getDeclsInPrototypeScope() const {
+ return DeclsInPrototypeScope;
+ }
+ void setDeclsInPrototypeScope(llvm::ArrayRef<NamedDecl *> NewDecls);
+
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
/// function parameters, if some of the parameters have default
@@ -1783,12 +1841,12 @@ public:
QualType getResultType() const {
return getType()->getAs<FunctionType>()->getResultType();
}
-
+
/// \brief Determine the type of an expression that calls this function.
QualType getCallResultType() const {
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
}
-
+
StorageClass getStorageClass() const { return StorageClass(SClass); }
void setStorageClass(StorageClass SC);
@@ -1799,10 +1857,10 @@ public:
/// \brief Determine whether the "inline" keyword was specified for this
/// function.
bool isInlineSpecified() const { return IsInlineSpecified; }
-
+
/// Set whether the "inline" keyword was specified for this function.
- void setInlineSpecified(bool I) {
- IsInlineSpecified = I;
+ void setInlineSpecified(bool I) {
+ IsInlineSpecified = I;
IsInline = I;
}
@@ -1819,7 +1877,7 @@ public:
bool isInlineDefinitionExternallyVisible() const;
bool doesDeclarationForceExternallyVisibleDefinition() const;
-
+
/// isOverloadedOperator - Whether this function declaration
/// represents an C++ overloaded operator, e.g., "operator+".
bool isOverloadedOperator() const {
@@ -1852,7 +1910,7 @@ public:
/// X<int>::A is required, it will be instantiated from the
/// declaration returned by getInstantiatedFromMemberFunction().
FunctionDecl *getInstantiatedFromMemberFunction() const;
-
+
/// \brief What kind of templated function this is.
TemplatedKind getTemplatedKind() const;
@@ -1860,7 +1918,7 @@ public:
/// class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const;
-
+
/// \brief Specify that this record is an instantiation of the
/// member function FD.
void setInstantiationOfMemberFunction(FunctionDecl *FD,
@@ -1888,7 +1946,7 @@ public:
TemplateOrSpecialization = Template;
}
- /// \brief Determine whether this function is a function template
+ /// \brief Determine whether this function is a function template
/// specialization.
bool isFunctionTemplateSpecialization() const {
return getPrimaryTemplate() != 0;
@@ -1899,7 +1957,7 @@ public:
FunctionDecl *getClassScopeSpecializationPattern() const;
/// \brief If this function is actually a function template specialization,
- /// retrieve information about this function template specialization.
+ /// retrieve information about this function template specialization.
/// Otherwise, returns NULL.
FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const {
return TemplateOrSpecialization.
@@ -1910,7 +1968,11 @@ public:
/// 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
+ /// function template.
+ bool isTemplateInstantiation() const;
+
/// \brief 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).
@@ -1958,7 +2020,7 @@ public:
/// \param TemplateArgsAsWritten location info of template arguments.
///
/// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
+ /// specialization was first instantiated.
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
@@ -1994,15 +2056,21 @@ public:
/// \brief 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
- /// instantiated from a template; otherwise, returns an invalid source
+ /// \returns the first point of instantiation, if this function was
+ /// instantiated from a template; otherwise, returns an invalid source
/// location.
SourceLocation getPointOfInstantiation() const;
-
- /// \brief Determine whether this is or was instantiated from an out-of-line
+
+ /// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
virtual bool isOutOfLine() const;
-
+
+ /// \brief 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;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionDecl *D) { return true; }
@@ -2056,6 +2124,8 @@ public:
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
bool HasInit);
+ static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
/// getFieldIndex - Returns the index of this field within its record,
/// as appropriate for passing to ASTRecordLayout::getFieldOffset.
unsigned getFieldIndex() const;
@@ -2108,7 +2178,8 @@ public:
Expr *getInClassInitializer() const {
return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0;
}
- /// setInClassInitializer - Set the C++0x in-class initializer for this member.
+ /// setInClassInitializer - Set the C++0x in-class initializer for this
+ /// member.
void setInClassInitializer(Expr *Init);
/// removeInClassInitializer - Remove the C++0x in-class initializer from this
/// member.
@@ -2128,7 +2199,7 @@ public:
return cast<RecordDecl>(getDeclContext());
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2155,7 +2226,8 @@ public:
SourceLocation L, IdentifierInfo *Id,
QualType T, Expr *E,
const llvm::APSInt &V);
-
+ static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
const Expr *getInitExpr() const { return (const Expr*) Init; }
Expr *getInitExpr() { return (Expr*) Init; }
const llvm::APSInt &getInitVal() const { return Val; }
@@ -2163,8 +2235,8 @@ public:
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
void setInitVal(const llvm::APSInt &V) { Val = V; }
- SourceRange getSourceRange() const;
-
+ SourceRange getSourceRange() const LLVM_READONLY;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumConstantDecl *D) { return true; }
@@ -2177,6 +2249,7 @@ public:
/// field injected from an anonymous union/struct into the parent scope.
/// IndirectFieldDecl are always implicit.
class IndirectFieldDecl : public ValueDecl {
+ virtual void anchor();
NamedDecl **Chaining;
unsigned ChainingSize;
@@ -2189,6 +2262,8 @@ public:
static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, NamedDecl **CH, unsigned CHS);
+
+ static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
typedef NamedDecl * const *chain_iterator;
chain_iterator chain_begin() const { return Chaining; }
@@ -2216,6 +2291,7 @@ public:
/// TypeDecl - Represents a declaration of a type.
///
class TypeDecl : public NamedDecl {
+ virtual void anchor();
/// TypeForDecl - This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
@@ -2228,6 +2304,7 @@ class TypeDecl : public NamedDecl {
friend class TagDecl;
friend class TemplateTypeParmDecl;
friend class TagType;
+ friend class ASTReader;
protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
@@ -2239,9 +2316,9 @@ public:
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
- SourceLocation getLocStart() const { return LocStart; }
+ SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
if (LocStart.isValid())
return SourceRange(LocStart, getLocation());
else
@@ -2257,6 +2334,7 @@ public:
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
+ virtual void anchor();
/// UnderlyingType - This is the type the typedef is set to.
TypeSourceInfo *TInfo;
@@ -2270,15 +2348,19 @@ protected:
virtual TypedefNameDecl *getNextRedeclaration() {
return RedeclLink.getNext();
}
+ virtual TypedefNameDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual TypedefNameDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
- redecl_iterator redecls_begin() const {
- return redeclarable_base::redecls_begin();
- }
- redecl_iterator redecls_end() const {
- return redeclarable_base::redecls_end();
- }
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
TypeSourceInfo *getTypeSourceInfo() const {
return TInfo;
@@ -2318,8 +2400,9 @@ public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
-
- SourceRange getSourceRange() const;
+ static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2338,8 +2421,9 @@ public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
+ static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2364,15 +2448,17 @@ private:
/// a definition until the definition has been fully processed.
bool IsCompleteDefinition : 1;
+protected:
/// IsBeingDefined - True if this is currently being defined.
bool 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.
bool IsEmbeddedInDeclarator : 1;
- /// /brief True if this tag is free standing, e.g. "struct foo;".
+ /// \brief True if this tag is free standing, e.g. "struct foo;".
bool IsFreeStanding : 1;
protected:
@@ -2381,7 +2467,7 @@ protected:
unsigned NumNegativeBits : 8;
/// IsScoped - True if this tag declaration is a scoped enumeration. Only
- /// possible in C++0x mode.
+ /// possible in C++11 mode.
bool IsScoped : 1;
/// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
/// then this is true if the scoped enum was declared using the class
@@ -2390,7 +2476,7 @@ protected:
bool IsScopedUsingClassTag : 1;
/// IsFixed - True if this is an enumeration with fixed underlying type. Only
- /// possible in C++0x mode.
+ /// possible in C++11 or Microsoft extensions mode.
bool IsFixed : 1;
private:
@@ -2431,20 +2517,24 @@ protected:
typedef Redeclarable<TagDecl> redeclarable_base;
virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+ virtual TagDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual TagDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
/// @brief Completes the definition of this tag declaration.
///
/// This is a helper function for derived classes.
- void completeDefinition();
-
+ void completeDefinition();
+
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
- redecl_iterator redecls_begin() const {
- return redeclarable_base::redecls_begin();
- }
- redecl_iterator redecls_end() const {
- return redeclarable_base::redecls_end();
- }
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
@@ -2456,7 +2546,7 @@ public:
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
virtual TagDecl* getCanonicalDecl();
const TagDecl* getCanonicalDecl() const {
@@ -2532,7 +2622,8 @@ public:
bool isEnum() const { return getTagKind() == TTK_Enum; }
TypedefNameDecl *getTypedefNameForAnonDecl() const {
- return hasExtInfo() ? 0 : TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
+ return hasExtInfo() ? 0 :
+ TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
}
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
@@ -2543,15 +2634,15 @@ public:
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
: 0;
}
-
- /// \brief Retrieve the nested-name-specifier (with source-location
- /// information) that qualifies the name of this declaration, if it was
+
+ /// \brief 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 {
return hasExtInfo() ? getExtInfo()->QualifierLoc
: NestedNameSpecifierLoc();
}
-
+
void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
unsigned getNumTemplateParameterLists() const {
@@ -2580,9 +2671,11 @@ public:
friend class ASTDeclWriter;
};
-/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
-/// enums.
+/// EnumDecl - 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 {
+ virtual void anchor();
/// IntegerType - 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.
@@ -2606,23 +2699,16 @@ class EnumDecl : public TagDecl {
/// in C++) are of the enum type instead.
QualType PromotionType;
- /// \brief If the enumeration was instantiated from an enumeration
- /// within a class or function template, this pointer refers to the
- /// enumeration declared within the template.
- EnumDecl *InstantiatedFrom;
-
- // The number of positive and negative bits required by the
- // enumerators are stored in the SubclassBits field.
- enum {
- NumBitsWidth = 8,
- NumBitsMask = (1 << NumBitsWidth) - 1
- };
+ /// \brief If this enumeration is an instantiation of a member enumeration
+ /// of a class template specialization, this is the member specialization
+ /// information.
+ MemberSpecializationInfo *SpecializationInfo;
EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
: TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
- InstantiatedFrom(0) {
+ SpecializationInfo(0) {
assert(Scoped || !ScopedUsingClassTag);
IntegerType = (const Type*)0;
NumNegativeBits = 0;
@@ -2631,6 +2717,9 @@ class EnumDecl : public TagDecl {
IsScopedUsingClassTag = ScopedUsingClassTag;
IsFixed = Fixed;
}
+
+ void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
+ TemplateSpecializationKind TSK);
public:
EnumDecl *getCanonicalDecl() {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
@@ -2639,11 +2728,22 @@ public:
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
- const EnumDecl *getPreviousDeclaration() const {
- return cast_or_null<EnumDecl>(TagDecl::getPreviousDeclaration());
+ const EnumDecl *getPreviousDecl() const {
+ return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl());
}
- EnumDecl *getPreviousDeclaration() {
- return cast_or_null<EnumDecl>(TagDecl::getPreviousDeclaration());
+ EnumDecl *getPreviousDecl() {
+ return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl());
+ }
+
+ const EnumDecl *getMostRecentDecl() const {
+ return cast<EnumDecl>(TagDecl::getMostRecentDecl());
+ }
+ EnumDecl *getMostRecentDecl() {
+ return cast<EnumDecl>(TagDecl::getMostRecentDecl());
+ }
+
+ EnumDecl *getDefinition() const {
+ return cast_or_null<EnumDecl>(TagDecl::getDefinition());
}
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2651,7 +2751,7 @@ public:
IdentifierInfo *Id, EnumDecl *PrevDecl,
bool IsScoped, bool IsScopedUsingClassTag,
bool IsFixed);
- static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
+ static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// completeDefinition - When created, the EnumDecl corresponds to a
/// forward-declared enum. This method is used to mark the
@@ -2668,14 +2768,14 @@ public:
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
enumerator_iterator enumerator_begin() const {
- const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+ const EnumDecl *E = getDefinition();
if (!E)
E = this;
return enumerator_iterator(E->decls_begin());
}
enumerator_iterator enumerator_end() const {
- const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+ const EnumDecl *E = getDefinition();
if (!E)
E = this;
return enumerator_iterator(E->decls_end());
@@ -2723,7 +2823,7 @@ public:
/// \brief Returns the width in bits required to store all the
/// negative enumerators of this enum. These widths include
/// the rightmost leading 1; that is:
- ///
+ ///
/// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS
/// ------------------------ ------- -----------------
/// -1 1111111 1
@@ -2760,11 +2860,31 @@ public:
/// \brief 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 {
- return InstantiatedFrom;
+ EnumDecl *getInstantiatedFromMemberEnum() const;
+
+ /// \brief 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
+ /// 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
+ /// a class template specialization, retrieves the member specialization
+ /// information.
+ MemberSpecializationInfo *getMemberSpecializationInfo() const {
+ return SpecializationInfo;
}
- void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
+ /// \brief Specify that this enumeration is an instantiation of the
+ /// member enumeration ED.
+ void setInstantiationOfMemberEnum(EnumDecl *ED,
+ TemplateSpecializationKind TSK) {
+ setInstantiationOfMemberEnum(getASTContext(), ED, TSK);
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumDecl *D) { return true; }
@@ -2791,7 +2911,7 @@ class RecordDecl : public TagDecl {
bool AnonymousStructOrUnion : 1;
/// HasObjectMember - This is true if this struct has at least one member
- /// containing an object.
+ /// containing an Objective-C object pointer type.
bool HasObjectMember : 1;
/// \brief Whether the field declarations of this record have been loaded
@@ -2810,13 +2930,20 @@ public:
static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
- static RecordDecl *Create(const ASTContext &C, EmptyShell Empty);
+ static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
- const RecordDecl *getPreviousDeclaration() const {
- return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
+ const RecordDecl *getPreviousDecl() const {
+ return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl());
}
- RecordDecl *getPreviousDeclaration() {
- return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
+ RecordDecl *getPreviousDecl() {
+ return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl());
+ }
+
+ const RecordDecl *getMostRecentDecl() const {
+ return cast<RecordDecl>(TagDecl::getMostRecentDecl());
+ }
+ RecordDecl *getMostRecentDecl() {
+ return cast<RecordDecl>(TagDecl::getMostRecentDecl());
}
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
@@ -2902,6 +3029,7 @@ private:
};
class FileScopeAsmDecl : public Decl {
+ virtual void anchor();
StringLiteral *AsmString;
SourceLocation RParenLoc;
FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
@@ -2912,10 +3040,12 @@ public:
StringLiteral *Str, SourceLocation AsmLoc,
SourceLocation RParenLoc);
+ static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
SourceLocation getAsmLoc() const { return getLocation(); }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getAsmLoc(), getRParenLoc());
}
@@ -2976,6 +3106,8 @@ private:
// FIXME: This can be packed into the bitfields in Decl.
bool IsVariadic : 1;
bool CapturesCXXThis : 1;
+ bool BlockMissingReturnType : 1;
+ bool IsConversionFromLambda : 1;
/// ParamInfo - 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.
@@ -2992,12 +3124,14 @@ protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
: Decl(Block, DC, CaretLoc), DeclContext(Block),
IsVariadic(false), CapturesCXXThis(false),
+ BlockMissingReturnType(true), IsConversionFromLambda(false),
ParamInfo(0), NumParams(0), Body(0),
SignatureAsWritten(0), Captures(0), NumCaptures(0) {}
public:
- static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
-
+ static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
+ static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
SourceLocation getCaretLocation() const { return getLocation(); }
bool isVariadic() const { return IsVariadic; }
@@ -3049,6 +3183,11 @@ public:
capture_const_iterator capture_end() const { return Captures + NumCaptures; }
bool capturesCXXThis() const { return CapturesCXXThis; }
+ bool blockMissingReturnType() const { return BlockMissingReturnType; }
+ void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; }
+
+ bool isConversionFromLambda() const { return IsConversionFromLambda; }
+ void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
bool capturesVariable(const VarDecl *var) const;
@@ -3057,8 +3196,8 @@ public:
const Capture *end,
bool capturesCXXThis);
- virtual SourceRange getSourceRange() const;
-
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const BlockDecl *D) { return true; }
@@ -3071,6 +3210,75 @@ public:
}
};
+/// \brief 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:
+/// \code
+/// @__experimental_modules_import std.vector;
+/// \endcode
+///
+/// Import declarations can also be implicitly generated from #include/#import
+/// directives.
+class ImportDecl : public Decl {
+ /// \brief The imported module, along with a bit that indicates whether
+ /// we have source-location information for each identifier in the module
+ /// name.
+ ///
+ /// When the bit is false, we only have a single source location for the
+ /// end of the import declaration.
+ llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
+
+ /// \brief The next import in the list of imports local to the translation
+ /// unit being parsed (not loaded from an AST file).
+ ImportDecl *NextLocalImport;
+
+ friend class ASTReader;
+ friend class ASTDeclReader;
+ friend class ASTContext;
+
+ ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
+ ArrayRef<SourceLocation> IdentifierLocs);
+
+ ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
+ SourceLocation EndLoc);
+
+ ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { }
+
+public:
+ /// \brief 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
+ /// import.
+ static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, Module *Imported,
+ SourceLocation EndLoc);
+
+ /// \brief 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.
+ Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
+
+ /// \brief 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
+ /// identifiers aren't available.
+ ArrayRef<SourceLocation> getIdentifierLocs() const;
+
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ImportDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Import; }
+};
+
+
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -3079,6 +3287,12 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
DiagnosticsEngine::ak_nameddecl);
return DB;
}
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const NamedDecl* ND) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+ DiagnosticsEngine::ak_nameddecl);
+ return PD;
+}
template<typename decl_type>
void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
@@ -3086,26 +3300,44 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
// and Redeclarable to be defined.
decl_type *First;
-
+
if (PrevDecl) {
// Point to previous. Make sure that this is actually the most recent
// redeclaration, or we can build invalid chains. If the most recent
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
- RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
- PrevDecl->getMostRecentDeclaration()));
+ RedeclLink = PreviousDeclLink(
+ llvm::cast<decl_type>(PrevDecl->getMostRecentDecl()));
First = PrevDecl->getFirstDeclaration();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
} else {
// Make this first.
First = static_cast<decl_type*>(this);
}
-
+
// First one will point to this one as latest.
First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this)))
ND->ClearLinkageCache();
}
+// Inline function definitions.
+
+/// \brief 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.
+inline bool IsEnumDeclComplete(EnumDecl *ED) {
+ return ED->isComplete();
+}
+
+/// \brief 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.
+inline bool IsEnumDeclScoped(EnumDecl *ED) {
+ return ED->isScoped();
+}
+
} // end namespace clang
#endif
OpenPOWER on IntegriCloud