aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
commitb3d5a323a5ca92ea73443499cee2f15db1ff0fb3 (patch)
tree60a1694bec5a44d15456acc880cb2f91619f66aa /include/clang
parent8f57cb0305232cb53fff00ef151ca716766f3437 (diff)
downloadsrc-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.tar.gz
src-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.zip
Update clang to r89205.
Notes
Notes: svn path=/vendor/clang/dist/; revision=199482
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h27
-rw-r--r--include/clang/AST/Attr.h2
-rw-r--r--include/clang/AST/CanonicalType.h17
-rw-r--r--include/clang/AST/Decl.h10
-rw-r--r--include/clang/AST/DeclBase.h11
-rw-r--r--include/clang/AST/DeclCXX.h364
-rw-r--r--include/clang/AST/DeclContextInternals.h3
-rw-r--r--include/clang/AST/DeclNodes.def4
-rw-r--r--include/clang/AST/DeclObjC.h32
-rw-r--r--include/clang/AST/DeclTemplate.h17
-rw-r--r--include/clang/AST/DeclarationName.h3
-rw-r--r--include/clang/AST/Expr.h11
-rw-r--r--include/clang/AST/ExprCXX.h2
-rw-r--r--include/clang/AST/RecordLayout.h2
-rw-r--r--include/clang/AST/Redeclarable.h3
-rw-r--r--include/clang/AST/TemplateBase.h100
-rw-r--r--include/clang/AST/Type.h327
-rw-r--r--include/clang/AST/TypeLoc.h12
-rw-r--r--include/clang/AST/TypeLocBuilder.h1
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h4
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowSolver.h1
-rw-r--r--include/clang/Analysis/LocalCheckers.h4
-rw-r--r--include/clang/Analysis/ManagerRegistry.h53
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h1
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisManager.h5
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h16
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h15
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h101
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.def15
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.h36
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h32
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h122
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h22
-rw-r--r--include/clang/Analysis/PathSensitive/GRWorkList.h7
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h2
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h4
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h6
-rw-r--r--include/clang/Analysis/ProgramPoint.h64
-rw-r--r--include/clang/Analysis/Support/Optional.h3
-rw-r--r--include/clang/Analysis/Support/SaveAndRestore.h3
-rw-r--r--include/clang/Basic/Diagnostic.h15
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td25
-rw-r--r--include/clang/Basic/DiagnosticGroups.td24
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td10
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td97
-rw-r--r--include/clang/Basic/LangOptions.h7
-rw-r--r--include/clang/Basic/Makefile4
-rw-r--r--include/clang/Basic/TargetInfo.h48
-rw-r--r--include/clang/Basic/TargetOptions.h39
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h75
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
-rw-r--r--include/clang/Driver/Driver.h2
-rw-r--r--include/clang/Driver/Options.def4
-rw-r--r--include/clang/Driver/ToolChain.h11
-rw-r--r--include/clang/Driver/Types.h3
-rw-r--r--include/clang/Frontend/ASTConsumers.h10
-rw-r--r--include/clang/Frontend/Analyses.def3
-rw-r--r--include/clang/Frontend/AnalysisConsumer.h41
-rw-r--r--include/clang/Frontend/ChainedDiagnosticClient.h58
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h3
-rw-r--r--include/clang/Frontend/CompilerInstance.h523
-rw-r--r--include/clang/Frontend/CompilerInvocation.h150
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h43
-rw-r--r--include/clang/Frontend/DiagnosticOptions.h30
-rw-r--r--include/clang/Frontend/FrontendAction.h215
-rw-r--r--include/clang/Frontend/FrontendActions.h216
-rw-r--r--include/clang/Frontend/FrontendOptions.h131
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h23
-rw-r--r--include/clang/Frontend/HeaderSearchOptions.h87
-rw-r--r--include/clang/Frontend/PCHReader.h44
-rw-r--r--include/clang/Frontend/PCHWriter.h3
-rw-r--r--include/clang/Frontend/PreprocessorOptions.h57
-rw-r--r--include/clang/Frontend/PreprocessorOutputOptions.h37
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h9
-rw-r--r--include/clang/Frontend/TypeXML.def6
-rw-r--r--include/clang/Frontend/Utils.h58
-rw-r--r--include/clang/Frontend/VerifyDiagnosticsClient.h82
-rw-r--r--include/clang/Lex/PTHManager.h3
-rw-r--r--include/clang/Lex/Preprocessor.h22
-rw-r--r--include/clang/Lex/Token.h63
-rw-r--r--include/clang/Parse/Action.h53
-rw-r--r--include/clang/Parse/AttributeList.h1
-rw-r--r--include/clang/Parse/DeclSpec.h11
-rw-r--r--include/clang/Parse/Ownership.h35
-rw-r--r--include/clang/Parse/Parser.h29
-rw-r--r--include/clang/Parse/Scope.h6
-rw-r--r--include/clang/Parse/Template.h183
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h146
-rw-r--r--include/clang/Sema/ParseAST.h8
91 files changed, 3317 insertions, 919 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7392170be995..f9d2f71b1f28 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -37,6 +37,7 @@ namespace llvm {
namespace clang {
class FileManager;
class ASTRecordLayout;
+ class BlockExpr;
class Expr;
class ExternalASTSource;
class IdentifierTable;
@@ -55,7 +56,6 @@ namespace clang {
class TranslationUnitDecl;
class TypeDecl;
class TypedefDecl;
- class UnresolvedUsingDecl;
class UsingDecl;
namespace Builtin { class Context; }
@@ -204,7 +204,7 @@ class ASTContext {
///
/// This mapping will contain an entry that maps from the UsingDecl in
/// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
+ llvm::DenseMap<UsingDecl *, NamedDecl *>
InstantiatedFromUnresolvedUsingDecl;
llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
@@ -232,7 +232,7 @@ class ASTContext {
llvm::DenseMap<const Decl *, std::string> DeclComments;
public:
- TargetInfo &Target;
+ const TargetInfo &Target;
IdentifierTable &Idents;
SelectorTable &Selectors;
Builtin::Context &BuiltinInfo;
@@ -284,12 +284,11 @@ public:
/// \brief If this using decl is instantiated from an unresolved using decl,
/// return it.
- UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
+ NamedDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
/// \brief Note that the using decl \p Inst is an instantiation of
/// the unresolved using decl \p Tmpl of a class template.
- void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst,
- UnresolvedUsingDecl *Tmpl);
+ void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst, NamedDecl *Tmpl);
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
@@ -319,7 +318,7 @@ public:
CanQualType UndeducedAutoTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
- ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
+ ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
Builtin::Context &builtins,
bool FreeMemory = true, unsigned size_reserve=0);
@@ -672,6 +671,10 @@ public:
/// declaration.
void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S);
+ /// getObjCEncodingForBlockDecl - Return the encoded type for this block
+ /// declaration.
+ void getObjCEncodingForBlock(const BlockExpr *Expr, std::string& S);
+
/// getObjCEncodingForPropertyDecl - Return the encoded type for
/// this method declaration. If non-NULL, Container must be either
/// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
@@ -872,9 +875,9 @@ public:
/// \brief Determine whether the given types are equivalent after
/// cvr-qualifiers have been removed.
bool hasSameUnqualifiedType(QualType T1, QualType T2) {
- T1 = getCanonicalType(T1);
- T2 = getCanonicalType(T2);
- return T1.getUnqualifiedType() == T2.getUnqualifiedType();
+ CanQualType CT1 = getCanonicalType(T1);
+ CanQualType CT2 = getCanonicalType(T2);
+ return CT1.getUnqualifiedType() == CT2.getUnqualifiedType();
}
/// \brief Retrieves the "canonical" declaration of
@@ -925,6 +928,10 @@ public:
/// types, values, and templates.
TemplateName getCanonicalTemplateName(TemplateName Name);
+ /// \brief Determine whether the given template names refer to the same
+ /// template.
+ bool hasSameTemplateName(TemplateName X, TemplateName Y);
+
/// \brief Retrieve the "canonical" template argument.
///
/// The canonical template argument is the simplest template argument
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index f7a47364a7f6..b36ff1229376 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -50,6 +50,7 @@ public:
Annotate,
AsmLabel, // Represent GCC asm label extension.
Blocks,
+ CDecl,
Cleanup,
Const,
Constructor,
@@ -442,6 +443,7 @@ DEF_SIMPLE_ATTR(DLLImport);
DEF_SIMPLE_ATTR(DLLExport);
DEF_SIMPLE_ATTR(FastCall);
DEF_SIMPLE_ATTR(StdCall);
+DEF_SIMPLE_ATTR(CDecl);
DEF_SIMPLE_ATTR(TransparentUnion);
DEF_SIMPLE_ATTR(ObjCNSObject);
DEF_SIMPLE_ATTR(ObjCException);
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index a7750517090e..9b1187770f6a 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -71,6 +71,9 @@ public:
/// \brief Implicit conversion to a qualified type.
operator QualType() const { return Stored; }
+ /// \brief Implicit conversion to bool.
+ operator bool() const { return !isNull(); }
+
bool isNull() const {
return Stored.isNull();
}
@@ -99,22 +102,22 @@ public:
CanProxy<T> operator->() const;
/// \brief Retrieve all qualifiers.
- Qualifiers getQualifiers() const { return Stored.getQualifiers(); }
+ Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
/// \brief Retrieve the const/volatile/restrict qualifiers.
- unsigned getCVRQualifiers() const { return Stored.getCVRQualifiers(); }
+ unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
/// \brief Determines whether this type has any qualifiers
- bool hasQualifiers() const { return Stored.hasQualifiers(); }
+ bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
bool isConstQualified() const {
- return Stored.isConstQualified();
+ return Stored.isLocalConstQualified();
}
bool isVolatileQualified() const {
- return Stored.isVolatileQualified();
+ return Stored.isLocalVolatileQualified();
}
bool isRestrictQualified() const {
- return Stored.isRestrictQualified();
+ return Stored.isLocalRestrictQualified();
}
/// \brief Retrieve the unqualified form of this type.
@@ -635,7 +638,7 @@ struct CanProxyAdaptor<ObjCObjectPointerType>
//----------------------------------------------------------------------------//
template<typename T>
inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
- return CanQual<T>::CreateUnsafe(Stored.getUnqualifiedType());
+ return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
}
template<typename T>
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 813e83accdb1..ac79a91792d7 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -232,6 +232,7 @@ public:
void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
+ const NamespaceDecl *getCanonicalDecl() const { return OrigNamespace; }
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), RBracLoc);
@@ -552,6 +553,9 @@ public:
}
virtual VarDecl *getCanonicalDecl();
+ const VarDecl *getCanonicalDecl() const {
+ return const_cast<VarDecl*>(this)->getCanonicalDecl();
+ }
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
@@ -1424,6 +1428,9 @@ public:
virtual SourceRange getSourceRange() const;
virtual TagDecl* getCanonicalDecl();
+ const TagDecl* getCanonicalDecl() const {
+ return const_cast<TagDecl*>(this)->getCanonicalDecl();
+ }
/// isDefinition - Return true if this decl has its body specified.
bool isDefinition() const {
@@ -1515,6 +1522,9 @@ public:
EnumDecl *getCanonicalDecl() {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
+ const EnumDecl *getCanonicalDecl() const {
+ return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ }
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 10db7030db18..79f766356138 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -79,9 +79,11 @@ public:
/// namespaces, labels, tags, members and ordinary
/// identifiers. These are meant as bitmasks, so that searches in
/// C++ can look into the "tag" namespace during ordinary lookup. We
- /// use additional namespaces for Objective-C entities. We also
- /// put C++ friend declarations (of previously-undeclared entities) in
- /// shadow namespaces.
+ /// use additional namespaces for Objective-C entities. We also put
+ /// C++ friend declarations (of previously-undeclared entities) in
+ /// shadow namespaces, and 'using' declarations (as opposed to their
+ /// implicit shadow declarations) can be found in their own
+ /// namespace.
enum IdentifierNamespace {
IDNS_Label = 0x1,
IDNS_Tag = 0x2,
@@ -91,7 +93,8 @@ public:
IDNS_ObjCImplementation = 0x20,
IDNS_ObjCCategoryImpl = 0x40,
IDNS_OrdinaryFriend = 0x80,
- IDNS_TagFriend = 0x100
+ IDNS_TagFriend = 0x100,
+ IDNS_Using = 0x200
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index c858c5c0df78..e5bf78cd10d2 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -432,6 +432,9 @@ public:
virtual CXXRecordDecl *getCanonicalDecl() {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+ virtual const CXXRecordDecl *getCanonicalDecl() const {
+ return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+ }
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -768,7 +771,7 @@ public:
/// \param Base the base class we are searching for.
///
/// \returns true if this class is derived from Base, false otherwise.
- bool isDerivedFrom(CXXRecordDecl *Base);
+ bool isDerivedFrom(CXXRecordDecl *Base) const;
/// \brief Determine whether this class is derived from the type \p Base.
///
@@ -786,7 +789,7 @@ public:
///
/// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
- bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths);
+ bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
/// \brief Function type used by lookupInBases() to determine whether a
/// specific base class subobject matches the lookup criteria.
@@ -801,7 +804,7 @@ public:
/// lookupInBases().
///
/// \returns true if this base matched the search criteria, false otherwise.
- typedef bool BaseMatchesCallback(CXXBaseSpecifier *Specifier,
+ typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *UserData);
@@ -826,7 +829,7 @@ public:
/// \returns true if there exists any path from this class to a base class
/// subobject that matches the search criteria.
bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
- CXXBasePaths &Paths);
+ CXXBasePaths &Paths) const;
/// \brief Base-class lookup callback that determines whether the given
/// base class specifier refers to a specific class declaration.
@@ -835,8 +838,8 @@ public:
/// a given derived class has is a base class subobject of a particular type.
/// The user data pointer should refer to the canonical CXXRecordDecl of the
/// base class that we are searching for.
- static bool FindBaseClass(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
- void *BaseRecord);
+ static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *BaseRecord);
/// \brief Base-class lookup callback that determines whether there exists
/// a tag with the given name.
@@ -844,8 +847,8 @@ public:
/// This callback can be used with \c lookupInBases() to find tag members
/// of the given name within a C++ class hierarchy. The user data pointer
/// is an opaque \c DeclarationName pointer.
- static bool FindTagMember(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
- void *Name);
+ static bool FindTagMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *Name);
/// \brief Base-class lookup callback that determines whether there exists
/// a member with the given name.
@@ -853,8 +856,8 @@ public:
/// This callback can be used with \c lookupInBases() to find members
/// of the given name within a C++ class hierarchy. The user data pointer
/// is an opaque \c DeclarationName pointer.
- static bool FindOrdinaryMember(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
- void *Name);
+ static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *Name);
/// \brief Base-class lookup callback that determines whether there exists
/// a member with the given name that can be used in a nested-name-specifier.
@@ -862,7 +865,7 @@ public:
/// This callback can be used with \c lookupInBases() to find membes of
/// the given name within a C++ class hierarchy that can occur within
/// nested-name-specifiers.
- static bool FindNestedNameSpecifierMember(CXXBaseSpecifier *Specifier,
+ static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *UserData);
@@ -1244,6 +1247,11 @@ public:
/// used for user-defined conversions.
bool isConvertingConstructor(bool AllowExplicit) const;
+ /// \brief Determine whether this is a member template specialization that
+ /// looks like a copy constructor. Such constructors are never used to copy
+ /// an object.
+ bool isCopyConstructorLikeSpecialization() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == CXXConstructor;
@@ -1261,13 +1269,6 @@ public:
/// };
/// @endcode
class CXXDestructorDecl : public CXXMethodDecl {
-public:
- enum KindOfObjectToDestroy {
- VBASE = 0x1,
- DRCTNONVBASE = 0x2,
- ANYBASE = 0x3
- };
-private:
/// ImplicitlyDefined - Whether this destructor was implicitly
/// defined by the compiler. When false, the destructor was defined
/// by the user. In C++03, this flag will have the same value as
@@ -1276,24 +1277,15 @@ private:
/// @c !Implicit && ImplicitlyDefined.
bool ImplicitlyDefined : 1;
- /// Support for base and member destruction.
- /// BaseOrMemberDestructions - The arguments used to destruct the base
- /// or member. Each uintptr_t value represents one of base classes (either
- /// virtual or direct non-virtual base), or non-static data member
- /// to be destroyed. The low two bits encode the kind of object
- /// being destroyed.
- uintptr_t *BaseOrMemberDestructions;
- unsigned NumBaseOrMemberDestructions;
-
+ FunctionDecl *OperatorDelete;
+
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXDestructor, RD, L, N, T, /*DInfo=*/0, false, isInline),
- ImplicitlyDefined(false),
- BaseOrMemberDestructions(0), NumBaseOrMemberDestructions(0) {
+ ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
- virtual void Destroy(ASTContext& C);
public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@@ -1319,95 +1311,8 @@ public:
ImplicitlyDefined = ID;
}
- /// destr_iterator - Iterates through the member/base destruction list.
-
- /// destr_const_iterator - Iterates through the member/base destruction list.
- typedef uintptr_t const destr_const_iterator;
-
- /// destr_begin() - Retrieve an iterator to the first destructed member/base.
- uintptr_t* destr_begin() {
- return BaseOrMemberDestructions;
- }
- /// destr_begin() - Retrieve an iterator to the first destructed member/base.
- uintptr_t* destr_begin() const {
- return BaseOrMemberDestructions;
- }
-
- /// destr_end() - Retrieve an iterator past the last destructed member/base.
- uintptr_t* destr_end() {
- return BaseOrMemberDestructions + NumBaseOrMemberDestructions;
- }
- /// destr_end() - Retrieve an iterator past the last destructed member/base.
- uintptr_t* destr_end() const {
- return BaseOrMemberDestructions + NumBaseOrMemberDestructions;
- }
-
- /// getNumBaseOrMemberDestructions - Number of base and non-static members
- /// to destroy.
- unsigned getNumBaseOrMemberDestructions() const {
- return NumBaseOrMemberDestructions;
- }
-
- /// setNumBaseOrMemberDestructions - Set number of base and non-static members
- /// to destroy.
- void setNumBaseOrMemberDestructions(unsigned numBaseOrMemberDestructions) {
- NumBaseOrMemberDestructions = numBaseOrMemberDestructions;
- }
-
- /// getBaseOrMemberToDestroy - get the generic 'member' representing either
- /// the field or a base class.
- uintptr_t* getBaseOrMemberToDestroy() const {
- return BaseOrMemberDestructions;
- }
-
- /// setBaseOrMemberToDestroy - set the generic 'member' representing either
- /// the field or a base class.
- void setBaseOrMemberDestructions(uintptr_t* baseOrMemberDestructions) {
- BaseOrMemberDestructions = baseOrMemberDestructions;
- }
-
- /// isVbaseToDestroy - returns true, if object is virtual base.
- bool isVbaseToDestroy(uintptr_t Vbase) const {
- return (Vbase & VBASE) != 0;
- }
- /// isDirectNonVBaseToDestroy - returns true, if object is direct non-virtual
- /// base.
- bool isDirectNonVBaseToDestroy(uintptr_t DrctNonVbase) const {
- return (DrctNonVbase & DRCTNONVBASE) != 0;
- }
- /// isAnyBaseToDestroy - returns true, if object is any base (virtual or
- /// direct non-virtual)
- bool isAnyBaseToDestroy(uintptr_t AnyBase) const {
- return (AnyBase & ANYBASE) != 0;
- }
- /// isMemberToDestroy - returns true if object is a non-static data member.
- bool isMemberToDestroy(uintptr_t Member) const {
- return (Member & ANYBASE) == 0;
- }
- /// getAnyBaseClassToDestroy - Get the type for the given base class object.
- Type *getAnyBaseClassToDestroy(uintptr_t Base) const {
- if (isAnyBaseToDestroy(Base))
- return reinterpret_cast<Type*>(Base & ~0x03);
- return 0;
- }
- /// getMemberToDestroy - Get the member for the given object.
- FieldDecl *getMemberToDestroy(uintptr_t Member) const {
- if (isMemberToDestroy(Member))
- return reinterpret_cast<FieldDecl *>(Member);
- return 0;
- }
- /// getVbaseClassToDestroy - Get the virtual base.
- Type *getVbaseClassToDestroy(uintptr_t Vbase) const {
- if (isVbaseToDestroy(Vbase))
- return reinterpret_cast<Type*>(Vbase & ~0x01);
- return 0;
- }
- /// getDirectNonVBaseClassToDestroy - Get the virtual base.
- Type *getDirectNonVBaseClassToDestroy(uintptr_t Base) const {
- if (isDirectNonVBaseToDestroy(Base))
- return reinterpret_cast<Type*>(Base & ~0x02);
- return 0;
- }
+ void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
+ const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
@@ -1739,6 +1644,56 @@ public:
static bool classof(const NamespaceAliasDecl *D) { return true; }
};
+/// UsingShadowDecl - Represents a shadow declaration introduced into
+/// a scope by a (resolved) using declaration. For example,
+///
+/// namespace A {
+/// void foo();
+/// }
+/// namespace B {
+/// using A::foo(); // <- a UsingDecl
+/// // Also creates a UsingShadowDecl for A::foo in B
+/// }
+///
+class UsingShadowDecl : public NamedDecl {
+ /// The referenced declaration.
+ NamedDecl *Underlying;
+
+ /// The using declaration which introduced this decl.
+ UsingDecl *Using;
+
+ UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target)
+ : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+ Underlying(Target), Using(Using) {
+ IdentifierNamespace = Target->getIdentifierNamespace();
+ setImplicit();
+ }
+
+public:
+ static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target) {
+ return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ }
+
+ /// Gets the underlying declaration which has been brought into the
+ /// local scope.
+ NamedDecl *getTargetDecl() const {
+ return Underlying;
+ }
+
+ /// Gets the using declaration to which this declaration is tied.
+ UsingDecl *getUsingDecl() const {
+ return Using;
+ }
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Decl::UsingShadow;
+ }
+ static bool classof(const UsingShadowDecl *D) { return true; }
+};
+
/// UsingDecl - Represents a C++ using-declaration. For example:
/// using someNameSpace::someIdentifier;
class UsingDecl : public NamedDecl {
@@ -1746,29 +1701,26 @@ class UsingDecl : public NamedDecl {
/// preceding the declaration name.
SourceRange NestedNameRange;
- /// \brief The source location of the target declaration name.
- SourceLocation TargetNameLocation;
-
/// \brief The source location of the "using" location itself.
SourceLocation UsingLocation;
- /// \brief Target declaration.
- NamedDecl* TargetDecl;
-
/// \brief Target nested name specifier.
- NestedNameSpecifier* TargetNestedNameDecl;
+ NestedNameSpecifier* TargetNestedName;
+
+ /// \brief The collection of shadow declarations associated with
+ /// this using declaration. This set can change as a class is
+ /// processed.
+ llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
// \brief Has 'typename' keyword.
bool IsTypeName;
UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
- SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg)
- : NamedDecl(Decl::Using, DC, L, Target->getDeclName()),
- NestedNameRange(NNR), TargetNameLocation(TargetNL),
- UsingLocation(UL), TargetDecl(Target),
- TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) {
- this->IdentifierNamespace = TargetDecl->getIdentifierNamespace();
+ SourceLocation UL, NestedNameSpecifier* TargetNNS,
+ DeclarationName Name, bool IsTypeNameArg)
+ : NamedDecl(Decl::Using, DC, L, Name),
+ NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
+ IsTypeName(IsTypeNameArg) {
}
public:
@@ -1776,28 +1728,37 @@ public:
/// preceding the namespace name.
SourceRange getNestedNameRange() { return NestedNameRange; }
- /// \brief Returns the source location of the target declaration name.
- SourceLocation getTargetNameLocation() { return TargetNameLocation; }
-
/// \brief Returns the source location of the "using" location itself.
SourceLocation getUsingLocation() { return UsingLocation; }
- /// \brief getTargetDecl - Returns target specified by using-decl.
- NamedDecl *getTargetDecl() { return TargetDecl; }
- const NamedDecl *getTargetDecl() const { return TargetDecl; }
-
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameDecl() {
- return TargetNestedNameDecl;
+ return TargetNestedName;
}
/// isTypeName - Return true if using decl has 'typename'.
bool isTypeName() const { return IsTypeName; }
+ typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
+ shadow_iterator shadow_begin() const { return Shadows.begin(); }
+ shadow_iterator shadow_end() const { return Shadows.end(); }
+
+ void addShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.insert(S)) {
+ assert(false && "declaration already in set");
+ }
+ }
+ void removeShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.erase(S)) {
+ assert(false && "declaration not in set");
+ }
+ }
+
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
- SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg);
+ SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
+ NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
static bool classof(const Decl *D) {
return D->getKind() == Decl::Using;
@@ -1805,31 +1766,88 @@ public:
static bool classof(const UsingDecl *D) { return true; }
};
-/// UnresolvedUsingDecl - Represents a using declaration whose name can not
-/// yet be resolved.
-class UnresolvedUsingDecl : public NamedDecl {
+/// UnresolvedUsingValueDecl - Represents a dependent using
+/// declaration which was not marked with 'typename'. Unlike
+/// non-dependent using declarations, these *only* bring through
+/// non-types; otherwise they would break two-phase lookup.
+///
+/// template <class T> class A : public Base<T> {
+/// using Base<T>::foo;
+/// };
+class UnresolvedUsingValueDecl : public ValueDecl {
/// \brief The source range that covers the nested-name-specifier
/// preceding the declaration name.
SourceRange TargetNestedNameRange;
- /// \brief The source location of the target declaration name.
- SourceLocation TargetNameLocation;
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
NestedNameSpecifier *TargetNestedNameSpecifier;
- DeclarationName TargetName;
+ UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
+ SourceLocation UsingLoc, SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName)
+ : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TargetNestedNameSpecifier(TargetNNS)
+ { }
- // \brief Has 'typename' keyword.
- bool IsTypeName;
+public:
+ /// \brief Returns the source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
- UnresolvedUsingDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc, DeclarationName TargetName,
- bool IsTypeNameArg)
- : NamedDecl(Decl::UnresolvedUsing, DC, UsingLoc, TargetName),
- TargetNestedNameRange(TargetNNR), TargetNameLocation(TargetNameLoc),
- TargetNestedNameSpecifier(TargetNNS), TargetName(TargetName),
- IsTypeName(IsTypeNameArg) { }
+ /// \brief Get target nested name declaration.
+ NestedNameSpecifier* getTargetNestedNameSpecifier() {
+ return TargetNestedNameSpecifier;
+ }
+
+ /// \brief Returns the source location of the 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
+
+ static UnresolvedUsingValueDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Decl::UnresolvedUsingValue;
+ }
+ static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+};
+
+/// UnresolvedUsingTypenameDecl - Represents a dependent using
+/// declaration which was marked with 'typename'.
+///
+/// template <class T> class A : public Base<T> {
+/// using typename Base<T>::foo;
+/// };
+///
+/// The type associated with a unresolved using typename decl is
+/// currently always a typename type.
+class UnresolvedUsingTypenameDecl : public TypeDecl {
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the declaration name.
+ SourceRange TargetNestedNameRange;
+
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
+
+ /// \brief The source location of the 'typename' keyword
+ SourceLocation TypenameLocation;
+
+ NestedNameSpecifier *TargetNestedNameSpecifier;
+
+ UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
+ : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
+ { }
public:
/// \brief Returns the source range that covers the nested-name-specifier
@@ -1841,26 +1859,22 @@ public:
return TargetNestedNameSpecifier;
}
- /// \brief Returns the source location of the target declaration name.
- SourceLocation getTargetNameLocation() const { return TargetNameLocation; }
+ /// \brief Returns the source location of the 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
- /// \brief Returns the source location of the target declaration name.
- DeclarationName getTargetName() const { return TargetName; }
-
- bool isTypeName() const { return IsTypeName; }
+ /// \brief Returns the source location of the 'typename' keyword.
+ SourceLocation getTypenameLoc() const { return TypenameLocation; }
- static UnresolvedUsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc,
- DeclarationName TargetName,
- bool IsTypeNameArg);
+ static UnresolvedUsingTypenameDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsing;
+ return D->getKind() == Decl::UnresolvedUsingTypename;
}
- static bool classof(const UnresolvedUsingDecl *D) { return true; }
+ static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index d9e40d478907..c2b48cee36f4 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -14,8 +14,9 @@
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
-#include "clang/AST/DeclBase.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
index 3ef3cc3f0975..ec1b3b055cab 100644
--- a/include/clang/AST/DeclNodes.def
+++ b/include/clang/AST/DeclNodes.def
@@ -81,6 +81,7 @@ ABSTRACT_DECL(Named, Decl)
DECL(NamespaceAlias, NamedDecl)
ABSTRACT_DECL(Type, NamedDecl)
DECL(Typedef, TypeDecl)
+ DECL(UnresolvedUsingTypename, TypeDecl)
ABSTRACT_DECL(Tag, TypeDecl)
DECL(Enum, TagDecl)
DECL(Record, TagDecl)
@@ -91,6 +92,7 @@ ABSTRACT_DECL(Named, Decl)
DECL(TemplateTypeParm, TypeDecl)
ABSTRACT_DECL(Value, NamedDecl)
DECL(EnumConstant, ValueDecl)
+ DECL(UnresolvedUsingValue, ValueDecl)
ABSTRACT_DECL(Declarator, ValueDecl)
DECL(Function, DeclaratorDecl)
DECL(CXXMethod, FunctionDecl)
@@ -109,7 +111,7 @@ ABSTRACT_DECL(Named, Decl)
DECL(ClassTemplate, TemplateDecl)
DECL(TemplateTemplateParm, TemplateDecl)
DECL(Using, NamedDecl)
- DECL(UnresolvedUsing, NamedDecl)
+ DECL(UsingShadow, NamedDecl)
DECL(ObjCMethod, NamedDecl)
DECL(ObjCContainer, NamedDecl)
DECL(ObjCCategory, ObjCContainerDecl)
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index bcd28eab039f..13193ffab55e 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -718,10 +718,22 @@ public:
/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
///
class ObjCClassDecl : public Decl {
- ObjCList<ObjCInterfaceDecl> ForwardDecls;
+public:
+ class ObjCClassRef {
+ ObjCInterfaceDecl *ID;
+ SourceLocation L;
+ public:
+ ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
+ SourceLocation getLocation() const { return L; }
+ ObjCInterfaceDecl *getInterface() const { return ID; }
+ };
+private:
+ ObjCClassRef *ForwardDecls;
+ unsigned NumDecls;
ObjCClassDecl(DeclContext *DC, SourceLocation L,
- ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C);
+ ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,
+ unsigned nElts, ASTContext &C);
virtual ~ObjCClassDecl() {}
public:
@@ -730,17 +742,19 @@ public:
static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts = 0,
+ const SourceLocation *Locs = 0,
unsigned nElts = 0);
+
+ virtual SourceRange getSourceRange() const;
- typedef ObjCList<ObjCInterfaceDecl>::iterator iterator;
- iterator begin() const { return ForwardDecls.begin(); }
- iterator end() const { return ForwardDecls.end(); }
- unsigned size() const { return ForwardDecls.size(); }
+ typedef const ObjCClassRef* iterator;
+ iterator begin() const { return ForwardDecls; }
+ iterator end() const { return ForwardDecls + NumDecls; }
+ unsigned size() const { return NumDecls; }
/// setClassList - Set the list of forward classes.
- void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) {
- ForwardDecls.set(List, Num, C);
- }
+ void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+ const SourceLocation *Locs, unsigned Num);
static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
static bool classof(const ObjCClassDecl *D) { return true; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index f1a27933a1b3..14f666005cd6 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -699,13 +699,13 @@ class TemplateTemplateParmDecl
: public TemplateDecl, protected TemplateParmPosition {
/// \brief The default template argument, if any.
- Expr *DefaultArgument;
+ TemplateArgumentLoc DefaultArgument;
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), DefaultArgument(0)
+ TemplateParmPosition(D, P), DefaultArgument()
{ }
public:
@@ -720,16 +720,17 @@ public:
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return DefaultArgument; }
+ bool hasDefaultArgument() const {
+ return !DefaultArgument.getArgument().isNull();
+ }
/// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const { return DefaultArgument; }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
+ const TemplateArgumentLoc &getDefaultArgument() const {
+ return DefaultArgument;
+ }
/// \brief Set the default argument for this template parameter.
- void setDefaultArgument(Expr *DefArg) {
+ void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
DefaultArgument = DefArg;
}
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index ed4ac6b5d4e7..a30f6e860dde 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -176,7 +176,6 @@ public:
/// getNameKind - Determine what kind of name this is.
NameKind getNameKind() const;
-
/// getName - Retrieve the human-readable string for this name.
std::string getAsString() const;
@@ -249,6 +248,8 @@ public:
static DeclarationName getTombstoneMarker() {
return DeclarationName(uintptr_t(-2));
}
+
+ void dump() const;
};
/// Ordering on two declaration names. If both names are identifiers,
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 2a87f5883588..dfc5b13f28d3 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -87,7 +87,7 @@ public:
// type. Additionally, inspect Expr::isLvalue to determine whether
// an expression that is adjusted in this manner should be
// considered an lvalue.
- assert((TR.isNull() || !TR->isReferenceType()) &&
+ assert((t.isNull() || !t->isReferenceType()) &&
"Expressions can't have reference type");
TR = t;
@@ -250,6 +250,12 @@ public:
/// folded, but discard the result.
bool isEvaluatable(ASTContext &Ctx) const;
+ /// HasSideEffects - This routine returns true for all those expressions
+ /// which must be evaluated each time and must not be optimization away
+ /// or evaluated at compile time. Example is a function call, volatile
+ /// variable read.
+ bool HasSideEffects(ASTContext &Ctx) const;
+
/// EvaluateAsInt - Call Evaluate and return the folded integer. This
/// must be called on an expression that constant folds to an integer.
llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const;
@@ -1513,6 +1519,9 @@ public:
/// CK_NoOp - Used for const_cast.
CK_NoOp,
+ /// CK_BaseToDerived - Base to derived class casts.
+ CK_BaseToDerived,
+
/// CK_DerivedToBase - Derived to base class casts.
CK_DerivedToBase,
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 5931a3fcf984..9e6fd4fd065b 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -95,6 +95,8 @@ public:
/// operation would return "x".
Expr *getImplicitObjectArgument();
+ virtual SourceRange getSourceRange() const;
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXMemberCallExprClass;
}
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 5f318ba0b33b..9b1c640a40b2 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -15,6 +15,8 @@
#define LLVM_CLANG_AST_LAYOUTINFO_H
#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/DeclCXX.h"
namespace clang {
class ASTContext;
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 1e6871ff3b9c..867932332d09 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "llvm/ADT/PointerIntPair.h"
+#include <iterator>
namespace clang {
@@ -23,6 +24,8 @@ template<typename decl_type>
class Redeclarable {
protected:
+ // FIXME: PointerIntPair is a value class that should not be inherited from.
+ // This should change to using containment.
struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> {
DeclLink(decl_type *D, bool isLatest)
: llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { }
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index bb14c62d7770..6db095872b0e 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/ErrorHandling.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TemplateName.h"
namespace llvm {
class FoldingSetNodeID;
@@ -48,21 +49,27 @@ class TemplateArgument {
public:
/// \brief The type of template argument we're storing.
enum ArgKind {
+ /// \brief Represents an empty template argument, e.g., one that has not
+ /// been deduced.
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,
+ Type,
+ /// The template argument is a declaration that was provided for a pointer
+ /// or reference non-type template parameter.
+ Declaration,
+ /// The template argument is an integral value stored in an llvm::APSInt
+ /// that was provided for an integral non-type template parameter.
+ Integral,
+ /// The template argument is a template name that was provided for a
+ /// template template parameter.
+ Template,
/// The template argument is a value- or type-dependent expression
/// stored in an Expr*.
- Expression = 4,
-
+ Expression,
/// The template argument is actually a parameter pack. Arguments are stored
/// in the Args struct.
- Pack = 5
+ Pack
} Kind;
/// \brief Construct an empty, invalid template argument.
@@ -82,12 +89,21 @@ public:
}
/// \brief Construct an integral constant template argument.
- TemplateArgument(const llvm::APSInt &Value, QualType Type)
- : Kind(Integral) {
+ TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
new (Integer.Value) llvm::APSInt(Value);
Integer.Type = Type.getAsOpaquePtr();
}
+ /// \brief Construct a template argument that is a template.
+ ///
+ /// This form of template argument is generally used for template template
+ /// parameters. However, the template name could be a dependent template
+ /// name that ends up being instantiated to a function template whose address
+ /// is taken.
+ TemplateArgument(TemplateName Name) : Kind(Template) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
+ }
+
/// \brief Construct a template argument that is an expression.
///
/// This form of template argument only occurs in template argument
@@ -172,6 +188,15 @@ public:
return reinterpret_cast<Decl *>(TypeOrValue);
}
+ /// \brief Retrieve the template argument as a template name.
+ TemplateName getAsTemplate() const {
+ if (Kind != Template)
+ return TemplateName();
+
+ return TemplateName::getFromVoidPointer(
+ reinterpret_cast<void *> (TypeOrValue));
+ }
+
/// \brief Retrieve the template argument as an integral value.
llvm::APSInt *getAsIntegral() {
if (Kind != Integral)
@@ -242,13 +267,18 @@ private:
union {
Expr *Expression;
DeclaratorInfo *Declarator;
+ struct {
+ unsigned QualifierRange[2];
+ unsigned TemplateNameLoc;
+ } Template;
};
#ifndef NDEBUG
enum Kind {
K_None,
K_DeclaratorInfo,
- K_Expression
+ K_Expression,
+ K_Template
} Kind;
#endif
@@ -273,6 +303,17 @@ public:
, Kind(K_Expression)
#endif
{}
+
+ TemplateArgumentLocInfo(SourceRange QualifierRange,
+ SourceLocation TemplateNameLoc)
+#ifndef NDEBUG
+ : Kind(K_Template)
+#endif
+ {
+ Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
+ Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
+ Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+ }
DeclaratorInfo *getAsDeclaratorInfo() const {
assert(Kind == K_DeclaratorInfo);
@@ -284,6 +325,18 @@ public:
return Expression;
}
+ SourceRange getTemplateQualifierRange() const {
+ assert(Kind == K_Template);
+ return SourceRange(
+ SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
+ SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ assert(Kind == K_Template);
+ return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
+ }
+
#ifndef NDEBUG
void validateForArgument(const TemplateArgument &Arg) {
switch (Arg.getKind()) {
@@ -294,6 +347,9 @@ public:
case TemplateArgument::Declaration:
assert(Kind == K_Expression);
break;
+ case TemplateArgument::Template:
+ assert(Kind == K_Template);
+ break;
case TemplateArgument::Integral:
case TemplateArgument::Pack:
assert(Kind == K_None);
@@ -329,8 +385,18 @@ public:
assert(Argument.getKind() == TemplateArgument::Expression);
}
- /// \brief - Fetches the start location of the argument.
+ TemplateArgumentLoc(const TemplateArgument &Argument,
+ SourceRange QualifierRange,
+ SourceLocation TemplateNameLoc)
+ : Argument(Argument), LocInfo(QualifierRange, TemplateNameLoc) {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ }
+
+ /// \brief - Fetches the primary location of the argument.
SourceLocation getLocation() const {
+ if (Argument.getKind() == TemplateArgument::Template)
+ return getTemplateNameLoc();
+
return getSourceRange().getBegin();
}
@@ -359,6 +425,16 @@ public:
assert(Argument.getKind() == TemplateArgument::Declaration);
return LocInfo.getAsExpr();
}
+
+ SourceRange getTemplateQualifierRange() const {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ return LocInfo.getTemplateQualifierRange();
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ return LocInfo.getTemplateNameLoc();
+ }
};
}
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index daa814739182..c28bafe9a30f 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -396,10 +396,6 @@ class QualType {
llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
Qualifiers::FastWidth> Value;
- bool hasExtQuals() const {
- return Value.getPointer().is<const ExtQuals*>();
- }
-
const ExtQuals *getExtQualsUnsafe() const {
return Value.getPointer().get<const ExtQuals*>();
}
@@ -408,6 +404,8 @@ class QualType {
return Value.getPointer().get<const Type*>();
}
+ QualType getUnqualifiedTypeSlow() const;
+
friend class QualifierCollector;
public:
QualType() {}
@@ -417,14 +415,14 @@ public:
QualType(const ExtQuals *Ptr, unsigned Quals)
: Value(Ptr, Quals) {}
- unsigned getFastQualifiers() const { return Value.getInt(); }
- void setFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+ unsigned getLocalFastQualifiers() const { return Value.getInt(); }
+ void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
/// Retrieves a pointer to the underlying (unqualified) type.
/// This should really return a const Type, but it's not worth
/// changing all the users right now.
Type *getTypePtr() const {
- if (hasNonFastQualifiers())
+ if (hasLocalNonFastQualifiers())
return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
return const_cast<Type*>(getTypePtrUnsafe());
}
@@ -452,41 +450,81 @@ public:
return Value.getPointer().isNull();
}
- bool isConstQualified() const {
- return (getFastQualifiers() & Qualifiers::Const);
- }
- bool isRestrictQualified() const {
- return (getFastQualifiers() & Qualifiers::Restrict);
- }
- bool isVolatileQualified() const {
- return (hasNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
- }
-
- // Determines whether this type has any direct qualifiers.
- bool hasQualifiers() const {
- return getFastQualifiers() || hasNonFastQualifiers();
- }
-
- bool hasNonFastQualifiers() const {
- return hasExtQuals();
+ /// \brief Determine whether this particular QualType instance has the
+ /// "const" qualifier set, without looking through typedefs that may have
+ /// added "const" at a different level.
+ bool isLocalConstQualified() const {
+ return (getLocalFastQualifiers() & Qualifiers::Const);
+ }
+
+ /// \brief Determine whether this type is const-qualified.
+ bool isConstQualified() const;
+
+ /// \brief Determine whether this particular QualType instance has the
+ /// "restrict" qualifier set, without looking through typedefs that may have
+ /// added "restrict" at a different level.
+ bool isLocalRestrictQualified() const {
+ return (getLocalFastQualifiers() & Qualifiers::Restrict);
+ }
+
+ /// \brief Determine whether this type is restrict-qualified.
+ bool isRestrictQualified() const;
+
+ /// \brief Determine whether this particular QualType instance has the
+ /// "volatile" qualifier set, without looking through typedefs that may have
+ /// added "volatile" at a different level.
+ bool isLocalVolatileQualified() const {
+ return (hasLocalNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
+ }
+
+ /// \brief Determine whether this type is volatile-qualified.
+ bool isVolatileQualified() const;
+
+ /// \brief Determine whether this particular QualType instance has any
+ /// qualifiers, without looking through any typedefs that might add
+ /// qualifiers at a different level.
+ bool hasLocalQualifiers() const {
+ return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
+ }
+
+ /// \brief Determine whether this type has any qualifiers.
+ bool hasQualifiers() const;
+
+ /// \brief Determine whether this particular QualType instance has any
+ /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
+ /// instance.
+ bool hasLocalNonFastQualifiers() const {
+ return Value.getPointer().is<const ExtQuals*>();
}
- // Retrieves the set of qualifiers belonging to this type.
- Qualifiers getQualifiers() const {
+ /// \brief Retrieve the set of qualifiers local to this particular QualType
+ /// instance, not including any qualifiers acquired through typedefs or
+ /// other sugar.
+ Qualifiers getLocalQualifiers() const {
Qualifiers Quals;
- if (hasNonFastQualifiers())
+ if (hasLocalNonFastQualifiers())
Quals = getExtQualsUnsafe()->getQualifiers();
- Quals.addFastQualifiers(getFastQualifiers());
+ Quals.addFastQualifiers(getLocalFastQualifiers());
return Quals;
}
- // Retrieves the CVR qualifiers of this type.
- unsigned getCVRQualifiers() const {
- unsigned CVR = getFastQualifiers();
- if (isVolatileQualified()) CVR |= Qualifiers::Volatile;
+ /// \brief Retrieve the set of qualifiers applied to this type.
+ Qualifiers getQualifiers() const;
+
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// local to this particular QualType instance, not including any qualifiers
+ /// acquired through typedefs or other sugar.
+ unsigned getLocalCVRQualifiers() const {
+ unsigned CVR = getLocalFastQualifiers();
+ if (isLocalVolatileQualified())
+ CVR |= Qualifiers::Volatile;
return CVR;
}
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// applied to this type.
+ unsigned getCVRQualifiers() const;
+
bool isConstant(ASTContext& Ctx) const {
return QualType::isConstant(*this, Ctx);
}
@@ -508,6 +546,9 @@ public:
Value.setInt(Value.getInt() | TQs);
}
+ // FIXME: The remove* functions are semantically broken, because they might
+ // not remove a qualifier stored on a typedef. Most of the with* functions
+ // have the same problem.
void removeConst();
void removeVolatile();
void removeRestrict();
@@ -540,8 +581,21 @@ public:
return T;
}
- QualType getUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+ /// \brief Return this type with all of the instance-specific qualifiers
+ /// removed, but without removing any qualifiers that may have been applied
+ /// through typedefs.
+ QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+ /// \brief Return the unqualified form of the given type, which might be
+ /// desugared to eliminate qualifiers introduced via typedefs.
+ QualType getUnqualifiedType() const {
+ QualType T = getLocalUnqualifiedType();
+ if (!T.hasQualifiers())
+ return T;
+
+ return getUnqualifiedTypeSlow();
+ }
+
bool isMoreQualifiedThan(QualType Other) const;
bool isAtLeastAsQualifiedAs(QualType Other) const;
QualType getNonReferenceType() const;
@@ -892,8 +946,6 @@ public:
QualType getCanonicalTypeInternal() const { return CanonicalType; }
void dump() const;
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const = 0;
static bool classof(const Type *) { return true; }
};
@@ -963,8 +1015,21 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
+ bool isInteger() const {
+ return TypeKind >= Bool && TypeKind <= Int128;
+ }
+
+ bool isSignedInteger() const {
+ return TypeKind >= Char_S && TypeKind <= Int128;
+ }
+
+ bool isUnsignedInteger() const {
+ return TypeKind >= Bool && TypeKind <= UInt128;
+ }
+
+ bool isFloatingPoint() const {
+ return TypeKind >= Float && TypeKind <= LongDouble;
+ }
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
@@ -988,9 +1053,6 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == FixedWidthInt; }
static bool classof(const FixedWidthIntType *) { return true; }
};
@@ -1008,9 +1070,6 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
public:
QualType getElementType() const { return ElementType; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1036,9 +1095,6 @@ class PointerType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these.
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
QualType getPointeeType() const { return PointeeType; }
bool isSugared() const { return false; }
@@ -1071,9 +1127,6 @@ public:
// Get the pointee type. Pointee is required to always be a function type.
QualType getPointeeType() const { return PointeeType; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1157,9 +1210,6 @@ class LValueReferenceType : public ReferenceType {
{}
friend class ASTContext; // ASTContext creates these
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1177,9 +1227,6 @@ class RValueReferenceType : public ReferenceType {
}
friend class ASTContext; // ASTContext creates these
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1209,9 +1256,6 @@ public:
const Type *getClass() const { return Class; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1302,9 +1346,6 @@ protected:
friend class ASTContext; // ASTContext creates these.
public:
const llvm::APInt &getSize() const { return Size; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1336,9 +1377,6 @@ class IncompleteArrayType : public ArrayType {
: ArrayType(IncompleteArray, et, can, sm, tq) {}
friend class ASTContext; // ASTContext creates these.
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1402,9 +1440,6 @@ public:
SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1458,9 +1493,6 @@ public:
SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1510,9 +1542,6 @@ public:
QualType getElementType() const { return ElementType; }
SourceLocation getAttributeLoc() const { return loc; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1555,9 +1584,6 @@ public:
QualType getElementType() const { return ElementType; }
unsigned getNumElements() const { return NumElements; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1633,9 +1659,6 @@ public:
return unsigned(idx-1) < NumElements;
return false;
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1699,9 +1722,6 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
public:
// No additional state past what FunctionType provides.
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1812,9 +1832,6 @@ public:
return exception_begin() + NumExceptions;
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1856,9 +1873,6 @@ public:
bool isSugared() const { return true; }
QualType desugar() const;
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
static bool classof(const TypedefType *) { return true; }
};
@@ -1879,9 +1893,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
static bool classof(const TypeOfExprType *) { return true; }
};
@@ -1924,9 +1935,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
static bool classof(const TypeOfType *) { return true; }
};
@@ -1953,9 +1961,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return !isDependentType(); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
static bool classof(const DecltypeType *) { return true; }
};
@@ -2000,9 +2005,6 @@ public:
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@@ -2117,9 +2119,6 @@ public:
}
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getUnderlyingType(), getTagKind());
}
@@ -2155,9 +2154,6 @@ public:
bool isParameterPack() const { return ParameterPack; }
IdentifierInfo *getName() const { return Name; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2211,9 +2207,6 @@ public:
return getCanonicalTypeInternal();
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return true; }
QualType desugar() const { return getReplacementType(); }
@@ -2309,9 +2302,6 @@ public:
/// \precondition @c isArgType(Arg)
const TemplateArgument &getArg(unsigned Idx) const;
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return !isDependentType(); }
QualType desugar() const { return getCanonicalTypeInternal(); }
@@ -2363,9 +2353,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, NNS, NamedType);
}
@@ -2440,9 +2427,6 @@ public:
return Name.dyn_cast<const TemplateSpecializationType *>();
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2493,9 +2477,6 @@ public:
qual_iterator qual_end() const { return Protocols.end(); }
bool qual_empty() const { return Protocols.size() == 0; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2581,8 +2562,6 @@ public:
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
ObjCProtocolDecl **protocols, unsigned NumProtocols);
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
@@ -2604,8 +2583,8 @@ public:
/// Collect any qualifiers on the given type and return an
/// unqualified type.
const Type *strip(QualType QT) {
- addFastQualifiers(QT.getFastQualifiers());
- if (QT.hasNonFastQualifiers()) {
+ addFastQualifiers(QT.getLocalFastQualifiers());
+ if (QT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = QT.getExtQualsUnsafe();
Context = &EQ->getContext();
addQualifiers(EQ->getQualifiers());
@@ -2627,18 +2606,51 @@ public:
inline bool QualType::isCanonical() const {
const Type *T = getTypePtr();
- if (hasQualifiers())
+ if (hasLocalQualifiers())
return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
return T->isCanonicalUnqualified();
}
inline bool QualType::isCanonicalAsParam() const {
- if (hasQualifiers()) return false;
+ if (hasLocalQualifiers()) return false;
const Type *T = getTypePtr();
return T->isCanonicalUnqualified() &&
!isa<FunctionType>(T) && !isa<ArrayType>(T);
}
+inline bool QualType::isConstQualified() const {
+ return isLocalConstQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+ return isLocalRestrictQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+ return isLocalVolatileQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalVolatileQualified();
+}
+
+inline bool QualType::hasQualifiers() const {
+ return hasLocalQualifiers() ||
+ getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers();
+}
+
+inline Qualifiers QualType::getQualifiers() const {
+ Qualifiers Quals = getLocalQualifiers();
+ Quals.addQualifiers(
+ getTypePtr()->getCanonicalTypeInternal().getLocalQualifiers());
+ return Quals;
+}
+
+inline unsigned QualType::getCVRQualifiers() const {
+ return getLocalCVRQualifiers() |
+ getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
+}
+
inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const);
}
@@ -2673,14 +2685,14 @@ inline void QualType::removeCVRQualifiers(unsigned Mask) {
/// getAddressSpace - Return the address space of this type.
inline unsigned QualType::getAddressSpace() const {
- if (hasNonFastQualifiers()) {
+ if (hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = getExtQualsUnsafe();
if (EQ->hasAddressSpace())
return EQ->getAddressSpace();
}
QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (CT.hasNonFastQualifiers()) {
+ if (CT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = CT.getExtQualsUnsafe();
if (EQ->hasAddressSpace())
return EQ->getAddressSpace();
@@ -2695,14 +2707,14 @@ inline unsigned QualType::getAddressSpace() const {
/// getObjCGCAttr - Return the gc attribute of this type.
inline Qualifiers::GC QualType::getObjCGCAttr() const {
- if (hasNonFastQualifiers()) {
+ if (hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = getExtQualsUnsafe();
if (EQ->hasObjCGCAttr())
return EQ->getObjCGCAttr();
}
QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (CT.hasNonFastQualifiers()) {
+ if (CT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = CT.getExtQualsUnsafe();
if (EQ->hasObjCGCAttr())
return EQ->getObjCGCAttr();
@@ -2780,28 +2792,26 @@ inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
return 0;
}
-// NOTE: All of these methods use "getUnqualifiedType" to strip off address
-// space qualifiers if present.
inline bool Type::isFunctionType() const {
- return isa<FunctionType>(CanonicalType.getUnqualifiedType());
+ return isa<FunctionType>(CanonicalType);
}
inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType.getUnqualifiedType());
+ return isa<PointerType>(CanonicalType);
}
inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
inline bool Type::isBlockPointerType() const {
- return isa<BlockPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<BlockPointerType>(CanonicalType);
}
inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<ReferenceType>(CanonicalType);
}
inline bool Type::isLValueReferenceType() const {
- return isa<LValueReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<LValueReferenceType>(CanonicalType);
}
inline bool Type::isRValueReferenceType() const {
- return isa<RValueReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<RValueReferenceType>(CanonicalType);
}
inline bool Type::isFunctionPointerType() const {
if (const PointerType* T = getAs<PointerType>())
@@ -2810,7 +2820,7 @@ inline bool Type::isFunctionPointerType() const {
return false;
}
inline bool Type::isMemberPointerType() const {
- return isa<MemberPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<MemberPointerType>(CanonicalType);
}
inline bool Type::isMemberFunctionPointerType() const {
if (const MemberPointerType* T = getAs<MemberPointerType>())
@@ -2819,37 +2829,37 @@ inline bool Type::isMemberFunctionPointerType() const {
return false;
}
inline bool Type::isArrayType() const {
- return isa<ArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<ArrayType>(CanonicalType);
}
inline bool Type::isConstantArrayType() const {
- return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<ConstantArrayType>(CanonicalType);
}
inline bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<IncompleteArrayType>(CanonicalType);
}
inline bool Type::isVariableArrayType() const {
- return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<VariableArrayType>(CanonicalType);
}
inline bool Type::isDependentSizedArrayType() const {
- return isa<DependentSizedArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<DependentSizedArrayType>(CanonicalType);
}
inline bool Type::isRecordType() const {
- return isa<RecordType>(CanonicalType.getUnqualifiedType());
+ return isa<RecordType>(CanonicalType);
}
inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType.getUnqualifiedType());
+ return isa<ComplexType>(CanonicalType);
}
inline bool Type::isVectorType() const {
- return isa<VectorType>(CanonicalType.getUnqualifiedType());
+ return isa<VectorType>(CanonicalType);
}
inline bool Type::isExtVectorType() const {
- return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
+ return isa<ExtVectorType>(CanonicalType);
}
inline bool Type::isObjCObjectPointerType() const {
- return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<ObjCObjectPointerType>(CanonicalType);
}
inline bool Type::isObjCInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
+ return isa<ObjCInterfaceType>(CanonicalType);
}
inline bool Type::isObjCQualifiedIdType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
@@ -2875,7 +2885,7 @@ inline bool Type::isObjCBuiltinType() const {
return isObjCIdType() || isObjCClassType();
}
inline bool Type::isTemplateTypeParmType() const {
- return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
+ return isa<TemplateTypeParmType>(CanonicalType);
}
inline bool Type::isSpecificBuiltinType(unsigned K) const {
@@ -2911,8 +2921,21 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
+// Helper class template that is used by Type::getAs to ensure that one does
+// not try to look through a qualified type to get to an array type.
+template<typename T,
+ bool isArrayType = (llvm::is_same<T, ArrayType>::value ||
+ llvm::is_base_of<ArrayType, T>::value)>
+struct ArrayType_cannot_be_used_with_getAs { };
+
+template<typename T>
+struct ArrayType_cannot_be_used_with_getAs<T, true>;
+
/// Member-template getAs<specific type>'.
template <typename T> const T *Type::getAs() const {
+ ArrayType_cannot_be_used_with_getAs<T> at;
+ (void)at;
+
// If this is directly a T type, return it.
if (const T *Ty = dyn_cast<T>(this))
return Ty;
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index da7857822e9c..f08ca6bf469b 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -58,7 +58,7 @@ public:
: Ty(ty), Data(opaqueData) { }
TypeLocClass getTypeLocClass() const {
- if (getType().hasQualifiers()) return Qualified;
+ if (getType().hasLocalQualifiers()) return Qualified;
return (TypeLocClass) getType()->getTypeClass();
}
@@ -155,7 +155,7 @@ public:
}
static bool classof(const TypeLoc *TL) {
- return !TL->getType().hasQualifiers();
+ return !TL->getType().hasLocalQualifiers();
}
static bool classof(const UnqualTypeLoc *TL) { return true; }
};
@@ -196,11 +196,11 @@ public:
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getLocalDataSize() +
- getFullDataSizeForType(getType().getUnqualifiedType());
+ getFullDataSizeForType(getType().getLocalUnqualifiedType());
}
static bool classof(const TypeLoc *TL) {
- return TL->getType().hasQualifiers();
+ return TL->getType().hasLocalQualifiers();
}
static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
@@ -919,6 +919,10 @@ public:
Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
break;
+ case TemplateArgument::Template:
+ Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+ break;
+
case TemplateArgument::Integral:
case TemplateArgument::Pack:
case TemplateArgument::Null:
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
index 4e1fbaaf4c5e..00e2b7f83219 100644
--- a/include/clang/AST/TypeLocBuilder.h
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -17,6 +17,7 @@
#include "clang/AST/TypeLoc.h"
#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/ASTContext.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 17f772da0c6d..867494396020 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -88,11 +88,11 @@ public:
/// dumpLiveness - Print to stderr the liveness information encoded
/// by a specified bitvector.
- void dumpLiveness(const ValTy& V, SourceManager& M) const;
+ void dumpLiveness(const ValTy& V, const SourceManager& M) const;
/// dumpBlockLiveness - Print to stderr the liveness information
/// associated with each basic block.
- void dumpBlockLiveness(SourceManager& M) const;
+ void dumpBlockLiveness(const SourceManager& M) const;
/// getNumDecls - Return the number of variables (declarations) that
/// whose liveness status is being tracked by the dataflow
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index f505bca9519c..cbf7010bfdb5 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -16,6 +16,7 @@
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "functional" // STL
diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h
index 1da15fbae6c4..8c70e4fc7b6c 100644
--- a/include/clang/Analysis/LocalCheckers.h
+++ b/include/clang/Analysis/LocalCheckers.h
@@ -50,10 +50,12 @@ void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
void CheckObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter& BR);
void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
+void RegisterExperimentalChecks(GRExprEngine &Eng);
+void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
-
+void CheckSizeofPointer(const Decl *D, BugReporter &BR);
} // end namespace clang
#endif
diff --git a/include/clang/Analysis/ManagerRegistry.h b/include/clang/Analysis/ManagerRegistry.h
new file mode 100644
index 000000000000..972993855c28
--- /dev/null
+++ b/include/clang/Analysis/ManagerRegistry.h
@@ -0,0 +1,53 @@
+//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ManagerRegistry and Register* classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+
+#include "clang/Analysis/PathSensitive/GRState.h"
+
+namespace clang {
+
+/// ManagerRegistry - This class records manager creators registered at
+/// runtime. The information is communicated to AnalysisManager through static
+/// members. Better design is expected.
+
+class ManagerRegistry {
+public:
+ static StoreManagerCreator StoreMgrCreator;
+ static ConstraintManagerCreator ConstraintMgrCreator;
+};
+
+/// RegisterConstraintManager - This class is used to setup the constraint
+/// manager of the static analyzer. The constructor takes a creator function
+/// pointer for creating the constraint manager.
+///
+/// It is used like this:
+///
+/// class MyConstraintManager {};
+/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
+/// return new MyConstraintManager(statemgr);
+/// }
+/// RegisterConstraintManager X(CreateMyConstraintManager);
+
+class RegisterConstraintManager {
+public:
+ RegisterConstraintManager(ConstraintManagerCreator CMC) {
+ assert(ManagerRegistry::ConstraintMgrCreator == 0
+ && "ConstraintMgrCreator already set!");
+ ManagerRegistry::ConstraintMgrCreator = CMC;
+ }
+};
+
+}
+#endif
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index 66e850a91444..9b58f745f0a5 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#include "clang/AST/Stmt.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h
index 488334623b34..18eae9ac9f14 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h
@@ -37,7 +37,6 @@ class AnalysisManager : public BugReporterData {
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
- bool DisplayedFunction;
bool VisualizeEGDot;
bool VisualizeEGUbi;
bool PurgeDead;
@@ -62,7 +61,7 @@ public:
: Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
- AScope(ScopeDecl), DisplayedFunction(!displayProgress),
+ AScope(ScopeDecl),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim) {}
@@ -120,8 +119,6 @@ public:
bool shouldEagerlyAssume() const { return EagerlyAssume; }
- void DisplayFunction(Decl *D);
-
CFG *getCFG(Decl const *D) {
return AnaCtxMgr.getContext(D)->getCFG();
}
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index 914118cb430d..f4297350ec70 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -81,10 +81,10 @@ public:
getOriginalNode(const ExplodedNode* N) = 0;
};
- BugReport(BugType& bt, const char* desc, const ExplodedNode *n)
+ BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *n)
: BT(bt), Description(desc), EndNode(n) {}
- BugReport(BugType& bt, const char* shortDesc, const char* desc,
+ BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc,
const ExplodedNode *n)
: BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
@@ -193,11 +193,11 @@ public:
class RangedBugReport : public BugReport {
std::vector<SourceRange> Ranges;
public:
- RangedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ RangedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
: BugReport(D, description, n) {}
- RangedBugReport(BugType& D, const char *shortDescription,
- const char *description, ExplodedNode *n)
+ RangedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
: BugReport(D, shortDescription, description, n) {}
~RangedBugReport();
@@ -229,11 +229,11 @@ private:
Creators creators;
public:
- EnhancedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ EnhancedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
: RangedBugReport(D, description, n) {}
- EnhancedBugReport(BugType& D, const char *shortDescription,
- const char *description, ExplodedNode *n)
+ EnhancedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
: RangedBugReport(D, shortDescription, description, n) {}
~EnhancedBugReport() {}
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h
index 242b8e9afebe..8303dee49afa 100644
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ b/include/clang/Analysis/PathSensitive/BugType.h
@@ -23,6 +23,7 @@ class BugReportEquivClass;
class BugReporter;
class BuiltinBugReport;
class BugReporterContext;
+class ExplodedNode;
class GRExprEngine;
class BugType {
@@ -59,21 +60,27 @@ public:
};
class BuiltinBug : public BugType {
- GRExprEngine &Eng;
+ GRExprEngine *Eng;
protected:
const std::string desc;
public:
+ BuiltinBug(const char *name, const char *description)
+ : BugType(name, "Logic error"), Eng(0), desc(description) {}
+
+ BuiltinBug(const char *name)
+ : BugType(name, "Logic error"), Eng(0), desc(name) {}
+
BuiltinBug(GRExprEngine *eng, const char* n, const char* d)
- : BugType(n, "Logic error"), Eng(*eng), desc(d) {}
+ : BugType(n, "Logic error"), Eng(eng), desc(d) {}
BuiltinBug(GRExprEngine *eng, const char* n)
- : BugType(n, "Logic error"), Eng(*eng), desc(n) {}
+ : BugType(n, "Logic error"), Eng(eng), desc(n) {}
const std::string &getDescription() const { return desc; }
virtual void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {}
- void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, Eng); }
+ void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, *Eng); }
virtual void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode* N,
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 4fc0a617ecf0..b7ed20fab250 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -39,22 +39,19 @@ class CheckerContext {
SaveAndRestore<const void*> OldTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
+ const GRState *state;
public:
- CheckerContext(ExplodedNodeSet &dst,
- GRStmtNodeBuilder &builder,
- GRExprEngine &eng,
- ExplodedNode *pred,
- const void *tag, bool preVisit)
+ CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
+ GRExprEngine &eng, ExplodedNode *pred,
+ const void *tag, ProgramPoint::Kind K,
+ const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
- OldSink(B.BuildSinks), OldTag(B.Tag),
- OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) {
- //assert(Dst.empty()); // This is a fake assertion.
- // See GRExprEngine::CheckerVisit(), CurrSet is repeatedly used.
- B.Tag = tag;
- if (preVisit)
- B.PointKind = ProgramPoint::PreStmtKind;
- }
+ OldSink(B.BuildSinks),
+ OldTag(B.Tag, tag),
+ OldPointKind(B.PointKind, K),
+ OldHasGen(B.HasGeneratedNode),
+ state(st) {}
~CheckerContext() {
if (!B.BuildSinks && !B.HasGeneratedNode)
@@ -64,10 +61,15 @@ public:
ConstraintManager &getConstraintManager() {
return Eng.getConstraintManager();
}
+
+ StoreManager &getStoreManager() {
+ return Eng.getStoreManager();
+ }
+
ExplodedNodeSet &getNodeSet() { return Dst; }
GRStmtNodeBuilder &getNodeBuilder() { return B; }
ExplodedNode *&getPredecessor() { return Pred; }
- const GRState *getState() { return B.GetState(Pred); }
+ const GRState *getState() { return state ? state : B.GetState(Pred); }
ASTContext &getASTContext() {
return Eng.getContext();
@@ -76,6 +78,10 @@ public:
BugReporter &getBugReporter() {
return Eng.getBugReporter();
}
+
+ SourceManager &getSourceManager() {
+ return getBugReporter().getSourceManager();
+ }
ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) {
return GenerateNode(S, getState(), markAsSink);
@@ -104,50 +110,69 @@ class Checker {
private:
friend class GRExprEngine;
+ // FIXME: Remove the 'tag' option.
void GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
- const Stmt *stmt,
+ const Stmt *S,
ExplodedNode *Pred, void *tag, bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
- assert(isPrevisit && "Only previsit supported for now.");
- _PreVisit(C, stmt);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
+ if (isPrevisit)
+ _PreVisit(C, S);
+ else
+ _PostVisit(C, S);
}
+ // FIXME: Remove the 'tag' option.
void GR_VisitBind(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
const Stmt *AssignE,
const Stmt *StoreE, ExplodedNode *Pred, void *tag,
SVal location, SVal val,
bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
assert(isPrevisit && "Only previsit supported for now.");
PreVisitBind(C, AssignE, StoreE, location, val);
}
-
-public:
- virtual ~Checker() {}
- virtual void _PreVisit(CheckerContext &C, const Stmt *ST) {}
- // This is a previsit which takes a node returns a node.
- virtual ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V,
- GRExprEngine &Eng) {
- return Pred;
+ // FIXME: Remove the 'tag' option.
+ void GR_VisitLocation(ExplodedNodeSet &Dst,
+ GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ const Stmt *S,
+ ExplodedNode *Pred, const GRState *state,
+ SVal location,
+ void *tag, bool isLoad) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isLoad ? ProgramPoint::PreLoadKind :
+ ProgramPoint::PreStoreKind, state);
+ VisitLocation(C, S, location);
}
-
- virtual void PreVisitBind(CheckerContext &C,
- const Stmt *AssignE, const Stmt *StoreE,
- SVal location, SVal val) {}
-
- virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
- const GRState *state, Stmt *S,
- GRExprEngine &Eng) {
- return Pred;
+
+ void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
+ SymbolReaper &SymReaper, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ ProgramPoint::PostPurgeDeadSymbolsKind, Pred->getState());
+ EvalDeadSymbols(C, S, SymReaper);
}
+public:
+ virtual ~Checker() {}
+ virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
+ virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
+ virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
+ virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+ const Stmt *StoreE, SVal location, SVal val) {}
+ virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+ SymbolReaper &SymReaper) {}
+ virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+ GRExprEngine &Eng) {}
};
-
} // end clang namespace
#endif
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
index ff6528dae8f5..090a5d397549 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.def
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
@@ -11,8 +11,19 @@
//
//===---------------------------------------------------------------------===//
+#ifdef PREVISIT
+PREVISIT(ArraySubscriptExpr)
+PREVISIT(BinaryOperator)
PREVISIT(CallExpr)
+PREVISIT(CastExpr)
+PREVISIT(DeclStmt)
PREVISIT(ObjCMessageExpr)
-PREVISIT(BinaryOperator)
-
+PREVISIT(ReturnStmt)
#undef PREVISIT
+#endif
+
+#ifdef POSTVISIT
+POSTVISIT(CallExpr)
+#undef POSTVISIT
+#endif
+
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
index e74f49c9a761..7cef17eb6591 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.h
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
@@ -27,8 +27,12 @@ namespace clang {
template<typename ImplClass>
class CheckerVisitor : public Checker {
public:
- virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) {
- PreVisit(C, stmt);
+ virtual void _PreVisit(CheckerContext &C, const Stmt *S) {
+ PreVisit(C, S);
+ }
+
+ virtual void _PostVisit(CheckerContext &C, const Stmt *S) {
+ PostVisit(C, S);
}
void PreVisit(CheckerContext &C, const Stmt *S) {
@@ -36,10 +40,19 @@ public:
default:
assert(false && "Unsupport statement.");
return;
+
+ case Stmt::ImplicitCastExprClass:
+ case Stmt::ExplicitCastExprClass:
+ case Stmt::CStyleCastExprClass:
+ static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
+ static_cast<const CastExpr*>(S));
+ break;
+
case Stmt::CompoundAssignOperatorClass:
static_cast<ImplClass*>(this)->PreVisitBinaryOperator(C,
static_cast<const BinaryOperator*>(S));
break;
+
#define PREVISIT(NAME) \
case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
@@ -47,13 +60,30 @@ break;
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
}
}
+
+ void PostVisit(CheckerContext &C, const Stmt *S) {
+ switch (S->getStmtClass()) {
+ default:
+ assert(false && "Unsupport statement.");
+ return;
+#define POSTVISIT(NAME) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->\
+PostVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+ }
+ }
#define PREVISIT(NAME) \
void PreVisit ## NAME(CheckerContext &C, const NAME* S) {}
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+
+#define POSTVISIT(NAME) \
+void PostVisit ## NAME(CheckerContext &C, const NAME* S) {}
+#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
};
} // end clang namespace
#endif
-
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
index 688cf641491d..a84183e7f27f 100644
--- a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
+++ b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
@@ -16,38 +16,16 @@
#ifndef LLVM_CLANG_DEREFCHECKER
#define LLVM_CLANG_DEREFCHECKER
-#include "clang/Analysis/PathSensitive/Checker.h"
-#include "clang/Analysis/PathSensitive/BugType.h"
+#include <utility>
namespace clang {
+class GRExprEngine;
class ExplodedNode;
-class NullDerefChecker : public Checker {
- BuiltinBug *BT;
- llvm::SmallVector<ExplodedNode*, 2> ImplicitNullDerefNodes;
-
-public:
- NullDerefChecker() : BT(0) {}
- ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V,GRExprEngine &Eng);
-
- static void *getTag();
- typedef llvm::SmallVectorImpl<ExplodedNode*>::iterator iterator;
- iterator implicit_nodes_begin() { return ImplicitNullDerefNodes.begin(); }
- iterator implicit_nodes_end() { return ImplicitNullDerefNodes.end(); }
-};
-
-class UndefDerefChecker : public Checker {
- BuiltinBug *BT;
-public:
- UndefDerefChecker() : BT(0) {}
-
- ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V, GRExprEngine &Eng);
-
- static void *getTag();
-};
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+GetImplicitNullDereferences(GRExprEngine &Eng);
} // end clang namespace
+
#endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 25e47038d72c..1b6d0bdf9c10 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -111,14 +111,6 @@ public:
// was larger than sizeof(void *) (an undefined value).
ErrorNodes NilReceiverLargerThanVoidPtrRetImplicit;
- /// RetsStackAddr - Nodes in the ExplodedGraph that result from returning
- /// the address of a stack variable.
- ErrorNodes RetsStackAddr;
-
- /// RetsUndef - Nodes in the ExplodedGraph that result from returning
- /// an undefined value.
- ErrorNodes RetsUndef;
-
/// UndefBranches - Nodes in the ExplodedGraph that result from
/// taking a branch based on an undefined value.
ErrorNodes UndefBranches;
@@ -131,22 +123,10 @@ public:
// calling a function with the attribute "noreturn".
ErrorNodes NoReturnCalls;
- /// ImplicitBadSizedVLA - Nodes in the ExplodedGraph that result from
- /// constructing a zero-sized VLA where the size may be zero.
- ErrorNodes ImplicitBadSizedVLA;
-
- /// ExplicitBadSizedVLA - Nodes in the ExplodedGraph that result from
- /// constructing a zero-sized VLA where the size must be zero.
- ErrorNodes ExplicitBadSizedVLA;
-
/// UndefResults - Nodes in the ExplodedGraph where the operands are defined
/// by the result is not. Excludes divide-by-zero errors.
ErrorNodes UndefResults;
- /// BadCalls - Nodes in the ExplodedGraph resulting from calls to function
- /// pointers that are NULL (or other constants) or Undefined.
- ErrorNodes BadCalls;
-
/// UndefReceiver - Nodes in the ExplodedGraph resulting from message
/// ObjC message expressions where the receiver is undefined (uninitialized).
ErrorNodes UndefReceivers;
@@ -156,14 +136,6 @@ public:
/// value.
UndefArgsTy MsgExprUndefArgs;
- /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
- /// out-of-bound memory accesses where the index MAY be out-of-bound.
- ErrorNodes ImplicitOOBMemAccesses;
-
- /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
- /// out-of-bound memory accesses where the index MUST be out-of-bound.
- ErrorNodes ExplicitOOBMemAccesses;
-
public:
GRExprEngine(AnalysisManager &mgr);
@@ -223,58 +195,10 @@ public:
return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
}
- bool isRetStackAddr(const ExplodedNode* N) const {
- return N->isSink() && RetsStackAddr.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isUndefControlFlow(const ExplodedNode* N) const {
- return N->isSink() && UndefBranches.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isUndefStore(const ExplodedNode* N) const {
- return N->isSink() && UndefStores.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isImplicitNullDeref(const ExplodedNode* N) const {
- return false;
- }
-
- bool isExplicitNullDeref(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefDeref(const ExplodedNode* N) const {
- return false;
- }
-
bool isNoReturnCall(const ExplodedNode* N) const {
return N->isSink() && NoReturnCalls.count(const_cast<ExplodedNode*>(N)) != 0;
}
- bool isUndefResult(const ExplodedNode* N) const {
- return N->isSink() && UndefResults.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isBadCall(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefArg(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefReceiver(const ExplodedNode* N) const {
- return N->isSink() && UndefReceivers.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- typedef ErrorNodes::iterator ret_stackaddr_iterator;
- ret_stackaddr_iterator ret_stackaddr_begin() { return RetsStackAddr.begin(); }
- ret_stackaddr_iterator ret_stackaddr_end() { return RetsStackAddr.end(); }
-
- typedef ErrorNodes::iterator ret_undef_iterator;
- ret_undef_iterator ret_undef_begin() { return RetsUndef.begin(); }
- ret_undef_iterator ret_undef_end() { return RetsUndef.end(); }
-
typedef ErrorNodes::iterator undef_branch_iterator;
undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }
@@ -305,10 +229,6 @@ public:
undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
undef_result_iterator undef_results_end() { return UndefResults.end(); }
- typedef ErrorNodes::iterator bad_calls_iterator;
- bad_calls_iterator bad_calls_begin() { return BadCalls.begin(); }
- bad_calls_iterator bad_calls_end() { return BadCalls.end(); }
-
typedef UndefArgsTy::iterator undef_arg_iterator;
undef_arg_iterator msg_expr_undef_arg_begin() {
return MsgExprUndefArgs.begin();
@@ -327,20 +247,6 @@ public:
return UndefReceivers.end();
}
- typedef ErrorNodes::iterator oob_memacc_iterator;
- oob_memacc_iterator implicit_oob_memacc_begin() {
- return ImplicitOOBMemAccesses.begin();
- }
- oob_memacc_iterator implicit_oob_memacc_end() {
- return ImplicitOOBMemAccesses.end();
- }
- oob_memacc_iterator explicit_oob_memacc_begin() {
- return ExplicitOOBMemAccesses.begin();
- }
- oob_memacc_iterator explicit_oob_memacc_end() {
- return ExplicitOOBMemAccesses.end();
- }
-
void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
void AddCheck(GRSimpleAPICheck* A);
@@ -368,10 +274,7 @@ public:
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function.
- void ProcessEndPath(GREndPathNodeBuilder& builder) {
- getTF().EvalEndPath(*this, builder);
- StateMgr.EndPath(builder.getState());
- }
+ void ProcessEndPath(GREndPathNodeBuilder& builder);
GRStateManager& getStateManager() { return StateMgr; }
const GRStateManager& getStateManager() const { return StateMgr; }
@@ -516,9 +419,6 @@ protected:
void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst,
bool asLValue);
- const GRState* CheckDivideZero(Expr* Ex, const GRState* St, ExplodedNode* Pred,
- SVal Denom);
-
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions.
@@ -553,15 +453,11 @@ public:
}
protected:
- void EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L, ExplodedNode* Pred);
-
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, ExplodedNode* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
}
- void EvalReturn(ExplodedNodeSet& Dst, ReturnStmt* s, ExplodedNode* Pred);
-
const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
bool branchTaken);
@@ -573,16 +469,22 @@ protected:
bool atDeclInit = false);
public:
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
- const GRState* St, SVal location, const void *tag = 0);
+ const GRState* St, SVal location, const void *tag = 0,
+ QualType LoadTy = QualType());
- ExplodedNode* EvalLocation(Stmt* Ex, ExplodedNode* Pred,
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
const GRState* St, SVal location,
- const void *tag = 0);
+ const void *tag, bool isLoad);
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
- ExplodedNode* Pred,
- const GRState* St, SVal TargetLV, SVal Val,
+ ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
const void *tag = 0);
};
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index 8678ca9b5b9b..ef0c36c44d9f 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -195,6 +195,9 @@ public:
//
const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const;
+
+ std::pair<const GRState*, const GRState*>
+ Assume(DefinedOrUnknownSVal cond) const;
const GRState *AssumeInBound(DefinedOrUnknownSVal idx,
DefinedOrUnknownSVal upperBound,
@@ -330,12 +333,6 @@ public:
void printStdErr() const;
void printDOT(llvm::raw_ostream& Out) const;
-
- // Tags used for the Generic Data Map.
- struct NullDerefTag {
- static int TagInt;
- typedef const SVal* data_type;
- };
};
class GRStateSet {
@@ -403,10 +400,6 @@ private:
/// Alloc - A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator& Alloc;
- /// CurrentStmt - The block-level statement currently being visited. This
- /// is set by GRExprEngine.
- Stmt* CurrentStmt;
-
/// TF - Object that represents a bundle of transfer functions
/// for manipulating and creating SVals.
GRTransferFuncs* TF;
@@ -583,6 +576,15 @@ inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond),
Assumption);
}
+
+inline std::pair<const GRState*, const GRState*>
+GRState::Assume(DefinedOrUnknownSVal Cond) const {
+ if (Cond.isUnknown())
+ return std::make_pair(this, this);
+
+ return getStateManager().ConstraintMgr->AssumeDual(this,
+ cast<DefinedSVal>(Cond));
+}
inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
DefinedOrUnknownSVal UpperBound,
diff --git a/include/clang/Analysis/PathSensitive/GRWorkList.h b/include/clang/Analysis/PathSensitive/GRWorkList.h
index 17b83fdf9fdc..857fa316911f 100644
--- a/include/clang/Analysis/PathSensitive/GRWorkList.h
+++ b/include/clang/Analysis/PathSensitive/GRWorkList.h
@@ -16,16 +16,19 @@
#define LLVM_CLANG_ANALYSIS_GRWORKLIST
#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+#include <cstddef>
namespace clang {
-
+
+class CFGBlock;
+class ExplodedNode;
class ExplodedNodeImpl;
class GRWorkListUnit {
ExplodedNode* Node;
GRBlockCounter Counter;
CFGBlock* Block;
- unsigned BlockIdx;
+ unsigned BlockIdx; // This is the index of the next statement.
public:
GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 0e487691a891..06d0d976df01 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -77,6 +77,8 @@ public:
const MemRegion *getBaseRegion() const;
+ const MemRegion *StripCasts() const;
+
bool hasStackStorage() const;
bool hasParametersStorage() const;
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h
index 4ba3c7396822..8b5cf40e29cb 100644
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ b/include/clang/Analysis/PathSensitive/SVals.h
@@ -96,6 +96,8 @@ public:
return getRawKind() > UnknownKind;
}
+ bool isConstant() const;
+
bool isZeroConstant() const;
/// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
@@ -434,7 +436,7 @@ public:
return static_cast<MemRegion*>(Data);
}
- const MemRegion* getBaseRegion() const;
+ const MemRegion* StripCasts() const;
template <typename REGION>
const REGION* getRegionAs() const {
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 6ca2e9e9aa68..55fa83d9ecc3 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -102,7 +102,8 @@ public:
virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
// FIXME: Make out-of-line.
- virtual SVal getSizeInElements(const GRState *state, const MemRegion *region){
+ virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
+ const MemRegion *region) {
return UnknownVal();
}
@@ -180,8 +181,7 @@ protected:
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted
/// as another region.
- SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
- const TypedRegion *R, QualType castTy);
+ SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
};
// FIXME: Do we still need this?
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 7aaae9c86653..78827dfabe2f 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -33,13 +33,10 @@ public:
BlockEntranceKind,
BlockExitKind,
PreStmtKind,
- // Keep the following together and in this order.
PostStmtKind,
- PostLocationChecksSucceedKind,
- PostOutOfBoundsCheckFailedKind,
- PostNullCheckFailedKind,
- PostUndefLocationCheckFailedKind,
+ PreLoadKind,
PostLoadKind,
+ PreStoreKind,
PostStoreKind,
PostPurgeDeadSymbolsKind,
PostStmtCustomKind,
@@ -194,17 +191,6 @@ public:
}
};
-class PostLocationChecksSucceed : public PostStmt {
-public:
- PostLocationChecksSucceed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostLocationChecksSucceedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLocationChecksSucceedKind;
- }
-};
-
class PostStmtCustom : public PostStmt {
public:
PostStmtCustom(const Stmt* S,
@@ -226,36 +212,36 @@ public:
}
};
-class PostOutOfBoundsCheckFailed : public PostStmt {
-public:
- PostOutOfBoundsCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostOutOfBoundsCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostOutOfBoundsCheckFailedKind;
+
+class LocationCheck : public StmtPoint {
+protected:
+ LocationCheck(const Stmt *S, const LocationContext *L,
+ ProgramPoint::Kind K, const void *tag)
+ : StmtPoint(S, NULL, K, L, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ unsigned k = location->getKind();
+ return k == PreLoadKind || k == PreStoreKind;
}
};
-
-class PostUndefLocationCheckFailed : public PostStmt {
+
+class PreLoad : public LocationCheck {
public:
- PostUndefLocationCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostUndefLocationCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostUndefLocationCheckFailedKind;
+ PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreLoadKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreLoadKind;
}
};
-class PostNullCheckFailed : public PostStmt {
+class PreStore : public LocationCheck {
public:
- PostNullCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostNullCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostNullCheckFailedKind;
+ PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreStoreKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreStoreKind;
}
};
diff --git a/include/clang/Analysis/Support/Optional.h b/include/clang/Analysis/Support/Optional.h
index 3940007bb574..40f38be020a9 100644
--- a/include/clang/Analysis/Support/Optional.h
+++ b/include/clang/Analysis/Support/Optional.h
@@ -39,6 +39,9 @@ public:
} //end clang namespace
namespace llvm {
+
+template<typename T> struct simplify_type;
+
template <typename T>
struct simplify_type<const ::clang::Optional<T> > {
typedef const T* SimpleType;
diff --git a/include/clang/Analysis/Support/SaveAndRestore.h b/include/clang/Analysis/Support/SaveAndRestore.h
index 4720c22d990e..f720639490d9 100644
--- a/include/clang/Analysis/Support/SaveAndRestore.h
+++ b/include/clang/Analysis/Support/SaveAndRestore.h
@@ -22,6 +22,9 @@ namespace clang {
template<typename T>
struct SaveAndRestore {
SaveAndRestore(T& x) : X(x), old_value(x) {}
+ SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
+ X = new_value;
+ }
~SaveAndRestore() { X = old_value; }
T get() { return old_value; }
private:
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 77a2079b766d..3a70e134b82b 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -32,6 +32,7 @@ namespace clang {
class IdentifierInfo;
class LangOptions;
class PartialDiagnostic;
+ class Preprocessor;
class SourceRange;
// Import the diagnostic enums themselves.
@@ -105,6 +106,10 @@ public:
/// modification is known.
CodeModificationHint() : RemoveRange(), InsertionLoc() { }
+ bool isNull() const {
+ return !RemoveRange.isValid() && !InsertionLoc.isValid();
+ }
+
/// \brief Create a code modification hint that inserts the given
/// code string at a specific location.
static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
@@ -382,6 +387,7 @@ public:
/// @c Pos represents the source location associated with the diagnostic,
/// which can be an invalid location if no position information is available.
inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
+ inline DiagnosticBuilder Report(unsigned DiagID);
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
@@ -586,6 +592,9 @@ public:
}
void AddCodeModificationHint(const CodeModificationHint &Hint) const {
+ if (Hint.isNull())
+ return;
+
assert(NumCodeModificationHints < Diagnostic::MaxCodeModificationHints &&
"Too many code modification hints!");
if (DiagObj)
@@ -664,6 +673,9 @@ inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
CurDiagID = DiagID;
return DiagnosticBuilder(this);
}
+inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) {
+ return Report(FullSourceLoc(), DiagID);
+}
//===----------------------------------------------------------------------===//
// DiagnosticInfo
@@ -780,7 +792,8 @@ public:
/// \arg LO - The language options for the source file being processed.
/// \arg PP - The preprocessor object being used for the source; this optional
/// and may not be present, for example when processing AST source files.
- virtual void BeginSourceFile(const LangOptions &LangOpts) {}
+ virtual void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP = 0) {}
/// EndSourceFile - Callback to inform the diagnostic client that processing
/// of a source file has ended. The diagnostic client should assume that any
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index bb251ad73bd8..9a342b592ca5 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -52,4 +52,11 @@ def warn_integer_too_large_for_signed : Warning<
def note_invalid_subexpr_in_ice : Note<
"subexpression not valid in an integer constant expression">;
+// Targets
+
+def err_target_unknown_triple : Error<
+ "unknown target triple '%0', please use -triple or -arch">;
+def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
+def err_target_invalid_feature : Error<"invalid target feature '%0'">;
+
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index ae8b92394443..e9b351ffe995 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -9,19 +9,33 @@
let Component = "Frontend" in {
-def err_fe_unknown_triple : Error<
- "unknown target triple '%0', please use -triple or -arch">;
-def err_fe_unknown_target_abi : Error<"unknown target ABI '%0'">;
def err_fe_error_opening : Error<"error opening '%0': %1">;
def err_fe_error_reading : Error<"error reading '%0'">;
def err_fe_error_reading_stdin : Error<"error reading stdin">;
def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal;
-def err_fe_invalid_code_complete_file
+def err_fe_invalid_code_complete_file
: Error<"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
"-dependency-file requires at least one -MT option">;
+def err_fe_incompatible_options : Error<
+ "'%0' cannot be used with '%1'">, DefaultFatal;
+def err_fe_no_fixit_and_codegen : Error<
+ "FIX-ITs cannot be applied when generating code">;
+def err_fe_unable_to_find_fixit_file : Error<
+ "FIX-IT could not find file '%0'">;
+def err_fe_invalid_plugin_name : Error<
+ "unable to find plugin '%0'">;
+
+def err_verify_bogus_characters : Error<
+ "bogus characters before '{{' in expected string">;
+def err_verify_missing_start : Error<
+ "cannot find start ('{{') of expected string">;
+def err_verify_missing_end : Error<
+ "cannot find end ('}}') of expected string">;
+def err_verify_inconsistent_diags : Error<
+ "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2">;
def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
def note_fixit_in_macro : Note<
@@ -162,6 +176,9 @@ def warn_pch_access_control : Error<
def warn_pch_char_signed : Error<
"char was %select{unsigned|signed}0 in the PCH file but "
"is currently %select{unsigned|signed}1">;
+def warn_pch_short_wchar : Error<
+ "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but "
+ "is currently %select{disabled|enabled}1">;
def err_not_a_pch_file : Error<
"'%0' does not appear to be a precompiled header file">, DefaultFatal;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 8cfdd4095027..93c655b50500 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -28,7 +28,7 @@ def : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
-def : DiagGroup<"conversion">;
+def : DiagGroup<"ctor-dtor-privacy">;
def : DiagGroup<"declaration-after-statement">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
@@ -40,6 +40,7 @@ def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
+def : DiagGroup<"idiomatic-parentheses">;
def : DiagGroup<"import">;
def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
@@ -58,19 +59,21 @@ def MismatchedTags : DiagGroup<"mismatched-tags">;
def : DiagGroup<"missing-field-initializers">;
def NonNull : DiagGroup<"nonnull">;
def : DiagGroup<"nonportable-cfstrings">;
+def : DiagGroup<"non-virtual-dtor">;
def : DiagGroup<"old-style-definition">;
def : DiagGroup<"overflow">;
def : DiagGroup<"overloaded-virtual">;
def : DiagGroup<"packed">;
-def Parentheses : DiagGroup<"parentheses">;
def PointerArith : DiagGroup<"pointer-arith">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def ReturnType : DiagGroup<"return-type">;
+def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def : DiagGroup<"sequence-point">;
def : DiagGroup<"shadow">;
def : DiagGroup<"shorten-64-to-32">;
-def : DiagGroup<"sign-compare">;
+def SignCompare : DiagGroup<"sign-compare">;
+def : DiagGroup<"synth">;
// Preprocessor warnings.
def : DiagGroup<"builtin-macro-redefined">;
@@ -114,6 +117,14 @@ def CharSubscript : DiagGroup<"char-subscripts">;
// Aggregation warning settings.
+// -Widiomatic-parentheses contains warnings about 'idiomatic'
+// missing parentheses; it is off by default.
+def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>;
+
+// -Wconversion has its own warnings, but we split this one out for
+// legacy reasons.
+def Conversion : DiagGroup<"conversion",
+ [DiagGroup<"shorten-64-to-32">]>;
def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
@@ -127,8 +138,9 @@ def FormatY2K : DiagGroup<"format-y2k", [Format]>;
def Format2 : DiagGroup<"format=2",
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
-
def Extra : DiagGroup<"extra", [
+ SemiBeforeMethodBody,
+ SignCompare,
UnusedParameter
]>;
@@ -158,3 +170,7 @@ def : DiagGroup<"all", [Most, Parentheses]>;
def : DiagGroup<"", [Extra]>; // -W = -Wextra
def : DiagGroup<"endif-labels", [ExtraTokens]>; // endif-labels = endif-tokens
+// A warning group for warnings that we want to have on by default in clang,
+// but which aren't on by default in GCC.
+def NonGCC : DiagGroup<"non-gcc",
+ [SignCompare, Conversion]>;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index bbc551373d96..7f3f4ea1fca0 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -90,6 +90,14 @@ def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">;
def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">;
//===----------------------------------------------------------------------===//
+// PTH Diagnostics
+//===----------------------------------------------------------------------===//
+def err_pth_cannot_read : Error<
+ "PTH file '%0' could not be read">;
+def err_invalid_pth_file : Error<
+ "invalid or corrupt PTH file '%0'">;
+
+//===----------------------------------------------------------------------===//
// Preprocessor Diagnostics
//===----------------------------------------------------------------------===//
def pp_hash_warning : Warning<"#warning%0">, InGroup<DiagGroup<"#warnings">>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index e173cffdfd2b..28c46cd2d707 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -201,9 +201,9 @@ def warn_expected_implementation : Warning<
"@end must appear in an @implementation context">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
-def warn_semicolon_before_method_nody : Warning<
+def warn_semicolon_before_method_body : Warning<
"semicolon before method body is ignored">,
- InGroup<DiagGroup<"semicolon-before-method-body">>;
+ InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
def err_expected_field_designator : Error<
"expected a field designator, such as '.field = 4'">;
@@ -230,7 +230,7 @@ def ext_ellipsis_exception_spec : Extension<
def err_expected_catch : Error<"expected catch">;
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
def err_using_namespace_in_class : Error<
- "'using namespace' in class not allowed">;
+ "'using namespace' is not allowed in classes">;
def err_ident_in_pseudo_dtor_not_a_type : Error<
"identifier %0 in pseudo-destructor expression does not name a type">;
@@ -289,6 +289,10 @@ def err_explicit_spec_non_template : Error<
def err_variadic_templates : Error<
"variadic templates are only allowed in C++0x">;
+def err_default_template_template_parameter_not_template : Error<
+ "default template argument for a template template parameter must be a class "
+ "template">;
+
// C++ declarations
def err_friend_decl_defines_class : Error<
"cannot define a type in a friend declaration">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2309908df7b4..78a3ae5d47b7 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -103,6 +103,8 @@ def err_using_requires_qualname : Error<
"using declaration requires a qualified name">;
def err_using_typename_non_type : Error<
"'typename' keyword used on a non-type">;
+def err_using_dependent_value_is_type : Error<
+ "dependent using declaration resolved to type without 'typename'">;
def err_using_decl_nested_name_specifier_is_not_a_base_class : Error<
"using declaration refers into '%0', which is not a base class of %1">;
def err_using_decl_can_not_refer_to_class_member : Error<
@@ -115,6 +117,8 @@ def err_using_decl_destructor : Error<
"using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error<
"using declaration can not refer to a template specialization">;
+def note_using_decl_target : Note<
+ "target of using declaration">;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
@@ -251,6 +255,7 @@ def warn_accessor_property_type_mismatch : Warning<
def note_declared_at : Note<"declared at">;
def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
+def warn_missing_atend : Warning<"'@end' is missing in implementation context">;
def err_objc_var_decl_inclass :
Error<"cannot declare variable inside @interface or @protocol">;
def error_missing_method_context : Error<
@@ -269,6 +274,9 @@ def warn_property_attr_mismatch : Warning<
def warn_objc_property_copy_missing_on_block : Warning<
"'copy' attribute must be specified for the block property "
"when -fobjc-gc-only is specified">;
+def warn_atomic_property_rule : Warning<
+ "writable atomic property %0 cannot pair a synthesized setter/getter "
+ "with a user defined setter/getter">;
def err_use_continuation_class : Error<
"property declaration in continuation class of %0 is to change a 'readonly' "
"property to 'readwrite'">;
@@ -397,7 +405,9 @@ def note_ambig_member_ref_scope : Note<
"lookup from the current scope refers here">;
def err_qualified_member_nonclass : Error<
"qualified member access refers to a member in %0">;
-
+def err_incomplete_member_access : Error<
+ "member access into incomplete type %0">;
+
// C++ class members
def err_storageclass_invalid_for_member : Error<
"storage class specified for a member declaration">;
@@ -430,9 +440,15 @@ def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
-def err_missing_default_constructor : Error<
- "default constructor for %1 is missing in initialization of "
- "%select{base class|member}0">;
+def note_field_decl : Note<"member is declared here">;
+def note_previous_class_decl : Note<
+ "%0 declared here">;
+def note_ctor_synthesized_at : Note<
+ "implicit default constructor for %0 first required here">;
+def err_missing_default_ctor : Error<
+ "%select{|implicit default }0constructor for %1 must explicitly initialize "
+ "the %select{base class|member}2 %3 which does not have a default "
+ "constructor">;
def err_illegal_union_member : Error<
"union member %0 has a non-trivial %select{constructor|"
"copy constructor|copy assignment operator|destructor}1">;
@@ -632,6 +648,25 @@ def err_cconv_knr : Error<
def err_cconv_varargs : Error<
"variadic function cannot use '%0' calling convention">;
+def warn_impcast_vector_scalar : Warning<
+ "implicit cast turns vector to scalar: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_complex_scalar : Warning<
+ "implicit cast discards imaginary component: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_precision : Warning<
+ "implicit cast loses floating-point precision: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_integer : Warning<
+ "implicit cast turns floating-point number into integer: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_precision : Warning<
+ "implicit cast loses integer precision: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_64_32 : Warning<
+ "implicit cast loses integer precision: %0 to %1">,
+ InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
+
def warn_attribute_ignored_for_field_of_type : Warning<
"%0 attribute ignored for field of type %1">;
def warn_transparent_union_attribute_field_size_align : Warning<
@@ -744,27 +779,18 @@ def err_param_default_argument_member_template_redecl : Error<
"default arguments cannot be added to an out-of-line definition of a member "
"of a %select{class template|class template partial specialization|nested "
"class in a template}0">;
-def note_field_decl : Note<"member is declared here">;
-def err_defining_default_ctor : Error<
- "cannot define the implicit default constructor for %0, because %select{base class|member's type}1 "
- "%2 does not have any default constructor">;
-def note_previous_class_decl : Note<
- "%0 declared here">;
def err_uninitialized_member_for_assign : Error<
"cannot define the implicit default assignment operator for %0, because "
"non-static %select{reference|const}1 member %2 can't use default "
"assignment operator">;
def note_first_required_here : Note<
"synthesized method is first required here">;
-def err_unintialized_member : Error<
- "cannot define the implicit default constructor for %0, because "
- "%select{reference|const}1 member %2 cannot be default-initialized">;
def err_null_intialized_reference_member : Error<
"cannot initialize the member to null in default constructor because "
"reference member %0 cannot be null-initialized">;
def err_unintialized_member_in_ctor : Error<
- "constructor for %0 must explicitly initialize the "
- "%select{reference|const}1 member %2 ">;
+ "%select{|implicit default }0constructor for %1 must explicitly initialize "
+ "the %select{reference|const}2 member %3">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
@@ -993,6 +1019,9 @@ def err_template_spec_friend : Error<
def err_template_spec_default_arg : Error<
"default argument not permitted on an explicit "
"%select{instantiation|specialization}0 of function %1">;
+def err_not_class_template_specialization : Error<
+ "cannot specialize a %select{dependent template|template template "
+ "parameter}0">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<
@@ -1083,6 +1112,12 @@ def note_function_template_deduction_instantiation_here : Note<
def note_partial_spec_deduct_instantiation_here : Note<
"during template argument deduction for class template partial "
"specialization %0, here">;
+def note_prior_template_arg_substitution : Note<
+ "while substituting prior template arguments into %select{non-type|template}0"
+ " template parameter%1 %2">;
+def note_template_default_arg_checking : Note<
+ "while checking a default template argument used here">;
+
def err_field_instantiates_to_function : Error<
"data member instantiated with function type %0">;
def err_nested_name_spec_non_tag : Error<
@@ -1447,8 +1482,9 @@ def err_typecheck_member_reference_type : Error<
"cannot refer to type member %0 with '%select{.|->}1'">;
def err_typecheck_member_reference_unknown : Error<
"cannot refer to member %0 with '%select{.|->}1'">;
-def note_member_reference_needs_call : Note<
- "perhaps you meant to call this function with '()'?">;
+def err_member_reference_needs_call : Error<
+ "base of member reference has function type %0; perhaps you meant to call "
+ "this function with '()'?">;
def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
InGroup<CharSubscript>, DefaultIgnore;
@@ -1488,6 +1524,9 @@ def err_tentative_def_incomplete_type_arr : Error<
"tentative definition has array of type %0 that is never completed">;
def warn_tentative_incomplete_array : Warning<
"tentative array definition assumed to have one element">;
+def err_typecheck_incomplete_array_needs_initializer : Error<
+ "definition of variable with array type needs an explicit size "
+ "or an initializer">;
def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
def err_typecheck_sclass_fscope : Error<
@@ -1539,10 +1578,10 @@ def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
def warn_mixed_sign_comparison : Warning<
"comparison of integers of different signs: %0 and %1">,
- InGroup<DiagGroup<"sign-compare">>;
+ InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
def warn_mixed_sign_conditional : Warning<
"operands of ? are integers of different signs: %0 and %1">,
- InGroup<DiagGroup<"sign-compare">>;
+ InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
def err_invalid_this_use : Error<
"invalid use of 'this' outside of a nonstatic member function">;
@@ -1707,6 +1746,10 @@ def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
"expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behaviour">;
+def err_no_suitable_delete_member_function_found : Error<
+ "no suitable member %0 in %1">;
+def note_delete_member_function_declared_here : Note<
+ "%0 declared here">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
def warn_increment_bool : Warning<
"incrementing expression of type bool is deprecated">;
@@ -1786,9 +1829,13 @@ def err_incomplete_object_call : Error<
def warn_condition_is_assignment : Warning<"using the result of an "
"assignment as a condition without parentheses">,
InGroup<Parentheses>;
+// Completely identical except off by default.
+def warn_condition_is_idiomatic_assignment : Warning<"using the result "
+ "of an assignment as a condition without parentheses">,
+ InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
-def warn_value_always_zero : Warning<"%0 is always zero in this context">;
-def warn_value_always_false : Warning<"%0 is always false in this context">;
+def warn_value_always_zero : Warning<
+ "%0 is always %select{zero|false|NULL}1 in this context">;
// assignment related diagnostics (also for argument passing, returning, etc).
// FIXME: %2 is an english string here.
@@ -1816,6 +1863,8 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
"incompatible pointer types %2 %1, expected %0">;
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
"%2 %1 discards qualifiers, expected %0">;
+def ext_nested_pointer_qualifier_mismatch : ExtWarn<
+ "%2, %0 and %1 have different qualifiers in nested pointer types">;
def warn_incompatible_vectors : Warning<
"incompatible vector types %2 %1, expected %0">,
InGroup<VectorConversions>, DefaultIgnore;
@@ -2086,6 +2135,10 @@ def err_operator_overload_needs_class_or_enum : Error<
def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
def err_operator_overload_static : Error<
"overloaded %0 cannot be a static member function">;
+def err_operator_new_param_type : Error<
+ "%0 takes type size_t (%1) as first parameter">;
+def err_operator_new_result_type : Error<
+ "%0 must return type %1">;
def err_operator_overload_default_arg : Error<
"parameter of overloaded %0 cannot have a default argument">;
def err_operator_overload_must_be : Error<
@@ -2328,7 +2381,7 @@ def error_private_ivar_access : Error<"instance variable %0 is private">,
NoSFINAE;
def error_protected_ivar_access : Error<"instance variable %0 is protected">,
NoSFINAE;
-def warn_maynot_respond : Warning<"%0 may not respond to %1">;
+def warn_maynot_respond : Warning<"%0 may not respond to %1">;
def warn_attribute_method_def : Warning<
"method attribute can only be specified on method declarations">;
def ext_typecheck_base_super : Warning<
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index d4d3fe50eba0..99c100d55e7e 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -55,6 +55,7 @@ public:
unsigned POSIXThreads : 1; // Compiling with POSIX thread support
// (-pthread)
unsigned Blocks : 1; // block extension to C
+ unsigned BlockIntrospection: 1; // block have ObjC type encodings.
unsigned EmitAllDecls : 1; // Emit all declarations, even if
// they are unused.
unsigned MathErrno : 1; // Math functions must respect errno
@@ -83,6 +84,7 @@ public:
unsigned AccessControl : 1; // Whether C++ access control should
// be enabled.
unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type
+ unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int.
unsigned OpenCL : 1; // OpenCL C99 language extensions.
@@ -125,7 +127,8 @@ public:
ObjCConstantStringClass = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = 0;
- Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
+ Exceptions = Freestanding = NoBuiltin = 0;
+ NeXTRuntime = 1;
Rtti = 1;
LaxVectorConversions = 1;
HeinousExtensions = 0;
@@ -137,6 +140,7 @@ public:
ThreadsafeStatics = 0;
POSIXThreads = 0;
Blocks = 0;
+ BlockIntrospection = 0;
EmitAllDecls = 0;
MathErrno = 1;
@@ -159,6 +163,7 @@ public:
NoInline = 0;
CharIsSigned = 1;
+ ShortWChar = 0;
MainFileName = 0;
}
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index 6ed5fefb7e64..b85eb0725ef0 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -9,12 +9,14 @@ TABLEGEN_INC_FILES_COMMON = 1
include $(LEVEL)/Makefile.common
+INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
+
$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN)
$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
$(Verb) -$(MKDIR) $(@D)
$(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
-$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(wildcard Diagnostic*.td) $(TBLGEN)
+$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN)
$(Echo) "Building Clang diagnostic groups with tblgen"
$(Verb) -$(MKDIR) $(@D)
$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index e61ef9265cfb..695f51d2c4c9 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -28,11 +28,12 @@ class StringRef;
}
namespace clang {
-
class Diagnostic;
+class LangOptions;
class SourceLocation;
class SourceManager;
-class LangOptions;
+class TargetOptions;
+
namespace Builtin { struct Info; }
/// TargetInfo - This class exposes information about the current target.
@@ -44,16 +45,12 @@ protected:
// values are specified by the TargetInfo constructor.
bool TLSSupported;
unsigned char PointerWidth, PointerAlign;
- unsigned char WCharWidth, WCharAlign;
- unsigned char Char16Width, Char16Align;
- unsigned char Char32Width, Char32Align;
unsigned char IntWidth, IntAlign;
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
unsigned char LongDoubleWidth, LongDoubleAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
- unsigned char IntMaxTWidth;
const char *DescriptionString;
const char *UserLabelPrefix;
const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
@@ -63,9 +60,9 @@ protected:
TargetInfo(const std::string &T);
public:
- /// CreateTargetInfo - Return the target info object for the specified target
- /// triple.
- static TargetInfo* CreateTargetInfo(const std::string &Triple);
+ /// CreateTargetInfo - Construct a target for the given options.
+ static TargetInfo* CreateTargetInfo(Diagnostic &Diags,
+ const TargetOptions &Opts);
virtual ~TargetInfo();
@@ -103,6 +100,10 @@ public:
/// enum. For example, SignedInt -> getIntWidth().
unsigned getTypeWidth(IntType T) const;
+ /// getTypeAlign - Return the alignment (in bits) of the specified integer
+ /// type enum. For example, SignedInt -> getIntAlign().
+ unsigned getTypeAlign(IntType T) const;
+
/// isTypeSigned - Return whether an integer types is signed. Returns true if
/// the type is signed; false otherwise.
bool isTypeSigned(IntType T) const;
@@ -146,18 +147,18 @@ public:
/// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
/// bits.
- unsigned getWCharWidth() const { return WCharWidth; }
- unsigned getWCharAlign() const { return WCharAlign; }
+ unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
+ unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
/// getChar16Width/Align - Return the size of 'char16_t' for this target, in
/// bits.
- unsigned getChar16Width() const { return Char16Width; }
- unsigned getChar16Align() const { return Char16Align; }
+ unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
+ unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
/// getChar32Width/Align - Return the size of 'char32_t' for this target, in
/// bits.
- unsigned getChar32Width() const { return Char32Width; }
- unsigned getChar32Align() const { return Char32Align; }
+ unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
+ unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
/// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
unsigned getFloatWidth() const { return FloatWidth; }
@@ -180,7 +181,7 @@ public:
/// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
/// target, in bits.
unsigned getIntMaxTWidth() const {
- return IntMaxTWidth;
+ return getTypeWidth(IntMaxType);
}
/// getUserLabelPrefix - This returns the default value of the
@@ -341,10 +342,10 @@ public:
return "";
}
- /// 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) {}
+ /// setForcedLangOptions - Set forced language options.
+ /// Apply changes to the target information with respect to certain
+ /// language options which change the target configuration.
+ virtual void setForcedLangOptions(LangOptions &Opts);
/// getDefaultFeatures - Get the default set of target features for
/// the \args CPU; this should include all legal feature strings on
@@ -375,9 +376,10 @@ public:
return false;
}
- /// HandleTargetOptions - Perform initialization based on the user
- /// configured set of features.
- virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features) {
+ /// HandleTargetOptions - Perform initialization based on the user configured
+ /// set of features (e.g., +sse4). The list is guaranteed to have at most one
+ /// entry per feature.
+ virtual void HandleTargetFeatures(const std::vector<std::string> &Features) {
}
// getRegParmMax - Returns maximal number of args passed in registers.
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
new file mode 100644
index 000000000000..eeaab1558fd1
--- /dev/null
+++ b/include/clang/Basic/TargetOptions.h
@@ -0,0 +1,39 @@
+//===--- TargetOptions.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// TargetOptions - Options for controlling the target.
+class TargetOptions {
+public:
+
+ /// If given, the name of the target triple to compile for. If not given the
+ /// target will be selected to match the host.
+ std::string Triple;
+
+ /// If given, the name of the target CPU to generate code for.
+ std::string CPU;
+
+ /// If given, the name of the target ABI to use.
+ std::string ABI;
+
+ /// The list of target specific features to enable or disable -- this should
+ /// be a list of strings starting with by '+' or '-'.
+ std::vector<std::string> Features;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
new file mode 100644
index 000000000000..02679cd99895
--- /dev/null
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -0,0 +1,75 @@
+//===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CodeGenOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+#define LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// CodeGenOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+class CodeGenOptions {
+public:
+ enum InliningMethod {
+ NoInlining, // Perform no inlining whatsoever.
+ NormalInlining, // Use the standard function inlining pass.
+ OnlyAlwaysInlining // Only run the always inlining pass.
+ };
+
+ unsigned DebugInfo : 1; /// Should generate deubg info (-g).
+ unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
+ /// getting .bc files that correspond to the
+ /// internal state before optimizations are
+ /// done.
+ unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
+ unsigned MergeAllConstants : 1; /// Merge identical constants.
+ unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
+ unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
+ unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
+ unsigned OptimizeSize : 1; /// If -Os is specified.
+ unsigned SimplifyLibCalls : 1; /// Should standard library calls be treated
+ /// specially.
+ unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
+ unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
+ /// selection.
+ unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
+ unsigned VerifyModule : 1; /// Control whether the module should be run
+ /// through the LLVM Verifier.
+
+ /// Inlining - The kind of inlining to perform.
+ InliningMethod Inlining;
+
+public:
+ CodeGenOptions() {
+ OptimizationLevel = 0;
+ OptimizeSize = 0;
+ DebugInfo = 0;
+ UnitAtATime = 1;
+ SimplifyLibCalls = UnrollLoops = 0;
+ VerifyModule = 1;
+ TimePasses = 0;
+ NoCommon = 0;
+ Inlining = NoInlining;
+ DisableRedZone = 0;
+ NoImplicitFloat = 0;
+ MergeAllConstants = 1;
+ DisableLLVMOpts = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 1871c8f206f3..2a3aa6a90404 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -25,7 +25,7 @@ namespace llvm {
namespace clang {
class Diagnostic;
class LangOptions;
- class CompileOptions;
+ class CodeGenOptions;
class CodeGenerator : public ASTConsumer {
public:
@@ -35,7 +35,7 @@ namespace clang {
CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
const std::string &ModuleName,
- const CompileOptions &CO,
+ const CodeGenOptions &CGO,
llvm::LLVMContext& C);
}
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index c0327a2f1d1c..d3ab1153371a 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -48,7 +48,7 @@ class Driver {
public:
// Diag - Forwarding function for diagnostics.
DiagnosticBuilder Diag(unsigned DiagID) const {
- return Diags.Report(FullSourceLoc(), DiagID);
+ return Diags.Report(DiagID);
}
// FIXME: Privatize once interface is stable.
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index 5370114ee824..2b66b3506b01 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -368,6 +368,7 @@ OPTION("-fastcp", fastcp, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fastf", fastf, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fast", fast, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fasynchronous-unwind-tables", fasynchronous_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fblock-introspection", fblock_introspection, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fblocks", fblocks, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fbootclasspath=", fbootclasspath_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fbuiltin-strcat", fbuiltin_strcat, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -430,6 +431,7 @@ OPTION("-fno-inline", fno_inline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0
OPTION("-fno-keep-inline-functions", fno_keep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-merge-all-constants", fno_merge_all_constants, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fno-ms-extensions", fno_ms_extensions, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-omit-frame-pointer", fno_omit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-rtti", fno_rtti, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -448,7 +450,6 @@ OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-tight-layout", fobjc_tight_layout, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fopenmp", fopenmp, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -463,6 +464,7 @@ OPTION("-fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
OPTION("-frtti", frtti, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fshort-wchar", fshort_wchar, Flag, f_Group, INVALID, "", 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)
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index b7630d8afdb8..df651a6c3d00 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -90,6 +90,17 @@ public:
/// default.
virtual bool IsMathErrnoDefault() const = 0;
+ /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
+ virtual bool IsBlocksDefault() const { return false; }
+
+ /// IsObjCNonFragileABIDefault - Does this tool chain set
+ /// -fobjc-nonfragile-abi by default.
+ virtual bool IsObjCNonFragileABIDefault() const { return false; }
+
+ /// GetDefaultStackProtectorLevel - Get the default stack protector level for
+ /// this tool chain (0=off, 1=on, 2=all).
+ virtual unsigned GetDefaultStackProtectorLevel() const { return 0; }
+
/// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
/// by default.
virtual bool IsUnwindTablesDefault() const = 0;
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index 92520a77b33b..3a343b385e7a 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -62,6 +62,9 @@ namespace types {
/// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
bool isCXX(ID Id);
+ /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
+ bool isObjC(ID Id);
+
/// lookupTypeForExtension - Lookup the type to use for the file
/// extension \arg Ext.
ID lookupTypeForExtension(const char *Ext);
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 742813c66907..0e7d55e6e45b 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -25,11 +25,12 @@ namespace llvm {
namespace clang {
class ASTConsumer;
+class CodeGenOptions;
class Diagnostic;
class FileManager;
-class Preprocessor;
-class CompileOptions;
class LangOptions;
+class Preprocessor;
+class TargetOptions;
// AST pretty-printer: prints out the AST in a format that is close to the
// original C code. The output is intended to be in a format such that
@@ -69,7 +70,7 @@ ASTConsumer *CreateObjCRewriter(const std::string &InFile,
bool SilenceRewriteMacroWarning);
// LLVM code generator: uses the code generation backend to generate LLVM
-// assembly. This runs optimizations depending on the CompileOptions
+// assembly. This runs optimizations depending on the CodeGenOptions
// parameter. The output depends on the Action parameter.
enum BackendAction {
Backend_EmitAssembly, // Emit native assembly
@@ -80,7 +81,8 @@ enum BackendAction {
ASTConsumer *CreateBackendConsumer(BackendAction Action,
Diagnostic &Diags,
const LangOptions &Features,
- const CompileOptions &CompileOpts,
+ const CodeGenOptions &CodeGenOpts,
+ const TargetOptions &TargetOpts,
const std::string &ModuleID,
llvm::raw_ostream *OS,
llvm::LLVMContext& C);
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index d5e408020a98..7d55673a612f 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -48,6 +48,9 @@ ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars",
ANALYSIS(CheckerCFRef, "checker-cfref",
"Run the [Core] Foundation reference count checker", Code)
+ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
+ "Warn about unintended use of sizeof() on pointer expressions", Code)
+
ANALYSIS(InlineCall, "inline-call",
"Experimental transfer function inling callees when its definition"
" is available.", TranslationUnit)
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
index 34054a7aa00e..7a324331ecdc 100644
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ b/include/clang/Frontend/AnalysisConsumer.h
@@ -1,4 +1,4 @@
-//===--- AnalysisConsumer.h - Front-end hooks for the analysis engine------===//
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,6 +12,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+#define LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+
#include <string>
#include <vector>
@@ -50,19 +53,37 @@ enum AnalysisDiagClients {
NUM_ANALYSIS_DIAG_CLIENTS
};
-struct AnalyzerOptions {
+class AnalyzerOptions {
+public:
std::vector<Analyses> AnalysisList;
AnalysisStores AnalysisStoreOpt;
AnalysisConstraints AnalysisConstraintsOpt;
AnalysisDiagClients AnalysisDiagOpt;
- bool VisualizeEGDot;
- bool VisualizeEGUbi;
- bool AnalyzeAll;
- bool AnalyzerDisplayProgress;
- bool PurgeDead;
- bool EagerlyAssume;
std::string AnalyzeSpecificFunction;
- bool TrimGraph;
+ unsigned AnalyzeAll : 1;
+ unsigned AnalyzerDisplayProgress : 1;
+ unsigned EagerlyAssume : 1;
+ unsigned PurgeDead : 1;
+ unsigned TrimGraph : 1;
+ unsigned VisualizeEGDot : 1;
+ unsigned VisualizeEGUbi : 1;
+ unsigned EnableExperimentalChecks : 1;
+ unsigned EnableExperimentalInternalChecks : 1;
+public:
+ AnalyzerOptions() {
+ AnalysisStoreOpt = BasicStoreModel;
+ AnalysisConstraintsOpt = RangeConstraintsModel;
+ AnalysisDiagOpt = PD_HTML;
+ AnalyzeAll = 0;
+ AnalyzerDisplayProgress = 0;
+ EagerlyAssume = 0;
+ PurgeDead = 0;
+ TrimGraph = 0;
+ VisualizeEGDot = 0;
+ VisualizeEGUbi = 0;
+ EnableExperimentalChecks = 0;
+ EnableExperimentalInternalChecks = 0;
+ }
};
/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
@@ -73,3 +94,5 @@ ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
const AnalyzerOptions& Opts);
}
+
+#endif
diff --git a/include/clang/Frontend/ChainedDiagnosticClient.h b/include/clang/Frontend/ChainedDiagnosticClient.h
new file mode 100644
index 000000000000..2d5e128dac37
--- /dev/null
+++ b/include/clang/Frontend/ChainedDiagnosticClient.h
@@ -0,0 +1,58 @@
+//===--- ChainedDiagnosticClient.h - Chain Diagnostic Clients ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+class LangOptions;
+
+/// ChainedDiagnosticClient - Chain two diagnostic clients so that diagnostics
+/// go to the first client and then the second. The first diagnostic client
+/// should be the "primary" client, and will be used for computing whether the
+/// diagnostics should be included in counts.
+class ChainedDiagnosticClient : public DiagnosticClient {
+ llvm::OwningPtr<DiagnosticClient> Primary;
+ llvm::OwningPtr<DiagnosticClient> Secondary;
+
+public:
+ ChainedDiagnosticClient(DiagnosticClient *_Primary,
+ DiagnosticClient *_Secondary) {
+ Primary.reset(_Primary);
+ Secondary.reset(_Secondary);
+ }
+
+ virtual void BeginSourceFile(const LangOptions &LO,
+ const Preprocessor *PP) {
+ Primary->BeginSourceFile(LO, PP);
+ Secondary->BeginSourceFile(LO, PP);
+ }
+
+ virtual void EndSourceFile() {
+ Secondary->EndSourceFile();
+ Primary->EndSourceFile();
+ }
+
+ virtual bool IncludeInDiagnosticCounts() const {
+ return Primary->IncludeInDiagnosticCounts();
+ }
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info) {
+ Primary->HandleDiagnostic(DiagLevel, Info);
+ Secondary->HandleDiagnostic(DiagLevel, Info);
+ }
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
index 59f70ede9129..d5a0598dfab2 100644
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -1,3 +1,4 @@
+
//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
@@ -37,7 +38,7 @@ namespace llvm {
class parser<clang::ParsedSourceLocation>
: public basic_parser<clang::ParsedSourceLocation> {
public:
- bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
+ inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
clang::ParsedSourceLocation &Val);
};
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
new file mode 100644
index 000000000000..ed280508778a
--- /dev/null
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -0,0 +1,523 @@
+//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+
+#include "clang/Frontend/CompilerInvocation.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <cassert>
+#include <list>
+#include <string>
+
+namespace llvm {
+class LLVMContext;
+class raw_ostream;
+class raw_fd_ostream;
+}
+
+namespace clang {
+class ASTContext;
+class ASTConsumer;
+class CodeCompleteConsumer;
+class Diagnostic;
+class DiagnosticClient;
+class ExternalASTSource;
+class FileManager;
+class Preprocessor;
+class Source;
+class SourceManager;
+class TargetInfo;
+
+/// CompilerInstance - Helper class for managing a single instance of the Clang
+/// compiler.
+///
+/// The CompilerInstance serves two purposes:
+/// (1) It manages the various objects which are necessary to run the compiler,
+/// for example the preprocessor, the target information, and the AST
+/// context.
+/// (2) It provides utility routines for constructing and manipulating the
+/// common Clang objects.
+///
+/// The compiler instance generally owns the instance of all the objects that it
+/// manages. However, clients can still share objects by manually setting the
+/// object and retaking ownership prior to destroying the CompilerInstance.
+///
+/// The compiler instance is intended to simplify clients, but not to lock them
+/// in to the compiler instance for everything. When possible, utility functions
+/// come in two forms; a short form that reuses the CompilerInstance objects,
+/// and a long form that takes explicit instances of any required objects.
+class CompilerInstance {
+ /// The LLVM context used for this instance.
+ llvm::LLVMContext *LLVMContext;
+ bool OwnsLLVMContext;
+
+ /// The options used in this compiler instance.
+ CompilerInvocation Invocation;
+
+ /// The diagnostics engine instance.
+ llvm::OwningPtr<Diagnostic> Diagnostics;
+
+ /// The diagnostics client instance.
+ llvm::OwningPtr<DiagnosticClient> DiagClient;
+
+ /// The target being compiled for.
+ llvm::OwningPtr<TargetInfo> Target;
+
+ /// The file manager.
+ llvm::OwningPtr<FileManager> FileMgr;
+
+ /// The source manager.
+ llvm::OwningPtr<SourceManager> SourceMgr;
+
+ /// The preprocessor.
+ llvm::OwningPtr<Preprocessor> PP;
+
+ /// The AST context.
+ llvm::OwningPtr<ASTContext> Context;
+
+ /// The AST consumer.
+ llvm::OwningPtr<ASTConsumer> Consumer;
+
+ /// The code completion consumer.
+ llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+
+ /// The list of active output files.
+ std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
+
+public:
+ /// Create a new compiler instance with the given LLVM context, optionally
+ /// taking ownership of it.
+ CompilerInstance(llvm::LLVMContext *_LLVMContext = 0,
+ bool _OwnsLLVMContext = true);
+ ~CompilerInstance();
+
+ /// @name LLVM Context
+ /// {
+
+ bool hasLLVMContext() const { return LLVMContext != 0; }
+
+ llvm::LLVMContext &getLLVMContext() const {
+ assert(LLVMContext && "Compiler instance has no LLVM context!");
+ return *LLVMContext;
+ }
+
+ /// setLLVMContext - Replace the current LLVM context and take ownership of
+ /// \arg Value.
+ void setLLVMContext(llvm::LLVMContext *Value, bool TakeOwnership = true) {
+ LLVMContext = Value;
+ OwnsLLVMContext = TakeOwnership;
+ }
+
+ /// }
+ /// @name Compiler Invocation and Options
+ /// {
+
+ CompilerInvocation &getInvocation() { return Invocation; }
+ const CompilerInvocation &getInvocation() const { return Invocation; }
+ void setInvocation(const CompilerInvocation &Value) { Invocation = Value; }
+
+ /// }
+ /// @name Forwarding Methods
+ /// {
+
+ AnalyzerOptions &getAnalyzerOpts() {
+ return Invocation.getAnalyzerOpts();
+ }
+ const AnalyzerOptions &getAnalyzerOpts() const {
+ return Invocation.getAnalyzerOpts();
+ }
+
+ CodeGenOptions &getCodeGenOpts() {
+ return Invocation.getCodeGenOpts();
+ }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return Invocation.getCodeGenOpts();
+ }
+
+ DependencyOutputOptions &getDependencyOutputOpts() {
+ return Invocation.getDependencyOutputOpts();
+ }
+ const DependencyOutputOptions &getDependencyOutputOpts() const {
+ return Invocation.getDependencyOutputOpts();
+ }
+
+ DiagnosticOptions &getDiagnosticOpts() {
+ return Invocation.getDiagnosticOpts();
+ }
+ const DiagnosticOptions &getDiagnosticOpts() const {
+ return Invocation.getDiagnosticOpts();
+ }
+
+ FrontendOptions &getFrontendOpts() {
+ return Invocation.getFrontendOpts();
+ }
+ const FrontendOptions &getFrontendOpts() const {
+ return Invocation.getFrontendOpts();
+ }
+
+ HeaderSearchOptions &getHeaderSearchOpts() {
+ return Invocation.getHeaderSearchOpts();
+ }
+ const HeaderSearchOptions &getHeaderSearchOpts() const {
+ return Invocation.getHeaderSearchOpts();
+ }
+
+ LangOptions &getLangOpts() {
+ return Invocation.getLangOpts();
+ }
+ const LangOptions &getLangOpts() const {
+ return Invocation.getLangOpts();
+ }
+
+ PreprocessorOptions &getPreprocessorOpts() {
+ return Invocation.getPreprocessorOpts();
+ }
+ const PreprocessorOptions &getPreprocessorOpts() const {
+ return Invocation.getPreprocessorOpts();
+ }
+
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+ return Invocation.getPreprocessorOutputOpts();
+ }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+ return Invocation.getPreprocessorOutputOpts();
+ }
+
+ TargetOptions &getTargetOpts() {
+ return Invocation.getTargetOpts();
+ }
+ const TargetOptions &getTargetOpts() const {
+ return Invocation.getTargetOpts();
+ }
+
+ /// }
+ /// @name Diagnostics Engine
+ /// {
+
+ bool hasDiagnostics() const { return Diagnostics != 0; }
+
+ Diagnostic &getDiagnostics() const {
+ assert(Diagnostics && "Compiler instance has no diagnostics!");
+ return *Diagnostics;
+ }
+
+ /// takeDiagnostics - Remove the current diagnostics engine and give ownership
+ /// to the caller.
+ Diagnostic *takeDiagnostics() { return Diagnostics.take(); }
+
+ /// setDiagnostics - Replace the current diagnostics engine; the compiler
+ /// instance takes ownership of \arg Value.
+ void setDiagnostics(Diagnostic *Value);
+
+ DiagnosticClient &getDiagnosticClient() const {
+ assert(Target && "Compiler instance has no diagnostic client!");
+ return *DiagClient;
+ }
+
+ /// takeDiagnosticClient - Remove the current diagnostics client and give
+ /// ownership to the caller.
+ DiagnosticClient *takeDiagnosticClient() { return DiagClient.take(); }
+
+ /// setDiagnosticClient - Replace the current diagnostics client; the compiler
+ /// instance takes ownership of \arg Value.
+ void setDiagnosticClient(DiagnosticClient *Value);
+
+ /// }
+ /// @name Target Info
+ /// {
+
+ bool hasTarget() const { return Target != 0; }
+
+ TargetInfo &getTarget() const {
+ assert(Target && "Compiler instance has no target!");
+ return *Target;
+ }
+
+ /// takeTarget - Remove the current diagnostics engine and give ownership
+ /// to the caller.
+ TargetInfo *takeTarget() { return Target.take(); }
+
+ /// setTarget - Replace the current diagnostics engine; the compiler
+ /// instance takes ownership of \arg Value.
+ void setTarget(TargetInfo *Value);
+
+ /// }
+ /// @name File Manager
+ /// {
+
+ bool hasFileManager() const { return FileMgr != 0; }
+
+ FileManager &getFileManager() const {
+ assert(FileMgr && "Compiler instance has no file manager!");
+ return *FileMgr;
+ }
+
+ /// takeFileManager - Remove the current file manager and give ownership to
+ /// the caller.
+ FileManager *takeFileManager() { return FileMgr.take(); }
+
+ /// setFileManager - Replace the current file manager; the compiler instance
+ /// takes ownership of \arg Value.
+ void setFileManager(FileManager *Value);
+
+ /// }
+ /// @name Source Manager
+ /// {
+
+ bool hasSourceManager() const { return SourceMgr != 0; }
+
+ SourceManager &getSourceManager() const {
+ assert(SourceMgr && "Compiler instance has no source manager!");
+ return *SourceMgr;
+ }
+
+ /// takeSourceManager - Remove the current source manager and give ownership
+ /// to the caller.
+ SourceManager *takeSourceManager() { return SourceMgr.take(); }
+
+ /// setSourceManager - Replace the current source manager; the compiler
+ /// instance takes ownership of \arg Value.
+ void setSourceManager(SourceManager *Value);
+
+ /// }
+ /// @name Preprocessor
+ /// {
+
+ bool hasPreprocessor() const { return PP != 0; }
+
+ Preprocessor &getPreprocessor() const {
+ assert(PP && "Compiler instance has no preprocessor!");
+ return *PP;
+ }
+
+ /// takePreprocessor - Remove the current preprocessor and give ownership to
+ /// the caller.
+ Preprocessor *takePreprocessor() { return PP.take(); }
+
+ /// setPreprocessor - Replace the current preprocessor; the compiler instance
+ /// takes ownership of \arg Value.
+ void setPreprocessor(Preprocessor *Value);
+
+ /// }
+ /// @name ASTContext
+ /// {
+
+ bool hasASTContext() const { return Context != 0; }
+
+ ASTContext &getASTContext() const {
+ assert(Context && "Compiler instance has no AST context!");
+ return *Context;
+ }
+
+ /// takeASTContext - Remove the current AST context and give ownership to the
+ /// caller.
+ ASTContext *takeASTContext() { return Context.take(); }
+
+ /// setASTContext - Replace the current AST context; the compiler instance
+ /// takes ownership of \arg Value.
+ void setASTContext(ASTContext *Value);
+
+ /// }
+ /// @name ASTConsumer
+ /// {
+
+ bool hasASTConsumer() const { return Consumer != 0; }
+
+ ASTConsumer &getASTConsumer() const {
+ assert(Consumer && "Compiler instance has no AST consumer!");
+ return *Consumer;
+ }
+
+ /// takeASTConsumer - Remove the current AST consumer and give ownership to
+ /// the caller.
+ ASTConsumer *takeASTConsumer() { return Consumer.take(); }
+
+ /// setASTConsumer - Replace the current AST consumer; the compiler instance
+ /// takes ownership of \arg Value.
+ void setASTConsumer(ASTConsumer *Value);
+
+ /// }
+ /// @name Code Completion
+ /// {
+
+ bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
+
+ CodeCompleteConsumer &getCodeCompletionConsumer() const {
+ assert(CompletionConsumer &&
+ "Compiler instance has no code completion consumer!");
+ return *CompletionConsumer;
+ }
+
+ /// takeCodeCompletionConsumer - Remove the current code completion consumer
+ /// and give ownership to the caller.
+ CodeCompleteConsumer *takeCodeCompletionConsumer() {
+ return CompletionConsumer.take();
+ }
+
+ /// setCodeCompletionConsumer - Replace the current code completion consumer;
+ /// the compiler instance takes ownership of \arg Value.
+ void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
+
+ /// }
+ /// @name Output Files
+ /// {
+
+ /// getOutputFileList - Get the list of (path, output stream) pairs of output
+ /// files; the path may be empty but the stream will always be non-null.
+ const std::list< std::pair<std::string,
+ llvm::raw_ostream*> > &getOutputFileList() const;
+
+ /// addOutputFile - Add an output file onto the list of tracked output files.
+ ///
+ /// \param Path - The path to the output file, or empty.
+ /// \param OS - The output stream, which should be non-null.
+ void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS);
+
+ /// ClearOutputFiles - Clear the output file list, destroying the contained
+ /// output streams.
+ ///
+ /// \param EraseFiles - If true, attempt to erase the files from disk.
+ void ClearOutputFiles(bool EraseFiles);
+
+ /// }
+ /// @name Construction Utility Methods
+ /// {
+
+ /// Create the diagnostics engine using the invocation's diagnostic options
+ /// and replace any existing one with it.
+ ///
+ /// Note that this routine also replaces the diagnostic client.
+ void createDiagnostics(int Argc, char **Argv);
+
+ /// Create a Diagnostic object with a the TextDiagnosticPrinter.
+ ///
+ /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
+ /// when the diagnostic options indicate that the compiler should output
+ /// logging information.
+ ///
+ /// Note that this creates an unowned DiagnosticClient, if using directly the
+ /// caller is responsible for releaseing the returned Diagnostic's client
+ /// eventually.
+ ///
+ /// \return The new object on success, or null on failure.
+ static Diagnostic *createDiagnostics(const DiagnosticOptions &Opts,
+ int Argc, char **Argv);
+
+ /// Create the file manager and replace any existing one with it.
+ void createFileManager();
+
+ /// Create the source manager and replace any existing one with it.
+ void createSourceManager();
+
+ /// Create the preprocessor, using the invocation, file, and source managers,
+ /// and replace any existing one with it.
+ void createPreprocessor();
+
+ /// Create a Preprocessor object.
+ ///
+ /// Note that this also creates a new HeaderSearch object which will be owned
+ /// by the resulting Preprocessor.
+ ///
+ /// \return The new object on success, or null on failure.
+ static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
+ const PreprocessorOptions &,
+ const HeaderSearchOptions &,
+ const DependencyOutputOptions &,
+ const TargetInfo &,
+ SourceManager &, FileManager &);
+
+ /// Create the AST context.
+ void createASTContext();
+
+ /// Create an external AST source to read a PCH file and attach it to the AST
+ /// context.
+ void createPCHExternalASTSource(llvm::StringRef Path);
+
+ /// Create an external AST source to read a PCH file.
+ ///
+ /// \return - The new object on success, or null on failure.
+ static ExternalASTSource *
+ createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
+ Preprocessor &PP, ASTContext &Context);
+
+ /// Create a code completion consumer using the invocation; note that this
+ /// will cause the source manager to truncate the input source file at the
+ /// completion point.
+ void createCodeCompletionConsumer();
+
+ /// Create a code completion consumer to print code completion results, at
+ /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
+ /// OS.
+ static CodeCompleteConsumer *
+ createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
+ unsigned Line, unsigned Column,
+ bool UseDebugPrinter, bool ShowMacros,
+ llvm::raw_ostream &OS);
+
+ /// Create the default output file (from the invocation's options) and add it
+ /// to the list of tracked output files.
+ llvm::raw_fd_ostream *
+ createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "");
+
+ /// Create a new output file and add it to the list of tracked output files,
+ /// optionally deriving the output path name.
+ llvm::raw_fd_ostream *
+ createOutputFile(llvm::StringRef OutputPath, bool Binary = true,
+ llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "");
+
+ /// Create a new output file, optionally deriving the output path name.
+ ///
+ /// If \arg OutputPath is empty, then createOutputFile will derive an output
+ /// path location as \arg BaseInput, with any suffix removed, and \arg
+ /// Extension appended.
+ ///
+ /// \param OutputPath - If given, the path to the output file.
+ /// \param Error [out] - On failure, the error message.
+ /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
+ /// for deriving the output path.
+ /// \param Extension - The extension to use for derived output names.
+ /// \param Binary - The mode to open the file in.
+ /// \param ResultPathName [out] - If given, the result path name will be
+ /// stored here on success.
+ static llvm::raw_fd_ostream *
+ createOutputFile(llvm::StringRef OutputPath, std::string &Error,
+ bool Binary = true, llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "",
+ std::string *ResultPathName = 0);
+
+ /// }
+ /// @name Initialization Utility Methods
+ /// {
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ bool InitializeSourceManager(llvm::StringRef InputFile);
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ static bool InitializeSourceManager(llvm::StringRef InputFile,
+ Diagnostic &Diags,
+ FileManager &FileMgr,
+ SourceManager &SourceMgr,
+ const FrontendOptions &Opts);
+
+ /// }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
new file mode 100644
index 000000000000..9d068c523c69
--- /dev/null
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -0,0 +1,150 @@
+//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/HeaderSearchOptions.h"
+#include "clang/Frontend/PreprocessorOptions.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+ template<typename T> class SmallVectorImpl;
+}
+
+namespace clang {
+
+/// CompilerInvocation - Helper class for holding the data necessary to invoke
+/// the compiler.
+///
+/// This class is designed to represent an abstract "invocation" of the
+/// compiler, including data such as the include paths, the code generation
+/// options, the warning flags, and so on.
+class CompilerInvocation {
+ /// Options controlling the static analyzer.
+ AnalyzerOptions AnalyzerOpts;
+
+ /// Options controlling IRgen and the backend.
+ CodeGenOptions CodeGenOpts;
+
+ /// Options controlling dependency output.
+ DependencyOutputOptions DependencyOutputOpts;
+
+ /// Options controlling the diagnostic engine.
+ DiagnosticOptions DiagnosticOpts;
+
+ /// Options controlling the frontend itself.
+ FrontendOptions FrontendOpts;
+
+ /// Options controlling the #include directive.
+ HeaderSearchOptions HeaderSearchOpts;
+
+ /// Options controlling the language variant.
+ LangOptions LangOpts;
+
+ /// Options controlling the preprocessor (aside from #include handling).
+ PreprocessorOptions PreprocessorOpts;
+
+ /// Options controlling preprocessed output.
+ PreprocessorOutputOptions PreprocessorOutputOpts;
+
+ /// Options controlling the target.
+ TargetOptions TargetOpts;
+
+public:
+ CompilerInvocation() {}
+
+ /// @name Utility Methods
+ /// @{
+
+ /// CreateFromArgs - Create a compiler invocation from a list of input
+ /// options.
+ ///
+ /// FIXME: Documenting error behavior.
+ ///
+ /// \param Res [out] - The resulting invocation.
+ /// \param Args - The input argument strings.
+ static void CreateFromArgs(CompilerInvocation &Res,
+ const llvm::SmallVectorImpl<llvm::StringRef> &Args);
+
+ /// toArgs - Convert the CompilerInvocation to a list of strings suitable for
+ /// passing to CreateFromArgs.
+ void toArgs(std::vector<std::string> &Res);
+
+ /// @}
+ /// @name Option Subgroups
+ /// @{
+
+ AnalyzerOptions &getAnalyzerOpts() { return AnalyzerOpts; }
+ const AnalyzerOptions &getAnalyzerOpts() const {
+ return AnalyzerOpts;
+ }
+
+ CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return CodeGenOpts;
+ }
+
+ DependencyOutputOptions &getDependencyOutputOpts() {
+ return DependencyOutputOpts;
+ }
+ const DependencyOutputOptions &getDependencyOutputOpts() const {
+ return DependencyOutputOpts;
+ }
+
+ DiagnosticOptions &getDiagnosticOpts() { return DiagnosticOpts; }
+ const DiagnosticOptions &getDiagnosticOpts() const { return DiagnosticOpts; }
+
+ HeaderSearchOptions &getHeaderSearchOpts() { return HeaderSearchOpts; }
+ const HeaderSearchOptions &getHeaderSearchOpts() const {
+ return HeaderSearchOpts;
+ }
+
+ FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+ const FrontendOptions &getFrontendOpts() const {
+ return FrontendOpts;
+ }
+
+ LangOptions &getLangOpts() { return LangOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
+
+ PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; }
+ const PreprocessorOptions &getPreprocessorOpts() const {
+ return PreprocessorOpts;
+ }
+
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+ return PreprocessorOutputOpts;
+ }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+ return PreprocessorOutputOpts;
+ }
+
+ TargetOptions &getTargetOpts() { return TargetOpts; }
+ const TargetOptions &getTargetOpts() const {
+ return TargetOpts;
+ }
+
+ /// @}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
new file mode 100644
index 000000000000..ab8e49df9a88
--- /dev/null
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -0,0 +1,43 @@
+//===--- DependencyOutputOptions.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// DependencyOutputOptions - Options for controlling the compiler dependency
+/// file generation.
+class DependencyOutputOptions {
+public:
+ unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
+ unsigned UsePhonyTargets : 1; ///< Include phony targets for each
+ /// dependency, which can avoid some 'make'
+ /// problems.
+
+ /// The file to write depencency output to.
+ std::string OutputFile;
+
+ /// A list of names to use as the targets in the dependency file; this list
+ /// must contain at least one entry.
+ std::vector<std::string> Targets;
+
+public:
+ DependencyOutputOptions() {
+ IncludeSystemHeaders = 0;
+ UsePhonyTargets = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
index 58673e4dad6b..6346dc0bfdec 100644
--- a/include/clang/Frontend/DiagnosticOptions.h
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -19,6 +19,10 @@ namespace clang {
/// engine.
class DiagnosticOptions {
public:
+ unsigned IgnoreWarnings : 1; /// -w
+ unsigned NoRewriteMacros : 1; /// -Wno-rewrite-macros
+ unsigned Pedantic : 1; /// -pedantic
+ unsigned PedanticErrors : 1; /// -pedantic-errors
unsigned ShowColumn : 1; /// Show column number on diagnostics.
unsigned ShowLocation : 1; /// Show source location information.
unsigned ShowCarets : 1; /// Show carets in diagnostics.
@@ -27,20 +31,36 @@ public:
unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable
/// diagnostics.
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
+ unsigned VerifyDiagnostics; /// Check that diagnostics match the expected
+ /// diagnostics, indicated by markers in the
+ /// input source file.
/// Column limit for formatting message diagnostics, or 0 if unused.
unsigned MessageLength;
+ /// If non-empty, a file to log extended build information to, for development
+ /// testing and analysis.
+ std::string DumpBuildInformation;
+
+ /// The list of -W... options used to alter the diagnostic mappings, with the
+ /// prefixes removed.
+ std::vector<std::string> Warnings;
+
public:
DiagnosticOptions() {
- ShowColumn = 1;
- ShowLocation = 1;
+ IgnoreWarnings = 0;
+ MessageLength = 0;
+ NoRewriteMacros = 0;
+ Pedantic = 0;
+ PedanticErrors = 0;
ShowCarets = 1;
+ ShowColors = 0;
+ ShowColumn = 1;
ShowFixits = 1;
- ShowSourceRanges = 0;
+ ShowLocation = 1;
ShowOptionNames = 0;
- ShowColors = 0;
- MessageLength = 0;
+ ShowSourceRanges = 0;
+ VerifyDiagnostics = 0;
}
};
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
new file mode 100644
index 000000000000..469ea535f6aa
--- /dev/null
+++ b/include/clang/Frontend/FrontendAction.h
@@ -0,0 +1,215 @@
+//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <string>
+
+namespace llvm {
+class Timer;
+}
+
+namespace clang {
+class ASTUnit;
+class ASTConsumer;
+class CompilerInstance;
+
+/// FrontendAction - Abstract base class for actions which can be performed by
+/// the frontend.
+class FrontendAction {
+ std::string CurrentFile;
+ llvm::OwningPtr<ASTUnit> CurrentASTUnit;
+ CompilerInstance *Instance;
+ llvm::Timer *CurrentTimer;
+
+protected:
+ /// @name Implementation Action Interface
+ /// @{
+
+ /// CreateASTConsumer - Create the AST consumer object for this action, if
+ /// supported.
+ ///
+ /// This routine is called as part of \see BeginSourceAction(), which will
+ /// fail if the AST consumer cannot be created. This will not be called if the
+ /// action has indicated that it only uses the preprocessor.
+ ///
+ /// \param CI - The current compiler instance, provided as a convenience, \see
+ /// getCompilerInstance().
+ ///
+ /// \param InFile - The current input file, provided as a convenience, \see
+ /// getCurrentFile().
+ ///
+ /// \return The new AST consumer, or 0 on failure.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) = 0;
+
+ /// BeginSourceFileAction - Callback at the start of processing a single
+ /// input.
+ ///
+ /// \return True on success; on failure \see ExecutionAction() and
+ /// EndSourceFileAction() will not be called.
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename) {
+ return true;
+ }
+
+ /// ExecuteAction - Callback to run the program action, using the initialized
+ /// compiler instance.
+ ///
+ /// This routine is guaranteed to only be called between \see
+ /// BeginSourceFileAction() and \see EndSourceFileAction().
+ virtual void ExecuteAction() = 0;
+
+ /// EndSourceFileAction - Callback at the end of processing a single input;
+ /// this is guaranteed to only be called following a successful call to
+ /// BeginSourceFileAction (and BeingSourceFile).
+ virtual void EndSourceFileAction() {}
+
+ /// @}
+
+public:
+ FrontendAction();
+ virtual ~FrontendAction();
+
+ /// @name Compiler Instance Access
+ /// @{
+
+ CompilerInstance &getCompilerInstance() const {
+ assert(Instance && "Compiler instance not registered!");
+ return *Instance;
+ }
+
+ void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
+
+ /// @}
+ /// @name Current File Information
+ /// @{
+
+ bool isCurrentFileAST() const {
+ assert(!CurrentFile.empty() && "No current file!");
+ return CurrentASTUnit != 0;
+ }
+
+ const std::string &getCurrentFile() const {
+ assert(!CurrentFile.empty() && "No current file!");
+ return CurrentFile;
+ }
+
+ ASTUnit &getCurrentASTUnit() const {
+ assert(!CurrentASTUnit && "No current AST unit!");
+ return *CurrentASTUnit;
+ }
+
+ void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
+
+ /// @}
+ /// @name Timing Utilities
+ /// @{
+
+ llvm::Timer *getCurrentTimer() const {
+ return CurrentTimer;
+ }
+
+ void setCurrentTimer(llvm::Timer *Value) {
+ CurrentTimer = Value;
+ }
+
+ /// @}
+ /// @name Supported Modes
+ /// @{
+
+ /// usesPreprocessorOnly - Does this action only use the preprocessor? If so
+ /// no AST context will be created and this action will be invalid with PCH
+ /// inputs.
+ virtual bool usesPreprocessorOnly() const = 0;
+
+ /// usesCompleteTranslationUnit - For AST based actions, should the
+ /// translation unit be completed?
+ virtual bool usesCompleteTranslationUnit() { return true; }
+
+ /// hasPCHSupport - Does this action support use with PCH?
+ virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasASTSupport - Does this action support use with AST files?
+ virtual bool hasASTSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasCodeCompletionSupport - Does this action support use with code
+ /// completion?
+ virtual bool hasCodeCompletionSupport() const { return false; }
+
+ /// @}
+ /// @name Public Action Interface
+ /// @{
+
+ /// BeginSourceFile - Prepare the action for processing the input file \arg
+ /// Filename; this is run after the options and frontend have been
+ /// initialized, but prior to executing any per-file processing.
+ ///
+ /// \param CI - The compiler instance this action is being run from. The
+ /// action may store and use this object up until the matching EndSourceFile
+ /// action.
+ ///
+ /// \param Filename - The input filename, which will be made available to
+ /// clients via \see getCurrentFile().
+ ///
+ /// \param IsAST - Indicates whether this is an AST input. AST inputs require
+ /// special handling, since the AST file itself contains several objects which
+ /// would normally be owned by the CompilerInstance. When processing AST input
+ /// files, these objects should generally not be initialized in the
+ /// CompilerInstance -- they will automatically be shared with the AST file in
+ /// between \see BeginSourceFile() and \see EndSourceFile().
+ ///
+ /// \return True on success; the compilation of this file should be aborted
+ /// and neither Execute nor EndSourceFile should be called.
+ bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename,
+ bool IsAST = false);
+
+ /// Execute - Set the source managers main input file, and run the action.
+ void Execute();
+
+ /// EndSourceFile - Perform any per-file post processing, deallocate per-file
+ /// objects, and run statistics and output file cleanup code.
+ void EndSourceFile();
+
+ /// @}
+};
+
+/// ASTFrontendAction - Abstract base class to use for AST consumer based
+/// frontend actios.
+class ASTFrontendAction : public FrontendAction {
+ /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
+ /// the already initialized AST consumer.
+ ///
+ /// This will also take care of instantiating a code completion consumer if
+ /// the user requested it and the action supports it.
+ virtual void ExecuteAction();
+
+public:
+ virtual bool usesPreprocessorOnly() const { return false; }
+};
+
+/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
+/// based frontend actions.
+class PreprocessorFrontendAction : public FrontendAction {
+protected:
+ /// CreateASTConsumer - Provide a default implementation which returns aborts,
+ /// this method should never be called by FrontendAction clients.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ virtual bool usesPreprocessorOnly() const { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
new file mode 100644
index 000000000000..e755fe1b1b5f
--- /dev/null
+++ b/include/clang/Frontend/FrontendActions.h
@@ -0,0 +1,216 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+class FixItRewriter;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTPrintXMLAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTDumpAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTViewAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class DeclContextPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class DumpRecordAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class FixItAction : public ASTFrontendAction {
+private:
+ llvm::OwningPtr<FixItRewriter> Rewriter;
+
+protected:
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename);
+
+ virtual void EndSourceFileAction();
+
+ virtual bool hasASTSupport() const { return false; }
+
+public:
+ FixItAction();
+ ~FixItAction();
+};
+
+class GeneratePCHAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool usesCompleteTranslationUnit() { return false; }
+
+ virtual bool hasASTSupport() const { return false; }
+};
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class InheritanceViewAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class RewriteBlocksAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class SyntaxOnlyAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ virtual bool hasCodeCompletionSupport() const { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Code Gen AST Actions
+//===----------------------------------------------------------------------===//
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+ unsigned Act;
+
+protected:
+ CodeGenAction(unsigned _Act);
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+public:
+ EmitAssemblyAction();
+};
+
+class EmitBCAction : public CodeGenAction {
+public:
+ EmitBCAction();
+};
+
+class EmitLLVMAction : public CodeGenAction {
+public:
+ EmitLLVMAction();
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+public:
+ EmitLLVMOnlyAction();
+};
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+class DumpRawTokensAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class DumpTokensAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class GeneratePTHAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class ParseOnlyAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PreprocessOnlyAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PrintParseAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PrintPreprocessedAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+
+ virtual bool hasPCHSupport() const { return true; }
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
new file mode 100644
index 000000000000..197a2a05e5e0
--- /dev/null
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -0,0 +1,131 @@
+//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+
+#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+ enum ActionKind {
+ ASTDump, ///< Parse ASTs and dump them.
+ ASTPrint, ///< Parse ASTs and print them.
+ ASTPrintXML, ///< Parse ASTs and print them in XML.
+ ASTView, ///< Parse ASTs and view them in Graphviz.
+ DumpRawTokens, ///< Dump out raw tokens.
+ DumpRecordLayouts, ///< Dump record layout information.
+ DumpTokens, ///< Dump out preprocessed tokens.
+ EmitAssembly, ///< Emit a .s file.
+ EmitBC, ///< Emit a .bc file.
+ EmitHTML, ///< Translate input source into HTML.
+ EmitLLVM, ///< Emit a .ll file.
+ EmitLLVMOnly, ///< Generate LLVM IR, but do not
+ FixIt, ///< Parse and apply any fixits to the source.
+ GeneratePCH, ///< Generate pre-compiled header.
+ GeneratePTH, ///< Generate pre-tokenized header.
+ InheritanceView, ///< View C++ inheritance for a specified class.
+ ParseNoop, ///< Parse with noop callbacks.
+ ParsePrintCallbacks, ///< Parse and print each callback.
+ ParseSyntaxOnly, ///< Parse and perform semantic analysis.
+ PluginAction, ///< Run a plugin action, \see ActionName.
+ PrintDeclContext, ///< Print DeclContext and their Decls.
+ PrintPreprocessedInput, ///< -E mode.
+ RewriteBlocks, ///< ObjC->C Rewriter for Blocks.
+ RewriteMacros, ///< Expand macros but not #includes.
+ RewriteObjC, ///< ObjC->C Rewriter.
+ RewriteTest, ///< Rewriter playground
+ RunAnalysis, ///< Run one or more source code analyses.
+ RunPreprocessorOnly ///< Just lex, no output.
+ };
+}
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+ enum InputKind {
+ IK_None,
+ IK_Asm,
+ IK_C,
+ IK_CXX,
+ IK_ObjC,
+ IK_ObjCXX,
+ IK_PreprocessedC,
+ IK_PreprocessedCXX,
+ IK_PreprocessedObjC,
+ IK_PreprocessedObjCXX,
+ IK_OpenCL,
+ IK_AST
+ };
+
+ unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code
+ /// completion results.
+ unsigned DisableFree : 1; ///< Disable memory freeing on exit.
+ unsigned EmptyInputOnly : 1; ///< Force input files to be treated
+ /// as if they were empty, for timing
+ /// the frontend startup.
+ unsigned RelocatablePCH : 1; ///< When generating PCH files,
+ /// instruct the PCH writer to create
+ /// relocatable PCH files.
+ unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
+ /// results.
+ unsigned ShowStats : 1; ///< Show frontend performance
+ /// metrics and statistics.
+ unsigned ShowTimers : 1; ///< Show timers for individual
+ /// actions.
+
+ /// The input files and their types.
+ std::vector<std::pair<InputKind, std::string> > Inputs;
+
+ /// The output file, if any.
+ std::string OutputFile;
+
+ /// If given, the name for a C++ class to view the inheritance of.
+ std::string ViewClassInheritance;
+
+ /// A list of locations to apply fix-its at.
+ std::vector<ParsedSourceLocation> FixItLocations;
+
+ /// If given, enable code completion at the provided location.
+ ParsedSourceLocation CodeCompletionAt;
+
+ /// The frontend action to perform.
+ frontend::ActionKind ProgramAction;
+
+ /// The name of the action to run when using a plugin action.
+ std::string ActionName;
+
+public:
+ FrontendOptions() {
+ DebugCodeCompletionPrinter = 0;
+ DisableFree = 0;
+ EmptyInputOnly = 0;
+ ProgramAction = frontend::ParseSyntaxOnly;
+ ActionName = "";
+ RelocatablePCH = 0;
+ ShowMacrosInCodeCompletion = 0;
+ ShowStats = 0;
+ ShowTimers = 0;
+ }
+
+ /// getInputKindForExtension - Return the appropriate input kind for a file
+ /// extension. For example, "c" would return IK_C.
+ ///
+ /// \return The input kind for the extension, or IK_None if the extension is
+ /// not recognized.
+ static InputKind getInputKindForExtension(llvm::StringRef Extension);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
new file mode 100644
index 000000000000..8341492cfd23
--- /dev/null
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -0,0 +1,23 @@
+//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+
+/// The frontend plugin registry.
+typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
new file mode 100644
index 000000000000..2edc7e1f4ab4
--- /dev/null
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -0,0 +1,87 @@
+//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+#define LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+ /// IncludeDirGroup - Identifiers the group a include entry belongs to, which
+ /// represents its relative positive in the search list.
+ enum IncludeDirGroup {
+ Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`.
+ Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`)
+ System, ///< Like Angled, but marks system directories.
+ After ///< Like System, but searched after the system directories.
+ };
+}
+
+/// HeaderSearchOptions - Helper class for storing options related to the
+/// initialization of the HeaderSearch object.
+class HeaderSearchOptions {
+public:
+ struct Entry {
+ std::string Path;
+ frontend::IncludeDirGroup Group;
+ unsigned IsUserSupplied : 1;
+ unsigned IsFramework : 1;
+
+ Entry(llvm::StringRef _Path, frontend::IncludeDirGroup _Group,
+ bool _IsUserSupplied, bool _IsFramework)
+ : Path(_Path), Group(_Group), IsUserSupplied(_IsUserSupplied),
+ IsFramework(_IsFramework) {}
+ };
+
+ /// If non-empty, the directory to use as a "virtual system root" for include
+ /// paths.
+ std::string Sysroot;
+
+ /// User specified include entries.
+ std::vector<Entry> UserEntries;
+
+ /// A (system-path) delimited list of include paths to be added from the
+ /// environment following the user specified includes (but prior to builtin
+ /// and standard includes). This is parsed in the same manner as the CPATH
+ /// environment variable for gcc.
+ std::string EnvIncPath;
+
+ /// Per-language environmental include paths, see \see EnvIncPath.
+ std::string CEnvIncPath;
+ std::string ObjCEnvIncPath;
+ std::string CXXEnvIncPath;
+ std::string ObjCXXEnvIncPath;
+
+ /// If non-empty, the path to the compiler builtin include directory, which
+ /// will be searched following the user and environment includes.
+ std::string BuiltinIncludePath;
+
+ /// Include the system standard include search directories.
+ unsigned UseStandardIncludes : 1;
+
+ /// Whether header search information should be output as for -v.
+ unsigned Verbose : 1;
+
+public:
+ HeaderSearchOptions(llvm::StringRef _Sysroot = "")
+ : Sysroot(_Sysroot), UseStandardIncludes(true) {}
+
+ /// AddPath - Add the \arg Path path to the specified \arg Group list.
+ void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
+ bool IsUserSupplied, bool IsFramework) {
+ UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework));
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index cc8b3a03e3e8..85861fab4a22 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -29,6 +29,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/System/DataTypes.h"
#include <deque>
@@ -78,7 +79,7 @@ public:
/// \brief Receives the target triple.
///
/// \returns true to indicate the target triple is invalid or false otherwise.
- virtual bool ReadTargetTriple(const std::string &Triple) {
+ virtual bool ReadTargetTriple(llvm::StringRef Triple) {
return false;
}
@@ -87,18 +88,18 @@ public:
/// \param PCHPredef The start of the predefines buffer in the PCH
/// file.
///
- /// \param PCHPredefLen The length of the predefines buffer in the PCH
- /// file.
- ///
/// \param PCHBufferID The FileID for the PCH predefines buffer.
///
+ /// \param OriginalFileName The original file name for the PCH, which will
+ /// appear as an entry in the predefines buffer.
+ ///
/// \param SuggestedPredefines If necessary, additional definitions are added
/// here.
///
/// \returns true to indicate the predefines are invalid or false otherwise.
- virtual bool ReadPredefinesBuffer(const char *PCHPredef,
- unsigned PCHPredefLen,
+ virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
std::string &SuggestedPredefines) {
return false;
}
@@ -123,10 +124,10 @@ public:
: PP(PP), Reader(Reader), NumHeaderInfos(0) {}
virtual bool ReadLanguageOptions(const LangOptions &LangOpts);
- virtual bool ReadTargetTriple(const std::string &Triple);
- virtual bool ReadPredefinesBuffer(const char *PCHPredef,
- unsigned PCHPredefLen,
+ virtual bool ReadTargetTriple(llvm::StringRef Triple);
+ virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
std::string &SuggestedPredefines);
virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI);
virtual void ReadCounter(unsigned Value);
@@ -312,10 +313,13 @@ private:
/// the PCH file.
llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls;
- /// \brief The original file name that was used to build the PCH
- /// file.
+ /// \brief The original file name that was used to build the PCH file, which
+ /// may have been modified for relocatable-pch support.
std::string OriginalFileName;
+ /// \brief The actual original file name that was used to build the PCH file.
+ std::string ActualOriginalFileName;
+
/// \brief Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH;
@@ -444,9 +448,7 @@ private:
void MaybeAddSystemRootToFilename(std::string &Filename);
PCHReadResult ReadPCHBlock();
- bool CheckPredefinesBuffer(const char *PCHPredef,
- unsigned PCHPredefLen,
- FileID PCHBufferID);
+ bool CheckPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID);
bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record);
PCHReadResult ReadSourceManagerBlock();
PCHReadResult ReadSLocEntryRecord(unsigned ID);
@@ -625,13 +627,15 @@ public:
/// \brief Retrieve the IdentifierInfo for the named identifier.
///
- /// This routine builds a new IdentifierInfo for the given
- /// identifier. If any declarations with this name are visible from
- /// translation unit scope, their declarations will be deserialized
- /// and introduced into the declaration chain of the
- /// identifier. FIXME: if this identifier names a macro, deserialize
- /// the macro.
+ /// This routine builds a new IdentifierInfo for the given identifier. If any
+ /// declarations with this name are visible from translation unit scope, their
+ /// declarations will be deserialized and introduced into the declaration
+ /// chain of the identifier. FIXME: if this identifier names a macro,
+ /// deserialize the macro.
virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd);
+ IdentifierInfo* get(llvm::StringRef Name) {
+ return get(Name.begin(), Name.end());
+ }
/// \brief Load the contents of the global method pool for a given
/// selector.
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 22427eb67103..b520f4be1d31 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -52,7 +52,8 @@ struct UnsafeQualTypeDenseMapInfo {
return QualType::getFromOpaquePtr((void*) 2);
}
static inline unsigned getHashValue(QualType T) {
- assert(!T.getFastQualifiers() && "hash invalid for types with fast quals");
+ assert(!T.getLocalFastQualifiers() &&
+ "hash invalid for types with fast quals");
uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
}
diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h
new file mode 100644
index 000000000000..f0c1d3c2c38d
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -0,0 +1,57 @@
+//===--- PreprocessorOptionms.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class LangOptions;
+
+/// PreprocessorOptions - This class is used for passing the various options
+/// used in preprocessor initialization to InitializePreprocessor().
+class PreprocessorOptions {
+public:
+ std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+ std::vector<std::string> Includes;
+ std::vector<std::string> MacroIncludes;
+
+ unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
+ /// and target specific predefines.
+
+ /// The implicit PCH included at the start of the translation unit, or empty.
+ std::string ImplicitPCHInclude;
+
+ /// The implicit PTH input included at the start of the translation unit, or
+ /// empty.
+ std::string ImplicitPTHInclude;
+
+ /// If given, a PTH cache file to use for speeding up header parsing.
+ std::string TokenCache;
+
+public:
+ PreprocessorOptions() : UsePredefines(true) {}
+
+ void addMacroDef(llvm::StringRef Name) {
+ Macros.push_back(std::make_pair(Name, false));
+ }
+ void addMacroUndef(llvm::StringRef Name) {
+ Macros.push_back(std::make_pair(Name, true));
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
new file mode 100644
index 000000000000..a712a3d1bb05
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -0,0 +1,37 @@
+//===--- PreprocessorOutputOptions.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+
+namespace clang {
+
+/// PreprocessorOutputOptions - Options for controlling the C preprocessor
+/// output (e.g., -E).
+class PreprocessorOutputOptions {
+public:
+ unsigned ShowCPP : 1; ///< Print normal preprocessed output.
+ unsigned ShowMacros : 1; ///< Print macro definitions.
+ unsigned ShowLineMarkers : 1; ///< Show #line markers.
+ unsigned ShowComments : 1; ///< Show comments.
+ unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+
+public:
+ PreprocessorOutputOptions() {
+ ShowCPP = 1;
+ ShowMacros = 0;
+ ShowLineMarkers = 1;
+ ShowComments = 0;
+ ShowMacroComments = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 3c5c6267c632..d727e4800727 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -34,12 +34,15 @@ class TextDiagnosticPrinter : public DiagnosticClient {
SourceLocation LastWarningLoc;
FullSourceLoc LastLoc;
- bool LastCaretDiagnosticWasNote;
+ unsigned LastCaretDiagnosticWasNote : 1;
+ unsigned OwnsOutputStream : 1;
public:
- TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags);
+ TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags,
+ bool OwnsOutputStream = false);
+ virtual ~TextDiagnosticPrinter();
- void BeginSourceFile(const LangOptions &LO) {
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
LangOpts = &LO;
}
diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def
index 6aca15a75427..35f5debe5cf0 100644
--- a/include/clang/Frontend/TypeXML.def
+++ b/include/clang/Frontend/TypeXML.def
@@ -65,9 +65,9 @@
NODE_XML(QualType, "CvQualifiedType")
ID_ATTRIBUTE_XML
TYPE_ATTRIBUTE_XML(getTypePtr()) // the qualified type, e.g. for 'T* const' it's 'T*'
- ATTRIBUTE_OPT_XML(isConstQualified(), "const") // boolean
- ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile") // boolean
- ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict") // boolean
+ ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const") // boolean
+ ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile") // boolean
+ ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict") // boolean
ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc") // Qualifiers::GC
ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned
END_NODE_XML
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 3c670286545b..27c14c917015 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -1,4 +1,4 @@
-//===--- Utils.h - Misc utilities for the front-end------------------------===//
+//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,42 +14,57 @@
#ifndef LLVM_CLANG_FRONTEND_UTILS_H
#define LLVM_CLANG_FRONTEND_UTILS_H
+#include "llvm/ADT/StringRef.h"
#include <vector>
#include <string>
namespace llvm {
+class Triple;
class raw_ostream;
class raw_fd_ostream;
}
namespace clang {
-class Preprocessor;
-class MinimalAction;
-class TargetInfo;
-class Diagnostic;
class ASTConsumer;
+class Decl;
+class DependencyOutputOptions;
+class Diagnostic;
+class DiagnosticOptions;
+class HeaderSearch;
+class HeaderSearchOptions;
class IdentifierTable;
-class SourceManager;
class LangOptions;
-class Decl;
+class MinimalAction;
+class Preprocessor;
+class PreprocessorOptions;
+class PreprocessorOutputOptions;
+class SourceManager;
class Stmt;
+class TargetInfo;
+
+/// Normalize \arg File for use in a user defined #include directive (in the
+/// predefines buffer).
+std::string NormalizeDashIncludePath(llvm::StringRef File);
+
+/// Apply the header search options to get given HeaderSearch object.
+void ApplyHeaderSearchOptions(HeaderSearch &HS,
+ const HeaderSearchOptions &HSOpts,
+ const LangOptions &Lang,
+ const llvm::Triple &triple);
+
+/// InitializePreprocessor - Initialize the preprocessor getting it and the
+/// environment ready to process a single file.
+void InitializePreprocessor(Preprocessor &PP,
+ const PreprocessorOptions &PPOpts,
+ const HeaderSearchOptions &HSOpts);
/// ProcessWarningOptions - Initialize the diagnostic client and process the
/// warning options specified on the command line.
-bool ProcessWarningOptions(Diagnostic &Diags,
- std::vector<std::string> &Warnings,
- bool Pedantic, bool PedanticErrors,
- bool NoWarnings);
-
-/// DoPrintPreprocessedInput - Implement -E -dM mode.
-void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream* OS);
+bool ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS,
- bool EnableCommentOutput,
- bool EnableMacroCommentOutput,
- bool DisableLineMarkers,
- bool DumpDefines);
+ const PreprocessorOutputOptions &Opts);
/// RewriteMacrosInInput - Implement -rewrite-macros mode.
void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
@@ -67,13 +82,12 @@ bool CheckDiagnostics(Preprocessor &PP);
/// AttachDependencyFileGen - Create a dependency file generator, and attach
/// it to the given preprocessor. This takes ownership of the output stream.
-void AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS,
- std::vector<std::string> &Targets,
- bool IncludeSystemHeaders, bool PhonyTarget);
+void AttachDependencyFileGen(Preprocessor &PP,
+ const DependencyOutputOptions &Opts);
/// CacheTokens - Cache tokens for use with PCH. Note that this requires
/// a seekable stream.
-void CacheTokens(Preprocessor& PP, llvm::raw_fd_ostream* OS);
+void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
} // end namespace clang
diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h
new file mode 100644
index 000000000000..6f7ebbe537f9
--- /dev/null
+++ b/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -0,0 +1,82 @@
+//===-- VerifyDiagnosticsClient.h - Verifying Diagnostic Client -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+
+class Diagnostic;
+class SourceMgr;
+class TextDiagnosticBuffer;
+
+/// VerifyDiagnosticsClient - Create a diagnostic client which will use markers
+/// in the input source to check that all the emitted diagnostics match those
+/// expected.
+///
+/// USING THE DIAGNOSTIC CHECKER:
+///
+/// Indicating that a line expects an error or a warning is simple. Put a
+/// comment on the line that has the diagnostic, use "expected-{error,warning}"
+/// to tag if it's an expected error or warning, and place the expected text
+/// between {{ and }} markers. The full text doesn't have to be included, only
+/// enough to ensure that the correct diagnostic was emitted.
+///
+/// Here's an example:
+///
+/// int A = B; // expected-error {{use of undeclared identifier 'B'}}
+///
+/// You can place as many diagnostics on one line as you wish. To make the code
+/// more readable, you can use slash-newline to separate out the diagnostics.
+///
+/// The simple syntax above allows each specification to match exactly one
+/// error. You can use the extended syntax to customize this. The extended
+/// syntax is "expected-<type> <n> {{diag text}}", where <type> is one of
+/// "error", "warning" or "note", and <n> is a positive integer. This allows the
+/// diagnostic to appear as many times as specified. Example:
+///
+/// void f(); // expected-note 2 {{previous declaration is here}}
+///
+class VerifyDiagnosticsClient : public DiagnosticClient {
+public:
+ Diagnostic &Diags;
+ llvm::OwningPtr<DiagnosticClient> PrimaryClient;
+ llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
+ Preprocessor *CurrentPreprocessor;
+ unsigned NumErrors;
+
+private:
+ void CheckDiagnostics();
+
+public:
+ /// Create a new verifying diagnostic client, which will issue errors to \arg
+ /// PrimaryClient when a diagnostic does not match what is expected (as
+ /// indicated in the source file). The verifying diagnostic client takes
+ /// ownership of \arg PrimaryClient.
+ VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient);
+ ~VerifyDiagnosticsClient();
+
+ virtual void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP);
+
+ virtual void EndSourceFile();
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+
+ /// HadErrors - Check if there were any mismatches in expected diagnostics.
+ bool HadErrors();
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index ff1a17259e8a..ac5594e55d7d 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -119,8 +119,7 @@ public:
/// Create - This method creates PTHManager objects. The 'file' argument
/// is the name of the PTH file. This method returns NULL upon failure.
- static PTHManager *Create(const std::string& file, Diagnostic* Diags = 0,
- Diagnostic::Level failureLevel=Diagnostic::Warning);
+ static PTHManager *Create(const std::string& file, Diagnostic &Diags);
void setPreprocessor(Preprocessor *pp) { PP = pp; }
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 2783716b89ff..1c0036e3edcb 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -51,7 +51,7 @@ class DirectoryLookup;
class Preprocessor {
Diagnostic *Diags;
LangOptions Features;
- TargetInfo &Target;
+ const TargetInfo &Target;
FileManager &FileMgr;
SourceManager &SourceMgr;
ScratchBuffer *ScratchBuf;
@@ -94,6 +94,9 @@ class Preprocessor {
bool DisableMacroExpansion : 1; // True if macro expansion is disabled.
bool InMacroArgs : 1; // True if parsing fn macro invocation args.
+ /// Whether the preprocessor owns the header search object.
+ bool OwnsHeaderSearch : 1;
+
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
@@ -207,9 +210,11 @@ private: // Cached tokens state.
std::vector<CachedTokensTy::size_type> BacktrackPositions;
public:
- Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
+ Preprocessor(Diagnostic &diags, const LangOptions &opts,
+ const TargetInfo &target,
SourceManager &SM, HeaderSearch &Headers,
- IdentifierInfoLookup *IILookup = 0);
+ IdentifierInfoLookup *IILookup = 0,
+ bool OwnsHeaderSearch = false);
~Preprocessor();
@@ -217,7 +222,7 @@ public:
void setDiagnostics(Diagnostic &D) { Diags = &D; }
const LangOptions &getLangOptions() const { return Features; }
- TargetInfo &getTargetInfo() const { return Target; }
+ const TargetInfo &getTargetInfo() const { return Target; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
@@ -498,6 +503,15 @@ public:
/// UCNs, etc.
std::string getSpelling(const Token &Tok) const;
+ /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
+ /// token is the characters used to represent the token in the source file
+ /// after trigraph expansion and escaped-newline folding. In particular, this
+ /// wants to get the true, uncanonicalized, spelling of things like digraphs
+ /// UCNs, etc.
+ static std::string getSpelling(const Token &Tok,
+ const SourceManager &SourceMgr,
+ const LangOptions &Features);
+
/// getSpelling - This method is used to get the spelling of a token into a
/// preallocated buffer, instead of as an std::string. The caller is required
/// to allocate enough space for the token, which is guaranteed to be at least
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 8d910959b9fa..604eae1027aa 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -248,69 +248,6 @@ struct PPConditionalInfo {
bool FoundElse;
};
-/// TemplateIdAnnotation - Information about a template-id annotation
-/// token, which contains the template declaration, template
-/// arguments, whether those template arguments were types or
-/// expressions, and the source locations for important tokens. All of
-/// the information about template arguments is allocated directly
-/// after this structure.
-struct TemplateIdAnnotation {
- /// TemplateNameLoc - The location of the template name within the
- /// source.
- SourceLocation TemplateNameLoc;
-
- /// FIXME: Temporarily stores the name of a specialization
- IdentifierInfo *Name;
-
- /// FIXME: Temporarily stores the overloaded operator kind.
- OverloadedOperatorKind Operator;
-
- /// The declaration of the template corresponding to the
- /// template-name. This is an Action::DeclTy*.
- void *Template;
-
- /// The kind of template that Template refers to.
- TemplateNameKind Kind;
-
- /// The location of the '<' before the template argument
- /// list.
- SourceLocation LAngleLoc;
-
- /// The location of the '>' after the template argument
- /// list.
- SourceLocation RAngleLoc;
-
- /// NumArgs - The number of template arguments.
- unsigned NumArgs;
-
- /// \brief Retrieves a pointer to the template arguments
- void **getTemplateArgs() { return (void **)(this + 1); }
-
- /// \brief Retrieves a pointer to the array of template argument
- /// locations.
- SourceLocation *getTemplateArgLocations() {
- return (SourceLocation *)(getTemplateArgs() + NumArgs);
- }
-
- /// \brief Retrieves a pointer to the array of flags that states
- /// whether the template arguments are types.
- bool *getTemplateArgIsType() {
- return (bool *)(getTemplateArgLocations() + NumArgs);
- }
-
- static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
- TemplateIdAnnotation *TemplateId
- = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
- sizeof(void*) * NumArgs +
- sizeof(SourceLocation) * NumArgs +
- sizeof(bool) * NumArgs);
- TemplateId->NumArgs = NumArgs;
- return TemplateId;
- }
-
- void Destroy() { free(this); }
-};
-
} // end namespace clang
#endif
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 657a14fff082..a9b32133234a 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -1203,6 +1203,8 @@ public:
/// 'typename' keyword. FIXME: This will eventually be split into a
/// separate action.
///
+ /// \param TypenameLoc the location of the 'typename' keyword, if present
+ ///
/// \returns a representation of the using declaration.
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
@@ -1210,7 +1212,8 @@ public:
const CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
- bool IsTypeName);
+ bool IsTypeName,
+ SourceLocation TypenameLoc);
/// ActOnParamDefaultArgument - Parse default argument for function parameter
virtual void ActOnParamDefaultArgument(DeclPtrTy param,
@@ -1577,7 +1580,7 @@ public:
/// parameter.
virtual void ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParam,
SourceLocation EqualLoc,
- ExprArg Default) {
+ const ParsedTemplateArgument &Default) {
}
/// ActOnTemplateParameterList - Called when a complete template
@@ -1632,7 +1635,6 @@ public:
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc) {
return TypeResult();
};
@@ -1737,7 +1739,6 @@ public:
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc,
AttributeList *Attr,
MultiTemplateParamsArg TemplateParameterLists) {
@@ -1817,7 +1818,6 @@ public:
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc,
AttributeList *Attr) {
return DeclResult();
@@ -2105,6 +2105,7 @@ public:
virtual DeclPtrTy ActOnForwardClassDeclaration(
SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
+ SourceLocation *IdentLocs,
unsigned NumElts) {
return DeclPtrTy();
}
@@ -2329,6 +2330,47 @@ public:
///
/// \param S the scope in which the operator keyword occurs.
virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) { }
+
+ /// \brief Code completion for an ObjC message expression that refers to
+ /// a class method.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the class name.
+ ///
+ /// \param S the scope in which the message expression occurs.
+ /// \param FName the factory name.
+ /// \param FNameLoc the source location of the factory name.
+ virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
+ SourceLocation FNameLoc){ }
+
+ /// \brief Code completion for an ObjC message expression that refers to
+ /// an instance method.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the receiver expression.
+ ///
+ /// \param S the scope in which the operator keyword occurs.
+ /// \param Receiver an expression for the receiver of the message.
+ virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) { }
+
+ /// \brief Code completion for a list of protocol references in Objective-C,
+ /// such as P1 and P2 in \c id<P1,P2>.
+ ///
+ /// This code completion action is invoked prior to each identifier
+ /// in the protocol list.
+ ///
+ /// \param Protocols the set of protocols that have already been parsed.
+ ///
+ /// \param NumProtocols the number of protocols that have already been
+ /// parsed.
+ virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+ unsigned NumProtocols) { }
+
+ /// \brief Code completion for a protocol declaration or definition, after
+ /// the @protocol but before any identifier.
+ ///
+ /// \param S the scope in which the protocol declaration occurs.
+ virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
//@}
};
@@ -2398,6 +2440,7 @@ public:
virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
+ SourceLocation *SLocs,
unsigned NumElts);
virtual DeclPtrTy ActOnStartClassInterface(SourceLocation interLoc,
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 9fcc845cb006..81bb3007baea 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -57,6 +57,7 @@ public:
AT_analyzer_noreturn,
AT_annotate,
AT_blocks,
+ AT_cdecl,
AT_cleanup,
AT_const,
AT_constructor,
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index d539508e973b..7e7d0b3f28e8 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -25,7 +25,8 @@ namespace clang {
class IdentifierInfo;
class Preprocessor;
class Declarator;
-
+ struct TemplateIdAnnotation;
+
/// DeclSpec - This class captures information about "declaration specifiers",
/// which encompasses storage-class-specifiers, type-specifiers,
/// type-qualifiers, and function-specifiers.
@@ -642,13 +643,7 @@ public:
/// \param TemplateId the template-id annotation that describes the parsed
/// template-id. This UnqualifiedId instance will take ownership of the
/// \p TemplateId and will free it on destruction.
- void setTemplateId(TemplateIdAnnotation *TemplateId) {
- assert(TemplateId && "NULL template-id annotation?");
- Kind = IK_TemplateId;
- this->TemplateId = TemplateId;
- StartLocation = TemplateId->TemplateNameLoc;
- EndLocation = TemplateId->RAngleLoc;
- }
+ void setTemplateId(TemplateIdAnnotation *TemplateId);
/// \brief Return the source range that covers this unqualified-id.
SourceRange getSourceRange() const {
diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h
index 9bd69c5fdb68..5eb9635f06a1 100644
--- a/include/clang/Parse/Ownership.h
+++ b/include/clang/Parse/Ownership.h
@@ -654,41 +654,33 @@ namespace clang {
#endif
};
+ class ParsedTemplateArgument;
+
class ASTTemplateArgsPtr {
#if !defined(DISABLE_SMART_POINTERS)
ActionBase &Actions;
#endif
- void **Args;
- bool *ArgIsType;
+ ParsedTemplateArgument *Args;
mutable unsigned Count;
#if !defined(DISABLE_SMART_POINTERS)
- void destroy() {
- if (!Count)
- return;
-
- for (unsigned i = 0; i != Count; ++i)
- if (Args[i] && !ArgIsType[i])
- Actions.DeleteExpr((ActionBase::ExprTy *)Args[i]);
-
- Count = 0;
- }
+ void destroy();
#endif
-
+
public:
- ASTTemplateArgsPtr(ActionBase &actions, void **args, bool *argIsType,
+ ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args,
unsigned count) :
#if !defined(DISABLE_SMART_POINTERS)
Actions(actions),
#endif
- Args(args), ArgIsType(argIsType), Count(count) { }
+ Args(args), Count(count) { }
// FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
#if !defined(DISABLE_SMART_POINTERS)
Actions(Other.Actions),
#endif
- Args(Other.Args), ArgIsType(Other.ArgIsType), Count(Other.Count) {
+ Args(Other.Args), Count(Other.Count) {
#if !defined(DISABLE_SMART_POINTERS)
Other.Count = 0;
#endif
@@ -700,7 +692,6 @@ namespace clang {
Actions = Other.Actions;
#endif
Args = Other.Args;
- ArgIsType = Other.ArgIsType;
Count = Other.Count;
#if !defined(DISABLE_SMART_POINTERS)
Other.Count = 0;
@@ -712,22 +703,20 @@ namespace clang {
~ASTTemplateArgsPtr() { destroy(); }
#endif
- void **getArgs() const { return Args; }
- bool *getArgIsType() const {return ArgIsType; }
+ ParsedTemplateArgument *getArgs() const { return Args; }
unsigned size() const { return Count; }
- void reset(void **args, bool *argIsType, unsigned count) {
+ void reset(ParsedTemplateArgument *args, unsigned count) {
#if !defined(DISABLE_SMART_POINTERS)
destroy();
#endif
Args = args;
- ArgIsType = argIsType;
Count = count;
}
- void *operator[](unsigned Arg) const { return Args[Arg]; }
+ const ParsedTemplateArgument &operator[](unsigned Arg) const;
- void **release() const {
+ ParsedTemplateArgument *release() const {
#if !defined(DISABLE_SMART_POINTERS)
Count = 0;
#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 1ca92edc9a8b..e7dabdbd5b66 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -114,7 +114,7 @@ public:
~Parser();
const LangOptions &getLang() const { return PP.getLangOptions(); }
- TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+ const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
Preprocessor &getPreprocessor() const { return PP; }
Action &getActions() const { return Actions; }
@@ -179,6 +179,8 @@ public:
/// the EOF was encountered.
bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+ DeclGroupPtrTy RetrievePendingObjCImpDecl();
+
private:
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
@@ -331,7 +333,7 @@ private:
/// either "commit the consumed tokens" or revert to the previously marked
/// token position. Example:
///
- /// TentativeParsingAction TPA;
+ /// TentativeParsingAction TPA(*this);
/// ConsumeToken();
/// ....
/// TPA.Revert();
@@ -783,6 +785,7 @@ private:
AttributeList *prefixAttrs = 0);
DeclPtrTy ObjCImpDecl;
+ llvm::SmallVector<DeclPtrTy, 4> PendingObjCImpDecl;
DeclPtrTy ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
DeclPtrTy ParseObjCAtEndDeclaration(SourceLocation atLoc);
@@ -1226,13 +1229,18 @@ private:
Parser &P;
CXXScopeSpec &SS;
bool EnteredScope;
+ bool CreatedScope;
public:
DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
- : P(p), SS(ss), EnteredScope(false) {}
+ : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
void EnterDeclaratorScope() {
assert(!EnteredScope && "Already entered the scope!");
assert(SS.isSet() && "C++ scope was not set!");
+
+ CreatedScope = true;
+ P.EnterScope(0); // Not a decl scope.
+
if (P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
SS.setScopeRep(0);
@@ -1245,6 +1253,8 @@ private:
assert(SS.isSet() && "C++ scope was cleared ?");
P.Actions.ActOnCXXExitDeclaratorScope(P.CurScope, SS);
}
+ if (CreatedScope)
+ P.ExitScope();
}
};
@@ -1347,9 +1357,7 @@ private:
DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
// C++ 14.3: Template arguments [temp.arg]
- typedef llvm::SmallVector<void *, 16> TemplateArgList;
- typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList;
- typedef llvm::SmallVector<SourceLocation, 16> TemplateArgLocationList;
+ typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
SourceLocation TemplateNameLoc,
@@ -1357,8 +1365,6 @@ private:
bool ConsumeLastToken,
SourceLocation &LAngleLoc,
TemplateArgList &TemplateArgs,
- TemplateArgIsTypeList &TemplateArgIsType,
- TemplateArgLocationList &TemplateArgLocations,
SourceLocation &RAngleLoc);
bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
@@ -1367,10 +1373,9 @@ private:
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
- bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
- TemplateArgIsTypeList &TemplateArgIsType,
- TemplateArgLocationList &TemplateArgLocations);
- void *ParseTemplateArgument(bool &ArgIsType);
+ bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+ ParsedTemplateArgument ParseTemplateTemplateArgument();
+ ParsedTemplateArgument ParseTemplateArgument();
DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd);
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
index 480b94f73f62..c6a1e53472c1 100644
--- a/include/clang/Parse/Scope.h
+++ b/include/clang/Parse/Scope.h
@@ -275,7 +275,8 @@ public:
AnyParent = Parent;
Depth = AnyParent ? AnyParent->Depth+1 : 0;
Flags = ScopeFlags;
-
+ WithinElse = false;
+
if (AnyParent) {
FnParent = AnyParent->FnParent;
BreakParent = AnyParent->BreakParent;
@@ -283,13 +284,10 @@ public:
ControlParent = AnyParent->ControlParent;
BlockParent = AnyParent->BlockParent;
TemplateParamParent = AnyParent->TemplateParamParent;
- WithinElse = AnyParent->WithinElse;
-
} else {
FnParent = BreakParent = ContinueParent = BlockParent = 0;
ControlParent = 0;
TemplateParamParent = 0;
- WithinElse = false;
}
// If this scope is a function or contains breaks/continues, remember it.
diff --git a/include/clang/Parse/Template.h b/include/clang/Parse/Template.h
new file mode 100644
index 000000000000..1f8ccfbf05c6
--- /dev/null
+++ b/include/clang/Parse/Template.h
@@ -0,0 +1,183 @@
+//===--- Template.h - Template Parsing Data Types -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides data structures that store the parsed representation of
+// templates.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_PARSE_TEMPLATE_H
+#define LLVM_CLANG_PARSE_TEMPLATE_H
+
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Ownership.h"
+#include <cassert>
+
+namespace clang {
+ /// \brief Represents the parsed form of a C++ template argument.
+ class ParsedTemplateArgument {
+ public:
+ /// \brief Describes the kind of template argument that was parsed.
+ enum KindType {
+ /// \brief A template type parameter, stored as a type.
+ Type,
+ /// \brief A non-type template parameter, stored as an expression.
+ NonType,
+ /// \brief A template template argument, stored as a template name.
+ Template
+ };
+
+ /// \brief Build an empty template argument. This template argument
+ ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+
+ /// \brief Create a template type argument or non-type template argument.
+ ///
+ /// \param Arg the template type argument or non-type template argument.
+ /// \param Loc the location of the type.
+ ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
+ : Kind(Kind), Arg(Arg), Loc(Loc) { }
+
+ /// \brief Create a template template argument.
+ ///
+ /// \param SS the C++ scope specifier that precedes the template name, if
+ /// any.
+ ///
+ /// \param Template the template to which this template template
+ /// argument refers.
+ ///
+ /// \param TemplateLoc the location of the template name.
+ ParsedTemplateArgument(const CXXScopeSpec &SS,
+ ActionBase::TemplateTy Template,
+ SourceLocation TemplateLoc)
+ : Kind(ParsedTemplateArgument::Template), Arg(Template.get()),
+ Loc(TemplateLoc), SS(SS) { }
+
+ /// \brief Determine whether the given template argument is invalid.
+ bool isInvalid() { return Arg == 0; }
+
+ /// \brief Determine what kind of template argument we have.
+ KindType getKind() const { return Kind; }
+
+ /// \brief Retrieve the template type argument's type.
+ ActionBase::TypeTy *getAsType() const {
+ assert(Kind == Type && "Not a template type argument");
+ return Arg;
+ }
+
+ /// \brief Retrieve the non-type template argument's expression.
+ ActionBase::ExprTy *getAsExpr() const {
+ assert(Kind == NonType && "Not a non-type template argument");
+ return Arg;
+ }
+
+ /// \brief Retrieve the template template argument's template name.
+ ActionBase::TemplateTy getAsTemplate() const {
+ assert(Kind == Template && "Not a template template argument");
+ return ActionBase::TemplateTy::make(Arg);
+ }
+
+ /// \brief Retrieve the location of the template argument.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Retrieve the nested-name-specifier that precedes the template
+ /// name in a template template argument.
+ const CXXScopeSpec &getScopeSpec() const {
+ assert(Kind == Template &&
+ "Only template template arguments can have a scope specifier");
+ return SS;
+ }
+
+ private:
+ KindType Kind;
+
+ /// \brief The actual template argument representation, which may be
+ /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an
+ /// expression), or an ActionBase::TemplateTy (for a template).
+ void *Arg;
+
+ /// \brief the location of the template argument.
+ SourceLocation Loc;
+
+ /// \brief The nested-name-specifier that can accompany a template template
+ /// argument.
+ CXXScopeSpec SS;
+ };
+
+ /// \brief Information about a template-id annotation
+ /// token.
+ ///
+ /// A template-id annotation token contains the template declaration,
+ /// template arguments, whether those template arguments were types,
+ /// expressions, or template names, and the source locations for important
+ /// tokens. All of the information about template arguments is allocated
+ /// directly after this structure.
+ struct TemplateIdAnnotation {
+ /// TemplateNameLoc - The location of the template name within the
+ /// source.
+ SourceLocation TemplateNameLoc;
+
+ /// FIXME: Temporarily stores the name of a specialization
+ IdentifierInfo *Name;
+
+ /// FIXME: Temporarily stores the overloaded operator kind.
+ OverloadedOperatorKind Operator;
+
+ /// The declaration of the template corresponding to the
+ /// template-name. This is an Action::TemplateTy.
+ void *Template;
+
+ /// The kind of template that Template refers to.
+ TemplateNameKind Kind;
+
+ /// The location of the '<' before the template argument
+ /// list.
+ SourceLocation LAngleLoc;
+
+ /// The location of the '>' after the template argument
+ /// list.
+ SourceLocation RAngleLoc;
+
+ /// NumArgs - The number of template arguments.
+ unsigned NumArgs;
+
+ /// \brief Retrieves a pointer to the template arguments
+ ParsedTemplateArgument *getTemplateArgs() {
+ return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
+ }
+
+ static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
+ TemplateIdAnnotation *TemplateId
+ = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
+ sizeof(ParsedTemplateArgument) * NumArgs);
+ TemplateId->NumArgs = NumArgs;
+ return TemplateId;
+ }
+
+ void Destroy() { free(this); }
+ };
+
+#if !defined(DISABLE_SMART_POINTERS)
+ inline void ASTTemplateArgsPtr::destroy() {
+ if (!Count)
+ return;
+
+ for (unsigned I = 0; I != Count; ++I)
+ if (Args[I].getKind() == ParsedTemplateArgument::NonType)
+ Actions.DeleteExpr(Args[I].getAsExpr());
+
+ Count = 0;
+ }
+#endif
+
+ inline const ParsedTemplateArgument &
+ ASTTemplateArgsPtr::operator[](unsigned Arg) const {
+ return Args[Arg];
+ }
+}
+
+#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 5b3522c9eb49..43ff6869184d 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <memory>
#include <string>
@@ -43,6 +44,10 @@ public:
/// \brief The different kinds of "chunks" that can occur within a code
/// completion string.
enum ChunkKind {
+ /// \brief The piece of text that the user is expected to type to
+ /// match the code-completion string, typically a keyword or the name of a
+ /// declarator or macro.
+ CK_TypedText,
/// \brief A piece of text that should be placed in the buffer, e.g.,
/// parentheses or a comma in a function call.
CK_Text,
@@ -55,7 +60,29 @@ public:
CK_Placeholder,
/// \brief A piece of text that describes something about the result but
/// should not be inserted into the buffer.
- CK_Informative
+ CK_Informative,
+ /// \brief A piece of text that describes the parameter that corresponds
+ /// to the code-completion location within a function call, message send,
+ /// macro invocation, etc.
+ CK_CurrentParameter,
+ /// \brief A left parenthesis ('(').
+ CK_LeftParen,
+ /// \brief A right parenthesis (')').
+ CK_RightParen,
+ /// \brief A left bracket ('[').
+ CK_LeftBracket,
+ /// \brief A right bracket (']').
+ CK_RightBracket,
+ /// \brief A left brace ('{').
+ CK_LeftBrace,
+ /// \brief A right brace ('}').
+ CK_RightBrace,
+ /// \brief A left angle bracket ('<').
+ CK_LeftAngle,
+ /// \brief A right angle bracket ('>').
+ CK_RightAngle,
+ /// \brief A comma separator (',').
+ CK_Comma
};
/// \brief One piece of the code completion string.
@@ -66,7 +93,7 @@ public:
union {
/// \brief The text string associated with a CK_Text, CK_Placeholder,
- /// or CK_Informative chunk.
+ /// CK_Informative, or CK_Comma chunk.
/// The string is owned by the chunk and will be deallocated
/// (with delete[]) when the chunk is destroyed.
const char *Text;
@@ -79,21 +106,22 @@ public:
Chunk() : Kind(CK_Text), Text(0) { }
- private:
- Chunk(ChunkKind Kind, const char *Text);
-
- public:
+ Chunk(ChunkKind Kind, llvm::StringRef Text = "");
+
/// \brief Create a new text chunk.
- static Chunk CreateText(const char *Text);
+ static Chunk CreateText(llvm::StringRef Text);
/// \brief Create a new optional chunk.
static Chunk CreateOptional(std::auto_ptr<CodeCompletionString> Optional);
/// \brief Create a new placeholder chunk.
- static Chunk CreatePlaceholder(const char *Placeholder);
+ static Chunk CreatePlaceholder(llvm::StringRef Placeholder);
/// \brief Create a new informative chunk.
- static Chunk CreateInformative(const char *Informative);
+ static Chunk CreateInformative(llvm::StringRef Informative);
+
+ /// \brief Create a new current-parameter chunk.
+ static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
/// \brief Destroy this chunk, deallocating any memory it owns.
void Destroy();
@@ -113,10 +141,28 @@ public:
typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator;
iterator begin() const { return Chunks.begin(); }
iterator end() const { return Chunks.end(); }
+ bool empty() const { return Chunks.empty(); }
+ unsigned size() const { return Chunks.size(); }
+
+ Chunk &operator[](unsigned I) {
+ assert(I < size() && "Chunk index out-of-range");
+ return Chunks[I];
+ }
+
+ const Chunk &operator[](unsigned I) const {
+ assert(I < size() && "Chunk index out-of-range");
+ return Chunks[I];
+ }
+
+ /// \brief Add a new typed-text chunk.
+ /// The text string will be copied.
+ void AddTypedTextChunk(llvm::StringRef Text) {
+ Chunks.push_back(Chunk(CK_TypedText, Text));
+ }
/// \brief Add a new text chunk.
/// The text string will be copied.
- void AddTextChunk(const char *Text) {
+ void AddTextChunk(llvm::StringRef Text) {
Chunks.push_back(Chunk::CreateText(Text));
}
@@ -127,24 +173,46 @@ public:
/// \brief Add a new placeholder chunk.
/// The placeholder text will be copied.
- void AddPlaceholderChunk(const char *Placeholder) {
+ void AddPlaceholderChunk(llvm::StringRef Placeholder) {
Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
}
/// \brief Add a new informative chunk.
/// The text will be copied.
- void AddInformativeChunk(const char *Text) {
+ void AddInformativeChunk(llvm::StringRef Text) {
Chunks.push_back(Chunk::CreateInformative(Text));
}
+
+ /// \brief Add a new current-parameter chunk.
+ /// The text will be copied.
+ void AddCurrentParameterChunk(llvm::StringRef CurrentParameter) {
+ Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
+ }
+
+ /// \brief Add a new chunk.
+ void AddChunk(Chunk C) { Chunks.push_back(C); }
/// \brief Retrieve a string representation of the code completion string,
/// which is mainly useful for debugging.
- std::string getAsString() const;
+ std::string getAsString() const;
+
+ /// \brief Serialize this code-completion string to the given stream.
+ void Serialize(llvm::raw_ostream &OS) const;
+
+ /// \brief Deserialize a code-completion string from the given string.
+ static CodeCompletionString *Deserialize(llvm::StringRef &Str);
};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const CodeCompletionString &CCS);
+
/// \brief Abstract interface for a consumer of code-completion
/// information.
class CodeCompleteConsumer {
+protected:
+ /// \brief Whether to include macros in the code-completion results.
+ bool IncludeMacros;
+
public:
/// \brief Captures a result of code completion.
struct Result {
@@ -291,23 +359,32 @@ public:
Sema &S) const;
};
+ CodeCompleteConsumer() : IncludeMacros(false) { }
+
+ explicit CodeCompleteConsumer(bool IncludeMacros)
+ : IncludeMacros(IncludeMacros) { }
+
+ /// \brief Whether the code-completion consumer wants to see macros.
+ bool includeMacros() const { return IncludeMacros; }
+
/// \brief Deregisters and destroys this code-completion consumer.
virtual ~CodeCompleteConsumer();
/// \name Code-completion callbacks
//@{
/// \brief Process the finalized code-completion results.
- virtual void ProcessCodeCompleteResults(Result *Results,
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
unsigned NumResults) { }
-
- /// \brief Process the set of overload candidates.
+
+ /// \param S the semantic-analyzer object for which code-completion is being
+ /// done.
///
/// \param CurrentArg the index of the current argument.
///
/// \param Candidates an array of overload candidates.
///
/// \param NumCandidates the number of overload candidates
- virtual void ProcessOverloadCandidates(unsigned CurrentArg,
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
unsigned NumCandidates) { }
//@}
@@ -316,24 +393,43 @@ public:
/// \brief A simple code-completion consumer that prints the results it
/// receives in a simple format.
class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
- /// \brief The semantic-analysis object to which this code-completion
- /// consumer is attached.
- Sema &SemaRef;
-
/// \brief The raw output stream.
llvm::raw_ostream &OS;
public:
/// \brief Create a new printing code-completion consumer that prints its
/// results to the given raw output stream.
- PrintingCodeCompleteConsumer(Sema &S, llvm::raw_ostream &OS)
- : SemaRef(S), OS(OS) { }
+ PrintingCodeCompleteConsumer(bool IncludeMacros,
+ llvm::raw_ostream &OS)
+ : CodeCompleteConsumer(IncludeMacros), OS(OS) { }
+
+ /// \brief Prints the finalized code-completion results.
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+ unsigned NumResults);
+
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates);
+};
+
+/// \brief A code-completion consumer that prints the results it receives
+/// in a format that is parsable by the CIndex library.
+class CIndexCodeCompleteConsumer : public CodeCompleteConsumer {
+ /// \brief The raw output stream.
+ llvm::raw_ostream &OS;
+
+public:
+ /// \brief Create a new CIndex code-completion consumer that prints its
+ /// results to the given raw output stream in a format readable to the CIndex
+ /// library.
+ CIndexCodeCompleteConsumer(bool IncludeMacros, llvm::raw_ostream &OS)
+ : CodeCompleteConsumer(IncludeMacros), OS(OS) { }
/// \brief Prints the finalized code-completion results.
- virtual void ProcessCodeCompleteResults(Result *Results,
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
unsigned NumResults);
- virtual void ProcessOverloadCandidates(unsigned CurrentArg,
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
unsigned NumCandidates);
};
diff --git a/include/clang/Sema/ParseAST.h b/include/clang/Sema/ParseAST.h
index 8a245d03cdaa..f6cff2a023e6 100644
--- a/include/clang/Sema/ParseAST.h
+++ b/include/clang/Sema/ParseAST.h
@@ -20,7 +20,7 @@ namespace clang {
class ASTContext;
class CodeCompleteConsumer;
class Sema;
-
+
/// \brief Parse the entire file specified, notifying the ASTConsumer as
/// the file is parsed.
///
@@ -30,11 +30,13 @@ namespace clang {
/// \param CompleteTranslationUnit When true, the parsed file is
/// considered to be a complete translation unit, and any
/// end-of-translation-unit wrapup will be performed.
+ ///
+ /// \param CompletionConsumer If given, an object to consume code completion
+ /// results.
void ParseAST(Preprocessor &pp, ASTConsumer *C,
ASTContext &Ctx, bool PrintStats = false,
bool CompleteTranslationUnit = true,
- CodeCompleteConsumer *(*CreateCodeCompleter)(Sema &, void *Data) = 0,
- void *CreateCodeCompleterData = 0);
+ CodeCompleteConsumer *CompletionConsumer = 0);
} // end namespace clang