aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h22
-rw-r--r--include/clang/AST/CFG.h17
-rw-r--r--include/clang/AST/Decl.h86
-rw-r--r--include/clang/AST/DeclBase.h81
-rw-r--r--include/clang/AST/DeclCXX.h112
-rw-r--r--include/clang/AST/DeclObjC.h135
-rw-r--r--include/clang/AST/DeclTemplate.h790
-rw-r--r--include/clang/AST/Expr.h9
-rw-r--r--include/clang/AST/ExprCXX.h94
-rw-r--r--include/clang/AST/ExternalASTSource.h9
-rw-r--r--include/clang/AST/NestedNameSpecifier.h3
-rw-r--r--include/clang/AST/PrettyPrinter.h10
-rw-r--r--include/clang/AST/Stmt.h10
-rw-r--r--include/clang/AST/StmtNodes.def3
-rw-r--r--include/clang/AST/Type.h6
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h59
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h2
-rw-r--r--include/clang/Analysis/PathSensitive/ValueManager.h11
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td26
-rw-r--r--include/clang/Basic/LangOptions.h25
-rw-r--r--include/clang/Basic/TargetInfo.h4
-rw-r--r--include/clang/Basic/TokenKinds.def6
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
-rw-r--r--include/clang/Driver/Action.h2
-rw-r--r--include/clang/Driver/ArgList.h2
-rw-r--r--include/clang/Driver/Compilation.h33
-rw-r--r--include/clang/Driver/Driver.h8
-rw-r--r--include/clang/Driver/HostInfo.h2
-rw-r--r--include/clang/Driver/Job.h10
-rw-r--r--include/clang/Driver/Options.def5
-rw-r--r--include/clang/Frontend/ASTConsumers.h4
-rw-r--r--include/clang/Frontend/PCHBitCodes.h6
-rw-r--r--include/clang/Frontend/PCHReader.h14
-rw-r--r--include/clang/Frontend/PCHWriter.h1
-rw-r--r--include/clang/Lex/Preprocessor.h24
-rw-r--r--include/clang/Parse/Action.h24
-rw-r--r--include/clang/Parse/Ownership.h19
-rw-r--r--include/clang/Parse/Parser.h3
-rw-r--r--lib/AST/ASTContext.cpp277
-rw-r--r--lib/AST/CFG.cpp61
-rw-r--r--lib/AST/Decl.cpp94
-rw-r--r--lib/AST/DeclBase.cpp114
-rw-r--r--lib/AST/DeclCXX.cpp63
-rw-r--r--lib/AST/DeclObjC.cpp103
-rw-r--r--lib/AST/DeclPrinter.cpp36
-rw-r--r--lib/AST/DeclTemplate.cpp27
-rw-r--r--lib/AST/Expr.cpp33
-rw-r--r--lib/AST/ExprCXX.cpp60
-rw-r--r--lib/AST/ExprConstant.cpp69
-rw-r--r--lib/AST/NestedNameSpecifier.cpp6
-rw-r--r--lib/AST/StmtDumper.cpp4
-rw-r--r--lib/AST/StmtPrinter.cpp24
-rw-r--r--lib/AST/TemplateName.cpp8
-rw-r--r--lib/AST/Type.cpp26
-rw-r--r--lib/Analysis/BasicStore.cpp104
-rw-r--r--lib/Analysis/BugReporter.cpp7
-rw-r--r--lib/Analysis/CFRefCount.cpp57
-rw-r--r--lib/Analysis/CheckDeadStores.cpp4
-rw-r--r--lib/Analysis/CheckObjCDealloc.cpp14
-rw-r--r--lib/Analysis/CheckObjCInstMethSignature.cpp8
-rw-r--r--lib/Analysis/CheckObjCUnusedIVars.cpp15
-rw-r--r--lib/Analysis/Environment.cpp15
-rw-r--r--lib/Analysis/GRExprEngine.cpp15
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp2
-rw-r--r--lib/Analysis/GRState.cpp6
-rw-r--r--lib/Analysis/LiveVariables.cpp3
-rw-r--r--lib/Analysis/MemRegion.cpp46
-rw-r--r--lib/Analysis/RegionStore.cpp135
-rw-r--r--lib/Analysis/SVals.cpp7
-rw-r--r--lib/Analysis/Store.cpp6
-rw-r--r--lib/Basic/IdentifierTable.cpp2
-rw-r--r--lib/Basic/TargetInfo.cpp1
-rw-r--r--lib/Basic/Targets.cpp510
-rw-r--r--lib/CodeGen/CGBuiltin.cpp4
-rw-r--r--lib/CodeGen/CGCXX.cpp4
-rw-r--r--lib/CodeGen/CGCall.cpp27
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp9
-rw-r--r--lib/CodeGen/CGDecl.cpp12
-rw-r--r--lib/CodeGen/CGExpr.cpp4
-rw-r--r--lib/CodeGen/CGExprAgg.cpp8
-rw-r--r--lib/CodeGen/CGExprConstant.cpp8
-rw-r--r--lib/CodeGen/CGObjC.cpp6
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp41
-rw-r--r--lib/CodeGen/CGObjCMac.cpp67
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp4
-rw-r--r--lib/CodeGen/CodeGenModule.cpp105
-rw-r--r--lib/CodeGen/CodeGenModule.h3
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp10
-rw-r--r--lib/CodeGen/Mangle.cpp34
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp10
-rw-r--r--lib/CodeGen/TargetABIInfo.cpp24
-rw-r--r--lib/Driver/ArgList.cpp29
-rw-r--r--lib/Driver/Compilation.cpp43
-rw-r--r--lib/Driver/Driver.cpp50
-rw-r--r--lib/Driver/HostInfo.cpp57
-rw-r--r--lib/Driver/Job.cpp6
-rw-r--r--lib/Driver/ToolChains.cpp30
-rw-r--r--lib/Driver/ToolChains.h7
-rw-r--r--lib/Driver/Tools.cpp148
-rw-r--r--lib/Driver/Tools.h34
-rw-r--r--lib/Frontend/ASTConsumers.cpp15
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp12
-rw-r--r--lib/Frontend/Backend.cpp11
-rw-r--r--lib/Frontend/DeclXML.cpp10
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp8
-rw-r--r--lib/Frontend/InitPreprocessor.cpp9
-rw-r--r--lib/Frontend/PCHReader.cpp14
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp2
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp1
-rw-r--r--lib/Frontend/PCHWriter.cpp33
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp6
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp1
-rw-r--r--lib/Frontend/ResolveLocation.cpp8
-rw-r--r--lib/Frontend/RewriteBlocks.cpp33
-rw-r--r--lib/Frontend/RewriteObjC.cpp131
-rw-r--r--lib/Lex/Lexer.cpp9
-rw-r--r--lib/Lex/Pragma.cpp1
-rw-r--r--lib/Lex/Preprocessor.cpp23
-rw-r--r--lib/Parse/ParseDecl.cpp8
-rw-r--r--lib/Parse/ParseDeclCXX.cpp25
-rw-r--r--lib/Parse/ParseExpr.cpp15
-rw-r--r--lib/Parse/ParseExprCXX.cpp29
-rw-r--r--lib/Parse/Parser.cpp17
-rw-r--r--lib/Rewrite/Rewriter.cpp2
-rw-r--r--lib/Sema/JumpDiagnostics.cpp6
-rw-r--r--lib/Sema/Sema.cpp4
-rw-r--r--lib/Sema/Sema.h92
-rw-r--r--lib/Sema/SemaAttr.cpp2
-rw-r--r--lib/Sema/SemaChecking.cpp55
-rw-r--r--lib/Sema/SemaDecl.cpp93
-rw-r--r--lib/Sema/SemaDeclAttr.cpp111
-rw-r--r--lib/Sema/SemaDeclCXX.cpp168
-rw-r--r--lib/Sema/SemaDeclObjC.cpp155
-rw-r--r--lib/Sema/SemaExpr.cpp575
-rw-r--r--lib/Sema/SemaExprCXX.cpp8
-rw-r--r--lib/Sema/SemaExprObjC.cpp34
-rw-r--r--lib/Sema/SemaInherit.cpp4
-rw-r--r--lib/Sema/SemaInit.cpp29
-rw-r--r--lib/Sema/SemaLookup.cpp42
-rw-r--r--lib/Sema/SemaOverload.cpp72
-rw-r--r--lib/Sema/SemaStmt.cpp6
-rw-r--r--lib/Sema/SemaTemplate.cpp55
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp134
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp102
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp124
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp59
-rw-r--r--lib/Sema/SemaType.cpp79
-rw-r--r--test/Analysis/array-struct.c27
-rw-r--r--test/Analysis/concrete-address.c7
-rw-r--r--test/Analysis/misc-ps.m19
-rw-r--r--test/Analysis/stack-addr-ps.c16
-rw-r--r--test/Analysis/xfail_regionstore_wine_crash.c3
-rw-r--r--test/CMakeLists.txt3
-rw-r--r--test/CXX/basic/basic.def.odr/p2-typeid.cpp2
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp12
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp11
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp17
-rw-r--r--test/CodeGen/attributes.c2
-rw-r--r--test/CodeGen/stack-protector.c22
-rw-r--r--test/CodeGen/unwind-attr.c4
-rw-r--r--test/CodeGenCXX/function-template-specialization.cpp27
-rw-r--r--test/Driver/openbsd.c6
-rw-r--r--test/Index/comments.c30
-rw-r--r--test/PCH/pr4489.c20
-rw-r--r--test/Parser/offsetof.c7
-rw-r--r--test/Sema/compare.c14
-rw-r--r--test/Sema/ext_vector_casts.c22
-rw-r--r--test/Sema/format-attr-pr4470.c11
-rw-r--r--test/SemaCXX/class-base-member-init.cpp19
-rw-r--r--test/SemaCXX/constructor-initializer.cpp39
-rw-r--r--test/SemaCXX/decltype-overloaded-functions.cpp12
-rw-r--r--test/SemaCXX/exception-spec.cpp30
-rw-r--r--test/SemaCXX/member-pointer.cpp2
-rw-r--r--test/SemaTemplate/class-template-ctor-initializer.cpp33
-rw-r--r--test/SemaTemplate/operator-template.cpp6
-rw-r--r--test/SemaTemplate/recursive-template-instantiation.cpp10
-rw-r--r--test/cxx-sections.data2063
-rw-r--r--tools/clang-cc/clang-cc.cpp28
-rw-r--r--tools/driver/driver.cpp2
-rw-r--r--tools/index-test/index-test.cpp7
-rwxr-xr-xutils/test/TestRunner.py3
-rw-r--r--www/analyzer/latest_checker.html.incl2
-rw-r--r--www/cxx_status.html1
184 files changed, 5851 insertions, 3551 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index aa01b7fdf06f..041a0f33ad4d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -141,10 +141,19 @@ class ASTContext {
/// this ASTContext object.
LangOptions LangOpts;
+ /// \brief Whether we have already loaded comment source ranges from an
+ /// external source.
+ bool LoadedExternalComments;
+
/// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects.
bool FreeMemory;
llvm::MallocAllocator MallocAlloc;
llvm::BumpPtrAllocator BumpAlloc;
+
+ /// \brief Mapping from declarations to their comments, once we have
+ /// already looked up the comment associated with a given declaration.
+ llvm::DenseMap<const Decl *, std::string> DeclComments;
+
public:
TargetInfo &Target;
IdentifierTable &Idents;
@@ -154,6 +163,10 @@ public:
llvm::OwningPtr<ExternalASTSource> ExternalSource;
clang::PrintingPolicy PrintingPolicy;
+ /// \brief Source ranges for all of the comments in the source file,
+ /// sorted in order of appearance in the translation unit.
+ std::vector<SourceRange> Comments;
+
SourceManager& getSourceManager() { return SourceMgr; }
const SourceManager& getSourceManager() const { return SourceMgr; }
void *Allocate(unsigned Size, unsigned Align = 8) {
@@ -178,7 +191,8 @@ public:
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
-
+ const char *getCommentForDecl(const Decl *D);
+
// Builtin Types.
QualType VoidTy;
QualType BoolTy;
@@ -351,12 +365,6 @@ public:
ObjCProtocolDecl **ProtocolList,
unsigned NumProtocols);
- /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for a
- /// given 'id' and conforming protocol list.
- QualType getObjCQualifiedIdType(ObjCProtocolDecl **ProtocolList,
- unsigned NumProtocols);
-
-
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
diff --git a/include/clang/AST/CFG.h b/include/clang/AST/CFG.h
index 7a9ee01d4f62..e60e58e1ac23 100644
--- a/include/clang/AST/CFG.h
+++ b/include/clang/AST/CFG.h
@@ -17,17 +17,20 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
#include <list>
#include <vector>
#include <cassert>
+namespace llvm {
+ class raw_ostream;
+}
namespace clang {
class Stmt;
class Expr;
class CFG;
class PrinterHelper;
class BlockEdge;
+ class LangOptions;
/// CFGBlock - Represents a single basic block in a source-level CFG.
/// It consists of:
@@ -181,9 +184,9 @@ public:
unsigned getBlockID() const { return BlockID; }
- void dump(const CFG* cfg) const;
- void print(llvm::raw_ostream& OS, const CFG* cfg) const;
- void printTerminator(llvm::raw_ostream& OS) const;
+ void dump(const CFG *cfg, const LangOptions &LO) const;
+ void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
+ void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
};
@@ -283,9 +286,9 @@ public:
// CFG Debugging: Pretty-Printing and Visualization.
//===--------------------------------------------------------------------===//
- void viewCFG() const;
- void print(llvm::raw_ostream& OS) const;
- void dump() const;
+ void viewCFG(const LangOptions &LO) const;
+ void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
+ void dump(const LangOptions &LO) const;
//===--------------------------------------------------------------------===//
// Internal: constructors and data.
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 3de01f3baeb5..69a52869d818 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -26,13 +26,19 @@ class Stmt;
class CompoundStmt;
class StringLiteral;
class TemplateArgumentList;
+class FunctionTemplateSpecializationInfo;
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
- TranslationUnitDecl()
+ ASTContext &Ctx;
+
+ explicit TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, 0, SourceLocation()),
- DeclContext(TranslationUnit) {}
+ DeclContext(TranslationUnit),
+ Ctx(ctx) {}
public:
+ ASTContext &getASTContext() const { return Ctx; }
+
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
@@ -621,15 +627,8 @@ public:
enum StorageClass {
None, Extern, Static, PrivateExtern
};
-private:
- /// \brief Provides information about a function template specialization,
- /// which is a FunctionDecl that has been explicitly specialization or
- /// instantiated from a function template.
- struct TemplateSpecializationInfo {
- FunctionTemplateDecl *Template;
- const TemplateArgumentList *TemplateArguments;
- };
+private:
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
@@ -684,7 +683,8 @@ private:
/// the template being specialized and the template arguments involved in
/// that specialization.
llvm::PointerUnion3<FunctionTemplateDecl*, FunctionDecl*,
- TemplateSpecializationInfo*> TemplateOrSpecialization;
+ FunctionTemplateSpecializationInfo*>
+ TemplateOrSpecialization;
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -724,11 +724,11 @@ public:
/// function. The variant that accepts a FunctionDecl pointer will
/// set that function declaration to the actual declaration
/// containing the body (if there is one).
- Stmt *getBody(ASTContext &Context, const FunctionDecl *&Definition) const;
+ Stmt *getBody(const FunctionDecl *&Definition) const;
- virtual Stmt *getBody(ASTContext &Context) const {
+ virtual Stmt *getBody() const {
const FunctionDecl* Definition;
- return getBody(Context, Definition);
+ return getBody(Definition);
}
/// \brief If the function has a body that is immediately available,
@@ -809,9 +809,7 @@ public:
return PreviousDeclaration;
}
- void setPreviousDeclaration(FunctionDecl * PrevDecl) {
- PreviousDeclaration = PrevDecl;
- }
+ void setPreviousDeclaration(FunctionDecl * PrevDecl);
unsigned getBuiltinID(ASTContext &Context) const;
@@ -940,27 +938,14 @@ public:
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
- FunctionTemplateDecl *getPrimaryTemplate() const {
- if (TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) {
- return Info->Template;
- }
- return 0;
- }
+ FunctionTemplateDecl *getPrimaryTemplate() const;
/// \brief Retrieve the template arguments used to produce this function
/// template specialization from the primary template.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
- const TemplateArgumentList *getTemplateSpecializationArgs() const {
- if (TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) {
- return Info->TemplateArguments;
- }
- return 0;
- }
-
+ const TemplateArgumentList *getTemplateSpecializationArgs() const;
/// \brief Specify that this function declaration is actually a function
/// template specialization.
@@ -974,8 +959,17 @@ public:
/// function template specialization from the template.
void setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs);
-
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos);
+
+ /// \brief Determine whether this is an explicit specialization of a
+ /// function template or a member function of a class template.
+ bool isExplicitSpecialization() const;
+
+ /// \brief Note that this is an explicit specialization of a function template
+ /// or a member function of a class template.
+ void setExplicitSpecialization(bool ES);
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
@@ -1268,12 +1262,12 @@ public:
// enumeration.
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
- enumerator_iterator enumerator_begin(ASTContext &Context) const {
- return enumerator_iterator(this->decls_begin(Context));
+ enumerator_iterator enumerator_begin() const {
+ return enumerator_iterator(this->decls_begin());
}
- enumerator_iterator enumerator_end(ASTContext &Context) const {
- return enumerator_iterator(this->decls_end(Context));
+ enumerator_iterator enumerator_end() const {
+ return enumerator_iterator(this->decls_end());
}
/// getIntegerType - Return the integer type this enum decl corresponds to.
@@ -1376,17 +1370,17 @@ public:
// data members, functions, constructors, destructors, etc.
typedef specific_decl_iterator<FieldDecl> field_iterator;
- field_iterator field_begin(ASTContext &Context) const {
- return field_iterator(decls_begin(Context));
+ field_iterator field_begin() const {
+ return field_iterator(decls_begin());
}
- field_iterator field_end(ASTContext &Context) const {
- return field_iterator(decls_end(Context));
+ field_iterator field_end() const {
+ return field_iterator(decls_end());
}
// field_empty - Whether there are any fields (non-static data
// members) in this record.
- bool field_empty(ASTContext &Context) const {
- return field_begin(Context) == field_end(Context);
+ bool field_empty() const {
+ return field_begin() == field_end();
}
/// completeDefinition - Notes that the definition of this type is
@@ -1448,8 +1442,8 @@ public:
bool IsVariadic() const { return isVariadic; }
void setIsVariadic(bool value) { isVariadic = value; }
- CompoundStmt *getBody() const { return (CompoundStmt*) Body; }
- Stmt *getBody(ASTContext &C) const { return (Stmt*) Body; }
+ CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
+ Stmt *getBody() const { return (Stmt*) Body; }
void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
// Iterator access to formal parameters.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index c959b05473fe..0bce2f84c7ba 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -213,6 +213,13 @@ public:
const DeclContext *getDeclContext() const {
return const_cast<Decl*>(this)->getDeclContext();
}
+
+ TranslationUnitDecl *getTranslationUnitDecl();
+ const TranslationUnitDecl *getTranslationUnitDecl() const {
+ return const_cast<Decl*>(this)->getTranslationUnitDecl();
+ }
+
+ ASTContext &getASTContext() const;
void setAccess(AccessSpecifier AS) {
Access = AS;
@@ -225,23 +232,23 @@ public:
}
bool hasAttrs() const { return HasAttrs; }
- void addAttr(ASTContext &Context, Attr *attr);
- const Attr *getAttrs(ASTContext &Context) const {
+ void addAttr(Attr *attr);
+ const Attr *getAttrs() const {
if (!HasAttrs) return 0; // common case, no attributes.
- return getAttrsImpl(Context); // Uncommon case, out of line hash lookup.
+ return getAttrsImpl(); // Uncommon case, out of line hash lookup.
}
- void swapAttrs(ASTContext &Context, Decl *D);
- void invalidateAttrs(ASTContext &Context);
+ void swapAttrs(Decl *D);
+ void invalidateAttrs();
- template<typename T> const T *getAttr(ASTContext &Context) const {
- for (const Attr *attr = getAttrs(Context); attr; attr = attr->getNext())
+ template<typename T> const T *getAttr() const {
+ for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
if (const T *V = dyn_cast<T>(attr))
return V;
return 0;
}
- template<typename T> bool hasAttr(ASTContext &Context) const {
- return getAttr<T>(Context) != 0;
+ template<typename T> bool hasAttr() const {
+ return getAttr<T>() != 0;
}
/// setInvalidDecl - Indicates the Decl had a semantic error. This
@@ -307,14 +314,14 @@ public:
/// getBody - If this Decl represents a declaration for a body of code,
/// such as a function or method definition, this method returns the
/// top-level Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody(ASTContext &Context) const { return 0; }
+ virtual Stmt* getBody() const { return 0; }
/// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
- CompoundStmt* getCompoundBody(ASTContext &Context) const;
+ CompoundStmt* getCompoundBody() const;
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
/// This works whether the body is a CompoundStmt or a CXXTryStmt.
- SourceLocation getBodyRBrace(ASTContext &Context) const;
+ SourceLocation getBodyRBrace() const;
// global temp stats (until we have a per-module visitor)
static void addDeclKind(Kind k);
@@ -340,18 +347,16 @@ public:
/// Destroy - Call destructors and release memory.
virtual void Destroy(ASTContext& C);
- void print(llvm::raw_ostream &Out, ASTContext &Context,
+ void print(llvm::raw_ostream &Out, unsigned Indentation = 0);
+ void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
- void print(llvm::raw_ostream &Out, ASTContext &Context,
- const PrintingPolicy &Policy, unsigned Indentation = 0);
static void printGroup(Decl** Begin, unsigned NumDecls,
- llvm::raw_ostream &Out, ASTContext &Context,
- const PrintingPolicy &Policy,
+ llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
- void dump(ASTContext &Context);
+ void dump();
private:
- const Attr *getAttrsImpl(ASTContext &Context) const;
+ const Attr *getAttrsImpl() const;
};
@@ -454,7 +459,11 @@ public:
const DeclContext *getLexicalParent() const {
return const_cast<DeclContext*>(this)->getLexicalParent();
}
-
+
+ ASTContext &getParentASTContext() const {
+ return cast<Decl>(this)->getASTContext();
+ }
+
bool isFunctionOrMethod() const {
switch (DeclKind) {
case Decl::Block:
@@ -592,9 +601,9 @@ public:
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
- decl_iterator decls_begin(ASTContext &Context) const;
- decl_iterator decls_end(ASTContext &Context) const;
- bool decls_empty(ASTContext &Context) const;
+ decl_iterator decls_begin() const;
+ decl_iterator decls_end() const;
+ bool decls_empty() const;
/// specific_decl_iterator - Iterates over a subrange of
/// declarations stored in a DeclContext, providing only those that
@@ -750,7 +759,7 @@ public:
///
/// If D is also a NamedDecl, it will be made visible within its
/// semantic context via makeDeclVisibleInContext.
- void addDecl(ASTContext &Context, Decl *D);
+ void addDecl(Decl *D);
/// lookup_iterator - An iterator that provides access to the results
/// of looking up a name within this context.
@@ -769,8 +778,8 @@ public:
/// the declarations with this name, with object, function, member,
/// and enumerator names preceding any tag name. Note that this
/// routine will not look into parent contexts.
- lookup_result lookup(ASTContext &Context, DeclarationName Name);
- lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const;
+ lookup_result lookup(DeclarationName Name);
+ lookup_const_result lookup(DeclarationName Name) const;
/// @brief Makes a declaration visible within this context.
///
@@ -786,7 +795,7 @@ public:
/// visible from this context, as determined by
/// NamedDecl::declarationReplaces, the previous declaration will be
/// replaced with D.
- void makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D);
+ void makeDeclVisibleInContext(NamedDecl *D);
/// udir_iterator - Iterates through the using-directives stored
/// within this context.
@@ -794,14 +803,14 @@ public:
typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
- udir_iterator_range getUsingDirectives(ASTContext &Context) const;
+ udir_iterator_range getUsingDirectives() const;
- udir_iterator using_directives_begin(ASTContext &Context) const {
- return getUsingDirectives(Context).first;
+ udir_iterator using_directives_begin() const {
+ return getUsingDirectives().first;
}
- udir_iterator using_directives_end(ASTContext &Context) const {
- return getUsingDirectives(Context).second;
+ udir_iterator using_directives_end() const {
+ return getUsingDirectives().second;
}
// Low-level accessors
@@ -836,11 +845,11 @@ public:
#include "clang/AST/DeclNodes.def"
private:
- void LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const;
- void LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const;
+ void LoadLexicalDeclsFromExternalStorage() const;
+ void LoadVisibleDeclsFromExternalStorage() const;
- void buildLookup(ASTContext &Context, DeclContext *DCtx);
- void makeDeclVisibleInContextImpl(ASTContext &Context, NamedDecl *D);
+ void buildLookup(DeclContext *DCtx);
+ void makeDeclVisibleInContextImpl(NamedDecl *D);
};
inline bool Decl::isTemplateParameter() const {
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a2fe24e83105..c523e96e03b0 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -32,6 +32,8 @@ class ClassTemplateSpecializationDecl;
class AnyFunctionDecl {
NamedDecl *Function;
+ AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+
public:
AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
AnyFunctionDecl(FunctionTemplateDecl *FTD);
@@ -42,6 +44,10 @@ public:
/// \brief Retrieve the underlying function or function template.
NamedDecl *get() const { return Function; }
+
+ static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
+ return AnyFunctionDecl(ND);
+ }
};
} // end namespace clang
@@ -57,6 +63,22 @@ namespace llvm {
};
template<> struct simplify_type< ::clang::AnyFunctionDecl>
: public simplify_type<const ::clang::AnyFunctionDecl> {};
+
+ // Provide PointerLikeTypeTraits for non-cvr pointers.
+ template<>
+ class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
+ public:
+ static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
+ return F.get();
+ }
+ static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
+ return ::clang::AnyFunctionDecl::getFromNamedDecl(
+ static_cast< ::clang::NamedDecl*>(P));
+ }
+
+ enum { NumLowBitsAvailable = 2 };
+ };
+
} // end namespace llvm
namespace clang {
@@ -91,24 +113,10 @@ public:
static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
DeclarationName N);
- /// addOverload - Add an overloaded function FD to this set of
- /// overloaded functions.
- void addOverload(FunctionDecl *FD) {
- assert((FD->getDeclName() == getDeclName() ||
- isa<CXXConversionDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
- "Overloaded functions must have the same name");
- Functions.push_back(FD);
-
- // An overloaded function declaration always has the location of
- // the most-recently-added function declaration.
- if (FD->getLocation().isValid())
- this->setLocation(FD->getLocation());
- }
+ /// \brief Add a new overloaded function or function template to the set
+ /// of overloaded function templates.
+ void addOverload(AnyFunctionDecl F);
- /// addOverload - Add an overloaded function template FTD to this set of
- /// overloaded functions.
- void addOverload(FunctionTemplateDecl *FTD);
-
function_iterator function_begin() { return Functions.begin(); }
function_iterator function_end() { return Functions.end(); }
function_const_iterator function_begin() const { return Functions.begin(); }
@@ -289,8 +297,11 @@ public:
CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
+ virtual void Destroy(ASTContext& C);
+
/// setBases - Sets the base classes of this struct or class.
- void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+ void setBases(ASTContext &C,
+ CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// getNumBases - Retrieves the number of base classes of this
/// class.
@@ -580,15 +591,20 @@ class CXXBaseOrMemberInitializer {
/// Args - The arguments used to initialize the base or member.
Expr **Args;
unsigned NumArgs;
+
+ /// IdLoc - Location of the id in ctor-initializer list.
+ SourceLocation IdLoc;
public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
- CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs);
+ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
+ SourceLocation L);
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
explicit
- CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs);
+ CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
+ SourceLocation L);
/// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
~CXXBaseOrMemberInitializer();
@@ -601,6 +617,10 @@ public:
/// arguments.
typedef Expr * const * arg_const_iterator;
+ /// getBaseOrMember - get the generic 'member' representing either the field
+ /// or a base class.
+ void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); }
+
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
@@ -641,6 +661,8 @@ public:
return 0;
}
+ SourceLocation getSourceLocation() const { return IdLoc; }
+
/// begin() - Retrieve an iterator to the first initializer argument.
arg_iterator begin() { return Args; }
/// begin() - Retrieve an iterator to the first initializer argument.
@@ -677,16 +699,22 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// @c !Implicit && ImplicitlyDefined.
bool ImplicitlyDefined : 1;
- /// FIXME: Add support for base and member initializers.
-
+ /// Support for base and member initializers.
+ /// BaseOrMemberInitializers - The arguments used to initialize the base
+ /// or member.
+ CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
+ unsigned NumBaseOrMemberInitializers;
+
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isExplicit, bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline),
- Explicit(isExplicit), ImplicitlyDefined(false) {
+ Explicit(isExplicit), ImplicitlyDefined(false),
+ BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
-
+ virtual void Destroy(ASTContext& C);
+
public:
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@@ -702,7 +730,8 @@ public:
/// already been defined.
bool isImplicitlyDefined(ASTContext &C) const {
assert(isThisDeclarationADefinition() &&
- "Can only get the implicit-definition flag once the constructor has been defined");
+ "Can only get the implicit-definition flag once the "
+ "constructor has been defined");
return ImplicitlyDefined;
}
@@ -710,10 +739,41 @@ public:
/// implicitly defined or not.
void setImplicitlyDefined(bool ID) {
assert(isThisDeclarationADefinition() &&
- "Can only set the implicit-definition flag once the constructor has been defined");
+ "Can only set the implicit-definition flag once the constructor "
+ "has been defined");
ImplicitlyDefined = ID;
}
+ /// init_iterator - Iterates through the member/base initializer list.
+ typedef CXXBaseOrMemberInitializer **init_iterator;
+
+ /// init_const_iterator - Iterates through the memberbase initializer list.
+ typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_iterator begin() { return BaseOrMemberInitializers; }
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_const_iterator begin() const { return BaseOrMemberInitializers; }
+
+ /// end() - Retrieve an iterator past the last initializer.
+ init_iterator end() {
+ return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ }
+ /// end() - Retrieve an iterator past the last initializer.
+ init_const_iterator end() const {
+ return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ }
+
+ /// getNumArgs - Determine the number of arguments used to
+ /// initialize the member or base.
+ unsigned getNumBaseOrMemberInitializers() const {
+ return NumBaseOrMemberInitializers;
+ }
+
+ void setBaseOrMemberInitializers(ASTContext &C,
+ CXXBaseOrMemberInitializer **Initializers,
+ unsigned NumInitializers);
+
/// isDefaultConstructor - Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
/// default-initialize a class of this type.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 3943ddc19638..2fcdaa3e2959 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -242,10 +242,10 @@ public:
return ImplementationControl(DeclImplementation);
}
- virtual Stmt *getBody(ASTContext &C) const {
+ virtual Stmt *getBody() const {
return (Stmt*) Body;
}
- CompoundStmt *getBody() { return (CompoundStmt*)Body; }
+ CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
void setBody(Stmt *B) { Body = B; }
// Implement isa/cast/dyncast/etc.
@@ -291,55 +291,52 @@ public:
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
- prop_iterator prop_begin(ASTContext &Context) const {
- return prop_iterator(decls_begin(Context));
+ prop_iterator prop_begin() const {
+ return prop_iterator(decls_begin());
}
- prop_iterator prop_end(ASTContext &Context) const {
- return prop_iterator(decls_end(Context));
+ prop_iterator prop_end() const {
+ return prop_iterator(decls_end());
}
// Iterator access to instance/class methods.
typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
- method_iterator meth_begin(ASTContext &Context) const {
- return method_iterator(decls_begin(Context));
+ method_iterator meth_begin() const {
+ return method_iterator(decls_begin());
}
- method_iterator meth_end(ASTContext &Context) const {
- return method_iterator(decls_end(Context));
+ method_iterator meth_end() const {
+ return method_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
- instmeth_iterator instmeth_begin(ASTContext &Context) const {
- return instmeth_iterator(decls_begin(Context));
+ instmeth_iterator instmeth_begin() const {
+ return instmeth_iterator(decls_begin());
}
- instmeth_iterator instmeth_end(ASTContext &Context) const {
- return instmeth_iterator(decls_end(Context));
+ instmeth_iterator instmeth_end() const {
+ return instmeth_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
- classmeth_iterator classmeth_begin(ASTContext &Context) const {
- return classmeth_iterator(decls_begin(Context));
+ classmeth_iterator classmeth_begin() const {
+ return classmeth_iterator(decls_begin());
}
- classmeth_iterator classmeth_end(ASTContext &Context) const {
- return classmeth_iterator(decls_end(Context));
+ classmeth_iterator classmeth_end() const {
+ return classmeth_iterator(decls_end());
}
// Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const;
- ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const;
- ObjCIvarDecl *getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const;
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
+ ObjCMethodDecl *getClassMethod(Selector Sel) const;
+ ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
- ObjCMethodDecl *
- getMethod(ASTContext &Context, Selector Sel, bool isInstance) const {
- return isInstance ? getInstanceMethod(Context, Sel)
- : getClassMethod(Context, Sel);
+ ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
+ return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
}
- ObjCPropertyDecl *FindPropertyDeclaration(ASTContext &Context,
- IdentifierInfo *PropertyId) const;
+ ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
// Marks the end of the container.
SourceLocation getAtEndLoc() const { return AtEndLoc; }
@@ -474,19 +471,17 @@ public:
return false;
}
- ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context,
- IdentifierInfo *IVarName,
+ ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context,
- IdentifierInfo *IVarName) {
+ ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(Context, IVarName, ClassDeclared);
+ return lookupInstanceVariable(IVarName, ClassDeclared);
}
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel);
- ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel);
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
+ ObjCMethodDecl *lookupClassMethod(Selector Sel);
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
// Location information, modeled after the Stmt API.
@@ -648,8 +643,8 @@ public:
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel);
- ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel);
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
+ ObjCMethodDecl *lookupClassMethod(Selector Sel);
bool isForwardDecl() const { return isForwardProtoDecl; }
void setForwardDecl(bool val) { isForwardProtoDecl = val; }
@@ -831,61 +826,57 @@ public:
ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
void setClassInterface(ObjCInterfaceDecl *IFace) { ClassInterface = IFace; }
- void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ void addInstanceMethod(ObjCMethodDecl *method) {
// FIXME: Context should be set correctly before we get here.
method->setLexicalDeclContext(this);
- addDecl(Context, method);
+ addDecl(method);
}
- void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ void addClassMethod(ObjCMethodDecl *method) {
// FIXME: Context should be set correctly before we get here.
method->setLexicalDeclContext(this);
- addDecl(Context, method);
+ addDecl(method);
}
// Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const;
- ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const;
- ObjCMethodDecl *getMethod(ASTContext &Context, Selector Sel,
- bool isInstance) const {
- return isInstance ? getInstanceMethod(Context, Sel)
- : getClassMethod(Context, Sel);
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
+ ObjCMethodDecl *getClassMethod(Selector Sel) const;
+ ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
+ return isInstance ? getInstanceMethod(Sel)
+ : getClassMethod(Sel);
}
- void addPropertyImplementation(ASTContext &Context,
- ObjCPropertyImplDecl *property);
+ void addPropertyImplementation(ObjCPropertyImplDecl *property);
- ObjCPropertyImplDecl *FindPropertyImplDecl(ASTContext &Context,
- IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(ASTContext &Context,
- IdentifierInfo *ivarId) const;
+ ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
+ ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
- propimpl_iterator propimpl_begin(ASTContext &Context) const {
- return propimpl_iterator(decls_begin(Context));
+ propimpl_iterator propimpl_begin() const {
+ return propimpl_iterator(decls_begin());
}
- propimpl_iterator propimpl_end(ASTContext &Context) const {
- return propimpl_iterator(decls_end(Context));
+ propimpl_iterator propimpl_end() const {
+ return propimpl_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
- instmeth_iterator instmeth_begin(ASTContext &Context) const {
- return instmeth_iterator(decls_begin(Context));
+ instmeth_iterator instmeth_begin() const {
+ return instmeth_iterator(decls_begin());
}
- instmeth_iterator instmeth_end(ASTContext &Context) const {
- return instmeth_iterator(decls_end(Context));
+ instmeth_iterator instmeth_end() const {
+ return instmeth_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
- classmeth_iterator classmeth_begin(ASTContext &Context) const {
- return classmeth_iterator(decls_begin(Context));
+ classmeth_iterator classmeth_begin() const {
+ return classmeth_iterator(decls_begin());
}
- classmeth_iterator classmeth_end(ASTContext &Context) const {
- return classmeth_iterator(decls_end(Context));
+ classmeth_iterator classmeth_end() const {
+ return classmeth_iterator(decls_end());
}
// Location information, modeled after the Stmt API.
@@ -1002,17 +993,17 @@ public:
void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- ivar_iterator ivar_begin(ASTContext &Context) const {
- return ivar_iterator(decls_begin(Context));
+ ivar_iterator ivar_begin() const {
+ return ivar_iterator(decls_begin());
}
- ivar_iterator ivar_end(ASTContext &Context) const {
- return ivar_iterator(decls_end(Context));
+ ivar_iterator ivar_end() const {
+ return ivar_iterator(decls_end());
}
- unsigned ivar_size(ASTContext &Context) const {
- return std::distance(ivar_begin(Context), ivar_end(Context));
+ unsigned ivar_size() const {
+ return std::distance(ivar_begin(), ivar_end());
}
- bool ivar_empty(ASTContext &Context) const {
- return ivar_begin(Context) == ivar_end(Context);
+ bool ivar_empty() const {
+ return ivar_begin() == ivar_end();
}
static bool classof(const Decl *D) {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index aad19a63ef0f..5d0fe158e054 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -100,6 +100,352 @@ public:
}
};
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+ union {
+ uintptr_t TypeOrValue;
+ struct {
+ char Value[sizeof(llvm::APSInt)];
+ void *Type;
+ } Integer;
+ struct {
+ TemplateArgument *Args;
+ unsigned NumArgs;
+ bool CopyArgs;
+ } Args;
+ };
+
+ /// \brief Location of the beginning of this template argument.
+ SourceLocation StartLoc;
+
+public:
+ /// \brief The type of template argument we're storing.
+ enum ArgKind {
+ Null = 0,
+ /// The template argument is a type. Its value is stored in the
+ /// TypeOrValue field.
+ Type = 1,
+ /// The template argument is a declaration
+ Declaration = 2,
+ /// The template argument is an integral value stored in an llvm::APSInt.
+ Integral = 3,
+ /// The template argument is a value- or type-dependent expression
+ /// stored in an Expr*.
+ Expression = 4,
+
+ /// The template argument is actually a parameter pack. Arguments are stored
+ /// in the Args struct.
+ Pack = 5
+ } Kind;
+
+ /// \brief Construct an empty, invalid template argument.
+ TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
+
+ /// \brief Construct a template type argument.
+ TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct a template argument that refers to a
+ /// declaration, which is either an external declaration or a
+ /// template declaration.
+ TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
+ // FIXME: Need to be sure we have the "canonical" declaration!
+ TypeOrValue = reinterpret_cast<uintptr_t>(D);
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct an integral constant template argument.
+ TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
+ QualType Type)
+ : Kind(Integral) {
+ new (Integer.Value) llvm::APSInt(Value);
+ Integer.Type = Type.getAsOpaquePtr();
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct a template argument that is an expression.
+ ///
+ /// This form of template argument only occurs in template argument
+ /// lists used for dependent types and for expression; it will not
+ /// occur in a non-dependent, canonical template argument list.
+ TemplateArgument(Expr *E);
+
+ /// \brief Copy constructor for a template argument.
+ TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ if (Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else if (Kind == Pack) {
+ Args.NumArgs = Other.Args.NumArgs;
+ Args.Args = new TemplateArgument[Args.NumArgs];
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I] = Other.Args.Args[I];
+ }
+ else
+ TypeOrValue = Other.TypeOrValue;
+ StartLoc = Other.StartLoc;
+ }
+
+ TemplateArgument& operator=(const TemplateArgument& Other) {
+ // FIXME: Does not provide the strong guarantee for exception
+ // safety.
+ using llvm::APSInt;
+
+ // FIXME: Handle Packs
+ assert(Kind != Pack && "FIXME: Handle packs");
+ assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+ if (Kind == Other.Kind && Kind == Integral) {
+ // Copy integral values.
+ *this->getAsIntegral() = *Other.getAsIntegral();
+ Integer.Type = Other.Integer.Type;
+ } else {
+ // Destroy the current integral value, if that's what we're holding.
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+
+ Kind = Other.Kind;
+
+ if (Other.Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else
+ TypeOrValue = Other.TypeOrValue;
+ }
+ StartLoc = Other.StartLoc;
+
+ return *this;
+ }
+
+ ~TemplateArgument() {
+ using llvm::APSInt;
+
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+ else if (Kind == Pack && Args.CopyArgs)
+ delete[] Args.Args;
+ }
+
+ /// \brief Return the kind of stored template argument.
+ ArgKind getKind() const { return Kind; }
+
+ /// \brief Determine whether this template argument has no value.
+ bool isNull() const { return Kind == Null; }
+
+ /// \brief Retrieve the template argument as a type.
+ QualType getAsType() const {
+ if (Kind != Type)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(
+ reinterpret_cast<void*>(TypeOrValue));
+ }
+
+ /// \brief Retrieve the template argument as a declaration.
+ Decl *getAsDecl() const {
+ if (Kind != Declaration)
+ return 0;
+ return reinterpret_cast<Decl *>(TypeOrValue);
+ }
+
+ /// \brief Retrieve the template argument as an integral value.
+ llvm::APSInt *getAsIntegral() {
+ if (Kind != Integral)
+ return 0;
+ return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+ }
+
+ const llvm::APSInt *getAsIntegral() const {
+ return const_cast<TemplateArgument*>(this)->getAsIntegral();
+ }
+
+ /// \brief Retrieve the type of the integral value.
+ QualType getIntegralType() const {
+ if (Kind != Integral)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(Integer.Type);
+ }
+
+ void setIntegralType(QualType T) {
+ assert(Kind == Integral &&
+ "Cannot set the integral type of a non-integral template argument");
+ Integer.Type = T.getAsOpaquePtr();
+ };
+
+ /// \brief Retrieve the template argument as an expression.
+ Expr *getAsExpr() const {
+ if (Kind != Expression)
+ return 0;
+
+ return reinterpret_cast<Expr *>(TypeOrValue);
+ }
+
+ /// \brief Iterator that traverses the elements of a template argument pack.
+ typedef const TemplateArgument * pack_iterator;
+
+ /// \brief Iterator referencing the first argument of a template argument
+ /// pack.
+ pack_iterator pack_begin() const {
+ assert(Kind == Pack);
+ return Args.Args;
+ }
+
+ /// \brief Iterator referencing one past the last argument of a template
+ /// argument pack.
+ pack_iterator pack_end() const {
+ assert(Kind == Pack);
+ return Args.Args + Args.NumArgs;
+ }
+
+ /// \brief The number of template arguments in the given template argument
+ /// pack.
+ unsigned pack_size() const {
+ assert(Kind == Pack);
+ return Args.NumArgs;
+ }
+
+ /// \brief Retrieve the location where the template argument starts.
+ SourceLocation getLocation() const { return StartLoc; }
+
+ /// \brief Construct a template argument pack.
+ void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+ /// \brief Used to insert TemplateArguments into FoldingSets.
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(Kind);
+ switch (Kind) {
+ case Null:
+ break;
+
+ case Type:
+ getAsType().Profile(ID);
+ break;
+
+ case Declaration:
+ ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
+ break;
+
+ case Integral:
+ getAsIntegral()->Profile(ID);
+ getIntegralType().Profile(ID);
+ break;
+
+ case Expression:
+ // FIXME: We need a canonical representation of expressions.
+ ID.AddPointer(getAsExpr());
+ break;
+
+ case Pack:
+ ID.AddInteger(Args.NumArgs);
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I].Profile(ID);
+ }
+ }
+};
+
+/// \brief A helper class for making template argument lists.
+class TemplateArgumentListBuilder {
+ TemplateArgument *StructuredArgs;
+ unsigned MaxStructuredArgs;
+ unsigned NumStructuredArgs;
+
+ TemplateArgument *FlatArgs;
+ unsigned MaxFlatArgs;
+ unsigned NumFlatArgs;
+
+ bool AddingToPack;
+ unsigned PackBeginIndex;
+
+public:
+ TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
+ unsigned NumTemplateArgs)
+ : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
+ NumStructuredArgs(0), FlatArgs(0),
+ MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
+ AddingToPack(false), PackBeginIndex(0) { }
+
+ void Append(const TemplateArgument& Arg);
+ void BeginPack();
+ void EndPack();
+
+ void ReleaseArgs();
+
+ unsigned flatSize() const {
+ return NumFlatArgs;
+ }
+ const TemplateArgument *getFlatArguments() const {
+ return FlatArgs;
+ }
+
+ unsigned structuredSize() const {
+ // If we don't have any structured args, just reuse the flat size.
+ if (!StructuredArgs)
+ return flatSize();
+
+ return NumStructuredArgs;
+ }
+ const TemplateArgument *getStructuredArguments() const {
+ // If we don't have any structured args, just reuse the flat args.
+ if (!StructuredArgs)
+ return getFlatArguments();
+
+ return StructuredArgs;
+ }
+};
+
+/// \brief A template argument list.
+///
+/// FIXME: In the future, this class will be extended to support
+/// variadic templates and member templates, which will make some of
+/// the function names below make more sense.
+class TemplateArgumentList {
+ /// \brief The template argument list.
+ ///
+ /// The integer value will be non-zero to indicate that this
+ /// template argument list does not own the pointer.
+ llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+
+ /// \brief The number of template arguments in this template
+ /// argument list.
+ unsigned NumFlatArguments;
+
+ llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
+ unsigned NumStructuredArguments;
+
+public:
+ TemplateArgumentList(ASTContext &Context,
+ TemplateArgumentListBuilder &Builder,
+ bool TakeArgs);
+
+ ~TemplateArgumentList();
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &get(unsigned Idx) const {
+ assert(Idx < NumFlatArguments && "Invalid template argument index");
+ return getFlatArgumentList()[Idx];
+ }
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+
+ /// \brief Retrieve the number of template arguments in this
+ /// template argument list.
+ unsigned size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the number of template arguments in the
+ /// flattened template argument list.
+ unsigned flat_size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the flattened template argument list.
+ const TemplateArgument *getFlatArgumentList() const {
+ return FlatArguments.getPointer();
+ }
+};
+
//===----------------------------------------------------------------------===//
// Kinds of Templates
//===----------------------------------------------------------------------===//
@@ -154,18 +500,110 @@ protected:
TemplateParameterList* TemplateParams;
};
+/// \brief Provides information about a function template specialization,
+/// which is a FunctionDecl that has been explicitly specialization or
+/// instantiated from a function template.
+class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
+public:
+ /// \brief The function template specialization that this structure
+ /// describes.
+ FunctionDecl *Function;
+
+ /// \brief The function template from which this function template
+ /// specialization was generated.
+ ///
+ /// The bit will be 0 for an implicit instantiation, 1 for an explicit
+ /// specialization.
+ llvm::PointerIntPair<FunctionTemplateDecl *, 1> Template;
+
+ /// \brief The template arguments used to produce the function template
+ /// specialization from the function template.
+ const TemplateArgumentList *TemplateArguments;
+
+ /// \brief Retrieve the template from which this function was specialized.
+ FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
+
+ /// \brief Determine whether this is an explicit specialization.
+ bool isExplicitSpecialization() const { return Template.getInt(); }
+
+ /// \brief Set whether this is an explicit specialization or an implicit
+ /// instantiation.
+ void setExplicitSpecialization(bool ES) {
+ Template.setInt(ES);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, TemplateArguments->getFlatArgumentList(),
+ TemplateArguments->flat_size());
+ }
+
+ static void
+ Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs) {
+ ID.AddInteger(NumTemplateArgs);
+ for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ TemplateArgs[Arg].Profile(ID);
+ }
+};
+
/// Declaration of a template function.
-class FunctionTemplateDecl : public TemplateDecl {
+class FunctionTemplateDecl : public TemplateDecl {
protected:
+ /// \brief Data that is common to all of the declarations of a given
+ /// function template.
+ struct Common {
+ /// \brief The function template specializations for this function
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+ };
+
+ /// \brief A pointer to the previous declaration (if this is a redeclaration)
+ /// or to the data that is common to all declarations of this function
+ /// template.
+ llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
+
+ /// \brief Retrieves the "common" pointer shared by all
+ /// (re-)declarations of the same function template. Calling this routine
+ /// may implicitly allocate memory for the common pointer.
+ Common *getCommonPtr();
+
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+ : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
+ CommonOrPrev((Common*)0) { }
+
public:
- /// Get the underling function declaration of the template.
+ void Destroy(ASTContext &C);
+
+ /// Get the underlying function declaration of the template.
FunctionDecl *getTemplatedDecl() const {
return static_cast<FunctionDecl*>(TemplatedDecl);
}
+ /// \brief Retrieve the set of function template specializations of this
+ /// function template.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+ return getCommonPtr()->Specializations;
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ const FunctionTemplateDecl *getPreviousDeclaration() const {
+ return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ FunctionTemplateDecl *getPreviousDeclaration() {
+ return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ }
+
+ /// \brief Set the previous declaration of this function template.
+ void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
+ if (Prev)
+ CommonOrPrev = Prev;
+ }
+
/// Create a template function node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -396,352 +834,6 @@ public:
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
};
-/// \brief Represents a template argument within a class template
-/// specialization.
-class TemplateArgument {
- union {
- uintptr_t TypeOrValue;
- struct {
- char Value[sizeof(llvm::APSInt)];
- void *Type;
- } Integer;
- struct {
- TemplateArgument *Args;
- unsigned NumArgs;
- bool CopyArgs;
- } Args;
- };
-
- /// \brief Location of the beginning of this template argument.
- SourceLocation StartLoc;
-
-public:
- /// \brief The type of template argument we're storing.
- enum ArgKind {
- Null = 0,
- /// The template argument is a type. Its value is stored in the
- /// TypeOrValue field.
- Type = 1,
- /// The template argument is a declaration
- Declaration = 2,
- /// The template argument is an integral value stored in an llvm::APSInt.
- Integral = 3,
- /// The template argument is a value- or type-dependent expression
- /// stored in an Expr*.
- Expression = 4,
-
- /// The template argument is actually a parameter pack. Arguments are stored
- /// in the Args struct.
- Pack = 5
- } Kind;
-
- /// \brief Construct an empty, invalid template argument.
- TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
-
- /// \brief Construct a template type argument.
- TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
- TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
- // FIXME: Need to be sure we have the "canonical" declaration!
- TypeOrValue = reinterpret_cast<uintptr_t>(D);
- StartLoc = Loc;
- }
-
- /// \brief Construct an integral constant template argument.
- TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
- QualType Type)
- : Kind(Integral) {
- new (Integer.Value) llvm::APSInt(Value);
- Integer.Type = Type.getAsOpaquePtr();
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that is an expression.
- ///
- /// This form of template argument only occurs in template argument
- /// lists used for dependent types and for expression; it will not
- /// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E);
-
- /// \brief Copy constructor for a template argument.
- TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
- if (Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else if (Kind == Pack) {
- Args.NumArgs = Other.Args.NumArgs;
- Args.Args = new TemplateArgument[Args.NumArgs];
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I] = Other.Args.Args[I];
- }
- else
- TypeOrValue = Other.TypeOrValue;
- StartLoc = Other.StartLoc;
- }
-
- TemplateArgument& operator=(const TemplateArgument& Other) {
- // FIXME: Does not provide the strong guarantee for exception
- // safety.
- using llvm::APSInt;
-
- // FIXME: Handle Packs
- assert(Kind != Pack && "FIXME: Handle packs");
- assert(Other.Kind != Pack && "FIXME: Handle packs");
-
- if (Kind == Other.Kind && Kind == Integral) {
- // Copy integral values.
- *this->getAsIntegral() = *Other.getAsIntegral();
- Integer.Type = Other.Integer.Type;
- } else {
- // Destroy the current integral value, if that's what we're holding.
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
-
- Kind = Other.Kind;
-
- if (Other.Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else
- TypeOrValue = Other.TypeOrValue;
- }
- StartLoc = Other.StartLoc;
-
- return *this;
- }
-
- ~TemplateArgument() {
- using llvm::APSInt;
-
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
- else if (Kind == Pack && Args.CopyArgs)
- delete[] Args.Args;
- }
-
- /// \brief Return the kind of stored template argument.
- ArgKind getKind() const { return Kind; }
-
- /// \brief Determine whether this template argument has no value.
- bool isNull() const { return Kind == Null; }
-
- /// \brief Retrieve the template argument as a type.
- QualType getAsType() const {
- if (Kind != Type)
- return QualType();
-
- return QualType::getFromOpaquePtr(
- reinterpret_cast<void*>(TypeOrValue));
- }
-
- /// \brief Retrieve the template argument as a declaration.
- Decl *getAsDecl() const {
- if (Kind != Declaration)
- return 0;
- return reinterpret_cast<Decl *>(TypeOrValue);
- }
-
- /// \brief Retrieve the template argument as an integral value.
- llvm::APSInt *getAsIntegral() {
- if (Kind != Integral)
- return 0;
- return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
- }
-
- const llvm::APSInt *getAsIntegral() const {
- return const_cast<TemplateArgument*>(this)->getAsIntegral();
- }
-
- /// \brief Retrieve the type of the integral value.
- QualType getIntegralType() const {
- if (Kind != Integral)
- return QualType();
-
- return QualType::getFromOpaquePtr(Integer.Type);
- }
-
- void setIntegralType(QualType T) {
- assert(Kind == Integral &&
- "Cannot set the integral type of a non-integral template argument");
- Integer.Type = T.getAsOpaquePtr();
- };
-
- /// \brief Retrieve the template argument as an expression.
- Expr *getAsExpr() const {
- if (Kind != Expression)
- return 0;
-
- return reinterpret_cast<Expr *>(TypeOrValue);
- }
-
- /// \brief Iterator that traverses the elements of a template argument pack.
- typedef const TemplateArgument * pack_iterator;
-
- /// \brief Iterator referencing the first argument of a template argument
- /// pack.
- pack_iterator pack_begin() const {
- assert(Kind == Pack);
- return Args.Args;
- }
-
- /// \brief Iterator referencing one past the last argument of a template
- /// argument pack.
- pack_iterator pack_end() const {
- assert(Kind == Pack);
- return Args.Args + Args.NumArgs;
- }
-
- /// \brief The number of template arguments in the given template argument
- /// pack.
- unsigned pack_size() const {
- assert(Kind == Pack);
- return Args.NumArgs;
- }
-
- /// \brief Retrieve the location where the template argument starts.
- SourceLocation getLocation() const { return StartLoc; }
-
- /// \brief Construct a template argument pack.
- void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
-
- /// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Kind);
- switch (Kind) {
- case Null:
- break;
-
- case Type:
- getAsType().Profile(ID);
- break;
-
- case Declaration:
- ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
- break;
-
- case Integral:
- getAsIntegral()->Profile(ID);
- getIntegralType().Profile(ID);
- break;
-
- case Expression:
- // FIXME: We need a canonical representation of expressions.
- ID.AddPointer(getAsExpr());
- break;
-
- case Pack:
- ID.AddInteger(Args.NumArgs);
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I].Profile(ID);
- }
- }
-};
-
-/// \brief A helper class for making template argument lists.
-class TemplateArgumentListBuilder {
- TemplateArgument *StructuredArgs;
- unsigned MaxStructuredArgs;
- unsigned NumStructuredArgs;
-
- TemplateArgument *FlatArgs;
- unsigned MaxFlatArgs;
- unsigned NumFlatArgs;
-
- bool AddingToPack;
- unsigned PackBeginIndex;
-
-public:
- TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
- unsigned NumTemplateArgs)
- : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
- NumStructuredArgs(0), FlatArgs(0),
- MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
- AddingToPack(false), PackBeginIndex(0) { }
-
- void Append(const TemplateArgument& Arg);
- void BeginPack();
- void EndPack();
-
- void ReleaseArgs();
-
- unsigned flatSize() const {
- return NumFlatArgs;
- }
- const TemplateArgument *getFlatArguments() const {
- return FlatArgs;
- }
-
- unsigned structuredSize() const {
- // If we don't have any structured args, just reuse the flat size.
- if (!StructuredArgs)
- return flatSize();
-
- return NumStructuredArgs;
- }
- const TemplateArgument *getStructuredArguments() const {
- // If we don't have any structured args, just reuse the flat args.
- if (!StructuredArgs)
- return getFlatArguments();
-
- return StructuredArgs;
- }
-};
-
-/// \brief A template argument list.
-///
-/// FIXME: In the future, this class will be extended to support
-/// variadic templates and member templates, which will make some of
-/// the function names below make more sense.
-class TemplateArgumentList {
- /// \brief The template argument list.
- ///
- /// The integer value will be non-zero to indicate that this
- /// template argument list does not own the pointer.
- llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
-
- /// \brief The number of template arguments in this template
- /// argument list.
- unsigned NumFlatArguments;
-
- llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
- unsigned NumStructuredArguments;
-
-public:
- TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool TakeArgs);
-
- ~TemplateArgumentList();
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumFlatArguments && "Invalid template argument index");
- return getFlatArgumentList()[Idx];
- }
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
-
- /// \brief Retrieve the number of template arguments in this
- /// template argument list.
- unsigned size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the number of template arguments in the
- /// flattened template argument list.
- unsigned flat_size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the flattened template argument list.
- const TemplateArgument *getFlatArgumentList() const {
- return FlatArguments.getPointer();
- }
-};
-
// \brief Describes the kind of template specialization that a
// particular template specialization declaration represents.
enum TemplateSpecializationKind {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 2ed91124758d..6a1046e6d03f 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -124,7 +124,7 @@ public:
/// with location to warn on and the source range[s] to report with the
/// warning.
bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
- SourceRange &R2, ASTContext &Context) const;
+ SourceRange &R2) const;
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
/// incomplete type other than void. Nonarray expressions that can be lvalues:
@@ -467,9 +467,9 @@ class FloatingLiteral : public Expr {
bool IsExact : 1;
SourceLocation Loc;
public:
- FloatingLiteral(const llvm::APFloat &V, bool* isexact,
+ FloatingLiteral(const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L)
- : Expr(FloatingLiteralClass, Type), Value(V), IsExact(*isexact), Loc(L) {}
+ : Expr(FloatingLiteralClass, Type), Value(V), IsExact(isexact), Loc(L) {}
/// \brief Construct an empty floating-point literal.
explicit FloatingLiteral(EmptyShell Empty)
@@ -2433,9 +2433,6 @@ public:
const Stmt *getBody() const;
Stmt *getBody();
- const Stmt *getBody(ASTContext &C) const { return getBody(); }
- Stmt *getBody(ASTContext &C) { return getBody(); }
-
virtual SourceRange getSourceRange() const {
return SourceRange(getCaretLocation(), getBody()->getLocEnd());
}
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f9f5da129142..7d76a49d1267 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1017,6 +1017,100 @@ public:
virtual StmtIterator child_end();
};
+/// \brief An expression that refers to a C++ template-id, such as
+/// @c isa<FunctionDecl>.
+class TemplateIdRefExpr : public Expr {
+ /// \brief If this template-id was qualified-id, e.g., @c std::sort<int>,
+ /// this nested name specifier contains the @c std::.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief If this template-id was a qualified-id, e.g., @c std::sort<int>,
+ /// this covers the source code range of the @c std::.
+ SourceRange QualifierRange;
+
+ /// \brief The actual template to which this template-id refers.
+ TemplateName Template;
+
+ /// \brief The source location of the template name.
+ SourceLocation TemplateNameLoc;
+
+ /// \brief The source location of the left angle bracket ('<');
+ SourceLocation LAngleLoc;
+
+ /// \brief The source location of the right angle bracket ('>');
+ SourceLocation RAngleLoc;
+
+ /// \brief The number of template arguments in TemplateArgs.
+ unsigned NumTemplateArgs;
+
+ TemplateIdRefExpr(QualType T,
+ NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ TemplateName Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc);
+
+public:
+ static TemplateIdRefExpr *
+ Create(ASTContext &Context, QualType T,
+ NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ TemplateName Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc, const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs, SourceLocation RAngleLoc);
+
+ void Destroy(ASTContext &Context);
+
+ /// \brief Retrieve the nested name specifier used to qualify the name of
+ /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL
+ /// if this template-id was an unqualified-id.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Retrieve the source range describing the nested name specifier
+ /// used to qualified the name of this template-id, if the name was qualified.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Retrieve the name of the template referenced, e.g., "sort" in
+ /// @c std::sort<int>;
+ TemplateName getTemplateName() const { return Template; }
+
+ /// \brief Retrieve the location of the name of the template referenced, e.g.,
+ /// the location of "sort" in @c std::sort<int>.
+ SourceLocation getTemplateNameLoc() const { return TemplateNameLoc; }
+
+ /// \brief Retrieve the location of the left angle bracket following the
+ /// template name ('<').
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgument *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgument *>(this + 1);
+ }
+
+ /// \brief Retrieve the number of template arguments provided as part of this
+ /// template-id.
+ unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
+
+ /// \brief Retrieve the location of the right angle bracket following the
+ /// template arguments ('>').
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(Qualifier? QualifierRange.getBegin() : TemplateNameLoc,
+ RAngleLoc);
+ }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == TemplateIdRefExprClass;
+ }
+ static bool classof(const TemplateIdRefExpr *) { return true; }
+};
+
class CXXExprWithTemporaries : public Expr {
Stmt *SubExpr;
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 4219bd507a90..6f862a55d4ba 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -18,6 +18,7 @@
#include "clang/AST/Type.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
+#include <vector>
namespace clang {
class ASTConsumer;
@@ -57,6 +58,14 @@ public:
virtual ~ExternalASTSource();
+ /// \brief Reads the source ranges that correspond to comments from
+ /// an external AST source.
+ ///
+ /// \param Comments the contents of this vector will be
+ /// replaced with the sorted set of source ranges corresponding to
+ /// comments in the source code.
+ virtual void ReadComments(std::vector<SourceRange> &Comments) = 0;
+
/// \brief Resolve a type ID into a type, potentially building a new
/// type.
virtual QualType GetType(uint32_t ID) = 0;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 4eea1031f063..b304cc8e8a04 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -28,6 +28,7 @@ class NamespaceDecl;
class IdentifierInfo;
class PrintingPolicy;
class Type;
+class LangOptions;
/// \brief Represents a C++ nested name specifier, such as
/// "::std::vector<int>::".
@@ -175,7 +176,7 @@ public:
/// \brief Dump the nested name specifier to standard output to aid
/// in debugging.
- void dump();
+ void dump(const LangOptions &LO);
};
}
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 385602b1fb9c..6ad3a6bcc276 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -22,6 +22,7 @@ namespace clang {
class Stmt;
class TagDecl;
+class LangOptions;
class PrinterHelper {
public:
@@ -33,16 +34,15 @@ public:
/// declarations should be printed.
struct PrintingPolicy {
/// \brief Create a default printing policy for C.
- PrintingPolicy()
- : Indentation(2), CPlusPlus(false), SuppressSpecifiers(false),
+ PrintingPolicy(const LangOptions &LO)
+ : Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
SuppressTag(false), SuppressTagKind(false), Dump(false) { }
/// \brief The number of spaces to use to indent each line.
unsigned Indentation : 8;
- /// \brief Whether we're printing C++ code (otherwise, we're
- /// printing C code).
- bool CPlusPlus : 1;
+ /// \brief What language we're printing.
+ const LangOptions &LangOpts;
/// \brief Whether we should suppress printing of the actual specifiers for
/// the given type or declaration.
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index a8688f62e2d9..0a64dafd4e2c 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -187,14 +187,14 @@ public:
/// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
/// back to its original source language syntax.
void dumpPretty(ASTContext& Context) const;
- void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper = 0,
- const PrintingPolicy &Policy = PrintingPolicy(),
+ void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
unsigned Indentation = 0) const {
printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
}
- void printPretty(llvm::raw_ostream &OS, ASTContext& Context,
- PrinterHelper *Helper = 0,
- const PrintingPolicy &Policy = PrintingPolicy(),
+ void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
+ PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
unsigned Indentation = 0) const;
/// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index ab6524663d63..a95a62731186 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -9,7 +9,7 @@
//
// This file defines the AST Node info database.
//
-//===----------------------------------------------------------------------===//
+//===---------------------------------------------------------------------===//
#ifndef FIRST_STMT
#define FIRST_STMT(CLASS)
@@ -123,6 +123,7 @@ EXPR(UnresolvedFunctionNameExpr , Expr)
EXPR(UnaryTypeTraitExpr , Expr)
EXPR(QualifiedDeclRefExpr , DeclRefExpr)
EXPR(UnresolvedDeclRefExpr , Expr)
+EXPR(TemplateIdRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 321b1f204fcf..a00c0c4ff1c4 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -188,7 +188,8 @@ public:
getAsStringInternal(S, Policy);
return S;
}
- void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const;
+ void getAsStringInternal(std::string &Str,
+ const PrintingPolicy &Policy) const;
void dump(const char *s) const;
void dump() const;
@@ -375,6 +376,7 @@ public:
bool isFunctionProtoType() const { return getAsFunctionProtoType() != 0; }
bool isPointerType() const;
bool isBlockPointerType() const;
+ bool isVoidPointerType() const;
bool isReferenceType() const;
bool isLValueReferenceType() const;
bool isRValueReferenceType() const;
@@ -585,7 +587,7 @@ public:
TypeKind(K) {}
Kind getKind() const { return TypeKind; }
- const char *getName(bool CPlusPlus) const;
+ const char *getName(const LangOptions &LO) const;
virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 65ac0b53027c..5926229e517c 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -62,7 +62,6 @@ protected:
ASTContext &getContext() const;
public:
- // virtual MemExtent getExtent(MemRegionManager& mrm) const = 0;
virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
virtual MemRegionManager* getMemRegionManager() const = 0;
@@ -73,17 +72,25 @@ public:
bool hasStackStorage() const;
+ bool hasParametersStorage() const;
+
+ bool hasGlobalsStorage() const;
+
+ bool hasGlobalsOrParametersStorage() const;
+
bool hasHeapStorage() const;
bool hasHeapOrStackStorage() const;
- virtual void print(llvm::raw_ostream& os) const;
+ virtual void print(llvm::raw_ostream& os) const;
+
+ void printStdErr() const;
Kind getKind() const { return kind; }
template<typename RegionTy> const RegionTy* getAs() const;
- virtual bool isBoundable() const { return true; }
+ virtual bool isBoundable() const { return false; }
static bool classof(const MemRegion*) { return true; }
};
@@ -104,8 +111,6 @@ protected:
}
public:
- //RegionExtent getExtent() const { return UndefinedExtent(); }
-
void Profile(llvm::FoldingSetNodeID& ID) const;
bool isBoundable() const { return false; }
@@ -315,6 +320,8 @@ public:
return Str->getType();
}
+ bool isBoundable() const { return false; }
+
void Profile(llvm::FoldingSetNodeID& ID) const {
ProfileRegion(ID, Str, superRegion);
}
@@ -384,7 +391,9 @@ public:
QualType getValueType(ASTContext& C) const {
return C.getCanonicalType(CL->getType());
}
-
+
+ bool isBoundable() const { return !CL->isFileScope(); }
+
void Profile(llvm::FoldingSetNodeID& ID) const;
void print(llvm::raw_ostream& os) const;
@@ -584,15 +593,17 @@ class MemRegionManager {
llvm::BumpPtrAllocator& A;
llvm::FoldingSet<MemRegion> Regions;
- MemSpaceRegion* globals;
- MemSpaceRegion* stack;
- MemSpaceRegion* heap;
- MemSpaceRegion* unknown;
- MemSpaceRegion* code;
+ MemSpaceRegion *globals;
+ MemSpaceRegion *stack;
+ MemSpaceRegion *stackArguments;
+ MemSpaceRegion *heap;
+ MemSpaceRegion *unknown;
+ MemSpaceRegion *code;
public:
MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), globals(0), stack(0), heap(0), unknown(0), code(0) {}
+ : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
+ unknown(0), code(0) {}
~MemRegionManager() {}
@@ -600,24 +611,28 @@ public:
/// getStackRegion - Retrieve the memory region associated with the
/// current stack frame.
- MemSpaceRegion* getStackRegion();
+ MemSpaceRegion *getStackRegion();
+
+ /// getStackArgumentsRegion - Retrieve the memory region associated with
+ /// function/method arguments of the current stack frame.
+ MemSpaceRegion *getStackArgumentsRegion();
/// getGlobalsRegion - Retrieve the memory region associated with
/// all global variables.
- MemSpaceRegion* getGlobalsRegion();
+ MemSpaceRegion *getGlobalsRegion();
/// getHeapRegion - Retrieve the memory region associated with the
/// generic "heap".
- MemSpaceRegion* getHeapRegion();
+ MemSpaceRegion *getHeapRegion();
/// getUnknownRegion - Retrieve the memory region associated with unknown
/// memory space.
- MemSpaceRegion* getUnknownRegion();
+ MemSpaceRegion *getUnknownRegion();
- MemSpaceRegion* getCodeRegion();
+ MemSpaceRegion *getCodeRegion();
/// getAllocaRegion - Retrieve a region associated with a call to alloca().
- AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt);
+ AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt);
/// getCompoundLiteralRegion - Retrieve the region associated with a
/// given CompoundLiteral.
@@ -785,8 +800,12 @@ template <> struct MemRegionManagerTrait<VarRegion> {
typedef MemRegion SuperRegionTy;
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
const VarDecl *d) {
- return d->hasLocalStorage() ? MRMgr.getStackRegion()
- : MRMgr.getGlobalsRegion();
+ if (d->hasLocalStorage()) {
+ return isa<ParmVarDecl>(d) || isa<ImplicitParamDecl>(d)
+ ? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion();
+ }
+
+ return MRMgr.getGlobalsRegion();
}
};
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h
index 36137fb117b3..4bc5e27aacf0 100644
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ b/include/clang/Analysis/PathSensitive/SVals.h
@@ -110,6 +110,8 @@ public:
/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
/// return that expression. Otherwise return NULL.
const SymExpr *getAsSymbolicExpression() const;
+
+ const MemRegion *getAsRegion() const;
void print(llvm::raw_ostream& OS) const;
void printStdErr() const;
diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h
index de318a0f03e8..36d1df2150df 100644
--- a/include/clang/Analysis/PathSensitive/ValueManager.h
+++ b/include/clang/Analysis/PathSensitive/ValueManager.h
@@ -67,12 +67,17 @@ public:
const void* SymbolTag = 0) {
return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
}
-
+
/// makeZeroVal - Construct an SVal representing '0' for the specified type.
SVal makeZeroVal(QualType T);
- /// GetRegionValueSymbolVal - make a unique symbol for value of R.
- SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType());
+ /// getRegionValueSymbolVal - make a unique symbol for value of R.
+ SVal getRegionValueSymbolVal(const MemRegion *R, QualType T = QualType());
+
+ SVal getRegionValueSymbolValOrUnknown(const MemRegion *R, QualType T) {
+ return SymMgr.canSymbolicate(T) ? getRegionValueSymbolVal(R, T)
+ : UnknownVal();
+ }
SVal getConjuredSymbolVal(const Expr *E, unsigned Count);
SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count);
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 327db00e0b28..a8dbd68df10f 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -45,6 +45,10 @@ def err_drv_no_linker_llvm_support : Error<
"'%0': unable to pass LLVM bit-code files to linker">;
def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
+def err_drv_command_failed : Error<
+ "%0 command failed with exit code %1 (use -v to see invocation)">;
+def err_drv_command_signalled : Error<
+ "%0 command failed due to signal %1 (use -v to see invocation)">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 4ba1083089e6..b1a73d05a45f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -287,6 +287,8 @@ def err_distant_exception_spec : Error<
def err_incomplete_in_exception_spec : Error<
"%select{|pointer to |reference to }1incomplete type %0 is not allowed "
"in exception specification">;
+def err_mismatched_exception_spec : Error<
+ "exception specification in declaration does not match previous declaration">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@@ -398,6 +400,10 @@ def err_init_reference_member_uninitialized : Error<
def note_uninit_reference_member : Note<
"uninitialized reference member is here">;
+// C++0x decltype
+def err_cannot_determine_declared_type_of_overloaded_function : Error<
+ "can't determine the declared type of an overloaded function">;
+
// C++0x auto
def err_auto_variable_cannot_appear_in_own_initializer : Error<
"variable %0 declared with 'auto' type cannot appear in its own initializer">;
@@ -835,6 +841,12 @@ def note_function_template_spec_here : Note<
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
+def note_explicit_template_arg_substitution_here : Note<
+ "while substituting explicitly-specified template arguments into function "
+ "template %f, here">;
+def note_function_template_deduction_instantiation_here : Note<
+ "while substituting deduced template arguments into function template %0, "
+ "here">;
def note_partial_spec_deduct_instantiation_here : Note<
"during template argument deduction for class template partial "
"specialization %0, here">;
@@ -1070,6 +1082,8 @@ def err_array_star_outside_prototype : Error<
"star modifier used outside of function prototype">;
def err_illegal_decl_pointer_to_reference : Error<
"'%0' declared as a pointer to a reference">;
+def err_illegal_decl_mempointer_to_reference : Error<
+ "'%0' declared as a member pointer to a reference">;
def err_illegal_decl_mempointer_to_void : Error<
"'%0' declared as a member pointer to void">;
def err_illegal_decl_mempointer_in_nonclass : Error<
@@ -1207,6 +1221,10 @@ def err_typecheck_sub_ptr_object : Error<
"subtraction of pointer %0 requires pointee to be a complete object type">;
def err_typecheck_sub_ptr_compatible : Error<
"%0 and %1 are not pointers to compatible types">;
+def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
+ "ordered comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
+ "ordered comparison of function pointers (%0 and %1)">;
def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
"comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
@@ -1579,6 +1597,12 @@ def err_overload_multiple_match : Error<
def err_only_constructors_take_base_inits : Error<
"only constructors take base initializers">;
+def error_multiple_mem_initialization : Error <
+ "multiple initializations given for non-static member '%0'">;
+
+def error_multiple_base_initialization : Error <
+ "multiple initializations given for base %0">;
+
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
@@ -1588,6 +1612,8 @@ def err_base_init_does_not_name_class : Error<
def err_base_init_direct_and_virtual : Error<
"base class initializer %0 names both a direct base class and an "
"inherited virtual base class">;
+def err_not_direct_base_or_virtual : Error<
+ "type %0 is not a direct or virtual base of '%1'">;
def err_in_class_initializer_non_integral_type : Error<
"in-class initializer has non-integral, non-enumeration type %0">;
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 543a0fff8e7b..26688bf56728 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -22,6 +22,7 @@ class LangOptions {
public:
unsigned Trigraphs : 1; // Trigraphs in source files.
unsigned BCPLComment : 1; // BCPL-style '//' comments.
+ unsigned Bool : 1; // 'bool', 'true', 'false' keywords.
unsigned DollarIdents : 1; // '$' allowed in identifiers.
unsigned AsmPreprocessor : 1; // Preprocessor in asm mode.
unsigned GNUMode : 1; // True in gnu99 mode false in c99 mode (etc)
@@ -84,12 +85,16 @@ public:
unsigned OpenCL : 1; // OpenCL C99 language extensions.
-
private:
- unsigned GC : 2; // Objective-C Garbage Collection modes. We declare
- // this enum as unsigned because MSVC insists on making enums
- // signed. Set/Query this value using accessors.
+ unsigned GC : 2; // Objective-C Garbage Collection modes. We
+ // declare this enum as unsigned because MSVC
+ // insists on making enums signed. Set/Query
+ // this value using accessors.
unsigned SymbolVisibility : 3; // Symbol's visibility.
+ unsigned StackProtector : 2; // Whether stack protectors are on. We declare
+ // this enum as unsigned because MSVC insists
+ // on making enums signed. Set/Query this
+ // value using accessors.
/// The user provided name for the "main file", if non-null. This is
/// useful in situations where the input file name does not match
@@ -100,6 +105,7 @@ public:
unsigned InstantiationDepth; // Maximum template instantiation depth.
enum GCMode { NonGC, GCOnly, HybridGC };
+ enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
enum VisibilityMode {
Default,
Protected,
@@ -107,7 +113,7 @@ public:
};
LangOptions() {
- Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0;
+ Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
GNUMode = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
@@ -116,7 +122,7 @@ public:
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
LaxVectorConversions = 1;
HeinousExtensions = 0;
- AltiVec = OpenCL = 0;
+ AltiVec = OpenCL = StackProtector = 0;
SymbolVisibility = (unsigned) Default;
@@ -152,6 +158,13 @@ public:
GCMode getGCMode() const { return (GCMode) GC; }
void setGCMode(GCMode m) { GC = (unsigned) m; }
+ StackProtectorMode getStackProtectorMode() const {
+ return static_cast<StackProtectorMode>(StackProtector);
+ }
+ void setStackProtectorMode(StackProtectorMode m) {
+ StackProtector = static_cast<unsigned>(m);
+ }
+
const char *getMainFileName() const { return MainFileName; }
void setMainFileName(const char *Name) { MainFileName = Name; }
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index a59c60b00224..537d553bc2d1 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -76,7 +76,8 @@ public:
UnsignedLongLong
};
protected:
- IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType;
+ IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
+ Int64Type;
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@@ -86,6 +87,7 @@ public:
}
IntType getIntPtrType() const { return IntPtrType; }
IntType getWCharType() const { return WCharType; }
+ IntType getInt64Type() const { return Int64Type; }
/// getPointerWidth - Return the width of pointers on this target, for the
/// specified address space.
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index ed0270acd0dd..e711996cf26d 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -224,7 +224,7 @@ KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , KEYCXX|BOOLSUPPORT)
+KEYWORD(bool , BOOLSUPPORT)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@@ -232,7 +232,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
-KEYWORD(false , KEYCXX|BOOLSUPPORT)
+KEYWORD(false , BOOLSUPPORT)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@@ -246,7 +246,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
-KEYWORD(true , KEYCXX|BOOLSUPPORT)
+KEYWORD(true , BOOLSUPPORT)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 5812da1b562e..12b74d51473e 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -18,6 +18,7 @@
#include <string>
namespace llvm {
+ class LLVMContext;
class Module;
}
@@ -34,7 +35,8 @@ namespace clang {
CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
const std::string &ModuleName,
- const CompileOptions &CO);
+ const CompileOptions &CO,
+ llvm::LLVMContext& C);
}
#endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index b9bf671db2bd..ceef189f7b7e 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -75,6 +75,8 @@ protected:
public:
virtual ~Action();
+ const char *getClassName() const { return Action::getClassName(getKind()); }
+
ActionClass getKind() const { return Kind; }
types::ID getType() const { return Type; }
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 84e0329a375e..a9c890b0b899 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -83,6 +83,8 @@ namespace driver {
/// \arg Claim Whether the argument should be claimed, if it exists.
Arg *getLastArg(options::ID Id, bool Claim=true) const;
Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const;
+ Arg *getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
+ bool Claim=true) const;
/// getArgString - Return the input argument string at \arg Index.
virtual const char *getArgString(unsigned Index) const = 0;
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 4985f30ad553..6414ef13692b 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -32,10 +32,10 @@ namespace driver {
/// invocation.
class Compilation {
/// The driver we were created by.
- Driver &TheDriver;
+ const Driver &TheDriver;
/// The default tool chain.
- ToolChain &DefaultToolChain;
+ const ToolChain &DefaultToolChain;
/// The original (untranslated) input argument list.
InputArgList *Args;
@@ -56,7 +56,8 @@ class Compilation {
ArgStringList ResultFiles;
public:
- Compilation(Driver &D, ToolChain &DefaultToolChain, InputArgList *Args);
+ Compilation(const Driver &D, const ToolChain &DefaultToolChain,
+ InputArgList *Args);
~Compilation();
const Driver &getDriver() const { return TheDriver; }
@@ -69,6 +70,11 @@ public:
const ActionList &getActions() const { return Actions; }
JobList &getJobs() { return Jobs; }
+ const JobList &getJobs() const { return Jobs; }
+
+ const ArgStringList &getTempFiles() const { return TempFiles; }
+
+ const ArgStringList &getResultFiles() const { return ResultFiles; }
/// getArgsForToolChain - Return the derived argument list for the
/// tool chain \arg TC (or the default tool chain, if TC is not
@@ -89,11 +95,6 @@ public:
return Name;
}
- /// Execute - Execute the compilation jobs and return an
- /// appropriate exit code.
- int Execute() const;
-
-private:
/// CleanupFileList - Remove the files in the given list.
///
/// \param IssueErrors - Report failures as errors.
@@ -103,22 +104,26 @@ private:
/// PrintJob - Print one job in -### format.
///
- /// OS - The stream to print on.
- /// J - The job to print.
- /// Terminator - A string to print at the end of the line.
- /// Quote - Should separate arguments be quoted.
+ /// \param OS - The stream to print on.
+ /// \param J - The job to print.
+ /// \param Terminator - A string to print at the end of the line.
+ /// \param Quote - Should separate arguments be quoted.
void PrintJob(llvm::raw_ostream &OS, const Job &J,
const char *Terminator, bool Quote) const;
/// ExecuteCommand - Execute an actual command.
///
+ /// \param FailingCommand - For non-zero results, this will be set to the
+ /// Command which failed, if any.
/// \return The result code of the subprocess.
- int ExecuteCommand(const Command &C) const;
+ int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
/// ExecuteJob - Execute a single job.
///
+ /// \param FailingCommand - For non-zero results, this will be set to the
+ /// Command which failed.
/// \return The accumulated result code of the job.
- int ExecuteJob(const Job &J) const;
+ int ExecuteJob(const Job &J, const Command *&FailingCommand) const;
};
} // end namespace driver
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 66e3b9787594..c0def2bcca29 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -161,6 +161,14 @@ public:
/// \arg C - The compilation that is being built.
void BuildJobs(Compilation &C) const;
+ /// ExecuteCompilation - Execute the compilation according to the command line
+ /// arguments and return an appropriate exit code.
+ ///
+ /// This routine handles additional processing that must be done in addition
+ /// to just running the subprocesses, for example reporting errors, removing
+ /// temporary files, etc.
+ int ExecuteCompilation(const Compilation &C) const;
+
/// @}
/// @name Helper Methods
/// @{
diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h
index 3485f5fbfd76..b5e80b0c3bfe 100644
--- a/include/clang/Driver/HostInfo.h
+++ b/include/clang/Driver/HostInfo.h
@@ -69,6 +69,8 @@ public:
const HostInfo *createDarwinHostInfo(const Driver &D,
const llvm::Triple& Triple);
+const HostInfo *createOpenBSDHostInfo(const Driver &D,
+ const llvm::Triple& Triple);
const HostInfo *createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createDragonFlyHostInfo(const Driver &D,
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index f60f5146414c..a23babdbb31a 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -52,6 +52,9 @@ public:
/// Command - An executable path/name and argument vector to
/// execute.
class Command : public Job {
+ /// Source - The action which caused the creation of this job.
+ const Action &Source;
+
/// The executable to run.
const char *Executable;
@@ -60,9 +63,14 @@ class Command : public Job {
ArgStringList Arguments;
public:
- Command(const char *_Executable, const ArgStringList &_Arguments);
+ Command(const Action &_Source, const char *_Executable,
+ const ArgStringList &_Arguments);
+
+ /// getSource - Return the Action which caused the creation of this job.
+ const Action &getSource() const { return Source; }
const char *getExecutable() const { return Executable; }
+
const ArgStringList &getArguments() const { return Arguments; }
static bool classof(const Job *J) {
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index abd07a92b1a2..af108a85ebdd 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -420,7 +420,7 @@ OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-show-column", fno_show_column, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-stack-protector", fno_stack_protector, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-strict-aliasing", fno_strict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-unit-at-a-time", fno_unit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-unwind-tables", fno_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -450,7 +450,8 @@ OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fstack-protector", fstack_protector, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fstack-protector-all", fstack_protector_all, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fstack-protector", fstack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fstrict-aliasing", fstrict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsyntax-only", fsyntax_only, Flag, INVALID, INVALID, "d", 0, 0, 0)
OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 04365d7c78d8..be4520262558 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -20,6 +20,7 @@
namespace llvm {
class Module;
+ class LLVMContext;
namespace sys { class Path; }
}
namespace clang {
@@ -79,7 +80,8 @@ ASTConsumer *CreateBackendConsumer(BackendAction Action,
const LangOptions &Features,
const CompileOptions &CompileOpts,
const std::string &ModuleID,
- llvm::raw_ostream *OS);
+ llvm::raw_ostream *OS,
+ llvm::LLVMContext& C);
// HTML printer: uses the rewriter to convert source code to HTML with
// syntax highlighting suitable for viewing in a web-browser.
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 63222725d529..80aa248a78e6 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -218,7 +218,11 @@ namespace clang {
/// \brief Record code for the original file that was used to
/// generate the precompiled header.
- ORIGINAL_FILE_NAME = 20
+ ORIGINAL_FILE_NAME = 20,
+
+ /// \brief Record code for the sorted array of source ranges where
+ /// comments were encountered in the source code.
+ COMMENT_RANGES = 21
};
/// \brief Record types used within a source manager block.
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index b3ed36434312..8291f4697a8e 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -279,6 +279,12 @@ private:
/// been loaded.
llvm::SmallVector<Selector, 16> SelectorsLoaded;
+ /// \brief A sorted array of source ranges containing comments.
+ SourceRange *Comments;
+
+ /// \brief The number of source ranges in the Comments array.
+ unsigned NumComments;
+
/// \brief The set of external definitions stored in the the PCH
/// file.
llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
@@ -452,6 +458,14 @@ public:
/// build prior to including the precompiled header.
const std::string &getSuggestedPredefines() { return SuggestedPredefines; }
+ /// \brief Reads the source ranges that correspond to comments from
+ /// an external AST source.
+ ///
+ /// \param Comments the contents of this vector will be
+ /// replaced with the sorted set of source ranges corresponding to
+ /// comments in the source code.
+ virtual void ReadComments(std::vector<SourceRange> &Comments);
+
/// \brief Resolve a type ID into a type, potentially building a new
/// type.
virtual QualType GetType(pch::TypeID ID);
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 5cb939547f2c..c663442e64d8 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -166,6 +166,7 @@ private:
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP);
void WritePreprocessor(const Preprocessor &PP);
+ void WriteComments(ASTContext &Context);
void WriteType(const Type *T);
void WriteTypesBlock(ASTContext &Context);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index f229881bfc44..6d5ed72455b9 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Allocator.h"
+#include <vector>
namespace clang {
@@ -35,6 +36,7 @@ class FileEntry;
class HeaderSearch;
class PragmaNamespace;
class PragmaHandler;
+class CommentHandler;
class ScratchBuffer;
class TargetInfo;
class PPCallbacks;
@@ -109,6 +111,10 @@ class Preprocessor {
/// with this preprocessor.
PragmaNamespace *PragmaHandlers;
+ /// \brief Tracks all of the comment handlers that the client registered
+ /// with this preprocessor.
+ std::vector<CommentHandler *> CommentHandlers;
+
/// CurLexer - This is the current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
@@ -301,6 +307,14 @@ public:
/// to remove a handler that has not been registered.
void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
+ /// \brief Add the specified comment handler to the preprocessor.
+ void AddCommentHandler(CommentHandler *Handler);
+
+ /// \brief Remove the specified comment handler.
+ ///
+ /// It is an error to remove a handler that has not been registered.
+ void RemoveCommentHandler(CommentHandler *Handler);
+
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
@@ -791,6 +805,7 @@ public:
void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaComment(Token &CommentTok);
+ void HandleComment(SourceRange Comment);
};
/// PreprocessorFactory - A generic factory interface for lazily creating
@@ -801,6 +816,15 @@ public:
virtual Preprocessor* CreatePreprocessor() = 0;
};
+/// \brief Abstract base class that describes a handler that will receive
+/// source ranges for each of the comments encountered in the source file.
+class CommentHandler {
+public:
+ virtual ~CommentHandler();
+
+ virtual void HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index bfb74748c5f1..d969562977ea 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -152,6 +152,10 @@ public:
/// an empty string if not. This is used for pretty crash reporting.
virtual std::string getDeclName(DeclPtrTy D) { return ""; }
+ /// \brief Invoked for each comment in the source code, providing the source
+ /// range that contains the comment.
+ virtual void ActOnComment(SourceRange Comment) { }
+
//===--------------------------------------------------------------------===//
// Declaration Tracking Callbacks.
//===--------------------------------------------------------------------===//
@@ -1203,7 +1207,9 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -1379,6 +1385,24 @@ public:
return TypeResult();
};
+ /// \brief Form a reference to a template-id (that will refer to a function)
+ /// from a template and a list of template arguments.
+ ///
+ /// This action forms an expression that references the given template-id,
+ /// possibly checking well-formedness of the template arguments. It does not
+ /// imply the declaration of any entity.
+ ///
+ /// \param Template A template whose specialization results in a
+ /// function or a dependent template.
+ virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ return ExprError();
+ }
+
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h
index 59517930de95..987edfa96dd1 100644
--- a/include/clang/Parse/Ownership.h
+++ b/include/clang/Parse/Ownership.h
@@ -574,6 +574,19 @@ namespace clang {
#if !defined(DISABLE_SMART_POINTERS)
friend class moving::ASTMultiMover<Destroyer>;
+#if defined(_MSC_VER)
+ // Last tested with Visual Studio 2008.
+ // Visual C++ appears to have a bug where it does not recognise
+ // the return value from ASTMultiMover<Destroyer>::opeator-> as
+ // being a pointer to ASTMultiPtr. However, the diagnostics
+ // suggest it has the right name, simply that the pointer type
+ // is not convertible to itself.
+ // Either way, a classic C-style hard cast resolves any issue.
+ static ASTMultiPtr* hack(moving::ASTMultiMover<Destroyer> & source) {
+ return (ASTMultiPtr*)source.operator->();
+ }
+#endif
+
ASTMultiPtr(ASTMultiPtr&); // DO NOT IMPLEMENT
// Reference member prevents copy assignment.
@@ -594,7 +607,13 @@ namespace clang {
: Actions(actions), Nodes(nodes), Count(count) {}
/// Move constructor
ASTMultiPtr(moving::ASTMultiMover<Destroyer> mover)
+#if defined(_MSC_VER)
+ // Apply the visual C++ hack supplied above.
+ // Last tested with Visual Studio 2008.
+ : Actions(hack(mover)->Actions), Nodes(hack(mover)->Nodes), Count(hack(mover)->Count) {
+#else
: Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) {
+#endif
mover.release();
}
#else
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index e5f62ec683e3..e2380542ae6f 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -82,7 +82,8 @@ class Parser {
llvm::OwningPtr<PragmaHandler> PackHandler;
llvm::OwningPtr<PragmaHandler> UnusedHandler;
llvm::OwningPtr<PragmaHandler> WeakHandler;
-
+ llvm::OwningPtr<clang::CommentHandler> CommentHandler;
+
/// Whether the '>' token acts as an operator or not. This will be
/// true except when we are parsing an expression within a C++
/// template argument list, where the '>' closes the template
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 12f75ae863a2..2877cc3b7fe7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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;
diff --git a/lib/AST/CFG.cpp b/lib/AST/CFG.cpp
index d7a830726fa4..69852f5fea57 100644
--- a/lib/AST/CFG.cpp
+++ b/lib/AST/CFG.cpp
@@ -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 @@ public:
virtual ~StmtPrinterHelper() {}
+ const LangOptions &getLangOpts() const { return LangOpts; }
void setBlockID(signed i) { CurrentBlock = i; }
void setStmtID(unsigned i) { CurrentStmt = i; }
@@ -1516,7 +1518,10 @@ public:
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 @@ public:
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;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5382ab52ab5b..3d02150b65bf 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -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);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 5815d820aef6..96ba19b9a6b9 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -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));
}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 752218db042a..b8b29528066d 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -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,
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 60a96d0471ab..54f13e14ba65 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -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())
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 2b06e93295bc..12e89cd80d19 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -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) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 165672d50f4e..f1bd1b67d21e 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -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
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index fce88cc0da28..482e1062d88c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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);
}
}
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 18c0f77ab29e..399c30255a8f 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -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");
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 9d765924e02a..eb6b5b725ff5 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -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
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 09522a20863c..90ec4d33fdfe 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -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));
}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index b24e912582d5..bc096bf0d9f3 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -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.
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index b300940824de..fec17fb22352 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -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,
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 3613da77b342..5b671c111fbf 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -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));
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 41536612fec8..4e061a9fbe62 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -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";
}
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 8fbce528fa9a..19d641ee9753 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -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();
+ if (isa<loc::ConcreteInt>(loc))
+ return store;
+
+ 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);
+ // 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 (isHigherOrderRawPtr(T, C))
+ R = ER->getSuperRegion();
+ }
- if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
- return store;
+ 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;
+ // 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();
+ 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();
}
- default:
- assert ("SetSVal for given Loc type not yet implemented.");
- return store;
}
+
+ 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);
}
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index 38ea458a6599..3db96ca9eacb 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -146,7 +146,7 @@ public:
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 @@ public:
// 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()));
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index f4a28e0c19fd..3cca482633ca 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -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 @@ public:
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());
}
diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp
index 0f61a5ee916a..69433d6396a5 100644
--- a/lib/Analysis/CheckDeadStores.cpp
+++ b/lib/Analysis/CheckDeadStores.cpp
@@ -85,7 +85,7 @@ public:
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 @@ public:
// 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;
diff --git a/lib/Analysis/CheckObjCDealloc.cpp b/lib/Analysis/CheckObjCDealloc.cpp
index 2ba7d868e90b..a14ae265128b 100644
--- a/lib/Analysis/CheckObjCDealloc.cpp
+++ b/lib/Analysis/CheckObjCDealloc.cpp
@@ -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)";
diff --git a/lib/Analysis/CheckObjCInstMethSignature.cpp b/lib/Analysis/CheckObjCInstMethSignature.cpp
index 9fec7c1dc111..28814867bd58 100644
--- a/lib/Analysis/CheckObjCInstMethSignature.cpp
+++ b/lib/Analysis/CheckObjCInstMethSignature.cpp
@@ -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();
diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp
index 21dc658dfa1a..0063c40482a0 100644
--- a/lib/Analysis/CheckObjCUnusedIVars.cpp
+++ b/lib/Analysis/CheckObjCUnusedIVars.cpp
@@ -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.
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
index 2b751df830c2..3f8f14dcb0b4 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -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);
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 8b4f5c8f11c1..d9117f5930e6 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -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 << ":";
diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp
index 76d26dd9f02a..a2ce79a2f390 100644
--- a/lib/Analysis/GRExprEngineInternalChecks.cpp
+++ b/lib/Analysis/GRExprEngineInternalChecks.cpp
@@ -566,7 +566,7 @@ public:
if (!FD)
return false;
- const NonNullAttr* Att = FD->getAttr<NonNullAttr>(BR.getContext());
+ const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
if (!Att)
return false;
diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp
index 493edc37bacb..54c0afbff33e 100644
--- a/lib/Analysis/GRState.cpp
+++ b/lib/Analysis/GRState.cpp
@@ -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);
}
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index b0eb37b06524..aead7f43ad8f 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -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) {
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index c8e027579a30..45305403585a 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -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.
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index d45048de1a42..23e8b738b601 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -347,9 +347,6 @@ public:
// 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;
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index 7d1850d73095..d711ce0a225e 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -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;
}
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 5aa756e14be3..cb099862f055 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -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);
}
}
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index d13ffa38213e..3810c49f71f3 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -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;
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index a513cb16886e..ba7f190408b2 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -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;
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 9910e28fcda9..3f7d9a31c61e 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -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 @@ public:
} // 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,104 +900,12 @@ public:
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 {
public:
@@ -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,96 +960,23 @@ public:
" 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 {
Armv4t,
@@ -1171,33 +1080,20 @@ public:
namespace {
-class DarwinARMTargetInfo : public ARMTargetInfo {
-public:
- DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {
- TLSSupported = false;
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- ARMTargetInfo::getTargetDefines(Opts, Defines);
+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, getTargetTriple());
+ getDarwinIPhoneOSDefines(Defines, 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);
- }
+ DarwinARMTargetInfo(const std::string& triple)
+ : DarwinTargetInfo<ARMTargetInfo>(triple) {}
};
-} // end anonymous namespace
+} // end anonymous namespace.
namespace {
class SparcV8TargetInfo : public TargetInfo {
@@ -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);
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 66b1f17368ea..a919dfa2e32c 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -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));
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 4f9a4caee695..5f3acea767d5 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -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;
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 30c5d28c227e..97391bc620be 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -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);
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 5e872c290dfa..2bf8a222a253 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -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()));
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index f97c62f9d142..2ae7e225ebbf 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -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));
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index a21140765c20..0951019f0108 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -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;
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 4268ae3b1701..412a06594f53 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -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())
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 0b109f9bee42..37c9c366fee6 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -199,8 +199,8 @@ public:
// 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 @@ public:
// 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
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index e7cf8e6e653a..33cb5bca3869 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -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
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 4f96b8baec06..6554da9cf98c 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -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;
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 865e8c240be2..c3354574c775 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -690,7 +690,6 @@ public:
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 @@ public:
}
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) {
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index f10a08f9db86..c3f9364e7ae4 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -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());
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 0a531e9b21a6..d88a37a45b23 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -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;
}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 4d50e8946bd6..ba9f1b28a07d 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -373,7 +373,8 @@ public:
GVA_Internal,
GVA_C99Inline,
GVA_CXXInline,
- GVA_StrongExternal
+ GVA_StrongExternal,
+ GVA_TemplateInstantiation
};
private:
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index f31c610bf97d..1a30ea37fbbc 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -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);
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index b5ad5acc0162..8018b4f45a84 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -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) {
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 9b85df61da05..4835454b47df 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -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);
}
diff --git a/lib/CodeGen/TargetABIInfo.cpp b/lib/CodeGen/TargetABIInfo.cpp
index 361e5c0005cc..896dbd685037 100644
--- a/lib/CodeGen/TargetABIInfo.cpp
+++ b/lib/CodeGen/TargetABIInfo.cpp
@@ -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();
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 593694cfbbf6..54dd4bb77538 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -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);
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 1e044c6b8fdc..7e29b67769d3 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -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;
-}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 8c2676b8cd7d..1b0b5615dfbc 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -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:
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 831e11b98e42..602a97713505 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -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.
@@ -417,6 +468,12 @@ clang::driver::createDarwinHostInfo(const Driver &D,
}
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) {
return new FreeBSDHostInfo(D, Triple);
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 222cf15db60f..1b0ea18453d0 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -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) {}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 436d343dd021..f663ed49536e 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -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)
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 3ecd1715da96..c921d52864f0 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -107,6 +107,13 @@ public:
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);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index bfc247a015ff..d198a54cf7dd 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -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));
}
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index db108db2b4d7..ab7349600907 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -241,6 +241,40 @@ namespace darwin {
};
}
+ /// openbsd -- Directly call GNU Binutils assembler and linker
+namespace openbsd {
+ class VISIBILITY_HIDDEN Assemble : public Tool {
+ public:
+ Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
+
+ virtual bool acceptsPipedInput() const { return true; }
+ virtual bool canPipeOutput() const { return true; }
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+ class VISIBILITY_HIDDEN Link : public Tool {
+ public:
+ Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
+
+ virtual bool acceptsPipedInput() const { return true; }
+ virtual bool canPipeOutput() const { return true; }
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+}
+
/// freebsd -- Directly call GNU Binutils assembler and linker
namespace freebsd {
class VISIBILITY_HIDDEN Assemble : public Tool {
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 5844be826cf7..8f0ad13319eb 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -44,7 +44,7 @@ namespace {
virtual void HandleTranslationUnit(ASTContext &Context) {
PrintingPolicy Policy = Context.PrintingPolicy;
Policy.Dump = Dump;
- Context.getTranslationUnitDecl()->print(Out, Context, Policy);
+ Context.getTranslationUnitDecl()->print(Out, Policy);
}
};
} // end anonymous namespace
@@ -70,8 +70,8 @@ namespace {
virtual void HandleTranslationUnit(ASTContext &Ctx) {
Doc.addSubNode("TranslationUnit");
for (DeclContext::decl_iterator
- D = Ctx.getTranslationUnitDecl()->decls_begin(Ctx),
- DEnd = Ctx.getTranslationUnitDecl()->decls_end(Ctx);
+ D = Ctx.getTranslationUnitDecl()->decls_begin(),
+ DEnd = Ctx.getTranslationUnitDecl()->decls_end();
D != DEnd;
++D)
{
@@ -114,7 +114,7 @@ namespace {
void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- FD->print(llvm::errs(), *Context);
+ FD->print(llvm::errs());
if (FD->getBodyIfAvailable()) {
llvm::cerr << '\n';
@@ -125,7 +125,7 @@ void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
}
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- MD->print(llvm::errs(), *Context);
+ MD->print(llvm::errs());
if (MD->getBody()) {
llvm::cerr << '\n';
@@ -340,10 +340,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "\n";
// Print decls in the DeclContext.
- // FIXME: Should not use a NULL DeclContext!
- ASTContext *Context = 0;
- for (DeclContext::decl_iterator I = DC->decls_begin(*Context),
- E = DC->decls_end(*Context);
+ for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
I != E; ++I) {
for (unsigned i = 0; i < Indentation; ++i)
Out << " ";
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
index d8fa141d8cb6..06af2d9a4e58 100644
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -307,7 +307,7 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
Opts.AnalyzeSpecificFunction != FD->getIdentifier()->getName())
break;
- Stmt* Body = FD->getBody(*Ctx);
+ Stmt* Body = FD->getBody();
if (Body) HandleCode(FD, Body, FunctionActions);
break;
}
@@ -341,8 +341,8 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
if (!ObjCImplementationActions.empty()) {
TranslationUnitDecl *TUD = C.getTranslationUnitDecl();
- for (DeclContext::decl_iterator I = TUD->decls_begin(C),
- E = TUD->decls_end(C);
+ for (DeclContext::decl_iterator I = TUD->decls_begin(),
+ E = TUD->decls_end();
I != E; ++I)
if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
HandleCode(ID, 0, ObjCImplementationActions);
@@ -479,14 +479,16 @@ static void ActionDisplayLiveVariables(AnalysisManager& mgr) {
static void ActionCFGDump(AnalysisManager& mgr) {
if (CFG* c = mgr.getCFG()) {
mgr.DisplayFunction();
- c->dump();
+ LangOptions LO; // FIXME!
+ c->dump(LO);
}
}
static void ActionCFGView(AnalysisManager& mgr) {
if (CFG* c = mgr.getCFG()) {
mgr.DisplayFunction();
- c->viewCFG();
+ LangOptions LO; // FIXME!
+ c->viewCFG(LO);
}
}
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp
index d8f8625d6740..1c536b07cee2 100644
--- a/lib/Frontend/Backend.cpp
+++ b/lib/Frontend/Backend.cpp
@@ -75,13 +75,14 @@ namespace {
public:
BackendConsumer(BackendAction action, Diagnostic &Diags,
const LangOptions &langopts, const CompileOptions &compopts,
- const std::string &infile, llvm::raw_ostream* OS) :
+ const std::string &infile, llvm::raw_ostream* OS,
+ LLVMContext& C) :
Action(action),
CompileOpts(compopts),
AsmOutStream(OS),
LLVMIRGeneration("LLVM IR Generation Time"),
CodeGenerationTime("Code Generation Time"),
- Gen(CreateLLVMCodeGen(Diags, infile, compopts)),
+ Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
TheModule(0), TheTargetData(0), ModuleProvider(0),
CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
@@ -359,6 +360,8 @@ ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
const LangOptions &LangOpts,
const CompileOptions &CompileOpts,
const std::string& InFile,
- llvm::raw_ostream* OS) {
- return new BackendConsumer(Action, Diags, LangOpts, CompileOpts, InFile, OS);
+ llvm::raw_ostream* OS,
+ LLVMContext& C) {
+ return new BackendConsumer(Action, Diags, LangOpts, CompileOpts,
+ InFile, OS, C);
}
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
index 5c21999bfa05..68f931fb6c69 100644
--- a/lib/Frontend/DeclXML.cpp
+++ b/lib/Frontend/DeclXML.cpp
@@ -34,8 +34,8 @@ class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter>
void addSubNodes(RecordDecl* RD)
{
- for (RecordDecl::field_iterator i = RD->field_begin(*Doc.Ctx), e = RD->field_end(*Doc.Ctx); i != e; ++i)
- {
+ for (RecordDecl::field_iterator i = RD->field_begin(),
+ e = RD->field_end(); i != e; ++i) {
Visit(*i);
Doc.toParent();
}
@@ -43,8 +43,8 @@ class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter>
void addSubNodes(EnumDecl* ED)
{
- for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Doc.Ctx), e = ED->enumerator_end(*Doc.Ctx); i != e; ++i)
- {
+ for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
+ e = ED->enumerator_end(); i != e; ++i) {
Visit(*i);
Doc.toParent();
}
@@ -147,7 +147,7 @@ void DocumentXML::writeDeclToXML(Decl *D)
DeclPrinter(*this).Visit(D);
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
{
- if (Stmt *Body = FD->getBody(*Ctx)) {
+ if (Stmt *Body = FD->getBody()) {
addSubNode("Body");
PrintStmt(Body);
toParent();
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 7a2b3a7317b4..8c80786210ff 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -178,6 +178,14 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang) {
AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4/backward",
System, true, false, false);
+ // Gentoo amd64 stable
+ AddPath("/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4", System,
+ true, false, false);
+ AddPath("/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4/"
+ "i686-pc-linux-gnu", System, true, false, false);
+ AddPath("/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4/backward",
+ System, true, false, false);
+
// DragonFly
AddPath("/usr/include/c++/4.1", System, true, false, false);
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 730414e44822..e41dfdda07e9 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -383,7 +383,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// 16-bit targets doesn't necessarily have a 64-bit type.
if (TI.getLongLongWidth() == 64)
- DefineBuiltinMacro(Buf, "__INT64_TYPE__=long long");
+ DefineType("__INT64_TYPE__", TI.getInt64Type(), Buf);
// Add __builtin_va_list typedef.
{
@@ -423,7 +423,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
sprintf(MacroBuf, "__DECIMAL_DIG__=%d",
PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33, 36));
DefineBuiltinMacro(Buf, MacroBuf);
-
+
+ if (LangOpts.getStackProtectorMode() == LangOptions::SSPOn)
+ DefineBuiltinMacro(Buf, "__SSP__=1");
+ else if (LangOpts.getStackProtectorMode() == LangOptions::SSPReq)
+ DefineBuiltinMacro(Buf, "__SSP_ALL__=2");
+
// Get other target #defines.
TI.getTargetDefines(LangOpts, Buf);
}
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 765655b01dd0..95b166159e7d 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -344,7 +344,8 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context)
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0),
- TotalNumSelectors(0), NumStatHits(0), NumStatMisses(0),
+ TotalNumSelectors(0), Comments(0), NumComments(0),
+ NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), NumStatementsRead(0),
NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0) { }
@@ -1350,6 +1351,11 @@ PCHReader::ReadPCHBlock() {
case pch::ORIGINAL_FILE_NAME:
OriginalFileName.assign(BlobStart, BlobLen);
break;
+
+ case pch::COMMENT_RANGES:
+ Comments = (SourceRange *)BlobStart;
+ NumComments = BlobLen / sizeof(SourceRange);
+ break;
}
}
Error("premature end of bitstream in PCH file");
@@ -1664,6 +1670,12 @@ bool PCHReader::ParseLanguageOptions(
return false;
}
+void PCHReader::ReadComments(std::vector<SourceRange> &Comments) {
+ Comments.resize(NumComments);
+ std::copy(this->Comments, this->Comments + NumComments,
+ Comments.begin());
+}
+
/// \brief Read and return the type at the given offset.
///
/// This routine actually reads the record corresponding to the type
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 3f6ae354dc3f..15b54a2d4fc6 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -80,7 +80,7 @@ void PCHDeclReader::VisitDecl(Decl *D) {
D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
D->setInvalidDecl(Record[Idx++]);
if (Record[Idx++])
- D->addAttr(*Reader.getContext(), Reader.ReadAttributes());
+ D->addAttr(Reader.ReadAttributes());
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index d09638806169..eccb53bf8189 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -1133,6 +1133,5 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
StmtStack.push_back(S);
}
assert(StmtStack.size() == 1 && "Extra expressions on stack!");
- SwitchCaseStmts.clear();
return StmtStack.back();
}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index e93219e01d5c..3bfc9e89d10a 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -374,7 +374,8 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(STAT_CACHE);
RECORD(EXT_VECTOR_DECLS);
RECORD(OBJC_CATEGORY_IMPLEMENTATIONS);
-
+ RECORD(COMMENT_RANGES);
+
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
RECORD(SM_SLOC_FILE_ENTRY);
@@ -989,6 +990,24 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
Stream.ExitBlock();
}
+void PCHWriter::WriteComments(ASTContext &Context) {
+ using namespace llvm;
+
+ if (Context.Comments.empty())
+ return;
+
+ BitCodeAbbrev *CommentAbbrev = new BitCodeAbbrev();
+ CommentAbbrev->Add(BitCodeAbbrevOp(pch::COMMENT_RANGES));
+ CommentAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned CommentCode = Stream.EmitAbbrev(CommentAbbrev);
+
+ RecordData Record;
+ Record.push_back(pch::COMMENT_RANGES);
+ Stream.EmitRecordWithBlob(CommentCode, Record,
+ (const char*)&Context.Comments[0],
+ Context.Comments.size() * sizeof(SourceRange));
+}
+
//===----------------------------------------------------------------------===//
// Type Serialization
//===----------------------------------------------------------------------===//
@@ -1064,14 +1083,13 @@ void PCHWriter::WriteTypesBlock(ASTContext &Context) {
/// bistream, or 0 if no block was written.
uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
DeclContext *DC) {
- if (DC->decls_empty(Context))
+ if (DC->decls_empty())
return 0;
uint64_t Offset = Stream.GetCurrentBitNo();
RecordData Record;
- for (DeclContext::decl_iterator D = DC->decls_begin(Context),
- DEnd = DC->decls_end(Context);
- D != DEnd; ++D)
+ for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
+ D != DEnd; ++D)
AddDeclRef(*D, Record);
++NumLexicalDeclContexts;
@@ -1097,7 +1115,7 @@ uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
return 0;
// Force the DeclContext to build a its name-lookup table.
- DC->lookup(Context, DeclarationName());
+ DC->lookup(DeclarationName());
// Serialize the contents of the mapping used for lookup. Note that,
// although we have two very different code paths, the serialized
@@ -1747,7 +1765,8 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls) {
WriteStatCache(*StatCalls);
WriteSourceManagerBlock(Context.getSourceManager(), PP);
WritePreprocessor(PP);
-
+ WriteComments(Context);
+
// Keep writing types and declarations until all types and
// declarations have been written.
do {
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 44da4d72f2df..a6843e1b9efd 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -146,7 +146,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitValueDecl(D);
Record.push_back(D->isThisDeclarationADefinition());
if (D->isThisDeclarationADefinition())
- Writer.AddStmt(D->getBody(Context));
+ Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->isInline());
@@ -172,7 +172,7 @@ void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Unlike C/C++, method bodies will never be in header files.
Record.push_back(D->getBody() != 0);
if (D->getBody() != 0) {
- Writer.AddStmt(D->getBody(Context));
+ Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getSelfDecl(), Record);
Writer.AddDeclRef(D->getCmdDecl(), Record);
}
@@ -520,7 +520,7 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
// If the declaration had any attributes, write them now.
if (D->hasAttrs())
- WriteAttributeRecord(D->getAttrs(Context));
+ WriteAttributeRecord(D->getAttrs());
// Flush any expressions that were written as part of this declaration.
FlushStmts();
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index c63c03c8823f..5235326e9ffd 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -826,5 +826,4 @@ void PCHWriter::FlushStmts() {
}
StmtsToEmit.clear();
- SwitchCaseIDs.clear();
}
diff --git a/lib/Frontend/ResolveLocation.cpp b/lib/Frontend/ResolveLocation.cpp
index a5f0d1f16365..d7a9b4852a96 100644
--- a/lib/Frontend/ResolveLocation.cpp
+++ b/lib/Frontend/ResolveLocation.cpp
@@ -163,7 +163,7 @@ void StmtLocResolver::VisitStmt(Stmt *Node) {
void DeclLocResolver::VisitDeclContext(DeclContext *DC) {
DeclLocResolver DLR(Ctx, Loc);
for (DeclContext::decl_iterator
- I = DC->decls_begin(Ctx), E = DC->decls_end(Ctx); I != E; ++I) {
+ I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
DLR.Visit(*I);
if (DLR.Finished()) {
if (DLR.FoundIt())
@@ -211,7 +211,7 @@ void DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) {
// Finally, search through the body of the function.
if (D->isThisDeclarationADefinition()) {
StmtLocResolver SLR(Ctx, Loc);
- SLR.Visit(D->getBody(Ctx));
+ SLR.Visit(D->getBody());
if (SLR.FoundIt()) {
llvm::tie(Dcl, Stm) = SLR.getResult();
// If we didn't find a more immediate 'parent' declaration for the
@@ -287,7 +287,7 @@ void LocResolverBase::FixRange(SourceRange &Range) {
void LocResolverBase::print(Decl *D) {
llvm::raw_ostream &OS = llvm::outs();
OS << "#### DECL ####\n";
- D->print(OS, Ctx);
+ D->print(OS);
OS << " <";
D->getLocStart().print(OS, Ctx.getSourceManager());
OS << " > - <";
@@ -299,7 +299,7 @@ void LocResolverBase::print(Decl *D) {
void LocResolverBase::print(Stmt *Node) {
llvm::raw_ostream &OS = llvm::outs();
OS << "#### STMT ####\n";
- Node->printPretty(OS, Ctx);
+ Node->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
OS << " <";
Node->getLocStart().print(OS, Ctx.getSourceManager());
OS << " > - <";
diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp
index d20d5cd152c4..bc855fa87912 100644
--- a/lib/Frontend/RewriteBlocks.cpp
+++ b/lib/Frontend/RewriteBlocks.cpp
@@ -306,39 +306,33 @@ void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl *Method) {
void RewriteBlocks::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
for (ObjCInterfaceDecl::instmeth_iterator
- I = ClassDecl->instmeth_begin(*Context),
- E = ClassDecl->instmeth_end(*Context);
+ I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
for (ObjCInterfaceDecl::classmeth_iterator
- I = ClassDecl->classmeth_begin(*Context),
- E = ClassDecl->classmeth_end(*Context);
+ I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
}
void RewriteBlocks::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
for (ObjCCategoryDecl::instmeth_iterator
- I = CatDecl->instmeth_begin(*Context),
- E = CatDecl->instmeth_end(*Context);
+ I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
for (ObjCCategoryDecl::classmeth_iterator
- I = CatDecl->classmeth_begin(*Context),
- E = CatDecl->classmeth_end(*Context);
+ I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
}
void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(*Context),
- E = PDecl->instmeth_end(*Context);
+ I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(*Context),
- E = PDecl->classmeth_end(*Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
}
@@ -724,7 +718,8 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
BlockCall += "((struct __block_impl *)";
std::string closureExprBufStr;
llvm::raw_string_ostream closureExprBuf(closureExprBufStr);
- Exp->getCallee()->printPretty(closureExprBuf, *Context);
+ Exp->getCallee()->printPretty(closureExprBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
BlockCall += closureExprBuf.str();
BlockCall += ")->FuncPtr)";
@@ -735,7 +730,7 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
E = Exp->arg_end(); I != E; ++I) {
std::string syncExprBufS;
llvm::raw_string_ostream Buf(syncExprBufS);
- (*I)->printPretty(Buf, *Context);
+ (*I)->printPretty(Buf, *Context, 0, PrintingPolicy(LangOpts));
BlockCall += ", " + Buf.str();
}
return BlockCall;
@@ -1088,7 +1083,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
RewriteFunctionProtoType(FD->getType(), FD);
// FIXME: Handle CXXTryStmt
- if (CompoundStmt *Body = FD->getCompoundBody(*Context)) {
+ if (CompoundStmt *Body = FD->getCompoundBody()) {
CurFunctionDef = FD;
FD->setBody(cast_or_null<CompoundStmt>(RewriteFunctionBody(Body)));
// This synthesizes and inserts the block "impl" struct, invoke function,
@@ -1100,7 +1095,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
}
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
RewriteMethodDecl(MD);
- if (Stmt *Body = MD->getBody(*Context)) {
+ if (Stmt *Body = MD->getBody()) {
CurMethodDef = MD;
RewriteFunctionBody(Body);
InsertBlockLiteralsWithinMethod(MD);
@@ -1112,7 +1107,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
RewriteBlockPointerDecl(VD);
if (VD->getInit()) {
if (BlockExpr *CBE = dyn_cast<BlockExpr>(VD->getInit())) {
- RewriteFunctionBody(CBE->getBody(*Context));
+ RewriteFunctionBody(CBE->getBody());
// We've just rewritten the block body in place.
// Now we snarf the rewritten text and stash it away for later use.
@@ -1146,8 +1141,8 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
if (RD->isDefinition()) {
- 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) {
FieldDecl *FD = *i;
if (isBlockPointerType(FD->getType()))
RewriteBlockPointerDecl(FD);
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index dce271070e03..cf31f2b2deab 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -171,7 +171,7 @@ namespace {
// Get the new text.
std::string SStr;
llvm::raw_string_ostream S(SStr);
- New->printPretty(S, *Context);
+ New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
const std::string &Str = S.str();
// If replacement succeeded or warning disabled return with no warning.
@@ -597,8 +597,8 @@ void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
RewriteForwardProtocolDecl(FP);
} else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
// Recurse into linkage specifications
- for (DeclContext::decl_iterator DI = LSD->decls_begin(*Context),
- DIEnd = LSD->decls_end(*Context);
+ for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+ DIEnd = LSD->decls_end();
DI != DIEnd; ++DI)
HandleTopLevelSingleDecl(*DI);
}
@@ -789,13 +789,11 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
ReplaceText(LocStart, 0, "// ", 3);
for (ObjCCategoryDecl::instmeth_iterator
- I = CatDecl->instmeth_begin(*Context),
- E = CatDecl->instmeth_end(*Context);
+ I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
for (ObjCCategoryDecl::classmeth_iterator
- I = CatDecl->classmeth_begin(*Context),
- E = CatDecl->classmeth_end(*Context);
+ I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
@@ -812,13 +810,11 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
ReplaceText(LocStart, 0, "// ", 3);
for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(*Context),
- E = PDecl->instmeth_end(*Context);
+ I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(*Context),
- E = PDecl->classmeth_end(*Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
@@ -986,14 +982,14 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
InsertText(CID->getLocStart(), "// ", 3);
for (ObjCCategoryImplDecl::instmeth_iterator
- I = IMD ? IMD->instmeth_begin(*Context) : CID->instmeth_begin(*Context),
- E = IMD ? IMD->instmeth_end(*Context) : CID->instmeth_end(*Context);
+ I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
+ E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
SourceLocation LocStart = OMD->getLocStart();
- SourceLocation LocEnd = OMD->getCompoundBody(*Context)->getLocStart();
+ SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
@@ -1002,14 +998,14 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
}
for (ObjCCategoryImplDecl::classmeth_iterator
- I = IMD ? IMD->classmeth_begin(*Context) : CID->classmeth_begin(*Context),
- E = IMD ? IMD->classmeth_end(*Context) : CID->classmeth_end(*Context);
+ I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
+ E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
SourceLocation LocStart = OMD->getLocStart();
- SourceLocation LocEnd = OMD->getCompoundBody(*Context)->getLocStart();
+ SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
@@ -1017,8 +1013,8 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
ResultStr.c_str(), ResultStr.size());
}
for (ObjCCategoryImplDecl::propimpl_iterator
- I = IMD ? IMD->propimpl_begin(*Context) : CID->propimpl_begin(*Context),
- E = IMD ? IMD->propimpl_end(*Context) : CID->propimpl_end(*Context);
+ I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
+ E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
I != E; ++I) {
RewritePropertyImplDecl(*I, IMD, CID);
}
@@ -1047,17 +1043,15 @@ void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
}
SynthesizeObjCInternalStruct(ClassDecl, ResultStr);
- for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(*Context),
- E = ClassDecl->prop_end(*Context); I != E; ++I)
+ for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
+ E = ClassDecl->prop_end(); I != E; ++I)
RewriteProperty(*I);
for (ObjCInterfaceDecl::instmeth_iterator
- I = ClassDecl->instmeth_begin(*Context),
- E = ClassDecl->instmeth_end(*Context);
+ I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
for (ObjCInterfaceDecl::classmeth_iterator
- I = ClassDecl->classmeth_begin(*Context),
- E = ClassDecl->classmeth_end(*Context);
+ I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
@@ -1149,8 +1143,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;
- iFaceDecl->getDecl()->lookupInstanceVariable(*Context,
- D->getIdentifier(),
+ iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
clsDeclared);
assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
@@ -1195,8 +1188,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
ObjCInterfaceType *iFaceDecl = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;
- iFaceDecl->getDecl()->lookupInstanceVariable(*Context,
- D->getIdentifier(),
+ iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
clsDeclared);
assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
@@ -1514,7 +1506,8 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
SourceLocation());
std::string syncExprBufS;
llvm::raw_string_ostream syncExprBuf(syncExprBufS);
- syncExpr->printPretty(syncExprBuf, *Context);
+ syncExpr->printPretty(syncExprBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
buf += syncExprBuf.str();
buf += ");\n";
buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
@@ -2143,7 +2136,8 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
// The pretty printer for StringLiteral handles escape characters properly.
std::string prettyBufS;
llvm::raw_string_ostream prettyBuf(prettyBufS);
- Exp->getString()->printPretty(prettyBuf, *Context);
+ Exp->getString()->printPretty(prettyBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
Preamble += prettyBuf.str();
Preamble += ",";
// The minus 2 removes the begin/end double quotes.
@@ -2192,8 +2186,7 @@ QualType RewriteObjC::getSuperStructType() {
// Create fields
for (unsigned i = 0; i < 2; ++i) {
- SuperStructDecl->addDecl(*Context,
- FieldDecl::Create(*Context, SuperStructDecl,
+ SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
SourceLocation(), 0,
FieldTypes[i], /*BitWidth=*/0,
/*Mutable=*/false));
@@ -2222,8 +2215,7 @@ QualType RewriteObjC::getConstantStringStructType() {
// Create fields
for (unsigned i = 0; i < 4; ++i) {
- ConstantStringDecl->addDecl(*Context,
- FieldDecl::Create(*Context,
+ ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
ConstantStringDecl,
SourceLocation(), 0,
FieldTypes[i],
@@ -2889,9 +2881,9 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
if (ObjCSynthesizedProtocols.count(PDecl))
return;
- if (PDecl->instmeth_begin(*Context) != PDecl->instmeth_end(*Context)) {
- unsigned NumMethods = std::distance(PDecl->instmeth_begin(*Context),
- PDecl->instmeth_end(*Context));
+ if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+ unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
+ PDecl->instmeth_end());
/* struct _objc_protocol_method_list {
int protocol_method_count;
struct protocol_methods protocols[];
@@ -2908,10 +2900,9 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
// Output instance methods declared in this protocol.
for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(*Context),
- E = PDecl->instmeth_end(*Context);
+ I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
I != E; ++I) {
- if (I == PDecl->instmeth_begin(*Context))
+ if (I == PDecl->instmeth_begin())
Result += "\t ,{{(struct objc_selector *)\"";
else
Result += "\t ,{(struct objc_selector *)\"";
@@ -2926,8 +2917,8 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
}
// Output class methods declared in this protocol.
- unsigned NumMethods = std::distance(PDecl->classmeth_begin(*Context),
- PDecl->classmeth_end(*Context));
+ unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
+ PDecl->classmeth_end());
if (NumMethods > 0) {
/* struct _objc_protocol_method_list {
int protocol_method_count;
@@ -2947,10 +2938,9 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
// Output instance methods declared in this protocol.
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(*Context),
- E = PDecl->classmeth_end(*Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I) {
- if (I == PDecl->classmeth_begin(*Context))
+ if (I == PDecl->classmeth_begin())
Result += "\t ,{{(struct objc_selector *)\"";
else
Result += "\t ,{(struct objc_selector *)\"";
@@ -2993,14 +2983,14 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
"{\n\t0, \"";
Result += PDecl->getNameAsString();
Result += "\", 0, ";
- if (PDecl->instmeth_begin(*Context) != PDecl->instmeth_end(*Context)) {
+ if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
Result += PDecl->getNameAsString();
Result += ", ";
}
else
Result += "0, ";
- if (PDecl->classmeth_begin(*Context) != PDecl->classmeth_end(*Context)) {
+ if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
Result += PDecl->getNameAsString();
Result += "\n";
@@ -3076,13 +3066,12 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
// Build _objc_method_list for class's instance methods if needed
llvm::SmallVector<ObjCMethodDecl *, 32>
- InstanceMethods(IDecl->instmeth_begin(*Context),
- IDecl->instmeth_end(*Context));
+ InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
// If any of our property implementations have associated getters or
// setters, produce metadata for them as well.
- for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
- PropEnd = IDecl->propimpl_end(*Context);
+ for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+ PropEnd = IDecl->propimpl_end();
Prop != PropEnd; ++Prop) {
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
@@ -3103,8 +3092,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
Result);
// Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
- IDecl->classmeth_end(*Context),
+ RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
false, "CATEGORY_", FullCategoryName.c_str(),
Result);
@@ -3147,7 +3135,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
Result += ClassDecl->getNameAsString();
Result += "\"\n";
- if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
+ if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_INSTANCE_METHODS_";
Result += FullCategoryName;
@@ -3155,7 +3143,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
}
else
Result += "\t, 0\n";
- if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
+ if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_CLASS_METHODS_";
Result += FullCategoryName;
@@ -3210,8 +3198,8 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
}
// Build _objc_ivar_list metadata for classes ivars if needed
- unsigned NumIvars = !IDecl->ivar_empty(*Context)
- ? IDecl->ivar_size(*Context)
+ unsigned NumIvars = !IDecl->ivar_empty()
+ ? IDecl->ivar_size()
: (CDecl ? CDecl->ivar_size() : 0);
if (NumIvars > 0) {
static bool objc_ivar = false;
@@ -3249,10 +3237,9 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
ObjCInterfaceDecl::ivar_iterator IVI, IVE;
llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
- if (!IDecl->ivar_empty(*Context)) {
+ if (!IDecl->ivar_empty()) {
for (ObjCImplementationDecl::ivar_iterator
- IV = IDecl->ivar_begin(*Context),
- IVEnd = IDecl->ivar_end(*Context);
+ IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
IV != IVEnd; ++IV)
IVars.push_back(*IV);
IVI = IVars.begin();
@@ -3289,13 +3276,12 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
// Build _objc_method_list for class's instance methods if needed
llvm::SmallVector<ObjCMethodDecl *, 32>
- InstanceMethods(IDecl->instmeth_begin(*Context),
- IDecl->instmeth_end(*Context));
+ InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
// If any of our property implementations have associated getters or
// setters, produce metadata for them as well.
- for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
- PropEnd = IDecl->propimpl_end(*Context);
+ for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+ PropEnd = IDecl->propimpl_end();
Prop != PropEnd; ++Prop) {
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
@@ -3315,8 +3301,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
true, "", IDecl->getNameAsCString(), Result);
// Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
- IDecl->classmeth_end(*Context),
+ RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
false, "", IDecl->getNameAsCString(), Result);
// Protocols referenced in class declaration?
@@ -3389,7 +3374,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
// Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
// 'info' field is initialized to CLS_META(2) for metaclass
Result += ", 0,2, sizeof(struct _objc_class), 0";
- if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
+ if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
Result += IDecl->getNameAsString();
Result += "\n";
@@ -3442,7 +3427,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
}
else
Result += ",0";
- if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
+ if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
Result += CDecl->getNameAsString();
Result += ", 0\n\t";
@@ -4552,7 +4537,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
RewriteBlocksInFunctionProtoType(FD->getType(), FD);
// FIXME: If this should support Obj-C++, support CXXTryStmt
- if (CompoundStmt *Body = FD->getCompoundBody(*Context)) {
+ if (CompoundStmt *Body = FD->getCompoundBody()) {
CurFunctionDef = FD;
CollectPropertySetters(Body);
CurrentBody = Body;
@@ -4572,7 +4557,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
return;
}
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (CompoundStmt *Body = MD->getBody()) {
+ if (CompoundStmt *Body = MD->getCompoundBody()) {
CurMethodDef = MD;
CollectPropertySetters(Body);
CurrentBody = Body;
@@ -4636,8 +4621,8 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
if (RD->isDefinition()) {
- 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) {
FieldDecl *FD = *i;
if (isTopLevelBlockPointerType(FD->getType()))
RewriteBlockPointerDecl(FD);
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 81ea606f0d9f..6f1043ae7353 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -903,7 +903,10 @@ bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
} while (C != '\n' && C != '\r');
// Found but did not consume the newline.
-
+ if (PP)
+ PP->HandleComment(SourceRange(getSourceLocation(BufferPtr),
+ getSourceLocation(CurPtr)));
+
// If we are returning comments as tokens, return this comment as a token.
if (inKeepCommentMode())
return SaveBCPLComment(Result, CurPtr);
@@ -1146,6 +1149,10 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
C = *CurPtr++;
}
+ if (PP)
+ PP->HandleComment(SourceRange(getSourceLocation(BufferPtr),
+ getSourceLocation(CurPtr)));
+
// If we are returning comments as tokens, return this comment as a token.
if (inKeepCommentMode()) {
FormTokenWithChars(Result, CurPtr, tok::comment);
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 3227d1cf09c5..bb0b71e22682 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -19,6 +19,7 @@
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
+#include <algorithm>
using namespace clang;
// Out-of-line destructor to provide a home for the class.
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 24ee5d8a8f92..9f0c15f59e49 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -476,3 +476,26 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
if (II.isExtensionToken() && !DisableMacroExpansion)
Diag(Identifier, diag::ext_token_used);
}
+
+void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
+ assert(Handler && "NULL comment handler");
+ assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) ==
+ CommentHandlers.end() && "Comment handler already registered");
+ CommentHandlers.push_back(Handler);
+}
+
+void Preprocessor::RemoveCommentHandler(CommentHandler *Handler) {
+ std::vector<CommentHandler *>::iterator Pos
+ = std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
+ assert(Pos != CommentHandlers.end() && "Comment handler not registered");
+ CommentHandlers.erase(Pos);
+}
+
+void Preprocessor::HandleComment(SourceRange Comment) {
+ for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(),
+ HEnd = CommentHandlers.end();
+ H != HEnd; ++H)
+ (*H)->HandleComment(*this, Comment);
+}
+
+CommentHandler::~CommentHandler() { }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index ff602e8ba79b..4a3532c4103b 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -802,7 +802,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
continue;
@@ -859,7 +859,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
@@ -1066,7 +1066,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
@@ -1179,7 +1179,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
return true;
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 225f9261ef8f..373d22fd9f4f 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1277,16 +1277,28 @@ void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
/// '::'[opt] nested-name-specifier[opt] class-name
/// identifier
Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
- // FIXME: parse '::'[opt] nested-name-specifier[opt]
-
- if (Tok.isNot(tok::identifier)) {
+ // parse '::'[opt] nested-name-specifier[opt]
+ CXXScopeSpec SS;
+ ParseOptionalCXXScopeSpecifier(SS);
+ TypeTy *TemplateTypeTy = 0;
+ if (Tok.is(tok::annot_template_id)) {
+ TemplateIdAnnotation *TemplateId
+ = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ if (TemplateId->Kind == TNK_Type_template) {
+ AnnotateTemplateIdTokenAsType(&SS);
+ assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
+ TemplateTypeTy = Tok.getAnnotationValue();
+ }
+ // FIXME. May need to check for TNK_Dependent_template as well.
+ }
+ if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_member_or_base_name);
return true;
}
-
+
// Get the identifier. This may be a member name or a class name,
// but we'll let the semantic analysis determine which it is.
- IdentifierInfo *II = Tok.getIdentifierInfo();
+ IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
SourceLocation IdLoc = ConsumeToken();
// Parse the '('.
@@ -1306,7 +1318,8 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
+ return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
+ TemplateTypeTy, IdLoc,
LParenLoc, ArgExprs.take(),
ArgExprs.size(), CommaLocs.data(),
RParenLoc);
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 13b32acd5b29..cd7618f66536 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -777,7 +777,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::annot_cxxscope: // [C++] id-expression: qualified-id
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
- // template-id
+ case tok::annot_template_id: // [C++] template-id
Res = ParseCXXIdExpression(isAddressOfOperand);
return ParsePostfixExpressionSuffix(move(Res));
@@ -1172,17 +1172,18 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
Comps.back().LocEnd =
MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
- } else if (Tok.is(tok::r_paren)) {
- if (Ty.isInvalid())
+ } else {
+ if (Tok.isNot(tok::r_paren)) {
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ Res = ExprError();
+ } else if (Ty.isInvalid()) {
Res = ExprError();
- else
+ } else {
Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc,
Ty.get(), &Comps[0],
Comps.size(), ConsumeParen());
+ }
break;
- } else {
- // Error occurred.
- return ExprError();
}
}
break;
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index d89f1e172ffb..1220b2d27b4f 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -207,13 +207,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
/// operator-function-id
/// conversion-function-id [TODO]
/// '~' class-name [TODO]
-/// template-id [TODO]
+/// template-id
///
/// qualified-id:
/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
/// '::' identifier
/// '::' operator-function-id
-/// '::' template-id [TODO]
+/// '::' template-id
///
/// nested-name-specifier:
/// type-name '::'
@@ -264,7 +264,7 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
// operator-function-id
// conversion-function-id
// '~' class-name [TODO]
- // template-id [TODO]
+ // template-id
//
switch (Tok.getKind()) {
default:
@@ -294,6 +294,29 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
return ExprError();
}
+ case tok::annot_template_id: {
+ TemplateIdAnnotation *TemplateId
+ = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ assert((TemplateId->Kind == TNK_Function_template ||
+ TemplateId->Kind == TNK_Dependent_template_name) &&
+ "A template type name is not an ID expression");
+
+ ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+ TemplateId->getTemplateArgs(),
+ TemplateId->getTemplateArgIsType(),
+ TemplateId->NumArgs);
+
+ OwningExprResult Result
+ = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template),
+ TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ TemplateId->getTemplateArgLocations(),
+ TemplateId->RAngleLoc);
+ ConsumeToken(); // Consume the template-id token
+ return move(Result);
+ }
+
} // switch.
assert(0 && "The switch was supposed to take care everything.");
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 29d1d8792e1a..9771cf7b8474 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -20,6 +20,19 @@
#include "ParsePragma.h"
using namespace clang;
+/// \brief A comment handler that passes comments found by the preprocessor
+/// to the parser action.
+class ActionCommentHandler : public CommentHandler {
+ Action &Actions;
+
+public:
+ explicit ActionCommentHandler(Action &Actions) : Actions(Actions) { }
+
+ virtual void HandleComment(Preprocessor &PP, SourceRange Comment) {
+ Actions.ActOnComment(Comment);
+ }
+};
+
Parser::Parser(Preprocessor &pp, Action &actions)
: CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
GreaterThanIsOperator(true) {
@@ -43,6 +56,9 @@ Parser::Parser(Preprocessor &pp, Action &actions)
WeakHandler.reset(new
PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions));
PP.AddPragmaHandler(0, WeakHandler.get());
+
+ CommentHandler.reset(new ActionCommentHandler(actions));
+ PP.AddCommentHandler(CommentHandler.get());
}
/// If a crash happens while the parser is active, print out a line indicating
@@ -294,6 +310,7 @@ Parser::~Parser() {
UnusedHandler.reset();
PP.RemovePragmaHandler(0, WeakHandler.get());
WeakHandler.reset();
+ PP.RemoveCommentHandler(CommentHandler.get());
}
/// Initialize - Warm up the parser.
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
index d81c38d6a466..ec5a60412d13 100644
--- a/lib/Rewrite/Rewriter.cpp
+++ b/lib/Rewrite/Rewriter.cpp
@@ -218,7 +218,7 @@ bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
// Get the new text.
std::string SStr;
llvm::raw_string_ostream S(SStr);
- To->printPretty(S);
+ To->printPretty(S, 0, PrintingPolicy(*LangOpts));
const std::string &Str = S.str();
ReplaceText(From->getLocStart(), Size, &Str[0], Str.size());
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 425d80443955..ae863f2df1ee 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -77,11 +77,11 @@ JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) : S(s) {
/// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
/// diagnostic that should be emitted if control goes over it. If not, return 0.
-static unsigned GetDiagForGotoScopeDecl(ASTContext &Context, const Decl *D) {
+static unsigned GetDiagForGotoScopeDecl(const Decl *D) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->getType()->isVariablyModifiedType())
return diag::note_protected_by_vla;
- if (VD->hasAttr<CleanupAttr>(Context))
+ if (VD->hasAttr<CleanupAttr>())
return diag::note_protected_by_cleanup;
} else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
if (TD->getUnderlyingType()->isVariablyModifiedType())
@@ -125,7 +125,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
I != E; ++I) {
// If this decl causes a new scope, push and switch to it.
- if (unsigned Diag = GetDiagForGotoScopeDecl(this->S.Context, *I)) {
+ if (unsigned Diag = GetDiagForGotoScopeDecl(*I)) {
Scopes.push_back(GotoScope(ParentScope, Diag, (*I)->getLocation()));
ParentScope = Scopes.size()-1;
}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index c37f66dae907..d1e8e2104d50 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -345,3 +345,7 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
= SemaRef.ActiveTemplateInstantiations.back();
}
}
+
+void Sema::ActOnComment(SourceRange Comment) {
+ Context.Comments.push_back(Comment);
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2d27ccc77839..7af80c0261e4 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -29,9 +29,9 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include <deque>
#include <list>
#include <string>
-#include <queue>
#include <vector>
namespace llvm {
@@ -86,6 +86,7 @@ namespace clang {
class ObjCMethodDecl;
class ObjCPropertyDecl;
class ObjCContainerDecl;
+ class FunctionProtoType;
class BasePaths;
struct MemberLookupCriteria;
class CXXTemporary;
@@ -362,6 +363,8 @@ public:
return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack;
}
+ virtual void ActOnComment(SourceRange Comment);
+
//===--------------------------------------------------------------------===//
// Type Analysis / Processing: SemaType.cpp.
//
@@ -392,6 +395,9 @@ public:
DeclarationName GetNameForDeclarator(Declarator &D);
bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
+ bool CheckEquivalentExceptionSpec(
+ const FunctionProtoType *Old, SourceLocation OldLoc,
+ const FunctionProtoType *New, SourceLocation NewLoc);
QualType ObjCGetTypeForMethodDefinition(DeclPtrTy D);
@@ -406,6 +412,9 @@ public:
QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T);
+ QualType BuildTypeofExprType(Expr *E);
+ QualType BuildDecltypeType(Expr *E);
+
//===--------------------------------------------------------------------===//
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
//
@@ -482,7 +491,7 @@ public:
void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) {
for (; Param != ParamEnd; ++Param) {
if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
- !(*Param)->template hasAttr<UnusedAttr>(Context))
+ !(*Param)->template hasAttr<UnusedAttr>())
Diag((*Param)->getLocation(), diag::warn_unused_parameter)
<< (*Param)->getDeclName();
}
@@ -679,7 +688,7 @@ public:
OR_Deleted ///< Overload resoltuion refers to a deleted function.
};
- typedef llvm::SmallPtrSet<FunctionDecl *, 16> FunctionSet;
+ typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
typedef llvm::SmallPtrSet<NamespaceDecl *, 16> AssociatedNamespaceSet;
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
@@ -698,6 +707,9 @@ public:
bool SuppressUserConversions = false,
bool ForceRValue = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
@@ -744,6 +756,9 @@ public:
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation *CommaLocs,
@@ -1398,7 +1413,11 @@ public:
bool HasTrailingLParen,
const CXXScopeSpec *SS,
bool isAddressOfOperand = false);
-
+ OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
+ bool HasTrailingLParen,
+ const CXXScopeSpec *SS,
+ bool isAddressOfOperand);
+
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind);
virtual OwningExprResult ActOnNumericConstant(const Token &);
@@ -1594,9 +1613,9 @@ public:
QualType DeclInitType,
Expr **Exprs, unsigned NumExprs);
- /// MarcDestructorReferenced - Prepare for calling destructor on the
+ /// MarkDestructorReferenced - Prepare for calling destructor on the
/// constructed decl.
- void MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType);
+ void MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType);
/// DefineImplicitDefaultConstructor - Checks for feasibility of
/// defining this constructor as the default constructor.
@@ -1884,7 +1903,9 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -2068,6 +2089,20 @@ public:
SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc);
+ OwningExprResult BuildTemplateIdExpr(TemplateName Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc);
+
+ virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc);
+
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
const IdentifierInfo &Name,
SourceLocation NameLoc,
@@ -2134,6 +2169,7 @@ public:
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
+ bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted);
bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
@@ -2225,7 +2261,10 @@ public:
TDK_TooManyArguments,
/// \brief When performing template argument deduction for a class
/// template, there were too few call arguments.
- TDK_TooFewArguments
+ TDK_TooFewArguments,
+ /// \brief The explicitly-specified template arguments were not valid
+ /// template arguments for the given template.
+ TDK_InvalidExplicitArguments
};
/// \brief Provides information about an attempted template argument
@@ -2307,6 +2346,9 @@ public:
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
TemplateDeductionInfo &Info);
@@ -2323,7 +2365,7 @@ public:
/// \brief A template instantiation that is currently in progress.
struct ActiveTemplateInstantiation {
/// \brief The kind of template instantiation we are performing
- enum {
+ enum InstantiationKind {
/// We are instantiating a template declaration. The entity is
/// the declaration we're instantiating (e.g., a CXXRecordDecl).
TemplateInstantiation,
@@ -2335,13 +2377,16 @@ public:
/// FIXME: Use a TemplateArgumentList
DefaultTemplateArgumentInstantiation,
- /// We are performing template argument deduction for a class
- /// template partial specialization. The Entity is the class
- /// template partial specialization, and
- /// TemplateArgs/NumTemplateArgs provides the deduced template
- /// arguments.
- /// FIXME: Use a TemplateArgumentList
- PartialSpecDeductionInstantiation
+ /// We are substituting explicit template arguments provided for
+ /// a function template. The entity is a FunctionTemplateDecl.
+ ExplicitTemplateArgumentSubstitution,
+
+ /// We are substituting template argument determined as part of
+ /// template argument deduction for either a class template
+ /// partial specialization or a function template. The
+ /// Entity is either a ClassTemplatePartialSpecializationDecl or
+ /// a FunctionTemplateDecl.
+ DeducedTemplateArgumentSubstitution
} Kind;
/// \brief The point of instantiation within the source code.
@@ -2375,7 +2420,8 @@ public:
return true;
case DefaultTemplateArgumentInstantiation:
- case PartialSpecDeductionInstantiation:
+ case ExplicitTemplateArgumentSubstitution:
+ case DeducedTemplateArgumentSubstitution:
return X.TemplateArgs == Y.TemplateArgs;
}
@@ -2432,6 +2478,15 @@ public:
unsigned NumTemplateArgs,
SourceRange InstantiationRange = SourceRange());
+ /// \brief Note that we are instantiating a default argument in a
+ /// template-id.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ FunctionTemplateDecl *FunctionTemplate,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ ActiveTemplateInstantiation::InstantiationKind Kind,
+ SourceRange InstantiationRange = SourceRange());
+
/// \brief Note that we are instantiating as part of template
/// argument deduction for a class template partial
/// specialization.
@@ -2574,7 +2629,7 @@ public:
/// \brief The queue of implicit template instantiations that are required
/// but have not yet been performed.
- std::queue<PendingImplicitInstantiation> PendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
void PerformPendingImplicitInstantiations();
@@ -2629,7 +2684,8 @@ public:
const TemplateArgumentList &TemplateArgs);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
- FunctionDecl *Function);
+ FunctionDecl *Function,
+ bool Recursive = false);
void InstantiateVariableDefinition(VarDecl *Var);
NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index cbfa56a6911f..1bf8444c42b7 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -205,7 +205,7 @@ void Sema::ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
// Otherwise, add the 'unused' attribute to each referenced declaration.
for (unsigned i = 0; i < NumExprs; ++i) {
DeclRefExpr *DR = (DeclRefExpr*) Exprs[i];
- DR->getDecl()->addAttr(Context, ::new (Context) UnusedAttr());
+ DR->getDecl()->addAttr(::new (Context) UnusedAttr());
DR->Destroy(Context);
}
}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index f6d6623f9a20..4eed01872246 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -166,7 +166,7 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
// handlers.
// Printf checking.
- if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>(Context)) {
+ if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
if (Format->getType() == "printf") {
bool HasVAListArg = Format->getFirstArg() == 0;
if (!HasVAListArg) {
@@ -178,7 +178,7 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
HasVAListArg ? 0 : Format->getFirstArg() - 1);
}
}
- for (const Attr *attr = FDecl->getAttrs(Context);
+ for (const Attr *attr = FDecl->getAttrs();
attr; attr = attr->getNext()) {
if (const NonNullAttr *NonNull = dyn_cast<NonNullAttr>(attr))
CheckNonNullArguments(NonNull, TheCall);
@@ -192,7 +192,7 @@ Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
OwningExprResult TheCallResult(Owned(TheCall));
// Printf checking.
- const FormatAttr *Format = NDecl->getAttr<FormatAttr>(Context);
+ const FormatAttr *Format = NDecl->getAttr<FormatAttr>();
if (!Format)
return move(TheCallResult);
const VarDecl *V = dyn_cast<VarDecl>(NDecl);
@@ -717,8 +717,6 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
if (E->isTypeDependent() || E->isValueDependent())
return false;
- E = E->IgnoreParenCasts();
-
switch (E->getStmtClass()) {
case Stmt::ConditionalOperatorClass: {
const ConditionalOperator *C = cast<ConditionalOperator>(E);
@@ -763,6 +761,28 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
return SemaCheckStringLiteral(Init, TheCall,
HasVAListArg, format_idx, firstDataArg);
}
+
+ // For vprintf* functions (i.e., HasVAListArg==true), we add a
+ // special check to see if the format string is a function parameter
+ // of the function calling the printf function. If the function
+ // has an attribute indicating it is a printf-like function, then we
+ // should suppress warnings concerning non-literals being used in a call
+ // to a vprintf function. For example:
+ //
+ // void
+ // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...){
+ // va_list ap;
+ // va_start(ap, fmt);
+ // vprintf(fmt, ap); // Do NOT emit a warning about "fmt".
+ // ...
+ //
+ //
+ // FIXME: We don't have full attribute support yet, so just check to see
+ // if the argument is a DeclRefExpr that references a parameter. We'll
+ // add proper support for checking the attribute later.
+ if (HasVAListArg)
+ if (isa<ParmVarDecl>(VD))
+ return true;
}
return false;
@@ -774,7 +794,7 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
= dyn_cast<ImplicitCastExpr>(CE->getCallee())) {
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>(Context)) {
+ if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) {
unsigned ArgIndex = FA->getFormatIdx();
const Expr *Arg = CE->getArg(ArgIndex - 1);
@@ -901,29 +921,6 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
firstDataArg))
return; // Literal format string found, check done!
- // For vprintf* functions (i.e., HasVAListArg==true), we add a
- // special check to see if the format string is a function parameter
- // of the function calling the printf function. If the function
- // has an attribute indicating it is a printf-like function, then we
- // should suppress warnings concerning non-literals being used in a call
- // to a vprintf function. For example:
- //
- // void
- // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...) {
- // va_list ap;
- // va_start(ap, fmt);
- // vprintf(fmt, ap); // Do NOT emit a warning about "fmt".
- // ...
- //
- //
- // FIXME: We don't have full attribute support yet, so just check to see
- // if the argument is a DeclRefExpr that references a parameter. We'll
- // add proper support for checking the attribute later.
- if (HasVAListArg)
- if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OrigFormatExpr))
- if (isa<ParmVarDecl>(DR->getDecl()))
- return;
-
// If there are no arguments specified, warn with -Wformat-security, otherwise
// warn only with -Wformat-nonliteral.
if (TheCall->getNumArgs() == format_idx+1)
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 13162d8e8ea9..1fd569729a37 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -256,7 +256,7 @@ static bool AllowOverloadingOfFunction(Decl *PrevDecl, ASTContext &Context) {
if (isa<OverloadedFunctionDecl>(PrevDecl))
return true;
- return PrevDecl->getAttr<OverloadableAttr>(Context) != 0;
+ return PrevDecl->getAttr<OverloadableAttr>() != 0;
}
/// Add this decl to the scope shadowed decl chains.
@@ -273,7 +273,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
// Add scoped declarations into their context, so that they can be
// found later. Declarations without a context won't be inserted
// into any context.
- CurContext->addDecl(Context, D);
+ CurContext->addDecl(D);
// C++ [basic.scope]p4:
// -- exactly one declaration shall declare a class name or
@@ -612,8 +612,8 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
static bool
-DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(Context); attr; attr = attr->getNext())
+DeclHasAttr(const Decl *decl, const Attr *target) {
+ for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
if (attr->getKind() == target->getKind())
return true;
@@ -622,11 +622,11 @@ DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) {
/// MergeAttributes - append attributes from the Old decl to the New one.
static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
- for (const Attr *attr = Old->getAttrs(C); attr; attr = attr->getNext()) {
- if (!DeclHasAttr(C, New, attr) && attr->isMerged()) {
+ for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
+ if (!DeclHasAttr(New, attr) && attr->isMerged()) {
Attr *NewAttr = attr->clone(C);
NewAttr->setInherited(true);
- New->addAttr(C, NewAttr);
+ New->addAttr(NewAttr);
}
}
}
@@ -1123,8 +1123,8 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
RecordDecl *AnonRecord) {
bool Invalid = false;
- for (RecordDecl::field_iterator F = AnonRecord->field_begin(Context),
- FEnd = AnonRecord->field_end(Context);
+ for (RecordDecl::field_iterator F = AnonRecord->field_begin(),
+ FEnd = AnonRecord->field_end();
F != FEnd; ++F) {
if ((*F)->getDeclName()) {
NamedDecl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(),
@@ -1147,7 +1147,7 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
// definition, the members of the anonymous union are
// considered to have been defined in the scope in which the
// anonymous union is declared.
- Owner->makeDeclVisibleInContext(Context, *F);
+ Owner->makeDeclVisibleInContext(*F);
S->AddDecl(DeclPtrTy::make(*F));
IdResolver.AddDecl(*F);
}
@@ -1213,8 +1213,8 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// The member-specification of an anonymous union shall only
// define non-static data members. [Note: nested types and
// functions cannot be declared within an anonymous union. ]
- for (DeclContext::decl_iterator Mem = Record->decls_begin(Context),
- MemEnd = Record->decls_end(Context);
+ for (DeclContext::decl_iterator Mem = Record->decls_begin(),
+ MemEnd = Record->decls_end();
Mem != MemEnd; ++Mem) {
if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem)) {
// C++ [class.union]p3:
@@ -1302,7 +1302,7 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Add the anonymous struct/union object to the current
// context. We'll be referencing this object when we refer to one of
// its members.
- Owner->addDecl(Context, Anon);
+ Owner->addDecl(Anon);
// Inject the members of the anonymous struct/union into the owning
// context and into the identifier resolver chain for name lookup
@@ -1851,8 +1851,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(Context,
- ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+ NewVD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -1931,11 +1930,11 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
}
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
- && !NewVD->hasAttr<BlocksAttr>(Context))
+ && !NewVD->hasAttr<BlocksAttr>())
Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
bool isVM = T->isVariablyModifiedType();
- if (isVM || NewVD->hasAttr<CleanupAttr>(Context))
+ if (isVM || NewVD->hasAttr<CleanupAttr>())
CurFunctionNeedsScopeChecking = true;
if ((isVM && NewVD->hasLinkage()) ||
@@ -1990,12 +1989,12 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
return NewVD->setInvalidDecl();
}
- if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>(Context)) {
+ if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
return NewVD->setInvalidDecl();
}
- if (isVM && NewVD->hasAttr<BlocksAttr>(Context)) {
+ if (isVM && NewVD->hasAttr<BlocksAttr>()) {
Diag(NewVD->getLocation(), diag::err_block_on_vm);
return NewVD->setInvalidDecl();
}
@@ -2251,8 +2250,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(Context,
- ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+ NewFD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -2371,7 +2369,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
ProcessDeclAttributes(S, NewFD, D);
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>(Context)) {
+ if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -2379,7 +2377,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (PrevDecl)
Diag(PrevDecl->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(Context, ::new (Context) OverloadableAttr());
+ NewFD->addAttr(::new (Context) OverloadableAttr());
}
// If this is a locally-scoped extern C function, update the
@@ -2797,7 +2795,7 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0);
// FIXME. Must do all that is needed to destroy the object
// on scope exit. For now, just mark the destructor as used.
- MarcDestructorReferenced(Var->getLocation(), InitType);
+ MarkDestructorReferenced(Var->getLocation(), InitType);
}
}
}
@@ -2998,7 +2996,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
ProcessDeclAttributes(S, New, D);
- if (New->hasAttr<BlocksAttr>(Context)) {
+ if (New->hasAttr<BlocksAttr>()) {
Diag(New->getLocation(), diag::err_block_on_nonlocal);
}
return DeclPtrTy::make(New);
@@ -3065,7 +3063,7 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// See if this is a redefinition.
const FunctionDecl *Definition;
- if (FD->getBody(Context, Definition)) {
+ if (FD->getBody(Definition)) {
Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
Diag(Definition->getLocation(), diag::note_previous_definition);
}
@@ -3128,10 +3126,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// Checking attributes of current function definition
// dllimport attribute.
- if (FD->getAttr<DLLImportAttr>(Context) &&
- (!FD->getAttr<DLLExportAttr>(Context))) {
+ if (FD->getAttr<DLLImportAttr>() &&
+ (!FD->getAttr<DLLExportAttr>())) {
// dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>(Context))->isInherited()) {
+ if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
<< "dllimport";
@@ -3313,9 +3311,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
unsigned FormatIdx;
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
- if (!FD->getAttr<FormatAttr>(Context))
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", FormatIdx + 1,
+ if (!FD->getAttr<FormatAttr>())
+ FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1,
HasVAListArg ? 0 : FormatIdx + 2));
}
@@ -3324,8 +3321,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
// IRgen to use LLVM intrinsics for such functions.
if (!getLangOptions().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
- if (!FD->getAttr<ConstAttr>(Context))
- FD->addAttr(Context, ::new (Context) ConstAttr());
+ if (!FD->getAttr<ConstAttr>())
+ FD->addAttr(::new (Context) ConstAttr());
}
}
@@ -3343,17 +3340,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
return;
if (Name->isStr("NSLog") || Name->isStr("NSLogv")) {
- if (const FormatAttr *Format = FD->getAttr<FormatAttr>(Context)) {
+ if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(Format)->setType("printf");
} else
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", 1,
+ FD->addAttr(::new (Context) FormatAttr("printf", 1,
Name->isStr("NSLogv") ? 0 : 2));
} else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
- if (!FD->getAttr<FormatAttr>(Context))
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", 2,
+ if (!FD->getAttr<FormatAttr>())
+ FD->addAttr(::new (Context) FormatAttr("printf", 2,
Name->isStr("vasprintf") ? 0 : 3));
}
}
@@ -3709,7 +3704,7 @@ CreateNewDecl:
// the #pragma tokens are effectively skipped over during the
// parsing of the struct).
if (unsigned Alignment = getPragmaPackAlignment())
- New->addAttr(Context, ::new (Context) PackedAttr(Alignment * 8));
+ New->addAttr(::new (Context) PackedAttr(Alignment * 8));
}
if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
@@ -3761,7 +3756,7 @@ CreateNewDecl:
S = getNonFieldDeclScope(S);
PushOnScopeChains(New, S);
} else {
- CurContext->addDecl(Context, New);
+ CurContext->addDecl(New);
}
OwnedDecl = true;
@@ -3917,7 +3912,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
} else if (II) {
PushOnScopeChains(NewFD, S);
} else
- Record->addDecl(Context, NewFD);
+ Record->addDecl(NewFD);
return NewFD;
}
@@ -4239,7 +4234,7 @@ void Sema::ActOnFields(Scope* S,
// Add ivar's to class's DeclContext.
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
ClsFields[i]->setLexicalDeclContext(ID);
- ID->addDecl(Context, ClsFields[i]);
+ ID->addDecl(ClsFields[i]);
}
// Must enforce the rule that ivars in the base classes may not be
// duplicates.
@@ -4250,7 +4245,7 @@ void Sema::ActOnFields(Scope* S,
if (IdentifierInfo *II = Ivar->getIdentifier()) {
ObjCIvarDecl* prevIvar =
- ID->getSuperClass()->lookupInstanceVariable(Context, II);
+ ID->getSuperClass()->lookupInstanceVariable(II);
if (prevIvar) {
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
@@ -4549,7 +4544,7 @@ Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext,
Loc, AsmString);
- CurContext->addDecl(Context, New);
+ CurContext->addDecl(New);
return DeclPtrTy::make(New);
}
@@ -4560,7 +4555,7 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
// FIXME: This implementation is an ugly hack!
if (PrevDecl) {
- PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) WeakAttr());
return;
}
Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
@@ -4576,8 +4571,8 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
// FIXME: This implementation is an ugly hack!
if (PrevDecl) {
- PrevDecl->addAttr(Context, ::new (Context) AliasAttr(AliasName->getName()));
- PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) AliasAttr(AliasName->getName()));
+ PrevDecl->addAttr(::new (Context) WeakAttr());
return;
}
Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f7dd9303cb47..2b71df722459 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -284,7 +284,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
if (TagDecl *TD = dyn_cast<TagDecl>(d))
- TD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
+ TD->addAttr(::new (S.Context) PackedAttr(1));
else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
// If the alignment is less than or equal to 8 bits, the packed attribute
// has no effect.
@@ -293,7 +293,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
<< Attr.getName() << FD->getType();
else
- FD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
+ FD->addAttr(::new (S.Context) PackedAttr(1));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -308,7 +308,7 @@ static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// The IBOutlet attribute only applies to instance variables of Objective-C
// classes.
if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
- d->addAttr(S.Context, ::new (S.Context) IBOutletAttr());
+ d->addAttr(::new (S.Context) IBOutletAttr());
else
S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
}
@@ -380,7 +380,7 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
unsigned* start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
std::sort(start, start + size);
- d->addAttr(S.Context, ::new (S.Context) NonNullAttr(start, size));
+ d->addAttr(::new (S.Context) NonNullAttr(start, size));
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -405,7 +405,7 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: check if target symbol exists in current file
- d->addAttr(S.Context, ::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
+ d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
}
static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -422,7 +422,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
return;
}
- d->addAttr(S.Context, ::new (S.Context) AlwaysInlineAttr());
+ d->addAttr(::new (S.Context) AlwaysInlineAttr());
}
static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
@@ -447,13 +447,13 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(S.Context, ::new (S.Context) NoReturnAttr());
+ d->addAttr(::new (S.Context) NoReturnAttr());
}
static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(S.Context, ::new (S.Context) AnalyzerNoReturnAttr());
+ d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
}
static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -469,7 +469,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) UnusedAttr());
+ d->addAttr(::new (S.Context) UnusedAttr());
}
static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -490,7 +490,7 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) UsedAttr());
}
static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -519,7 +519,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) ConstructorAttr(priority));
+ d->addAttr(::new (S.Context) ConstructorAttr(priority));
}
static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -548,7 +548,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) DestructorAttr(priority));
+ d->addAttr(::new (S.Context) DestructorAttr(priority));
}
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -558,7 +558,7 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) DeprecatedAttr());
+ d->addAttr(::new (S.Context) DeprecatedAttr());
}
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -568,7 +568,7 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) UnavailableAttr());
+ d->addAttr(::new (S.Context) UnavailableAttr());
}
static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -605,7 +605,7 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) VisibilityAttr(type));
+ d->addAttr(::new (S.Context) VisibilityAttr(type));
}
static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -621,7 +621,7 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
return;
}
- D->addAttr(S.Context, ::new (S.Context) ObjCExceptionAttr());
+ D->addAttr(::new (S.Context) ObjCExceptionAttr());
}
static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -637,7 +637,7 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
}
- D->addAttr(S.Context, ::new (S.Context) ObjCNSObjectAttr());
+ D->addAttr(::new (S.Context) ObjCNSObjectAttr());
}
static void
@@ -652,7 +652,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) OverloadableAttr());
+ D->addAttr(::new (S.Context) OverloadableAttr());
}
static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -676,7 +676,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) BlocksAttr(type));
+ d->addAttr(::new (S.Context) BlocksAttr(type));
}
static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -768,7 +768,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
<< Attr.getName() << 6 /*function, method or block */;
return;
}
- d->addAttr(S.Context, ::new (S.Context) SentinelAttr(sentinel, nullPos));
+ d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
}
static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -786,7 +786,7 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S)
return;
}
- Fn->addAttr(S.Context, ::new (S.Context) WarnUnusedResultAttr());
+ Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
}
static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -803,7 +803,7 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) WeakAttr());
+ D->addAttr(::new (S.Context) WeakAttr());
}
static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -818,7 +818,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
isDef = (!VD->hasExternalStorage() || VD->getInit());
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- isDef = FD->getBody(S.Context);
+ isDef = FD->getBody();
} else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
// We ignore weak import on properties and methods
return;
@@ -836,7 +836,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) WeakImportAttr());
+ D->addAttr(::new (S.Context) WeakImportAttr());
}
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -848,7 +848,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(S.Context, ::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr());
return;
}
@@ -876,12 +876,12 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
}
}
- if (D->getAttr<DLLExportAttr>(S.Context)) {
+ if (D->getAttr<DLLExportAttr>()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
return;
}
- D->addAttr(S.Context, ::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr());
}
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -893,7 +893,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(S.Context, ::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr());
return;
}
@@ -912,7 +912,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr());
}
static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -934,8 +934,7 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
}
WGSize[i] = (unsigned) ArgNum.getZExtValue();
}
- D->addAttr(S.Context,
- ::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+ D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
WGSize[2]));
}
@@ -955,8 +954,7 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
return;
}
- D->addAttr(S.Context,
- ::new (S.Context) SectionAttr(std::string(SE->getStrData(),
+ D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -975,13 +973,13 @@ static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// stdcall and fastcall attributes are mutually incompatible.
- if (d->getAttr<FastCallAttr>(S.Context)) {
+ if (d->getAttr<FastCallAttr>()) {
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< "stdcall" << "fastcall";
return;
}
- d->addAttr(S.Context, ::new (S.Context) StdCallAttr());
+ d->addAttr(::new (S.Context) StdCallAttr());
}
static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -998,13 +996,13 @@ static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// stdcall and fastcall attributes are mutually incompatible.
- if (d->getAttr<StdCallAttr>(S.Context)) {
+ if (d->getAttr<StdCallAttr>()) {
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< "fastcall" << "stdcall";
return;
}
- d->addAttr(S.Context, ::new (S.Context) FastCallAttr());
+ d->addAttr(::new (S.Context) FastCallAttr());
}
static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1014,7 +1012,7 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) NoThrowAttr());
+ d->addAttr(::new (S.Context) NoThrowAttr());
}
static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1024,7 +1022,7 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) ConstAttr());
+ d->addAttr(::new (S.Context) ConstAttr());
}
static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1034,7 +1032,7 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) PureAttr());
+ d->addAttr(::new (S.Context) PureAttr());
}
static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1092,7 +1090,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) CleanupAttr(FD));
+ d->addAttr(::new (S.Context) CleanupAttr(FD));
}
/// Handle __attribute__((format_arg((idx)))) attribute
@@ -1155,7 +1153,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+ d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes
@@ -1296,8 +1294,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context,
- ::new (S.Context) FormatAttr(std::string(Format, FormatLen),
+ d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
Idx.getZExtValue(), FirstArg.getZExtValue()));
}
@@ -1329,8 +1326,8 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
return;
}
- RecordDecl::field_iterator Field = RD->field_begin(S.Context),
- FieldEnd = RD->field_end(S.Context);
+ RecordDecl::field_iterator Field = RD->field_begin(),
+ FieldEnd = RD->field_end();
if (Field == FieldEnd) {
S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
return;
@@ -1365,7 +1362,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
}
}
- RD->addAttr(S.Context, ::new (S.Context) TransparentUnionAttr());
+ RD->addAttr(::new (S.Context) TransparentUnionAttr());
}
static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1383,8 +1380,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
return;
}
- d->addAttr(S.Context,
- ::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
+ d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -1400,7 +1396,7 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: This should be the target specific maximum alignment.
// (For now we just use 128 bits which is the maximum on X86).
Align = 128;
- d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Align));
+ d->addAttr(::new (S.Context) AlignedAttr(Align));
return;
}
@@ -1417,7 +1413,7 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
+ d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
}
/// HandleModeAttr - This attribute modifies the width of a decl with
@@ -1598,7 +1594,7 @@ static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) NodebugAttr());
+ d->addAttr(::new (S.Context) NodebugAttr());
}
static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1614,7 +1610,7 @@ static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) NoinlineAttr());
+ d->addAttr(::new (S.Context) NoinlineAttr());
}
static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1636,7 +1632,7 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) GNUInlineAttr());
+ d->addAttr(::new (S.Context) GNUInlineAttr());
}
static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1672,8 +1668,7 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context,
- ::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+ d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
}
//===----------------------------------------------------------------------===//
@@ -1706,10 +1701,10 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_cf_returns_retained:
- d->addAttr(S.Context, ::new (S.Context) CFReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
return;
case AttributeList::AT_ns_returns_retained:
- d->addAttr(S.Context, ::new (S.Context) NSReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
return;
};
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index cf0dab5cf298..75ceb1916555 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -258,6 +258,12 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
}
}
+ if (CheckEquivalentExceptionSpec(
+ Old->getType()->getAsFunctionProtoType(), Old->getLocation(),
+ New->getType()->getAsFunctionProtoType(), New->getLocation())) {
+ Invalid = true;
+ }
+
return Invalid;
}
@@ -481,7 +487,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
}
// Attach the remaining base class specifiers to the derived class.
- Class->setBases(Bases, NumGoodBases);
+ Class->setBases(Context, Bases, NumGoodBases);
// Delete the remaining (good) base class specifiers, since their
// data has been copied into the CXXRecordDecl.
@@ -646,7 +652,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
Sema::MemInitResult
Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -677,28 +685,31 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
// composed of a single identifier refers to the class member. A
// mem-initializer-id for the hidden base class may be specified
// using a qualified name. ]
- // Look for a member, first.
- FieldDecl *Member = 0;
- DeclContext::lookup_result Result
- = ClassDecl->lookup(Context, MemberOrBase);
- if (Result.first != Result.second)
- Member = dyn_cast<FieldDecl>(*Result.first);
-
- // FIXME: Handle members of an anonymous union.
-
- if (Member) {
- // FIXME: Perform direct initialization of the member.
- return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs);
+ if (!SS.getScopeRep() && !TemplateTypeTy) {
+ // Look for a member, first.
+ FieldDecl *Member = 0;
+ DeclContext::lookup_result Result
+ = ClassDecl->lookup(MemberOrBase);
+ if (Result.first != Result.second)
+ Member = dyn_cast<FieldDecl>(*Result.first);
+
+ // FIXME: Handle members of an anonymous union.
+
+ if (Member) {
+ // FIXME: Perform direct initialization of the member.
+ return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs,
+ IdLoc);
+ }
}
-
// It didn't name a member, so see if it names a class.
- TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, 0/*SS*/);
+ TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy
+ : getTypeName(*MemberOrBase, IdLoc, S, &SS);
if (!BaseTy)
return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
QualType BaseType = QualType::getFromOpaquePtr(BaseTy);
- if (!BaseType->isRecordType())
+ if (!BaseType->isRecordType() && !BaseType->isDependentType())
return Diag(IdLoc, diag::err_base_init_does_not_name_class)
<< BaseType << SourceRange(IdLoc, RParenLoc);
@@ -749,8 +760,18 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
if (DirectBaseSpec && VirtualBaseSpec)
return Diag(IdLoc, diag::err_base_init_direct_and_virtual)
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
+ // C++ [base.class.init]p2:
+ // Unless the mem-initializer-id names a nonstatic data membeer of the
+ // constructor's class ot a direst or virtual base of that class, the
+ // mem-initializer is ill-formed.
+ if (!DirectBaseSpec && !VirtualBaseSpec)
+ return Diag(IdLoc, diag::err_not_direct_base_or_virtual)
+ << BaseType << ClassDecl->getNameAsCString()
+ << SourceRange(IdLoc, RParenLoc);
+
- return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs);
+ return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs,
+ IdLoc);
}
void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
@@ -766,6 +787,42 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
return;
}
+ llvm::DenseMap<void*, CXXBaseOrMemberInitializer *>Members;
+ bool err = false;
+ for (unsigned i = 0; i < NumMemInits; i++) {
+ CXXBaseOrMemberInitializer *Member =
+ static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
+ void *KeyToMember = Member->getBaseOrMember();
+ // For fields injected into the class via declaration of an anonymous union,
+ // use its anonymous union class declaration as the unique key.
+ if (FieldDecl *Field = Member->getMember())
+ if (Field->getDeclContext()->isRecord() &&
+ cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
+ KeyToMember = static_cast<void *>(Field->getDeclContext());
+ CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember];
+ if (!PrevMember) {
+ PrevMember = Member;
+ continue;
+ }
+ if (FieldDecl *Field = Member->getMember())
+ Diag(Member->getSourceLocation(),
+ diag::error_multiple_mem_initialization)
+ << Field->getNameAsString();
+ else {
+ Type *BaseClass = Member->getBaseClass();
+ assert(BaseClass && "ActOnMemInitializers - neither field or base");
+ Diag(Member->getSourceLocation(),
+ diag::error_multiple_base_initialization)
+ << BaseClass->getDesugaredType(true);
+ }
+ Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer)
+ << 0;
+ err = true;
+ }
+ if (!err)
+ Constructor->setBaseOrMemberInitializers(Context,
+ reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits),
+ NumMemInits);
}
namespace {
@@ -821,8 +878,7 @@ namespace {
MethodSetTy OverriddenMethods;
size_t MethodsSize = Methods.size();
- for (RecordDecl::decl_iterator i = RD->decls_begin(Context),
- e = RD->decls_end(Context);
+ for (RecordDecl::decl_iterator i = RD->decls_begin(), e = RD->decls_end();
i != e; ++i) {
// Traverse the record, looking for methods.
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*i)) {
@@ -919,8 +975,8 @@ namespace {
bool VisitDeclContext(const DeclContext *DC) {
bool Invalid = false;
- for (CXXRecordDecl::decl_iterator I = DC->decls_begin(SemaRef.Context),
- E = DC->decls_end(SemaRef.Context); I != E; ++I)
+ for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
+ E = DC->decls_end(); I != E; ++I)
Invalid |= Visit(*I);
return Invalid;
@@ -996,8 +1052,8 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
AbstractClassUsageDiagnoser(*this, RD);
if (RD->hasTrivialConstructor() || RD->hasTrivialDestructor()) {
- 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) {
// All the nonstatic data members must have trivial constructors.
QualType FTy = i->getType();
while (const ArrayType *AT = Context.getAsArrayType(FTy))
@@ -1054,7 +1110,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
/*isImplicitlyDeclared=*/true);
DefaultCon->setAccess(AS_public);
DefaultCon->setImplicit();
- ClassDecl->addDecl(Context, DefaultCon);
+ ClassDecl->addDecl(DefaultCon);
}
if (!ClassDecl->hasUserDeclaredCopyConstructor()) {
@@ -1086,8 +1142,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// class type M (or array thereof), each such class type
// has a copy constructor whose first parameter is of type
// const M& or const volatile M&.
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- HasConstCopyConstructor && Field != ClassDecl->field_end(Context);
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
+ HasConstCopyConstructor && Field != ClassDecl->field_end();
++Field) {
QualType FieldType = (*Field)->getType();
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
@@ -1131,7 +1187,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
/*IdentifierInfo=*/0,
ArgType, VarDecl::None, 0);
CopyConstructor->setParams(Context, &FromParam, 1);
- ClassDecl->addDecl(Context, CopyConstructor);
+ ClassDecl->addDecl(CopyConstructor);
}
if (!ClassDecl->hasUserDeclaredCopyAssignment()) {
@@ -1165,8 +1221,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// type M (or array thereof), each such class type has a copy
// assignment operator whose parameter is of type const M&,
// const volatile M& or M.
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- HasConstCopyAssignment && Field != ClassDecl->field_end(Context);
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
+ HasConstCopyAssignment && Field != ClassDecl->field_end();
++Field) {
QualType FieldType = (*Field)->getType();
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
@@ -1210,7 +1266,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// Don't call addedAssignmentOperator. There is no way to distinguish an
// implicit from an explicit assignment operator.
- ClassDecl->addDecl(Context, CopyAssignment);
+ ClassDecl->addDecl(CopyAssignment);
}
if (!ClassDecl->hasUserDeclaredDestructor()) {
@@ -1229,7 +1285,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
/*isImplicitlyDeclared=*/true);
Destructor->setAccess(AS_public);
Destructor->setImplicit();
- ClassDecl->addDecl(Context, Destructor);
+ ClassDecl->addDecl(Destructor);
}
}
@@ -1772,7 +1828,7 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
// or translation unit scope. We add UsingDirectiveDecls, into
// it's lookup structure.
if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity()))
- Ctx->addDecl(Context, UDir);
+ Ctx->addDecl(UDir);
else
// Otherwise it is block-sope. using-directives will affect lookup
// only to the end of scope.
@@ -1873,7 +1929,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
(NestedNameSpecifier *)SS.getScopeRep(),
IdentLoc, R);
- CurContext->addDecl(Context, AliasDecl);
+ CurContext->addDecl(AliasDecl);
return DeclPtrTy::make(AliasDecl);
}
@@ -1891,8 +1947,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
// for its base class and its non-static data members shall have been
// implicitly defined.
bool err = false;
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
if (!BaseClassDecl->hasTrivialConstructor()) {
@@ -1909,9 +1965,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
}
}
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -1964,8 +2019,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
// implicitly defined, all the implicitly-declared default destructors
// for its base class and its non-static data members shall have been
// implicitly defined.
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
if (!BaseClassDecl->hasTrivialDestructor()) {
@@ -1978,9 +2033,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
}
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -2010,7 +2064,6 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
CXXRecordDecl *ClassDecl
= cast<CXXRecordDecl>(MethodDecl->getDeclContext());
- assert(ClassDecl && "DefineImplicitOverloadedAssign - invalid constructor");
// C++[class.copy] p12
// Before the implicitly-declared copy assignment operator for a class is
@@ -2018,17 +2071,16 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
// for its direct base classes and its nonstatic data members shall have
// been implicitly defined.
bool err = false;
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
if (CXXMethodDecl *BaseAssignOpMethod =
getAssignOperatorMethod(MethodDecl->getParamDecl(0), BaseClassDecl))
MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod);
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -2113,9 +2165,9 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
BaseClassDecl->getCopyConstructor(Context, TypeQuals))
MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor);
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -2140,7 +2192,7 @@ void Sema::InitializeVarWithConstructor(VarDecl *VD,
VD->setInit(Context, Temp);
}
-void Sema::MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType)
+void Sema::MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType)
{
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(
DeclInitType->getAsRecordType()->getDecl());
@@ -2218,7 +2270,7 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
(Expr**)Exprs.release(), NumExprs);
// FIXME. Must do all that is needed to destroy the object
// on scope exit. For now, just mark the destructor as used.
- MarcDestructorReferenced(VDecl->getLocation(), DeclInitType);
+ MarkDestructorReferenced(VDecl->getLocation(), DeclInitType);
}
return;
}
@@ -2282,7 +2334,7 @@ Sema::PerformInitializationByConstructor(QualType ClassType,
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(ClassType.getUnqualifiedType()));
DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName);
+ for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if ((Kind == IK_Direct) ||
@@ -2892,7 +2944,7 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext,
LangLoc, Language,
LBraceLoc.isValid());
- CurContext->addDecl(Context, D);
+ CurContext->addDecl(D);
PushDeclContext(S, D);
return DeclPtrTy::make(D);
}
@@ -3006,7 +3058,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
if (II)
PushOnScopeChains(ExDecl, S);
else
- CurContext->addDecl(Context, ExDecl);
+ CurContext->addDecl(ExDecl);
ProcessDeclAttributes(S, ExDecl, D);
return DeclPtrTy::make(ExDecl);
@@ -3040,7 +3092,7 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc,
AssertExpr, AssertMessage);
- CurContext->addDecl(Context, Decl);
+ CurContext->addDecl(Decl);
return DeclPtrTy::make(Decl);
}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 9013726e1aee..5cf48d6da0c8 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -379,12 +379,12 @@ void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
if (!SDecl)
return;
// FIXME: O(N^2)
- for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(Context),
- E = SDecl->prop_end(Context); S != E; ++S) {
+ for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
+ E = SDecl->prop_end(); S != E; ++S) {
ObjCPropertyDecl *SuperPDecl = (*S);
// Does property in super class has declaration in current class?
- for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(Context),
- E = IDecl->prop_end(Context); I != E; ++I) {
+ for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(),
+ E = IDecl->prop_end(); I != E; ++I) {
ObjCPropertyDecl *PDecl = (*I);
if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
DiagnosePropertyMismatch(PDecl, SuperPDecl,
@@ -404,13 +404,12 @@ Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
// Category
ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
assert (CatDecl && "MergeOneProtocolPropertiesIntoClass");
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context),
- E = PDecl->prop_end(Context); P != E; ++P) {
+ for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+ E = PDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *Pr = (*P);
ObjCCategoryDecl::prop_iterator CP, CE;
// Is this property already in category's list of properties?
- for (CP = CatDecl->prop_begin(Context), CE = CatDecl->prop_end(Context);
- CP != CE; ++CP)
+ for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP != CE; ++CP)
if ((*CP)->getIdentifier() == Pr->getIdentifier())
break;
if (CP != CE)
@@ -419,13 +418,12 @@ Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
}
return;
}
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context),
- E = PDecl->prop_end(Context); P != E; ++P) {
+ for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+ E = PDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *Pr = (*P);
ObjCInterfaceDecl::prop_iterator CP, CE;
// Is this property already in class's list of properties?
- for (CP = IDecl->prop_begin(Context), CE = IDecl->prop_end(Context);
- CP != CE; ++CP)
+ for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP)
if ((*CP)->getIdentifier() == Pr->getIdentifier())
break;
if (CP != CE)
@@ -495,16 +493,16 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
return; // Possibly due to previous error
llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
- for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(Context),
- e = ID->meth_end(Context); i != e; ++i) {
+ for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(),
+ e = ID->meth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
MethodMap[MD->getSelector()] = MD;
}
if (MethodMap.empty())
return;
- for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(Context),
- e = CAT->meth_end(Context); i != e; ++i) {
+ for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(),
+ e = CAT->meth_end(); i != e; ++i) {
ObjCMethodDecl *Method = *i;
const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
@@ -539,7 +537,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
ObjCForwardProtocolDecl *PDecl =
ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc,
&Protocols[0], Protocols.size());
- CurContext->addDecl(Context, PDecl);
+ CurContext->addDecl(PDecl);
CheckObjCDeclScope(PDecl);
return DeclPtrTy::make(PDecl);
}
@@ -555,7 +553,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
ObjCCategoryDecl *CDecl =
ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName);
// FIXME: PushOnScopeChains?
- CurContext->addDecl(Context, CDecl);
+ CurContext->addDecl(CDecl);
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
/// Check that class of this category is already completely declared.
@@ -609,7 +607,7 @@ Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
Diag(ClassLoc, diag::err_undef_interface) << ClassName;
// FIXME: PushOnScopeChains?
- CurContext->addDecl(Context, CDecl);
+ CurContext->addDecl(CDecl);
/// TODO: Check that CatName, category name, is not used in another
// implementation.
@@ -808,7 +806,7 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
return false;
// Even if property is ready only, if interface has a user defined setter,
// it is not considered read only.
- if (IDecl->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (IDecl->getInstanceMethod(PDecl->getSetterName()))
return false;
// Main class has the property as 'readonly'. Must search
@@ -818,10 +816,10 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
Category; Category = Category->getNextClassCategory()) {
// Even if property is ready only, if a category has a user defined setter,
// it is not considered read only.
- if (Category->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (Category->getInstanceMethod(PDecl->getSetterName()))
return false;
ObjCPropertyDecl *P =
- Category->FindPropertyDeclaration(Context, PDecl->getIdentifier());
+ Category->FindPropertyDeclaration(PDecl->getIdentifier());
if (P && !P->isReadOnly())
return false;
}
@@ -831,19 +829,19 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
if (ObjCImplementationDecl *IMD =
dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
- if (IMD->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (IMD->getInstanceMethod(PDecl->getSetterName()))
return false;
}
else if (ObjCCategoryImplDecl *CIMD =
dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
- if (CIMD->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (CIMD->getInstanceMethod(PDecl->getSetterName()))
return false;
}
}
// Lastly, look through the implementation (if one is in scope).
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(IDecl->getIdentifier()))
- if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
return false;
// If all fails, look at the super class.
if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
@@ -890,31 +888,30 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
// check unimplemented instance methods.
if (!NSIDecl)
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(Context),
- E = PDecl->instmeth_end(Context); I != E; ++I) {
+ for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
+ E = PDecl->instmeth_end(); I != E; ++I) {
ObjCMethodDecl *method = *I;
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!method->isSynthesized() && !InsMap.count(method->getSelector()) &&
(!Super ||
- !Super->lookupInstanceMethod(Context, method->getSelector()))) {
+ !Super->lookupInstanceMethod(method->getSelector()))) {
// Ugly, but necessary. Method declared in protcol might have
// have been synthesized due to a property declared in the class which
// uses the protocol.
ObjCMethodDecl *MethodInClass =
- IDecl->lookupInstanceMethod(Context, method->getSelector());
+ IDecl->lookupInstanceMethod(method->getSelector());
if (!MethodInClass || !MethodInClass->isSynthesized())
WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
}
}
// check unimplemented class methods
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(Context),
- E = PDecl->classmeth_end(Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I) {
ObjCMethodDecl *method = *I;
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!ClsMap.count(method->getSelector()) &&
- (!Super || !Super->lookupClassMethod(Context, method->getSelector())))
+ (!Super || !Super->lookupClassMethod(method->getSelector())))
WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
}
// Check on this protocols's referenced protocols, recursively.
@@ -937,8 +934,8 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
{
// Check and see if instance methods in class interface have been
// implemented in the implementation class. If so, their types match.
- for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
- E = CDecl->instmeth_end(Context); I != E; ++I) {
+ for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
+ E = CDecl->instmeth_end(); I != E; ++I) {
if (InsMapSeen.count((*I)->getSelector()))
continue;
InsMapSeen.insert((*I)->getSelector());
@@ -950,9 +947,9 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
}
else {
ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
+ IMPDecl->getInstanceMethod((*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
- CDecl->getInstanceMethod(Context, (*I)->getSelector());
+ CDecl->getInstanceMethod((*I)->getSelector());
assert(IntfMethodDecl &&
"IntfMethodDecl is null in ImplMethodsVsClassMethods");
// ImpMethodDecl may be null as in a @dynamic property.
@@ -964,9 +961,7 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
// Check and see if class methods in class interface have been
// implemented in the implementation class. If so, their types match.
for (ObjCInterfaceDecl::classmeth_iterator
- I = CDecl->classmeth_begin(Context),
- E = CDecl->classmeth_end(Context);
- I != E; ++I) {
+ I = CDecl->classmeth_begin(), E = CDecl->classmeth_end(); I != E; ++I) {
if (ClsMapSeen.count((*I)->getSelector()))
continue;
ClsMapSeen.insert((*I)->getSelector());
@@ -975,10 +970,10 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
}
else {
- ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getClassMethod(Context, (*I)->getSelector());
+ ObjCMethodDecl *ImpMethodDecl =
+ IMPDecl->getClassMethod((*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
- CDecl->getClassMethod(Context, (*I)->getSelector());
+ CDecl->getClassMethod((*I)->getSelector());
WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
}
}
@@ -1003,24 +998,23 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
// Check and see if instance methods in class interface have been
// implemented in the implementation class.
for (ObjCImplementationDecl::instmeth_iterator
- I = IMPDecl->instmeth_begin(Context),
- E = IMPDecl->instmeth_end(Context); I != E; ++I)
+ I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
InsMap.insert((*I)->getSelector());
// Check and see if properties declared in the interface have either 1)
// an implementation or 2) there is a @synthesize/@dynamic implementation
// of the property in the @implementation.
if (isa<ObjCInterfaceDecl>(CDecl))
- for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(Context),
- E = CDecl->prop_end(Context); P != E; ++P) {
+ for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(),
+ E = CDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *Prop = (*P);
if (Prop->isInvalidDecl())
continue;
ObjCPropertyImplDecl *PI = 0;
// Is there a matching propery synthesize/dynamic?
for (ObjCImplDecl::propimpl_iterator
- I = IMPDecl->propimpl_begin(Context),
- EI = IMPDecl->propimpl_end(Context); I != EI; ++I)
+ I = IMPDecl->propimpl_begin(),
+ EI = IMPDecl->propimpl_end(); I != EI; ++I)
if ((*I)->getPropertyDecl() == Prop) {
PI = (*I);
break;
@@ -1046,8 +1040,8 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
llvm::DenseSet<Selector> ClsMap;
for (ObjCImplementationDecl::classmeth_iterator
- I = IMPDecl->classmeth_begin(Context),
- E = IMPDecl->classmeth_end(Context); I != E; ++I)
+ I = IMPDecl->classmeth_begin(),
+ E = IMPDecl->classmeth_end(); I != E; ++I)
ClsMap.insert((*I)->getSelector());
// Check for type conflict of methods declared in a class/protocol and
@@ -1134,7 +1128,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
&Interfaces[0],
Interfaces.size());
- CurContext->addDecl(Context, CDecl);
+ CurContext->addDecl(CDecl);
CheckObjCDeclScope(CDecl);
return DeclPtrTy::make(CDecl);
}
@@ -1348,8 +1342,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
ObjCContainerDecl *CD) {
ObjCMethodDecl *GetterMethod, *SetterMethod;
- GetterMethod = CD->getInstanceMethod(Context, property->getGetterName());
- SetterMethod = CD->getInstanceMethod(Context, property->getSetterName());
+ GetterMethod = CD->getInstanceMethod(property->getGetterName());
+ SetterMethod = CD->getInstanceMethod(property->getSetterName());
DiagnosePropertyAccessorMismatch(property, GetterMethod,
property->getLocation());
@@ -1384,7 +1378,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
- CD->addDecl(Context, GetterMethod);
+ CD->addDecl(GetterMethod);
} else
// A user declared getter will be synthesize when @synthesize of
// the property with the same name is seen in the @implementation
@@ -1415,7 +1409,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
VarDecl::None,
0);
SetterMethod->setMethodParams(Context, &Argument, 1);
- CD->addDecl(Context, SetterMethod);
+ CD->addDecl(SetterMethod);
} else
// A user declared setter will be synthesize when @synthesize of
// the property with the same name is seen in the @implementation
@@ -1481,7 +1475,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
<< Method->getDeclName();
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
} else {
- DC->addDecl(Context, Method);
+ DC->addDecl(Method);
InsMap[Method->getSelector()] = Method;
/// The following allows us to typecheck messages to "id".
AddInstanceMethodToGlobalPool(Method);
@@ -1498,7 +1492,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
<< Method->getDeclName();
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
} else {
- DC->addDecl(Context, Method);
+ DC->addDecl(Method);
ClsMap[Method->getSelector()] = Method;
/// The following allows us to typecheck messages to "Class".
AddFactoryMethodToGlobalPool(Method);
@@ -1524,8 +1518,8 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
// ProcessPropertyDecl is responsible for diagnosing conflicts with any
// user-defined setter/getter. It also synthesizes setter/getter methods
// and adds them to the DeclContext and global method pools.
- for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(Context),
- E = CDecl->prop_end(Context);
+ for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
+ E = CDecl->prop_end();
I != E; ++I)
ProcessPropertyDecl(*I, CDecl);
CDecl->setAtEndLoc(AtEndLoc);
@@ -1683,11 +1677,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
if (ObjCImplementationDecl *ImpDecl =
dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
- PrevMethod = ImpDecl->getInstanceMethod(Context, Sel);
- ImpDecl->addInstanceMethod(Context, ObjCMethod);
+ PrevMethod = ImpDecl->getInstanceMethod(Sel);
+ ImpDecl->addInstanceMethod(ObjCMethod);
} else {
- PrevMethod = ImpDecl->getClassMethod(Context, Sel);
- ImpDecl->addClassMethod(Context, ObjCMethod);
+ PrevMethod = ImpDecl->getClassMethod(Sel);
+ ImpDecl->addClassMethod(ObjCMethod);
}
if (AttrList)
Diag(EndLoc, diag::warn_attribute_method_def);
@@ -1695,11 +1689,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
- PrevMethod = CatImpDecl->getInstanceMethod(Context, Sel);
- CatImpDecl->addInstanceMethod(Context, ObjCMethod);
+ PrevMethod = CatImpDecl->getInstanceMethod(Sel);
+ CatImpDecl->addInstanceMethod(ObjCMethod);
} else {
- PrevMethod = CatImpDecl->getClassMethod(Context, Sel);
- CatImpDecl->addClassMethod(Context, ObjCMethod);
+ PrevMethod = CatImpDecl->getClassMethod(Sel);
+ CatImpDecl->addClassMethod(ObjCMethod);
}
if (AttrList)
Diag(EndLoc, diag::warn_attribute_method_def);
@@ -1823,8 +1817,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
ObjCPropertyDecl *PIDecl = 0;
IdentifierInfo *PropertyId = FD.D.getIdentifier();
for (ObjCInterfaceDecl::prop_iterator
- I = CCPrimary->prop_begin(Context),
- E = CCPrimary->prop_end(Context);
+ I = CCPrimary->prop_begin(), E = CCPrimary->prop_end();
I != E; ++I)
if ((*I)->getIdentifier() == PropertyId) {
PIDecl = *I;
@@ -1870,7 +1863,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
FD.D.getIdentifierLoc(),
FD.D.getIdentifier(), T);
- DC->addDecl(Context, PDecl);
+ DC->addDecl(PDecl);
if (T->isArrayType() || T->isFunctionType()) {
Diag(AtLoc, diag::err_property_type) << T;
@@ -1951,7 +1944,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
"ActOnPropertyImplDecl - @implementation without @interface");
// Look for this property declaration in the @implementation's @interface
- property = IDecl->FindPropertyDeclaration(Context, PropertyId);
+ property = IDecl->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
return DeclPtrTy();
@@ -1975,7 +1968,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
if (!Category)
return DeclPtrTy();
// Look for this property declaration in @implementation's category
- property = Category->FindPropertyDeclaration(Context, PropertyId);
+ property = Category->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_category_property_decl)
<< Category->getDeclName();
@@ -1994,7 +1987,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
QualType PropType = Context.getCanonicalType(property->getType());
// Check that this is a previously declared 'ivar' in 'IDecl' interface
ObjCInterfaceDecl *ClassDeclared;
- Ivar = IDecl->lookupInstanceVariable(Context, PropertyIvar, ClassDeclared);
+ Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
if (!Ivar) {
DeclContext *EnclosingContext = cast_or_null<DeclContext>(IDecl);
assert(EnclosingContext &&
@@ -2004,7 +1997,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
ObjCIvarDecl::Public,
(Expr *)0);
Ivar->setLexicalDeclContext(IDecl);
- IDecl->addDecl(Context, Ivar);
+ IDecl->addDecl(Ivar);
property->setPropertyIvarDecl(Ivar);
if (!getLangOptions().ObjCNonFragileABI)
Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
@@ -2071,7 +2064,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
if (IC) {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
- IC->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
+ IC->FindPropertyImplIvarDecl(PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
@@ -2079,17 +2072,17 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
}
if (ObjCPropertyImplDecl *PPIDecl
- = IC->FindPropertyImplDecl(Context, PropertyId)) {
+ = IC->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
- IC->addPropertyImplementation(Context, PIDecl);
+ IC->addPropertyImplementation(PIDecl);
}
else {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
- CatImplClass->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
+ CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
@@ -2097,12 +2090,12 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
}
if (ObjCPropertyImplDecl *PPIDecl =
- CatImplClass->FindPropertyImplDecl(Context, PropertyId)) {
+ CatImplClass->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
- CatImplClass->addPropertyImplementation(Context, PIDecl);
+ CatImplClass->addPropertyImplementation(PIDecl);
}
return DeclPtrTy::make(PIDecl);
@@ -2154,7 +2147,7 @@ void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
if (getLangOptions().CPlusPlus)
PushOnScopeChains(cast<FieldDecl>(FD), S);
else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
- Record->addDecl(Context, FD);
+ Record->addDecl(FD);
}
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 383edeca07a0..a5e508396422 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -39,7 +39,7 @@ using namespace clang;
/// referenced), false otherwise.
bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
// See if the decl is deprecated.
- if (D->getAttr<DeprecatedAttr>(Context)) {
+ if (D->getAttr<DeprecatedAttr>()) {
// Implementing deprecated stuff requires referencing deprecated
// stuff. Don't warn if we are implementing a deprecated
// construct.
@@ -48,7 +48,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
if (NamedDecl *ND = getCurFunctionOrMethodDecl()) {
// If this reference happens *in* a deprecated function or method, don't
// warn.
- isSilenced = ND->getAttr<DeprecatedAttr>(Context);
+ isSilenced = ND->getAttr<DeprecatedAttr>();
// If this is an Objective-C method implementation, check to see if the
// method was deprecated on the declaration, not the definition.
@@ -58,10 +58,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
if (ObjCImplementationDecl *Impl
= dyn_cast<ObjCImplementationDecl>(MD->getParent())) {
- MD = Impl->getClassInterface()->getMethod(Context,
- MD->getSelector(),
+ MD = Impl->getClassInterface()->getMethod(MD->getSelector(),
MD->isInstanceMethod());
- isSilenced |= MD && MD->getAttr<DeprecatedAttr>(Context);
+ isSilenced |= MD && MD->getAttr<DeprecatedAttr>();
}
}
}
@@ -80,7 +79,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
}
// See if the decl is unavailable
- if (D->getAttr<UnavailableAttr>(Context)) {
+ if (D->getAttr<UnavailableAttr>()) {
Diag(Loc, diag::warn_unavailable) << D->getDeclName();
Diag(D->getLocation(), diag::note_unavailable_here) << 0;
}
@@ -95,7 +94,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
Expr **Args, unsigned NumArgs)
{
- const SentinelAttr *attr = D->getAttr<SentinelAttr>(Context);
+ const SentinelAttr *attr = D->getAttr<SentinelAttr>();
if (!attr)
return;
int sentinelPos = attr->getSentinel();
@@ -673,8 +672,8 @@ static Decl *getObjectForAnonymousRecordDecl(ASTContext &Context,
// operation rather than a slow walk through DeclContext's vector (which
// itself will be eliminated). DeclGroups might make this even better.
DeclContext *Ctx = Record->getDeclContext();
- for (DeclContext::decl_iterator D = Ctx->decls_begin(Context),
- DEnd = Ctx->decls_end(Context);
+ for (DeclContext::decl_iterator D = Ctx->decls_begin(),
+ DEnd = Ctx->decls_end();
D != DEnd; ++D) {
if (*D == Record) {
// The object for the anonymous struct/union directly
@@ -877,8 +876,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
ObjCInterfaceDecl *ClassDeclared;
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(Context, II,
- ClassDeclared)) {
+ if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
// Check if referencing a field with __attribute__((deprecated)).
if (DiagnoseUseOfDecl(IV, Loc))
return ExprError();
@@ -915,8 +913,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// We should warn if a local variable hides an ivar.
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
ObjCInterfaceDecl *ClassDeclared;
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(Context, II,
- ClassDeclared)) {
+ if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
if (IV->getAccessControl() != ObjCIvarDecl::Private ||
IFace == ClassDeclared)
Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
@@ -973,7 +970,64 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
return ExprError(Diag(Loc, diag::err_undeclared_var_use) << Name);
}
}
+
+ if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ // Warn about constructs like:
+ // if (void *X = foo()) { ... } else { X }.
+ // In the else block, the pointer is always false.
+
+ // FIXME: In a template instantiation, we don't have scope
+ // information to check this property.
+ if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
+ Scope *CheckS = S;
+ while (CheckS) {
+ if (CheckS->isWithinElse() &&
+ CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
+ if (Var->getType()->isBooleanType())
+ ExprError(Diag(Loc, diag::warn_value_always_false)
+ << Var->getDeclName());
+ else
+ ExprError(Diag(Loc, diag::warn_value_always_zero)
+ << Var->getDeclName());
+ break;
+ }
+
+ // Move up one more control parent to check again.
+ CheckS = CheckS->getControlParent();
+ if (CheckS)
+ CheckS = CheckS->getParent();
+ }
+ }
+ } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
+ if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
+ // C99 DR 316 says that, if a function type comes from a
+ // function definition (without a prototype), that type is only
+ // used for checking compatibility. Therefore, when referencing
+ // the function, we pretend that we don't have the full function
+ // type.
+ if (DiagnoseUseOfDecl(Func, Loc))
+ return ExprError();
+
+ QualType T = Func->getType();
+ QualType NoProtoType = T;
+ if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
+ NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
+ return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS);
+ }
+ }
+
+ return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand);
+}
+/// \brief Complete semantic analysis for a reference to the given declaration.
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
+ bool HasTrailingLParen,
+ const CXXScopeSpec *SS,
+ bool isAddressOfOperand) {
+ assert(D && "Cannot refer to a NULL declaration");
+ DeclarationName Name = D->getDeclName();
+
// If this is an expression of the form &Class::member, don't build an
// implicit member ref, because we want a pointer to the member in general,
// not any specific instance's member.
@@ -1097,51 +1151,11 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// this check when we're going to perform argument-dependent lookup
// on this function name, because this might not be the function
// that overload resolution actually selects.
+ bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
+ HasTrailingLParen;
if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
return ExprError();
- if (VarDecl *Var = dyn_cast<VarDecl>(VD)) {
- // Warn about constructs like:
- // if (void *X = foo()) { ... } else { X }.
- // In the else block, the pointer is always false.
-
- // FIXME: In a template instantiation, we don't have scope
- // information to check this property.
- if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
- Scope *CheckS = S;
- while (CheckS) {
- if (CheckS->isWithinElse() &&
- CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
- if (Var->getType()->isBooleanType())
- ExprError(Diag(Loc, diag::warn_value_always_false)
- << Var->getDeclName());
- else
- ExprError(Diag(Loc, diag::warn_value_always_zero)
- << Var->getDeclName());
- break;
- }
-
- // Move up one more control parent to check again.
- CheckS = CheckS->getControlParent();
- if (CheckS)
- CheckS = CheckS->getParent();
- }
- }
- } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(VD)) {
- if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
- // C99 DR 316 says that, if a function type comes from a
- // function definition (without a prototype), that type is only
- // used for checking compatibility. Therefore, when referencing
- // the function, we pretend that we don't have the full function
- // type.
- QualType T = Func->getType();
- QualType NoProtoType = T;
- if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
- NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
- return BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS);
- }
- }
-
// Only create DeclRefExpr's for valid Decl's.
if (VD->isInvalidDecl())
return ExprError();
@@ -1158,7 +1172,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
MarkDeclarationReferenced(Loc, VD);
QualType ExprTy = VD->getType().getNonReferenceType();
// The BlocksAttr indicates the variable is bound by-reference.
- if (VD->getAttr<BlocksAttr>(Context))
+ if (VD->getAttr<BlocksAttr>())
return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true));
// This is to record that a 'const' was actually synthesize and added.
bool constAdded = !ExprTy.isConstQualified();
@@ -1310,8 +1324,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// isExact will be set by GetFloatValue().
bool isExact = false;
- Res = new (Context) FloatingLiteral(Literal.GetFloatValue(Format, &isExact),
- &isExact, Ty, Tok.getLocation());
+ llvm::APFloat Val = Literal.GetFloatValue(Format, &isExact);
+ Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
} else if (!Literal.isIntegerLiteral()) {
return ExprError();
@@ -1989,9 +2003,9 @@ static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
const Selector &Sel,
ASTContext &Context) {
- if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(Context, &Member))
+ if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(&Member))
return PD;
- if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Context, Sel))
+ if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
return OMD;
for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
@@ -2011,12 +2025,12 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
Decl *GDecl = 0;
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
E = QIdTy->qual_end(); I != E; ++I) {
- if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context, &Member)) {
+ if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
GDecl = PD;
break;
}
// Also must look for a getter name which uses property syntax.
- if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Context, Sel)) {
+ if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
GDecl = OMD;
break;
}
@@ -2042,7 +2056,7 @@ ObjCMethodDecl *Sema::FindMethodInNestedImplementations(
ObjCMethodDecl *Method = 0;
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(IFace->getIdentifier()))
- Method = ImpDecl->getInstanceMethod(Context, Sel);
+ Method = ImpDecl->getInstanceMethod(Sel);
if (!Method && IFace->getSuperClass())
return FindMethodInNestedImplementations(IFace->getSuperClass(), Sel);
@@ -2201,8 +2215,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// (*Obj).ivar.
if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) {
ObjCInterfaceDecl *ClassDeclared;
- if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(Context,
- &Member,
+ if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member,
ClassDeclared)) {
// If the decl being referenced had an error, return an error for this
// sub-expr without emitting another error, in order to avoid cascading
@@ -2262,14 +2275,13 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
ObjCInterfaceDecl *IFace = IFTy->getDecl();
// Search for a declared property first.
- if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Context,
- &Member)) {
+ if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member)) {
// Check whether we can reference this property.
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
QualType ResTy = PD->getType();
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel);
+ ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
ResTy = Getter->getResultType();
return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
@@ -2279,8 +2291,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// Check protocols on qualified interfaces.
for (ObjCInterfaceType::qual_iterator I = IFTy->qual_begin(),
E = IFTy->qual_end(); I != E; ++I)
- if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context,
- &Member)) {
+ if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
// Check whether we can reference this property.
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
@@ -2296,7 +2307,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// shared with the code in ActOnInstanceMessage.
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel);
+ ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
// If this reference is in an @implementation, check for 'private' methods.
if (!Getter)
@@ -2306,7 +2317,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Getter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Getter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Getter = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
+ Getter = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
}
}
if (Getter) {
@@ -2319,7 +2330,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
Selector SetterSel =
SelectorTable::constructSetterName(PP.getIdentifierTable(),
PP.getSelectorTable(), &Member);
- ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(Context, SetterSel);
+ ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
if (!Setter) {
// If this reference is in an @implementation, also check for 'private'
// methods.
@@ -2329,7 +2340,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getInstanceMethod(Context, SetterSel);
+ Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
}
}
@@ -2390,7 +2401,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
ObjCInterfaceDecl *IFace = MD->getClassInterface();
ObjCMethodDecl *Getter;
// FIXME: need to also look locally in the implementation.
- if ((Getter = IFace->lookupClassMethod(Context, Sel))) {
+ if ((Getter = IFace->lookupClassMethod(Sel))) {
// Check the use of this method.
if (DiagnoseUseOfDecl(Getter, MemberLoc))
return ExprError();
@@ -2400,7 +2411,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
Selector SetterSel =
SelectorTable::constructSetterName(PP.getIdentifierTable(),
PP.getSelectorTable(), &Member);
- ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel);
+ ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
if (!Setter) {
// If this reference is in an @implementation, also check for 'private'
// methods.
@@ -2410,7 +2421,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
+ Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
}
}
@@ -2624,9 +2635,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
}
// If we're directly calling a function, get the appropriate declaration.
- DeclRefExpr *DRExpr = NULL;
+ // Also, in C++, keep track of whether we should perform argument-dependent
+ // lookup and whether there were any explicitly-specified template arguments.
Expr *FnExpr = Fn;
bool ADL = true;
+ bool HasExplicitTemplateArgs = 0;
+ const TemplateArgument *ExplicitTemplateArgs = 0;
+ unsigned NumExplicitTemplateArgs = 0;
while (true) {
if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(FnExpr))
FnExpr = IcExpr->getSubExpr();
@@ -2639,14 +2654,41 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
cast<UnaryOperator>(FnExpr)->getOpcode()
== UnaryOperator::AddrOf) {
FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
- } else if ((DRExpr = dyn_cast<DeclRefExpr>(FnExpr))) {
+ } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
// Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
ADL &= !isa<QualifiedDeclRefExpr>(DRExpr);
+ NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
break;
} else if (UnresolvedFunctionNameExpr *DepName
= dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
UnqualifiedName = DepName->getName();
break;
+ } else if (TemplateIdRefExpr *TemplateIdRef
+ = dyn_cast<TemplateIdRefExpr>(FnExpr)) {
+ NDecl = TemplateIdRef->getTemplateName().getAsTemplateDecl();
+ HasExplicitTemplateArgs = true;
+ ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
+ NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
+
+ // C++ [temp.arg.explicit]p6:
+ // [Note: For simple function names, argument dependent lookup (3.4.2)
+ // applies even when the function name is not visible within the
+ // scope of the call. This is because the call still has the syntactic
+ // form of a function call (3.4.1). But when a function template with
+ // explicit template arguments is used, the call does not have the
+ // correct syntactic form unless there is a function template with
+ // that name visible at the point of the call. If no such name is
+ // visible, the call is not syntactically well-formed and
+ // argument-dependent lookup does not apply. If some such name is
+ // visible, argument dependent lookup applies and additional function
+ // templates may be found in other namespaces.
+ //
+ // The summary of this paragraph is that, if we get to this point and the
+ // template-id was not a qualified name, then argument-dependent lookup
+ // is still possible.
+ if (TemplateIdRef->getQualifier())
+ ADL = false;
+ break;
} else {
// Any kind of name that does not refer to a declaration (or
// set of declarations) disables ADL (C++0x [basic.lookup.argdep]p3).
@@ -2657,14 +2699,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
OverloadedFunctionDecl *Ovl = 0;
FunctionTemplateDecl *FunctionTemplate = 0;
- if (DRExpr) {
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
- if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DRExpr->getDecl())))
+ if (NDecl) {
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
+ if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl)))
FDecl = FunctionTemplate->getTemplatedDecl();
else
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
- Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
- NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
+ Ovl = dyn_cast<OverloadedFunctionDecl>(NDecl);
}
if (Ovl || FunctionTemplate ||
@@ -2678,16 +2719,19 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
ADL = false;
if (Ovl || FunctionTemplate || ADL) {
- FDecl = ResolveOverloadedCallFn(Fn, DRExpr? DRExpr->getDecl() : 0,
- UnqualifiedName, LParenLoc, Args,
- NumArgs, CommaLocs, RParenLoc, ADL);
+ FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName,
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ LParenLoc, Args, NumArgs, CommaLocs,
+ RParenLoc, ADL);
if (!FDecl)
return ExprError();
// Update Fn to refer to the actual function selected.
Expr *NewFn = 0;
if (QualifiedDeclRefExpr *QDRExpr
- = dyn_cast_or_null<QualifiedDeclRefExpr>(DRExpr))
+ = dyn_cast<QualifiedDeclRefExpr>(FnExpr))
NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(),
QDRExpr->getLocation(),
false, false,
@@ -2750,7 +2794,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// Check if we have too few/too many template arguments, based
// on our knowledge of the function definition.
const FunctionDecl *Def = 0;
- if (FDecl->getBody(Context, Def) && NumArgs != Def->param_size()) {
+ if (FDecl->getBody(Def) && NumArgs != Def->param_size()) {
const FunctionProtoType *Proto =
Def->getType()->getAsFunctionProtoType();
if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {
@@ -2860,7 +2904,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) {
// GCC cast to union extension
RecordDecl *RD = castType->getAsRecordType()->getDecl();
RecordDecl::field_iterator Field, FieldEnd;
- for (Field = RD->field_begin(Context), FieldEnd = RD->field_end(Context);
+ for (Field = RD->field_begin(), FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
if (Context.getCanonicalType(Field->getType()).getUnqualifiedType() ==
Context.getCanonicalType(castExpr->getType()).getUnqualifiedType()) {
@@ -2931,19 +2975,8 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) {
bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
assert(DestTy->isExtVectorType() && "Not an extended vector type!");
- // If SrcTy is also an ExtVectorType, the types must be identical unless
- // lax vector conversions is enabled.
- if (SrcTy->isExtVectorType()) {
- if (getLangOptions().LaxVectorConversions &&
- Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy))
- return false;
- if (DestTy != SrcTy)
- return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
- << DestTy << SrcTy << R;
- return false;
- }
-
- // If SrcTy is a VectorType, then only the total size must match.
+ // If SrcTy is a VectorType, the total size must match to explicitly cast to
+ // an ExtVectorType.
if (SrcTy->isVectorType()) {
if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
@@ -2951,9 +2984,13 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
return false;
}
- // All scalar -> ext vector "c-style" casts are legal; the appropriate
+ // All non-pointer scalars can be cast to ExtVector type. The appropriate
// conversion will take place first from scalar to elt type, and then
// splat from elt type to vector.
+ if (SrcTy->isPointerType())
+ return Diag(R.getBegin(),
+ diag::err_invalid_conversion_between_vector_and_scalar)
+ << DestTy << SrcTy << R;
return false;
}
@@ -3042,24 +3079,133 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
ImpCastExprToType(LHS, RHSTy); // promote the null to a pointer.
return RHSTy;
}
+ // Handle block pointer types.
+ if (LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) {
+ if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
+ if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
+ QualType destType = Context.getPointerType(Context.VoidTy);
+ ImpCastExprToType(LHS, destType);
+ ImpCastExprToType(RHS, destType);
+ return destType;
+ }
+ Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
+ << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+ return QualType();
+ }
+ // We have 2 block pointer types.
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ // Two identical block pointer types are always compatible.
+ return LHSTy;
+ }
+ // The block pointer types aren't identical, continue checking.
+ QualType lhptee = LHSTy->getAsBlockPointerType()->getPointeeType();
+ QualType rhptee = RHSTy->getAsBlockPointerType()->getPointeeType();
- const PointerType *LHSPT = LHSTy->getAsPointerType();
- const PointerType *RHSPT = RHSTy->getAsPointerType();
- const BlockPointerType *LHSBPT = LHSTy->getAsBlockPointerType();
- const BlockPointerType *RHSBPT = RHSTy->getAsBlockPointerType();
+ if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+ rhptee.getUnqualifiedType())) {
+ Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
+ << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+ // In this situation, we assume void* type. No especially good
+ // reason, but this is what gcc does, and we do have to pick
+ // to get a consistent AST.
+ QualType incompatTy = Context.getPointerType(Context.VoidTy);
+ ImpCastExprToType(LHS, incompatTy);
+ ImpCastExprToType(RHS, incompatTy);
+ return incompatTy;
+ }
+ // The block pointer types are compatible.
+ ImpCastExprToType(LHS, LHSTy);
+ ImpCastExprToType(RHS, LHSTy);
+ return LHSTy;
+ }
+ // Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
+ // evaluates to "struct objc_object *" (and is handled above when comparing
+ // id with statically typed objects).
+ if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) {
+ // GCC allows qualified id and any Objective-C type to devolve to
+ // id. Currently localizing to here until clear this should be
+ // part of ObjCQualifiedIdTypesAreCompatible.
+ if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) ||
+ (LHSTy->isObjCQualifiedIdType() &&
+ Context.isObjCObjectPointerType(RHSTy)) ||
+ (RHSTy->isObjCQualifiedIdType() &&
+ Context.isObjCObjectPointerType(LHSTy))) {
+ // FIXME: This is not the correct composite type. This only happens to
+ // work because id can more or less be used anywhere, however this may
+ // change the type of method sends.
- // Handle the case where both operands are pointers before we handle null
- // pointer constants in case both operands are null pointer constants.
- if ((LHSPT || LHSBPT) && (RHSPT || RHSBPT)) { // C99 6.5.15p3,6
+ // FIXME: gcc adds some type-checking of the arguments and emits
+ // (confusing) incompatible comparison warnings in some
+ // cases. Investigate.
+ QualType compositeType = Context.getObjCIdType();
+ ImpCastExprToType(LHS, compositeType);
+ ImpCastExprToType(RHS, compositeType);
+ return compositeType;
+ }
+ }
+ // Check constraints for Objective-C object pointers types.
+ if (Context.isObjCObjectPointerType(LHSTy) &&
+ Context.isObjCObjectPointerType(RHSTy)) {
+
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ // Two identical object pointer types are always compatible.
+ return LHSTy;
+ }
+ // No need to check for block pointer types or qualified id types (they
+ // were handled above).
+ assert((LHSTy->isPointerType() && RHSTy->isPointerType()) &&
+ "Sema::CheckConditionalOperands(): Unexpected type");
+ QualType lhptee = LHSTy->getAsPointerType()->getPointeeType();
+ QualType rhptee = RHSTy->getAsPointerType()->getPointeeType();
+
+ QualType compositeType = LHSTy;
+
+ // If both operands are interfaces and either operand can be
+ // assigned to the other, use that type as the composite
+ // type. This allows
+ // xxx ? (A*) a : (B*) b
+ // where B is a subclass of A.
+ //
+ // Additionally, as for assignment, if either type is 'id'
+ // allow silent coercion. Finally, if the types are
+ // incompatible then make sure to use 'id' as the composite
+ // type so the result is acceptable for sending messages to.
+
+ // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
+ // It could return the composite type.
+ const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
+ const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
+ if (LHSIface && RHSIface &&
+ Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
+ compositeType = LHSTy;
+ } else if (LHSIface && RHSIface &&
+ Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
+ compositeType = RHSTy;
+ } else if (Context.isObjCIdStructType(lhptee) ||
+ Context.isObjCIdStructType(rhptee)) {
+ compositeType = Context.getObjCIdType();
+ } else {
+ Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
+ << LHSTy << RHSTy
+ << LHS->getSourceRange() << RHS->getSourceRange();
+ QualType incompatTy = Context.getObjCIdType();
+ ImpCastExprToType(LHS, incompatTy);
+ ImpCastExprToType(RHS, incompatTy);
+ return incompatTy;
+ }
+ // The object pointer types are compatible.
+ ImpCastExprToType(LHS, compositeType);
+ ImpCastExprToType(RHS, compositeType);
+ return compositeType;
+ }
+ // Check constraints for C object pointers types (C99 6.5.15p3,6).
+ if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
// get the "pointed to" types
- QualType lhptee = (LHSPT ? LHSPT->getPointeeType()
- : LHSBPT->getPointeeType());
- QualType rhptee = (RHSPT ? RHSPT->getPointeeType()
- : RHSBPT->getPointeeType());
+ QualType lhptee = LHSTy->getAsPointerType()->getPointeeType();
+ QualType rhptee = RHSTy->getAsPointerType()->getPointeeType();
// ignore qualifiers on void (C99 6.5.15p3, clause 6)
- if (lhptee->isVoidType()
- && (RHSBPT || rhptee->isIncompleteOrObjectType())) {
+ if (lhptee->isVoidType() && rhptee->isIncompleteOrObjectType()) {
// Figure out necessary qualifiers (C99 6.5.15p6)
QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers());
QualType destType = Context.getPointerType(destPointee);
@@ -3067,8 +3213,7 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
ImpCastExprToType(RHS, destType); // promote to void*
return destType;
}
- if (rhptee->isVoidType()
- && (LHSBPT || lhptee->isIncompleteOrObjectType())) {
+ if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers());
QualType destType = Context.getPointerType(destPointee);
ImpCastExprToType(LHS, destType); // add qualifiers if necessary
@@ -3076,62 +3221,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
return destType;
}
- bool sameKind = (LHSPT && RHSPT) || (LHSBPT && RHSBPT);
- if (sameKind
- && Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
// Two identical pointer types are always compatible.
return LHSTy;
}
-
- QualType compositeType = LHSTy;
-
- // If either type is an Objective-C object type then check
- // compatibility according to Objective-C.
- if (Context.isObjCObjectPointerType(LHSTy) ||
- Context.isObjCObjectPointerType(RHSTy)) {
- // If both operands are interfaces and either operand can be
- // assigned to the other, use that type as the composite
- // type. This allows
- // xxx ? (A*) a : (B*) b
- // where B is a subclass of A.
- //
- // Additionally, as for assignment, if either type is 'id'
- // allow silent coercion. Finally, if the types are
- // incompatible then make sure to use 'id' as the composite
- // type so the result is acceptable for sending messages to.
-
- // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
- // It could return the composite type.
- const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
- const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
- if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
- compositeType = LHSTy;
- } else if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
- compositeType = RHSTy;
- } else if (Context.isObjCIdStructType(lhptee) ||
- Context.isObjCIdStructType(rhptee)) {
- compositeType = Context.getObjCIdType();
- } else if (LHSBPT || RHSBPT) {
- if (!sameKind
- || !Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType()))
- Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
- << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
- return QualType();
- } else {
- Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
- << LHSTy << RHSTy
- << LHS->getSourceRange() << RHS->getSourceRange();
- QualType incompatTy = Context.getObjCIdType();
- ImpCastExprToType(LHS, incompatTy);
- ImpCastExprToType(RHS, incompatTy);
- return incompatTy;
- }
- } else if (!sameKind
- || !Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType())) {
+ if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+ rhptee.getUnqualifiedType())) {
Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
// In this situation, we assume void* type. No especially good
@@ -3149,11 +3244,11 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// type.
// FIXME: Need to calculate the composite type.
// FIXME: Need to add qualifiers
- ImpCastExprToType(LHS, compositeType);
- ImpCastExprToType(RHS, compositeType);
- return compositeType;
+ ImpCastExprToType(LHS, LHSTy);
+ ImpCastExprToType(RHS, LHSTy);
+ return LHSTy;
}
-
+
// GCC compatibility: soften pointer/integer mismatch.
if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
@@ -3168,32 +3263,6 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
return LHSTy;
}
- // Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
- // evaluates to "struct objc_object *" (and is handled above when comparing
- // id with statically typed objects).
- if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) {
- // GCC allows qualified id and any Objective-C type to devolve to
- // id. Currently localizing to here until clear this should be
- // part of ObjCQualifiedIdTypesAreCompatible.
- if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) ||
- (LHSTy->isObjCQualifiedIdType() &&
- Context.isObjCObjectPointerType(RHSTy)) ||
- (RHSTy->isObjCQualifiedIdType() &&
- Context.isObjCObjectPointerType(LHSTy))) {
- // FIXME: This is not the correct composite type. This only happens to
- // work because id can more or less be used anywhere, however this may
- // change the type of method sends.
-
- // FIXME: gcc adds some type-checking of the arguments and emits
- // (confusing) incompatible comparison warnings in some
- // cases. Investigate.
- QualType compositeType = Context.getObjCIdType();
- ImpCastExprToType(LHS, compositeType);
- ImpCastExprToType(RHS, compositeType);
- return compositeType;
- }
- }
-
// Otherwise, the operands are not compatible.
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
@@ -3385,12 +3454,16 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
return IncompatibleObjCQualifiedId;
}
+ // Allow scalar to ExtVector assignments, and assignments of an ExtVector type
+ // to the same ExtVector type.
+ if (lhsType->isExtVectorType()) {
+ if (rhsType->isExtVectorType())
+ return lhsType == rhsType ? Compatible : Incompatible;
+ if (!rhsType->isVectorType() && rhsType->isArithmeticType())
+ return Compatible;
+ }
+
if (lhsType->isVectorType() || rhsType->isVectorType()) {
- // For ExtVector, allow vector splats; float -> <n x float>
- if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
- if (LV->getElementType() == rhsType)
- return Compatible;
-
// If we are allowing lax vector conversions, and LHS and RHS are both
// vectors, the total size only needs to be the same. This is a bitcast;
// no bits are changed but the result type is different.
@@ -3492,15 +3565,15 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
// If the ArgType is a Union type, we want to handle a potential
// transparent_union GCC extension.
const RecordType *UT = ArgType->getAsUnionType();
- if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>(Context))
+ if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
return Incompatible;
// The field to initialize within the transparent union.
RecordDecl *UD = UT->getDecl();
FieldDecl *InitField = 0;
// It's compatible if the expression matches any of the fields.
- for (RecordDecl::field_iterator it = UD->field_begin(Context),
- itend = UD->field_end(Context);
+ for (RecordDecl::field_iterator it = UD->field_begin(),
+ itend = UD->field_end();
it != itend; ++it) {
if (it->getType()->isPointerType()) {
// If the transparent union contains a pointer type, we allow:
@@ -3617,33 +3690,36 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex,
}
}
- // If the lhs is an extended vector and the rhs is a scalar of the same type
- // or a literal, promote the rhs to the vector type.
- if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
- ImpCastExprToType(rex, lhsType);
- return lhsType;
- }
+ // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
+ // swap back (so that we don't reverse the inputs to a subtract, for instance.
+ bool swapped = false;
+ if (rhsType->isExtVectorType()) {
+ swapped = true;
+ std::swap(rex, lex);
+ std::swap(rhsType, lhsType);
}
-
- // If the rhs is an extended vector and the lhs is a scalar of the same type,
- // promote the lhs to the vector type.
- if (const ExtVectorType *V = rhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
- ImpCastExprToType(lex, rhsType);
- return rhsType;
+
+ // Handle the case of an ext vector and scalar.
+ if (const ExtVectorType *LV = lhsType->getAsExtVectorType()) {
+ QualType EltTy = LV->getElementType();
+ if (EltTy->isIntegralType() && rhsType->isIntegralType()) {
+ if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
+ ImpCastExprToType(rex, lhsType);
+ if (swapped) std::swap(rex, lex);
+ return lhsType;
+ }
+ }
+ if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
+ rhsType->isRealFloatingType()) {
+ if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
+ ImpCastExprToType(rex, lhsType);
+ if (swapped) std::swap(rex, lex);
+ return lhsType;
+ }
}
}
-
- // You cannot convert between vector values of different size.
+
+ // Vectors of different size or scalar and non-ext-vector are errors.
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< lex->getType() << rex->getType()
<< lex->getSourceRange() << rex->getSourceRange();
@@ -4034,6 +4110,17 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
QualType RCanPointeeTy =
Context.getCanonicalType(rType->getAsPointerType()->getPointeeType());
+ if (rType->isFunctionPointerType() || lType->isFunctionPointerType()) {
+ if (isRelational) {
+ Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ }
+ }
+ if (((!LHSIsNull || isRelational) && LCanPointeeTy->isVoidType()) !=
+ ((!RHSIsNull || isRelational) && RCanPointeeTy->isVoidType())) {
+ Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ }
// Simple check: if the pointee types are identical, we're done.
if (LCanPointeeTy == RCanPointeeTy)
return ResultTy;
@@ -4146,7 +4233,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
}
if ((lType->isPointerType() || lType->isObjCQualifiedIdType()) &&
rType->isIntegerType()) {
- if (!RHSIsNull)
+ if (isRelational)
+ Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ else if (!RHSIsNull)
Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
ImpCastExprToType(rex, lType); // promote the integer to pointer
@@ -4154,7 +4244,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
}
if (lType->isIntegerType() &&
(rType->isPointerType() || rType->isObjCQualifiedIdType())) {
- if (!LHSIsNull)
+ if (isRelational)
+ Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ else if (!LHSIsNull)
Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
ImpCastExprToType(lex, rType); // promote the integer to pointer
@@ -5226,7 +5319,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
CurBlock->hasPrototype = true;
CurBlock->isVariadic = false;
// Check for a valid sentinel attribute on this block.
- if (CurBlock->TheDecl->getAttr<SentinelAttr>(Context)) {
+ if (CurBlock->TheDecl->getAttr<SentinelAttr>()) {
Diag(ParamInfo.getAttributes()->getLoc(),
diag::warn_attribute_sentinel_not_variadic) << 1;
// FIXME: remove the attribute.
@@ -5275,7 +5368,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
// Check for a valid sentinel attribute on this block.
if (!CurBlock->isVariadic &&
- CurBlock->TheDecl->getAttr<SentinelAttr>(Context)) {
+ CurBlock->TheDecl->getAttr<SentinelAttr>()) {
Diag(ParamInfo.getAttributes()->getLoc(),
diag::warn_attribute_sentinel_not_variadic) << 1;
// FIXME: remove the attribute.
@@ -5607,13 +5700,13 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// Implicit instantiation of function templates and member functions of
// class templates.
- if (!Function->getBody(Context)) {
+ if (!Function->getBody()) {
// FIXME: distinguish between implicit instantiations of function
// templates and explicit specializations (the latter don't get
// instantiated, naturally).
if (Function->getInstantiatedFromMemberFunction() ||
Function->getPrimaryTemplate())
- PendingImplicitInstantiations.push(std::make_pair(Function, Loc));
+ PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index bc8fc4eae502..7afa5941dad9 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -552,7 +552,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
bool AllowMissing, FunctionDecl *&Operator)
{
DeclContext::lookup_iterator Alloc, AllocEnd;
- llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name);
+ llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name);
if (Alloc == AllocEnd) {
if (AllowMissing)
return false;
@@ -657,7 +657,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
// Check if this function is already declared.
{
DeclContext::lookup_iterator Alloc, AllocEnd;
- for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Context, Name);
+ for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name);
Alloc != AllocEnd; ++Alloc) {
// FIXME: Do we need to check for default arguments here?
FunctionDecl *Func = cast<FunctionDecl>(*Alloc);
@@ -680,7 +680,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
// FIXME: Also add this declaration to the IdentifierResolver, but
// make sure it is at the end of the chain to coincide with the
// global scope.
- ((DeclContext *)TUScope->getEntity())->addDecl(Context, Alloc);
+ ((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
}
/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
@@ -1567,7 +1567,7 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
CXXTemporary *Temp = CXXTemporary::Create(Context,
RD->getDestructor(Context));
ExprTemporaries.push_back(Temp);
- MarcDestructorReferenced(E->getExprLoc(), E->getType());
+ MarkDestructorReferenced(E->getExprLoc(), E->getType());
// FIXME: Add the temporary to the temporaries vector.
return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E));
}
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index f1869f903719..7bb6b44c39cf 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -243,13 +243,13 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
while (ClassDecl && !Method) {
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Method = ImpDecl->getClassMethod(Context, Sel);
+ Method = ImpDecl->getClassMethod(Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getClassMethod(Context, Sel);
+ Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
}
}
@@ -257,7 +257,7 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
// But only in the root. This matches gcc's behaviour and what the
// runtime expects.
if (!Method && !ClassDecl->getSuperClass()) {
- Method = ClassDecl->lookupInstanceMethod(Context, Sel);
+ Method = ClassDecl->lookupInstanceMethod(Sel);
// Look through local category implementations associated
// with the root class.
if (!Method)
@@ -276,13 +276,13 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
// If we have implementations in scope, check "private" methods.
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Method = ImpDecl->getInstanceMethod(Context, Sel);
+ Method = ImpDecl->getInstanceMethod(Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
+ Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
}
}
ClassDecl = ClassDecl->getSuperClass();
@@ -301,7 +301,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
// Search for a declared property first.
Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
- ObjCMethodDecl *Getter = IFace->lookupClassMethod(Context, Sel);
+ ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
// If this reference is in an @implementation, check for 'private' methods.
if (!Getter)
@@ -309,7 +309,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Getter = ImpDecl->getClassMethod(Context, Sel);
+ Getter = ImpDecl->getClassMethod(Sel);
if (Getter) {
// FIXME: refactor/share with ActOnMemberReference().
@@ -323,7 +323,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
SelectorTable::constructSetterName(PP.getIdentifierTable(),
PP.getSelectorTable(), &propertyName);
- ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel);
+ ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
if (!Setter) {
// If this reference is in an @implementation, also check for 'private'
// methods.
@@ -331,13 +331,13 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Setter = ImpDecl->getClassMethod(Context, SetterSel);
+ Setter = ImpDecl->getClassMethod(SetterSel);
}
// Look through local category implementations associated with the class.
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
+ Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
}
}
@@ -450,7 +450,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
<< Method->getDeclName();
}
if (!Method)
- Method = ClassDecl->lookupClassMethod(Context, Sel);
+ Method = ClassDecl->lookupClassMethod(Sel);
// If we have an implementation in scope, check "private" methods.
if (!Method)
@@ -507,7 +507,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// If we have an interface in scope, check 'super' methods.
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
- Method = SuperDecl->lookupInstanceMethod(Context, Sel);
+ Method = SuperDecl->lookupInstanceMethod(Sel);
if (!Method)
// If we have implementations in scope, check "private" methods.
@@ -550,7 +550,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
// First check the public methods in the class interface.
- Method = ClassDecl->lookupClassMethod(Context, Sel);
+ Method = ClassDecl->lookupClassMethod(Sel);
if (!Method)
Method = LookupPrivateClassMethod(Sel, ClassDecl);
@@ -596,10 +596,10 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
E = QIdTy->qual_end(); I != E; ++I) {
ObjCProtocolDecl *PDecl = *I;
- if (PDecl && (Method = PDecl->lookupInstanceMethod(Context, Sel)))
+ if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
break;
// Since we aren't supporting "Class<foo>", look for a class method.
- if (PDecl && (Method = PDecl->lookupClassMethod(Context, Sel)))
+ if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
break;
}
} else if (const ObjCInterfaceType *OCIType =
@@ -610,13 +610,13 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
// faster than the following method (which can do *many* linear searches).
// The idea is to add class info to InstanceMethodPool.
- Method = ClassDecl->lookupInstanceMethod(Context, Sel);
+ Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method) {
// Search protocol qualifiers.
for (ObjCQualifiedInterfaceType::qual_iterator QI = OCIType->qual_begin(),
E = OCIType->qual_end(); QI != E; ++QI) {
- if ((Method = (*QI)->lookupInstanceMethod(Context, Sel)))
+ if ((Method = (*QI)->lookupInstanceMethod(Sel)))
break;
}
}
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp
index 28ca5f64ef59..2f914f14a81f 100644
--- a/lib/Sema/SemaInherit.cpp
+++ b/lib/Sema/SemaInherit.cpp
@@ -187,7 +187,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
= (Context.getCanonicalType(BaseSpec->getType()) == Criteria.Base);
break;
case MemberLookupCriteria::LK_NamedMember:
- Paths.ScratchPath.Decls = BaseRecord->lookup(Context, Criteria.Name);
+ Paths.ScratchPath.Decls = BaseRecord->lookup(Criteria.Name);
while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
if (isAcceptableLookupResult(*Paths.ScratchPath.Decls.first,
Criteria.NameKind, Criteria.IDNS)) {
@@ -199,7 +199,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
break;
case MemberLookupCriteria::LK_OverriddenMember:
Paths.ScratchPath.Decls =
- BaseRecord->lookup(Context, Criteria.Method->getDeclName());
+ BaseRecord->lookup(Criteria.Method->getDeclName());
while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
if (CXXMethodDecl *MD =
dyn_cast<CXXMethodDecl>(*Paths.ScratchPath.Decls.first)) {
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 6b812e1968de..ecfdfd7ba0b6 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -343,8 +343,8 @@ void InitListChecker::FillInValueInitializations(InitListExpr *ILE) {
if (const RecordType *RType = ILE->getType()->getAsRecordType()) {
unsigned Init = 0, NumInits = ILE->getNumInits();
for (RecordDecl::field_iterator
- Field = RType->getDecl()->field_begin(SemaRef.Context),
- FieldEnd = RType->getDecl()->field_end(SemaRef.Context);
+ Field = RType->getDecl()->field_begin(),
+ FieldEnd = RType->getDecl()->field_end();
Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
@@ -449,8 +449,8 @@ int InitListChecker::numStructUnionElements(QualType DeclType) {
RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
int InitializableMembers = 0;
for (RecordDecl::field_iterator
- Field = structDecl->field_begin(SemaRef.Context),
- FieldEnd = structDecl->field_end(SemaRef.Context);
+ Field = structDecl->field_begin(),
+ FieldEnd = structDecl->field_end();
Field != FieldEnd; ++Field) {
if ((*Field)->getIdentifier() || !(*Field)->isBitField())
++InitializableMembers;
@@ -580,7 +580,7 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
} else if (DeclType->isAggregateType()) {
if (DeclType->isRecordType()) {
RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
- CheckStructUnionTypes(IList, DeclType, RD->field_begin(SemaRef.Context),
+ CheckStructUnionTypes(IList, DeclType, RD->field_begin(),
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex,
TopLevelObject);
@@ -946,7 +946,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
if (DeclType->isUnionType() && IList->getNumInits() == 0) {
// Value-initialize the first named member of the union.
RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
- for (RecordDecl::field_iterator FieldEnd = RD->field_end(SemaRef.Context);
+ for (RecordDecl::field_iterator FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
if (Field->getDeclName()) {
StructuredList->setInitializedFieldInUnion(*Field);
@@ -961,7 +961,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
// because an error should get printed out elsewhere. It might be
// worthwhile to skip over the rest of the initializer, though.
RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
- RecordDecl::field_iterator FieldEnd = RD->field_end(SemaRef.Context);
+ RecordDecl::field_iterator FieldEnd = RD->field_end();
bool InitializedSomething = false;
while (Index < IList->getNumInits()) {
Expr *Init = IList->getInit(Index);
@@ -1090,9 +1090,9 @@ static void ExpandAnonymousFieldDesignator(Sema &SemaRef,
// Update FieldIter/FieldIndex;
RecordDecl *Record = cast<RecordDecl>(Path.back()->getDeclContext());
- FieldIter = Record->field_begin(SemaRef.Context);
+ FieldIter = Record->field_begin();
FieldIndex = 0;
- for (RecordDecl::field_iterator FEnd = Record->field_end(SemaRef.Context);
+ for (RecordDecl::field_iterator FEnd = Record->field_end();
FieldIter != FEnd; ++FieldIter) {
if (FieldIter->isUnnamedBitfield())
continue;
@@ -1217,8 +1217,8 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
IdentifierInfo *FieldName = D->getFieldName();
unsigned FieldIndex = 0;
RecordDecl::field_iterator
- Field = RT->getDecl()->field_begin(SemaRef.Context),
- FieldEnd = RT->getDecl()->field_end(SemaRef.Context);
+ Field = RT->getDecl()->field_begin(),
+ FieldEnd = RT->getDecl()->field_end();
for (; Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
@@ -1235,8 +1235,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
// something that we can't designate (e.g., a member function),
// may find nothing, or may find a member of an anonymous
// struct/union.
- DeclContext::lookup_result Lookup
- = RT->getDecl()->lookup(SemaRef.Context, FieldName);
+ DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
if (Lookup.first == Lookup.second) {
// Name lookup didn't find anything.
SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
@@ -1565,8 +1564,8 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
if (RDecl->isUnion())
NumElements = 1;
else
- NumElements = std::distance(RDecl->field_begin(SemaRef.Context),
- RDecl->field_end(SemaRef.Context));
+ NumElements = std::distance(RDecl->field_begin(),
+ RDecl->field_end());
}
if (NumElements < NumInits)
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index cc9e783f6166..6f2fc5e0c434 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -65,7 +65,7 @@ void AddNamespaceUsingDirectives(ASTContext &Context,
NamespaceSet &Visited) {
DeclContext::udir_iterator I, End;
- for (llvm::tie(I, End) = NS->getUsingDirectives(Context); I !=End; ++I) {
+ for (llvm::tie(I, End) = NS->getUsingDirectives(); I !=End; ++I) {
UDirs.push_back(*I);
std::push_heap(UDirs.begin(), UDirs.end(), UsingDirAncestorCompare());
NamespaceDecl *Nominated = (*I)->getNominatedNamespace();
@@ -609,7 +609,7 @@ CppNamespaceLookup(ASTContext &Context, DeclContext *NS,
// Perform qualified name lookup into the LookupCtx.
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = NS->lookup(Context, Name); I != E; ++I)
+ for (llvm::tie(I, E) = NS->lookup(Name); I != E; ++I)
if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS)) {
Results.push_back(Sema::LookupResult::CreateLookupResult(Context, I, E));
break;
@@ -903,7 +903,7 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind,
continue;
}
- if ((*I)->getAttr<OverloadableAttr>(Context)) {
+ if ((*I)->getAttr<OverloadableAttr>()) {
// If this declaration has the "overloadable" attribute, we
// might have a set of overloaded functions.
@@ -1005,7 +1005,7 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
// Perform qualified name lookup into the LookupCtx.
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I)
+ for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
if (isAcceptableLookupResult(*I, NameKind, IDNS))
return LookupResult::CreateLookupResult(Context, I, E);
@@ -1148,7 +1148,7 @@ Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS,
// (C++0x [temp.dep.type]).
unsigned IDNS = getIdentifierNamespacesFromLookupNameKind(NameKind, true);
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = Current->lookup(Context, Name); I != E; ++I)
+ for (llvm::tie(I, E) = Current->lookup(Name); I != E; ++I)
if (isAcceptableLookupResult(*I, NameKind, IDNS))
return LookupResult::CreateLookupResult(Context, I, E);
}
@@ -1604,9 +1604,17 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
Op != OpEnd; ++Op) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op))
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
Functions.insert(FD); // FIXME: canonical FD
+ } else if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(*Op)) {
+ // FIXME: friend operators?
+ // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
+ // later?
+ if (!FunTmpl->getDeclContext()->isRecord())
+ Functions.insert(FunTmpl);
+ }
}
}
@@ -1648,25 +1656,23 @@ void Sema::ArgumentDependentLookup(DeclarationName Name,
// namespaces even if they are not visible during an ordinary
// lookup (11.4).
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = (*NS)->lookup(Context, Name); I != E; ++I) {
- FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
- if (!Func)
- break;
-
- Functions.insert(Func);
+ for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) {
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+ Functions.insert(Func);
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))
+ Functions.insert(FunTmpl);
}
}
if (GlobalScope) {
DeclContext::lookup_iterator I, E;
for (llvm::tie(I, E)
- = Context.getTranslationUnitDecl()->lookup(Context, Name);
+ = Context.getTranslationUnitDecl()->lookup(Name);
I != E; ++I) {
- FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
- if (!Func)
- break;
-
- Functions.insert(Func);
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+ Functions.insert(Func);
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))
+ Functions.insert(FunTmpl);
}
}
}
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index fcc155750cdc..03ac2d9bb73a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1375,7 +1375,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
Context.getCanonicalType(ToType).getUnqualifiedType());
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd)
- = ToRecordDecl->lookup(Context, ConstructorName);
+ = ToRecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if (Constructor->isConvertingConstructor())
@@ -2161,9 +2161,16 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions,
bool SuppressUserConversions) {
for (FunctionSet::const_iterator F = Functions.begin(),
FEnd = Functions.end();
- F != FEnd; ++F)
- AddOverloadCandidate(*F, Args, NumArgs, CandidateSet,
- SuppressUserConversions);
+ F != FEnd; ++F) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F),
+ /*FIXME: explicit args */false, 0, 0,
+ Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ }
}
/// AddMethodCandidate - Adds the given C++ member function to the set
@@ -2267,6 +2274,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
/// template specialization.
void
Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
@@ -2283,8 +2293,9 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult Result
- = DeduceTemplateArguments(FunctionTemplate, Args, NumArgs,
- Specialization, Info)) {
+ = DeduceTemplateArguments(FunctionTemplate, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs,
+ Args, NumArgs, Specialization, Info)) {
// FIXME: Record what happened with template argument deduction, so
// that we can give the user a beautiful diagnostic.
(void)Result;
@@ -2510,7 +2521,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
// FIXME: Lookup in base classes, too!
if (const RecordType *T1Rec = T1->getAsRecordType()) {
DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName);
+ for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName);
Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0],
Args+1, NumArgs - 1, CandidateSet,
@@ -3405,8 +3416,11 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
CandEnd = CandidateSet.end();
Cand != CandEnd; ++Cand)
- if (Cand->Function)
+ if (Cand->Function) {
Functions.insert(Cand->Function);
+ if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+ Functions.insert(FunTmpl);
+ }
ArgumentDependentLookup(Name, Args, NumArgs, Functions);
@@ -3415,15 +3429,24 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
CandEnd = CandidateSet.end();
Cand != CandEnd; ++Cand)
- if (Cand->Function)
+ if (Cand->Function) {
Functions.erase(Cand->Function);
+ if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+ Functions.erase(FunTmpl);
+ }
// For each of the ADL candidates we found, add it to the overload
// set.
for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
- Func != FuncEnd; ++Func)
- AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet);
+ Func != FuncEnd; ++Func) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
+ else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
+ /*FIXME: explicit args */false, 0, 0,
+ Args, NumArgs, CandidateSet);
+ }
}
/// isBetterOverloadCandidate - Determines whether the first overload
@@ -3556,7 +3579,7 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
// Best is the best viable function.
if (Best->Function &&
(Best->Function->isDeleted() ||
- Best->Function->getAttr<UnavailableAttr>(Context)))
+ Best->Function->getAttr<UnavailableAttr>()))
return OR_Deleted;
// C++ [basic.def.odr]p2:
@@ -3583,7 +3606,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
if (Cand->Viable || !OnlyViable) {
if (Cand->Function) {
if (Cand->Function->isDeleted() ||
- Cand->Function->getAttr<UnavailableAttr>(Context)) {
+ Cand->Function->getAttr<UnavailableAttr>()) {
// Deleted or "unavailable" function.
Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted)
<< Cand->Function->isDeleted();
@@ -3741,6 +3764,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
/// arguments and Fn, and returns NULL.
FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation *CommaLocs,
@@ -3773,11 +3799,17 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
Func != FuncEnd; ++Func) {
DeclContext *Ctx = 0;
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Func)) {
+ if (HasExplicitTemplateArgs)
+ continue;
+
AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet);
Ctx = FunDecl->getDeclContext();
} else {
FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*Func);
- AddTemplateOverloadCandidate(FunTmpl, Args, NumArgs, CandidateSet);
+ AddTemplateOverloadCandidate(FunTmpl, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet);
Ctx = FunTmpl->getDeclContext();
}
@@ -3786,6 +3818,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
ArgumentDependentLookup = false;
}
} else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) {
+ assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
AddOverloadCandidate(Func, Args, NumArgs, CandidateSet);
if (Func->getDeclContext()->isRecord() ||
@@ -3793,7 +3826,10 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
ArgumentDependentLookup = false;
} else if (FunctionTemplateDecl *FuncTemplate
= dyn_cast_or_null<FunctionTemplateDecl>(Callee)) {
- AddTemplateOverloadCandidate(FuncTemplate, Args, NumArgs, CandidateSet);
+ AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet);
if (FuncTemplate->getDeclContext()->isRecord())
ArgumentDependentLookup = false;
@@ -3802,6 +3838,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
if (Callee)
UnqualifiedName = Callee->getDeclName();
+ // FIXME: Pass explicit template arguments through for ADL
if (ArgumentDependentLookup)
AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
CandidateSet);
@@ -4273,7 +4310,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
OverloadCandidateSet CandidateSet;
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName);
+ for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
CandidateSet, /*SuppressUserConversions=*/false);
@@ -4477,8 +4514,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
DeclContext::lookup_const_iterator Oper, OperEnd;
for (llvm::tie(Oper, OperEnd)
- = BaseRecord->getDecl()->lookup(Context, OpName);
- Oper != OperEnd; ++Oper)
+ = BaseRecord->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet,
/*SuppressUserConversions=*/false);
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 914839cbf790..63191e0e00cc 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -84,7 +84,7 @@ Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
SourceLocation Loc;
SourceRange R1, R2;
- if (!E->isUnusedResultAWarning(Loc, R1, R2, Context))
+ if (!E->isUnusedResultAWarning(Loc, R1, R2))
continue;
Diag(Loc, diag::warn_unused_expr) << R1 << R2;
@@ -766,7 +766,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
QualType FnRetType = CurBlock->ReturnType;
- if (CurBlock->TheDecl->hasAttr<NoReturnAttr>(Context)) {
+ if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
<< getCurFunctionOrMethodDecl()->getDeclName();
return StmtError();
@@ -842,7 +842,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, FullExprArg rex) {
QualType FnRetType;
if (const FunctionDecl *FD = getCurFunctionDecl()) {
FnRetType = FD->getResultType();
- if (FD->hasAttr<NoReturnAttr>(Context))
+ if (FD->hasAttr<NoReturnAttr>())
Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
<< getCurFunctionOrMethodDecl()->getDeclName();
} else if (ObjCMethodDecl *MD = getCurMethodDecl())
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index cd985c536c77..568d68c9a7e8 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -852,7 +852,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
NumTemplateArgs);
if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
TemplateArgs, NumTemplateArgs, RAngleLoc,
- Converted))
+ false, Converted))
return QualType();
assert((Converted.structuredSize() ==
@@ -933,6 +933,42 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
return Result.getAsOpaquePtr();
}
+Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc) {
+ // FIXME: Can we do any checking at this point? I guess we could check the
+ // template arguments that we have against the template name, if the template
+ // name refers to a single template. That's not a terribly common case,
+ // though.
+ return Owned(TemplateIdRefExpr::Create(Context,
+ /*FIXME: New type?*/Context.OverloadTy,
+ /*FIXME: Necessary?*/0,
+ /*FIXME: Necessary?*/SourceRange(),
+ Template, TemplateNameLoc, LAngleLoc,
+ TemplateArgs,
+ NumTemplateArgs, RAngleLoc));
+}
+
+Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ TemplateName Template = TemplateD.getAsVal<TemplateName>();
+
+ // Translate the parser's template argument list in our AST format.
+ llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+
+ return BuildTemplateIdExpr(Template, TemplateNameLoc, LAngleLoc,
+ TemplateArgs.data(), TemplateArgs.size(),
+ RAngleLoc);
+}
+
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
@@ -1019,6 +1055,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
+ bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size();
@@ -1029,7 +1066,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
if ((NumArgs > NumParams && !HasParameterPack) ||
- NumArgs < Params->getMinRequiredArguments()) {
+ (NumArgs < Params->getMinRequiredArguments() &&
+ !PartialTemplateArgs)) {
// FIXME: point at either the first arg beyond what we can handle,
// or the '>', depending on whether we have too many or too few
// arguments.
@@ -1056,6 +1094,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
for (TemplateParameterList::iterator Param = Params->begin(),
ParamEnd = Params->end();
Param != ParamEnd; ++Param, ++ArgIdx) {
+ if (ArgIdx > NumArgs && PartialTemplateArgs)
+ break;
+
// Decode the template argument
TemplateArgument Arg;
if (ArgIdx >= NumArgs) {
@@ -2302,7 +2343,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
TemplateArgs.size());
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, Converted))
+ RAngleLoc, false, Converted))
return true;
assert((Converted.structuredSize() ==
@@ -2498,7 +2539,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
// Add the specialization into its lexical context, so that it can
// be seen when iterating through the list of declarations in that
// context. However, specializations are not found by name lookup.
- CurContext->addDecl(Context, Specialization);
+ CurContext->addDecl(Specialization);
return DeclPtrTy::make(Specialization);
}
@@ -2597,7 +2638,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
TemplateArgs.size());
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, Converted))
+ RAngleLoc, false, Converted))
return true;
assert((Converted.structuredSize() ==
@@ -2654,7 +2695,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
ClassTemplate,
Converted, 0);
Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Context, Specialization);
+ CurContext->addDecl(Specialization);
return DeclPtrTy::make(Specialization);
}
@@ -2703,7 +2744,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
// since explicit instantiations are never found by name lookup, we
// just put it into the declaration context directly.
Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Context, Specialization);
+ CurContext->addDecl(Specialization);
// C++ [temp.explicit]p3:
// A definition of a class template or class member template
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 3d909bb26a79..5a0578f6bcb7 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -868,6 +868,16 @@ static bool isSimpleTemplateIdType(QualType T) {
/// \param FunctionTemplate the function template for which we are performing
/// template argument deduction.
///
+/// \param HasExplicitTemplateArgs whether any template arguments were
+/// explicitly specified.
+///
+/// \param ExplicitTemplateArguments when @p HasExplicitTemplateArgs is true,
+/// the explicitly-specified template arguments.
+///
+/// \param NumExplicitTemplateArguments when @p HasExplicitTemplateArgs is true,
+/// the number of explicitly-specified template arguments in
+/// @p ExplicitTemplateArguments. This value may be zero.
+///
/// \param Args the function call arguments
///
/// \param NumArgs the number of arguments in Args
@@ -880,22 +890,22 @@ static bool isSimpleTemplateIdType(QualType T) {
/// about template argument deduction.
///
/// \returns the result of template argument deduction.
-///
-/// FIXME: We will also need to pass in any explicitly-specified template
-/// arguments.
Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
TemplateDeductionInfo &Info) {
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
-
+
// C++ [temp.deduct.call]p1:
// Template argument deduction is done by comparing each function template
// parameter type (call it P) with the type of the corresponding argument
// of the call (call it A) as described below.
unsigned CheckArgs = NumArgs;
- if (NumArgs < Function->getNumParams())
+ if (NumArgs < Function->getMinRequiredArguments())
return TDK_TooFewArguments;
else if (NumArgs > Function->getNumParams()) {
const FunctionProtoType *Proto
@@ -905,18 +915,87 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
CheckArgs = Function->getNumParams();
}
-
+
// Template argument deduction for function templates in a SFINAE context.
// Trap any errors that might occur.
SFINAETrap Trap(*this);
-
- // Deduce template arguments from the function parameters.
- llvm::SmallVector<TemplateArgument, 4> Deduced;
- Deduced.resize(FunctionTemplate->getTemplateParameters()->size());
+
+ // The types of the parameters from which we will perform template argument
+ // deduction.
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
+ llvm::SmallVector<TemplateArgument, 4> Deduced;
+ llvm::SmallVector<QualType, 4> ParamTypes;
+ if (NumExplicitTemplateArgs) {
+ // C++ [temp.arg.explicit]p3:
+ // Template arguments that are present shall be specified in the
+ // declaration order of their corresponding template-parameters. The
+ // template argument list shall not specify more template-arguments than
+ // there are corresponding template-parameters.
+ TemplateArgumentListBuilder Builder(TemplateParams,
+ NumExplicitTemplateArgs);
+
+ // Enter a new template instantiation context where we check the
+ // explicitly-specified template arguments against this function template,
+ // and then substitute them into the function parameter types.
+ InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+ FunctionTemplate, Deduced.data(), Deduced.size(),
+ ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution);
+ if (Inst)
+ return TDK_InstantiationDepth;
+
+ if (CheckTemplateArgumentList(FunctionTemplate,
+ SourceLocation(), SourceLocation(),
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ SourceLocation(),
+ true,
+ Builder) || Trap.hasErrorOccurred())
+ return TDK_InvalidExplicitArguments;
+
+ // Form the template argument list from the explicitly-specified
+ // template arguments.
+ TemplateArgumentList *ExplicitArgumentList
+ = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+ Info.reset(ExplicitArgumentList);
+
+ // Instantiate the types of each of the function parameters given the
+ // explicitly-specified template arguments.
+ for (FunctionDecl::param_iterator P = Function->param_begin(),
+ PEnd = Function->param_end();
+ P != PEnd;
+ ++P) {
+ QualType ParamType = InstantiateType((*P)->getType(),
+ *ExplicitArgumentList,
+ (*P)->getLocation(),
+ (*P)->getDeclName());
+ if (ParamType.isNull() || Trap.hasErrorOccurred())
+ return TDK_SubstitutionFailure;
+
+ ParamTypes.push_back(ParamType);
+ }
+
+ // C++ [temp.arg.explicit]p2:
+ // Trailing template arguments that can be deduced (14.8.2) may be
+ // omitted from the list of explicit template- arguments. If all of the
+ // template arguments can be deduced, they may all be omitted; in this
+ // case, the empty template argument list <> itself may also be omitted.
+ //
+ // Take all of the explicitly-specified arguments and put them into the
+ // set of deduced template arguments.
+ Deduced.reserve(TemplateParams->size());
+ for (unsigned I = 0, N = ExplicitArgumentList->size(); I != N; ++I)
+ Deduced.push_back(ExplicitArgumentList->get(I));
+ } else {
+ // Just fill in the parameter types from the function declaration.
+ for (unsigned I = 0; I != CheckArgs; ++I)
+ ParamTypes.push_back(Function->getParamDecl(I)->getType());
+ }
+
+ // Deduce template arguments from the function parameters.
+ Deduced.resize(TemplateParams->size());
for (unsigned I = 0; I != CheckArgs; ++I) {
- QualType ParamType = Function->getParamDecl(I)->getType();
+ QualType ParamType = ParamTypes[I];
QualType ArgType = Args[I]->getType();
// C++ [temp.deduct.call]p2:
@@ -998,11 +1077,6 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// FIXME: C++ [temp.deduct.call] paragraphs 6-9 deal with function
// pointer parameters.
}
-
- InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
- FunctionTemplate, Deduced.data(), Deduced.size());
- if (Inst)
- return TDK_InstantiationDepth;
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
@@ -1030,20 +1104,36 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
= new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
Info.reset(DeducedArgumentList);
+ // Enter a new template instantiation context while we instantiate the
+ // actual function declaration.
+ InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+ FunctionTemplate, Deduced.data(), Deduced.size(),
+ ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
+ if (Inst)
+ return TDK_InstantiationDepth;
+
// Substitute the deduced template arguments into the function template
// declaration to produce the function template specialization.
Specialization = cast_or_null<FunctionDecl>(
InstantiateDecl(FunctionTemplate->getTemplatedDecl(),
FunctionTemplate->getDeclContext(),
*DeducedArgumentList));
+ if (!Specialization)
+ return TDK_SubstitutionFailure;
- if (!Specialization || Trap.hasErrorOccurred())
+ // If the template argument list is owned by the function template
+ // specialization, release it.
+ if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList)
+ Info.take();
+
+ // There may have been an error that did not prevent us from constructing a
+ // declaration. Mark the declaration invalid and return with a substitution
+ // failure.
+ if (Trap.hasErrorOccurred()) {
+ Specialization->setInvalidDecl(true);
return TDK_SubstitutionFailure;
-
- // Turn the specialization into an actual function template specialization.
- Specialization->setFunctionTemplateSpecialization(Context,
- FunctionTemplate,
- Info.take());
+ }
+
return TDK_Success;
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index aed348966a4f..6c2dc77b4cce 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -100,6 +100,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Sema::InstantiatingTemplat