aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
committerEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
commit5362a71c02e7d448a8ce98cf00c47e353fba5d04 (patch)
tree8ddfe382e1c6d590dc240e76f7cd45cea5c78e24 /include
parent4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (diff)
downloadsrc-5362a71c02e7d448a8ce98cf00c47e353fba5d04.tar.gz
src-5362a71c02e7d448a8ce98cf00c47e353fba5d04.zip
Import Clang r74788.vendor/clang/clang-r74788
Notes
Notes: svn path=/vendor/clang/dist/; revision=195341 svn path=/vendor/clang/clang-r74788/; revision=195343; tag=vendor/clang/clang-r74788
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/ASTContext.h22
-rw-r--r--include/clang/AST/CFG.h17
-rw-r--r--include/clang/AST/Decl.h86
-rw-r--r--include/clang/AST/DeclBase.h81
-rw-r--r--include/clang/AST/DeclCXX.h112
-rw-r--r--include/clang/AST/DeclObjC.h135
-rw-r--r--include/clang/AST/DeclTemplate.h790
-rw-r--r--include/clang/AST/Expr.h9
-rw-r--r--include/clang/AST/ExprCXX.h94
-rw-r--r--include/clang/AST/ExternalASTSource.h9
-rw-r--r--include/clang/AST/NestedNameSpecifier.h3
-rw-r--r--include/clang/AST/PrettyPrinter.h10
-rw-r--r--include/clang/AST/Stmt.h10
-rw-r--r--include/clang/AST/StmtNodes.def3
-rw-r--r--include/clang/AST/Type.h6
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h59
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h2
-rw-r--r--include/clang/Analysis/PathSensitive/ValueManager.h11
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td26
-rw-r--r--include/clang/Basic/LangOptions.h25
-rw-r--r--include/clang/Basic/TargetInfo.h4
-rw-r--r--include/clang/Basic/TokenKinds.def6
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
-rw-r--r--include/clang/Driver/Action.h2
-rw-r--r--include/clang/Driver/ArgList.h2
-rw-r--r--include/clang/Driver/Compilation.h33
-rw-r--r--include/clang/Driver/Driver.h8
-rw-r--r--include/clang/Driver/HostInfo.h2
-rw-r--r--include/clang/Driver/Job.h10
-rw-r--r--include/clang/Driver/Options.def5
-rw-r--r--include/clang/Frontend/ASTConsumers.h4
-rw-r--r--include/clang/Frontend/PCHBitCodes.h6
-rw-r--r--include/clang/Frontend/PCHReader.h14
-rw-r--r--include/clang/Frontend/PCHWriter.h1
-rw-r--r--include/clang/Lex/Preprocessor.h24
-rw-r--r--include/clang/Parse/Action.h24
-rw-r--r--include/clang/Parse/Ownership.h19
-rw-r--r--include/clang/Parse/Parser.h3
39 files changed, 1068 insertions, 617 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index aa01b7fdf06f..041a0f33ad4d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -141,10 +141,19 @@ class ASTContext {
/// this ASTContext object.
LangOptions LangOpts;
+ /// \brief Whether we have already loaded comment source ranges from an
+ /// external source.
+ bool LoadedExternalComments;
+
/// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects.
bool FreeMemory;
llvm::MallocAllocator MallocAlloc;
llvm::BumpPtrAllocator BumpAlloc;
+
+ /// \brief Mapping from declarations to their comments, once we have
+ /// already looked up the comment associated with a given declaration.
+ llvm::DenseMap<const Decl *, std::string> DeclComments;
+
public:
TargetInfo &Target;
IdentifierTable &Idents;
@@ -154,6 +163,10 @@ public:
llvm::OwningPtr<ExternalASTSource> ExternalSource;
clang::PrintingPolicy PrintingPolicy;
+ /// \brief Source ranges for all of the comments in the source file,
+ /// sorted in order of appearance in the translation unit.
+ std::vector<SourceRange> Comments;
+
SourceManager& getSourceManager() { return SourceMgr; }
const SourceManager& getSourceManager() const { return SourceMgr; }
void *Allocate(unsigned Size, unsigned Align = 8) {
@@ -178,7 +191,8 @@ public:
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
-
+ const char *getCommentForDecl(const Decl *D);
+
// Builtin Types.
QualType VoidTy;
QualType BoolTy;
@@ -351,12 +365,6 @@ public:
ObjCProtocolDecl **ProtocolList,
unsigned NumProtocols);
- /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for a
- /// given 'id' and conforming protocol list.
- QualType getObjCQualifiedIdType(ObjCProtocolDecl **ProtocolList,
- unsigned NumProtocols);
-
-
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
diff --git a/include/clang/AST/CFG.h b/include/clang/AST/CFG.h
index 7a9ee01d4f62..e60e58e1ac23 100644
--- a/include/clang/AST/CFG.h
+++ b/include/clang/AST/CFG.h
@@ -17,17 +17,20 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
#include <list>
#include <vector>
#include <cassert>
+namespace llvm {
+ class raw_ostream;
+}
namespace clang {
class Stmt;
class Expr;
class CFG;
class PrinterHelper;
class BlockEdge;
+ class LangOptions;
/// CFGBlock - Represents a single basic block in a source-level CFG.
/// It consists of:
@@ -181,9 +184,9 @@ public:
unsigned getBlockID() const { return BlockID; }
- void dump(const CFG* cfg) const;
- void print(llvm::raw_ostream& OS, const CFG* cfg) const;
- void printTerminator(llvm::raw_ostream& OS) const;
+ void dump(const CFG *cfg, const LangOptions &LO) const;
+ void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
+ void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
};
@@ -283,9 +286,9 @@ public:
// CFG Debugging: Pretty-Printing and Visualization.
//===--------------------------------------------------------------------===//
- void viewCFG() const;
- void print(llvm::raw_ostream& OS) const;
- void dump() const;
+ void viewCFG(const LangOptions &LO) const;
+ void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
+ void dump(const LangOptions &LO) const;
//===--------------------------------------------------------------------===//
// Internal: constructors and data.
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 3de01f3baeb5..69a52869d818 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -26,13 +26,19 @@ class Stmt;
class CompoundStmt;
class StringLiteral;
class TemplateArgumentList;
+class FunctionTemplateSpecializationInfo;
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
- TranslationUnitDecl()
+ ASTContext &Ctx;
+
+ explicit TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, 0, SourceLocation()),
- DeclContext(TranslationUnit) {}
+ DeclContext(TranslationUnit),
+ Ctx(ctx) {}
public:
+ ASTContext &getASTContext() const { return Ctx; }
+
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
@@ -621,15 +627,8 @@ public:
enum StorageClass {
None, Extern, Static, PrivateExtern
};
-private:
- /// \brief Provides information about a function template specialization,
- /// which is a FunctionDecl that has been explicitly specialization or
- /// instantiated from a function template.
- struct TemplateSpecializationInfo {
- FunctionTemplateDecl *Template;
- const TemplateArgumentList *TemplateArguments;
- };
+private:
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
@@ -684,7 +683,8 @@ private:
/// the template being specialized and the template arguments involved in
/// that specialization.
llvm::PointerUnion3<FunctionTemplateDecl*, FunctionDecl*,
- TemplateSpecializationInfo*> TemplateOrSpecialization;
+ FunctionTemplateSpecializationInfo*>
+ TemplateOrSpecialization;
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -724,11 +724,11 @@ public:
/// function. The variant that accepts a FunctionDecl pointer will
/// set that function declaration to the actual declaration
/// containing the body (if there is one).
- Stmt *getBody(ASTContext &Context, const FunctionDecl *&Definition) const;
+ Stmt *getBody(const FunctionDecl *&Definition) const;
- virtual Stmt *getBody(ASTContext &Context) const {
+ virtual Stmt *getBody() const {
const FunctionDecl* Definition;
- return getBody(Context, Definition);
+ return getBody(Definition);
}
/// \brief If the function has a body that is immediately available,
@@ -809,9 +809,7 @@ public:
return PreviousDeclaration;
}
- void setPreviousDeclaration(FunctionDecl * PrevDecl) {
- PreviousDeclaration = PrevDecl;
- }
+ void setPreviousDeclaration(FunctionDecl * PrevDecl);
unsigned getBuiltinID(ASTContext &Context) const;
@@ -940,27 +938,14 @@ public:
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
- FunctionTemplateDecl *getPrimaryTemplate() const {
- if (TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) {
- return Info->Template;
- }
- return 0;
- }
+ FunctionTemplateDecl *getPrimaryTemplate() const;
/// \brief Retrieve the template arguments used to produce this function
/// template specialization from the primary template.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
- const TemplateArgumentList *getTemplateSpecializationArgs() const {
- if (TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) {
- return Info->TemplateArguments;
- }
- return 0;
- }
-
+ const TemplateArgumentList *getTemplateSpecializationArgs() const;
/// \brief Specify that this function declaration is actually a function
/// template specialization.
@@ -974,8 +959,17 @@ public:
/// function template specialization from the template.
void setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs);
-
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos);
+
+ /// \brief Determine whether this is an explicit specialization of a
+ /// function template or a member function of a class template.
+ bool isExplicitSpecialization() const;
+
+ /// \brief Note that this is an explicit specialization of a function template
+ /// or a member function of a class template.
+ void setExplicitSpecialization(bool ES);
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
@@ -1268,12 +1262,12 @@ public:
// enumeration.
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
- enumerator_iterator enumerator_begin(ASTContext &Context) const {
- return enumerator_iterator(this->decls_begin(Context));
+ enumerator_iterator enumerator_begin() const {
+ return enumerator_iterator(this->decls_begin());
}
- enumerator_iterator enumerator_end(ASTContext &Context) const {
- return enumerator_iterator(this->decls_end(Context));
+ enumerator_iterator enumerator_end() const {
+ return enumerator_iterator(this->decls_end());
}
/// getIntegerType - Return the integer type this enum decl corresponds to.
@@ -1376,17 +1370,17 @@ public:
// data members, functions, constructors, destructors, etc.
typedef specific_decl_iterator<FieldDecl> field_iterator;
- field_iterator field_begin(ASTContext &Context) const {
- return field_iterator(decls_begin(Context));
+ field_iterator field_begin() const {
+ return field_iterator(decls_begin());
}
- field_iterator field_end(ASTContext &Context) const {
- return field_iterator(decls_end(Context));
+ field_iterator field_end() const {
+ return field_iterator(decls_end());
}
// field_empty - Whether there are any fields (non-static data
// members) in this record.
- bool field_empty(ASTContext &Context) const {
- return field_begin(Context) == field_end(Context);
+ bool field_empty() const {
+ return field_begin() == field_end();
}
/// completeDefinition - Notes that the definition of this type is
@@ -1448,8 +1442,8 @@ public:
bool IsVariadic() const { return isVariadic; }
void setIsVariadic(bool value) { isVariadic = value; }
- CompoundStmt *getBody() const { return (CompoundStmt*) Body; }
- Stmt *getBody(ASTContext &C) const { return (Stmt*) Body; }
+ CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
+ Stmt *getBody() const { return (Stmt*) Body; }
void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
// Iterator access to formal parameters.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index c959b05473fe..0bce2f84c7ba 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -213,6 +213,13 @@ public:
const DeclContext *getDeclContext() const {
return const_cast<Decl*>(this)->getDeclContext();
}
+
+ TranslationUnitDecl *getTranslationUnitDecl();
+ const TranslationUnitDecl *getTranslationUnitDecl() const {
+ return const_cast<Decl*>(this)->getTranslationUnitDecl();
+ }
+
+ ASTContext &getASTContext() const;
void setAccess(AccessSpecifier AS) {
Access = AS;
@@ -225,23 +232,23 @@ public:
}
bool hasAttrs() const { return HasAttrs; }
- void addAttr(ASTContext &Context, Attr *attr);
- const Attr *getAttrs(ASTContext &Context) const {
+ void addAttr(Attr *attr);
+ const Attr *getAttrs() const {
if (!HasAttrs) return 0; // common case, no attributes.
- return getAttrsImpl(Context); // Uncommon case, out of line hash lookup.
+ return getAttrsImpl(); // Uncommon case, out of line hash lookup.
}
- void swapAttrs(ASTContext &Context, Decl *D);
- void invalidateAttrs(ASTContext &Context);
+ void swapAttrs(Decl *D);
+ void invalidateAttrs();
- template<typename T> const T *getAttr(ASTContext &Context) const {
- for (const Attr *attr = getAttrs(Context); attr; attr = attr->getNext())
+ template<typename T> const T *getAttr() const {
+ for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
if (const T *V = dyn_cast<T>(attr))
return V;
return 0;
}
- template<typename T> bool hasAttr(ASTContext &Context) const {
- return getAttr<T>(Context) != 0;
+ template<typename T> bool hasAttr() const {
+ return getAttr<T>() != 0;
}
/// setInvalidDecl - Indicates the Decl had a semantic error. This
@@ -307,14 +314,14 @@ public:
/// getBody - If this Decl represents a declaration for a body of code,
/// such as a function or method definition, this method returns the
/// top-level Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody(ASTContext &Context) const { return 0; }
+ virtual Stmt* getBody() const { return 0; }
/// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
- CompoundStmt* getCompoundBody(ASTContext &Context) const;
+ CompoundStmt* getCompoundBody() const;
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
/// This works whether the body is a CompoundStmt or a CXXTryStmt.
- SourceLocation getBodyRBrace(ASTContext &Context) const;
+ SourceLocation getBodyRBrace() const;
// global temp stats (until we have a per-module visitor)
static void addDeclKind(Kind k);
@@ -340,18 +347,16 @@ public:
/// Destroy - Call destructors and release memory.
virtual void Destroy(ASTContext& C);
- void print(llvm::raw_ostream &Out, ASTContext &Context,
+ void print(llvm::raw_ostream &Out, unsigned Indentation = 0);
+ void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
- void print(llvm::raw_ostream &Out, ASTContext &Context,
- const PrintingPolicy &Policy, unsigned Indentation = 0);
static void printGroup(Decl** Begin, unsigned NumDecls,
- llvm::raw_ostream &Out, ASTContext &Context,
- const PrintingPolicy &Policy,
+ llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
- void dump(ASTContext &Context);
+ void dump();
private:
- const Attr *getAttrsImpl(ASTContext &Context) const;
+ const Attr *getAttrsImpl() const;
};
@@ -454,7 +459,11 @@ public:
const DeclContext *getLexicalParent() const {
return const_cast<DeclContext*>(this)->getLexicalParent();
}
-
+
+ ASTContext &getParentASTContext() const {
+ return cast<Decl>(this)->getASTContext();
+ }
+
bool isFunctionOrMethod() const {
switch (DeclKind) {
case Decl::Block:
@@ -592,9 +601,9 @@ public:
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
- decl_iterator decls_begin(ASTContext &Context) const;
- decl_iterator decls_end(ASTContext &Context) const;
- bool decls_empty(ASTContext &Context) const;
+ decl_iterator decls_begin() const;
+ decl_iterator decls_end() const;
+ bool decls_empty() const;
/// specific_decl_iterator - Iterates over a subrange of
/// declarations stored in a DeclContext, providing only those that
@@ -750,7 +759,7 @@ public:
///
/// If D is also a NamedDecl, it will be made visible within its
/// semantic context via makeDeclVisibleInContext.
- void addDecl(ASTContext &Context, Decl *D);
+ void addDecl(Decl *D);
/// lookup_iterator - An iterator that provides access to the results
/// of looking up a name within this context.
@@ -769,8 +778,8 @@ public:
/// the declarations with this name, with object, function, member,
/// and enumerator names preceding any tag name. Note that this
/// routine will not look into parent contexts.
- lookup_result lookup(ASTContext &Context, DeclarationName Name);
- lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const;
+ lookup_result lookup(DeclarationName Name);
+ lookup_const_result lookup(DeclarationName Name) const;
/// @brief Makes a declaration visible within this context.
///
@@ -786,7 +795,7 @@ public:
/// visible from this context, as determined by
/// NamedDecl::declarationReplaces, the previous declaration will be
/// replaced with D.
- void makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D);
+ void makeDeclVisibleInContext(NamedDecl *D);
/// udir_iterator - Iterates through the using-directives stored
/// within this context.
@@ -794,14 +803,14 @@ public:
typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
- udir_iterator_range getUsingDirectives(ASTContext &Context) const;
+ udir_iterator_range getUsingDirectives() const;
- udir_iterator using_directives_begin(ASTContext &Context) const {
- return getUsingDirectives(Context).first;
+ udir_iterator using_directives_begin() const {
+ return getUsingDirectives().first;
}
- udir_iterator using_directives_end(ASTContext &Context) const {
- return getUsingDirectives(Context).second;
+ udir_iterator using_directives_end() const {
+ return getUsingDirectives().second;
}
// Low-level accessors
@@ -836,11 +845,11 @@ public:
#include "clang/AST/DeclNodes.def"
private:
- void LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const;
- void LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const;
+ void LoadLexicalDeclsFromExternalStorage() const;
+ void LoadVisibleDeclsFromExternalStorage() const;
- void buildLookup(ASTContext &Context, DeclContext *DCtx);
- void makeDeclVisibleInContextImpl(ASTContext &Context, NamedDecl *D);
+ void buildLookup(DeclContext *DCtx);
+ void makeDeclVisibleInContextImpl(NamedDecl *D);
};
inline bool Decl::isTemplateParameter() const {
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a2fe24e83105..c523e96e03b0 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -32,6 +32,8 @@ class ClassTemplateSpecializationDecl;
class AnyFunctionDecl {
NamedDecl *Function;
+ AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+
public:
AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
AnyFunctionDecl(FunctionTemplateDecl *FTD);
@@ -42,6 +44,10 @@ public:
/// \brief Retrieve the underlying function or function template.
NamedDecl *get() const { return Function; }
+
+ static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
+ return AnyFunctionDecl(ND);
+ }
};
} // end namespace clang
@@ -57,6 +63,22 @@ namespace llvm {
};
template<> struct simplify_type< ::clang::AnyFunctionDecl>
: public simplify_type<const ::clang::AnyFunctionDecl> {};
+
+ // Provide PointerLikeTypeTraits for non-cvr pointers.
+ template<>
+ class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
+ public:
+ static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
+ return F.get();
+ }
+ static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
+ return ::clang::AnyFunctionDecl::getFromNamedDecl(
+ static_cast< ::clang::NamedDecl*>(P));
+ }
+
+ enum { NumLowBitsAvailable = 2 };
+ };
+
} // end namespace llvm
namespace clang {
@@ -91,24 +113,10 @@ public:
static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
DeclarationName N);
- /// addOverload - Add an overloaded function FD to this set of
- /// overloaded functions.
- void addOverload(FunctionDecl *FD) {
- assert((FD->getDeclName() == getDeclName() ||
- isa<CXXConversionDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
- "Overloaded functions must have the same name");
- Functions.push_back(FD);
-
- // An overloaded function declaration always has the location of
- // the most-recently-added function declaration.
- if (FD->getLocation().isValid())
- this->setLocation(FD->getLocation());
- }
+ /// \brief Add a new overloaded function or function template to the set
+ /// of overloaded function templates.
+ void addOverload(AnyFunctionDecl F);
- /// addOverload - Add an overloaded function template FTD to this set of
- /// overloaded functions.
- void addOverload(FunctionTemplateDecl *FTD);
-
function_iterator function_begin() { return Functions.begin(); }
function_iterator function_end() { return Functions.end(); }
function_const_iterator function_begin() const { return Functions.begin(); }
@@ -289,8 +297,11 @@ public:
CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
+ virtual void Destroy(ASTContext& C);
+
/// setBases - Sets the base classes of this struct or class.
- void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+ void setBases(ASTContext &C,
+ CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// getNumBases - Retrieves the number of base classes of this
/// class.
@@ -580,15 +591,20 @@ class CXXBaseOrMemberInitializer {
/// Args - The arguments used to initialize the base or member.
Expr **Args;
unsigned NumArgs;
+
+ /// IdLoc - Location of the id in ctor-initializer list.
+ SourceLocation IdLoc;
public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
- CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs);
+ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
+ SourceLocation L);
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
explicit
- CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs);
+ CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
+ SourceLocation L);
/// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
~CXXBaseOrMemberInitializer();
@@ -601,6 +617,10 @@ public:
/// arguments.
typedef Expr * const * arg_const_iterator;
+ /// getBaseOrMember - get the generic 'member' representing either the field
+ /// or a base class.
+ void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); }
+
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
@@ -641,6 +661,8 @@ public:
return 0;
}
+ SourceLocation getSourceLocation() const { return IdLoc; }
+
/// begin() - Retrieve an iterator to the first initializer argument.
arg_iterator begin() { return Args; }
/// begin() - Retrieve an iterator to the first initializer argument.
@@ -677,16 +699,22 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// @c !Implicit && ImplicitlyDefined.
bool ImplicitlyDefined : 1;
- /// FIXME: Add support for base and member initializers.
-
+ /// Support for base and member initializers.
+ /// BaseOrMemberInitializers - The arguments used to initialize the base
+ /// or member.
+ CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
+ unsigned NumBaseOrMemberInitializers;
+
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isExplicit, bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline),
- Explicit(isExplicit), ImplicitlyDefined(false) {
+ Explicit(isExplicit), ImplicitlyDefined(false),
+ BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
-
+ virtual void Destroy(ASTContext& C);
+
public:
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@@ -702,7 +730,8 @@ public:
/// already been defined.
bool isImplicitlyDefined(ASTContext &C) const {
assert(isThisDeclarationADefinition() &&
- "Can only get the implicit-definition flag once the constructor has been defined");
+ "Can only get the implicit-definition flag once the "
+ "constructor has been defined");
return ImplicitlyDefined;
}
@@ -710,10 +739,41 @@ public:
/// implicitly defined or not.
void setImplicitlyDefined(bool ID) {
assert(isThisDeclarationADefinition() &&
- "Can only set the implicit-definition flag once the constructor has been defined");
+ "Can only set the implicit-definition flag once the constructor "
+ "has been defined");
ImplicitlyDefined = ID;
}
+ /// init_iterator - Iterates through the member/base initializer list.
+ typedef CXXBaseOrMemberInitializer **init_iterator;
+
+ /// init_const_iterator - Iterates through the memberbase initializer list.
+ typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_iterator begin() { return BaseOrMemberInitializers; }
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_const_iterator begin() const { return BaseOrMemberInitializers; }
+
+ /// end() - Retrieve an iterator past the last initializer.
+ init_iterator end() {
+ return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ }
+ /// end() - Retrieve an iterator past the last initializer.
+ init_const_iterator end() const {
+ return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ }
+
+ /// getNumArgs - Determine the number of arguments used to
+ /// initialize the member or base.
+ unsigned getNumBaseOrMemberInitializers() const {
+ return NumBaseOrMemberInitializers;
+ }
+
+ void setBaseOrMemberInitializers(ASTContext &C,
+ CXXBaseOrMemberInitializer **Initializers,
+ unsigned NumInitializers);
+
/// isDefaultConstructor - Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
/// default-initialize a class of this type.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 3943ddc19638..2fcdaa3e2959 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -242,10 +242,10 @@ public:
return ImplementationControl(DeclImplementation);
}
- virtual Stmt *getBody(ASTContext &C) const {
+ virtual Stmt *getBody() const {
return (Stmt*) Body;
}
- CompoundStmt *getBody() { return (CompoundStmt*)Body; }
+ CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
void setBody(Stmt *B) { Body = B; }
// Implement isa/cast/dyncast/etc.
@@ -291,55 +291,52 @@ public:
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
- prop_iterator prop_begin(ASTContext &Context) const {
- return prop_iterator(decls_begin(Context));
+ prop_iterator prop_begin() const {
+ return prop_iterator(decls_begin());
}
- prop_iterator prop_end(ASTContext &Context) const {
- return prop_iterator(decls_end(Context));
+ prop_iterator prop_end() const {
+ return prop_iterator(decls_end());
}
// Iterator access to instance/class methods.
typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
- method_iterator meth_begin(ASTContext &Context) const {
- return method_iterator(decls_begin(Context));
+ method_iterator meth_begin() const {
+ return method_iterator(decls_begin());
}
- method_iterator meth_end(ASTContext &Context) const {
- return method_iterator(decls_end(Context));
+ method_iterator meth_end() const {
+ return method_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
- instmeth_iterator instmeth_begin(ASTContext &Context) const {
- return instmeth_iterator(decls_begin(Context));
+ instmeth_iterator instmeth_begin() const {
+ return instmeth_iterator(decls_begin());
}
- instmeth_iterator instmeth_end(ASTContext &Context) const {
- return instmeth_iterator(decls_end(Context));
+ instmeth_iterator instmeth_end() const {
+ return instmeth_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
- classmeth_iterator classmeth_begin(ASTContext &Context) const {
- return classmeth_iterator(decls_begin(Context));
+ classmeth_iterator classmeth_begin() const {
+ return classmeth_iterator(decls_begin());
}
- classmeth_iterator classmeth_end(ASTContext &Context) const {
- return classmeth_iterator(decls_end(Context));
+ classmeth_iterator classmeth_end() const {
+ return classmeth_iterator(decls_end());
}
// Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const;
- ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const;
- ObjCIvarDecl *getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const;
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
+ ObjCMethodDecl *getClassMethod(Selector Sel) const;
+ ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
- ObjCMethodDecl *
- getMethod(ASTContext &Context, Selector Sel, bool isInstance) const {
- return isInstance ? getInstanceMethod(Context, Sel)
- : getClassMethod(Context, Sel);
+ ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
+ return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
}
- ObjCPropertyDecl *FindPropertyDeclaration(ASTContext &Context,
- IdentifierInfo *PropertyId) const;
+ ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
// Marks the end of the container.
SourceLocation getAtEndLoc() const { return AtEndLoc; }
@@ -474,19 +471,17 @@ public:
return false;
}
- ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context,
- IdentifierInfo *IVarName,
+ ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context,
- IdentifierInfo *IVarName) {
+ ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(Context, IVarName, ClassDeclared);
+ return lookupInstanceVariable(IVarName, ClassDeclared);
}
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel);
- ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel);
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
+ ObjCMethodDecl *lookupClassMethod(Selector Sel);
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
// Location information, modeled after the Stmt API.
@@ -648,8 +643,8 @@ public:
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel);
- ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel);
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
+ ObjCMethodDecl *lookupClassMethod(Selector Sel);
bool isForwardDecl() const { return isForwardProtoDecl; }
void setForwardDecl(bool val) { isForwardProtoDecl = val; }
@@ -831,61 +826,57 @@ public:
ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
void setClassInterface(ObjCInterfaceDecl *IFace) { ClassInterface = IFace; }
- void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ void addInstanceMethod(ObjCMethodDecl *method) {
// FIXME: Context should be set correctly before we get here.
method->setLexicalDeclContext(this);
- addDecl(Context, method);
+ addDecl(method);
}
- void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ void addClassMethod(ObjCMethodDecl *method) {
// FIXME: Context should be set correctly before we get here.
method->setLexicalDeclContext(this);
- addDecl(Context, method);
+ addDecl(method);
}
// Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const;
- ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const;
- ObjCMethodDecl *getMethod(ASTContext &Context, Selector Sel,
- bool isInstance) const {
- return isInstance ? getInstanceMethod(Context, Sel)
- : getClassMethod(Context, Sel);
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
+ ObjCMethodDecl *getClassMethod(Selector Sel) const;
+ ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
+ return isInstance ? getInstanceMethod(Sel)
+ : getClassMethod(Sel);
}
- void addPropertyImplementation(ASTContext &Context,
- ObjCPropertyImplDecl *property);
+ void addPropertyImplementation(ObjCPropertyImplDecl *property);
- ObjCPropertyImplDecl *FindPropertyImplDecl(ASTContext &Context,
- IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(ASTContext &Context,
- IdentifierInfo *ivarId) const;
+ ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
+ ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
- propimpl_iterator propimpl_begin(ASTContext &Context) const {
- return propimpl_iterator(decls_begin(Context));
+ propimpl_iterator propimpl_begin() const {
+ return propimpl_iterator(decls_begin());
}
- propimpl_iterator propimpl_end(ASTContext &Context) const {
- return propimpl_iterator(decls_end(Context));
+ propimpl_iterator propimpl_end() const {
+ return propimpl_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
- instmeth_iterator instmeth_begin(ASTContext &Context) const {
- return instmeth_iterator(decls_begin(Context));
+ instmeth_iterator instmeth_begin() const {
+ return instmeth_iterator(decls_begin());
}
- instmeth_iterator instmeth_end(ASTContext &Context) const {
- return instmeth_iterator(decls_end(Context));
+ instmeth_iterator instmeth_end() const {
+ return instmeth_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
- classmeth_iterator classmeth_begin(ASTContext &Context) const {
- return classmeth_iterator(decls_begin(Context));
+ classmeth_iterator classmeth_begin() const {
+ return classmeth_iterator(decls_begin());
}
- classmeth_iterator classmeth_end(ASTContext &Context) const {
- return classmeth_iterator(decls_end(Context));
+ classmeth_iterator classmeth_end() const {
+ return classmeth_iterator(decls_end());
}
// Location information, modeled after the Stmt API.
@@ -1002,17 +993,17 @@ public:
void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- ivar_iterator ivar_begin(ASTContext &Context) const {
- return ivar_iterator(decls_begin(Context));
+ ivar_iterator ivar_begin() const {
+ return ivar_iterator(decls_begin());
}
- ivar_iterator ivar_end(ASTContext &Context) const {
- return ivar_iterator(decls_end(Context));
+ ivar_iterator ivar_end() const {
+ return ivar_iterator(decls_end());
}
- unsigned ivar_size(ASTContext &Context) const {
- return std::distance(ivar_begin(Context), ivar_end(Context));
+ unsigned ivar_size() const {
+ return std::distance(ivar_begin(), ivar_end());
}
- bool ivar_empty(ASTContext &Context) const {
- return ivar_begin(Context) == ivar_end(Context);
+ bool ivar_empty() const {
+ return ivar_begin() == ivar_end();
}
static bool classof(const Decl *D) {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index aad19a63ef0f..5d0fe158e054 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -100,6 +100,352 @@ public:
}
};
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+ union {
+ uintptr_t TypeOrValue;
+ struct {
+ char Value[sizeof(llvm::APSInt)];
+ void *Type;
+ } Integer;
+ struct {
+ TemplateArgument *Args;
+ unsigned NumArgs;
+ bool CopyArgs;
+ } Args;
+ };
+
+ /// \brief Location of the beginning of this template argument.
+ SourceLocation StartLoc;
+
+public:
+ /// \brief The type of template argument we're storing.
+ enum ArgKind {
+ Null = 0,
+ /// The template argument is a type. Its value is stored in the
+ /// TypeOrValue field.
+ Type = 1,
+ /// The template argument is a declaration
+ Declaration = 2,
+ /// The template argument is an integral value stored in an llvm::APSInt.
+ Integral = 3,
+ /// The template argument is a value- or type-dependent expression
+ /// stored in an Expr*.
+ Expression = 4,
+
+ /// The template argument is actually a parameter pack. Arguments are stored
+ /// in the Args struct.
+ Pack = 5
+ } Kind;
+
+ /// \brief Construct an empty, invalid template argument.
+ TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
+
+ /// \brief Construct a template type argument.
+ TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct a template argument that refers to a
+ /// declaration, which is either an external declaration or a
+ /// template declaration.
+ TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
+ // FIXME: Need to be sure we have the "canonical" declaration!
+ TypeOrValue = reinterpret_cast<uintptr_t>(D);
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct an integral constant template argument.
+ TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
+ QualType Type)
+ : Kind(Integral) {
+ new (Integer.Value) llvm::APSInt(Value);
+ Integer.Type = Type.getAsOpaquePtr();
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct a template argument that is an expression.
+ ///
+ /// This form of template argument only occurs in template argument
+ /// lists used for dependent types and for expression; it will not
+ /// occur in a non-dependent, canonical template argument list.
+ TemplateArgument(Expr *E);
+
+ /// \brief Copy constructor for a template argument.
+ TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ if (Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else if (Kind == Pack) {
+ Args.NumArgs = Other.Args.NumArgs;
+ Args.Args = new TemplateArgument[Args.NumArgs];
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I] = Other.Args.Args[I];
+ }
+ else
+ TypeOrValue = Other.TypeOrValue;
+ StartLoc = Other.StartLoc;
+ }
+
+ TemplateArgument& operator=(const TemplateArgument& Other) {
+ // FIXME: Does not provide the strong guarantee for exception
+ // safety.
+ using llvm::APSInt;
+
+ // FIXME: Handle Packs
+ assert(Kind != Pack && "FIXME: Handle packs");
+ assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+ if (Kind == Other.Kind && Kind == Integral) {
+ // Copy integral values.
+ *this->getAsIntegral() = *Other.getAsIntegral();
+ Integer.Type = Other.Integer.Type;
+ } else {
+ // Destroy the current integral value, if that's what we're holding.
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+
+ Kind = Other.Kind;
+
+ if (Other.Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else
+ TypeOrValue = Other.TypeOrValue;
+ }
+ StartLoc = Other.StartLoc;
+
+ return *this;
+ }
+
+ ~TemplateArgument() {
+ using llvm::APSInt;
+
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+ else if (Kind == Pack && Args.CopyArgs)
+ delete[] Args.Args;
+ }
+
+ /// \brief Return the kind of stored template argument.
+ ArgKind getKind() const { return Kind; }
+
+ /// \brief Determine whether this template argument has no value.
+ bool isNull() const { return Kind == Null; }
+
+ /// \brief Retrieve the template argument as a type.
+ QualType getAsType() const {
+ if (Kind != Type)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(
+ reinterpret_cast<void*>(TypeOrValue));
+ }
+
+ /// \brief Retrieve the template argument as a declaration.
+ Decl *getAsDecl() const {
+ if (Kind != Declaration)
+ return 0;
+ return reinterpret_cast<Decl *>(TypeOrValue);
+ }
+
+ /// \brief Retrieve the template argument as an integral value.
+ llvm::APSInt *getAsIntegral() {
+ if (Kind != Integral)
+ return 0;
+ return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+ }
+
+ const llvm::APSInt *getAsIntegral() const {
+ return const_cast<TemplateArgument*>(this)->getAsIntegral();
+ }
+
+ /// \brief Retrieve the type of the integral value.
+ QualType getIntegralType() const {
+ if (Kind != Integral)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(Integer.Type);
+ }
+
+ void setIntegralType(QualType T) {
+ assert(Kind == Integral &&
+ "Cannot set the integral type of a non-integral template argument");
+ Integer.Type = T.getAsOpaquePtr();
+ };
+
+ /// \brief Retrieve the template argument as an expression.
+ Expr *getAsExpr() const {
+ if (Kind != Expression)
+ return 0;
+
+ return reinterpret_cast<Expr *>(TypeOrValue);
+ }
+
+ /// \brief Iterator that traverses the elements of a template argument pack.
+ typedef const TemplateArgument * pack_iterator;
+
+ /// \brief Iterator referencing the first argument of a template argument
+ /// pack.
+ pack_iterator pack_begin() const {
+ assert(Kind == Pack);
+ return Args.Args;
+ }
+
+ /// \brief Iterator referencing one past the last argument of a template
+ /// argument pack.
+ pack_iterator pack_end() const {
+ assert(Kind == Pack);
+ return Args.Args + Args.NumArgs;
+ }
+
+ /// \brief The number of template arguments in the given template argument
+ /// pack.
+ unsigned pack_size() const {
+ assert(Kind == Pack);
+ return Args.NumArgs;
+ }
+
+ /// \brief Retrieve the location where the template argument starts.
+ SourceLocation getLocation() const { return StartLoc; }
+
+ /// \brief Construct a template argument pack.
+ void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+ /// \brief Used to insert TemplateArguments into FoldingSets.
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(Kind);
+ switch (Kind) {
+ case Null:
+ break;
+
+ case Type:
+ getAsType().Profile(ID);
+ break;
+
+ case Declaration:
+ ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
+ break;
+
+ case Integral:
+ getAsIntegral()->Profile(ID);
+ getIntegralType().Profile(ID);
+ break;
+
+ case Expression:
+ // FIXME: We need a canonical representation of expressions.
+ ID.AddPointer(getAsExpr());
+ break;
+
+ case Pack:
+ ID.AddInteger(Args.NumArgs);
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I].Profile(ID);
+ }
+ }
+};
+
+/// \brief A helper class for making template argument lists.
+class TemplateArgumentListBuilder {
+ TemplateArgument *StructuredArgs;
+ unsigned MaxStructuredArgs;
+ unsigned NumStructuredArgs;
+
+ TemplateArgument *FlatArgs;
+ unsigned MaxFlatArgs;
+ unsigned NumFlatArgs;
+
+ bool AddingToPack;
+ unsigned PackBeginIndex;
+
+public:
+ TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
+ unsigned NumTemplateArgs)
+ : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
+ NumStructuredArgs(0), FlatArgs(0),
+ MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
+ AddingToPack(false), PackBeginIndex(0) { }
+
+ void Append(const TemplateArgument& Arg);
+ void BeginPack();
+ void EndPack();
+
+ void ReleaseArgs();
+
+ unsigned flatSize() const {
+ return NumFlatArgs;
+ }
+ const TemplateArgument *getFlatArguments() const {
+ return FlatArgs;
+ }
+
+ unsigned structuredSize() const {
+ // If we don't have any structured args, just reuse the flat size.
+ if (!StructuredArgs)
+ return flatSize();
+
+ return NumStructuredArgs;
+ }
+ const TemplateArgument *getStructuredArguments() const {
+ // If we don't have any structured args, just reuse the flat args.
+ if (!StructuredArgs)
+ return getFlatArguments();
+
+ return StructuredArgs;
+ }
+};
+
+/// \brief A template argument list.
+///
+/// FIXME: In the future, this class will be extended to support
+/// variadic templates and member templates, which will make some of
+/// the function names below make more sense.
+class TemplateArgumentList {
+ /// \brief The template argument list.
+ ///
+ /// The integer value will be non-zero to indicate that this
+ /// template argument list does not own the pointer.
+ llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+
+ /// \brief The number of template arguments in this template
+ /// argument list.
+ unsigned NumFlatArguments;
+
+ llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
+ unsigned NumStructuredArguments;
+
+public:
+ TemplateArgumentList(ASTContext &Context,
+ TemplateArgumentListBuilder &Builder,
+ bool TakeArgs);
+
+ ~TemplateArgumentList();
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &get(unsigned Idx) const {
+ assert(Idx < NumFlatArguments && "Invalid template argument index");
+ return getFlatArgumentList()[Idx];
+ }
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+
+ /// \brief Retrieve the number of template arguments in this
+ /// template argument list.
+ unsigned size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the number of template arguments in the
+ /// flattened template argument list.
+ unsigned flat_size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the flattened template argument list.
+ const TemplateArgument *getFlatArgumentList() const {
+ return FlatArguments.getPointer();
+ }
+};
+
//===----------------------------------------------------------------------===//
// Kinds of Templates
//===----------------------------------------------------------------------===//
@@ -154,18 +500,110 @@ protected:
TemplateParameterList* TemplateParams;
};
+/// \brief Provides information about a function template specialization,
+/// which is a FunctionDecl that has been explicitly specialization or
+/// instantiated from a function template.
+class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
+public:
+ /// \brief The function template specialization that this structure
+ /// describes.
+ FunctionDecl *Function;
+
+ /// \brief The function template from which this function template
+ /// specialization was generated.
+ ///
+ /// The bit will be 0 for an implicit instantiation, 1 for an explicit
+ /// specialization.
+ llvm::PointerIntPair<FunctionTemplateDecl *, 1> Template;
+
+ /// \brief The template arguments used to produce the function template
+ /// specialization from the function template.
+ const TemplateArgumentList *TemplateArguments;
+
+ /// \brief Retrieve the template from which this function was specialized.
+ FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
+
+ /// \brief Determine whether this is an explicit specialization.
+ bool isExplicitSpecialization() const { return Template.getInt(); }
+
+ /// \brief Set whether this is an explicit specialization or an implicit
+ /// instantiation.
+ void setExplicitSpecialization(bool ES) {
+ Template.setInt(ES);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, TemplateArguments->getFlatArgumentList(),
+ TemplateArguments->flat_size());
+ }
+
+ static void
+ Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs) {
+ ID.AddInteger(NumTemplateArgs);
+ for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ TemplateArgs[Arg].Profile(ID);
+ }
+};
+
/// Declaration of a template function.
-class FunctionTemplateDecl : public TemplateDecl {
+class FunctionTemplateDecl : public TemplateDecl {
protected:
+ /// \brief Data that is common to all of the declarations of a given
+ /// function template.
+ struct Common {
+ /// \brief The function template specializations for this function
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+ };
+
+ /// \brief A pointer to the previous declaration (if this is a redeclaration)
+ /// or to the data that is common to all declarations of this function
+ /// template.
+ llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
+
+ /// \brief Retrieves the "common" pointer shared by all
+ /// (re-)declarations of the same function template. Calling this routine
+ /// may implicitly allocate memory for the common pointer.
+ Common *getCommonPtr();
+
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+ : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
+ CommonOrPrev((Common*)0) { }
+
public:
- /// Get the underling function declaration of the template.
+ void Destroy(ASTContext &C);
+
+ /// Get the underlying function declaration of the template.
FunctionDecl *getTemplatedDecl() const {
return static_cast<FunctionDecl*>(TemplatedDecl);
}
+ /// \brief Retrieve the set of function template specializations of this
+ /// function template.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+ return getCommonPtr()->Specializations;
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ const FunctionTemplateDecl *getPreviousDeclaration() const {
+ return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ FunctionTemplateDecl *getPreviousDeclaration() {
+ return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ /// \brief Set the previous declaration of this function template.
+ void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
+ if (Prev)
+ CommonOrPrev = Prev;
+ }
+
/// Create a template function node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -396,352 +834,6 @@ public:
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
};
-/// \brief Represents a template argument within a class template
-/// specialization.
-class TemplateArgument {
- union {
- uintptr_t TypeOrValue;
- struct {
- char Value[sizeof(llvm::APSInt)];
- void *Type;
- } Integer;
- struct {
- TemplateArgument *Args;
- unsigned NumArgs;
- bool CopyArgs;
- } Args;
- };
-
- /// \brief Location of the beginning of this template argument.
- SourceLocation StartLoc;
-
-public:
- /// \brief The type of template argument we're storing.
- enum ArgKind {
- Null = 0,
- /// The template argument is a type. Its value is stored in the
- /// TypeOrValue field.
- Type = 1,
- /// The template argument is a declaration
- Declaration = 2,
- /// The template argument is an integral value stored in an llvm::APSInt.
- Integral = 3,
- /// The template argument is a value- or type-dependent expression
- /// stored in an Expr*.
- Expression = 4,
-
- /// The template argument is actually a parameter pack. Arguments are stored
- /// in the Args struct.
- Pack = 5
- } Kind;
-
- /// \brief Construct an empty, invalid template argument.
- TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
-
- /// \brief Construct a template type argument.
- TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
- TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
- // FIXME: Need to be sure we have the "canonical" declaration!
- TypeOrValue = reinterpret_cast<uintptr_t>(D);
- StartLoc = Loc;
- }
-
- /// \brief Construct an integral constant template argument.
- TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
- QualType Type)
- : Kind(Integral) {
- new (Integer.Value) llvm::APSInt(Value);
- Integer.Type = Type.getAsOpaquePtr();
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that is an expression.
- ///
- /// This form of template argument only occurs in template argument
- /// lists used for dependent types and for expression; it will not
- /// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E);
-
- /// \brief Copy constructor for a template argument.
- TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
- if (Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else if (Kind == Pack) {
- Args.NumArgs = Other.Args.NumArgs;
- Args.Args = new TemplateArgument[Args.NumArgs];
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I] = Other.Args.Args[I];
- }
- else
- TypeOrValue = Other.TypeOrValue;
- StartLoc = Other.StartLoc;
- }
-
- TemplateArgument& operator=(const TemplateArgument& Other) {
- // FIXME: Does not provide the strong guarantee for exception
- // safety.
- using llvm::APSInt;
-
- // FIXME: Handle Packs
- assert(Kind != Pack && "FIXME: Handle packs");
- assert(Other.Kind != Pack && "FIXME: Handle packs");
-
- if (Kind == Other.Kind && Kind == Integral) {
- // Copy integral values.
- *this->getAsIntegral() = *Other.getAsIntegral();
- Integer.Type = Other.Integer.Type;
- } else {
- // Destroy the current integral value, if that's what we're holding.
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
-
- Kind = Other.Kind;
-
- if (Other.Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else
- TypeOrValue = Other.TypeOrValue;
- }
- StartLoc = Other.StartLoc;
-
- return *this;
- }
-
- ~TemplateArgument() {
- using llvm::APSInt;
-
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
- else if (Kind == Pack && Args.CopyArgs)
- delete[] Args.Args;
- }
-
- /// \brief Return the kind of stored template argument.
- ArgKind getKind() const { return Kind; }
-
- /// \brief Determine whether this template argument has no value.
- bool isNull() const { return Kind == Null; }
-
- /// \brief Retrieve the template argument as a type.
- QualType getAsType() const {
- if (Kind != Type)
- return QualType();
-
- return QualType::getFromOpaquePtr(
- reinterpret_cast<void*>(TypeOrValue));
- }
-
- /// \brief Retrieve the template argument as a declaration.
- Decl *getAsDecl() const {
- if (Kind != Declaration)
- return 0;
- return reinterpret_cast<Decl *>(TypeOrValue);
- }
-
- /// \brief Retrieve the template argument as an integral value.
- llvm::APSInt *getAsIntegral() {
- if (Kind != Integral)
- return 0;
- return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
- }
-
- const llvm::APSInt *getAsIntegral() const {
- return const_cast<TemplateArgument*>(this)->getAsIntegral();
- }
-
- /// \brief Retrieve the type of the integral value.
- QualType getIntegralType() const {
- if (Kind != Integral)
- return QualType();
-
- return QualType::getFromOpaquePtr(Integer.Type);
- }
-
- void setIntegralType(QualType T) {
- assert(Kind == Integral &&
- "Cannot set the integral type of a non-integral template argument");
- Integer.Type = T.getAsOpaquePtr();
- };
-
- /// \brief Retrieve the template argument as an expression.
- Expr *getAsExpr() const {
- if (Kind != Expression)
- return 0;
-
- return reinterpret_cast<Expr *>(TypeOrValue);
- }
-
- /// \brief Iterator that traverses the elements of a template argument pack.
- typedef const TemplateArgument * pack_iterator;
-
- /// \brief Iterator referencing the first argument of a template argument
- /// pack.
- pack_iterator pack_begin() const {
- assert(Kind == Pack);
- return Args.Args;
- }
-
- /// \brief Iterator referencing one past the last argument of a template
- /// argument pack.
- pack_iterator pack_end() const {
- assert(Kind == Pack);
- return Args.Args + Args.NumArgs;
- }
-
- /// \brief The number of template arguments in the given template argument
- /// pack.
- unsigned pack_size() const {
- assert(Kind == Pack);
- return Args.NumArgs;
- }
-
- /// \brief Retrieve the location where the template argument starts.
- SourceLocation getLocation() const { return StartLoc; }
-
- /// \brief Construct a template argument pack.
- void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
-
- /// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Kind);
- switch (Kind) {
- case Null:
- break;
-
- case Type:
- getAsType().Profile(ID);
- break;
-
- case Declaration:
- ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
- break;
-
- case Integral:
- getAsIntegral()->Profile(ID);
- getIntegralType().Profile(ID);
- break;
-
- case Expression:
- // FIXME: We need a canonical representation of expressions.
- ID.AddPointer(getAsExpr());
- break;
-
- case Pack:
- ID.AddInteger(Args.NumArgs);
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I].Profile(ID);
- }
- }
-};
-
-/// \brief A helper class for making template argument lists.
-class TemplateArgumentListBuilder {
- TemplateArgument *StructuredArgs;
- unsigned MaxStructuredArgs;
- unsigned NumStructuredArgs;
-
- TemplateArgument *FlatArgs;
- unsigned MaxFlatArgs;
- unsigned NumFlatArgs;
-
- bool AddingToPack;
- unsigned PackBeginIndex;
-
-public:
- TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
- unsigned NumTemplateArgs)
- : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
- NumStructuredArgs(0), FlatArgs(0),
- MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
- AddingToPack(false), PackBeginIndex(0) { }
-
- void Append(const TemplateArgument& Arg);
- void BeginPack();
- void EndPack();
-
- void ReleaseArgs();
-
- unsigned flatSize() const {
- return NumFlatArgs;
- }
- const TemplateArgument *getFlatArguments() const {
- return FlatArgs;
- }
-
- unsigned structuredSize() const {
- // If we don't have any structured args, just reuse the flat size.
- if (!StructuredArgs)
- return flatSize();
-
- return NumStructuredArgs;
- }
- const TemplateArgument *getStructuredArguments() const {
- // If we don't have any structured args, just reuse the flat args.
- if (!StructuredArgs)
- return getFlatArguments();
-
- return StructuredArgs;
- }
-};
-
-/// \brief A template argument list.
-///
-/// FIXME: In the future, this class will be extended to support
-/// variadic templates and member templates, which will make some of
-/// the function names below make more sense.
-class TemplateArgumentList {
- /// \brief The template argument list.
- ///
- /// The integer value will be non-zero to indicate that this
- /// template argument list does not own the pointer.
- llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
-
- /// \brief The number of template arguments in this template
- /// argument list.
- unsigned NumFlatArguments;
-
- llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
- unsigned NumStructuredArguments;
-
-public:
- TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool TakeArgs);
-
- ~TemplateArgumentList();
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumFlatArguments && "Invalid template argument index");
- return getFlatArgumentList()[Idx];
- }
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
-
- /// \brief Retrieve the number of template arguments in this
- /// template argument list.
- unsigned size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the number of template arguments in the
- /// flattened template argument list.
- unsigned flat_size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the flattened template argument list.
- const TemplateArgument *getFlatArgumentList() const {
- return FlatArguments.getPointer();
- }
-};
-
// \brief Describes the kind of template specialization that a
// particular template specialization declaration represents.
enum TemplateSpecializationKind {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 2ed91124758d..6a1046e6d03f 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -124,7 +124,7 @@ public:
/// with location to warn on and the source range[s] to report with the
/// warning.
bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
- SourceRange &R2, ASTContext &Context) const;
+ SourceRange &R2) const;
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
/// incomplete type other than void. Nonarray expressions that can be lvalues:
@@ -467,9 +467,9 @@ class FloatingLiteral : public Expr {
bool IsExact : 1;
SourceLocation Loc;
public:
- FloatingLiteral(const llvm::APFloat &V, bool* isexact,
+ FloatingLiteral(const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L)
- : Expr(FloatingLiteralClass, Type), Value(V), IsExact(*isexact), Loc(L) {}
+ : Expr(FloatingLiteralClass, Type), Value(V), IsExact(isexact), Loc(L) {}
/// \brief Construct an empty floating-point literal.
explicit FloatingLiteral(EmptyShell Empty)
@@ -2433,9 +2433,6 @@ public:
const Stmt *getBody() const;
Stmt *getBody();
- const Stmt *getBody(ASTContext &C) const { return getBody(); }
- Stmt *getBody(ASTContext &C) { return getBody(); }
-
virtual SourceRange getSourceRange() const {
return SourceRange(getCaretLocation(), getBody()->getLocEnd());
}
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f9f5da129142..7d76a49d1267 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1017,6 +1017,100 @@ public:
virtual StmtIterator child_end();
};
+/// \brief An expression that refers to a C++ template-id, such as
+/// @c isa<FunctionDecl>.
+class TemplateIdRefExpr : public Expr {
+ /// \brief If this template-id was qualified-id, e.g., @c std::sort<int>,
+ /// this nested name specifier contains the @c std::.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief If this template-id was a qualified-id, e.g., @c std::sort<int>,
+ /// this covers the source code range of the @c std::.
+ SourceRange QualifierRange;
+
+ /// \brief The actual template to which this template-id refers.
+ TemplateName Template;
+
+ /// \brief The source location of the template name.
+ SourceLocation TemplateNameLoc;
+
+ /// \brief The source location of the left angle bracket ('<');
+ SourceLocation LAngleLoc;
+
+ /// \brief The source location of the right angle bracket ('>');
+ SourceLocation RAngleLoc;
+
+ /// \brief The number of template arguments in TemplateArgs.
+ unsigned NumTemplateArgs;
+
+ TemplateIdRefExpr(QualType T,
+ NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ TemplateName Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc);
+
+public:
+ static TemplateIdRefExpr *
+ Create(ASTContext &Context, QualType T,
+ NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ TemplateName Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc, const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs, SourceLocation RAngleLoc);
+
+ void Destroy(ASTContext &Context);
+
+ /// \brief Retrieve the nested name specifier used to qualify the name of
+ /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL
+ /// if this template-id was an unqualified-id.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Retrieve the source range describing the nested name specifier
+ /// used to qualified the name of this template-id, if the name was qualified.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Retrieve the name of the template referenced, e.g., "sort" in
+ /// @c std::sort<int>;
+ TemplateName getTemplateName() const { return Template; }
+
+ /// \brief Retrieve the location of the name of the template referenced, e.g.,
+ /// the location of "sort" in @c std::sort<int>.
+ SourceLocation getTemplateNameLoc() const { return TemplateNameLoc; }
+
+ /// \brief Retrieve the location of the left angle bracket following the
+ /// template name ('<').
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgument *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgument *>(this + 1);
+ }
+
+ /// \brief Retrieve the number of template arguments provided as part of this
+ /// template-id.
+ unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
+
+ /// \brief Retrieve the location of the right angle bracket following the
+ /// template arguments ('>').
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(Qualifier? QualifierRange.getBegin() : TemplateNameLoc,
+ RAngleLoc);
+ }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == TemplateIdRefExprClass;
+ }
+ static bool classof(const TemplateIdRefExpr *) { return true; }
+};
+
class CXXExprWithTemporaries : public Expr {
Stmt *SubExpr;
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 4219bd507a90..6f862a55d4ba 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -18,6 +18,7 @@
#include "clang/AST/Type.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
+#include <vector>
namespace clang {
class ASTConsumer;
@@ -57,6 +58,14 @@ public:
virtual ~ExternalASTSource();
+ /// \brief Reads the source ranges that correspond to comments from
+ /// an external AST source.
+ ///
+ /// \param Comments the contents of this vector will be
+ /// replaced with the sorted set of source ranges corresponding to
+ /// comments in the source code.
+ virtual void ReadComments(std::vector<SourceRange> &Comments) = 0;
+
/// \brief Resolve a type ID into a type, potentially building a new
/// type.
virtual QualType GetType(uint32_t ID) = 0;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 4eea1031f063..b304cc8e8a04 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -28,6 +28,7 @@ class NamespaceDecl;
class IdentifierInfo;
class PrintingPolicy;
class Type;
+class LangOptions;
/// \brief Represents a C++ nested name specifier, such as
/// "::std::vector<int>::".
@@ -175,7 +176,7 @@ public:
/// \brief Dump the nested name specifier to standard output to aid
/// in debugging.
- void dump();
+ void dump(const LangOptions &LO);
};
}
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 385602b1fb9c..6ad3a6bcc276 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -22,6 +22,7 @@ namespace clang {
class Stmt;
class TagDecl;
+class LangOptions;
class PrinterHelper {
public:
@@ -33,16 +34,15 @@ public:
/// declarations should be printed.
struct PrintingPolicy {
/// \brief Create a default printing policy for C.
- PrintingPolicy()
- : Indentation(2), CPlusPlus(false), SuppressSpecifiers(false),
+ PrintingPolicy(const LangOptions &LO)
+ : Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
SuppressTag(false), SuppressTagKind(false), Dump(false) { }
/// \brief The number of spaces to use to indent each line.
unsigned Indentation : 8;
- /// \brief Whether we're printing C++ code (otherwise, we're
- /// printing C code).
- bool CPlusPlus : 1;
+ /// \brief What language we're printing.
+ const LangOptions &LangOpts;
/// \brief Whether we should suppress printing of the actual specifiers for
/// the given type or declaration.
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index a8688f62e2d9..0a64dafd4e2c 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -187,14 +187,14 @@ public:
/// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
/// back to its original source language syntax.
void dumpPretty(ASTContext& Context) const;
- void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper = 0,
- const PrintingPolicy &Policy = PrintingPolicy(),
+ void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
unsigned Indentation = 0) const {
printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
}
- void printPretty(llvm::raw_ostream &OS, ASTContext& Context,
- PrinterHelper *Helper = 0,
- const PrintingPolicy &Policy = PrintingPolicy(),
+ void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
+ PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
unsigned Indentation = 0) const;
/// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index ab6524663d63..a95a62731186 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -9,7 +9,7 @@
//
// This file defines the AST Node info database.
//
-//===----------------------------------------------------------------------===//
+//===---------------------------------------------------------------------===//
#ifndef FIRST_STMT
#define FIRST_STMT(CLASS)
@@ -123,6 +123,7 @@ EXPR(UnresolvedFunctionNameExpr , Expr)
EXPR(UnaryTypeTraitExpr , Expr)
EXPR(QualifiedDeclRefExpr , DeclRefExpr)
EXPR(UnresolvedDeclRefExpr , Expr)
+EXPR(TemplateIdRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 321b1f204fcf..a00c0c4ff1c4 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -188,7 +188,8 @@ public:
getAsStringInternal(S, Policy);
return S;
}
- void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const;
+ void getAsStringInternal(std::string &Str,
+ const PrintingPolicy &Policy) const;
void dump(const char *s) const;
void dump() const;
@@ -375,6 +376,7 @@ public:
bool isFunctionProtoType() const { return getAsFunctionProtoType() != 0; }
bool isPointerType() const;
bool isBlockPointerType() const;
+ bool isVoidPointerType() const;
bool isReferenceType() const;
bool isLValueReferenceType() const;
bool isRValueReferenceType() const;
@@ -585,7 +587,7 @@ public:
TypeKind(K) {}
Kind getKind() const { return TypeKind; }
- const char *getName(bool CPlusPlus) const;
+ const char *getName(const LangOptions &LO) const;
virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 65ac0b53027c..5926229e517c 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -62,7 +62,6 @@ protected:
ASTContext &getContext() const;
public:
- // virtual MemExtent getExtent(MemRegionManager& mrm) const = 0;
virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
virtual MemRegionManager* getMemRegionManager() const = 0;
@@ -73,17 +72,25 @@ public:
bool hasStackStorage() const;
+ bool hasParametersStorage() const;
+
+ bool hasGlobalsStorage() const;
+
+ bool hasGlobalsOrParametersStorage() const;
+
bool hasHeapStorage() const;
bool hasHeapOrStackStorage() const;
- virtual void print(llvm::raw_ostream& os) const;
+ virtual void print(llvm::raw_ostream& os) const;
+
+ void printStdErr() const;
Kind getKind() const { return kind; }
template<typename RegionTy> const RegionTy* getAs() const;
- virtual bool isBoundable() const { return true; }
+ virtual bool isBoundable() const { return false; }
static bool classof(const MemRegion*) { return true; }
};
@@ -104,8 +111,6 @@ protected:
}
public:
- //RegionExtent getExtent() const { return UndefinedExtent(); }
-
void Profile(llvm::FoldingSetNodeID& ID) const;
bool isBoundable() const { return false; }
@@ -315,6 +320,8 @@ public:
return Str->getType();
}
+ bool isBoundable() const { return false; }
+
void Profile(llvm::FoldingSetNodeID& ID) const {
ProfileRegion(ID, Str, superRegion);
}
@@ -384,7 +391,9 @@ public:
QualType getValueType(ASTContext& C) const {
return C.getCanonicalType(CL->getType());
}
-
+
+ bool isBoundable() const { return !CL->isFileScope(); }
+
void Profile(llvm::FoldingSetNodeID& ID) const;
void print(llvm::raw_ostream& os) const;
@@ -584,15 +593,17 @@ class MemRegionManager {
llvm::BumpPtrAllocator& A;
llvm::FoldingSet<MemRegion> Regions;
- MemSpaceRegion* globals;
- MemSpaceRegion* stack;
- MemSpaceRegion* heap;
- MemSpaceRegion* unknown;
- MemSpaceRegion* code;
+ MemSpaceRegion *globals;
+ MemSpaceRegion *stack;
+ MemSpaceRegion *stackArguments;
+ MemSpaceRegion *heap;
+ MemSpaceRegion *unknown;
+ MemSpaceRegion *code;
public:
MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), globals(0), stack(0), heap(0), unknown(0), code(0) {}
+ : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
+ unknown(0), code(0) {}
~MemRegionManager() {}
@@ -600,24 +611,28 @@ public:
/// getStackRegion - Retrieve the memory region associated with the
/// current stack frame.
- MemSpaceRegion* getStackRegion();
+ MemSpaceRegion *getStackRegion();
+
+ /// getStackArgumentsRegion - Retrieve the memory region associated with
+ /// function/method arguments of the current stack frame.
+ MemSpaceRegion *getStackArgumentsRegion();
/// getGlobalsRegion - Retrieve the memory region associated with
/// all global variables.
- MemSpaceRegion* getGlobalsRegion();
+ MemSpaceRegion *getGlobalsRegion();
/// getHeapRegion - Retrieve the memory region associated with the
/// generic "heap".
- MemSpaceRegion* getHeapRegion();
+ MemSpaceRegion *getHeapRegion();
/// getUnknownRegion - Retrieve the memory region associated with unknown
/// memory space.
- MemSpaceRegion* getUnknownRegion();
+ MemSpaceRegion *getUnknownRegion();
- MemSpaceRegion* getCodeRegion();
+ MemSpaceRegion *getCodeRegion();
/// getAllocaRegion - Retrieve a region associated with a call to alloca().
- AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt);
+ AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt);
/// getCompoundLiteralRegion - Retrieve the region associated with a
/// given CompoundLiteral.
@@ -785,8 +800,12 @@ template <> struct MemRegionManagerTrait<VarRegion> {
typedef MemRegion SuperRegionTy;
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
const VarDecl *d) {
- return d->hasLocalStorage() ? MRMgr.getStackRegion()
- : MRMgr.getGlobalsRegion();
+ if (d->hasLocalStorage()) {
+ return isa<ParmVarDecl>(d) || isa<ImplicitParamDecl>(d)
+ ? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion();
+ }
+
+ return MRMgr.getGlobalsRegion();
}
};
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h
index 36137fb117b3..4bc5e27aacf0 100644
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ b/include/clang/Analysis/PathSensitive/SVals.h
@@ -110,6 +110,8 @@ public:
/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
/// return that expression. Otherwise return NULL.
const SymExpr *getAsSymbolicExpression() const;
+
+ const MemRegion *getAsRegion() const;
void print(llvm::raw_ostream& OS) const;
void printStdErr() const;
diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h
index de318a0f03e8..36d1df2150df 100644
--- a/include/clang/Analysis/PathSensitive/ValueManager.h
+++ b/include/clang/Analysis/PathSensitive/ValueManager.h
@@ -67,12 +67,17 @@ public:
const void* SymbolTag = 0) {
return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
}
-
+
/// makeZeroVal - Construct an SVal representing '0' for the specified type.
SVal makeZeroVal(QualType T);
- /// GetRegionValueSymbolVal - make a unique symbol for value of R.
- SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType());
+ /// getRegionValueSymbolVal - make a unique symbol for value of R.
+ SVal getRegionValueSymbolVal(const MemRegion *R, QualType T = QualType());
+
+ SVal getRegionValueSymbolValOrUnknown(const MemRegion *R, QualType T) {
+ return SymMgr.canSymbolicate(T) ? getRegionValueSymbolVal(R, T)
+ : UnknownVal();
+ }
SVal getConjuredSymbolVal(const Expr *E, unsigned Count);
SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count);
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 327db00e0b28..a8dbd68df10f 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -45,6 +45,10 @@ def err_drv_no_linker_llvm_support : Error<
"'%0': unable to pass LLVM bit-code files to linker">;
def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
+def err_drv_command_failed : Error<
+ "%0 command failed with exit code %1 (use -v to see invocation)">;
+def err_drv_command_signalled : Error<
+ "%0 command failed due to signal %1 (use -v to see invocation)">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 4ba1083089e6..b1a73d05a45f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -287,6 +287,8 @@ def err_distant_exception_spec : Error<
def err_incomplete_in_exception_spec : Error<
"%select{|pointer to |reference to }1incomplete type %0 is not allowed "
"in exception specification">;
+def err_mismatched_exception_spec : Error<
+ "exception specification in declaration does not match previous declaration">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@@ -398,6 +400,10 @@ def err_init_reference_member_uninitialized : Error<
def note_uninit_reference_member : Note<
"uninitialized reference member is here">;
+// C++0x decltype
+def err_cannot_determine_declared_type_of_overloaded_function : Error<
+ "can't determine the declared type of an overloaded function">;
+
// C++0x auto
def err_auto_variable_cannot_appear_in_own_initializer : Error<
"variable %0 declared with 'auto' type cannot appear in its own initializer">;
@@ -835,6 +841,12 @@ def note_function_template_spec_here : Note<
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
+def note_explicit_template_arg_substitution_here : Note<
+ "while substituting explicitly-specified template arguments into function "
+ "template %f, here">;
+def note_function_template_deduction_instantiation_here : Note<
+ "while substituting deduced template arguments into function template %0, "
+ "here">;
def note_partial_spec_deduct_instantiation_here : Note<
"during template argument deduction for class template partial "
"specialization %0, here">;
@@ -1070,6 +1082,8 @@ def err_array_star_outside_prototype : Error<
"star modifier used outside of function prototype">;
def err_illegal_decl_pointer_to_reference : Error<
"'%0' declared as a pointer to a reference">;
+def err_illegal_decl_mempointer_to_reference : Error<
+ "'%0' declared as a member pointer to a reference">;
def err_illegal_decl_mempointer_to_void : Error<
"'%0' declared as a member pointer to void">;
def err_illegal_decl_mempointer_in_nonclass : Error<
@@ -1207,6 +1221,10 @@ def err_typecheck_sub_ptr_object : Error<
"subtraction of pointer %0 requires pointee to be a complete object type">;
def err_typecheck_sub_ptr_compatible : Error<
"%0 and %1 are not pointers to compatible types">;
+def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
+ "ordered comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
+ "ordered comparison of function pointers (%0 and %1)">;
def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
"comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
@@ -1579,6 +1597,12 @@ def err_overload_multiple_match : Error<
def err_only_constructors_take_base_inits : Error<
"only constructors take base initializers">;
+def error_multiple_mem_initialization : Error <
+ "multiple initializations given for non-static member '%0'">;
+
+def error_multiple_base_initialization : Error <
+ "multiple initializations given for base %0">;
+
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
@@ -1588,6 +1612,8 @@ def err_base_init_does_not_name_class : Error<
def err_base_init_direct_and_virtual : Error<
"base class initializer %0 names both a direct base class and an "
"inherited virtual base class">;
+def err_not_direct_base_or_virtual : Error<
+ "type %0 is not a direct or virtual base of '%1'">;
def err_in_class_initializer_non_integral_type : Error<
"in-class initializer has non-integral, non-enumeration type %0">;
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 543a0fff8e7b..26688bf56728 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -22,6 +22,7 @@ class LangOptions {
public:
unsigned Trigraphs : 1; // Trigraphs in source files.
unsigned BCPLComment : 1; // BCPL-style '//' comments.
+ unsigned Bool : 1; // 'bool', 'true', 'false' keywords.
unsigned DollarIdents : 1; // '$' allowed in identifiers.
unsigned AsmPreprocessor : 1; // Preprocessor in asm mode.
unsigned GNUMode : 1; // True in gnu99 mode false in c99 mode (etc)
@@ -84,12 +85,16 @@ public:
unsigned OpenCL : 1; // OpenCL C99 language extensions.
-
private:
- unsigned GC : 2; // Objective-C Garbage Collection modes. We declare
- // this enum as unsigned because MSVC insists on making enums
- // signed. Set/Query this value using accessors.
+ unsigned GC : 2; // Objective-C Garbage Collection modes. We
+ // declare this enum as unsigned because MSVC
+ // insists on making enums signed. Set/Query
+ // this value using accessors.
unsigned SymbolVisibility : 3; // Symbol's visibility.
+ unsigned StackProtector : 2; // Whether stack protectors are on. We declare
+ // this enum as unsigned because MSVC insists
+ // on making enums signed. Set/Query this
+ // value using accessors.
/// The user provided name for the "main file", if non-null. This is
/// useful in situations where the input file name does not match
@@ -100,6 +105,7 @@ public:
unsigned InstantiationDepth; // Maximum template instantiation depth.
enum GCMode { NonGC, GCOnly, HybridGC };
+ enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
enum VisibilityMode {
Default,
Protected,
@@ -107,7 +113,7 @@ public:
};
LangOptions() {
- Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0;
+ Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
GNUMode = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
@@ -116,7 +122,7 @@ public:
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
LaxVectorConversions = 1;
HeinousExtensions = 0;
- AltiVec = OpenCL = 0;
+ AltiVec = OpenCL = StackProtector = 0;
SymbolVisibility = (unsigned) Default;
@@ -152,6 +158,13 @@ public:
GCMode getGCMode() const { return (GCMode) GC; }
void setGCMode(GCMode m) { GC = (unsigned) m; }
+ StackProtectorMode getStackProtectorMode() const {
+ return static_cast<StackProtectorMode>(StackProtector);
+ }
+ void setStackProtectorMode(StackProtectorMode m) {
+ StackProtector = static_cast<unsigned>(m);
+ }
+
const char *getMainFileName() const { return MainFileName; }
void setMainFileName(const char *Name) { MainFileName = Name; }
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index a59c60b00224..537d553bc2d1 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -76,7 +76,8 @@ public:
UnsignedLongLong
};
protected:
- IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType;
+ IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
+ Int64Type;
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@@ -86,6 +87,7 @@ public:
}
IntType getIntPtrType() const { return IntPtrType; }
IntType getWCharType() const { return WCharType; }
+ IntType getInt64Type() const { return Int64Type; }
/// getPointerWidth - Return the width of pointers on this target, for the
/// specified address space.
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index ed0270acd0dd..e711996cf26d 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -224,7 +224,7 @@ KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , KEYCXX|BOOLSUPPORT)
+KEYWORD(bool , BOOLSUPPORT)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@@ -232,7 +232,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
-KEYWORD(false , KEYCXX|BOOLSUPPORT)
+KEYWORD(false , BOOLSUPPORT)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@@ -246,7 +246,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
-KEYWORD(true , KEYCXX|BOOLSUPPORT)
+KEYWORD(true , BOOLSUPPORT)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 5812da1b562e..12b74d51473e 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -18,6 +18,7 @@
#include <string>
namespace llvm {
+ class LLVMContext;
class Module;
}
@@ -34,7 +35,8 @@ namespace clang {
CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
const std::string &ModuleName,
- const CompileOptions &CO);
+ const CompileOptions &CO,
+ llvm::LLVMContext& C);
}
#endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index b9bf671db2bd..ceef189f7b7e 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -75,6 +75,8 @@ protected:
public:
virtual ~Action();
+ const char *getClassName() const { return Action::getClassName(getKind()); }
+
ActionClass getKind() const { return Kind; }
types::ID getType() const { return Type; }
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 84e0329a375e..a9c890b0b899 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -83,6 +83,8 @@ namespace driver {
/// \arg Claim Whether the argument should be claimed, if it exists.
Arg *getLastArg(options::ID Id, bool Claim=true) const;
Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const;
+ Arg *getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
+ bool Claim=true) const;
/// getArgString - Return the input argument string at \arg Index.
virtual const char *getArgString(unsigned Index) const = 0;
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 4985f30ad553..6414ef13692b 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -32,10 +32,10 @@ namespace driver {
/// invocation.
class Compilation {
/// The driver we were created by.
- Driver &TheDriver;
+ const Driver &TheDriver;
/// The default tool chain.
- ToolChain &DefaultToolChain;
+ const ToolChain &DefaultToolChain;
/// The original (untranslated) input argument list.
InputArgList *Args;
@@ -56,7 +56,8 @@ class Compilation {
ArgStringList ResultFiles;
public:
- Compilation(Driver &D, ToolChain &DefaultToolChain, InputArgList *Args);
+ Compilation(const Driver &D, const ToolChain &DefaultToolChain,
+ InputArgList *Args);
~Compilation();
const Driver &getDriver() const { return TheDriver; }
@@ -69,6 +70,11 @@ public:
const ActionList &getActions() const { return Actions; }
JobList &getJobs() { return Jobs; }
+ const JobList &getJobs() const { return Jobs; }
+
+ const ArgStringList &getTempFiles() const { return TempFiles; }
+
+ const ArgStringList &getResultFiles() const { return ResultFiles; }
/// getArgsForToolChain - Return the derived argument list for the
/// tool chain \arg TC (or the default tool chain, if TC is not
@@ -89,11 +95,6 @@ public:
return Name;
}
- /// Execute - Execute the compilation jobs and return an
- /// appropriate exit code.
- int Execute() const;
-
-private:
/// CleanupFileList - Remove the files in the given list.
///
/// \param IssueErrors - Report failures as errors.
@@ -103,22 +104,26 @@ private:
/// PrintJob - Print one job in -### format.
///
- /// OS - The stream to print on.
- /// J - The job to print.
- /// Terminator - A string to print at the end of the line.
- /// Quote - Should separate arguments be quoted.
+ /// \param OS - The stream to print on.
+ /// \param J - The job to print.
+ /// \param Terminator - A string to print at the end of the line.
+ /// \param Quote - Should separate arguments be quoted.
void PrintJob(llvm::raw_ostream &OS, const Job &J,
const char *Terminator, bool Quote) const;
/// ExecuteCommand - Execute an actual command.
///
+ /// \param FailingCommand - For non-zero results, this will be set to the
+ /// Command which failed, if any.
/// \return The result code of the subprocess.
- int ExecuteCommand(const Command &C) const;
+ int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
/// ExecuteJob - Execute a single job.
///
+ /// \param FailingCommand - For non-zero results, this will be set to the
+ /// Command which failed.
/// \return The accumulated result code of the job.
- int ExecuteJob(const Job &J) const;
+ int ExecuteJob(const Job &J, const Command *&FailingCommand) const;
};
} // end namespace driver
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 66e3b9787594..c0def2bcca29 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -161,6 +161,14 @@ public:
/// \arg C - The compilation that is being built.
void BuildJobs(Compilation &C) const;
+ /// ExecuteCompilation - Execute the compilation according to the command line
+ /// arguments and return an appropriate exit code.
+ ///
+ /// This routine handles additional processing that must be done in addition
+ /// to just running the subprocesses, for example reporting errors, removing
+ /// temporary files, etc.
+ int ExecuteCompilation(const Compilation &C) const;
+
/// @}
/// @name Helper Methods
/// @{
diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h
index 3485f5fbfd76..b5e80b0c3bfe 100644
--- a/include/clang/Driver/HostInfo.h
+++ b/include/clang/Driver/HostInfo.h
@@ -69,6 +69,8 @@ public:
const HostInfo *createDarwinHostInfo(const Driver &D,
const llvm::Triple& Triple);
+const HostInfo *createOpenBSDHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
const HostInfo *createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createDragonFlyHostInfo(const Driver &D,
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index f60f5146414c..a23babdbb31a 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -52,6 +52,9 @@ public:
/// Command - An executable path/name and argument vector to
/// execute.
class Command : public Job {
+ /// Source - The action which caused the creation of this job.
+ const Action &Source;
+
/// The executable to run.
const char *Executable;
@@ -60,9 +63,14 @@ class Command : public Job {
ArgStringList Arguments;
public:
- Command(const char *_Executable, const ArgStringList &_Arguments);
+ Command(const Action &_Source, const char *_Executable,
+ const ArgStringList &_Arguments);
+
+ /// getSource - Return the Action which caused the creation of this job.
+ const Action &getSource() const { return Source; }
const char *getExecutable() const { return Executable; }
+
const ArgStringList &getArguments() const { return Arguments; }
static bool classof(const Job *J) {
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index abd07a92b1a2..af108a85ebdd 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -420,7 +420,7 @@ OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-show-column", fno_show_column, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-stack-protector", fno_stack_protector, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-strict-aliasing", fno_strict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-unit-at-a-time", fno_unit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-unwind-tables", fno_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -450,7 +450,8 @@ OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fstack-protector", fstack_protector, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fstack-protector-all", fstack_protector_all, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fstack-protector", fstack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fstrict-aliasing", fstrict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsyntax-only", fsyntax_only, Flag, INVALID, INVALID, "d", 0, 0, 0)
OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 04365d7c78d8..be4520262558 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -20,6 +20,7 @@
namespace llvm {
class Module;
+ class LLVMContext;
namespace sys { class Path; }
}
namespace clang {
@@ -79,7 +80,8 @@ ASTConsumer *CreateBackendConsumer(BackendAction Action,
const LangOptions &Features,
const CompileOptions &CompileOpts,
const std::string &ModuleID,
- llvm::raw_ostream *OS);
+ llvm::raw_ostream *OS,
+ llvm::LLVMContext& C);
// HTML printer: uses the rewriter to convert source code to HTML with
// syntax highlighting suitable for viewing in a web-browser.
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 63222725d529..80aa248a78e6 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -218,7 +218,11 @@ namespace clang {
/// \brief Record code for the original file that was used to
/// generate the precompiled header.
- ORIGINAL_FILE_NAME = 20
+ ORIGINAL_FILE_NAME = 20,
+
+ /// \brief Record code for the sorted array of source ranges where
+ /// comments were encountered in the source code.
+ COMMENT_RANGES = 21
};
/// \brief Record types used within a source manager block.
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index b3ed36434312..8291f4697a8e 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -279,6 +279,12 @@ private:
/// been loaded.
llvm::SmallVector<Selector, 16> SelectorsLoaded;
+ /// \brief A sorted array of source ranges containing comments.
+ SourceRange *Comments;
+
+ /// \brief The number of source ranges in the Comments array.
+ unsigned NumComments;
+
/// \brief The set of external definitions stored in the the PCH
/// file.
llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
@@ -452,6 +458,14 @@ public:
/// build prior to including the precompiled header.
const std::string &getSuggestedPredefines() { return SuggestedPredefines; }
+ /// \brief Reads the source ranges that correspond to comments from
+ /// an external AST source.
+ ///
+ /// \param Comments the contents of this vector will be
+ /// replaced with the sorted set of source ranges corresponding to
+ /// comments in the source code.
+ virtual void ReadComments(std::vector<SourceRange> &Comments);
+
/// \brief Resolve a type ID into a type, potentially building a new
/// type.
virtual QualType GetType(pch::TypeID ID);
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 5cb939547f2c..c663442e64d8 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -166,6 +166,7 @@ private:
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP);
void WritePreprocessor(const Preprocessor &PP);
+ void WriteComments(ASTContext &Context);
void WriteType(const Type *T);
void WriteTypesBlock(ASTContext &Context);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index f229881bfc44..6d5ed72455b9 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Allocator.h"
+#include <vector>
namespace clang {
@@ -35,6 +36,7 @@ class FileEntry;
class HeaderSearch;
class PragmaNamespace;
class PragmaHandler;
+class CommentHandler;
class ScratchBuffer;
class TargetInfo;
class PPCallbacks;
@@ -109,6 +111,10 @@ class Preprocessor {
/// with this preprocessor.
PragmaNamespace *PragmaHandlers;
+ /// \brief Tracks all of the comment handlers that the client registered
+ /// with this preprocessor.
+ std::vector<CommentHandler *> CommentHandlers;
+
/// CurLexer - This is the current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
@@ -301,6 +307,14 @@ public:
/// to remove a handler that has not been registered.
void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
+ /// \brief Add the specified comment handler to the preprocessor.
+ void AddCommentHandler(CommentHandler *Handler);
+
+ /// \brief Remove the specified comment handler.
+ ///
+ /// It is an error to remove a handler that has not been registered.
+ void RemoveCommentHandler(CommentHandler *Handler);
+
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
@@ -791,6 +805,7 @@ public:
void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaComment(Token &CommentTok);
+ void HandleComment(SourceRange Comment);
};
/// PreprocessorFactory - A generic factory interface for lazily creating
@@ -801,6 +816,15 @@ public:
virtual Preprocessor* CreatePreprocessor() = 0;
};
+/// \brief Abstract base class that describes a handler that will receive
+/// source ranges for each of the comments encountered in the source file.
+class CommentHandler {
+public:
+ virtual ~CommentHandler();
+
+ virtual void HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index bfb74748c5f1..d969562977ea 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -152,6 +152,10 @@ public:
/// an empty string if not. This is used for pretty crash reporting.
virtual std::string getDeclName(DeclPtrTy D) { return ""; }
+ /// \brief Invoked for each comment in the source code, providing the source
+ /// range that contains the comment.
+ virtual void ActOnComment(SourceRange Comment) { }
+
//===--------------------------------------------------------------------===//
// Declaration Tracking Callbacks.
//===--------------------------------------------------------------------===//
@@ -1203,7 +1207,9 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -1379,6 +1385,24 @@ public:
return TypeResult();
};
+ /// \brief Form a reference to a template-id (that will refer to a function)
+ /// from a template and a list of template arguments.
+ ///
+ /// This action forms an expression that references the given template-id,
+ /// possibly checking well-formedness of the template arguments. It does not
+ /// imply the declaration of any entity.
+ ///
+ /// \param Template A template whose specialization results in a
+ /// function or a dependent template.
+ virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ return ExprError();
+ }
+
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h
index 59517930de95..987edfa96dd1 100644
--- a/include/clang/Parse/Ownership.h
+++ b/include/clang/Parse/Ownership.h
@@ -574,6 +574,19 @@ namespace clang {
#if !defined(DISABLE_SMART_POINTERS)
friend class moving::ASTMultiMover<Destroyer>;
+#if defined(_MSC_VER)
+ // Last tested with Visual Studio 2008.
+ // Visual C++ appears to have a bug where it does not recognise
+ // the return value from ASTMultiMover<Destroyer>::opeator-> as
+ // being a pointer to ASTMultiPtr. However, the diagnostics
+ // suggest it has the right name, simply that the pointer type
+ // is not convertible to itself.
+ // Either way, a classic C-style hard cast resolves any issue.
+ static ASTMultiPtr* hack(moving::ASTMultiMover<Destroyer> & source) {
+ return (ASTMultiPtr*)source.operator->();
+ }
+#endif
+
ASTMultiPtr(ASTMultiPtr&); // DO NOT IMPLEMENT
// Reference member prevents copy assignment.
@@ -594,7 +607,13 @@ namespace clang {
: Actions(actions), Nodes(nodes), Count(count) {}
/// Move constructor
ASTMultiPtr(moving::ASTMultiMover<Destroyer> mover)
+#if defined(_MSC_VER)
+ // Apply the visual C++ hack supplied above.
+ // Last tested with Visual Studio 2008.
+ : Actions(hack(mover)->Actions), Nodes(hack(mover)->Nodes), Count(hack(mover)->Count) {
+#else
: Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) {
+#endif
mover.release();
}
#else
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index e5f62ec683e3..e2380542ae6f 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -82,7 +82,8 @@ class Parser {
llvm::OwningPtr<PragmaHandler> PackHandler;
llvm::OwningPtr<PragmaHandler> UnusedHandler;
llvm::OwningPtr<PragmaHandler> WeakHandler;
-
+ llvm::OwningPtr<clang::CommentHandler> CommentHandler;
+
/// Whether the '>' token acts as an operator or not. This will be
/// true except when we are parsing an expression within a C++
/// template argument list, where the '>' closes the template