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.h162
1 files changed, 132 insertions, 30 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ce8b8b7..a39888f 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -43,6 +43,7 @@ class Stmt;
class StringLiteral;
class TemplateArgumentList;
class TemplateParameterList;
+class TypeAliasTemplateDecl;
class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
@@ -67,6 +68,9 @@ public:
/// \brief 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!
+ void overrideType(QualType T) { Ty = T; }
};
/// TranslationUnitDecl - The top declaration context.
@@ -288,6 +292,8 @@ public:
return const_cast<NamedDecl*>(this)->getMostRecentDecl();
}
+ ObjCStringFormatFamily getObjCFStringFormattingFamily() const;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
};
@@ -305,6 +311,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
class LabelDecl : public NamedDecl {
void anchor() override;
LabelStmt *TheStmt;
+ StringRef MSAsmName;
+ bool MSAsmNameResolved;
/// LocStart - 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.
@@ -312,7 +320,10 @@ class LabelDecl : public NamedDecl {
LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
LabelStmt *S, SourceLocation StartL)
- : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
+ : NamedDecl(Label, DC, IdentL, II),
+ TheStmt(S),
+ MSAsmNameResolved(false),
+ LocStart(StartL) {}
public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
@@ -332,6 +343,12 @@ public:
return SourceRange(LocStart, getLocation());
}
+ bool isMSAsmLabel() const { return MSAsmName.size() != 0; }
+ bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
+ void setMSAsmLabel(StringRef Name);
+ StringRef getMSAsmLabel() const { return MSAsmName; }
+ void setMSAsmLabelResolved() { MSAsmNameResolved = true; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Label; }
@@ -648,8 +665,6 @@ struct EvaluatedStmt {
/// declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- typedef clang::StorageClass StorageClass;
-
/// getStorageClassSpecifierString - Return the string used to
/// specify the storage class \p SC.
///
@@ -891,6 +906,11 @@ public:
return false;
}
+ /// \brief 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.
bool isFunctionOrMethodVarDecl() const {
@@ -1423,8 +1443,6 @@ private:
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
- typedef clang::StorageClass StorageClass;
-
/// \brief The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
TK_NonTemplate,
@@ -1650,7 +1668,7 @@ public:
/// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
- Stmt *getBody() const override {
+ Stmt *getBody() const override {
const FunctionDecl* Definition;
return getBody(Definition);
}
@@ -1880,7 +1898,7 @@ public:
return llvm::makeArrayRef(ParamInfo, getNumParams());
}
- const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
+ ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
@@ -2154,17 +2172,41 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
bool Mutable : 1;
mutable unsigned CachedFieldIndex : 31;
- /// \brief An InClassInitStyle value, and either a bit width expression (if
- /// the InClassInitStyle value is ICIS_NoInit), or a pointer to the in-class
- /// initializer for this field (otherwise).
+ /// The kinds of value we can store in InitializerOrBitWidth.
///
- /// We can safely combine these two because in-class initializers are not
- /// permitted for bit-fields.
+ /// Note that this is compatible with InClassInitStyle except for
+ /// ISK_CapturedVLAType.
+ enum InitStorageKind {
+ /// If the pointer is null, there's nothing special. Otherwise,
+ /// this is a bitfield and the pointer is the Expr* storing the
+ /// bit-width.
+ ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit,
+
+ /// The pointer is an (optional due to delayed parsing) Expr*
+ /// holding the copy-initializer.
+ ISK_InClassCopyInit = (unsigned) ICIS_CopyInit,
+
+ /// The pointer is an (optional due to delayed parsing) Expr*
+ /// holding the list-initializer.
+ ISK_InClassListInit = (unsigned) ICIS_ListInit,
+
+ /// The pointer is a VariableArrayType* that's been captured;
+ /// the enclosing context is a lambda or captured statement.
+ ISK_CapturedVLAType,
+ };
+
+ /// \brief Storage for either the bit-width, the in-class
+ /// initializer, or the captured variable length array bound.
+ ///
+ /// We can safely combine these because in-class initializers are
+ /// not permitted for bit-fields, and both are exclusive with VLA
+ /// captures.
///
- /// If the InClassInitStyle is not ICIS_NoInit and the initializer is null,
- /// then this field has an in-class initializer which has not yet been parsed
+ /// If the storage kind is ISK_InClassCopyInit or
+ /// ISK_InClassListInit, but the initializer is null, then this
+ /// field has an in-class initializer which has not yet been parsed
/// and attached.
- llvm::PointerIntPair<Expr *, 2, unsigned> InitializerOrBitWidth;
+ llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -2172,7 +2214,7 @@ protected:
InClassInitStyle InitStyle)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0),
- InitializerOrBitWidth(BW, InitStyle) {
+ InitStorage(BW, (InitStorageKind) InitStyle) {
assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
}
@@ -2192,10 +2234,10 @@ public:
/// isMutable - Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
- /// isBitfield - Determines whether this field is a bitfield.
+ /// \brief Determines whether this field is a bitfield.
bool isBitField() const {
- return getInClassInitStyle() == ICIS_NoInit &&
- InitializerOrBitWidth.getPointer();
+ return InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ InitStorage.getPointer() != nullptr;
}
/// @brief Determines whether this is an unnamed bitfield.
@@ -2208,24 +2250,34 @@ public:
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const {
- return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
+ return isBitField()
+ ? static_cast<Expr *>(InitStorage.getPointer())
+ : nullptr;
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
/// setBitWidth - Set the bit-field width for this member.
// Note: used by some clients (i.e., do not remove it).
- void setBitWidth(Expr *Width);
+ void setBitWidth(Expr *Width) {
+ assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ InitStorage.getPointer() == nullptr &&
+ "bit width, initializer or captured type already set");
+ InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing);
+ }
+
/// removeBitWidth - 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");
- InitializerOrBitWidth.setPointer(nullptr);
+ InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
}
/// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
/// this field has.
InClassInitStyle getInClassInitStyle() const {
- return static_cast<InClassInitStyle>(InitializerOrBitWidth.getInt());
+ InitStorageKind storageKind = InitStorage.getInt();
+ return (storageKind == ISK_CapturedVLAType
+ ? ICIS_NoInit : (InClassInitStyle) storageKind);
}
/// hasInClassInitializer - Determine whether this member has a C++11 in-class
@@ -2233,24 +2285,47 @@ public:
bool hasInClassInitializer() const {
return getInClassInitStyle() != ICIS_NoInit;
}
+
/// getInClassInitializer - Get the C++11 in-class initializer for this
/// member, or null if one has not been set. If a valid declaration has an
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
- return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
- : nullptr;
+ return hasInClassInitializer()
+ ? static_cast<Expr *>(InitStorage.getPointer())
+ : nullptr;
}
+
/// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
- void setInClassInitializer(Expr *Init);
+ void setInClassInitializer(Expr *Init) {
+ assert(hasInClassInitializer() &&
+ InitStorage.getPointer() == nullptr &&
+ "bit width, initializer or captured type already set");
+ InitStorage.setPointer(Init);
+ }
+
/// removeInClassInitializer - Remove the C++11 in-class initializer from this
/// member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitializerOrBitWidth.setPointer(nullptr);
- InitializerOrBitWidth.setInt(ICIS_NoInit);
+ InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
+ }
+
+ /// \brief 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.
+ const VariableArrayType *getCapturedVLAType() const {
+ return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
+ InitStorage.getPointer())
+ : nullptr;
}
+ /// \brief Set the captured variable length array type for this field.
+ void setCapturedVLAType(const VariableArrayType *VLAType);
/// getParent - Returns the parent of this field declaration, which
/// is the struct in which this method is defined.
@@ -2492,9 +2567,13 @@ public:
/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
+ /// The template for which this is the pattern, if any.
+ TypeAliasTemplateDecl *Template;
+
TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
+ : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
+ Template(nullptr) {}
public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2504,6 +2583,9 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; }
+ void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TypeAlias; }
@@ -2647,7 +2729,7 @@ public:
}
/// isThisDeclarationADefinition() - Return true if this declaration
- /// is a completion definintion of the type. Provided for consistency.
+ /// is a completion definition of the type. Provided for consistency.
bool isThisDeclarationADefinition() const {
return isCompleteDefinition();
}
@@ -3136,6 +3218,17 @@ public:
/// \endcode
bool isInjectedClassName() const;
+ /// \brief 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
+ /// CapturedStmt construct.
+ bool isCapturedRecord() const;
+ /// \brief Mark the record as a record for captured variables in CapturedStmt
+ /// construct.
+ void setCapturedRecord();
+
/// getDefinition - 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
@@ -3181,6 +3274,15 @@ public:
/// commandline option.
bool isMsStruct(const ASTContext &C) const;
+ /// \brief 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;
+
+ /// Finds the first data member which has a name.
+ /// nullptr is returned if no named data member exists.
+ const FieldDecl *findFirstNamedDataMember() const;
+
private:
/// \brief Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
OpenPOWER on IntegriCloud