summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
committerdim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
commitea266cad53e3d49771fa38103913d3ec7a166694 (patch)
tree8f7776b7310bebaf415ac5b69e46e9f928c37144 /include/clang/AST
parentc72c57c9e9b69944e3e009cd5e209634839581d3 (diff)
downloadFreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip
FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release): http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h27
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h15
-rw-r--r--include/clang/AST/CommentCommands.td16
-rw-r--r--include/clang/AST/CommentLexer.h10
-rw-r--r--include/clang/AST/Decl.h122
-rw-r--r--include/clang/AST/DeclBase.h33
-rw-r--r--include/clang/AST/DeclCXX.h101
-rw-r--r--include/clang/AST/DeclFriend.h2
-rw-r--r--include/clang/AST/DeclObjC.h19
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h11
-rw-r--r--include/clang/AST/Expr.h20
-rw-r--r--include/clang/AST/ExprCXX.h106
-rw-r--r--include/clang/AST/ExprObjC.h3
-rw-r--r--include/clang/AST/Mangle.h10
-rw-r--r--include/clang/AST/RawCommentList.h20
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h30
-rw-r--r--include/clang/AST/Stmt.h287
-rw-r--r--include/clang/AST/Type.h76
-rw-r--r--include/clang/AST/TypeNodes.def2
19 files changed, 768 insertions, 142 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index d4878a9..c5d3337 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -867,6 +867,9 @@ public:
const FunctionType *adjustFunctionType(const FunctionType *Fn,
FunctionType::ExtInfo EInfo);
+ /// \brief Change the result type of a function type once it is deduced.
+ void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
+
/// \brief Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T) const;
@@ -1100,7 +1103,8 @@ public:
UnaryTransformType::UTTKind UKind) const;
/// \brief C++11 deduced auto type.
- QualType getAutoType(QualType DeducedType) const;
+ QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto,
+ bool IsDependent = false) const;
/// \brief C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
@@ -1451,7 +1455,18 @@ public:
qs.addObjCLifetime(lifetime);
return getQualifiedType(type, qs);
}
-
+
+ /// getUnqualifiedObjCPointerType - Returns version of
+ /// Objective-C pointer type with lifetime qualifier removed.
+ QualType getUnqualifiedObjCPointerType(QualType type) const {
+ if (!type.getTypePtr()->isObjCObjectPointerType() ||
+ !type.getQualifiers().hasObjCLifetime())
+ return type;
+ Qualifiers Qs = type.getQualifiers();
+ Qs.removeObjCLifetime();
+ return getQualifiedType(type.getUnqualifiedType(), Qs);
+ }
+
DeclarationNameInfo getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const;
@@ -1578,6 +1593,14 @@ public:
/// beneficial for performance to overalign a data type.
unsigned getPreferredTypeAlign(const Type *T) const;
+ /// \brief Return the alignment in bits that should be given to a
+ /// global variable with type \p T.
+ unsigned getAlignOfGlobalVar(QualType T) const;
+
+ /// \brief Return the alignment in characters that should be given to a
+ /// global variable with type \p T.
+ CharUnits getAlignOfGlobalVarInChars(QualType T) const;
+
/// \brief Return a conservative estimate of the alignment of the specified
/// decl \p D.
///
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index c709895..5a56b4d 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -41,10 +41,6 @@ public:
const_iterator begin() const { return const_iterator(Decls.begin()); }
const_iterator end() const { return const_iterator(Decls.end()); }
- void addDecl(ASTContext &C, NamedDecl *D) {
- addDecl(C, D, AS_none);
- }
-
void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
Decls.push_back(DeclAccessPair::make(D, AS), C);
}
@@ -52,10 +48,13 @@ public:
/// Replaces the given declaration with the new one, once.
///
/// \return true if the set changed
- bool replace(const NamedDecl* Old, NamedDecl *New) {
- for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
- if (I->getDecl() == Old)
- return (I->setDecl(New), true);
+ bool replace(const NamedDecl* Old, NamedDecl *New, AccessSpecifier AS) {
+ for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
+ if (I->getDecl() == Old) {
+ I->set(New, AS);
+ return true;
+ }
+ }
return false;
}
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index 9587ace..8c88494 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -67,14 +67,12 @@ class DeclarationVerbatimLineCommand<string name> :
}
class FunctionDeclarationVerbatimLineCommand<string name> :
- VerbatimLineCommand<name> {
- let IsDeclarationCommand = 1;
+ DeclarationVerbatimLineCommand<name> {
let IsFunctionDeclarationCommand = 1;
}
class RecordLikeDeclarationVerbatimLineCommand<string name> :
- VerbatimLineCommand<name> {
- let IsDeclarationCommand = 1;
+ DeclarationVerbatimLineCommand<name> {
let IsRecordLikeDeclarationCommand = 1;
}
@@ -121,6 +119,7 @@ def Headerfile : BlockCommand<"headerfile"> { let IsHeaderfileCommand = 1; }
// We don't do any additional semantic analysis for the following
// BlockCommands. It might be a good idea to do something extra for them, but
// for now we model them as plain BlockCommands.
+def Arg : BlockCommand<"arg">;
def Attention : BlockCommand<"attention">;
def Author : BlockCommand<"author">;
def Authors : BlockCommand<"authors">;
@@ -128,7 +127,9 @@ def Bug : BlockCommand<"bug">;
def Copyright : BlockCommand<"copyright">;
def Date : BlockCommand<"date">;
def Invariant : BlockCommand<"invariant">;
+def Li : BlockCommand<"li">;
def Note : BlockCommand<"note">;
+def Par : BlockCommand<"par">;
def Post : BlockCommand<"post">;
def Pre : BlockCommand<"pre">;
def Remark : BlockCommand<"remark">;
@@ -140,9 +141,11 @@ def Todo : BlockCommand<"todo">;
def Version : BlockCommand<"version">;
def Warning : BlockCommand<"warning">;
// HeaderDoc commands
+def Abstract : BlockCommand<"abstract">;
def ClassDesign : RecordLikeDetailCommand<"classdesign">;
def CoClass : RecordLikeDetailCommand<"coclass">;
def Dependency : RecordLikeDetailCommand<"dependency">;
+def Discussion : BlockCommand<"discussion">;
def Helper : RecordLikeDetailCommand<"helper">;
def HelperClass : RecordLikeDetailCommand<"helperclass">;
def Helps : RecordLikeDetailCommand<"helps">;
@@ -150,6 +153,7 @@ def InstanceSize : RecordLikeDetailCommand<"instancesize">;
def Ownership : RecordLikeDetailCommand<"ownership">;
def Performance : RecordLikeDetailCommand<"performance">;
def Security : RecordLikeDetailCommand<"security">;
+def SeeAlso : BlockCommand<"seealso">;
def SuperClass : RecordLikeDetailCommand<"superclass">;
//===----------------------------------------------------------------------===//
@@ -173,6 +177,10 @@ def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
+// HeaderDoc commands
+defm Textblock : VerbatimBlockCommand<"textblock", "/textblock">;
+defm Link : VerbatimBlockCommand<"link", "/link">;
+
//===----------------------------------------------------------------------===//
// VerbatimLineCommand
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index 4179f45..f152c77 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_COMMENT_LEXER_H
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -227,6 +228,8 @@ private:
/// computed (for example, resolved decimal character references).
llvm::BumpPtrAllocator &Allocator;
+ DiagnosticsEngine &Diags;
+
const CommandTraits &Traits;
const char *const BufferStart;
@@ -316,6 +319,10 @@ private:
return FileLoc.getLocWithOffset(CharNo);
}
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+ return Diags.Report(Loc, DiagID);
+ }
+
/// Eat string matching regexp \code \s*\* \endcode.
void skipLineStartingDecorations();
@@ -346,7 +353,8 @@ private:
void lexHTMLEndTag(Token &T);
public:
- Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
+ Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
+ const CommandTraits &Traits,
SourceLocation FileLoc,
const char *BufferStart, const char *BufferEnd);
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 7927279..a0c76c0 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -219,10 +219,6 @@ public:
return getLinkage() == ExternalLinkage;
}
- /// \brief True if this decl has external linkage. Don't cache the linkage,
- /// because we are not finished setting up the redecl chain for the decl.
- bool hasExternalLinkageUncached() const;
-
/// \brief Determines the visibility of this entity.
Visibility getVisibility() const {
return getLinkageAndVisibility().getVisibility();
@@ -641,6 +637,13 @@ public:
ListInit ///< Direct list-initialization (C++11)
};
+ /// \brief Kinds of thread-local storage.
+ enum TLSKind {
+ TLS_None, ///< Not a TLS variable.
+ TLS_Static, ///< TLS with a known-constant initializer.
+ TLS_Dynamic ///< TLS with a dynamic initializer.
+ };
+
protected:
/// \brief Placeholder type used in Init to denote an unparsed C++ default
/// argument.
@@ -664,7 +667,7 @@ private:
friend class ASTDeclReader;
unsigned SClass : 3;
- unsigned ThreadSpecified : 1;
+ unsigned TSCSpec : 2;
unsigned InitStyle : 2;
/// \brief Whether this variable is the exception variable in a C++ catch
@@ -687,7 +690,7 @@ private:
/// \brief Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
};
- enum { NumVarDeclBits = 14 };
+ enum { NumVarDeclBits = 12 };
friend class ASTDeclReader;
friend class StmtIteratorBase;
@@ -771,9 +774,23 @@ public:
}
void setStorageClass(StorageClass SC);
- void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; }
- bool isThreadSpecified() const {
- return VarDeclBits.ThreadSpecified;
+ void setTSCSpec(ThreadStorageClassSpecifier TSC) {
+ VarDeclBits.TSCSpec = TSC;
+ }
+ ThreadStorageClassSpecifier getTSCSpec() const {
+ return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
+ }
+ TLSKind getTLSKind() const {
+ switch (VarDeclBits.TSCSpec) {
+ case TSCS_unspecified:
+ return TLS_None;
+ case TSCS___thread: // Fall through.
+ case TSCS__Thread_local:
+ return TLS_Static;
+ case TSCS_thread_local:
+ return TLS_Dynamic;
+ }
+ llvm_unreachable("Unknown thread storage class specifier!");
}
/// hasLocalStorage - Returns true if a variable with function scope
@@ -813,6 +830,14 @@ public:
/// external, C linkage.
bool isExternC() const;
+ /// \brief 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,
+ /// 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.
@@ -1698,6 +1723,14 @@ public:
/// external, C linkage.
bool isExternC() const;
+ /// \brief 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,
+ /// a C++ extern "C++" linkage spec.
+ bool isInExternCXXContext() const;
+
/// \brief Determines whether this is a global function.
bool isGlobal() const;
@@ -2394,7 +2427,7 @@ protected:
bool IsScopedUsingClassTag : 1;
/// IsFixed - True if this is an enumeration with fixed underlying type. Only
- /// possible in C++11 or Microsoft extensions mode.
+ /// possible in C++11, Microsoft extensions, or Objective C mode.
bool IsFixed : 1;
/// \brief Indicates whether it is possible for declarations of this kind
@@ -2780,18 +2813,18 @@ public:
NumNegativeBits = Num;
}
- /// \brief Returns true if this is a C++0x scoped enumeration.
+ /// \brief Returns true if this is a C++11 scoped enumeration.
bool isScoped() const {
return IsScoped;
}
- /// \brief Returns true if this is a C++0x scoped enumeration.
+ /// \brief Returns true if this is a C++11 scoped enumeration.
bool isScopedUsingClassTag() const {
return IsScopedUsingClassTag;
}
- /// \brief Returns true if this is a C++0x enumeration with fixed underlying
- /// type.
+ /// \brief Returns true if this is an Objective-C, C++11, or
+ /// Microsoft-style enumeration with a fixed underlying type.
bool isFixed() const {
return IsFixed;
}
@@ -3162,6 +3195,67 @@ public:
}
};
+/// \brief This represents the body of a CapturedStmt, and serves as its
+/// DeclContext.
+class CapturedDecl : public Decl, public DeclContext {
+private:
+ /// \brief The number of parameters to the outlined function.
+ unsigned NumParams;
+ /// \brief The body of the outlined function.
+ Stmt *Body;
+
+ explicit CapturedDecl(DeclContext *DC, unsigned NumParams)
+ : Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
+ NumParams(NumParams), Body(0) { }
+
+ ImplicitParamDecl **getParams() const {
+ return reinterpret_cast<ImplicitParamDecl **>(
+ const_cast<CapturedDecl *>(this) + 1);
+ }
+
+public:
+ static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams);
+ static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NumParams);
+
+ Stmt *getBody() const { return Body; }
+ void setBody(Stmt *B) { Body = B; }
+
+ unsigned getNumParams() const { return NumParams; }
+
+ ImplicitParamDecl *getParam(unsigned i) const {
+ assert(i < NumParams);
+ return getParams()[i];
+ }
+ void setParam(unsigned i, ImplicitParamDecl *P) {
+ assert(i < NumParams);
+ getParams()[i] = P;
+ }
+
+ /// \brief Retrieve the parameter containing captured variables.
+ ImplicitParamDecl *getContextParam() const { return getParam(0); }
+ void setContextParam(ImplicitParamDecl *P) { setParam(0, P); }
+
+ typedef ImplicitParamDecl **param_iterator;
+ /// \brief 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.
+ param_iterator param_end() const { return getParams() + NumParams; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Captured; }
+ static DeclContext *castToDeclContext(const CapturedDecl *D) {
+ return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D));
+ }
+ static CapturedDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC));
+ }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
/// \brief Describes a module import declaration, which makes the contents
/// of the named module visible in the current translation unit.
///
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 852bb9a..754facf 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -372,10 +372,13 @@ public:
return const_cast<Decl*>(this)->getDeclContext();
}
- /// Finds the innermost non-closure context of this declaration.
- /// That is, walk out the DeclContext chain, skipping any blocks.
- DeclContext *getNonClosureContext();
- const DeclContext *getNonClosureContext() const {
+ /// Find the innermost non-closure ancestor of this declaration,
+ /// walking up through blocks, lambdas, etc. If that ancestor is
+ /// not a code context (!isFunctionOrMethod()), returns null.
+ ///
+ /// A declaration may be its own non-closure context.
+ Decl *getNonClosureContext();
+ const Decl *getNonClosureContext() const {
return const_cast<Decl*>(this)->getNonClosureContext();
}
@@ -402,6 +405,12 @@ public:
return AccessSpecifier(Access);
}
+ /// \brief Retrieve the access specifier for this declaration, even though
+ /// it may not yet have been properly set.
+ AccessSpecifier getAccessUnsafe() const {
+ return AccessSpecifier(Access);
+ }
+
bool hasAttrs() const { return HasAttrs; }
void setAttrs(const AttrVec& Attrs) {
return setAttrsImpl(Attrs, getASTContext());
@@ -1040,6 +1049,7 @@ public:
bool isFunctionOrMethod() const {
switch (DeclKind) {
case Decl::Block:
+ case Decl::Captured:
case Decl::ObjCMethod:
return true;
default:
@@ -1086,14 +1096,6 @@ public:
/// C++0x scoped enums), and C++ linkage specifications.
bool isTransparentContext() const;
- /// \brief Determines whether this context is, or is nested within,
- /// a C++ extern "C" linkage spec.
- bool isExternCContext() const;
-
- /// \brief Determines whether this context is, or is nested within,
- /// a C++ extern "C++" linkage spec.
- bool isExternCXXContext() const;
-
/// \brief Determine whether this declaration context is equivalent
/// to the declaration context DC.
bool Equals(const DeclContext *DC) const {
@@ -1107,8 +1109,8 @@ public:
/// \brief Find the nearest non-closure ancestor of this context,
/// i.e. the innermost semantic parent of this context which is not
/// a closure. A context may be its own non-closure ancestor.
- DeclContext *getNonClosureAncestor();
- const DeclContext *getNonClosureAncestor() const {
+ Decl *getNonClosureAncestor();
+ const Decl *getNonClosureAncestor() const {
return const_cast<DeclContext*>(this)->getNonClosureAncestor();
}
@@ -1402,6 +1404,9 @@ public:
/// @brief Removes a declaration from this context.
void removeDecl(Decl *D);
+
+ /// @brief Checks whether a declaration is in this context.
+ bool containsDecl(Decl *D) const;
/// lookup_iterator - An iterator that provides access to the results
/// of looking up a name within this context.
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 05ff49c..c483dde 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -254,6 +254,16 @@ public:
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
+/// The inheritance model to use for member pointers of a given CXXRecordDecl.
+enum MSInheritanceModel {
+ MSIM_Single,
+ MSIM_SinglePolymorphic,
+ MSIM_Multiple,
+ MSIM_MultiplePolymorphic,
+ MSIM_Virtual,
+ MSIM_Unspecified
+};
+
/// CXXRecordDecl - Represents a C++ struct/union/class.
/// FIXME: This class will disappear once we've properly taught RecordDecl
/// to deal with C++-specific things.
@@ -1744,8 +1754,6 @@ class CXXCtorInitializer {
/// \brief The argument used to initialize the base or member, which may
/// end up constructing an object (when multiple arguments are involved).
- /// If 0, this is a field initializer, and the in-class member initializer
- /// will be used.
Stmt *Init;
/// LParenLoc - Location of the left paren of the ctor-initializer.
@@ -1830,7 +1838,7 @@ public:
/// implicit ctor initializer generated for a field with an initializer
/// defined on the member declaration.
bool isInClassMemberInitializer() const {
- return !Init;
+ return isa<CXXDefaultInitExpr>(Init);
}
/// isDelegatingInitializer - Returns true when this initializer is creating
@@ -1957,14 +1965,8 @@ public:
getNumArrayIndices());
}
- /// \brief Get the initializer. This is 0 if this is an in-class initializer
- /// for a non-static data member which has not yet been parsed.
- Expr *getInit() const {
- if (!Init)
- return getAnyMember()->getInClassInitializer();
-
- return static_cast<Expr*>(Init);
- }
+ /// \brief Get the initializer.
+ Expr *getInit() const { return static_cast<Expr*>(Init); }
};
/// CXXConstructorDecl - Represents a C++ constructor within a
@@ -2349,38 +2351,49 @@ public:
};
private:
/// Language - The language for this linkage specification.
- LanguageIDs Language;
+ unsigned Language : 3;
+ /// True if this linkage spec has brances. This is needed so that hasBraces()
+ /// returns the correct result while the linkage spec body is being parsed.
+ /// Once RBraceLoc has been set this is not used, so it doesn't need to be
+ /// serialized.
+ unsigned HasBraces : 1;
/// ExternLoc - The source location for the extern keyword.
SourceLocation ExternLoc;
/// RBraceLoc - The source location for the right brace (if valid).
SourceLocation RBraceLoc;
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs lang,
- SourceLocation RBLoc)
+ SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
: Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
- Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { }
+ Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
+ RBraceLoc(SourceLocation()) { }
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation ExternLoc,
SourceLocation LangLoc, LanguageIDs Lang,
- SourceLocation RBraceLoc = SourceLocation());
+ bool HasBraces);
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// \brief Return the language specified by this linkage specification.
- LanguageIDs getLanguage() const { return Language; }
+ LanguageIDs getLanguage() const { return LanguageIDs(Language); }
/// \brief Set the language specified by this linkage specification.
void setLanguage(LanguageIDs L) { Language = L; }
/// \brief Determines whether this linkage specification had braces in
/// its syntactic form.
- bool hasBraces() const { return RBraceLoc.isValid(); }
+ bool hasBraces() const {
+ assert(!RBraceLoc.isValid() || HasBraces);
+ return HasBraces;
+ }
SourceLocation getExternLoc() const { return ExternLoc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setExternLoc(SourceLocation L) { ExternLoc = L; }
- void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+ void setRBraceLoc(SourceLocation L) {
+ RBraceLoc = L;
+ HasBraces = RBraceLoc.isValid();
+ }
SourceLocation getLocEnd() const LLVM_READONLY {
if (hasBraces())
@@ -2974,6 +2987,56 @@ public:
friend class ASTDeclReader;
};
+/// An instance of this class represents the declaration of a property
+/// member. This is a Microsoft extension to C++, first introduced in
+/// Visual Studio .NET 2003 as a parallel to similar features in C#
+/// and Managed C++.
+///
+/// A property must always be a non-static class member.
+///
+/// A property member superficially resembles a non-static data
+/// member, except preceded by a property attribute:
+/// __declspec(property(get=GetX, put=PutX)) int x;
+/// Either (but not both) of the 'get' and 'put' names may be omitted.
+///
+/// A reference to a property is always an lvalue. If the lvalue
+/// undergoes lvalue-to-rvalue conversion, then a getter name is
+/// required, and that member is called with no arguments.
+/// If the lvalue is assigned into, then a setter name is required,
+/// and that member is called with one argument, the value assigned.
+/// Both operations are potentially overloaded. Compound assignments
+/// are permitted, as are the increment and decrement operators.
+///
+/// The getter and putter methods are permitted to be overloaded,
+/// although their return and parameter types are subject to certain
+/// restrictions according to the type of the property.
+///
+/// A property declared using an incomplete array type may
+/// additionally be subscripted, adding extra parameters to the getter
+/// and putter methods.
+class MSPropertyDecl : public DeclaratorDecl {
+ IdentifierInfo *GetterId, *SetterId;
+
+public:
+ MSPropertyDecl(DeclContext *DC, SourceLocation L,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ SourceLocation StartL, IdentifierInfo *Getter,
+ IdentifierInfo *Setter):
+ DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
+ SetterId(Setter) {}
+
+ static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
+
+ bool hasGetter() const { return GetterId != NULL; }
+ IdentifierInfo* getGetterId() const { return GetterId; }
+ bool hasSetter() const { return SetterId != NULL; }
+ IdentifierInfo* getSetterId() const { return SetterId; }
+
+ friend class ASTDeclReader;
+};
+
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
/// into a diagnostic with <<.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 253c23c..3a12878 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -101,7 +101,7 @@ public:
SourceLocation L, FriendUnion Friend_,
SourceLocation FriendL,
ArrayRef<TemplateParameterList*> FriendTypeTPLists
- = ArrayRef<TemplateParameterList*>());
+ = None);
static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned FriendTypeNumTPLists);
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index c294922..40de013 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1136,7 +1136,8 @@ public:
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup= false) const;
+ bool shallowCategoryLookup= false,
+ const ObjCCategoryDecl *C= 0) const;
ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
bool shallowCategoryLookup = false) const {
return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
@@ -1155,6 +1156,15 @@ public:
return lookupPrivateMethod(Sel, false);
}
+ /// \brief Lookup a setter or getter in the class hierarchy,
+ /// including in all categories except for category passed
+ /// as argument.
+ ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
+ const ObjCCategoryDecl *Cat) const {
+ return lookupMethod(Sel, true/*isInstance*/,
+ false/*shallowCategoryLookup*/, Cat);
+ }
+
SourceLocation getEndOfDefinitionLoc() const {
if (!hasDefinition())
return getLocation();
@@ -1788,6 +1798,8 @@ class ObjCImplementationDecl : public ObjCImplDecl {
virtual void anchor();
/// Implementation Class's super class.
ObjCInterfaceDecl *SuperClass;
+ SourceLocation SuperLoc;
+
/// \@implementation may have private ivars.
SourceLocation IvarLBraceLoc;
SourceLocation IvarRBraceLoc;
@@ -1808,10 +1820,11 @@ class ObjCImplementationDecl : public ObjCImplDecl {
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl,
SourceLocation nameLoc, SourceLocation atStartLoc,
+ SourceLocation superLoc = SourceLocation(),
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation())
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
- SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc),
+ SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
IvarRBraceLoc(IvarRBraceLoc),
IvarInitializers(0), NumIvarInitializers(0),
HasNonZeroConstructors(false), HasDestructors(false) {}
@@ -1821,6 +1834,7 @@ public:
ObjCInterfaceDecl *superDecl,
SourceLocation nameLoc,
SourceLocation atStartLoc,
+ SourceLocation superLoc = SourceLocation(),
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation());
@@ -1893,6 +1907,7 @@ public:
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
+ SourceLocation getSuperClassLoc() const { return SuperLoc; }
void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index eb186c2..2e3cbfa 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -55,7 +55,7 @@ public:
// Only the selected subexpression matters; the other one is not evaluated.
return this->Visit(E->getChosenSubExpr(Context));
}
-
+
void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
// Only the actual initializer matters; the designators are all constant
// expressions.
@@ -72,6 +72,15 @@ public:
return static_cast<ImplClass*>(this)->VisitExpr(CE);
}
+ void VisitLambdaExpr(LambdaExpr *LE) {
+ // Only visit the capture initializers, and not the body.
+ for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(),
+ E = LE->capture_init_end();
+ I != E; ++I)
+ if (*I)
+ this->Visit(*I);
+ }
+
/// \brief The basis case walks all of the children of the statement or
/// expression, assuming they are all potentially evaluated.
void VisitStmt(Stmt *S) {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 36d70d8..4ff1257 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -427,12 +427,24 @@ private:
public:
+ /// \brief Returns true if this expression is a gl-value that
+ /// potentially refers to a bit-field.
+ ///
+ /// In C++, whether a gl-value refers to a bitfield is essentially
+ /// an aspect of the value-kind type system.
+ bool refersToBitField() const { return getObjectKind() == OK_BitField; }
+
/// \brief If this expression refers to a bit-field, retrieve the
/// declaration of that bit-field.
- FieldDecl *getBitField();
+ ///
+ /// Note that this returns a non-null pointer in subtly different
+ /// places than refersToBitField returns true. In particular, this can
+ /// return a non-null pointer even for r-values loaded from
+ /// bit-fields, but it will return null for a conditional bit-field.
+ FieldDecl *getSourceBitField();
- const FieldDecl *getBitField() const {
- return const_cast<Expr*>(this)->getBitField();
+ const FieldDecl *getSourceBitField() const {
+ return const_cast<Expr*>(this)->getSourceBitField();
}
/// \brief If this expression is an l-value for an Objective C
@@ -2644,7 +2656,7 @@ protected:
(ty->isInstantiationDependentType() ||
(op && op->isInstantiationDependent())),
(ty->containsUnexpandedParameterPack() ||
- op->containsUnexpandedParameterPack())),
+ (op && op->containsUnexpandedParameterPack()))),
Op(op) {
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 04f6fb6..91e5b21 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -29,6 +29,7 @@ class CXXConstructorDecl;
class CXXDestructorDecl;
class CXXMethodDecl;
class CXXTemporary;
+class MSPropertyDecl;
class TemplateArgumentListInfo;
class UuidAttr;
@@ -560,6 +561,64 @@ public:
}
};
+/// A member reference to an MSPropertyDecl. This expression always
+/// has pseudo-object type, and therefore it is typically not
+/// encountered in a fully-typechecked expression except within the
+/// syntactic form of a PseudoObjectExpr.
+class MSPropertyRefExpr : public Expr {
+ Expr *BaseExpr;
+ MSPropertyDecl *TheDecl;
+ SourceLocation MemberLoc;
+ bool IsArrow;
+ NestedNameSpecifierLoc QualifierLoc;
+
+public:
+ MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
+ QualType ty, ExprValueKind VK,
+ NestedNameSpecifierLoc qualifierLoc,
+ SourceLocation nameLoc)
+ : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
+ /*type-dependent*/ false, baseExpr->isValueDependent(),
+ baseExpr->isInstantiationDependent(),
+ baseExpr->containsUnexpandedParameterPack()),
+ BaseExpr(baseExpr), TheDecl(decl),
+ MemberLoc(nameLoc), IsArrow(isArrow),
+ QualifierLoc(qualifierLoc) {}
+
+ MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getLocStart(), getLocEnd());
+ }
+ bool isImplicitAccess() const {
+ return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
+ }
+ SourceLocation getLocStart() const {
+ if (!isImplicitAccess())
+ return BaseExpr->getLocStart();
+ else if (QualifierLoc)
+ return QualifierLoc.getBeginLoc();
+ else
+ return MemberLoc;
+ }
+ SourceLocation getLocEnd() const { return getMemberLoc(); }
+
+ child_range children() {
+ return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == MSPropertyRefExprClass;
+ }
+
+ Expr *getBaseExpr() const { return BaseExpr; }
+ MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
+ bool isArrow() const { return IsArrow; }
+ SourceLocation getMemberLoc() const { return MemberLoc; }
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+ friend class ASTStmtReader;
+};
+
/// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets
/// the _GUID that corresponds to the supplied type or expression.
///
@@ -825,6 +884,53 @@ public:
friend class ASTStmtWriter;
};
+/// \brief This wraps a use of a C++ default initializer (technically,
+/// a brace-or-equal-initializer for a non-static data member) when it
+/// is implicitly used in a mem-initializer-list in a constructor
+/// (C++11 [class.base.init]p8) or in aggregate initialization
+/// (C++1y [dcl.init.aggr]p7).
+class CXXDefaultInitExpr : public Expr {
+ /// \brief The field whose default is being used.
+ FieldDecl *Field;
+
+ /// \brief The location where the default initializer expression was used.
+ SourceLocation Loc;
+
+ CXXDefaultInitExpr(ASTContext &C, SourceLocation Loc, FieldDecl *Field,
+ QualType T);
+
+ CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
+
+public:
+ // Field is the non-static data member whose default initializer is used
+ // by this expression.
+ static CXXDefaultInitExpr *Create(ASTContext &C, SourceLocation Loc,
+ FieldDecl *Field) {
+ return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
+ }
+
+ // Get the field whose initializer will be used.
+ FieldDecl *getField() { return Field; }
+ const FieldDecl *getField() const { return Field; }
+
+ // Get the initialization expression that will be used.
+ const Expr *getExpr() const { return Field->getInClassInitializer(); }
+ Expr *getExpr() { return Field->getInClassInitializer(); }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXDefaultInitExprClass;
+ }
+
+ // Iterators
+ child_range children() { return child_range(); }
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+};
+
/// CXXTemporary - Represents a C++ temporary.
class CXXTemporary {
/// Destructor - The destructor that needs to be called.
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index dfd4527..a94c69a 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -476,7 +476,8 @@ public:
SourceLocation l, SourceLocation oploc,
Expr *base,
bool arrow = false, bool freeIvar = false) :
- Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
+ Expr(ObjCIvarRefExprClass, t, VK_LValue,
+ d->isBitField() ? OK_BitField : OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index 94faa19..b6d22cf 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -141,6 +141,16 @@ public:
raw_ostream &) {
llvm_unreachable("Target does not support mangling guard variables");
}
+ // FIXME: Revisit this once we know what we need to do for MSVC compatibility.
+ virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
+ raw_ostream &) {
+ llvm_unreachable("Target does not support mangling thread_local variables");
+ }
+ virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
+ raw_ostream &) {
+ llvm_unreachable("Target does not support mangling thread_local variables");
+ }
+
/// @}
};
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 3a8b218..84a6e96 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -10,6 +10,7 @@
#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H
#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H
+#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
@@ -40,7 +41,7 @@ public:
RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
RawComment(const SourceManager &SourceMgr, SourceRange SR,
- bool Merged = false);
+ bool Merged, bool ParseAllComments);
CommentKind getKind() const LLVM_READONLY {
return (CommentKind) Kind;
@@ -82,7 +83,8 @@ public:
/// Returns true if this comment is not a documentation comment.
bool isOrdinary() const LLVM_READONLY {
- return (Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC);
+ return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
+ !ParseAllComments;
}
/// Returns true if this comment any kind of a documentation comment.
@@ -90,6 +92,11 @@ public:
return !isInvalid() && !isOrdinary();
}
+ /// Returns whether we are parsing all comments.
+ bool isParseAllComments() const LLVM_READONLY {
+ return ParseAllComments;
+ }
+
/// Returns raw comment text with comment markers.
StringRef getRawText(const SourceManager &SourceMgr) const {
if (RawTextValid)
@@ -135,6 +142,10 @@ private:
bool IsTrailingComment : 1;
bool IsAlmostTrailingComment : 1;
+ /// When true, ordinary comments starting with "//" and "/*" will be
+ /// considered as documentation comments.
+ bool ParseAllComments : 1;
+
mutable bool BeginLineValid : 1; ///< True if BeginLine is valid
mutable bool EndLineValid : 1; ///< True if EndLine is valid
mutable unsigned BeginLine; ///< Cached line number
@@ -142,10 +153,12 @@ private:
/// \brief Constructor for AST deserialization.
RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
- bool IsAlmostTrailingComment) :
+ bool IsAlmostTrailingComment,
+ bool ParseAllComments) :
Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
IsAttached(false), IsTrailingComment(IsTrailingComment),
IsAlmostTrailingComment(IsAlmostTrailingComment),
+ ParseAllComments(ParseAllComments),
BeginLineValid(false), EndLineValid(false)
{ }
@@ -207,4 +220,3 @@ private:
} // end namespace clang
#endif
-
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 0191964..b5a4b5e 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1228,8 +1228,9 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
for (DeclContext::decl_iterator Child = DC->decls_begin(),
ChildEnd = DC->decls_end();
Child != ChildEnd; ++Child) {
- // BlockDecls are traversed through BlockExprs.
- if (!isa<BlockDecl>(*Child))
+ // BlockDecls and CapturedDecls are traversed through BlockExprs and
+ // CapturedStmts respectively.
+ if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
TRY_TO(TraverseDecl(*Child));
}
@@ -1258,6 +1259,14 @@ DEF_TRAVERSE_DECL(BlockDecl, {
return true;
})
+DEF_TRAVERSE_DECL(CapturedDecl, {
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+ })
+
DEF_TRAVERSE_DECL(EmptyDecl, { })
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
@@ -1671,6 +1680,10 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
return true;
}
+DEF_TRAVERSE_DECL(MSPropertyDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ })
+
DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
@@ -2058,6 +2071,10 @@ DEF_TRAVERSE_STMT(CXXTypeidExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
})
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
+
DEF_TRAVERSE_STMT(CXXUuidofExpr, {
// The child-iterator will pick up the arg if it's an expression,
// but not if it's a type.
@@ -2153,6 +2170,7 @@ DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
DEF_TRAVERSE_STMT(ExprWithCleanups, { })
DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
@@ -2177,7 +2195,10 @@ DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
})
DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
+DEF_TRAVERSE_STMT(ObjCMessageExpr, {
+ if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
@@ -2210,6 +2231,9 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
DEF_TRAVERSE_STMT(SEHTryStmt, {})
DEF_TRAVERSE_STMT(SEHExceptStmt, {})
DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
+DEF_TRAVERSE_STMT(CapturedStmt, {
+ TRY_TO(TraverseDecl(S->getCapturedDecl()));
+})
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index cf8fc24..74c9ec2 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -16,10 +16,12 @@
#include "clang/AST/DeclGroup.h"
#include "clang/AST/StmtIterator.h"
+#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
@@ -31,6 +33,7 @@ namespace llvm {
namespace clang {
class ASTContext;
class Attr;
+ class CapturedDecl;
class Decl;
class Expr;
class IdentifierInfo;
@@ -39,6 +42,7 @@ namespace clang {
class PrinterHelper;
struct PrintingPolicy;
class QualType;
+ class RecordDecl;
class SourceManager;
class StringLiteral;
class SwitchStmt;
@@ -1384,7 +1388,6 @@ protected:
unsigned NumInputs;
unsigned NumClobbers;
- IdentifierInfo **Names;
Stmt **Exprs;
AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
@@ -1392,10 +1395,12 @@ protected:
Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
+ friend class ASTStmtReader;
+
public:
/// \brief Build an empty inline-assembly statement.
explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
- Stmt(SC, Empty), Names(0), Exprs(0) { }
+ Stmt(SC, Empty), Exprs(0) { }
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@@ -1418,17 +1423,6 @@ public:
unsigned getNumOutputs() const { return NumOutputs; }
- IdentifierInfo *getOutputIdentifier(unsigned i) const {
- return Names[i];
- }
-
- StringRef getOutputName(unsigned i) const {
- if (IdentifierInfo *II = getOutputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
@@ -1451,17 +1445,6 @@ public:
unsigned getNumInputs() const { return NumInputs; }
- IdentifierInfo *getInputIdentifier(unsigned i) const {
- return Names[i + NumOutputs];
- }
-
- StringRef getInputName(unsigned i) const {
- if (IdentifierInfo *II = getInputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
/// getInputConstraint - Return the specified input constraint. Unlike output
/// constraints, these can be empty.
StringRef getInputConstraint(unsigned i) const;
@@ -1532,6 +1515,9 @@ class GCCAsmStmt : public AsmStmt {
// FIXME: If we wanted to, we could allocate all of these in one big array.
StringLiteral **Constraints;
StringLiteral **Clobbers;
+ IdentifierInfo **Names;
+
+ friend class ASTStmtReader;
public:
GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
@@ -1542,7 +1528,7 @@ public:
/// \brief Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
- Constraints(0), Clobbers(0) { }
+ Constraints(0), Clobbers(0), Names(0) { }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
@@ -1607,6 +1593,17 @@ public:
//===--- Output operands ---===//
+ IdentifierInfo *getOutputIdentifier(unsigned i) const {
+ return Names[i];
+ }
+
+ StringRef getOutputName(unsigned i) const {
+ if (IdentifierInfo *II = getOutputIdentifier(i))
+ return II->getName();
+
+ return StringRef();
+ }
+
StringRef getOutputConstraint(unsigned i) const;
const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
@@ -1624,6 +1621,17 @@ public:
//===--- Input operands ---===//
+ IdentifierInfo *getInputIdentifier(unsigned i) const {
+ return Names[i + NumOutputs];
+ }
+
+ StringRef getInputName(unsigned i) const {
+ if (IdentifierInfo *II = getInputIdentifier(i))
+ return II->getName();
+
+ return StringRef();
+ }
+
StringRef getInputConstraint(unsigned i) const;
const StringLiteral *getInputConstraintLiteral(unsigned i) const {
@@ -1640,6 +1648,7 @@ public:
return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
}
+private:
void setOutputsAndInputsAndClobbers(ASTContext &C,
IdentifierInfo **Names,
StringLiteral **Constraints,
@@ -1648,6 +1657,7 @@ public:
unsigned NumInputs,
StringLiteral **Clobbers,
unsigned NumClobbers);
+public:
//===--- Other ---===//
@@ -1674,7 +1684,7 @@ public:
///
class MSAsmStmt : public AsmStmt {
SourceLocation LBraceLoc, EndLoc;
- std::string AsmStr;
+ StringRef AsmStr;
unsigned NumAsmToks;
@@ -1682,11 +1692,13 @@ class MSAsmStmt : public AsmStmt {
StringRef *Constraints;
StringRef *Clobbers;
+ friend class ASTStmtReader;
+
public:
MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc,
bool issimple, bool isvolatile, ArrayRef<Token> asmtoks,
unsigned numoutputs, unsigned numinputs,
- ArrayRef<IdentifierInfo*> names, ArrayRef<StringRef> constraints,
+ ArrayRef<StringRef> constraints,
ArrayRef<Expr*> exprs, StringRef asmstr,
ArrayRef<StringRef> clobbers, SourceLocation endloc);
@@ -1705,10 +1717,7 @@ public:
Token *getAsmToks() { return AsmToks; }
//===--- Asm String Analysis ---===//
-
- const std::string *getAsmString() const { return &AsmStr; }
- std::string *getAsmString() { return &AsmStr; }
- void setAsmString(StringRef &E) { AsmStr = E.str(); }
+ StringRef getAsmString() const { return AsmStr; }
/// Assemble final IR asm string.
std::string generateAsmString(ASTContext &C) const;
@@ -1716,6 +1725,7 @@ public:
//===--- Output operands ---===//
StringRef getOutputConstraint(unsigned i) const {
+ assert(i < NumOutputs);
return Constraints[i];
}
@@ -1728,6 +1738,7 @@ public:
//===--- Input operands ---===//
StringRef getInputConstraint(unsigned i) const {
+ assert(i < NumInputs);
return Constraints[i + NumOutputs];
}
@@ -1740,7 +1751,27 @@ public:
//===--- Other ---===//
- StringRef getClobber(unsigned i) const { return Clobbers[i]; }
+ ArrayRef<StringRef> getAllConstraints() const {
+ return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs);
+ }
+ ArrayRef<StringRef> getClobbers() const {
+ return ArrayRef<StringRef>(Clobbers, NumClobbers);
+ }
+ ArrayRef<Expr*> getAllExprs() const {
+ return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs),
+ NumInputs + NumOutputs);
+ }
+
+ StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
+
+private:
+ void initialize(ASTContext &C,
+ StringRef AsmString,
+ ArrayRef<Token> AsmToks,
+ ArrayRef<StringRef> Constraints,
+ ArrayRef<Expr*> Exprs,
+ ArrayRef<StringRef> Clobbers);
+public:
SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
@@ -1882,6 +1913,198 @@ public:
}
};
+/// \brief This captures a statement into a function. For example, the following
+/// pragma annotated compound statement can be represented as a CapturedStmt,
+/// and this compound statement is the body of an anonymous outlined function.
+/// @code
+/// #pragma omp parallel
+/// {
+/// compute();
+/// }
+/// @endcode
+class CapturedStmt : public Stmt {
+public:
+ /// \brief The different capture forms: by 'this' or by reference, etc.
+ enum VariableCaptureKind {
+ VCK_This,
+ VCK_ByRef
+ };
+
+ /// \brief Describes the capture of either a variable or 'this'.
+ class Capture {
+ llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind;
+ SourceLocation Loc;
+
+ public:
+ /// \brief Create a new capture.
+ ///
+ /// \param Loc The source location associated with this capture.
+ ///
+ /// \param Kind The kind of capture (this, ByRef, ...).
+ ///
+ /// \param Var The variable being captured, or null if capturing this.
+ ///
+ Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0)
+ : VarAndKind(Var, Kind), Loc(Loc) {
+ switch (Kind) {
+ case VCK_This:
+ assert(Var == 0 && "'this' capture cannot have a variable!");
+ break;
+ case VCK_ByRef:
+ assert(Var && "capturing by reference must have a variable!");
+ break;
+ }
+ }
+
+ /// \brief Determine the kind of capture.
+ VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); }
+
+ /// \brief Retrieve the source location at which the variable or 'this' was
+ /// first used.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Determine whether this capture handles the C++ 'this' pointer.
+ bool capturesThis() const { return getCaptureKind() == VCK_This; }
+
+ /// \brief Determine whether this capture handles a variable.
+ bool capturesVariable() const { return getCaptureKind() != VCK_This; }
+
+ /// \brief Retrieve the declaration of the variable being captured.
+ ///
+ /// This operation is only valid if this capture does not capture 'this'.
+ VarDecl *getCapturedVar() const {
+ assert(!capturesThis() && "No variable available for 'this' capture");
+ return VarAndKind.getPointer();
+ }
+ friend class ASTStmtReader;
+ };
+
+private:
+ /// \brief The number of variable captured, including 'this'.
+ unsigned NumCaptures;
+
+ /// \brief The pointer part is the implicit the outlined function and the
+ /// int part is the captured region kind, 'CR_Default' etc.
+ llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
+
+ /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
+ RecordDecl *TheRecordDecl;
+
+ /// \brief Construct a captured statement.
+ CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
+ ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
+
+ /// \brief Construct an empty captured statement.
+ CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
+
+ Stmt **getStoredStmts() const {
+ return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1);
+ }
+
+ Capture *getStoredCaptures() const;
+
+ void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
+
+public:
+ static CapturedStmt *Create(ASTContext &Context, Stmt *S,
+ CapturedRegionKind Kind,
+ ArrayRef<Capture> Captures,
+ ArrayRef<Expr *> CaptureInits,
+ CapturedDecl *CD, RecordDecl *RD);
+
+ static CapturedStmt *CreateDeserialized(ASTContext &Context,
+ unsigned NumCaptures);
+
+ /// \brief Retrieve the statement being captured.
+ Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
+ const Stmt *getCapturedStmt() const {
+ return const_cast<CapturedStmt *>(this)->getCapturedStmt();
+ }
+
+ /// \brief Retrieve the outlined function declaration.
+ CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); }
+ const CapturedDecl *getCapturedDecl() const {
+ return const_cast<CapturedStmt *>(this)->getCapturedDecl();
+ }
+
+ /// \brief Set the outlined function declaration.
+ void setCapturedDecl(CapturedDecl *D) {
+ assert(D && "null CapturedDecl");
+ CapDeclAndKind.setPointer(D);
+ }
+
+ /// \brief Retrieve the captured region kind.
+ CapturedRegionKind getCapturedRegionKind() const {
+ return CapDeclAndKind.getInt();
+ }
+
+ /// \brief Set the captured region kind.
+ void setCapturedRegionKind(CapturedRegionKind Kind) {
+ CapDeclAndKind.setInt(Kind);
+ }
+
+ /// \brief Retrieve the record declaration for captured variables.
+ const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
+
+ /// \brief Set the record declaration for captured variables.
+ void setCapturedRecordDecl(RecordDecl *D) {
+ assert(D && "null RecordDecl");
+ TheRecordDecl = D;
+ }
+
+ /// \brief True if this variable has been captured.
+ bool capturesVariable(const VarDecl *Var) const;
+
+ /// \brief An iterator that walks over the captures.
+ typedef Capture *capture_iterator;
+ typedef const Capture *const_capture_iterator;
+
+ /// \brief Retrieve an iterator pointing to the first capture.
+ capture_iterator capture_begin() { return getStoredCaptures(); }
+ const_capture_iterator capture_begin() const { return getStoredCaptures(); }
+
+ /// \brief Retrieve an iterator pointing past the end of the sequence of
+ /// captures.
+ capture_iterator capture_end() const {
+ return getStoredCaptures() + NumCaptures;
+ }
+
+ /// \brief Retrieve the number of captures, including 'this'.
+ unsigned capture_size() const { return NumCaptures; }
+
+ /// \brief Iterator that walks over the capture initialization arguments.
+ typedef Expr **capture_init_iterator;
+
+ /// \brief Retrieve the first initialization argument.
+ capture_init_iterator capture_init_begin() const {
+ return reinterpret_cast<Expr **>(getStoredStmts());
+ }
+
+ /// \brief Retrieve the iterator pointing one past the last initialization
+ /// argument.
+ capture_init_iterator capture_init_end() const {
+ return capture_init_begin() + NumCaptures;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getCapturedStmt()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getCapturedStmt()->getLocEnd();
+ }
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return getCapturedStmt()->getSourceRange();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CapturedStmtClass;
+ }
+
+ child_range children();
+
+ friend class ASTStmtReader;
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 23fa3e8..39f10d3 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1326,10 +1326,20 @@ protected:
unsigned AttrKind : 32 - NumTypeBits;
};
+ class AutoTypeBitfields {
+ friend class AutoType;
+
+ unsigned : NumTypeBits;
+
+ /// Was this placeholder type spelled as 'decltype(auto)'?
+ unsigned IsDecltypeAuto : 1;
+ };
+
union {
TypeBitfields TypeBits;
ArrayTypeBitfields ArrayTypeBits;
AttributedTypeBitfields AttributedTypeBits;
+ AutoTypeBitfields AutoTypeBits;
BuiltinTypeBitfields BuiltinTypeBits;
FunctionTypeBitfields FunctionTypeBits;
ObjCObjectTypeBitfields ObjCObjectTypeBits;
@@ -1443,8 +1453,8 @@ public:
}
/// isLiteralType - Return true if this is a literal type
- /// (C++0x [basic.types]p10)
- bool isLiteralType() const;
+ /// (C++11 [basic.types]p10)
+ bool isLiteralType(ASTContext &Ctx) const;
/// \brief Test if this type is a standard-layout type.
/// (C++0x [basic.type]p9)
@@ -1609,6 +1619,10 @@ public:
return TypeBits.InstantiationDependent;
}
+ /// \brief Determine whether this type is an undeduced type, meaning that
+ /// it somehow involves a C++11 'auto' type which has not yet been deduced.
+ bool isUndeducedType() const;
+
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
@@ -2092,14 +2106,6 @@ public:
}
};
-/// The inheritance model to use for this member pointer.
-enum MSInheritanceModel {
- MSIM_Single,
- MSIM_Multiple,
- MSIM_Virtual,
- MSIM_Unspecified
-};
-
/// MemberPointerType - C++ 8.3.3 - Pointers to members
///
class MemberPointerType : public Type, public llvm::FoldingSetNode {
@@ -2135,10 +2141,6 @@ public:
return !PointeeType->isFunctionProtoType();
}
- /// Returns the number of pointer and integer slots used to represent this
- /// member pointer in the MS C++ ABI.
- std::pair<unsigned, unsigned> getMSMemberPointerSlots() const;
-
const Type *getClass() const { return Class; }
bool isSugared() const { return false; }
@@ -3554,41 +3556,48 @@ public:
}
};
-/// \brief Represents a C++0x auto type.
+/// \brief Represents a C++11 auto or C++1y decltype(auto) type.
///
-/// These types are usually a placeholder for a deduced type. However, within
-/// templates and before the initializer is attached, there is no deduced type
-/// and an auto type is type-dependent and canonical.
+/// These types are usually a placeholder for a deduced type. However, before
+/// the initializer is attached, or if the initializer is type-dependent, there
+/// is no deduced type and an auto type is canonical. In the latter case, it is
+/// also a dependent type.
class AutoType : public Type, public llvm::FoldingSetNode {
- AutoType(QualType DeducedType)
+ AutoType(QualType DeducedType, bool IsDecltypeAuto, bool IsDependent)
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
- /*Dependent=*/DeducedType.isNull(),
- /*InstantiationDependent=*/DeducedType.isNull(),
+ /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
- assert((DeducedType.isNull() || !DeducedType->isDependentType()) &&
- "deduced a dependent type for auto");
+ assert((DeducedType.isNull() || !IsDependent) &&
+ "auto deduced to dependent type");
+ AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto;
}
friend class ASTContext; // ASTContext creates these
public:
- bool isSugared() const { return isDeduced(); }
+ bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; }
+
+ bool isSugared() const { return !isCanonicalUnqualified(); }
QualType desugar() const { return getCanonicalTypeInternal(); }
+ /// \brief Get the type deduced for this auto type, or null if it's either
+ /// not been deduced or was deduced to a dependent type.
QualType getDeducedType() const {
- return isDeduced() ? getCanonicalTypeInternal() : QualType();
+ return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
}
bool isDeduced() const {
- return !isDependentType();
+ return !isCanonicalUnqualified() || isDependentType();
}
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDeducedType());
+ Profile(ID, getDeducedType(), isDecltypeAuto(), isDependentType());
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- QualType Deduced) {
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
+ bool IsDecltypeAuto, bool IsDependent) {
ID.AddPointer(Deduced.getAsOpaquePtr());
+ ID.AddBoolean(IsDecltypeAuto);
+ ID.AddBoolean(IsDependent);
}
static bool classof(const Type *T) {
@@ -4638,7 +4647,7 @@ inline QualType QualType::getUnqualifiedType() const {
return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
}
-
+
inline SplitQualType QualType::getSplitUnqualifiedType() const {
if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
return split();
@@ -4670,7 +4679,7 @@ inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
inline unsigned QualType::getAddressSpace() const {
return getQualifiers().getAddressSpace();
}
-
+
/// getObjCGCAttr - Return the gc attribute of this type.
inline Qualifiers::GC QualType::getObjCGCAttr() const {
return getQualifiers().getObjCGCAttr();
@@ -5031,6 +5040,11 @@ inline bool Type::isBooleanType() const {
return false;
}
+inline bool Type::isUndeducedType() const {
+ const AutoType *AT = getContainedAutoType();
+ return AT && !AT->isDeduced();
+}
+
/// \brief Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index d5c485f..840e07d 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -94,7 +94,7 @@ DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Auto, Type)
+TYPE(Auto, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
OpenPOWER on IntegriCloud