Import Clang r74788.

This commit is contained in:
Ed Schouten 2009-07-04 13:58:54 +00:00
parent 4ebdf5c4f5
commit 5362a71c02
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=195341
svn path=/vendor/clang/clang-r74788/; revision=195343; tag=vendor/clang/clang-r74788
184 changed files with 5868 additions and 3568 deletions

View File

@ -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 @@ class ASTContext {
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 @@ class ASTContext {
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
const char *getCommentForDecl(const Decl *D);
// Builtin Types.
QualType VoidTy;
QualType BoolTy;
@ -351,12 +365,6 @@ class ASTContext {
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);

View File

@ -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 @@ class CFGBlock {
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 @@ class CFG {
// 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.

View File

@ -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 @@ class FunctionDecl : public ValueDecl, public DeclContext {
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 @@ class FunctionDecl : public ValueDecl, public DeclContext {
/// 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 @@ class FunctionDecl : public ValueDecl, public DeclContext {
/// 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 @@ class FunctionDecl : public ValueDecl, public DeclContext {
return PreviousDeclaration;
}
void setPreviousDeclaration(FunctionDecl * PrevDecl) {
PreviousDeclaration = PrevDecl;
}
void setPreviousDeclaration(FunctionDecl * PrevDecl);
unsigned getBuiltinID(ASTContext &Context) const;
@ -940,27 +938,14 @@ class FunctionDecl : public ValueDecl, public DeclContext {
///
/// 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 @@ class FunctionDecl : public ValueDecl, public DeclContext {
/// 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 @@ class EnumDecl : public TagDecl {
// 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 @@ class RecordDecl : public TagDecl {
// 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 @@ class BlockDecl : public Decl, public DeclContext {
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.

View File

@ -213,6 +213,13 @@ class Decl {
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 @@ class Decl {
}
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 @@ class Decl {
/// 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 @@ class Decl {
/// 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 @@ class DeclContext {
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 @@ class DeclContext {
/// 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 @@ class DeclContext {
///
/// 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 @@ class DeclContext {
/// 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 @@ class DeclContext {
/// 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 @@ class DeclContext {
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 @@ class DeclContext {
#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 {

View File

@ -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 @@ class AnyFunctionDecl {
/// \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 @@ class OverloadedFunctionDecl : public NamedDecl {
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);
/// \brief Add a new overloaded function or function template to the set
/// of overloaded function templates.
void addOverload(AnyFunctionDecl F);
// An overloaded function declaration always has the location of
// the most-recently-added function declaration.
if (FD->getLocation().isValid())
this->setLocation(FD->getLocation());
}
/// 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 @@ class CXXRecordDecl : public RecordDecl {
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 @@ class CXXBaseOrMemberInitializer {
/// 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 @@ class CXXBaseOrMemberInitializer {
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 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// 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 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// 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.

View File

@ -242,10 +242,10 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
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 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
// 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 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
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 @@ class ObjCProtocolDecl : public ObjCContainerDecl {
// 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 @@ class ObjCImplDecl : public NamedDecl, public DeclContext {
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 @@ class ObjCImplementationDecl : public ObjCImplDecl {
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) {

View File

@ -100,6 +100,352 @@ class TemplateParameterList {
}
};
/// \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 @@ class TemplateDecl : public NamedDecl {
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 @@ class TemplateTemplateParmDecl
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 {

View File

@ -124,7 +124,7 @@ class Expr : public Stmt {
/// 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 @@ class BlockExpr : public Expr {
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());
}

View File

@ -1017,6 +1017,100 @@ class UnresolvedDeclRefExpr : public Expr {
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;

View File

@ -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 @@ class ExternalASTSource {
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;

View File

@ -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 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// \brief Dump the nested name specifier to standard output to aid
/// in debugging.
void dump();
void dump(const LangOptions &LO);
};
}

View File

@ -22,6 +22,7 @@ namespace clang {
class Stmt;
class TagDecl;
class LangOptions;
class PrinterHelper {
public:
@ -33,16 +34,15 @@ class PrinterHelper {
/// 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.

View File

@ -187,14 +187,14 @@ class Stmt {
/// 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

View File

@ -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)

View File

@ -188,7 +188,8 @@ class QualType {
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 @@ class Type {
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 @@ class BuiltinType : public Type {
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;

View File

@ -62,7 +62,6 @@ class MemRegion : public llvm::FoldingSetNode {
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 @@ class MemRegion : public llvm::FoldingSetNode {
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 @@ class MemSpaceRegion : public MemRegion {
}
public:
//RegionExtent getExtent() const { return UndefinedExtent(); }
void Profile(llvm::FoldingSetNodeID& ID) const;
bool isBoundable() const { return false; }
@ -315,6 +320,8 @@ class StringRegion : public TypedRegion {
return Str->getType();
}
bool isBoundable() const { return false; }
void Profile(llvm::FoldingSetNodeID& ID) const {
ProfileRegion(ID, Str, superRegion);
}
@ -384,7 +391,9 @@ class CompoundLiteralRegion : public TypedRegion {
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 @@ class MemRegionManager {
/// 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();
}
};

View File

@ -110,6 +110,8 @@ class SVal {
/// 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;

View File

@ -67,12 +67,17 @@ class ValueManager {
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);

View File

@ -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">;

View File

@ -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">;

View File

@ -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 @@ class LangOptions {
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 @@ class LangOptions {
unsigned InstantiationDepth; // Maximum template instantiation depth.
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
enum VisibilityMode {
Default,
Protected,
@ -107,7 +113,7 @@ class LangOptions {
};
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 @@ class LangOptions {
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
LaxVectorConversions = 1;
HeinousExtensions = 0;
AltiVec = OpenCL = 0;
AltiVec = OpenCL = StackProtector = 0;
SymbolVisibility = (unsigned) Default;
@ -152,6 +158,13 @@ class LangOptions {
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; }

View File

@ -76,7 +76,8 @@ class TargetInfo {
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 @@ class TargetInfo {
}
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.

View File

@ -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)

View File

@ -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

View File

@ -75,6 +75,8 @@ class Action {
public:
virtual ~Action();
const char *getClassName() const { return Action::getClassName(getKind()); }
ActionClass getKind() const { return Kind; }
types::ID getType() const { return Type; }

View File

@ -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;

View File

@ -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 @@ class Compilation {
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 @@ class Compilation {
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 @@ class Compilation {
/// 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

View File

@ -161,6 +161,14 @@ class Driver {
/// \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
/// @{

View File

@ -69,6 +69,8 @@ class HostInfo {
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,

View File

@ -52,6 +52,9 @@ class Job {
/// 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) {

View File

@ -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)

View File

@ -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.

View File

@ -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.

View File

@ -279,6 +279,12 @@ class PCHReader
/// 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 @@ class PCHReader
/// 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);

View File

@ -166,6 +166,7 @@ class PCHWriter {
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);

View File

@ -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 @@ class Preprocessor {
/// 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 @@ class Preprocessor {
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 @@ class PreprocessorFactory {
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

View File

@ -152,6 +152,10 @@ class Action : public ActionBase {
/// 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 @@ class Action : public ActionBase {
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 @@ class Action : public ActionBase {
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

View File

@ -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

View File

@ -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

View File

@ -37,12 +37,12 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
bool FreeMem, unsigned size_reserve) :
GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts),
FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0) {
LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
if (size_reserve > 0) Types.reserve(size_reserve);
InitBuiltinTypes();
TUDecl = TranslationUnitDecl::Create(*this);
PrintingPolicy.CPlusPlus = LangOpts.CPlusPlus;
}
ASTContext::~ASTContext() {
@ -203,6 +203,207 @@ void ASTContext::InitBuiltinTypes() {
InitBuiltinType(NullPtrTy, BuiltinType::NullPtr);
}
namespace {
class BeforeInTranslationUnit
: std::binary_function<SourceRange, SourceRange, bool> {
SourceManager *SourceMgr;
public:
explicit BeforeInTranslationUnit(SourceManager *SM) : SourceMgr(SM) { }
bool operator()(SourceRange X, SourceRange Y) {
return SourceMgr->isBeforeInTranslationUnit(X.getBegin(), Y.getBegin());
}
};
}
/// \brief Determine whether the given comment is a Doxygen-style comment.
///
/// \param Start the start of the comment text.
///
/// \param End the end of the comment text.
///
/// \param Member whether we want to check whether this is a member comment
/// (which requires a < after the Doxygen-comment delimiter). Otherwise,
/// we only return true when we find a non-member comment.
static bool
isDoxygenComment(SourceManager &SourceMgr, SourceRange Comment,
bool Member = false) {
const char *BufferStart
= SourceMgr.getBufferData(SourceMgr.getFileID(Comment.getBegin())).first;
const char *Start = BufferStart + SourceMgr.getFileOffset(Comment.getBegin());
const char* End = BufferStart + SourceMgr.getFileOffset(Comment.getEnd());
if (End - Start < 4)
return false;
assert(Start[0] == '/' && "Not a comment?");
if (Start[1] == '*' && !(Start[2] == '!' || Start[2] == '*'))
return false;
if (Start[1] == '/' && !(Start[2] == '!' || Start[2] == '/'))
return false;
return (Start[3] == '<') == Member;
}
/// \brief Retrieve the comment associated with the given declaration, if
/// it has one.
const char *ASTContext::getCommentForDecl(const Decl *D) {
if (!D)
return 0;
// Check whether we have cached a comment string for this declaration
// already.
llvm::DenseMap<const Decl *, std::string>::iterator Pos
= DeclComments.find(D);
if (Pos != DeclComments.end())
return Pos->second.c_str();
// If we have an external AST source and have not yet loaded comments from
// that source, do so now.
if (ExternalSource && !LoadedExternalComments) {
std::vector<SourceRange> LoadedComments;
ExternalSource->ReadComments(LoadedComments);
if (!LoadedComments.empty())
Comments.insert(Comments.begin(), LoadedComments.begin(),
LoadedComments.end());
LoadedExternalComments = true;
}
// If there are no comments anywhere, we won't find anything.
if (Comments.empty())
return 0;
// If the declaration doesn't map directly to a location in a file, we
// can't find the comment.
SourceLocation DeclStartLoc = D->getLocStart();
if (DeclStartLoc.isInvalid() || !DeclStartLoc.isFileID())
return 0;
// Find the comment that occurs just before this declaration.
std::vector<SourceRange>::iterator LastComment
= std::lower_bound(Comments.begin(), Comments.end(),
SourceRange(DeclStartLoc),
BeforeInTranslationUnit(&SourceMgr));
// Decompose the location for the start of the declaration and find the
// beginning of the file buffer.
std::pair<FileID, unsigned> DeclStartDecomp
= SourceMgr.getDecomposedLoc(DeclStartLoc);
const char *FileBufferStart
= SourceMgr.getBufferData(DeclStartDecomp.first).first;
// First check whether we have a comment for a member.
if (LastComment != Comments.end() &&
!isa<TagDecl>(D) && !isa<NamespaceDecl>(D) &&
isDoxygenComment(SourceMgr, *LastComment, true)) {
std::pair<FileID, unsigned> LastCommentEndDecomp
= SourceMgr.getDecomposedLoc(LastComment->getEnd());
if (DeclStartDecomp.first == LastCommentEndDecomp.first &&
SourceMgr.getLineNumber(DeclStartDecomp.first, DeclStartDecomp.second)
== SourceMgr.getLineNumber(LastCommentEndDecomp.first,
LastCommentEndDecomp.second)) {
// The Doxygen member comment comes after the declaration starts and
// is on the same line and in the same file as the declaration. This
// is the comment we want.
std::string &Result = DeclComments[D];
Result.append(FileBufferStart +
SourceMgr.getFileOffset(LastComment->getBegin()),
FileBufferStart + LastCommentEndDecomp.second + 1);
return Result.c_str();
}
}
if (LastComment == Comments.begin())
return 0;
--LastComment;
// Decompose the end of the comment.
std::pair<FileID, unsigned> LastCommentEndDecomp
= SourceMgr.getDecomposedLoc(LastComment->getEnd());
// If the comment and the declaration aren't in the same file, then they
// aren't related.
if (DeclStartDecomp.first != LastCommentEndDecomp.first)
return 0;
// Check that we actually have a Doxygen comment.
if (!isDoxygenComment(SourceMgr, *LastComment))
return 0;
// Compute the starting line for the declaration and for the end of the
// comment (this is expensive).
unsigned DeclStartLine
= SourceMgr.getLineNumber(DeclStartDecomp.first, DeclStartDecomp.second);
unsigned CommentEndLine
= SourceMgr.getLineNumber(LastCommentEndDecomp.first,
LastCommentEndDecomp.second);
// If the comment does not end on the line prior to the declaration, then
// the comment is not associated with the declaration at all.
if (CommentEndLine + 1 != DeclStartLine)
return 0;
// We have a comment, but there may be more comments on the previous lines.
// Keep looking so long as the comments are still Doxygen comments and are
// still adjacent.
unsigned ExpectedLine
= SourceMgr.getSpellingLineNumber(LastComment->getBegin()) - 1;
std::vector<SourceRange>::iterator FirstComment = LastComment;
while (FirstComment != Comments.begin()) {
// Look at the previous comment
--FirstComment;
std::pair<FileID, unsigned> Decomp
= SourceMgr.getDecomposedLoc(FirstComment->getEnd());
// If this previous comment is in a different file, we're done.
if (Decomp.first != DeclStartDecomp.first) {
++FirstComment;
break;
}
// If this comment is not a Doxygen comment, we're done.
if (!isDoxygenComment(SourceMgr, *FirstComment)) {
++FirstComment;
break;
}
// If the line number is not what we expected, we're done.
unsigned Line = SourceMgr.getLineNumber(Decomp.first, Decomp.second);
if (Line != ExpectedLine) {
++FirstComment;
break;
}
// Set the next expected line number.
ExpectedLine
= SourceMgr.getSpellingLineNumber(FirstComment->getBegin()) - 1;
}
// The iterator range [FirstComment, LastComment] contains all of the
// BCPL comments that, together, are associated with this declaration.
// Form a single comment block string for this declaration that concatenates
// all of these comments.
std::string &Result = DeclComments[D];
while (FirstComment != LastComment) {
std::pair<FileID, unsigned> DecompStart
= SourceMgr.getDecomposedLoc(FirstComment->getBegin());
std::pair<FileID, unsigned> DecompEnd
= SourceMgr.getDecomposedLoc(FirstComment->getEnd());
Result.append(FileBufferStart + DecompStart.second,
FileBufferStart + DecompEnd.second + 1);
++FirstComment;
}
// Append the last comment line.
Result.append(FileBufferStart +
SourceMgr.getFileOffset(LastComment->getBegin()),
FileBufferStart + LastCommentEndDecomp.second + 1);
return Result.c_str();
}
//===----------------------------------------------------------------------===//
// Type Sizing and Analysis
//===----------------------------------------------------------------------===//
@ -226,7 +427,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
unsigned ASTContext::getDeclAlignInBytes(const Decl *D) {
unsigned Align = Target.getCharWidth();
if (const AlignedAttr* AA = D->getAttr<AlignedAttr>(*this))
if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
Align = std::max(Align, AA->getAlignment());
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
@ -449,7 +650,7 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>(*this)) {
if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
Align = Aligned->getAlignment();
Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
} else
@ -513,7 +714,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
// FIXME: Should this override struct packing? Probably we want to
// take the minimum?
if (const PackedAttr *PA = FD->getAttr<PackedAttr>(Context))
if (const PackedAttr *PA = FD->getAttr<PackedAttr>())
FieldPacking = PA->getAlignment();
if (const Expr *BitWidthExpr = FD->getBitWidth()) {
@ -533,7 +734,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
FieldAlign = FieldInfo.second;
if (FieldPacking)
FieldAlign = std::min(FieldAlign, FieldPacking);
if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context))
if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
FieldAlign = std::max(FieldAlign, AA->getAlignment());
// Check if we need to add padding to give the field the correct
@ -573,7 +774,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
// is smaller than the specified packing?
if (FieldPacking)
FieldAlign = std::min(FieldAlign, std::max(8U, FieldPacking));
if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context))
if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
FieldAlign = std::max(FieldAlign, AA->getAlignment());
// Round up the current record size to the field's alignment boundary.
@ -631,8 +832,8 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(*this),
E = PD->prop_end(*this); I != E; ++I)
for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(),
E = PD->prop_end(); I != E; ++I)
if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
Ivars.push_back(Ivar);
@ -647,8 +848,8 @@ void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
///
void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(*this),
E = OI->prop_end(*this); I != E; ++I) {
for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
E = OI->prop_end(); I != E; ++I) {
if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
Ivars.push_back(Ivar);
}
@ -663,8 +864,8 @@ void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
unsigned ASTContext::CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD) {
unsigned count = 0;
for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(*this),
E = PD->prop_end(*this); I != E; ++I)
for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(),
E = PD->prop_end(); I != E; ++I)
if ((*I)->getPropertyIvarDecl())
++count;
@ -678,8 +879,8 @@ unsigned ASTContext::CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD) {
unsigned ASTContext::CountSynthesizedIvars(const ObjCInterfaceDecl *OI)
{
unsigned count = 0;
for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(*this),
E = OI->prop_end(*this); I != E; ++I) {
for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
E = OI->prop_end(); I != E; ++I) {
if ((*I)->getPropertyIvarDecl())
++count;
}
@ -739,10 +940,10 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
}
unsigned StructPacking = 0;
if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this))
if (const PackedAttr *PA = D->getAttr<PackedAttr>())
StructPacking = PA->getAlignment();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this))
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
AA->getAlignment()));
@ -786,23 +987,22 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
Entry = NewEntry;
// FIXME: Avoid linear walk through the fields, if possible.
NewEntry->InitializeLayout(std::distance(D->field_begin(*this),
D->field_end(*this)));
NewEntry->InitializeLayout(std::distance(D->field_begin(), D->field_end()));
bool IsUnion = D->isUnion();
unsigned StructPacking = 0;
if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this))
if (const PackedAttr *PA = D->getAttr<PackedAttr>())
StructPacking = PA->getAlignment();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this))
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
AA->getAlignment()));
// Layout each field, for now, just sequentially, respecting alignment. In
// the future, this will need to be tweakable by targets.
unsigned FieldIdx = 0;
for (RecordDecl::field_iterator Field = D->field_begin(*this),
FieldEnd = D->field_end(*this);
for (RecordDecl::field_iterator Field = D->field_begin(),
FieldEnd = D->field_end();
Field != FieldEnd; (void)++Field, ++FieldIdx)
NewEntry->LayoutField(*Field, FieldIdx, IsUnion, StructPacking, *this);
@ -1636,13 +1836,6 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
return QualType(QType, 0);
}
/// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for the 'id' decl
/// and the conforming protocol list.
QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,
unsigned NumProtocols) {
return getObjCObjectPointerType(0, Protocols, NumProtocols);
}
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
/// TypeOfExprType AST's (since expression's are never shared). For example,
/// multiple declarations that refer to "typeof(x)" all contain different
@ -1813,6 +2006,12 @@ Decl *ASTContext::getCanonicalDecl(Decl *D) {
return const_cast<FunctionDecl *>(Function);
}
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
while (FunTmpl->getPreviousDeclaration())
FunTmpl = FunTmpl->getPreviousDeclaration();
return FunTmpl;
}
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
while (Var->getPreviousDeclaration())
Var = Var->getPreviousDeclaration();
@ -2143,7 +2342,7 @@ QualType ASTContext::getCFConstantStringType() {
SourceLocation(), 0,
FieldTypes[i], /*BitWidth=*/0,
/*Mutable=*/false);
CFConstantStringTypeDecl->addDecl(*this, Field);
CFConstantStringTypeDecl->addDecl(Field);
}
CFConstantStringTypeDecl->completeDefinition(*this);
@ -2179,7 +2378,7 @@ QualType ASTContext::getObjCFastEnumerationStateType()
SourceLocation(), 0,
FieldTypes[i], /*BitWidth=*/0,
/*Mutable=*/false);
ObjCFastEnumerationStateTypeDecl->addDecl(*this, Field);
ObjCFastEnumerationStateTypeDecl->addDecl(Field);
}
ObjCFastEnumerationStateTypeDecl->completeDefinition(*this);
@ -2306,7 +2505,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
if (const ObjCCategoryImplDecl *CID =
dyn_cast<ObjCCategoryImplDecl>(Container)) {
for (ObjCCategoryImplDecl::propimpl_iterator
i = CID->propimpl_begin(*this), e = CID->propimpl_end(*this);
i = CID->propimpl_begin(), e = CID->propimpl_end();
i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
@ -2320,7 +2519,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
} else {
const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
for (ObjCCategoryImplDecl::propimpl_iterator
i = OID->propimpl_begin(*this), e = OID->propimpl_end(*this);
i = OID->propimpl_begin(), e = OID->propimpl_end();
i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
@ -2611,8 +2810,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
if (ExpandStructures) {
S += '=';
for (RecordDecl::field_iterator Field = RDecl->field_begin(*this),
FieldEnd = RDecl->field_end(*this);
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field) {
if (FD) {
S += '"';
@ -2834,7 +3033,7 @@ QualType ASTContext::getFromTargetType(unsigned Type) const {
bool ASTContext::isObjCNSObjectType(QualType Ty) const {
if (TypedefType *TDT = dyn_cast<TypedefType>(Ty)) {
if (TypedefDecl *TD = TDT->getDecl())
if (TD->getAttr<ObjCNSObjectAttr>(*const_cast<ASTContext*>(this)))
if (TD->getAttr<ObjCNSObjectAttr>())
return true;
}
return false;
@ -3578,7 +3777,7 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
case 'P': {
IdentifierInfo *II = &Context.Idents.get("FILE");
DeclContext::lookup_result Lookup
= Context.getTranslationUnitDecl()->lookup(Context, II);
= Context.getTranslationUnitDecl()->lookup(II);
if (Lookup.first != Lookup.second && isa<TypeDecl>(*Lookup.first)) {
Type = Context.getTypeDeclType(cast<TypeDecl>(*Lookup.first));
break;

View File

@ -556,7 +556,7 @@ CFGBlock* CFGBuilder::VisitNullStmt(NullStmt* Statement) {
CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
CFGBlock* LastBlock = NULL;
CFGBlock* LastBlock = Block;
for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
I != E; ++I ) {
@ -1484,10 +1484,11 @@ class VISIBILITY_HIDDEN StmtPrinterHelper : public PrinterHelper {
StmtMapTy StmtMap;
signed CurrentBlock;
unsigned CurrentStmt;
const LangOptions &LangOpts;
public:
StmtPrinterHelper(const CFG* cfg) : CurrentBlock(0), CurrentStmt(0) {
StmtPrinterHelper(const CFG* cfg, const LangOptions &LO)
: CurrentBlock(0), CurrentStmt(0), LangOpts(LO) {
for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
unsigned j = 1;
for (CFGBlock::const_iterator BI = I->begin(), BEnd = I->end() ;
@ -1498,6 +1499,7 @@ class VISIBILITY_HIDDEN StmtPrinterHelper : public PrinterHelper {
virtual ~StmtPrinterHelper() {}
const LangOptions &getLangOpts() const { return LangOpts; }
void setBlockID(signed i) { CurrentBlock = i; }
void setStmtID(unsigned i) { CurrentStmt = i; }
@ -1516,7 +1518,10 @@ class VISIBILITY_HIDDEN StmtPrinterHelper : public PrinterHelper {
return true;
}
};
} // end anonymous namespace
namespace {
class VISIBILITY_HIDDEN CFGBlockTerminatorPrint
: public StmtVisitor<CFGBlockTerminatorPrint,void> {
@ -1526,7 +1531,7 @@ class VISIBILITY_HIDDEN CFGBlockTerminatorPrint
public:
CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper,
const PrintingPolicy &Policy = PrintingPolicy())
const PrintingPolicy &Policy)
: OS(os), Helper(helper), Policy(Policy) {}
void VisitIfStmt(IfStmt* I) {
@ -1602,9 +1607,11 @@ class VISIBILITY_HIDDEN CFGBlockTerminatorPrint
E->printPretty(OS, Helper, Policy);
}
};
} // end anonymous namespace
void print_stmt(llvm::raw_ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminator) {
static void print_stmt(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
Stmt* Terminator) {
if (Helper) {
// special printing for statement-expressions.
if (StmtExpr* SE = dyn_cast<StmtExpr>(Terminator)) {
@ -1629,14 +1636,15 @@ void print_stmt(llvm::raw_ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminato
}
}
Terminator->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy());
Terminator->printPretty(OS, Helper, PrintingPolicy(Helper->getLangOpts()));
// Expressions need a newline.
if (isa<Expr>(Terminator)) OS << '\n';
}
void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
StmtPrinterHelper* Helper, bool print_edges) {
static void print_block(llvm::raw_ostream& OS, const CFG* cfg,
const CFGBlock& B,
StmtPrinterHelper* Helper, bool print_edges) {
if (Helper) Helper->setBlockID(B.getBlockID());
@ -1662,10 +1670,12 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
OS << L->getName();
else if (CaseStmt* C = dyn_cast<CaseStmt>(Terminator)) {
OS << "case ";
C->getLHS()->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy());
C->getLHS()->printPretty(OS, Helper,
PrintingPolicy(Helper->getLangOpts()));
if (C->getRHS()) {
OS << " ... ";
C->getRHS()->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy());
C->getRHS()->printPretty(OS, Helper,
PrintingPolicy(Helper->getLangOpts()));
}
}
else if (isa<DefaultStmt>(Terminator))
@ -1703,7 +1713,8 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
if (Helper) Helper->setBlockID(-1);
CFGBlockTerminatorPrint TPrinter(OS, Helper, /*FIXME*/PrintingPolicy());
CFGBlockTerminatorPrint TPrinter(OS, Helper,
PrintingPolicy(Helper->getLangOpts()));
TPrinter.Visit(const_cast<Stmt*>(B.getTerminator()));
OS << '\n';
}
@ -1741,15 +1752,13 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
}
}
} // end anonymous namespace
/// dump - A simple pretty printer of a CFG that outputs to stderr.
void CFG::dump() const { print(llvm::errs()); }
void CFG::dump(const LangOptions &LO) const { print(llvm::errs(), LO); }
/// print - A simple pretty printer of a CFG that outputs to an ostream.
void CFG::print(llvm::raw_ostream& OS) const {
StmtPrinterHelper Helper(this);
void CFG::print(llvm::raw_ostream &OS, const LangOptions &LO) const {
StmtPrinterHelper Helper(this, LO);
// Print the entry block.
print_block(OS, this, getEntry(), &Helper, true);
@ -1769,18 +1778,22 @@ void CFG::print(llvm::raw_ostream& OS) const {
}
/// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
void CFGBlock::dump(const CFG* cfg) const { print(llvm::errs(), cfg); }
void CFGBlock::dump(const CFG* cfg, const LangOptions &LO) const {
print(llvm::errs(), cfg, LO);
}
/// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
/// Generally this will only be called from CFG::print.
void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg) const {
StmtPrinterHelper Helper(cfg);
void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg,
const LangOptions &LO) const {
StmtPrinterHelper Helper(cfg, LO);
print_block(OS, cfg, *this, &Helper, true);
}
/// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
void CFGBlock::printTerminator(llvm::raw_ostream& OS) const {
CFGBlockTerminatorPrint TPrinter(OS,NULL);
void CFGBlock::printTerminator(llvm::raw_ostream &OS,
const LangOptions &LO) const {
CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));
TPrinter.Visit(const_cast<Stmt*>(getTerminator()));
}
@ -1872,9 +1885,9 @@ bool CFGBlock::hasBinaryBranchTerminator() const {
static StmtPrinterHelper* GraphHelper;
#endif
void CFG::viewCFG() const {
void CFG::viewCFG(const LangOptions &LO) const {
#ifndef NDEBUG
StmtPrinterHelper H(this);
StmtPrinterHelper H(this, LO);
GraphHelper = &H;
llvm::ViewGraph(this,"CFG");
GraphHelper = NULL;

View File

@ -41,7 +41,7 @@ void Attr::Destroy(ASTContext &C) {
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
return new (C) TranslationUnitDecl();
return new (C) TranslationUnitDecl(C);
}
NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
@ -226,8 +226,7 @@ std::string NamedDecl::getQualifiedNameAsString() const {
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
PrintingPolicy Policy;
Policy.CPlusPlus = true;
PrintingPolicy Policy(getASTContext().getLangOptions());
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.getFlatArgumentList(),
@ -372,20 +371,15 @@ void FunctionDecl::Destroy(ASTContext& C) {
C.Deallocate(ParamInfo);
if (TemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>())
C.Deallocate(Info);
Decl::Destroy(C);
}
Stmt *FunctionDecl::getBody(ASTContext &Context,
const FunctionDecl *&Definition) const {
Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) {
if (FD->Body) {
Definition = FD;
return FD->Body.get(Context.getExternalSource());
return FD->Body.get(getASTContext().getExternalSource());
}
}
@ -417,14 +411,14 @@ bool FunctionDecl::isExternC(ASTContext &Context) const {
// In C, any non-static, non-overloadable function has external
// linkage.
if (!Context.getLangOptions().CPlusPlus)
return getStorageClass() != Static && !getAttr<OverloadableAttr>(Context);
return getStorageClass() != Static && !getAttr<OverloadableAttr>();
for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
DC = DC->getParent()) {
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
return getStorageClass() != Static &&
!getAttr<OverloadableAttr>(Context);
!getAttr<OverloadableAttr>();
break;
}
@ -489,7 +483,7 @@ unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const {
if (isa<LinkageSpecDecl>(getDeclContext()) &&
cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
== LinkageSpecDecl::lang_c &&
!getAttr<OverloadableAttr>(Context))
!getAttr<OverloadableAttr>())
return BuiltinID;
// Not a builtin
@ -540,12 +534,12 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
}
bool FunctionDecl::hasActiveGNUInlineAttribute(ASTContext &Context) const {
if (!isInline() || !hasAttr<GNUInlineAttr>(Context))
if (!isInline() || !hasAttr<GNUInlineAttr>())
return false;
for (const FunctionDecl *FD = getPreviousDeclaration(); FD;
FD = FD->getPreviousDeclaration()) {
if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>(Context))
if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>())
return false;
}
@ -557,12 +551,24 @@ bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
return false;
for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration())
if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>(Context))
if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>())
return true;
return false;
}
void
FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
PreviousDeclaration = PrevDecl;
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
FunctionTemplateDecl *PrevFunTmpl
= PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
FunTmpl->setPreviousDeclaration(PrevFunTmpl);
}
}
/// getOverloadedOperator - Which C++ overloaded operator this
/// function represents, if any.
OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
@ -572,18 +578,64 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
return OO_None;
}
FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
if (FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->Template.getPointer();
}
return 0;
}
const TemplateArgumentList *
FunctionDecl::getTemplateSpecializationArgs() const {
if (FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->TemplateArguments;
}
return 0;
}
void
FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs) {
TemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>();
const TemplateArgumentList *TemplateArgs,
void *InsertPos) {
FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (!Info)
Info = new (Context) TemplateSpecializationInfo;
Info = new (Context) FunctionTemplateSpecializationInfo;
Info->Template = Template;
Info->Function = this;
Info->Template.setPointer(Template);
Info->Template.setInt(0); // Implicit instantiation, unless told otherwise
Info->TemplateArguments = TemplateArgs;
TemplateOrSpecialization = Info;
// Insert this function template specialization into the set of known
// function template specialiations.
Template->getSpecializations().InsertNode(Info, InsertPos);
}
bool FunctionDecl::isExplicitSpecialization() const {
// FIXME: check this property for explicit specializations of member
// functions of class templates.
FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (!Info)
return false;
return Info->isExplicitSpecialization();
}
void FunctionDecl::setExplicitSpecialization(bool ES) {
// FIXME: set this property for explicit specializations of member functions
// of class templates.
FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (Info)
Info->setExplicitSpecialization(ES);
}
//===----------------------------------------------------------------------===//

View File

@ -157,6 +157,25 @@ void Decl::setLexicalDeclContext(DeclContext *DC) {
}
}
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
return TUD;
DeclContext *DC = getDeclContext();
assert(DC && "This decl is not contained in a translation unit!");
while (!DC->isTranslationUnit()) {
DC = DC->getParent();
assert(DC && "This decl is not contained in a translation unit!");
}
return cast<TranslationUnitDecl>(DC);
}
ASTContext &Decl::getASTContext() const {
return getTranslationUnitDecl()->getASTContext();
}
unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
switch (DeclKind) {
default:
@ -226,8 +245,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
}
}
void Decl::addAttr(ASTContext &Context, Attr *NewAttr) {
Attr *&ExistingAttr = Context.getDeclAttrs(this);
void Decl::addAttr(Attr *NewAttr) {
Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
NewAttr->setNext(ExistingAttr);
ExistingAttr = NewAttr;
@ -235,19 +254,19 @@ void Decl::addAttr(ASTContext &Context, Attr *NewAttr) {
HasAttrs = true;
}
void Decl::invalidateAttrs(ASTContext &Context) {
void Decl::invalidateAttrs() {
if (!HasAttrs) return;
HasAttrs = false;
Context.eraseDeclAttrs(this);
getASTContext().eraseDeclAttrs(this);
}
const Attr *Decl::getAttrsImpl(ASTContext &Context) const {
const Attr *Decl::getAttrsImpl() const {
assert(HasAttrs && "getAttrs() should verify this!");
return Context.getDeclAttrs(this);
return getASTContext().getDeclAttrs(this);
}
void Decl::swapAttrs(ASTContext &Context, Decl *RHS) {
void Decl::swapAttrs(Decl *RHS) {
bool HasLHSAttr = this->HasAttrs;
bool HasRHSAttr = RHS->HasAttrs;
@ -256,7 +275,9 @@ void Decl::swapAttrs(ASTContext &Context, Decl *RHS) {
// If 'this' has no attrs, swap the other way.
if (!HasLHSAttr)
return RHS->swapAttrs(Context, this);
return RHS->swapAttrs(this);
ASTContext &Context = getASTContext();
// Handle the case when both decls have attrs.
if (HasRHSAttr) {
@ -276,7 +297,7 @@ void Decl::Destroy(ASTContext &C) {
// Free attributes for this decl.
if (HasAttrs) {
C.getDeclAttrs(this)->Destroy(C);
invalidateAttrs(C);
invalidateAttrs();
HasAttrs = false;
}
@ -339,12 +360,12 @@ DeclContext *Decl::castToDeclContext(const Decl *D) {
}
}
CompoundStmt* Decl::getCompoundBody(ASTContext &Context) const {
return dyn_cast_or_null<CompoundStmt>(getBody(Context));
CompoundStmt* Decl::getCompoundBody() const {
return dyn_cast_or_null<CompoundStmt>(getBody());
}
SourceLocation Decl::getBodyRBrace(ASTContext &Context) const {
Stmt *Body = getBody(Context);
SourceLocation Decl::getBodyRBrace() const {
Stmt *Body = getBody();
if (!Body)
return SourceLocation();
if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
@ -388,7 +409,7 @@ DeclContext::~DeclContext() {
}
void DeclContext::DestroyDecls(ASTContext &C) {
for (decl_iterator D = decls_begin(C); D != decls_end(C); )
for (decl_iterator D = decls_begin(); D != decls_end(); )
(*D++)->Destroy(C);
}
@ -479,8 +500,8 @@ DeclContext *DeclContext::getNextContext() {
/// \brief Load the declarations within this lexical storage from an
/// external source.
void
DeclContext::LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const {
ExternalASTSource *Source = Context.getExternalSource();
DeclContext::LoadLexicalDeclsFromExternalStorage() const {
ExternalASTSource *Source = getParentASTContext().getExternalSource();
assert(hasExternalLexicalStorage() && Source && "No external storage?");
llvm::SmallVector<uint32_t, 64> Decls;
@ -517,9 +538,9 @@ DeclContext::LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const {
}
void
DeclContext::LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const {
DeclContext::LoadVisibleDeclsFromExternalStorage() const {
DeclContext *This = const_cast<DeclContext *>(this);
ExternalASTSource *Source = Context.getExternalSource();
ExternalASTSource *Source = getParentASTContext().getExternalSource();
assert(hasExternalVisibleStorage() && Source && "No external storage?");
llvm::SmallVector<VisibleDeclaration, 64> Decls;
@ -539,30 +560,30 @@ DeclContext::LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const {
}
}
DeclContext::decl_iterator DeclContext::decls_begin(ASTContext &Context) const {
DeclContext::decl_iterator DeclContext::decls_begin() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage(Context);
LoadLexicalDeclsFromExternalStorage();
// FIXME: Check whether we need to load some declarations from
// external storage.
return decl_iterator(FirstDecl);
}
DeclContext::decl_iterator DeclContext::decls_end(ASTContext &Context) const {
DeclContext::decl_iterator DeclContext::decls_end() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage(Context);
LoadLexicalDeclsFromExternalStorage();
return decl_iterator();
}
bool DeclContext::decls_empty(ASTContext &Context) const {
bool DeclContext::decls_empty() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage(Context);
LoadLexicalDeclsFromExternalStorage();
return !FirstDecl;
}
void DeclContext::addDecl(ASTContext &Context, Decl *D) {
void DeclContext::addDecl(Decl *D) {
assert(D->getLexicalDeclContext() == this &&
"Decl inserted into wrong lexical context");
assert(!D->getNextDeclInContext() && D != LastDecl &&
@ -576,44 +597,44 @@ void DeclContext::addDecl(ASTContext &Context, Decl *D) {
}
if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
ND->getDeclContext()->makeDeclVisibleInContext(Context, ND);
ND->getDeclContext()->makeDeclVisibleInContext(ND);
}
/// buildLookup - Build the lookup data structure with all of the
/// declarations in DCtx (and any other contexts linked to it or
/// transparent contexts nested within it).
void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
void DeclContext::buildLookup(DeclContext *DCtx) {
for (; DCtx; DCtx = DCtx->getNextContext()) {
for (decl_iterator D = DCtx->decls_begin(Context),
DEnd = DCtx->decls_end(Context);
for (decl_iterator D = DCtx->decls_begin(),
DEnd = DCtx->decls_end();
D != DEnd; ++D) {
// Insert this declaration into the lookup structure
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
makeDeclVisibleInContextImpl(Context, ND);
makeDeclVisibleInContextImpl(ND);
// If this declaration is itself a transparent declaration context,
// add its members (recursively).
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
if (InnerCtx->isTransparentContext())
buildLookup(Context, InnerCtx->getPrimaryContext());
buildLookup(InnerCtx->getPrimaryContext());
}
}
}
DeclContext::lookup_result
DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
DeclContext::lookup(DeclarationName Name) {
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this)
return PrimaryContext->lookup(Context, Name);
return PrimaryContext->lookup(Name);
if (hasExternalVisibleStorage())
LoadVisibleDeclsFromExternalStorage(Context);
LoadVisibleDeclsFromExternalStorage();
/// If there is no lookup data structure, build one now by walking
/// all of the linked DeclContexts (in declaration order!) and
/// inserting their values.
if (!LookupPtr) {
buildLookup(Context, this);
buildLookup(this);
if (!LookupPtr)
return lookup_result(0, 0);
@ -623,12 +644,12 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
StoredDeclsMap::iterator Pos = Map->find(Name);
if (Pos == Map->end())
return lookup_result(0, 0);
return Pos->second.getLookupResult(Context);
return Pos->second.getLookupResult(getParentASTContext());
}
DeclContext::lookup_const_result
DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
return const_cast<DeclContext*>(this)->lookup(Context, Name);
DeclContext::lookup(DeclarationName Name) const {
return const_cast<DeclContext*>(this)->lookup(Name);
}
DeclContext *DeclContext::getLookupContext() {
@ -647,7 +668,7 @@ DeclContext *DeclContext::getEnclosingNamespaceContext() {
return Ctx->getPrimaryContext();
}
void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
// FIXME: This feels like a hack. Should DeclarationName support
// template-ids, or is there a better way to keep specializations
// from being visible?
@ -656,7 +677,7 @@ void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this) {
PrimaryContext->makeDeclVisibleInContext(Context, D);
PrimaryContext->makeDeclVisibleInContext(D);
return;
}
@ -664,16 +685,15 @@ void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
// into it. Otherwise, be lazy and don't build that structure until
// someone asks for it.
if (LookupPtr)
makeDeclVisibleInContextImpl(Context, D);
makeDeclVisibleInContextImpl(D);
// If we are a transparent context, insert into our parent context,
// too. This operation is recursive.
if (isTransparentContext())
getParent()->makeDeclVisibleInContext(Context, D);
getParent()->makeDeclVisibleInContext(D);
}
void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
NamedDecl *D) {
void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
// Skip unnamed declarations.
if (!D->getDeclName())
return;
@ -698,7 +718,7 @@ void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
// If it is possible that this is a redeclaration, check to see if there is
// already a decl for which declarationReplaces returns true. If there is
// one, just replace it and return.
if (DeclNameEntries.HandleRedeclaration(Context, D))
if (DeclNameEntries.HandleRedeclaration(getParentASTContext(), D))
return;
// Put this declaration into the appropriate slot.
@ -708,8 +728,8 @@ void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
/// this context.
DeclContext::udir_iterator_range
DeclContext::getUsingDirectives(ASTContext &Context) const {
lookup_const_result Result = lookup(Context, UsingDirectiveDecl::getName());
DeclContext::getUsingDirectives() const {
lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
reinterpret_cast<udir_iterator>(Result.second));
}

View File

@ -44,11 +44,16 @@ CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
}
CXXRecordDecl::~CXXRecordDecl() {
delete [] Bases;
}
void CXXRecordDecl::Destroy(ASTContext &C) {
C.Deallocate(Bases);
this->RecordDecl::Destroy(C);
}
void
CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
CXXRecordDecl::setBases(ASTContext &C,
CXXBaseSpecifier const * const *Bases,
unsigned NumBases) {
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with [...]
@ -56,10 +61,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
Aggregate = false;
if (this->Bases)
delete [] this->Bases;
C.Deallocate(this->Bases);
// FIXME: allocate using the ASTContext
this->Bases = new CXXBaseSpecifier[NumBases];
this->Bases = new(C) CXXBaseSpecifier [NumBases];
this->NumBases = NumBases;
for (unsigned i = 0; i < NumBases; ++i)
this->Bases[i] = *Bases[i];
@ -78,7 +82,7 @@ CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
Context.getCanonicalType(ClassType));
unsigned FoundTQs;
DeclContext::lookup_const_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
Con != ConEnd; ++Con) {
if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context,
FoundTQs)) {
@ -97,7 +101,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
DeclContext::lookup_const_iterator Op, OpEnd;
for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
Op != OpEnd; ++Op) {
// C++ [class.copy]p9:
// A user-declared copy assignment operator is a non-static non-template
@ -201,7 +205,7 @@ CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
Context.getCanonicalType(ClassType.getUnqualifiedType()));
DeclContext::lookup_const_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = lookup(Context, ConstructorName);
for (llvm::tie(Con, ConEnd) = lookup(ConstructorName);
Con != ConEnd; ++Con) {
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if (Constructor->isDefaultConstructor())
@ -218,7 +222,7 @@ CXXRecordDecl::getDestructor(ASTContext &Context) {
= Context.DeclarationNames.getCXXDestructorName(ClassType);
DeclContext::lookup_iterator I, E;
llvm::tie(I, E) = lookup(Context, Name);
llvm::tie(I, E) = lookup(Name);
assert(I != E && "Did not find a destructor!");
const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
@ -294,8 +298,9 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
}
CXXBaseOrMemberInitializer::
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
: Args(0), NumArgs(0) {
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
SourceLocation L)
: Args(0), NumArgs(0), IdLoc(L) {
BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
BaseOrMember |= 0x01;
@ -309,8 +314,9 @@ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
}
CXXBaseOrMemberInitializer::
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
: Args(0), NumArgs(0) {
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
SourceLocation L)
: Args(0), NumArgs(0), IdLoc(L) {
BaseOrMember = reinterpret_cast<uintptr_t>(Member);
assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
@ -405,6 +411,27 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
isImplicitlyDeclared);
}
void
CXXConstructorDecl::setBaseOrMemberInitializers(
ASTContext &C,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers) {
if (NumInitializers > 0) {
NumBaseOrMemberInitializers = NumInitializers;
BaseOrMemberInitializers =
new (C, 8) CXXBaseOrMemberInitializer*[NumInitializers];
for (unsigned Idx = 0; Idx < NumInitializers; ++Idx)
BaseOrMemberInitializers[Idx] = Initializers[Idx];
}
}
void
CXXConstructorDecl::Destroy(ASTContext& C) {
C.Deallocate(BaseOrMemberInitializers);
this->~CXXMethodDecl();
C.Deallocate((void *)this);
}
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -420,13 +447,9 @@ OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) OverloadedFunctionDecl(DC, N);
}
void OverloadedFunctionDecl::addOverload(FunctionTemplateDecl *FTD) {
Functions.push_back(FTD);
// An overloaded function declaration always has the location of
// the most-recently-added function declaration.
if (FTD->getLocation().isValid())
this->setLocation(FTD->getLocation());
void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) {
Functions.push_back(F);
this->setLocation(F.get()->getLocation());
}
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,

View File

@ -45,10 +45,9 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
/// getIvarDecl - This method looks up an ivar in this ContextDecl.
///
ObjCIvarDecl *
ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const {
ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
lookup_const_iterator Ivar, IvarEnd;
for (llvm::tie(Ivar, IvarEnd) = lookup(Context, Id);
Ivar != IvarEnd; ++Ivar) {
for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
return ivar;
}
@ -57,7 +56,7 @@ ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const {
// Get the local instance method declared in this interface.
ObjCMethodDecl *
ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@ -67,8 +66,7 @@ ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
// @end
//
lookup_const_iterator Meth, MethEnd;
for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Meth != MethEnd; ++Meth) {
for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isInstanceMethod())
return MD;
@ -78,7 +76,7 @@ ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
// Get the local class method declared in this interface.
ObjCMethodDecl *
ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
ObjCContainerDecl::getClassMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@ -88,8 +86,7 @@ ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
// @end
//
lookup_const_iterator Meth, MethEnd;
for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Meth != MethEnd; ++Meth) {
for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isClassMethod())
return MD;
@ -102,10 +99,8 @@ ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
/// FIXME: Convert to DeclContext lookup...
///
ObjCPropertyDecl *
ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
IdentifierInfo *PropertyId) const {
for (prop_iterator I = prop_begin(Context), E = prop_end(Context);
I != E; ++I)
ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
if ((*I)->getIdentifier() == PropertyId)
return *I;
@ -113,8 +108,7 @@ ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
if (PID) {
for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
E = PID->protocol_end(); I != E; ++I)
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
PropertyId))
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
@ -122,37 +116,33 @@ ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
// Look through categories.
for (ObjCCategoryDecl *Category = OID->getCategoryList();
Category; Category = Category->getNextClassCategory()) {
if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(Context,
PropertyId))
if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
return P;
}
// Look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
E = OID->protocol_end(); I != E; ++I) {
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
PropertyId))
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
if (OID->getSuperClass())
return OID->getSuperClass()->FindPropertyDeclaration(Context,
PropertyId);
return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
} else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
// Look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
E = OCD->protocol_end(); I != E; ++I) {
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
PropertyId))
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
}
return 0;
}
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
ObjCInterfaceDecl *&clsDeclared) {
ObjCInterfaceDecl* ClassDecl = this;
while (ClassDecl != NULL) {
if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(Context, ID)) {
if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
clsDeclared = ClassDecl;
return I;
}
@ -177,13 +167,12 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
/// lookupInstanceMethod - This method returns an instance method by looking in
/// the class, its categories, and its super classes (using a linear search).
ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
Selector Sel) {
ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
ObjCInterfaceDecl* ClassDecl = this;
ObjCMethodDecl *MethodDecl = 0;
while (ClassDecl != NULL) {
if ((MethodDecl = ClassDecl->getInstanceMethod(Context, Sel)))
if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
@ -191,13 +180,13 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
ClassDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
return MethodDecl;
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
if ((MethodDecl = CatDecl->getInstanceMethod(Context, Sel)))
if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
@ -205,7 +194,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
CatDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
return MethodDecl;
CatDecl = CatDecl->getNextClassCategory();
}
@ -216,25 +205,24 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
// lookupClassMethod - This method returns a class method by looking in the
// class, its categories, and its super classes (using a linear search).
ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
Selector Sel) {
ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
ObjCInterfaceDecl* ClassDecl = this;
ObjCMethodDecl *MethodDecl = 0;
while (ClassDecl != NULL) {
if ((MethodDecl = ClassDecl->getClassMethod(Context, Sel)))
if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
E = ClassDecl->protocol_end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
return MethodDecl;
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
if ((MethodDecl = CatDecl->getClassMethod(Context, Sel)))
if ((MethodDecl = CatDecl->getClassMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
@ -242,7 +230,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
CatDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
return MethodDecl;
CatDecl = CatDecl->getNextClassCategory();
}
@ -446,30 +434,28 @@ ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
// it inherited.
ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
Selector Sel) {
ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
ObjCMethodDecl *MethodDecl = NULL;
if ((MethodDecl = getInstanceMethod(Context, Sel)))
if ((MethodDecl = getInstanceMethod(Sel)))
return MethodDecl;
for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
return MethodDecl;
return NULL;
}
// lookupInstanceMethod - Lookup a class method in the protocol and protocols
// it inherited.
ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
Selector Sel) {
ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
ObjCMethodDecl *MethodDecl = NULL;
if ((MethodDecl = getClassMethod(Context, Sel)))
if ((MethodDecl = getClassMethod(Sel)))
return MethodDecl;
for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
return MethodDecl;
return NULL;
}
@ -555,11 +541,10 @@ ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
}
void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
ObjCPropertyImplDecl *property) {
void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
// FIXME: The context should be correct before we get here.
property->setLexicalDeclContext(this);
addDecl(Context, property);
addDecl(property);
}
/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
@ -567,9 +552,8 @@ void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
/// the implemented property that uses it.
///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
i != e; ++i){
FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyIvarDecl() &&
PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
@ -583,9 +567,8 @@ FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
/// category @implementation block.
///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
i != e; ++i){
FindPropertyImplDecl(IdentifierInfo *Id) const {
for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl()->getIdentifier() == Id)
return PID;
@ -596,8 +579,7 @@ FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
// getInstanceMethod - This method returns an instance method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
Selector Sel) const {
ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@ -607,7 +589,7 @@ ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
// @end
//
lookup_const_iterator Meth, MethEnd;
for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
for (llvm::tie(Meth, MethEnd) = lookup(Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isInstanceMethod())
@ -619,8 +601,7 @@ ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
// getClassMethod - This method returns an instance method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
Selector Sel) const {
ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@ -630,7 +611,7 @@ ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
// @end
//
lookup_const_iterator Meth, MethEnd;
for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
for (llvm::tie(Meth, MethEnd) = lookup(Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isClassMethod())

View File

@ -74,14 +74,13 @@ namespace {
};
}
void Decl::print(llvm::raw_ostream &Out, ASTContext &Context,
unsigned Indentation) {
print(Out, Context, Context.PrintingPolicy, Indentation);
void Decl::print(llvm::raw_ostream &Out, unsigned Indentation) {
print(Out, getASTContext().PrintingPolicy, Indentation);
}
void Decl::print(llvm::raw_ostream &Out, ASTContext &Context,
const PrintingPolicy &Policy, unsigned Indentation) {
DeclPrinter Printer(Out, Context, Policy, Indentation);
void Decl::print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation) {
DeclPrinter Printer(Out, getASTContext(), Policy, Indentation);
Printer.Visit(this);
}
@ -97,6 +96,8 @@ static QualType GetBaseType(QualType T) {
BaseType = ATy->getElementType();
else if (const FunctionType* FTy = BaseType->getAsFunctionType())
BaseType = FTy->getResultType();
else if (const VectorType *VTy = BaseType->getAsVectorType())
BaseType = VTy->getElementType();
else
assert(0 && "Unknown declarator!");
}
@ -112,11 +113,10 @@ static QualType getDeclType(Decl* D) {
}
void Decl::printGroup(Decl** Begin, unsigned NumDecls,
llvm::raw_ostream &Out, ASTContext &Context,
const PrintingPolicy &Policy,
llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation) {
if (NumDecls == 1) {
(*Begin)->print(Out, Context, Policy, Indentation);
(*Begin)->print(Out, Policy, Indentation);
return;
}
@ -127,7 +127,7 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
PrintingPolicy SubPolicy(Policy);
if (TD && TD->isDefinition()) {
TD->print(Out, Context, Policy, Indentation);
TD->print(Out, Policy, Indentation);
Out << " ";
SubPolicy.SuppressTag = true;
}
@ -142,12 +142,12 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
SubPolicy.SuppressSpecifiers = true;
}
(*Begin)->print(Out, Context, SubPolicy, Indentation);
(*Begin)->print(Out, SubPolicy, Indentation);
}
}
void Decl::dump(ASTContext &Context) {
print(llvm::errs(), Context);
void Decl::dump() {
print(llvm::errs());
}
llvm::raw_ostream& DeclPrinter::Indent() {
@ -158,8 +158,7 @@ llvm::raw_ostream& DeclPrinter::Indent() {
void DeclPrinter::ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls) {
this->Indent();
Decl::printGroup(Decls.data(), Decls.size(), Out, Context,
Policy, Indentation);
Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
Out << ";\n";
Decls.clear();
@ -174,8 +173,7 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
Indentation += Policy.Indentation;
llvm::SmallVector<Decl*, 2> Decls;
for (DeclContext::decl_iterator D = DC->decls_begin(Context),
DEnd = DC->decls_end(Context);
for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
D != DEnd; ++D) {
if (!Policy.Dump) {
// Skip over implicit declarations in pretty-printing mode.
@ -364,7 +362,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
} else
Out << ' ';
D->getBody(Context)->printPretty(Out, Context, 0, SubPolicy, Indentation);
D->getBody()->printPretty(Out, Context, 0, SubPolicy, Indentation);
Out << '\n';
}
}
@ -504,7 +502,7 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
VisitDeclContext(D);
Indent() << "}";
} else
Visit(*D->decls_begin(Context));
Visit(*D->decls_begin());
}
void DeclPrinter::VisitTemplateDecl(TemplateDecl *D) {

View File

@ -81,11 +81,36 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
TemplateParameterList *Params,
NamedDecl *Decl) {
return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
}
void FunctionTemplateDecl::Destroy(ASTContext &C) {
if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) {
for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
Spec = CommonPtr->Specializations.begin(),
SpecEnd = CommonPtr->Specializations.end();
Spec != SpecEnd; ++Spec)
C.Deallocate(&*Spec);
}
Decl::Destroy(C);
}
FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
// Find the first declaration of this function template.
FunctionTemplateDecl *First = this;
while (First->getPreviousDeclaration())
First = First->getPreviousDeclaration();
if (First->CommonOrPrev.isNull()) {
// FIXME: Allocate with the ASTContext
First->CommonOrPrev = new Common;
}
return First->CommonOrPrev.get<Common*>();
}
//===----------------------------------------------------------------------===//
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//

View File

@ -41,8 +41,7 @@ CharacterLiteral* CharacterLiteral::Clone(ASTContext &C) const {
}
FloatingLiteral* FloatingLiteral::Clone(ASTContext &C) const {
bool exact = IsExact;
return new (C) FloatingLiteral(Value, &exact, getType(), Loc);
return new (C) FloatingLiteral(Value, IsExact, getType(), Loc);
}
ImaginaryLiteral* ImaginaryLiteral::Clone(ASTContext &C) const {
@ -456,7 +455,7 @@ Stmt *BlockExpr::getBody() {
/// with location to warn on and the source range[s] to report with the
/// warning.
bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
SourceRange &R2, ASTContext &Context) const {
SourceRange &R2) const {
// Don't warn if the expr is type dependent. The type could end up
// instantiating to void.
if (isTypeDependent())
@ -469,7 +468,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return true;
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->
isUnusedResultAWarning(Loc, R1, R2, Context);
isUnusedResultAWarning(Loc, R1, R2);
case UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(this);
@ -492,7 +491,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return false;
break;
case UnaryOperator::Extension:
return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
}
Loc = UO->getOperatorLoc();
R1 = UO->getSubExpr()->getSourceRange();
@ -502,8 +501,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
const BinaryOperator *BO = cast<BinaryOperator>(this);
// Consider comma to have side effects if the LHS or RHS does.
if (BO->getOpcode() == BinaryOperator::Comma)
return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context) ||
BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context);
return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2) ||
BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2);
if (BO->isAssignmentOp())
return false;
@ -520,9 +519,9 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// warning, warn about them.
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
if (Exp->getLHS() &&
Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context))
Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2))
return true;
return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context);
return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2);
}
case MemberExprClass:
@ -555,8 +554,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// If the callee has attribute pure, const, or warn_unused_result, warn
// about it. void foo() { strlen("bar"); } should warn.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeDRE->getDecl()))
if (FD->getAttr<WarnUnusedResultAttr>(Context) ||
FD->getAttr<PureAttr>(Context) || FD->getAttr<ConstAttr>(Context)) {
if (FD->getAttr<WarnUnusedResultAttr>() ||
FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
Loc = CE->getCallee()->getLocStart();
R1 = CE->getCallee()->getSourceRange();
@ -579,7 +578,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
if (!CS->body_empty())
if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
return E->isUnusedResultAWarning(Loc, R1, R2, Context);
return E->isUnusedResultAWarning(Loc, R1, R2);
Loc = cast<StmtExpr>(this)->getLParenLoc();
R1 = getSourceRange();
@ -590,7 +589,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// the cast is unused.
if (getType()->isVoidType())
return cast<CastExpr>(this)->getSubExpr()
->isUnusedResultAWarning(Loc, R1, R2, Context);
->isUnusedResultAWarning(Loc, R1, R2);
Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
@ -599,7 +598,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// the cast is unused.
if (getType()->isVoidType())
return cast<CastExpr>(this)->getSubExpr()
->isUnusedResultAWarning(Loc, R1, R2, Context);
->isUnusedResultAWarning(Loc, R1, R2);
Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
@ -607,11 +606,11 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
case ImplicitCastExprClass:
// Check the operand, since implicit casts are inserted by Sema
return cast<ImplicitCastExpr>(this)
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
case CXXDefaultArgExprClass:
return cast<CXXDefaultArgExpr>(this)
->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
->getExpr()->isUnusedResultAWarning(Loc, R1, R2);
case CXXNewExprClass:
// FIXME: In theory, there might be new expressions that don't have side
@ -620,7 +619,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return false;
case CXXExprWithTemporariesClass:
return cast<CXXExprWithTemporaries>(this)
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
}
}

View File

@ -13,6 +13,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
using namespace clang;
@ -153,6 +154,65 @@ StmtIterator UnresolvedDeclRefExpr::child_end() {
return child_iterator();
}
TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc)
: Expr(TemplateIdRefExprClass, T,
(Template.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs, NumTemplateArgs)),
(Template.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs, NumTemplateArgs))),
Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs)
{
TemplateArgument *StoredTemplateArgs
= reinterpret_cast<TemplateArgument *> (this+1);
for (unsigned I = 0; I != NumTemplateArgs; ++I)
new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
}
TemplateIdRefExpr *
TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
sizeof(TemplateArgument) * NumTemplateArgs);
return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
TemplateNameLoc, LAngleLoc, TemplateArgs,
NumTemplateArgs, RAngleLoc);
}
void TemplateIdRefExpr::Destroy(ASTContext &Context) {
const TemplateArgument *TemplateArgs = getTemplateArgs();
for (unsigned I = 0; I != NumTemplateArgs; ++I)
if (Expr *E = TemplateArgs[I].getAsExpr())
E->Destroy(Context);
}
Stmt::child_iterator TemplateIdRefExpr::child_begin() {
// FIXME: Walk the expressions in the template arguments (?)
return Stmt::child_iterator();
}
Stmt::child_iterator TemplateIdRefExpr::child_end() {
// FIXME: Walk the expressions in the template arguments (?)
return Stmt::child_iterator();
}
bool UnaryTypeTraitExpr::EvaluateTrait() const {
switch(UTT) {
default: assert(false && "Unknown type trait or not implemented");

View File

@ -242,8 +242,8 @@ APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
// FIXME: This is linear time.
unsigned i = 0;
for (RecordDecl::field_iterator Field = RD->field_begin(Info.Ctx),
FieldEnd = RD->field_end(Info.Ctx);
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end();
Field != FieldEnd; (void)++Field, ++i) {
if (*Field == FD)
break;
@ -485,6 +485,11 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
}
APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
const VectorType *VTy = E->getType()->getAsVectorType();
QualType EltTy = VTy->getElementType();
unsigned NElts = VTy->getNumElements();
unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
const Expr* SE = E->getSubExpr();
QualType SETy = SE->getType();
APValue Result = APValue();
@ -494,20 +499,62 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
return this->Visit(const_cast<Expr*>(SE));
} else if (SETy->isIntegerType()) {
APSInt IntResult;
if (EvaluateInteger(SE, IntResult, Info))
Result = APValue(IntResult);
if (!EvaluateInteger(SE, IntResult, Info))
return APValue();
Result = APValue(IntResult);
} else if (SETy->isRealFloatingType()) {
APFloat F(0.0);
if (EvaluateFloat(SE, F, Info))
Result = APValue(F);
if (!EvaluateFloat(SE, F, Info))
return APValue();
Result = APValue(F);
} else
return APValue();
// For casts of a scalar to ExtVector, convert the scalar to the element type
// and splat it to all elements.
if (E->getType()->isExtVectorType()) {
if (EltTy->isIntegerType() && Result.isInt())
Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(),
Info.Ctx));
else if (EltTy->isIntegerType())
Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(),
Info.Ctx));
else if (EltTy->isRealFloatingType() && Result.isInt())
Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(),
Info.Ctx));
else if (EltTy->isRealFloatingType())
Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(),
Info.Ctx));
else
return APValue();
// Splat and create vector APValue.
llvm::SmallVector<APValue, 4> Elts(NElts, Result);
return APValue(&Elts[0], Elts.size());
}
if (Result.isInt() || Result.isFloat()) {
unsigned NumElts = E->getType()->getAsVectorType()->getNumElements();
llvm::SmallVector<APValue, 4> Elts(NumElts, Result);
Result = APValue(&Elts[0], Elts.size());
// For casts of a scalar to regular gcc-style vector type, bitcast the scalar
// to the vector. To construct the APValue vector initializer, bitcast the
// initializing value to an APInt, and shift out the bits pertaining to each
// element.
APSInt Init;
Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt();
llvm::SmallVector<APValue, 4> Elts;
for (unsigned i = 0; i != NElts; ++i) {
APSInt Tmp = Init;
Tmp.extOrTrunc(EltWidth);
if (EltTy->isIntegerType())
Elts.push_back(APValue(Tmp));
else if (EltTy->isRealFloatingType())
Elts.push_back(APValue(APFloat(Tmp)));
else
return APValue();
Init >>= EltWidth;
}
return Result;
return APValue(&Elts[0], Elts.size());
}
APValue

View File

@ -153,8 +153,6 @@ void NestedNameSpecifier::Destroy(ASTContext &Context) {
Context.Deallocate((void *)this);
}
void NestedNameSpecifier::dump() {
PrintingPolicy Policy;
Policy.CPlusPlus = true;
print(llvm::errs(), Policy);
void NestedNameSpecifier::dump(const LangOptions &LO) {
print(llvm::errs(), PrintingPolicy(LO));
}

View File

@ -41,7 +41,6 @@ namespace {
const char *LastLocFilename;
unsigned LastLocLine;
PrintingPolicy Policy;
public:
StmtDumper(SourceManager *sm, FILE *f, unsigned maxDepth)
: SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {
@ -226,7 +225,8 @@ void StmtDumper::DumpDeclarator(Decl *D) {
}
std::string Name = VD->getNameAsString();
VD->getType().getAsStringInternal(Name, Policy);
VD->getType().getAsStringInternal(Name,
PrintingPolicy(VD->getASTContext().getLangOptions()));
fprintf(F, "%s", Name.c_str());
// If this is a vardecl with an initializer, emit it.

View File

@ -35,7 +35,7 @@ namespace {
public:
StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
const PrintingPolicy &Policy = PrintingPolicy(),
const PrintingPolicy &Policy,
unsigned Indentation = 0)
: OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
Policy(Policy) {}
@ -114,7 +114,7 @@ void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
}
void StmtPrinter::PrintRawDecl(Decl *D) {
D->print(OS, Context, Policy, IndentLevel);
D->print(OS, Policy, IndentLevel);
}
void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
@ -123,8 +123,7 @@ void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
for ( ; Begin != End; ++Begin)
Decls.push_back(*Begin);
Decl::printGroup(Decls.data(), Decls.size(), OS, Context, Policy,
IndentLevel);
Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
}
void StmtPrinter::VisitNullStmt(NullStmt *Node) {
@ -491,6 +490,18 @@ void StmtPrinter::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *Node) {
OS << Node->getDeclName().getAsString();
}
void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
if (Node->getQualifier())
Node->getQualifier()->print(OS, Policy);
Node->getTemplateName().print(OS, Policy, true);
OS << '<';
OS << TemplateSpecializationType::PrintTemplateArgumentList(
Node->getTemplateArgs(),
Node->getNumTemplateArgs(),
Policy);
OS << '>';
}
void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
if (Node->getBase()) {
PrintExpr(Node->getBase());
@ -861,7 +872,7 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
}
void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
if (Policy.CPlusPlus)
if (Policy.LangOpts.CPlusPlus)
OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
else {
OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
@ -1216,7 +1227,8 @@ void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
//===----------------------------------------------------------------------===//
void Stmt::dumpPretty(ASTContext& Context) const {
printPretty(llvm::errs(), Context, 0, PrintingPolicy());
printPretty(llvm::errs(), Context, 0,
PrintingPolicy(Context.getLangOptions()));
}
void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,

View File

@ -15,6 +15,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@ -59,7 +60,8 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
}
void TemplateName::dump() const {
PrintingPolicy Policy;
Policy.CPlusPlus = true;
print(llvm::errs(), Policy);
LangOptions LO; // FIXME!
LO.CPlusPlus = true;
LO.Bool = true;
print(llvm::errs(), PrintingPolicy(LO));
}

View File

@ -185,6 +185,12 @@ bool Type::isStructureType() const {
return RT->getDecl()->isStruct();
return false;
}
bool Type::isVoidPointerType() const {
if (const PointerType *PT = getAsPointerType())
return PT->getPointeeType()->isVoidType();
return false;
}
bool Type::isUnionType() const {
if (const RecordType *RT = getAsRecordType())
return RT->getDecl()->isUnion();
@ -938,11 +944,11 @@ bool Type::isSpecifierType() const {
}
}
const char *BuiltinType::getName(bool CPlusPlus) const {
const char *BuiltinType::getName(const LangOptions &LO) const {
switch (getKind()) {
default: assert(0 && "Unknown builtin type!");
case Void: return "void";
case Bool: return CPlusPlus? "bool" : "_Bool";
case Bool: return LO.Bool ? "bool" : "_Bool";
case Char_S: return "char";
case Char_U: return "char";
case SChar: return "signed char";
@ -1160,9 +1166,9 @@ TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
//===----------------------------------------------------------------------===//
void QualType::dump(const char *msg) const {
PrintingPolicy Policy;
std::string R = "identifier";
getAsStringInternal(R, Policy);
LangOptions LO;
getAsStringInternal(R, PrintingPolicy(LO));
if (msg)
fprintf(stderr, "%s: %s\n", msg, R.c_str());
else
@ -1174,7 +1180,8 @@ void QualType::dump() const {
void Type::dump() const {
std::string S = "identifier";
getAsStringInternal(S, PrintingPolicy());
LangOptions LO;
getAsStringInternal(S, PrintingPolicy(LO));
fprintf(stderr, "%s\n", S.c_str());
}
@ -1193,7 +1200,8 @@ static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
std::string QualType::getAsString() const {
std::string S;
getAsStringInternal(S, PrintingPolicy());
LangOptions LO;
getAsStringInternal(S, PrintingPolicy(LO));
return S;
}
@ -1224,11 +1232,11 @@ QualType::getAsStringInternal(std::string &S,
void BuiltinType::getAsStringInternal(std::string &S,
const PrintingPolicy &Policy) const {
if (S.empty()) {
S = getName(Policy.CPlusPlus);
S = getName(Policy.LangOpts);
} else {
// Prefix the basic type, e.g. 'int X'.
S = ' ' + S;
S = getName(Policy.CPlusPlus) + S;
S = getName(Policy.LangOpts) + S;
}
}
@ -1470,7 +1478,7 @@ void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy
if (getNumArgs())
S += ", ";
S += "...";
} else if (getNumArgs() == 0 && !Policy.CPlusPlus) {
} else if (getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
// Do not emit int() if we have a proto, emit 'int(void)'.
S += "void";
}

View File

@ -198,7 +198,7 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,
return Base;
Loc BaseL = cast<Loc>(Base);
const TypedRegion* BaseR = 0;
const MemRegion* BaseR = 0;
switch(BaseL.getSubKind()) {
case loc::GotoLabelKind:
@ -216,17 +216,11 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,
return Base;
}
if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
BaseR = TR;
if (isa<TypedRegion>(R) || isa<SymbolicRegion>(R)) {
BaseR = R;
break;
}
if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
SymbolRef Sym = SR->getSymbol();
BaseR = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR);
}
break;
}
@ -242,9 +236,10 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,
return Base;
}
if (BaseR)
if (BaseR) {
return ValMgr.makeLoc(MRMgr.getElementRegion(elementType, UnknownVal(),
BaseR, getContext()));
}
else
return UnknownVal();
}
@ -319,54 +314,50 @@ SVal BasicStoreManager::Retrieve(const GRState *state, Loc loc, QualType T) {
}
Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {
switch (loc.getSubKind()) {
case loc::MemRegionKind: {
const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
ASTContext &C = StateMgr.getContext();
// Special case: handle store of pointer values (Loc) to pointers via
// a cast to intXX_t*, void*, etc. This is needed to handle
// OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
// FIXME: Should check for index 0.
QualType T = ER->getLocationType(C);
if (isHigherOrderRawPtr(T, C))
R = ER->getSuperRegion();
}
if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
return store;
// We only track bindings to self.ivar.
if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
if (IVR->getSuperRegion() != SelfRegion)
return store;
if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
// Only convert 'V' to a location iff the underlying region type
// is a location as well.
// FIXME: We are allowing a store of an arbitrary location to
// a pointer. We may wish to flag a type error here if the types
// are incompatible. This may also cause lots of breakage
// elsewhere. Food for thought.
if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) {
if (TyR->isBoundable() &&
Loc::IsLocType(TyR->getValueType(C)))
V = X->getLoc();
}
}
if (isa<loc::ConcreteInt>(loc))
return store;
BindingsTy B = GetBindings(store);
return V.isUnknown()
? VBFactory.Remove(B, R).getRoot()
: VBFactory.Add(B, R, V).getRoot();
}
default:
assert ("SetSVal for given Loc type not yet implemented.");
const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
ASTContext &C = StateMgr.getContext();
// Special case: handle store of pointer values (Loc) to pointers via
// a cast to intXX_t*, void*, etc. This is needed to handle
// OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
// FIXME: Should check for index 0.
QualType T = ER->getLocationType(C);
if (isHigherOrderRawPtr(T, C))
R = ER->getSuperRegion();
}
if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
return store;
// We only track bindings to self.ivar.
if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
if (IVR->getSuperRegion() != SelfRegion)
return store;
if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
// Only convert 'V' to a location iff the underlying region type
// is a location as well.
// FIXME: We are allowing a store of an arbitrary location to
// a pointer. We may wish to flag a type error here if the types
// are incompatible. This may also cause lots of breakage
// elsewhere. Food for thought.
if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) {
if (TyR->isBoundable() &&
Loc::IsLocType(TyR->getValueType(C)))
V = X->getLoc();
}
}
BindingsTy B = GetBindings(store);
return V.isUnknown()
? VBFactory.Remove(B, R).getRoot()
: VBFactory.Add(B, R, V).getRoot();
}
Store BasicStoreManager::Remove(Store store, Loc loc) {
@ -521,7 +512,7 @@ Store BasicStoreManager::getInitialStore() {
// Scan the method for ivar references. While this requires an
// entire AST scan, the cost should not be high in practice.
St = scanForIvars(MD->getBody(getContext()), PD, St);
St = scanForIvars(MD->getBody(), PD, St);
}
}
}
@ -537,10 +528,9 @@ Store BasicStoreManager::getInitialStore() {
// Initialize globals and parameters to symbolic values.
// Initialize local variables to undefined.
const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD);
SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
isa<ImplicitParamDecl>(VD))
? ValMgr.getRegionValueSymbolVal(R)
: UndefinedVal();
SVal X = R->hasGlobalsOrParametersStorage()
? ValMgr.getRegionValueSymbolVal(R)
: UndefinedVal();
St = BindInternal(St, ValMgr.makeLoc(R), X);
}
@ -594,7 +584,7 @@ Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
} else {
// Process local scalar variables.
QualType T = VD->getType();
if (Loc::IsLocType(T) || T->isIntegerType()) {
if (ValMgr.getSymbolManager().canSymbolicate(T)) {
SVal V = InitVal ? *InitVal : UndefinedVal();
store = BindInternal(store, getLoc(VD), V);
}

View File

@ -146,7 +146,7 @@ class VISIBILITY_HIDDEN PathDiagnosticBuilder : public BugReporterContext {
ParentMap& getParentMap() {
if (PM.get() == 0)
PM.reset(new ParentMap(getCodeDecl().getBody(getASTContext())));
PM.reset(new ParentMap(getCodeDecl().getBody()));
return *PM.get();
}
@ -182,8 +182,7 @@ PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N) {
if (Stmt *S = GetNextStmt(N))
return PathDiagnosticLocation(S, getSourceManager());
return FullSourceLoc(getCodeDecl().getBodyRBrace(getASTContext()),
getSourceManager());
return FullSourceLoc(getCodeDecl().getBodyRBrace(), getSourceManager());
}
PathDiagnosticLocation
@ -893,7 +892,7 @@ class VISIBILITY_HIDDEN EdgeBuilder {
// statement (if it doesn't already exist).
// FIXME: Should handle CXXTryStmt if analyser starts supporting C++.
if (const CompoundStmt *CS =
PDB.getCodeDecl().getCompoundBody(PDB.getASTContext()))
PDB.getCodeDecl().getCompoundBody())
if (!CS->body_empty()) {
SourceLocation Loc = (*CS->body_begin())->getLocStart();
rawAddEdge(PathDiagnosticLocation(Loc, PDB.getSourceManager()));

View File

@ -156,13 +156,13 @@ static bool followsFundamentalRule(Selector S) {
}
static const ObjCMethodDecl*
ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD, ASTContext &Context) {
ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
ObjCInterfaceDecl *ID =
const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());
return MD->isInstanceMethod()
? ID->lookupInstanceMethod(Context, MD->getSelector())
: ID->lookupClassMethod(Context, MD->getSelector());
? ID->lookupInstanceMethod(MD->getSelector())
: ID->lookupClassMethod(MD->getSelector());
}
namespace {
@ -827,8 +827,7 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
QualType ResultTy = MD->getResultType();
// Resolve the method decl last.
if (const ObjCMethodDecl *InterfaceMD =
ResolveToInterfaceMethodDecl(MD, Ctx))
if (const ObjCMethodDecl *InterfaceMD = ResolveToInterfaceMethodDecl(MD))
MD = InterfaceMD;
if (MD->isInstanceMethod())
@ -1248,15 +1247,15 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
// Determine if there is a special return effect for this method.
if (isTrackedObjCObjectType(RetTy)) {
if (FD->getAttr<NSReturnsRetainedAttr>(Ctx)) {
if (FD->getAttr<NSReturnsRetainedAttr>()) {
Summ.setRetEffect(ObjCAllocRetE);
}
else if (FD->getAttr<CFReturnsRetainedAttr>(Ctx)) {
else if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
}
else if (RetTy->getAsPointerType()) {
if (FD->getAttr<CFReturnsRetainedAttr>(Ctx)) {
if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
}
@ -1270,10 +1269,10 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
// Determine if there is a special return effect for this method.
if (isTrackedObjCObjectType(MD->getResultType())) {
if (MD->getAttr<NSReturnsRetainedAttr>(Ctx)) {
if (MD->getAttr<NSReturnsRetainedAttr>()) {
Summ.setRetEffect(ObjCAllocRetE);
}
else if (MD->getAttr<CFReturnsRetainedAttr>(Ctx)) {
else if (MD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
}
@ -2632,7 +2631,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,
if (!L.isValid()) {
const Decl &D = BRC.getCodeDecl();
L = PathDiagnosticLocation(D.getBodyRBrace(BRC.getASTContext()), SMgr);
L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);
}
std::string sbuf;
@ -2796,7 +2795,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
// to identify conjured symbols by an expression pair: the enclosing
// expression (the context) and the expression itself. This should
// disambiguate conjured symbols.
unsigned Count = Builder.getCurrentBlockCount();
const TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());
if (R) {
@ -2833,7 +2832,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (R->isBoundable()) {
// Set the value of the variable to be a conjured symbol.
unsigned Count = Builder.getCurrentBlockCount();
QualType T = R->getValueType(Ctx);
if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())){
@ -2857,20 +2856,31 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
state->getStateManager().getRegionManager();
// Iterate through the fields and construct new symbols.
for (RecordDecl::field_iterator FI=RD->field_begin(Ctx),
FE=RD->field_end(Ctx); FI!=FE; ++FI) {
for (RecordDecl::field_iterator FI=RD->field_begin(),
FE=RD->field_end(); FI!=FE; ++FI) {
// For now just handle scalar fields.
FieldDecl *FD = *FI;
QualType FT = FD->getType();
const FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
if (Loc::IsLocType(FT) ||
(FT->isIntegerType() && FT->isScalarType())) {
const FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
SVal V = ValMgr.getConjuredSymbolVal(*I, FT, Count);
state = state->bindLoc(ValMgr.makeLoc(FR), V);
}
}
else if (FT->isStructureType()) {
// set the default value of the struct field to conjured
// symbol. Note that the type of the symbol is irrelavant.
// We cannot use the type of the struct otherwise ValMgr won't
// give us the conjured symbol.
StoreManager& StoreMgr =
Eng.getStateManager().getStoreManager();
SVal V = ValMgr.getConjuredSymbolVal(*I,
Eng.getContext().IntTy,
Count);
state = StoreMgr.setDefaultValue(state, FR, V);
}
}
} else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
// Set the default value of the array to conjured symbol.
@ -2884,6 +2894,15 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
}
}
}
else if (isa<AllocaRegion>(MR->getRegion())) {
// Invalidate the alloca region by setting its default value to
// conjured symbol. The type of the symbol is irrelavant.
SVal V = ValMgr.getConjuredSymbolVal(*I, Eng.getContext().IntTy,
Count);
StoreManager& StoreMgr =
Eng.getStateManager().getStoreManager();
state = StoreMgr.setDefaultValue(state, MR->getRegion(), V);
}
else
state = state->bindLoc(*MR, UnknownVal());
}

View File

@ -85,7 +85,7 @@ class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
const LiveVariables::AnalysisDataTy& AD,
const LiveVariables::ValTy& Live) {
if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>(Ctx))
if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())
Report(VD, dsk, Ex->getSourceRange().getBegin(),
Val->getSourceRange());
}
@ -190,7 +190,7 @@ class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
// A dead initialization is a variable that is dead after it
// is initialized. We don't flag warnings for those variables
// marked 'unused'.
if (!Live(V, AD) && V->getAttr<UnusedAttr>(Ctx) == 0) {
if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {
// Special case: check for initializations with constants.
//
// e.g. : int x = 0;

View File

@ -109,7 +109,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
QualType T = ID->getType();
if (!Ctx.isObjCObjectPointerType(T) ||
ID->getAttr<IBOutletAttr>(Ctx)) // Skip IBOutlets.
ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
continue;
containsPointerIvar = true;
@ -147,8 +147,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
ObjCMethodDecl* MD = 0;
// Scan the instance methods for "dealloc".
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
E = D->instmeth_end(Ctx); I!=E; ++I) {
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
E = D->instmeth_end(); I!=E; ++I) {
if ((*I)->getSelector() == S) {
MD = *I;
@ -172,7 +172,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
}
// dealloc found. Scan for missing [super dealloc].
if (MD->getBody(Ctx) && !scan_dealloc(MD->getBody(Ctx), S)) {
if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {
const char* name = LOpts.getGCMode() == LangOptions::NonGC
? "missing [super dealloc]"
@ -198,8 +198,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
// Scan for missing and extra releases of ivars used by implementations
// of synthesized properties
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
E = D->propimpl_end(Ctx); I!=E; ++I) {
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
E = D->propimpl_end(); I!=E; ++I) {
// We can only check the synthesized properties
if((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
@ -223,7 +223,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
// ivar must be released if and only if the kind of setter was not 'assign'
bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign;
if(scan_ivar_release(MD->getBody(Ctx), ID, PD, RS, SelfII, Ctx)
if(scan_ivar_release(MD->getBody(), ID, PD, RS, SelfII, Ctx)
!= requiresRelease) {
const char *name;
const char* category = "Memory (Core Foundation/Objective-C)";

View File

@ -86,8 +86,8 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
MapTy IMeths;
unsigned NumMethods = 0;
for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(Ctx),
E=ID->instmeth_end(Ctx); I!=E; ++I) {
for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
E=ID->instmeth_end(); I!=E; ++I) {
ObjCMethodDecl* M = *I;
IMeths[M->getSelector()] = M;
@ -97,8 +97,8 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
// Now recurse the class hierarchy chain looking for methods with the
// same signatures.
while (C && NumMethods) {
for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(Ctx),
E=C->instmeth_end(Ctx); I!=E; ++I) {
for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(),
E=C->instmeth_end(); I!=E; ++I) {
ObjCMethodDecl* M = *I;
Selector S = M->getSelector();

View File

@ -59,9 +59,6 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
ObjCInterfaceDecl* ID = D->getClassInterface();
IvarUsageMap M;
ASTContext &Ctx = BR.getContext();
// Iterate over the ivars.
for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
I!=E; ++I) {
@ -73,7 +70,7 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
continue;
// Skip IB Outlets.
if (ID->getAttr<IBOutletAttr>(Ctx))
if (ID->getAttr<IBOutletAttr>())
continue;
M[ID] = Unused;
@ -83,14 +80,14 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
return;
// Now scan the methods for accesses.
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
E = D->instmeth_end(Ctx); I!=E; ++I)
Scan(M, (*I)->getBody(Ctx));
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
E = D->instmeth_end(); I!=E; ++I)
Scan(M, (*I)->getBody());
// Scan for @synthesized property methods that act as setters/getters
// to an ivar.
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
E = D->propimpl_end(Ctx); I!=E; ++I)
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
E = D->propimpl_end(); I!=E; ++I)
Scan(M, *I);
// Find ivars that are unused.

View File

@ -143,8 +143,19 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
SVal X = I.getData();
// If the block expr's value is a memory region, then mark that region.
if (isa<loc::MemRegionVal>(X))
DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());
if (isa<loc::MemRegionVal>(X)) {
const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
DRoots.push_back(R);
// Mark the super region of the RX as live.
// e.g.: int x; char *y = (char*) &x; if (*y) ...
// 'y' => element region. 'x' is its super region.
// We only add one level super region for now.
// FIXME: maybe multiple level of super regions should be added.
if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
DRoots.push_back(SR->getSuperRegion());
}
}
// Mark all symbols in the block expr's value live.
MarkLiveCallback cb(SymReaper);

View File

@ -1437,8 +1437,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
const FunctionDecl* FD = L.getAsFunctionDecl();
if (FD) {
if (FD->getAttr<NoReturnAttr>(getContext()) ||
FD->getAttr<AnalyzerNoReturnAttr>(getContext()))
if (FD->getAttr<NoReturnAttr>() ||
FD->getAttr<AnalyzerNoReturnAttr>())
Builder->BuildSinks = true;
else {
// HACK: Some functions are not marked noreturn, and don't return.
@ -3154,7 +3154,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
SourceLocation SLoc = S->getLocStart();
Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
S->printPretty(Out);
LangOptions LO; // FIXME.
S->printPretty(Out, 0, PrintingPolicy(LO));
if (SLoc.isFileID()) {
Out << "\\lline="
@ -3208,7 +3209,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
SourceLocation SLoc = T->getLocStart();
Out << "\\|Terminator: ";
E.getSrc()->printTerminator(Out);
LangOptions LO; // FIXME.
E.getSrc()->printTerminator(Out, LO);
if (SLoc.isFileID()) {
Out << "\\lline="
@ -3223,11 +3225,12 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
if (Label) {
if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
Out << "\\lcase ";
C->getLHS()->printPretty(Out);
LangOptions LO; // FIXME.
C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
if (Stmt* RHS = C->getRHS()) {
Out << " .. ";
RHS->printPretty(Out);
RHS->printPretty(Out, 0, PrintingPolicy(LO));
}
Out << ":";

View File

@ -566,7 +566,7 @@ class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck {
if (!FD)
return false;
const NonNullAttr* Att = FD->getAttr<NonNullAttr>(BR.getContext());
const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
if (!Att)
return false;

View File

@ -166,7 +166,8 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
else { Out << nl; }
Out << " (" << (void*) I.getKey() << ") ";
I.getKey()->printPretty(Out);
LangOptions LO; // FIXME.
I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
Out << " : ";
I.getData().print(Out);
}
@ -183,7 +184,8 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
else { Out << nl; }
Out << " (" << (void*) I.getKey() << ") ";
I.getKey()->printPretty(Out);
LangOptions LO; // FIXME.
I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
Out << " : ";
I.getData().print(Out);
}

View File

@ -135,9 +135,10 @@ void TransferFuncs::Visit(Stmt *S) {
StmtVisitor<TransferFuncs,void>::Visit(S);
}
else
else {
// For block-level expressions, mark that they are live.
LiveState(S,AD) = Alive;
}
}
void TransferFuncs::VisitTerminator(CFGBlock* B) {

View File

@ -143,6 +143,10 @@ void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
// Region pretty-printing.
//===----------------------------------------------------------------------===//
void MemRegion::printStdErr() const {
print(llvm::errs());
}
std::string MemRegion::getString() const {
std::string s;
llvm::raw_string_ostream os(s);
@ -184,7 +188,8 @@ void FieldRegion::print(llvm::raw_ostream& os) const {
}
void StringRegion::print(llvm::raw_ostream& os) const {
Str->printPretty(os);
LangOptions LO; // FIXME.
Str->printPretty(os, 0, PrintingPolicy(LO));
}
void SymbolicRegion::print(llvm::raw_ostream& os) const {
@ -218,6 +223,10 @@ MemSpaceRegion* MemRegionManager::getStackRegion() {
return LazyAllocate(stack);
}
MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
return LazyAllocate(stackArguments);
}
MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
return LazyAllocate(globals);
}
@ -327,8 +336,10 @@ const MemSpaceRegion *MemRegion::getMemorySpace() const {
}
bool MemRegion::hasStackStorage() const {
if (const MemSpaceRegion *MS = getMemorySpace())
return MS == getMemRegionManager()->getStackRegion();
if (const MemSpaceRegion *MS = getMemorySpace()) {
MemRegionManager *Mgr = getMemRegionManager();
return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
}
return false;
}
@ -343,10 +354,35 @@ bool MemRegion::hasHeapStorage() const {
bool MemRegion::hasHeapOrStackStorage() const {
if (const MemSpaceRegion *MS = getMemorySpace()) {
MemRegionManager *Mgr = getMemRegionManager();
return MS == Mgr->getHeapRegion() || MS == Mgr->getStackRegion();
return MS == Mgr->getHeapRegion()
|| MS == Mgr->getStackRegion()
|| MS == Mgr->getStackArgumentsRegion();
}
return false;
}
}
bool MemRegion::hasGlobalsStorage() const {
if (const MemSpaceRegion *MS = getMemorySpace())
return MS == getMemRegionManager()->getGlobalsRegion();
return false;
}
bool MemRegion::hasParametersStorage() const {
if (const MemSpaceRegion *MS = getMemorySpace())
return MS == getMemRegionManager()->getStackArgumentsRegion();
return false;
}
bool MemRegion::hasGlobalsOrParametersStorage() const {
if (const MemSpaceRegion *MS = getMemorySpace()) {
MemRegionManager *Mgr = getMemRegionManager();
return MS == Mgr->getGlobalsRegion()
|| MS == Mgr->getStackArgumentsRegion();
}
return false;
}
//===----------------------------------------------------------------------===//
// View handling.

View File

@ -347,9 +347,6 @@ class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
// FIXME: Remove.
ASTContext& getContext() { return StateMgr.getContext(); }
// FIXME: Use ValueManager?
SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
};
} // end anonymous namespace
@ -822,12 +819,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
const TypedRegion *R = cast<TypedRegion>(MR);
assert(R && "bad region");
if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
return RetrieveField(state, FR);
if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
return RetrieveElement(state, ER);
// FIXME: We should eventually handle funny addressing. e.g.:
//
// int x = ...;
@ -848,6 +839,12 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
// FIXME: handle Vector types.
if (RTy->isVectorType())
return UnknownVal();
if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
return RetrieveField(state, FR);
if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
return RetrieveElement(state, ER);
RegionBindingsTy B = GetRegionBindings(state->getStore());
RegionBindingsTy::data_type* V = B.lookup(R);
@ -882,14 +879,8 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
if (VD == SelfDecl)
return loc::MemRegionVal(getSelfRegion(0));
if (isa<ParmVarDecl>(VD) || isa<ImplicitParamDecl>(VD) ||
VD->hasGlobalStorage()) {
QualType VTy = VD->getType();
if (Loc::IsLocType(VTy) || VTy->isIntegerType())
return ValMgr.getRegionValueSymbolVal(VR);
else
return UnknownVal();
}
if (VR->hasGlobalsOrParametersStorage())
return ValMgr.getRegionValueSymbolValOrUnknown(VR, VD->getType());
}
if (R->hasHeapOrStackStorage()) {
@ -907,23 +898,21 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
RTy = T->getAsPointerType()->getPointeeType();
}
// All other integer values are symbolic.
if (Loc::IsLocType(RTy) || RTy->isIntegerType())
return ValMgr.getRegionValueSymbolVal(R, RTy);
else
return UnknownVal();
// All other values are symbolic.
return ValMgr.getRegionValueSymbolValOrUnknown(R, RTy);
}
SVal RegionStoreManager::RetrieveElement(const GRState* state,
const ElementRegion* R) {
// Check if the region has a binding.
RegionBindingsTy B = GetRegionBindings(state->getStore());
const SVal* V = B.lookup(R);
if (V)
if (const SVal* V = B.lookup(R))
return *V;
const MemRegion* superR = R->getSuperRegion();
// Check if the region is an element region of a string literal.
if (const StringRegion *StrR=dyn_cast<StringRegion>(R->getSuperRegion())) {
if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
const StringLiteral *Str = StrR->getStringLiteral();
SVal Idx = R->getIndex();
if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
@ -937,18 +926,38 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,
}
}
const MemRegion* SuperR = R->getSuperRegion();
const SVal* D = state->get<RegionDefaultValue>(SuperR);
if (D) {
// Check if the super region has a default value.
if (const SVal *D = state->get<RegionDefaultValue>(superR)) {
if (D->hasConjuredSymbol())
return ValMgr.getRegionValueSymbolVal(R);
else
return *D;
}
if (R->hasHeapOrStackStorage())
// Check if the super region has a binding.
if (B.lookup(superR)) {
// We do not extract the bit value from super region for now.
return UnknownVal();
}
if (R->hasHeapStorage()) {
// FIXME: If the region has heap storage and we know nothing special
// about its bindings, should we instead return UnknownVal? Seems like
// we should only return UndefinedVal in the cases where we know the value
// will be undefined.
return UndefinedVal();
}
if (R->hasStackStorage() && !R->hasParametersStorage()) {
// Currently we don't reason specially about Clang-style vectors. Check
// if superR is a vector and if so return Unknown.
if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
if (typedSuperR->getValueType(getContext())->isVectorType())
return UnknownVal();
}
return UndefinedVal();
}
QualType Ty = R->getValueType(getContext());
@ -957,10 +966,7 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,
if (const QualType *p = state->get<RegionCasts>(R))
Ty = (*p)->getAsPointerType()->getPointeeType();
if (Loc::IsLocType(Ty) || Ty->isIntegerType())
return ValMgr.getRegionValueSymbolVal(R, Ty);
else
return UnknownVal();
return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
}
SVal RegionStoreManager::RetrieveField(const GRState* state,
@ -969,13 +975,11 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
// Check if the region has a binding.
RegionBindingsTy B = GetRegionBindings(state->getStore());
const SVal* V = B.lookup(R);
if (V)
if (const SVal* V = B.lookup(R))
return *V;
const MemRegion* SuperR = R->getSuperRegion();
const SVal* D = state->get<RegionDefaultValue>(SuperR);
if (D) {
const MemRegion* superR = R->getSuperRegion();
if (const SVal* D = state->get<RegionDefaultValue>(superR)) {
if (D->hasConjuredSymbol())
return ValMgr.getRegionValueSymbolVal(R);
@ -988,7 +992,11 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
assert(0 && "Unknown default value");
}
if (R->hasHeapOrStackStorage())
// FIXME: Is this correct? Should it be UnknownVal?
if (R->hasHeapStorage())
return UndefinedVal();
if (R->hasStackStorage() && !R->hasParametersStorage())
return UndefinedVal();
// If the region is already cast to another type, use that type to create the
@ -998,11 +1006,8 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
Ty = tmp->getAsPointerType()->getPointeeType();
}
// All other integer values are symbolic.
if (Loc::IsLocType(Ty) || Ty->isIntegerType())
return ValMgr.getRegionValueSymbolVal(R, Ty);
else
return UnknownVal();
// All other values are symbolic.
return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
}
SVal RegionStoreManager::RetrieveStruct(const GRState *state,
@ -1018,8 +1023,7 @@ SVal RegionStoreManager::RetrieveStruct(const GRState *state,
// FIXME: We shouldn't use a std::vector. If RecordDecl doesn't have a
// reverse iterator, we should implement one.
std::vector<FieldDecl *> Fields(RD->field_begin(getContext()),
RD->field_end(getContext()));
std::vector<FieldDecl *> Fields(RD->field_begin(), RD->field_end());
for (std::vector<FieldDecl *>::reverse_iterator Field = Fields.rbegin(),
FieldEnd = Fields.rend();
@ -1074,6 +1078,9 @@ Store RegionStoreManager::Remove(Store store, Loc L) {
}
const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
if (isa<loc::ConcreteInt>(L))
return state;
// If we get here, the location should be a region.
const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
@ -1204,8 +1211,7 @@ RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R,
RecordDecl::field_iterator FI, FE;
for (FI = RD->field_begin(getContext()), FE = RD->field_end(getContext());
FI != FE; ++FI, ++VI) {
for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI, ++VI) {
if (VI == VE)
break;
@ -1357,8 +1363,9 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
IntermediateRoots.pop_back();
if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
if (SymReaper.isLive(Loc, VR->getDecl()))
if (SymReaper.isLive(Loc, VR->getDecl())) {
RegionRoots.push_back(VR); // This is a live "root".
}
}
else if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
if (SymReaper.isLive(SR->getSymbol()))
@ -1366,19 +1373,19 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
}
else {
// Get the super region for R.
const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
const MemRegion* superR = cast<SubRegion>(R)->getSuperRegion();
// Get the current set of subregions for SuperR.
const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR);
const SubRegionsTy* SRptr = SubRegMap.lookup(superR);
SubRegionsTy SRs = SRptr ? *SRptr : SubRegF.GetEmptySet();
// Add R to the subregions of SuperR.
SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SRs, R));
SubRegMap = SubRegMapF.Add(SubRegMap, superR, SubRegF.Add(SRs, R));
// Super region may be VarRegion or subregion of another VarRegion. Add it
// to the work list.
if (isa<SubRegion>(SuperR))
IntermediateRoots.push_back(SuperR);
if (isa<SubRegion>(superR))
IntermediateRoots.push_back(superR);
}
}
@ -1409,9 +1416,19 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
SVal X = *Xptr;
UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
// If X is a region, then add it the RegionRoots.
if (loc::MemRegionVal* RegionX = dyn_cast<loc::MemRegionVal>(&X))
RegionRoots.push_back(RegionX->getRegion());
// If X is a region, then add it to the RegionRoots.
if (const MemRegion *RX = X.getAsRegion()) {
RegionRoots.push_back(RX);
// Mark the super region of the RX as live.
// e.g.: int x; char *y = (char*) &x; if (*y) ...
// 'y' => element region. 'x' is its super region.
// We only add one level super region for now.
// FIXME: maybe multiple level of super regions should be added.
if (const SubRegion *SR = dyn_cast<SubRegion>(RX)) {
RegionRoots.push_back(SR->getSuperRegion());
}
}
}
// Get the subregions of R. These are RegionRoots as well since they
@ -1422,6 +1439,7 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
for (SubRegionsTy::iterator I=SR.begin(), E=SR.end(); I!=E; ++I)
RegionRoots.push_back(*I);
}
// We have now scanned the store, marking reachable regions and symbols
@ -1429,7 +1447,6 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
// as well as update DSymbols with the set symbols that are now dead.
for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
const MemRegion* R = I.getKey();
// If this region live? Is so, none of its symbols are dead.
if (Marked.count(R))
continue;

View File

@ -114,6 +114,13 @@ const SymExpr *SVal::getAsSymbolicExpression() const {
return getAsSymbol();
}
const MemRegion *SVal::getAsRegion() const {
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this))
return X->getRegion();
return 0;
}
bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
return itr == X.itr;
}

View File

@ -88,10 +88,10 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R,
// If the super region is an element region, strip it away.
// FIXME: Is this the right thing to do in all cases?
const TypedRegion *Base = isa<ElementRegion>(TR) ?
cast<TypedRegion>(TR->getSuperRegion()) : TR;
const MemRegion *Base = isa<ElementRegion>(TR) ? TR->getSuperRegion()
: TR;
ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base,
StateMgr.getContext());
StateMgr.getContext());
return CastResult(state, ER);
}
}

View File

@ -89,7 +89,7 @@ static void AddKeyword(const char *Keyword, unsigned KWLen,
else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2;
else if (LangOpts.GNUMode && (Flags & KEYGNU)) AddResult = 1;
else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
else if (LangOpts.OpenCL && (Flags & BOOLSUPPORT)) AddResult = 2;
else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
// Don't add this keyword if disabled in this language.
if (AddResult == 0) return;

View File

@ -41,6 +41,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
UIntMaxType = UnsignedLongLong;
IntPtrType = SignedLong;
WCharType = SignedInt;
Int64Type = SignedLongLong;
FloatFormat = &llvm::APFloat::IEEEsingle;
DoubleFormat = &llvm::APFloat::IEEEdouble;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;

View File

@ -61,55 +61,24 @@ static void DefineStd(std::vector<char> &Buf, const char *MacroName,
//===----------------------------------------------------------------------===//
// Defines specific to certain operating systems.
//===----------------------------------------------------------------------===//
static void getSolarisDefines(const LangOptions &Opts, std::vector<char> &Defs) {
DefineStd(Defs, "sun", Opts);
DefineStd(Defs, "unix", Opts);
Define(Defs, "__ELF__");
Define(Defs, "__svr4__");
Define(Defs, "__SVR4");
}
static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
const char *Triple, std::vector<char> &Defs) {
// FreeBSD defines; list based off of gcc output
const char *FreeBSD = strstr(Triple, "-freebsd");
FreeBSD += strlen("-freebsd");
char release[] = "X";
release[0] = FreeBSD[0];
char version[] = "X00001";
version[0] = FreeBSD[0];
Define(Defs, "__FreeBSD__", release);
Define(Defs, "__FreeBSD_cc_version", version);
Define(Defs, "__KPRINTF_ATTRIBUTE__");
DefineStd(Defs, "unix", Opts);
Define(Defs, "__ELF__", "1");
if (is64Bit) {
Define(Defs, "__LP64__");
namespace {
template<typename TgtInfo>
class OSTargetInfo : public TgtInfo {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defines) const=0;
public:
OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
TgtInfo::getTargetDefines(Opts, Defines);
getOSDefines(Opts, TgtInfo::getTargetTriple(), Defines);
}
};
}
static void getDragonFlyDefines(const LangOptions &Opts,
std::vector<char> &Defs) {
// DragonFly defines; list based off of gcc output
Define(Defs, "__DragonFly__");
Define(Defs, "__DragonFly_cc_version", "100001");
Define(Defs, "__ELF__");
Define(Defs, "__KPRINTF_ATTRIBUTE__");
Define(Defs, "__tune_i386__");
DefineStd(Defs, "unix", Opts);
}
static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
// Linux defines; list based off of gcc output
DefineStd(Defs, "unix", Opts);
DefineStd(Defs, "linux", Opts);
Define(Defs, "__gnu_linux__");
Define(Defs, "__ELF__", "1");
}
namespace {
/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
/// not defined, return 0's. Return true if we have -darwin in the string or
@ -235,15 +204,160 @@ static void GetDarwinLanguageOptions(LangOptions &Opts,
if (!getDarwinNumber(Triple, Maj, Min, Rev))
return;
// Blocks default to on for 10.6 (darwin10) and beyond.
// As does nonfragile-abi for 64bit mode
if (Maj > 9)
// Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
if (Maj > 9) {
Opts.Blocks = 1;
Opts.setStackProtectorMode(LangOptions::SSPOn);
}
// Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
// beyond.
if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
Opts.ObjCNonFragileABI = 1;
}
template<typename Target>
class DarwinTargetInfo : public OSTargetInfo<Target> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defines) const {
getDarwinDefines(Defines, Opts);
getDarwinOSXDefines(Defines, Triple);
}
/// getDefaultLangOptions - Allow the target to specify default settings for
/// various language options. These may be overridden by command line
/// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {
TargetInfo::getDefaultLangOptions(Opts);
GetDarwinLanguageOptions(Opts, TargetInfo::getTargetTriple());
}
public:
DarwinTargetInfo(const std::string& triple) :
OSTargetInfo<Target>(triple) {
this->TLSSupported = false;
}
virtual const char *getCFStringSymbolPrefix() const {
return "\01L_unnamed_cfstring_";
}
virtual const char *getStringSymbolPrefix(bool IsConstant) const {
return IsConstant ? "\01LC" : "\01lC";
}
virtual const char *getUnicodeStringSymbolPrefix() const {
return "__utf16_string_";
}
virtual const char *getUnicodeStringSection() const {
return "__TEXT,__ustring";
}
};
// DragonFlyBSD Target
template<typename Target>
class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defs) const {
// DragonFly defines; list based off of gcc output
Define(Defs, "__DragonFly__");
Define(Defs, "__DragonFly_cc_version", "100001");
Define(Defs, "__ELF__");
Define(Defs, "__KPRINTF_ATTRIBUTE__");
Define(Defs, "__tune_i386__");
DefineStd(Defs, "unix", Opts);
}
public:
DragonFlyBSDTargetInfo(const std::string &triple)
: OSTargetInfo<Target>(triple) {}
};
// FreeBSD Target
template<typename Target>
class FreeBSDTargetInfo : public OSTargetInfo<Target> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defs) const {
// FreeBSD defines; list based off of gcc output
const char *FreeBSD = strstr(Triple, "-freebsd");
FreeBSD += strlen("-freebsd");
char release[] = "X";
release[0] = FreeBSD[0];
char version[] = "X00001";
version[0] = FreeBSD[0];
Define(Defs, "__FreeBSD__", release);
Define(Defs, "__FreeBSD_cc_version", version);
Define(Defs, "__KPRINTF_ATTRIBUTE__");
DefineStd(Defs, "unix", Opts);
Define(Defs, "__ELF__", "1");
}
public:
FreeBSDTargetInfo(const std::string &triple)
: OSTargetInfo<Target>(triple) {}
};
// Linux target
template<typename Target>
class LinuxTargetInfo : public OSTargetInfo<Target> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defs) const {
// Linux defines; list based off of gcc output
DefineStd(Defs, "unix", Opts);
DefineStd(Defs, "linux", Opts);
Define(Defs, "__gnu_linux__");
Define(Defs, "__ELF__", "1");
}
public:
LinuxTargetInfo(const std::string& triple)
: OSTargetInfo<Target>(triple) {
this->UserLabelPrefix = "";
}
};
// OpenBSD Target
template<typename Target>
class OpenBSDTargetInfo : public OSTargetInfo<Target> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defs) const {
// OpenBSD defines; list based off of gcc output
Define(Defs, "__OpenBSD__", "1");
DefineStd(Defs, "unix", Opts);
Define(Defs, "__ELF__", "1");
}
public:
OpenBSDTargetInfo(const std::string &triple)
: OSTargetInfo<Target>(triple) {}
};
// Solaris target
template<typename Target>
class SolarisTargetInfo : public OSTargetInfo<Target> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defs) const {
DefineStd(Defs, "sun", Opts);
DefineStd(Defs, "unix", Opts);
Define(Defs, "__ELF__");
Define(Defs, "__svr4__");
Define(Defs, "__SVR4");
}
public:
SolarisTargetInfo(const std::string& triple)
: OSTargetInfo<Target>(triple) {
this->UserLabelPrefix = "";
this->WCharType = this->SignedLong;
// FIXME: WIntType should be SignedLong
}
};
} // end anonymous namespace.
/// GetWindowsLanguageOptions - Set the default language options for Windows.
static void GetWindowsLanguageOptions(LangOptions &Opts,
const char *Triple) {
@ -435,55 +549,15 @@ class PPC64TargetInfo : public PPCTargetInfo {
public:
PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
Int64Type = SignedLong;
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v128:128:128";
}
};
} // end anonymous namespace.
namespace {
class DarwinPPCTargetInfo : public PPC32TargetInfo {
public:
DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
PPC32TargetInfo::getTargetDefines(Opts, Defines);
getDarwinDefines(Defines, Opts);
getDarwinOSXDefines(Defines, getTargetTriple());
}
/// getDefaultLangOptions - Allow the target to specify default settings for
/// various language options. These may be overridden by command line
/// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {
PPC32TargetInfo::getDefaultLangOptions(Opts);
GetDarwinLanguageOptions(Opts, getTargetTriple());
}
};
} // end anonymous namespace.
namespace {
class DarwinPPC64TargetInfo : public PPC64TargetInfo {
public:
DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
PPC64TargetInfo::getTargetDefines(Opts, Defines);
getDarwinDefines(Defines, Opts);
getDarwinOSXDefines(Defines, getTargetTriple());
}
/// getDefaultLangOptions - Allow the target to specify default settings for
/// various language options. These may be overridden by command line
/// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {
PPC64TargetInfo::getDefaultLangOptions(Opts);
GetDarwinLanguageOptions(Opts, getTargetTriple());
}
};
} // end anonymous namespace.
namespace {
// Namespace for x86 abstract base class
const Builtin::Info BuiltinInfo[] = {
@ -815,10 +889,10 @@ class X86_32TargetInfo : public X86TargetInfo {
} // end anonymous namespace
namespace {
// x86-32 Darwin (OS X) target
class DarwinI386TargetInfo : public X86_32TargetInfo {
class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
public:
DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
DarwinI386TargetInfo(const std::string& triple) :
DarwinTargetInfo<X86_32TargetInfo>(triple) {
LongDoubleWidth = 128;
LongDoubleAlign = 128;
SizeType = UnsignedLong;
@ -826,103 +900,11 @@ class DarwinI386TargetInfo : public X86_32TargetInfo {
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
"a0:0:64-f80:128:128";
TLSSupported = false;
}
virtual const char *getStringSymbolPrefix(bool IsConstant) const {
return IsConstant ? "\01LC" : "\01lC";
}
virtual const char *getUnicodeStringSymbolPrefix() const {
return "__utf16_string_";
}
virtual const char *getUnicodeStringSection() const {
return "__TEXT,__ustring";
}
virtual const char *getCFStringSymbolPrefix() const {
return "\01LC";
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_32TargetInfo::getTargetDefines(Opts, Defines);
getDarwinDefines(Defines, Opts);
getDarwinOSXDefines(Defines, getTargetTriple());
}
/// getDefaultLangOptions - Allow the target to specify default settings for
/// various language options. These may be overridden by command line
/// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {
X86_32TargetInfo::getDefaultLangOptions(Opts);
GetDarwinLanguageOptions(Opts, getTargetTriple());
}
};
} // end anonymous namespace
namespace {
// x86-32 FreeBSD target
class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
public:
FreeBSDX86_32TargetInfo(const std::string& triple) :
X86_32TargetInfo(triple) { }
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_32TargetInfo::getTargetDefines(Opts, Defines);
getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
}
};
} // end anonymous namespace
namespace {
// x86-32 DragonFly target
class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
public:
DragonFlyX86_32TargetInfo(const std::string& triple) :
X86_32TargetInfo(triple) { }
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_32TargetInfo::getTargetDefines(Opts, Defines);
getDragonFlyDefines(Opts, Defines);
}
};
} // end anonymous namespace
namespace {
// x86-32 Linux target
class LinuxX86_32TargetInfo : public X86_32TargetInfo {
public:
LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
UserLabelPrefix = "";
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_32TargetInfo::getTargetDefines(Opts, Defines);
getLinuxDefines(Opts, Defines);
}
};
} // end anonymous namespace
namespace {
// x86-32 Solaris target
class SolarisX86_32TargetInfo : public X86_32TargetInfo {
public:
SolarisX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
UserLabelPrefix = "";
WCharType = SignedLong;
// FIXME: WIntType should be SignedLong
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_32TargetInfo::getTargetDefines(Opts, Defines);
getSolarisDefines(Opts, Defines);
}
};
} // end anonymous namespace
namespace {
// x86-32 Windows target
class WindowsX86_32TargetInfo : public X86_32TargetInfo {
@ -961,11 +943,11 @@ class X86_64TargetInfo : public X86TargetInfo {
public:
X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
DoubleAlign = LongLongAlign = 64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
Int64Type = SignedLong;
RegParmMax = 6;
DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@ -978,95 +960,22 @@ class X86_64TargetInfo : public X86TargetInfo {
" unsigned fp_offset;"
" void* overflow_arg_area;"
" void* reg_save_area;"
"} __builtin_va_list[1];";
"} __va_list_tag;"
"typedef __va_list_tag __builtin_va_list[1];";
}
};
} // end anonymous namespace
namespace {
// x86-64 FreeBSD target
class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
public:
FreeBSDX86_64TargetInfo(const std::string &triple)
: X86_64TargetInfo(triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_64TargetInfo::getTargetDefines(Opts, Defines);
getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
DarwinX86_64TargetInfo(const std::string& triple)
: DarwinTargetInfo<X86_64TargetInfo>(triple) {
Int64Type = SignedLongLong;
}
};
} // end anonymous namespace
namespace {
// x86-64 Linux target
class LinuxX86_64TargetInfo : public X86_64TargetInfo {
public:
LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
UserLabelPrefix = "";
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_64TargetInfo::getTargetDefines(Opts, Defines);
getLinuxDefines(Opts, Defines);
}
};
} // end anonymous namespace
namespace {
// x86-64 Solaris target
class SolarisX86_64TargetInfo : public X86_64TargetInfo {
public:
SolarisX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
UserLabelPrefix = "";
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_64TargetInfo::getTargetDefines(Opts, Defines);
getSolarisDefines(Opts, Defines);
}
};
} // end anonymous namespace
namespace {
// x86-64 Darwin (OS X) target
class DarwinX86_64TargetInfo : public X86_64TargetInfo {
public:
DarwinX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
TLSSupported = false;
}
virtual const char *getStringSymbolPrefix(bool IsConstant) const {
return IsConstant ? "\01LC" : "\01lC";
}
virtual const char *getUnicodeStringSymbolPrefix() const {
return "__utf16_string_";
}
virtual const char *getUnicodeStringSection() const {
return "__TEXT,__ustring";
}
virtual const char *getCFStringSymbolPrefix() const {
return "\01L_unnamed_cfstring_";
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_64TargetInfo::getTargetDefines(Opts, Defines);
getDarwinDefines(Defines, Opts);
getDarwinOSXDefines(Defines, getTargetTriple());
}
/// getDefaultLangOptions - Allow the target to specify default settings for
/// various language options. These may be overridden by command line
/// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {
GetDarwinLanguageOptions(Opts, getTargetTriple());
}
};
} // end anonymous namespace.
namespace {
class ARMTargetInfo : public TargetInfo {
enum {
@ -1171,34 +1080,21 @@ class ARMTargetInfo : public TargetInfo {
namespace {
class DarwinARMTargetInfo : public ARMTargetInfo {
public:
DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {
TLSSupported = false;
class DarwinARMTargetInfo :
public DarwinTargetInfo<ARMTargetInfo> {
protected:
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
std::vector<char> &Defines) const {
getDarwinDefines(Defines, Opts);
getDarwinIPhoneOSDefines(Defines, Triple);
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
ARMTargetInfo::getTargetDefines(Opts, Defines);
getDarwinDefines(Defines, Opts);
getDarwinIPhoneOSDefines(Defines, getTargetTriple());
}
public:
DarwinARMTargetInfo(const std::string& triple)
: DarwinTargetInfo<ARMTargetInfo>(triple) {}
};
} // end anonymous namespace.
namespace {
// arm FreeBSD target
class FreeBSDARMTargetInfo : public ARMTargetInfo {
public:
FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
ARMTargetInfo::getTargetDefines(Opts, Defines);
getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
}
};
} // end anonymous namespace
namespace {
class SparcV8TargetInfo : public TargetInfo {
static const TargetInfo::GCCRegAlias GCCRegAliases[];
@ -1296,21 +1192,12 @@ void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
} // end anonymous namespace.
namespace {
class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
public:
SolarisSparcV8TargetInfo(const std::string& triple) :
SparcV8TargetInfo(triple) {
SolarisTargetInfo<SparcV8TargetInfo>(triple) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
WCharType = SignedLong;
// FIXME: WIntType should be SignedLong
UserLabelPrefix = "";
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
SparcV8TargetInfo::getTargetDefines(Opts, Defines);
getSolarisDefines(Opts, Defines);
}
};
} // end anonymous namespace.
@ -1454,6 +1341,7 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
// Additions and corrections are welcome.
bool isDarwin = T.find("-darwin") != std::string::npos;
bool isDragonFly = T.find("-dragonfly") != std::string::npos;
bool isOpenBSD = T.find("-openbsd") != std::string::npos;
bool isFreeBSD = T.find("-freebsd") != std::string::npos;
bool isSolaris = T.find("-solaris") != std::string::npos;
bool isLinux = T.find("-linux") != std::string::npos;
@ -1463,13 +1351,13 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
if (isDarwin)
return new DarwinPPCTargetInfo(T);
return new DarwinTargetInfo<PPCTargetInfo>(T);
return new PPC32TargetInfo(T);
}
if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
if (isDarwin)
return new DarwinPPC64TargetInfo(T);
return new DarwinTargetInfo<PPC64TargetInfo>(T);
return new PPC64TargetInfo(T);
}
@ -1477,7 +1365,7 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (isDarwin)
return new DarwinARMTargetInfo(T);
if (isFreeBSD)
return new FreeBSDARMTargetInfo(T);
return new FreeBSDTargetInfo<ARMTargetInfo>(T);
return new ARMTargetInfo(T);
}
@ -1491,11 +1379,13 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (isDarwin)
return new DarwinX86_64TargetInfo(T);
if (isLinux)
return new LinuxX86_64TargetInfo(T);
return new LinuxTargetInfo<X86_64TargetInfo>(T);
if (isOpenBSD)
return new OpenBSDTargetInfo<X86_64TargetInfo>(T);
if (isFreeBSD)
return new FreeBSDX86_64TargetInfo(T);
return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
if (isSolaris)
return new SolarisX86_64TargetInfo(T);
return new SolarisTargetInfo<X86_64TargetInfo>(T);
return new X86_64TargetInfo(T);
}
@ -1509,13 +1399,15 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (isDarwin)
return new DarwinI386TargetInfo(T);
if (isLinux)
return new LinuxX86_32TargetInfo(T);
return new LinuxTargetInfo<X86_32TargetInfo>(T);
if (isDragonFly)
return new DragonFlyX86_32TargetInfo(T);
return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
if (isOpenBSD)
return new OpenBSDTargetInfo<X86_32TargetInfo>(T);
if (isFreeBSD)
return new FreeBSDX86_32TargetInfo(T);
return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
if (isSolaris)
return new SolarisX86_32TargetInfo(T);
return new SolarisTargetInfo<X86_32TargetInfo>(T);
if (isWindows)
return new WindowsX86_32TargetInfo(T);
return new X86_32TargetInfo(T);

View File

@ -522,7 +522,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BIsqrtf:
case Builtin::BIsqrtl: {
// Rewrite sqrt to intrinsic if allowed.
if (!FD->hasAttr<ConstAttr>(getContext()))
if (!FD->hasAttr<ConstAttr>())
break;
Value *Arg0 = EmitScalarExpr(E->getArg(0));
const llvm::Type *ArgType = Arg0->getType();
@ -534,7 +534,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BIpowf:
case Builtin::BIpowl: {
// Rewrite sqrt to intrinsic if allowed.
if (!FD->hasAttr<ConstAttr>(getContext()))
if (!FD->hasAttr<ConstAttr>())
break;
Value *Base = EmitScalarExpr(E->getArg(0));
Value *Exponent = EmitScalarExpr(E->getArg(1));

View File

@ -323,8 +323,8 @@ static bool canGenerateCXXstructor(const CXXRecordDecl *RD,
if (RD->getNumBases() > 0)
return false;
for (CXXRecordDecl::field_iterator I = RD->field_begin(Context),
E = RD->field_end(Context); I != E; ++I) {
for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
I != E; ++I) {
// We don't support ctors for fields that aren't POD.
if (!I->getType()->isPODType())
return false;

View File

@ -142,8 +142,8 @@ void CodeGenTypes::GetExpandedTypes(QualType Ty,
assert(!RD->hasFlexibleArrayMember() &&
"Cannot expand structure with flexible array.");
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
const FieldDecl *FD = *i;
assert(!FD->isBitField() &&
"Cannot expand structure with bit-field members.");
@ -167,8 +167,8 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
assert(LV.isSimple() &&
"Unexpected non-simple lvalue during struct expansion.");
llvm::Value *Addr = LV.getAddress();
for (RecordDecl::field_iterator i = RD->field_begin(getContext()),
e = RD->field_end(getContext()); i != e; ++i) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
FieldDecl *FD = *i;
QualType FT = FD->getType();
@ -194,8 +194,8 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
RecordDecl *RD = RT->getDecl();
assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
llvm::Value *Addr = RV.getAggregateAddr();
for (RecordDecl::field_iterator i = RD->field_begin(getContext()),
e = RD->field_end(getContext()); i != e; ++i) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
FieldDecl *FD = *i;
QualType FT = FD->getType();
@ -377,13 +377,13 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
// FIXME: handle sseregparm someday...
if (TargetDecl) {
if (TargetDecl->hasAttr<NoThrowAttr>(getContext()))
if (TargetDecl->hasAttr<NoThrowAttr>())
FuncAttrs |= llvm::Attribute::NoUnwind;
if (TargetDecl->hasAttr<NoReturnAttr>(getContext()))
if (TargetDecl->hasAttr<NoReturnAttr>())
FuncAttrs |= llvm::Attribute::NoReturn;
if (TargetDecl->hasAttr<ConstAttr>(getContext()))
if (TargetDecl->hasAttr<ConstAttr>())
FuncAttrs |= llvm::Attribute::ReadNone;
else if (TargetDecl->hasAttr<PureAttr>(getContext()))
else if (TargetDecl->hasAttr<PureAttr>())
FuncAttrs |= llvm::Attribute::ReadOnly;
}
@ -392,6 +392,11 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
if (CompileOpts.NoImplicitFloat)
FuncAttrs |= llvm::Attribute::NoImplicitFloat;
if (Features.getStackProtectorMode() == LangOptions::SSPOn)
FuncAttrs |= llvm::Attribute::StackProtect;
else if (Features.getStackProtectorMode() == LangOptions::SSPReq)
FuncAttrs |= llvm::Attribute::StackProtectReq;
QualType RetTy = FI.getReturnType();
unsigned Index = 1;
const ABIArgInfo &RetAI = FI.getReturnInfo();
@ -433,7 +438,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
signed RegParm = 0;
if (TargetDecl)
if (const RegparmAttr *RegParmAttr
= TargetDecl->getAttr<RegparmAttr>(getContext()))
= TargetDecl->getAttr<RegparmAttr>())
RegParm = RegParmAttr->getNumParams();
unsigned PointerWidth = getContext().Target.getPointerWidth(0);

View File

@ -151,7 +151,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
uint64_t Offset = 0;
return DebugFactory.CreateBasicType(Unit,
BT->getName(M->getContext().getLangOptions().CPlusPlus),
BT->getName(M->getContext().getLangOptions()),
Unit, 0, Size, Align,
Offset, /*flags*/ 0, Encoding);
}
@ -437,8 +437,8 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(Decl);
unsigned FieldNo = 0;
for (RecordDecl::field_iterator I = Decl->field_begin(M->getContext()),
E = Decl->field_end(M->getContext());
for (RecordDecl::field_iterator I = Decl->field_begin(),
E = Decl->field_end();
I != E; ++I, ++FieldNo) {
FieldDecl *Field = *I;
llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
@ -638,8 +638,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
// Create DIEnumerator elements for each enumerator.
for (EnumDecl::enumerator_iterator
Enum = Decl->enumerator_begin(M->getContext()),
EnumEnd = Decl->enumerator_end(M->getContext());
Enum = Decl->enumerator_begin(), EnumEnd = Decl->enumerator_end();
Enum != EnumEnd; ++Enum) {
Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getNameAsString(),
Enum->getInitVal().getZExtValue()));

View File

@ -60,7 +60,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
/// EmitBlockVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
if (D.hasAttr<AsmLabelAttr>(getContext()))
if (D.hasAttr<AsmLabelAttr>())
CGM.ErrorUnsupported(&D, "__asm__");
switch (D.getStorageClass()) {
@ -171,7 +171,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
}
// FIXME: Merge attribute handling.
if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>(getContext())) {
if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
SourceManager &SM = CGM.getContext().getSourceManager();
llvm::Constant *Ann =
CGM.EmitAnnotateAttr(GV, AA,
@ -179,10 +179,10 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
CGM.AddAnnotation(Ann);
}
if (const SectionAttr *SA = D.getAttr<SectionAttr>(getContext()))
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
GV->setSection(SA->getName());
if (D.hasAttr<UsedAttr>(getContext()))
if (D.hasAttr<UsedAttr>())
CGM.AddUsedGlobal(GV);
// We may have to cast the constant because of the initializer
@ -244,7 +244,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(QualType Ty,
/// These turn into simple stack objects, or GlobalValues depending on target.
void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
QualType Ty = D.getType();
bool isByRef = D.hasAttr<BlocksAttr>(getContext());
bool isByRef = D.hasAttr<BlocksAttr>();
bool needsDispose = false;
unsigned Align = 0;
@ -414,7 +414,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
}
// Handle the cleanup attribute
if (const CleanupAttr *CA = D.getAttr<CleanupAttr>(getContext())) {
if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
const FunctionDecl *FD = CA->getFunctionDecl();
llvm::Constant* F = CGM.GetAddrOfFunction(GlobalDecl(FD));

View File

@ -670,7 +670,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
isa<ImplicitParamDecl>(VD))) {
LValue LV;
bool NonGCable = VD->hasLocalStorage() &&
!VD->hasAttr<BlocksAttr>(getContext());
!VD->hasAttr<BlocksAttr>();
if (VD->hasExternalStorage()) {
llvm::Value *V = CGM.GetAddrOfGlobalVar(VD);
if (VD->getType()->isReferenceType())
@ -686,7 +686,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// local static?
if (!NonGCable)
attr = getContext().getObjCGCAttrKind(E->getType());
if (VD->hasAttr<BlocksAttr>(getContext())) {
if (VD->hasAttr<BlocksAttr>()) {
bool needsCopyDispose = BlockRequiresCopying(VD->getType());
const llvm::Type *PtrStructTy = V->getType();
const llvm::Type *Ty = PtrStructTy;

View File

@ -436,8 +436,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
#ifndef NDEBUG
// Make sure that it's really an empty and not a failure of
// semantic analysis.
for (RecordDecl::field_iterator Field = SD->field_begin(CGF.getContext()),
FieldEnd = SD->field_end(CGF.getContext());
for (RecordDecl::field_iterator Field = SD->field_begin(),
FieldEnd = SD->field_end();
Field != FieldEnd; ++Field)
assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif
@ -461,8 +461,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// Here we iterate over the fields; this makes it simpler to both
// default-initialize fields and skip over unnamed fields.
for (RecordDecl::field_iterator Field = SD->field_begin(CGF.getContext()),
FieldEnd = SD->field_end(CGF.getContext());
for (RecordDecl::field_iterator Field = SD->field_begin(),
FieldEnd = SD->field_end();
Field != FieldEnd; ++Field) {
// We're done once we hit the flexible array member
if (Field->getType()->isIncompleteArrayType())

View File

@ -199,8 +199,8 @@ class VISIBILITY_HIDDEN ConstExprEmitter :
// Copy initializer elements. Skip padding fields.
unsigned EltNo = 0; // Element no in ILE
bool RewriteType = false;
for (RecordDecl::field_iterator Field = RD->field_begin(CGM.getContext()),
FieldEnd = RD->field_end(CGM.getContext());
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end();
EltNo < ILE->getNumInits() && Field != FieldEnd; ++Field) {
if (Field->isBitField()) {
if (!Field->getIdentifier())
@ -263,8 +263,8 @@ class VISIBILITY_HIDDEN ConstExprEmitter :
// Make sure that it's really an empty and not a failure of
// semantic analysis.
RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
for (RecordDecl::field_iterator Field = RD->field_begin(CGM.getContext()),
FieldEnd = RD->field_end(CGM.getContext());
for (RecordDecl::field_iterator Field = RD->field_begin(),
FieldEnd = RD->field_end();
Field != FieldEnd; ++Field)
assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif

View File

@ -126,11 +126,11 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
/// its pointer, name, and types registered in the class struture.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
// Check if we should generate debug info for this method.
if (CGM.getDebugInfo() && !OMD->hasAttr<NodebugAttr>(getContext()))
if (CGM.getDebugInfo() && !OMD->hasAttr<NodebugAttr>())
DebugInfo = CGM.getDebugInfo();
StartObjCMethod(OMD, OMD->getClassInterface());
EmitStmt(OMD->getBody(getContext()));
FinishFunction(OMD->getBodyRBrace(getContext()));
EmitStmt(OMD->getBody());
FinishFunction(OMD->getBodyRBrace());
}
// FIXME: I wasn't sure about the synthesis approach. If we end up generating an

View File

@ -180,7 +180,7 @@ void CGObjCGNU::EmitClassRef(const std::string &className){
std::string symbolName = "__objc_class_name_" + className;
llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
if (!ClassSymbol) {
ClassSymbol = new llvm::GlobalVariable(LongTy, false,
ClassSymbol = new llvm::GlobalVariable(LongTy, false,
llvm::GlobalValue::ExternalLinkage, 0, symbolName, &TheModule);
}
new llvm::GlobalVariable(ClassSymbol->getType(), true,
@ -739,8 +739,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
Protocols.push_back((*PI)->getNameAsString());
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(Context),
E = PD->instmeth_end(Context); iter != E; iter++) {
for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
E = PD->instmeth_end(); iter != E; iter++) {
std::string TypeStr;
Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
InstanceMethodNames.push_back(
@ -751,8 +751,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCProtocolDecl::classmeth_iterator
iter = PD->classmeth_begin(Context),
endIter = PD->classmeth_end(Context) ; iter != endIter ; iter++) {
iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
iter != endIter ; iter++) {
std::string TypeStr;
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
ClassMethodNames.push_back(
@ -794,8 +794,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCCategoryImplDecl::instmeth_iterator
iter = OCD->instmeth_begin(CGM.getContext()),
endIter = OCD->instmeth_end(CGM.getContext());
iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@ -807,8 +806,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCCategoryImplDecl::classmeth_iterator
iter = OCD->classmeth_begin(CGM.getContext()),
endIter = OCD->classmeth_end(CGM.getContext());
iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@ -861,9 +859,14 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
std::string ClassName = ClassDecl->getNameAsString();
// Emit the symbol that is used to generate linker errors if this class is
// referenced in other modules but not declared.
new llvm::GlobalVariable(LongTy, false, llvm::GlobalValue::ExternalLinkage,
llvm::ConstantInt::get(LongTy, 0), "__objc_class_name_" + ClassName,
&TheModule);
std::string classSymbolName = "__objc_class_name_" + ClassName;
if (llvm::GlobalVariable *symbol =
TheModule.getGlobalVariable(classSymbolName)) {
symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
} else {
new llvm::GlobalVariable(LongTy, false, llvm::GlobalValue::ExternalLinkage,
llvm::ConstantInt::get(LongTy, 0), classSymbolName, &TheModule);
}
// Get the size of instances.
int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
@ -906,8 +909,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCImplementationDecl::instmeth_iterator
iter = OID->instmeth_begin(CGM.getContext()),
endIter = OID->instmeth_end(CGM.getContext());
iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@ -915,8 +917,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
}
for (ObjCImplDecl::propimpl_iterator
iter = OID->propimpl_begin(CGM.getContext()),
endIter = OID->propimpl_end(CGM.getContext());
iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
iter != endIter ; iter++) {
ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
@ -937,8 +938,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCImplementationDecl::classmeth_iterator
iter = OID->classmeth_begin(CGM.getContext()),
endIter = OID->classmeth_end(CGM.getContext());
iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@ -1163,9 +1163,8 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
// Create the load function calling the runtime entry point with the module
// structure
std::vector<const llvm::Type*> VoidArgs;
llvm::Function * LoadFunction = llvm::Function::Create(
llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false),
llvm::FunctionType::get(llvm::Type::VoidTy, false),
llvm::GlobalValue::InternalLinkage, ".objc_load_function",
&TheModule);
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction);
@ -1250,7 +1249,7 @@ void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// Pointer to the personality function
llvm::Constant *Personality =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
std::vector<const llvm::Type*>(), true),
true),
"__gnu_objc_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy);
std::vector<const llvm::Type*> Params;

View File

@ -690,7 +690,6 @@ class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
llvm::Value *getEHPersonalityPtr() {
llvm::Constant *Personality =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
std::vector<const llvm::Type*>(),
true),
"__objc_personality_v0");
return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy);
@ -705,9 +704,8 @@ class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
}
llvm::Constant *getObjCEndCatchFn() {
std::vector<const llvm::Type*> Params;
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
Params, false),
false),
"objc_end_catch");
}
@ -1360,7 +1358,7 @@ static llvm::Constant *getConstantGEP(llvm::Constant *C,
/// class has the __objc_exception__ attribute.
static bool hasObjCExceptionAttribute(ASTContext &Context,
const ObjCInterfaceDecl *OID) {
if (OID->hasAttr<ObjCExceptionAttr>(Context))
if (OID->hasAttr<ObjCExceptionAttr>())
return true;
if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
return hasObjCExceptionAttribute(Context, Super);
@ -1585,8 +1583,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
for (ObjCProtocolDecl::instmeth_iterator
i = PD->instmeth_begin(CGM.getContext()),
e = PD->instmeth_end(CGM.getContext()); i != e; ++i) {
i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
@ -1597,8 +1594,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
}
for (ObjCProtocolDecl::classmeth_iterator
i = PD->classmeth_begin(CGM.getContext()),
e = PD->classmeth_end(CGM.getContext()); i != e; ++i) {
i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
@ -1772,8 +1768,8 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(const std::string &Name,
const ObjCContainerDecl *OCD,
const ObjCCommonTypesHelper &ObjCTypes) {
std::vector<llvm::Constant*> Properties, Prop(2);
for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(CGM.getContext()),
E = OCD->prop_end(CGM.getContext()); I != E; ++I) {
for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
E = OCD->prop_end(); I != E; ++I) {
const ObjCPropertyDecl *PD = *I;
Prop[0] = GetPropertyName(PD->getIdentifier());
Prop[1] = GetPropertyTypeString(PD, Container);
@ -1865,14 +1861,12 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
for (ObjCCategoryImplDecl::instmeth_iterator
i = OCD->instmeth_begin(CGM.getContext()),
e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
for (ObjCCategoryImplDecl::classmeth_iterator
i = OCD->classmeth_begin(CGM.getContext()),
e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
@ -1969,21 +1963,18 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
for (ObjCImplementationDecl::instmeth_iterator
i = ID->instmeth_begin(CGM.getContext()),
e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::classmeth_iterator
i = ID->classmeth_begin(CGM.getContext()),
e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::propimpl_iterator
i = ID->propimpl_begin(CGM.getContext()),
e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
@ -2983,8 +2974,7 @@ void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
bool &HasUnion) {
const RecordDecl *RD = RT->getDecl();
// FIXME - Use iterator.
llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(CGM.getContext()),
RD->field_end(CGM.getContext()));
llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
const llvm::StructLayout *RecLayout =
CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
@ -3528,9 +3518,9 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
SourceLocation(),
&Ctx.Idents.get("_objc_super"));
RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.getObjCIdType(), 0, false));
RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.getObjCClassType(), 0, false));
RD->completeDefinition(Ctx);
@ -3987,9 +3977,9 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
SourceLocation(),
&Ctx.Idents.get("_message_ref_t"));
RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.VoidPtrTy, 0, false));
RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.getObjCSelType(), 0, false));
RD->completeDefinition(Ctx);
@ -4190,22 +4180,19 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
if (flags & CLS_META) {
MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
for (ObjCImplementationDecl::classmeth_iterator
i = ID->classmeth_begin(CGM.getContext()),
e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
} else {
MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
for (ObjCImplementationDecl::instmeth_iterator
i = ID->instmeth_begin(CGM.getContext()),
e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::propimpl_iterator
i = ID->propimpl_begin(CGM.getContext()),
e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
@ -4298,7 +4285,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
bool
CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
return OD->getClassMethod(CGM.getContext(), GetNullarySelector("load")) != 0;
return OD->getClassMethod(GetNullarySelector("load")) != 0;
}
void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
@ -4478,8 +4465,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
"_$_" + OCD->getNameAsString();
for (ObjCCategoryImplDecl::instmeth_iterator
i = OCD->instmeth_begin(CGM.getContext()),
e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
@ -4493,8 +4479,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
OCD->getNameAsString();
Methods.clear();
for (ObjCCategoryImplDecl::classmeth_iterator
i = OCD->classmeth_begin(CGM.getContext()),
e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
@ -4782,9 +4767,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
for (ObjCProtocolDecl::instmeth_iterator
i = PD->instmeth_begin(CGM.getContext()),
e = PD->instmeth_end(CGM.getContext());
i != e; ++i) {
i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
@ -4795,9 +4778,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
}
for (ObjCProtocolDecl::classmeth_iterator
i = PD->classmeth_begin(CGM.getContext()),
e = PD->classmeth_end(CGM.getContext());
i != e; ++i) {
i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {

View File

@ -199,7 +199,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy,
void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
llvm::Function *Fn) {
// Check if we should generate debug info for this function.
if (CGM.getDebugInfo() && !FD->hasAttr<NodebugAttr>(getContext()))
if (CGM.getDebugInfo() && !FD->hasAttr<NodebugAttr>())
DebugInfo = CGM.getDebugInfo();
FunctionArgList Args;
@ -226,7 +226,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
}
// FIXME: Support CXXTryStmt here, too.
if (const CompoundStmt *S = FD->getCompoundBody(getContext())) {
if (const CompoundStmt *S = FD->getCompoundBody()) {
StartFunction(FD, FD->getResultType(), Fn, Args, S->getLBracLoc());
EmitStmt(S);
FinishFunction(S->getRBracLoc());

View File

@ -102,7 +102,7 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
if (VD->getStorageClass() == VarDecl::PrivateExtern)
return LangOptions::Hidden;
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>(getContext())) {
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
switch (attr->getVisibility()) {
default: assert(0 && "Unknown visibility!");
case VisibilityAttr::DefaultVisibility:
@ -243,12 +243,20 @@ void CodeGenModule::EmitAnnotations() {
static CodeGenModule::GVALinkage
GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
const LangOptions &Features) {
// The kind of external linkage this function will have, if it is not
// inline or static.
CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal;
if (Context.getLangOptions().CPlusPlus &&
(FD->getPrimaryTemplate() || FD->getInstantiatedFromMemberFunction()) &&
!FD->isExplicitSpecialization())
External = CodeGenModule::GVA_TemplateInstantiation;
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
// C++ member functions defined inside the class are always inline.
if (MD->isInline() || !MD->isOutOfLine())
return CodeGenModule::GVA_CXXInline;
return CodeGenModule::GVA_StrongExternal;
return External;
}
// "static" functions get internal linkage.
@ -256,7 +264,7 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
return CodeGenModule::GVA_Internal;
if (!FD->isInline())
return CodeGenModule::GVA_StrongExternal;
return External;
// If the inline function explicitly has the GNU inline attribute on it, or if
// this is C89 mode, we use to GNU semantics.
@ -273,7 +281,7 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
if (FD->isExternGNUInline(Context))
return CodeGenModule::GVA_C99Inline;
// Normal inline is a strong symbol.
return CodeGenModule::GVA_StrongExternal;
return External;
}
// The definition of inline changes based on the language. Note that we
@ -298,15 +306,15 @@ void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
if (Linkage == GVA_Internal) {
GV->setLinkage(llvm::Function::InternalLinkage);
} else if (D->hasAttr<DLLExportAttr>(getContext())) {
} else if (D->hasAttr<DLLExportAttr>()) {
GV->setLinkage(llvm::Function::DLLExportLinkage);
} else if (D->hasAttr<WeakAttr>(getContext())) {
} else if (D->hasAttr<WeakAttr>()) {
GV->setLinkage(llvm::Function::WeakAnyLinkage);
} else if (Linkage == GVA_C99Inline) {
// In C99 mode, 'inline' functions are guaranteed to have a strong
// definition somewhere else, so we can use available_externally linkage.
GV->setLinkage(llvm::Function::AvailableExternallyLinkage);
} else if (Linkage == GVA_CXXInline) {
} else if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) {
// In C++, the compiler has to emit a definition in every translation unit
// that references the function. We should use linkonce_odr because
// a) if all references in this translation unit are optimized away, we
@ -333,10 +341,10 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
AttributeList.size()));
// Set the appropriate calling convention for the Function.
if (D->hasAttr<FastCallAttr>(getContext()))
if (D->hasAttr<FastCallAttr>())
F->setCallingConv(llvm::CallingConv::X86_FastCall);
if (D->hasAttr<StdCallAttr>(getContext()))
if (D->hasAttr<StdCallAttr>())
F->setCallingConv(llvm::CallingConv::X86_StdCall);
}
@ -345,10 +353,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
if (!Features.Exceptions && !Features.ObjCNonFragileABI)
F->addFnAttr(llvm::Attribute::NoUnwind);
if (D->hasAttr<AlwaysInlineAttr>(getContext()))
if (D->hasAttr<AlwaysInlineAttr>())
F->addFnAttr(llvm::Attribute::AlwaysInline);
if (D->hasAttr<NoinlineAttr>(getContext()))
if (D->hasAttr<NoinlineAttr>())
F->addFnAttr(llvm::Attribute::NoInline);
}
@ -356,10 +364,10 @@ void CodeGenModule::SetCommonAttributes(const Decl *D,
llvm::GlobalValue *GV) {
setGlobalVisibility(GV, D);
if (D->hasAttr<UsedAttr>(getContext()))
if (D->hasAttr<UsedAttr>())
AddUsedGlobal(GV);
if (const SectionAttr *SA = D->getAttr<SectionAttr>(getContext()))
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
GV->setSection(SA->getName());
}
@ -383,10 +391,10 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
// Only a few attributes are set on declarations; these may later be
// overridden by a definition.
if (FD->hasAttr<DLLImportAttr>(getContext())) {
if (FD->hasAttr<DLLImportAttr>()) {
F->setLinkage(llvm::Function::DLLImportLinkage);
} else if (FD->hasAttr<WeakAttr>(getContext()) ||
FD->hasAttr<WeakImportAttr>(getContext())) {
} else if (FD->hasAttr<WeakAttr>() ||
FD->hasAttr<WeakImportAttr>()) {
// "extern_weak" is overloaded in LLVM; we probably should have
// separate linkage types for this.
F->setLinkage(llvm::Function::ExternalWeakLinkage);
@ -394,7 +402,7 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
F->setLinkage(llvm::Function::ExternalLinkage);
}
if (const SectionAttr *SA = FD->getAttr<SectionAttr>(getContext()))
if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
F->setSection(SA->getName());
}
@ -508,13 +516,13 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
// Never defer when EmitAllDecls is specified or the decl has
// attribute used.
if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>(getContext()))
if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>())
return false;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
// Constructors and destructors should never be deferred.
if (FD->hasAttr<ConstructorAttr>(getContext()) ||
FD->hasAttr<DestructorAttr>(getContext()))
if (FD->hasAttr<ConstructorAttr>() ||
FD->hasAttr<DestructorAttr>())
return false;
GVALinkage Linkage = GetLinkageForFunction(getContext(), FD, Features);
@ -538,7 +546,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// If this is an alias definition (which otherwise looks like a declaration)
// emit it now.
if (Global->hasAttr<AliasAttr>(getContext()))
if (Global->hasAttr<AliasAttr>())
return EmitAliasDefinition(Global);
// Ignore declarations, they will be emitted on their first use.
@ -727,8 +735,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
if (D->getStorageClass() == VarDecl::PrivateExtern)
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
if (D->hasAttr<WeakAttr>(getContext()) ||
D->hasAttr<WeakImportAttr>(getContext()))
if (D->hasAttr<WeakAttr>() ||
D->hasAttr<WeakImportAttr>())
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
GV->setThreadLocal(D->isThreadSpecified());
@ -848,7 +856,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
cast<llvm::GlobalValue>(Entry)->eraseFromParent();
}
if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>(getContext())) {
if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
SourceManager &SM = Context.getSourceManager();
AddAnnotation(EmitAnnotateAttr(GV, AA,
SM.getInstantiationLineNumber(D->getLocation())));
@ -861,11 +869,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// Set the llvm linkage type as appropriate.
if (D->getStorageClass() == VarDecl::Static)
GV->setLinkage(llvm::Function::InternalLinkage);
else if (D->hasAttr<DLLImportAttr>(getContext()))
else if (D->hasAttr<DLLImportAttr>())
GV->setLinkage(llvm::Function::DLLImportLinkage);
else if (D->hasAttr<DLLExportAttr>(getContext()))
else if (D->hasAttr<DLLExportAttr>())
GV->setLinkage(llvm::Function::DLLExportLinkage);
else if (D->hasAttr<WeakAttr>(getContext()))
else if (D->hasAttr<WeakAttr>())
GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
else if (!CompileOpts.NoCommon &&
(!D->hasExternalStorage() && !D->getInit()))
@ -1028,14 +1036,14 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
SetFunctionDefinitionAttributes(D, Fn);
SetLLVMFunctionAttributesForDefinition(D, Fn);
if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>(getContext()))
if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
AddGlobalCtor(Fn, CA->getPriority());
if (const DestructorAttr *DA = D->getAttr<DestructorAttr>(getContext()))
if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
AddGlobalDtor(Fn, DA->getPriority());
}
void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
const AliasAttr *AA = D->getAttr<AliasAttr>(getContext());
const AliasAttr *AA = D->getAttr<AliasAttr>();
assert(AA && "Not an alias?");
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
@ -1091,16 +1099,16 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
// Set attributes which are particular to an alias; this is a
// specialization of the attributes which may be set on a global
// variable/function.
if (D->hasAttr<DLLExportAttr>(getContext())) {
if (D->hasAttr<DLLExportAttr>()) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// The dllexport attribute is ignored for undefined symbols.
if (FD->getBody(getContext()))
if (FD->getBody())
GA->setLinkage(llvm::Function::DLLExportLinkage);
} else {
GA->setLinkage(llvm::Function::DLLExportLinkage);
}
} else if (D->hasAttr<WeakAttr>(getContext()) ||
D->hasAttr<WeakImportAttr>(getContext())) {
} else if (D->hasAttr<WeakAttr>() ||
D->hasAttr<WeakImportAttr>()) {
GA->setLinkage(llvm::Function::WeakAnyLinkage);
}
@ -1254,7 +1262,7 @@ GetAddrOfConstantCFString(const StringLiteral *Literal) {
cast<llvm::StructType>(getTypes().ConvertType(CFTy));
std::vector<llvm::Constant*> Fields;
RecordDecl::field_iterator Field = CFRD->field_begin(getContext());
RecordDecl::field_iterator Field = CFRD->field_begin();
// Class pointer.
FieldDecl *CurField = *Field++;
@ -1424,8 +1432,7 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str,
void CodeGenModule::EmitObjCPropertyImplementations(const
ObjCImplementationDecl *D) {
for (ObjCImplementationDecl::propimpl_iterator
i = D->propimpl_begin(getContext()),
e = D->propimpl_end(getContext()); i != e; ++i) {
i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
// Dynamic is just for type-checking.
@ -1437,11 +1444,11 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
// we want, that just indicates if the decl came from a
// property. What we want to know is if the method is defined in
// this implementation.
if (!D->getInstanceMethod(getContext(), PD->getGetterName()))
if (!D->getInstanceMethod(PD->getGetterName()))
CodeGenFunction(*this).GenerateObjCGetter(
const_cast<ObjCImplementationDecl *>(D), PID);
if (!PD->isReadOnly() &&
!D->getInstanceMethod(getContext(), PD->getSetterName()))
!D->getInstanceMethod(PD->getSetterName()))
CodeGenFunction(*this).GenerateObjCSetter(
const_cast<ObjCImplementationDecl *>(D), PID);
}
@ -1450,8 +1457,7 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
/// EmitNamespace - Emit all declarations in a namespace.
void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
for (RecordDecl::decl_iterator I = ND->decls_begin(getContext()),
E = ND->decls_end(getContext());
for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end();
I != E; ++I)
EmitTopLevelDecl(*I);
}
@ -1463,8 +1469,7 @@ void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {
return;
}
for (RecordDecl::decl_iterator I = LSD->decls_begin(getContext()),
E = LSD->decls_end(getContext());
for (RecordDecl::decl_iterator I = LSD->decls_begin(), E = LSD->decls_end();
I != E; ++I)
EmitTopLevelDecl(*I);
}
@ -1477,9 +1482,19 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
if (Diags.hasErrorOccurred())
return;
// Ignore dependent declarations.
if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
return;
switch (D->getKind()) {
case Decl::CXXMethod:
case Decl::Function:
// Skip function templates
if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate())
return;
// Fall through
case Decl::Var:
EmitGlobal(GlobalDecl(cast<ValueDecl>(D)));
break;
@ -1490,6 +1505,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
// No code generation needed.
case Decl::Using:
case Decl::ClassTemplate:
case Decl::FunctionTemplate:
break;
case Decl::CXXConstructor:
EmitCXXConstructors(cast<CXXConstructorDecl>(D));
@ -1530,7 +1547,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::ObjCMethod: {
ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
// If this is not a prototype, emit the body.
if (OMD->getBody(getContext()))
if (OMD->getBody())
CodeGenFunction(*this).GenerateObjCMethod(OMD);
break;
}

View File

@ -373,7 +373,8 @@ class CodeGenModule : public BlockModule {
GVA_Internal,
GVA_C99Inline,
GVA_CXXInline,
GVA_StrongExternal
GVA_StrongExternal,
GVA_TemplateInstantiation
};
private:

View File

@ -449,7 +449,7 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
const RecordDecl *RD = cast<const RecordDecl>(TD);
// There isn't any extra information for empty structures/unions.
if (RD->field_empty(getContext())) {
if (RD->field_empty()) {
ResultType = llvm::StructType::get(std::vector<const llvm::Type*>());
} else {
// Layout fields.
@ -532,8 +532,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
std::vector<const llvm::Type*> LLVMFields;
unsigned curField = 0;
for (RecordDecl::field_iterator Field = RD.field_begin(CGT.getContext()),
FieldEnd = RD.field_end(CGT.getContext());
for (RecordDecl::field_iterator Field = RD.field_begin(),
FieldEnd = RD.field_end();
Field != FieldEnd; ++Field) {
uint64_t offset = RL.getFieldOffset(curField);
const llvm::Type *Ty = CGT.ConvertTypeForMemRecursive(Field->getType());
@ -578,8 +578,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
/// all fields are added.
void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
unsigned curField = 0;
for (RecordDecl::field_iterator Field = RD.field_begin(CGT.getContext()),
FieldEnd = RD.field_end(CGT.getContext());
for (RecordDecl::field_iterator Field = RD.field_begin(),
FieldEnd = RD.field_end();
Field != FieldEnd; ++Field) {
// The offset should usually be zero, but bitfields could be strange
uint64_t offset = RL.getFieldOffset(curField);

View File

@ -87,7 +87,7 @@ static bool isInCLinkageSpecification(const Decl *D) {
bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
// Clang's "overloadable" attribute extension to C/C++ implies
// name mangling (always).
if (!FD->hasAttr<OverloadableAttr>(Context)) {
if (!FD->hasAttr<OverloadableAttr>()) {
// C functions are not mangled, and "main" is never mangled.
if (!Context.getLangOptions().CPlusPlus || FD->isMain())
return false;
@ -111,7 +111,7 @@ bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
bool CXXNameMangler::mangle(const NamedDecl *D) {
// Any decl can be declared with __asm("foo") on it, and this takes
// precedence over all other naming in the .o file.
if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>(Context)) {
if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
// If we have an asm name, then we use it as the mangling.
Out << '\01'; // LLVM IR Marker for __asm("foo")
Out << ALA->getLabel();
@ -170,7 +170,29 @@ void CXXNameMangler::mangleGuardVariable(const VarDecl *D)
void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
// <encoding> ::= <function name> <bare-function-type>
mangleName(FD);
mangleBareFunctionType(FD->getType()->getAsFunctionType(), false);
// Whether the mangling of a function type includes the return type depends
// on the context and the nature of the function. The rules for deciding
// whether the return type is included are:
//
// 1. Template functions (names or types) have return types encoded, with
// the exceptions listed below.
// 2. Function types not appearing as part of a function name mangling,
// e.g. parameters, pointer types, etc., have return type encoded, with the
// exceptions listed below.
// 3. Non-template function names do not have return types encoded.
//
// The exceptions mentioned in (1) and (2) above, for which the return
// type is never included, are
// 1. Constructors.
// 2. Destructors.
// 3. Conversion operator functions, e.g. operator int.
bool MangleReturnType = false;
if (FD->getPrimaryTemplate() &&
!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
isa<CXXConversionDecl>(FD)))
MangleReturnType = true;
mangleBareFunctionType(FD->getType()->getAsFunctionType(), MangleReturnType);
}
static bool isStdNamespace(const DeclContext *DC) {
@ -253,6 +275,12 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
assert(false && "Can't mangle a using directive name!");
break;
}
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
if (const TemplateArgumentList *TemplateArgs
= Function->getTemplateSpecializationArgs())
mangleTemplateArgumentList(*TemplateArgs);
}
}
void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {

View File

@ -19,6 +19,7 @@
#include "clang/AST/Expr.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/Compiler.h"
@ -37,8 +38,8 @@ namespace {
llvm::OwningPtr<CodeGen::CodeGenModule> Builder;
public:
CodeGeneratorImpl(Diagnostic &diags, const std::string& ModuleName,
const CompileOptions &CO)
: Diags(diags), CompileOpts(CO), M(new llvm::Module(ModuleName)) {}
const CompileOptions &CO, llvm::LLVMContext& C)
: Diags(diags), CompileOpts(CO), M(new llvm::Module(ModuleName, C)) {}
virtual ~CodeGeneratorImpl() {}
@ -95,6 +96,7 @@ namespace {
CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags,
const std::string& ModuleName,
const CompileOptions &CO) {
return new CodeGeneratorImpl(Diags, ModuleName, CO);
const CompileOptions &CO,
llvm::LLVMContext& C) {
return new CodeGeneratorImpl(Diags, ModuleName, CO, C);
}

View File

@ -74,8 +74,8 @@ static bool isEmptyRecord(ASTContext &Context, QualType T) {
const RecordDecl *RD = RT->getDecl();
if (RD->hasFlexibleArrayMember())
return false;
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i)
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i)
if (!isEmptyField(Context, *i))
return false;
return true;
@ -99,8 +99,8 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) {
return 0;
const Type *Found = 0;
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
const FieldDecl *FD = *i;
QualType FT = FD->getType();
@ -142,8 +142,8 @@ static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) {
static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
ASTContext &Context) {
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
const FieldDecl *FD = *i;
if (!is32Or64BitBasicType(FD->getType(), Context))
@ -160,8 +160,8 @@ static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
}
static bool typeContainsSSEVector(const RecordDecl *RD, ASTContext &Context) {
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
const FieldDecl *FD = *i;
if (FD->getType()->isVectorType() &&
@ -269,8 +269,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
// Structure types are passed in register if all fields would be
// passed in a register.
for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(Context),
e = RT->getDecl()->field_end(Context); i != e; ++i) {
for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
e = RT->getDecl()->field_end(); i != e; ++i) {
const FieldDecl *FD = *i;
// Empty fields are ignored.
@ -707,8 +707,8 @@ void X86_64ABIInfo::classify(QualType Ty,
// Reset Lo class, this will be recomputed.
Current = NoClass;
unsigned idx = 0;
for (RecordDecl::field_iterator i = RD->field_begin(Context),
e = RD->field_end(Context); i != e; ++i, ++idx) {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i, ++idx) {
uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
bool BitField = i->isBitField();

View File

@ -49,6 +49,35 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
return Res;
}
Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
bool Claim) const {
Arg *Res = 0;
Arg *A0 = getLastArg(Id0, false);
Arg *A1 = getLastArg(Id1, false);
Arg *A2 = getLastArg(Id2, false);
int A0Idx = A0 ? A0->getIndex() : -1;
int A1Idx = A1 ? A1->getIndex() : -1;
int A2Idx = A2 ? A2->getIndex() : -1;
if (A0Idx > A1Idx) {
if (A0Idx > A2Idx)
Res = A0;
else if (A2Idx != -1)
Res = A2;
} else {
if (A1Idx > A2Idx)
Res = A1;
else if (A2Idx != -1)
Res = A2;
}
if (Claim && Res)
Res->claim();
return Res;
}
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);

View File

@ -21,8 +21,8 @@
#include <errno.h>
using namespace clang::driver;
Compilation::Compilation(Driver &D,
ToolChain &_DefaultToolChain,
Compilation::Compilation(const Driver &D,
const ToolChain &_DefaultToolChain,
InputArgList *_Args)
: TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
}
@ -105,7 +105,8 @@ bool Compilation::CleanupFileList(const ArgStringList &Files,
return Success;
}
int Compilation::ExecuteCommand(const Command &C) const {
int Compilation::ExecuteCommand(const Command &C,
const Command *&FailingCommand) const {
llvm::sys::Path Prog(C.getExecutable());
const char **Argv = new const char*[C.getArguments().size() + 2];
Argv[0] = C.getExecutable();
@ -126,49 +127,31 @@ int Compilation::ExecuteCommand(const Command &C) const {
getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
}
if (Res)
FailingCommand = &C;
delete[] Argv;
return Res;
}
int Compilation::ExecuteJob(const Job &J) const {
int Compilation::ExecuteJob(const Job &J,
const Command *&FailingCommand) const {
if (const Command *C = dyn_cast<Command>(&J)) {
return ExecuteCommand(*C);
return ExecuteCommand(*C, FailingCommand);
} else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
// Piped commands with a single job are easy.
if (PJ->size() == 1)
return ExecuteCommand(**PJ->begin());
return ExecuteCommand(**PJ->begin(), FailingCommand);
FailingCommand = *PJ->begin();
getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe";
return 1;
} else {
const JobList *Jobs = cast<JobList>(&J);
for (JobList::const_iterator
it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
if (int Res = ExecuteJob(**it))
if (int Res = ExecuteJob(**it, FailingCommand))
return Res;
return 0;
}
}
int Compilation::Execute() const {
// Just print if -### was present.
if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
PrintJob(llvm::errs(), Jobs, "\n", true);
return 0;
}
// If there were errors building the compilation, quit now.
if (getDriver().getDiags().getNumErrors())
return 1;
int Res = ExecuteJob(Jobs);
// Remove temp files.
CleanupFileList(TempFiles);
// If the compilation failed, remove result files as well.
if (Res != 0 && !getArgs().hasArg(options::OPT_save_temps))
CleanupFileList(ResultFiles, true);
return Res;
}

View File

@ -217,6 +217,54 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
return C;
}
int Driver::ExecuteCompilation(const Compilation &C) const {
// Just print if -### was present.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
return 0;
}
// If there were errors building the compilation, quit now.
if (getDiags().getNumErrors())
return 1;
const Command *FailingCommand = 0;
int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
// Remove temp files.
C.CleanupFileList(C.getTempFiles());
// If the compilation failed, remove result files as well.
if (Res != 0 && !C.getArgs().hasArg(options::OPT_save_temps))
C.CleanupFileList(C.getResultFiles(), true);
// Print extra information about abnormal failures, if possible.
if (Res) {
// This is ad-hoc, but we don't want to be excessively noisy. If the result
// status was 1, assume the command failed normally. In particular, if it
// was the compiler then assume it gave a reasonable error code. Failures in
// other tools are less common, and they generally have worse diagnostics,
// so always print the diagnostic there.
const Action &Source = FailingCommand->getSource();
bool IsFriendlyTool = (isa<PreprocessJobAction>(Source) ||
isa<PrecompileJobAction>(Source) ||
isa<AnalyzeJobAction>(Source) ||
isa<CompileJobAction>(Source));
if (!IsFriendlyTool || Res != 1) {
// FIXME: See FIXME above regarding result code interpretation.
if (Res < 0)
Diag(clang::diag::err_drv_command_signalled)
<< Source.getClassName() << -Res;
else
Diag(clang::diag::err_drv_command_failed)
<< Source.getClassName() << Res;
}
}
return Res;
}
void Driver::PrintOptions(const ArgList &Args) const {
unsigned i = 0;
for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
@ -1205,6 +1253,8 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
return createDarwinHostInfo(*this, Triple);
case llvm::Triple::DragonFly:
return createDragonFlyHostInfo(*this, Triple);
case llvm::Triple::OpenBSD:
return createOpenBSDHostInfo(*this, Triple);
case llvm::Triple::FreeBSD:
return createFreeBSDHostInfo(*this, Triple);
case llvm::Triple::Linux:

View File

@ -234,6 +234,57 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
return TC;
}
// OpenBSD Host Info
/// OpenBSDHostInfo - OpenBSD host information implementation.
class OpenBSDHostInfo : public HostInfo {
/// Cache of tool chains we have created.
mutable llvm::StringMap<ToolChain*> ToolChains;
public:
OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
: HostInfo(D, Triple) {}
~OpenBSDHostInfo();
virtual bool useDriverDriver() const;
virtual types::ID lookupTypeForExtension(const char *Ext) const {
return types::lookupTypeForExtension(Ext);
}
virtual ToolChain *getToolChain(const ArgList &Args,
const char *ArchName) const;
};
OpenBSDHostInfo::~OpenBSDHostInfo() {
for (llvm::StringMap<ToolChain*>::iterator
it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
delete it->second;
}
bool OpenBSDHostInfo::useDriverDriver() const {
return false;
}
ToolChain *OpenBSDHostInfo::getToolChain(const ArgList &Args,
const char *ArchName) const {
assert(!ArchName &&
"Unexpected arch name on platform without driver driver support.");
std::string Arch = getArchName();
ArchName = Arch.c_str();
ToolChain *&TC = ToolChains[ArchName];
if (!TC) {
llvm::Triple TCTriple(getTriple());
TCTriple.setArchName(ArchName);
TC = new toolchains::OpenBSD(*this, TCTriple);
}
return TC;
}
// FreeBSD Host Info
/// FreeBSDHostInfo - FreeBSD host information implementation.
@ -416,6 +467,12 @@ clang::driver::createDarwinHostInfo(const Driver &D,
return new DarwinHostInfo(D, Triple);
}
const HostInfo *
clang::driver::createOpenBSDHostInfo(const Driver &D,
const llvm::Triple& Triple) {
return new OpenBSDHostInfo(D, Triple);
}
const HostInfo *
clang::driver::createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple) {

View File

@ -14,8 +14,10 @@ using namespace clang::driver;
Job::~Job() {}
Command::Command(const char *_Executable, const ArgStringList &_Arguments)
: Job(CommandClass), Executable(_Executable), Arguments(_Arguments) {
Command::Command(const Action &_Source, const char *_Executable,
const ArgStringList &_Arguments)
: Job(CommandClass), Source(_Source), Executable(_Executable),
Arguments(_Arguments) {
}
PipedJob::PipedJob() : Job(PipedJobClass) {}

View File

@ -384,6 +384,36 @@ DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
return new DerivedArgList(Args, true);
}
/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
: Generic_GCC(Host, Triple) {
getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
getFilePaths().push_back("/usr/lib");
}
Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
Action::ActionClass Key;
if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Key = Action::AnalyzeJobClass;
else
Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
case Action::AssembleJobClass:
T = new tools::openbsd::Assemble(*this); break;
case Action::LinkJobClass:
T = new tools::openbsd::Link(*this); break;
default:
T = &Generic_GCC::SelectTool(C, JA);
}
}
return *T;
}
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)

View File

@ -107,6 +107,13 @@ class VISIBILITY_HIDDEN Darwin_GCC : public Generic_GCC {
virtual const char *GetDefaultRelocationModel() const { return "pic"; }
};
class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC {
public:
OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
};
class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
public:
FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);

View File

@ -498,6 +498,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
// Forward stack protector flags.
if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
options::OPT_fstack_protector_all,
options::OPT_fstack_protector)) {
if (A->getOption().matches(options::OPT_fno_stack_protector))
CmdArgs.push_back("--stack-protector=0");
else if (A->getOption().matches(options::OPT_fstack_protector))
CmdArgs.push_back("--stack-protector=1");
else
CmdArgs.push_back("--stack-protector=2");
}
// Forward -f options with positive and negative forms; we translate
// these by hand.
@ -616,7 +628,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
// Explicitly warn that these options are unsupported, even though
// we are allowing compilation to continue.
@ -747,7 +759,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().getHost().getDriver().CCCGenericGCCName.c_str();
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName).c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
@ -1123,7 +1135,7 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
const char *CC1Name = getCC1Name(Inputs[0].getType());
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
@ -1211,7 +1223,7 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
const char *CC1Name = getCC1Name(Inputs[0].getType());
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@ -1264,7 +1276,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
/// Helper routine for seeing if we should use dsymutil; this is a
@ -1688,7 +1700,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
// Find the first non-empty base input (we want to ignore linker
// inputs).
@ -1718,7 +1730,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil").c_str());
ArgStringList CmdArgs;
CmdArgs.push_back(Output.getFilename());
C.getJobs().addCommand(new Command(Exec, CmdArgs));
C.getJobs().addCommand(new Command(JA, Exec, CmdArgs));
}
}
}
@ -1744,9 +1756,121 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const
{
ArgStringList CmdArgs;
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);
CmdArgs.push_back("-o");
if (Output.isPipe())
CmdArgs.push_back("-");
else
CmdArgs.push_back(Output.getFilename());
for (InputInfoList::const_iterator
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
if (II.isPipe())
CmdArgs.push_back("-");
else
CmdArgs.push_back(II.getFilename());
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const Driver &D = getToolChain().getHost().getDriver();
ArgStringList CmdArgs;
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
CmdArgs.push_back("--eh-frame-hdr");
if (Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back("-Bshareable");
} else {
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/usr/libexec/ld.so");
}
}
if (Output.isPipe()) {
CmdArgs.push_back("-o");
CmdArgs.push_back("-");
} else if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o").c_str()));
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o").c_str()));
} else {
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o").c_str()));
}
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
for (InputInfoList::const_iterator
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
// Don't try to pass LLVM inputs to a generic gcc.
if (II.getType() == types::TY_LLVMBC)
D.Diag(clang::diag::err_drv_no_linker_llvm_support)
<< getToolChain().getTripleString().c_str();
if (II.isPipe())
CmdArgs.push_back("-");
else if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
II.getInputArg().renderAsInput(Args, CmdArgs);
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
if (Args.hasArg(options::OPT_pthread))
CmdArgs.push_back("-pthread");
CmdArgs.push_back("-lc");
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared))
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o").c_str()));
else
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o").c_str()));
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
@ -1781,7 +1905,7 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
@ -1892,7 +2016,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
/// DragonFly Tools
@ -1931,7 +2055,7 @@ void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
@ -2055,5 +2179,5 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
Dest.addCommand(new Command(JA, Exec, CmdArgs));
}

Some files were not shown because too many files have changed in this diff Show More