aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-02-16 09:31:36 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-02-16 09:31:36 +0000
commitecb7e5c8afe929ee38155db94de6b084ec32a645 (patch)
tree53010172e19c77ea447bcd89e117cda052ab52e0 /include/clang
parent5044f5c816adfd5cba17f1adee1a10127296d0bf (diff)
downloadsrc-ecb7e5c8afe929ee38155db94de6b084ec32a645.tar.gz
src-ecb7e5c8afe929ee38155db94de6b084ec32a645.zip
Update clang to r96341.
Notes
Notes: svn path=/vendor/clang/dist/; revision=203955
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h46
-rw-r--r--include/clang/AST/ASTDiagnostic.h22
-rw-r--r--include/clang/AST/ASTImporter.h234
-rw-r--r--include/clang/AST/Attr.h78
-rw-r--r--include/clang/AST/CXXInheritance.h11
-rw-r--r--include/clang/AST/Decl.h377
-rw-r--r--include/clang/AST/DeclBase.h86
-rw-r--r--include/clang/AST/DeclCXX.h512
-rw-r--r--include/clang/AST/DeclObjC.h70
-rw-r--r--include/clang/AST/DeclTemplate.h53
-rw-r--r--include/clang/AST/DeclarationName.h12
-rw-r--r--include/clang/AST/Expr.h19
-rw-r--r--include/clang/AST/ExprCXX.h418
-rw-r--r--include/clang/AST/ExprObjC.h10
-rw-r--r--include/clang/AST/Stmt.h93
-rw-r--r--include/clang/AST/StmtCXX.h27
-rw-r--r--include/clang/AST/StmtNodes.def9
-rw-r--r--include/clang/AST/StmtVisitor.h1
-rw-r--r--include/clang/AST/Type.h170
-rw-r--r--include/clang/AST/TypeNodes.def5
-rw-r--r--include/clang/AST/UnresolvedSet.h116
-rw-r--r--include/clang/Analysis/Analyses/PrintfFormatString.h279
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h3
-rw-r--r--include/clang/Analysis/AnalysisContext.h (renamed from include/clang/Analysis/PathSensitive/AnalysisContext.h)33
-rw-r--r--include/clang/Analysis/Support/Optional.h12
-rw-r--r--include/clang/Basic/Builtins.def39
-rw-r--r--include/clang/Basic/Diagnostic.h27
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td29
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td3
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td11
-rw-r--r--include/clang/Basic/DiagnosticGroups.td6
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td15
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td152
-rw-r--r--include/clang/Basic/LangOptions.h14
-rw-r--r--include/clang/Basic/Linkage.h57
-rw-r--r--include/clang/Basic/PartialDiagnostic.h2
-rw-r--r--include/clang/Basic/SourceManager.h8
-rw-r--r--include/clang/Basic/Specifiers.h3
-rw-r--r--include/clang/Basic/TargetInfo.h19
-rw-r--r--include/clang/Basic/TokenKinds.def10
-rw-r--r--include/clang/Basic/Version.h6
-rw-r--r--include/clang/Checker/BugReporter/BugReporter.h (renamed from include/clang/Analysis/PathSensitive/BugReporter.h)12
-rw-r--r--include/clang/Checker/BugReporter/BugType.h (renamed from include/clang/Analysis/PathSensitive/BugType.h)1
-rw-r--r--include/clang/Checker/BugReporter/PathDiagnostic.h (renamed from include/clang/Analysis/PathDiagnostic.h)0
-rw-r--r--include/clang/Checker/Checkers/DereferenceChecker.h (renamed from include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h)0
-rw-r--r--include/clang/Checker/Checkers/LocalCheckers.h (renamed from include/clang/Analysis/LocalCheckers.h)6
-rw-r--r--include/clang/Checker/DomainSpecific/CocoaConventions.h40
-rw-r--r--include/clang/Checker/ManagerRegistry.h (renamed from include/clang/Analysis/ManagerRegistry.h)2
-rw-r--r--include/clang/Checker/PathSensitive/AnalysisManager.h (renamed from include/clang/Analysis/PathSensitive/AnalysisManager.h)6
-rw-r--r--include/clang/Checker/PathSensitive/BasicValueFactory.h (renamed from include/clang/Analysis/PathSensitive/BasicValueFactory.h)18
-rw-r--r--include/clang/Checker/PathSensitive/Checker.h (renamed from include/clang/Analysis/PathSensitive/Checker.h)6
-rw-r--r--include/clang/Checker/PathSensitive/CheckerVisitor.def (renamed from include/clang/Analysis/PathSensitive/CheckerVisitor.def)1
-rw-r--r--include/clang/Checker/PathSensitive/CheckerVisitor.h (renamed from include/clang/Analysis/PathSensitive/CheckerVisitor.h)19
-rw-r--r--include/clang/Checker/PathSensitive/ConstraintManager.h (renamed from include/clang/Analysis/PathSensitive/ConstraintManager.h)2
-rw-r--r--include/clang/Checker/PathSensitive/Environment.h (renamed from include/clang/Analysis/PathSensitive/Environment.h)4
-rw-r--r--include/clang/Checker/PathSensitive/ExplodedGraph.h (renamed from include/clang/Analysis/PathSensitive/ExplodedGraph.h)2
-rw-r--r--include/clang/Checker/PathSensitive/GRAuditor.h (renamed from include/clang/Analysis/PathSensitive/GRAuditor.h)0
-rw-r--r--include/clang/Checker/PathSensitive/GRBlockCounter.h (renamed from include/clang/Analysis/PathSensitive/GRBlockCounter.h)0
-rw-r--r--include/clang/Checker/PathSensitive/GRCoreEngine.h (renamed from include/clang/Analysis/PathSensitive/GRCoreEngine.h)10
-rw-r--r--include/clang/Checker/PathSensitive/GRExprEngine.h (renamed from include/clang/Analysis/PathSensitive/GRExprEngine.h)25
-rw-r--r--include/clang/Checker/PathSensitive/GRExprEngineBuilders.h (renamed from include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h)2
-rw-r--r--include/clang/Checker/PathSensitive/GRSimpleAPICheck.h (renamed from include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h)4
-rw-r--r--include/clang/Checker/PathSensitive/GRState.h (renamed from include/clang/Analysis/PathSensitive/GRState.h)29
-rw-r--r--include/clang/Checker/PathSensitive/GRStateTrait.h (renamed from include/clang/Analysis/PathSensitive/GRStateTrait.h)0
-rw-r--r--include/clang/Checker/PathSensitive/GRSubEngine.h (renamed from include/clang/Analysis/PathSensitive/GRSubEngine.h)2
-rw-r--r--include/clang/Checker/PathSensitive/GRTransferFuncs.h (renamed from include/clang/Analysis/PathSensitive/GRTransferFuncs.h)6
-rw-r--r--include/clang/Checker/PathSensitive/GRWorkList.h (renamed from include/clang/Analysis/PathSensitive/GRWorkList.h)2
-rw-r--r--include/clang/Checker/PathSensitive/MemRegion.h (renamed from include/clang/Analysis/PathSensitive/MemRegion.h)15
-rw-r--r--include/clang/Checker/PathSensitive/SVals.h (renamed from include/clang/Analysis/PathSensitive/SVals.h)4
-rw-r--r--include/clang/Checker/PathSensitive/SValuator.h (renamed from include/clang/Analysis/PathSensitive/SValuator.h)29
-rw-r--r--include/clang/Checker/PathSensitive/Store.h (renamed from include/clang/Analysis/PathSensitive/Store.h)80
-rw-r--r--include/clang/Checker/PathSensitive/SummaryManager.h57
-rw-r--r--include/clang/Checker/PathSensitive/SymbolManager.h (renamed from include/clang/Analysis/PathSensitive/SymbolManager.h)0
-rw-r--r--include/clang/Checker/PathSensitive/ValueManager.h (renamed from include/clang/Analysis/PathSensitive/ValueManager.h)14
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h5
-rw-r--r--include/clang/Driver/CC1Options.td32
-rw-r--r--include/clang/Driver/Driver.h28
-rw-r--r--include/clang/Driver/Options.td17
-rw-r--r--include/clang/Driver/Tool.h1
-rw-r--r--include/clang/Driver/ToolChain.h18
-rw-r--r--include/clang/Driver/Types.def1
-rw-r--r--include/clang/Frontend/ASTConsumers.h7
-rw-r--r--include/clang/Frontend/ASTUnit.h10
-rw-r--r--include/clang/Frontend/Analyses.def17
-rw-r--r--include/clang/Frontend/CompilerInstance.h74
-rw-r--r--include/clang/Frontend/DiagnosticOptions.h6
-rw-r--r--include/clang/Frontend/FrontendAction.h8
-rw-r--r--include/clang/Frontend/FrontendActions.h44
-rw-r--r--include/clang/Frontend/FrontendOptions.h4
-rw-r--r--include/clang/Frontend/PCHBitCodes.h12
-rw-r--r--include/clang/Frontend/PCHReader.h4
-rw-r--r--include/clang/Lex/Lexer.h3
-rw-r--r--include/clang/Lex/Token.h4
-rw-r--r--include/clang/Parse/Action.h17
-rw-r--r--include/clang/Parse/DeclSpec.h13
-rw-r--r--include/clang/Parse/Parser.h92
97 files changed, 2710 insertions, 1206 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index e5429bec143c..2ed9fd708018 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -27,6 +27,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include <vector>
@@ -46,6 +47,7 @@ namespace clang {
class SourceManager;
class TargetInfo;
// Decls
+ class DeclContext;
class CXXMethodDecl;
class CXXRecordDecl;
class Decl;
@@ -502,7 +504,8 @@ public:
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
- QualType getVectorType(QualType VectorType, unsigned NumElts);
+ QualType getVectorType(QualType VectorType, unsigned NumElts,
+ bool AltiVec, bool IsPixel);
/// getExtVectorType - Return the unique reference to an extended vector type
/// of the specified element type and size. VectorType must be a built-in
@@ -534,11 +537,11 @@ public:
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
- QualType getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl=0);
+ QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl* PrevDecl=0);
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
- QualType getTypedefType(TypedefDecl *Decl);
+ QualType getTypedefType(const TypedefDecl *Decl);
QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
QualType Replacement);
@@ -835,13 +838,23 @@ public:
return getTypeInfo(T).second;
}
+ /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
+ /// characters. This method does not work on incomplete types.
+ CharUnits getTypeAlignInChars(QualType T);
+ CharUnits getTypeAlignInChars(const Type *T);
+
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign
/// a data type.
unsigned getPreferredTypeAlign(const Type *T);
- unsigned getDeclAlignInBytes(const Decl *D, bool RefAsPointee = false);
+ /// getDeclAlign - Return a conservative estimate of the alignment of
+ /// the specified decl. Note that bitfields do not have a valid alignment, so
+ /// this method will assert on them.
+ /// If @p RefAsPointee, references are treated like their underlying type
+ /// (for alignof), else they're treated like pointers (for CodeGen).
+ CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false);
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
@@ -878,7 +891,7 @@ public:
unsigned CountSynthesizedIvars(const ObjCInterfaceDecl *OI);
unsigned CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD);
void CollectInheritedProtocols(const Decl *CDecl,
- llvm::SmallVectorImpl<ObjCProtocolDecl*> &Protocols);
+ llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
//===--------------------------------------------------------------------===//
// Type Operators
@@ -960,6 +973,20 @@ public:
NestedNameSpecifier *
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS);
+ /// \brief Retrieves the canonical representation of the given
+ /// calling convention.
+ CallingConv getCanonicalCallConv(CallingConv CC) {
+ if (CC == CC_C)
+ return CC_Default;
+ return CC;
+ }
+
+ /// \brief Determines whether two calling conventions name the same
+ /// calling convention.
+ bool isSameCallConv(CallingConv lcc, CallingConv rcc) {
+ return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc));
+ }
+
/// \brief Retrieves the "canonical" template name that refers to a
/// given template.
///
@@ -1187,6 +1214,15 @@ private:
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
+
+private:
+ // FIXME: This currently contains the set of StoredDeclMaps used
+ // by DeclContext objects. This probably should not be in ASTContext,
+ // but we include it here so that ASTContext can quickly deallocate them.
+ std::vector<void*> SDMs;
+ friend class DeclContext;
+ void *CreateStoredDeclsMap();
+ void ReleaseDeclContextMaps();
};
/// @brief Utility function for constructing a nullary selector.
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index abd36f7e5f0f..2d314913469e 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -1,4 +1,4 @@
-//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- C++ -*-===//
+//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,6 +22,26 @@ namespace clang {
NUM_BUILTIN_AST_DIAGNOSTICS
};
} // end namespace diag
+
+ /// \brief Diagnostic argument formatting function for diagnostics that
+ /// involve AST nodes.
+ ///
+ /// This function formats diagnostic arguments for various AST nodes,
+ /// including types, declaration names, nested name specifiers, and
+ /// declaration contexts, into strings that can be printed as part of
+ /// diagnostics. It is meant to be used as the argument to
+ /// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
+ /// pointer.
+ void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind,
+ intptr_t Val,
+ const char *Modifier,
+ unsigned ModLen,
+ const char *Argument,
+ unsigned ArgLen,
+ const Diagnostic::ArgumentValue *PrevArgs,
+ unsigned NumPrevArgs,
+ llvm::SmallVectorImpl<char> &Output,
+ void *Cookie);
} // end namespace clang
#endif
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
new file mode 100644
index 000000000000..f5f11ca83662
--- /dev/null
+++ b/include/clang/AST/ASTImporter.h
@@ -0,0 +1,234 @@
+//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- 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 ASTImporter class which imports AST nodes from one
+// context into another context.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
+#define LLVM_CLANG_AST_ASTIMPORTER_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class ASTContext;
+ class Decl;
+ class DeclContext;
+ class Diagnostic;
+ class Expr;
+ class FileManager;
+ class IdentifierInfo;
+ class NestedNameSpecifier;
+ class Stmt;
+ class TypeSourceInfo;
+
+ /// \brief Imports selected nodes from one AST context into another context,
+ /// merging AST nodes where appropriate.
+ class ASTImporter {
+ public:
+ typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
+
+ private:
+ /// \brief The contexts we're importing to and from.
+ ASTContext &ToContext, &FromContext;
+
+ /// \brief The file managers we're importing to and from.
+ FileManager &ToFileManager, &FromFileManager;
+
+ /// \brief The diagnostics object that we should use to emit diagnostics.
+ Diagnostic &Diags;
+
+ /// \brief Mapping from the already-imported types in the "from" context
+ /// to the corresponding types in the "to" context.
+ llvm::DenseMap<Type *, Type *> ImportedTypes;
+
+ /// \brief Mapping from the already-imported declarations in the "from"
+ /// context to the corresponding declarations in the "to" context.
+ llvm::DenseMap<Decl *, Decl *> ImportedDecls;
+
+ /// \brief Mapping from the already-imported statements in the "from"
+ /// context to the corresponding statements in the "to" context.
+ llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
+
+ /// \brief Mapping from the already-imported FileIDs in the "from" source
+ /// manager to the corresponding FileIDs in the "to" source manager.
+ llvm::DenseMap<unsigned, FileID> ImportedFileIDs;
+
+ /// \brief Imported, anonymous tag declarations that are missing their
+ /// corresponding typedefs.
+ llvm::SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
+
+ /// \brief Declaration (from, to) pairs that are known not to be equivalent
+ /// (which we have already complained about).
+ NonEquivalentDeclSet NonEquivalentDecls;
+
+ public:
+ ASTImporter(Diagnostic &Diags,
+ ASTContext &ToContext, FileManager &ToFileManager,
+ ASTContext &FromContext, FileManager &FromFileManager);
+
+ virtual ~ASTImporter();
+
+ /// \brief Import the given type from the "from" context into the "to"
+ /// context.
+ ///
+ /// \returns the equivalent type in the "to" context, or a NULL type if
+ /// an error occurred.
+ QualType Import(QualType FromT);
+
+ /// \brief Import the given type source information from the
+ /// "from" context into the "to" context.
+ ///
+ /// \returns the equivalent type source information in the "to"
+ /// context, or NULL if an error occurred.
+ TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
+
+ /// \brief Import the given declaration from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent declaration in the "to" context, or a NULL type
+ /// if an error occurred.
+ Decl *Import(Decl *FromD);
+
+ /// \brief Import the given declaration context from the "from"
+ /// AST context into the "to" AST context.
+ ///
+ /// \returns the equivalent declaration context in the "to"
+ /// context, or a NULL type if an error occurred.
+ DeclContext *ImportContext(DeclContext *FromDC);
+
+ /// \brief Import the given expression from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent expression in the "to" context, or NULL if
+ /// an error occurred.
+ Expr *Import(Expr *FromE);
+
+ /// \brief Import the given statement from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent statement in the "to" context, or NULL if
+ /// an error occurred.
+ Stmt *Import(Stmt *FromS);
+
+ /// \brief Import the given nested-name-specifier from the "from"
+ /// context into the "to" context.
+ ///
+ /// \returns the equivalent nested-name-specifier in the "to"
+ /// context, or NULL if an error occurred.
+ NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
+
+ /// \brief Import the given source location from the "from" context into
+ /// the "to" context.
+ ///
+ /// \returns the equivalent source location in the "to" context, or an
+ /// invalid source location if an error occurred.
+ SourceLocation Import(SourceLocation FromLoc);
+
+ /// \brief Import the given source range from the "from" context into
+ /// the "to" context.
+ ///
+ /// \returns the equivalent source range in the "to" context, or an
+ /// invalid source location if an error occurred.
+ SourceRange Import(SourceRange FromRange);
+
+ /// \brief Import the given declaration name from the "from"
+ /// context into the "to" context.
+ ///
+ /// \returns the equivalent declaration name in the "to" context,
+ /// or an empty declaration name if an error occurred.
+ DeclarationName Import(DeclarationName FromName);
+
+ /// \brief Import the given identifier from the "from" context
+ /// into the "to" context.
+ ///
+ /// \returns the equivalent identifier in the "to" context.
+ IdentifierInfo *Import(IdentifierInfo *FromId);
+
+ /// \brief Import the given file ID from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent file ID in the source manager of the "to"
+ /// context.
+ FileID Import(FileID);
+
+ /// \brief Cope with a name conflict when importing a declaration into the
+ /// given context.
+ ///
+ /// This routine is invoked whenever there is a name conflict while
+ /// importing a declaration. The returned name will become the name of the
+ /// imported declaration. By default, the returned name is the same as the
+ /// original name, leaving the conflict unresolve such that name lookup
+ /// for this name is likely to find an ambiguity later.
+ ///
+ /// Subclasses may override this routine to resolve the conflict, e.g., by
+ /// renaming the declaration being imported.
+ ///
+ /// \param Name the name of the declaration being imported, which conflicts
+ /// with other declarations.
+ ///
+ /// \param DC the declaration context (in the "to" AST context) in which
+ /// the name is being imported.
+ ///
+ /// \param IDNS the identifier namespace in which the name will be found.
+ ///
+ /// \param Decls the set of declarations with the same name as the
+ /// declaration being imported.
+ ///
+ /// \param NumDecls the number of conflicting declarations in \p Decls.
+ ///
+ /// \returns the name that the newly-imported declaration should have.
+ virtual DeclarationName HandleNameConflict(DeclarationName Name,
+ DeclContext *DC,
+ unsigned IDNS,
+ NamedDecl **Decls,
+ unsigned NumDecls);
+
+ /// \brief Retrieve the context that AST nodes are being imported into.
+ ASTContext &getToContext() const { return ToContext; }
+
+ /// \brief Retrieve the context that AST nodes are being imported from.
+ ASTContext &getFromContext() const { return FromContext; }
+
+ /// \brief Retrieve the file manager that AST nodes are being imported into.
+ FileManager &getToFileManager() const { return ToFileManager; }
+
+ /// \brief Retrieve the file manager that AST nodes are being imported from.
+ FileManager &getFromFileManager() const { return FromFileManager; }
+
+ /// \brief Retrieve the diagnostic formatter.
+ Diagnostic &getDiags() const { return Diags; }
+
+ /// \brief Report a diagnostic in the "to" context.
+ DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
+
+ /// \brief Report a diagnostic in the "from" context.
+ DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
+
+ /// \brief Return the set of declarations that we know are not equivalent.
+ NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
+
+ /// \brief Note that we have imported the "from" declaration by mapping it
+ /// to the (potentially-newly-created) "to" declaration.
+ ///
+ /// \returns \p To
+ Decl *Imported(Decl *From, Decl *To);
+
+ /// \brief Determine whether the given types are structurally
+ /// equivalent.
+ bool IsStructurallyEquivalent(QualType From, QualType To);
+ };
+}
+
+#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 03ab0f07020b..37225907c6de 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -18,7 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstring>
-#include <string>
#include <algorithm>
using llvm::dyn_cast;
@@ -96,7 +95,8 @@ public:
FIRST_TARGET_ATTRIBUTE,
DLLExport,
DLLImport,
- MSP430Interrupt
+ MSP430Interrupt,
+ X86ForceAlignArgPointer
};
private:
@@ -119,8 +119,7 @@ protected:
assert(Next == 0 && "Destroy didn't work");
}
public:
-
- void Destroy(ASTContext &C);
+ virtual void Destroy(ASTContext &C);
/// \brief Whether this attribute should be merged to new
/// declarations.
@@ -156,6 +155,18 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *) { return true; }
};
+
+class AttrWithString : public Attr {
+private:
+ const char *Str;
+ unsigned StrLen;
+protected:
+ AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
+ llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
+ void ReplaceString(ASTContext &C, llvm::StringRef newS);
+public:
+ virtual void Destroy(ASTContext &C);
+};
#define DEF_SIMPLE_ATTR(ATTR) \
class ATTR##Attr : public Attr { \
@@ -213,12 +224,12 @@ public:
static bool classof(const AlignedAttr *A) { return true; }
};
-class AnnotateAttr : public Attr {
- std::string Annotation;
+class AnnotateAttr : public AttrWithString {
public:
- AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
+ AnnotateAttr(ASTContext &C, llvm::StringRef ann)
+ : AttrWithString(Annotate, C, ann) {}
- const std::string& getAnnotation() const { return Annotation; }
+ llvm::StringRef getAnnotation() const { return getString(); }
virtual Attr* clone(ASTContext &C) const;
@@ -229,12 +240,12 @@ public:
static bool classof(const AnnotateAttr *A) { return true; }
};
-class AsmLabelAttr : public Attr {
- std::string Label;
+class AsmLabelAttr : public AttrWithString {
public:
- AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
+ AsmLabelAttr(ASTContext &C, llvm::StringRef L)
+ : AttrWithString(AsmLabel, C, L) {}
- const std::string& getLabel() const { return Label; }
+ llvm::StringRef getLabel() const { return getString(); }
virtual Attr* clone(ASTContext &C) const;
@@ -247,12 +258,12 @@ public:
DEF_SIMPLE_ATTR(AlwaysInline);
-class AliasAttr : public Attr {
- std::string Aliasee;
+class AliasAttr : public AttrWithString {
public:
- AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
+ AliasAttr(ASTContext &C, llvm::StringRef aliasee)
+ : AttrWithString(Alias, C, aliasee) {}
- const std::string& getAliasee() const { return Aliasee; }
+ llvm::StringRef getAliasee() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
@@ -321,12 +332,12 @@ DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
DEF_SIMPLE_ATTR(Final);
-class SectionAttr : public Attr {
- std::string Name;
+class SectionAttr : public AttrWithString {
public:
- SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
+ SectionAttr(ASTContext &C, llvm::StringRef N)
+ : AttrWithString(Section, C, N) {}
- const std::string& getName() const { return Name; }
+ llvm::StringRef getName() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
@@ -350,19 +361,9 @@ class NonNullAttr : public Attr {
unsigned* ArgNums;
unsigned Size;
public:
- NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
- ArgNums(0), Size(0) {
-
- if (size == 0) return;
- assert(arg_nums);
- ArgNums = new unsigned[size];
- Size = size;
- memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
- }
+ NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
- virtual ~NonNullAttr() {
- delete [] ArgNums;
- }
+ virtual void Destroy(ASTContext &C);
typedef const unsigned *iterator;
iterator begin() const { return ArgNums; }
@@ -379,15 +380,14 @@ public:
static bool classof(const NonNullAttr *A) { return true; }
};
-class FormatAttr : public Attr {
- std::string Type;
+class FormatAttr : public AttrWithString {
int formatIdx, firstArg;
public:
- FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
- Type(type), formatIdx(idx), firstArg(first) {}
+ FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
+ : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
- const std::string& getType() const { return Type; }
- void setType(llvm::StringRef type) { Type = type; }
+ llvm::StringRef getType() const { return getString(); }
+ void setType(ASTContext &C, llvm::StringRef type);
int getFormatIdx() const { return formatIdx; }
int getFirstArg() const { return firstArg; }
@@ -570,6 +570,8 @@ public:
static bool classof(const MSP430InterruptAttr *A) { return true; }
};
+DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+
#undef DEF_SIMPLE_ATTR
} // end namespace clang
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 1491b1edbbac..79a3022ee014 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -161,7 +161,8 @@ class CXXBasePaths {
void ComputeDeclsFound();
public:
- typedef std::list<CXXBasePath>::const_iterator paths_iterator;
+ typedef std::list<CXXBasePath>::iterator paths_iterator;
+ typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
typedef NamedDecl **decl_iterator;
/// BasePaths - Construct a new BasePaths structure to record the
@@ -175,8 +176,10 @@ public:
~CXXBasePaths() { delete [] DeclsFound; }
- paths_iterator begin() const { return Paths.begin(); }
- paths_iterator end() const { return Paths.end(); }
+ paths_iterator begin() { return Paths.begin(); }
+ paths_iterator end() { return Paths.end(); }
+ const_paths_iterator begin() const { return Paths.begin(); }
+ const_paths_iterator end() const { return Paths.end(); }
CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { return Paths.front(); }
@@ -206,7 +209,7 @@ public:
const RecordType* getDetectedVirtual() const {
return DetectedVirtual;
}
-
+
/// \brief Retrieve the type from which this base-paths search
/// began
CXXRecordDecl *getOrigin() const { return Origin; }
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 6d52b2b2bc91..07442896dc4b 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -19,6 +19,7 @@
#include "clang/AST/Redeclarable.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Linkage.h"
namespace clang {
class CXXTemporary;
@@ -75,8 +76,9 @@ public:
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TranslationUnitDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TranslationUnit; }
static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
}
@@ -194,23 +196,6 @@ public:
return DC->isRecord();
}
- /// \brief Describes the different kinds of linkage
- /// (C++ [basic.link], C99 6.2.2) that an entity may have.
- enum Linkage {
- /// \brief No linkage, which means that the entity is unique and
- /// can only be referred to from within its scope.
- NoLinkage = 0,
-
- /// \brief Internal linkage, which indicates that the entity can
- /// be referred to from within the translation unit (but not other
- /// translation units).
- InternalLinkage,
-
- /// \brief External linkage, which indicates that the entity can
- /// be referred to from other translation units.
- ExternalLinkage
- };
-
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;
@@ -221,10 +206,9 @@ public:
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
- static bool classof(const Decl *D) {
- return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamedDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
};
/// NamespaceDecl - Represent a C++ namespace.
@@ -301,8 +285,9 @@ public:
void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Namespace; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Namespace; }
static DeclContext *castToDeclContext(const NamespaceDecl *D) {
return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
}
@@ -326,10 +311,9 @@ public:
void setType(QualType newType) { DeclType = newType; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= ValueFirst && D->getKind() <= ValueLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ValueDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= ValueFirst && K <= ValueLast; }
};
/// \brief Represents a ValueDecl that came out of a declarator.
@@ -349,10 +333,11 @@ public:
SourceLocation getTypeSpecStartLoc() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= DeclaratorFirst && D->getKind() <= DeclaratorLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const DeclaratorDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= DeclaratorFirst && K <= DeclaratorLast;
+ }
};
/// \brief Structure used to store a statement, the constant value to
@@ -474,14 +459,142 @@ public:
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass S);
- virtual ~VarDecl();
virtual void Destroy(ASTContext& C);
+ virtual ~VarDecl();
+
+ virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
void setStorageClass(StorageClass SC) { SClass = SC; }
- virtual SourceRange getSourceRange() const;
+ void setThreadSpecified(bool T) { ThreadSpecified = T; }
+ bool isThreadSpecified() const {
+ return ThreadSpecified;
+ }
+
+ /// hasLocalStorage - Returns true if a variable with function scope
+ /// is a non-static local variable.
+ bool hasLocalStorage() const {
+ if (getStorageClass() == None)
+ return !isFileVarDecl();
+
+ // Return true for: Auto, Register.
+ // Return false for: Extern, Static, PrivateExtern.
+
+ return getStorageClass() <= Register;
+ }
+
+ /// hasExternStorage - Returns true if a variable has extern or
+ /// __private_extern__ storage.
+ bool hasExternalStorage() const {
+ return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
+ }
+
+ /// hasGlobalStorage - Returns true for all variables that do not
+ /// have local storage. This includs all global variables as well
+ /// as static variables declared within a function.
+ bool hasGlobalStorage() const { return !hasLocalStorage(); }
+
+ /// \brief Determines whether this variable is a variable with
+ /// external, C linkage.
+ bool isExternC() const;
+
+ /// isBlockVarDecl - Returns true for local variable declarations. Note that
+ /// this includes static variables inside of functions.
+ ///
+ /// void foo() { int x; static int y; extern int z; }
+ ///
+ bool isBlockVarDecl() const {
+ if (getKind() != Decl::Var)
+ return false;
+ if (const DeclContext *DC = getDeclContext())
+ return DC->getLookupContext()->isFunctionOrMethod();
+ return false;
+ }
+
+ /// \brief Determines whether this is a static data member.
+ ///
+ /// This will only be true in C++, and applies to, e.g., the
+ /// variable 'x' in:
+ /// \code
+ /// struct S {
+ /// static int x;
+ /// };
+ /// \endcode
+ bool isStaticDataMember() const {
+ // If it wasn't static, it would be a FieldDecl.
+ return getDeclContext()->isRecord();
+ }
+
+ virtual VarDecl *getCanonicalDecl();
+ const VarDecl *getCanonicalDecl() const {
+ return const_cast<VarDecl*>(this)->getCanonicalDecl();
+ }
+
+ enum DefinitionKind {
+ DeclarationOnly, ///< This declaration is only a declaration.
+ TentativeDefinition, ///< This declaration is a tentative definition.
+ Definition ///< This declaration is definitely a definition.
+ };
+
+ /// \brief Check whether this declaration is a definition. If this could be
+ /// a tentative definition (in C), don't check whether there's an overriding
+ /// definition.
+ DefinitionKind isThisDeclarationADefinition() const;
+
+ /// \brief Get the tentative definition that acts as the real definition in
+ /// a TU. Returns null if there is a proper definition available.
+ VarDecl *getActingDefinition();
+ const VarDecl *getActingDefinition() const {
+ return const_cast<VarDecl*>(this)->getActingDefinition();
+ }
+
+ /// \brief Determine whether this is a tentative definition of a
+ /// variable in C.
+ bool isTentativeDefinitionNow() const;
+
+ /// \brief Get the real (not just tentative) definition for this declaration.
+ VarDecl *getDefinition();
+ const VarDecl *getDefinition() const {
+ return const_cast<VarDecl*>(this)->getDefinition();
+ }
+
+ /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// definition of a static data member.
+ bool isOutOfLine() const;
+
+ /// \brief If this is a static data member, find its out-of-line definition.
+ VarDecl *getOutOfLineDefinition();
+
+ /// isFileVarDecl - Returns true for file scoped variable declaration.
+ bool isFileVarDecl() const {
+ if (getKind() != Decl::Var)
+ return false;
+ if (const DeclContext *Ctx = getDeclContext()) {
+ Ctx = Ctx->getLookupContext();
+ if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
+ return true;
+ }
+ if (isStaticDataMember())
+ return true;
+
+ return false;
+ }
+
+ /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// declaration it is attached to.
+ const Expr *getAnyInitializer() const {
+ const VarDecl *D;
+ return getAnyInitializer(D);
+ }
+ /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// declaration it is attached to. Also get that declaration.
+ const Expr *getAnyInitializer(const VarDecl *&D) const;
+
+ bool hasInit() const {
+ return !Init.isNull();
+ }
const Expr *getInit() const {
if (Init.isNull())
return 0;
@@ -521,7 +634,7 @@ public:
return StmtPtr;
}
- void setInit(ASTContext &C, Expr *I);
+ void setInit(Expr *I);
EvaluatedStmt *EnsureEvaluatedStmt() const {
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
@@ -614,17 +727,6 @@ public:
Eval->IsICE = IsICE;
}
- /// \brief Retrieve the definition of this variable, which may come
- /// from a previous declaration. Def will be set to the VarDecl that
- /// contains the initializer, and the result will be that
- /// initializer.
- const Expr *getDefinition(const VarDecl *&Def) const;
-
- void setThreadSpecified(bool T) { ThreadSpecified = T; }
- bool isThreadSpecified() const {
- return ThreadSpecified;
- }
-
void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
/// hasCXXDirectInitializer - If true, the initializer was a direct
@@ -648,67 +750,6 @@ public:
void setDeclaredInCondition(bool InCondition) {
DeclaredInCondition = InCondition;
}
-
- 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.
- bool hasLocalStorage() const {
- if (getStorageClass() == None)
- return !isFileVarDecl();
-
- // Return true for: Auto, Register.
- // Return false for: Extern, Static, PrivateExtern.
-
- return getStorageClass() <= Register;
- }
-
- /// hasExternStorage - Returns true if a variable has extern or
- /// __private_extern__ storage.
- bool hasExternalStorage() const {
- return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
- }
-
- /// hasGlobalStorage - Returns true for all variables that do not
- /// have local storage. This includs all global variables as well
- /// as static variables declared within a function.
- bool hasGlobalStorage() const { return !hasLocalStorage(); }
-
- /// isBlockVarDecl - Returns true for local variable declarations. Note that
- /// this includes static variables inside of functions.
- ///
- /// void foo() { int x; static int y; extern int z; }
- ///
- bool isBlockVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (const DeclContext *DC = getDeclContext())
- return DC->getLookupContext()->isFunctionOrMethod();
- return false;
- }
-
- /// \brief Determines whether this is a static data member.
- ///
- /// This will only be true in C++, and applies to, e.g., the
- /// variable 'x' in:
- /// \code
- /// struct S {
- /// static int x;
- /// };
- /// \endcode
- bool isStaticDataMember() const {
- return getDeclContext()->isRecord();
- }
-
- /// \brief Determine whether this is or was instantiated from an out-of-line
- /// definition of a static data member.
- bool isOutOfLine() const;
-
- /// \brief If this is a static data member, find its out-of-line definition.
- VarDecl *getOutOfLineDefinition();
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@@ -728,35 +769,11 @@ public:
/// data member of a class template, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
-
- /// isFileVarDecl - Returns true for file scoped variable declaration.
- bool isFileVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (const DeclContext *Ctx = getDeclContext()) {
- Ctx = Ctx->getLookupContext();
- if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
- return true;
- }
- if (isStaticDataMember())
- return true;
-
- return false;
- }
-
- /// \brief Determine whether this is a tentative definition of a
- /// variable in C.
- bool isTentativeDefinition(ASTContext &Context) const;
-
- /// \brief Determines whether this variable is a variable with
- /// external, C linkage.
- bool isExternC() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= VarFirst && D->getKind() <= VarLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const VarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= VarFirst && K <= VarLast; }
};
class ImplicitParamDecl : public VarDecl {
@@ -770,7 +787,8 @@ public:
QualType T);
// Implement isa/cast/dyncast/etc.
static bool classof(const ImplicitParamDecl *D) { return true; }
- static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == ImplicitParam; }
};
/// ParmVarDecl - Represent a parameter to a function.
@@ -876,10 +894,9 @@ public:
void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return (D->getKind() == ParmVar);
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ParmVarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ParmVar; }
};
/// FunctionDecl - An instance of this class is created to represent a
@@ -1096,8 +1113,6 @@ public:
unsigned getBuiltinID() const;
- unsigned getNumParmVarDeclsFromType() const;
-
// Iterator access to formal parameters.
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
@@ -1110,7 +1125,7 @@ public:
param_const_iterator param_end() const { return ParamInfo+param_size(); }
/// getNumParams - Return the number of parameters this function must have
- /// based on its functiontype. This is the length of the PararmInfo array
+ /// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
unsigned getNumParams() const;
@@ -1122,7 +1137,7 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
@@ -1267,8 +1282,7 @@ public:
/// be inserted.
///
/// \param TSK the kind of template specialization this is.
- void setFunctionTemplateSpecialization(ASTContext &Context,
- FunctionTemplateDecl *Template,
+ void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
@@ -1295,10 +1309,11 @@ public:
bool isOutOfLine() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= FunctionFirst && K <= FunctionLast;
+ }
static DeclContext *castToDeclContext(const FunctionDecl *D) {
return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
}
@@ -1347,11 +1362,20 @@ public:
Expr *getBitWidth() const { return BitWidth; }
void setBitWidth(Expr *BW) { BitWidth = BW; }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
+ /// getParent - Returns the parent of this field declaration, which
+ /// is the struct in which this method is defined.
+ const RecordDecl *getParent() const {
+ return cast<RecordDecl>(getDeclContext());
}
+
+ RecordDecl *getParent() {
+ return cast<RecordDecl>(getDeclContext());
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= FieldFirst && K <= FieldLast; }
};
/// EnumConstantDecl - An instance of this object exists for each enum constant
@@ -1385,8 +1409,9 @@ public:
void setInitVal(const llvm::APSInt &V) { Val = V; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == EnumConstant; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumConstantDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == EnumConstant; }
friend class StmtIteratorBase;
};
@@ -1418,10 +1443,9 @@ public:
void setTypeForDecl(Type *TD) { TypeForDecl = TD; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TypeFirst && D->getKind() <= TypeLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= TypeFirst && K <= TypeLast; }
};
@@ -1460,8 +1484,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Typedef; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypedefDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Typedef; }
};
class TypedefDecl;
@@ -1486,6 +1511,11 @@ private:
/// it is a declaration ("struct foo;").
bool IsDefinition : 1;
+ /// IsEmbeddedInDeclarator - True if this tag declaration is
+ /// "embedded" (i.e., defined or declared for the very first time)
+ /// in the syntax of a declarator,
+ bool IsEmbeddedInDeclarator : 1;
+
/// TypedefForAnonDecl - If a TagDecl is anonymous and part of a typedef,
/// this points to the TypedefDecl. Used for mangling.
TypedefDecl *TypedefForAnonDecl;
@@ -1502,6 +1532,7 @@ protected:
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
TagDeclKind = TK;
IsDefinition = false;
+ IsEmbeddedInDeclarator = false;
setPreviousDeclaration(PrevDecl);
}
@@ -1535,6 +1566,13 @@ public:
return IsDefinition;
}
+ bool isEmbeddedInDeclarator() const {
+ return IsEmbeddedInDeclarator;
+ }
+ void setEmbeddedInDeclarator(bool isInDeclarator) {
+ IsEmbeddedInDeclarator = isInDeclarator;
+ }
+
/// \brief Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
@@ -1557,7 +1595,9 @@ public:
/// specific TagDecl is defining declaration, not whether or not the
/// struct/union/class/enum type is defined. This method returns NULL if
/// there is no TagDecl that defines the struct/union/class/enum.
- TagDecl* getDefinition(ASTContext& C) const;
+ TagDecl* getDefinition() const;
+
+ void setDefinition(bool V) { IsDefinition = V; }
const char *getKindName() const {
return ElaboratedType::getNameForTagKind(getTagKind());
@@ -1583,10 +1623,9 @@ public:
void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefForAnonDecl = TDD; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TagFirst && D->getKind() <= TagLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TagDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= TagFirst && K <= TagLast; }
static DeclContext *castToDeclContext(const TagDecl *D) {
return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
@@ -1594,8 +1633,6 @@ public:
static TagDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
}
-
- void setDefinition(bool V) { IsDefinition = V; }
};
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
@@ -1641,7 +1678,7 @@ public:
/// declaration as being defined; it's enumerators have already been
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
- void completeDefinition(ASTContext &C, QualType NewType,
+ void completeDefinition(QualType NewType,
QualType PromotionType);
// enumerator_iterator - Iterates through the enumerators of this
@@ -1679,8 +1716,9 @@ public:
void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
- static bool classof(const Decl *D) { return D->getKind() == Enum; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Enum; }
};
@@ -1763,8 +1801,8 @@ public:
/// RecordDecl is defining declaration, not whether or not the record
/// type is defined. This method returns NULL if there is no RecordDecl
/// that defines the struct/union/tag.
- RecordDecl* getDefinition(ASTContext& C) const {
- return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
+ RecordDecl* getDefinition() const {
+ return cast_or_null<RecordDecl>(TagDecl::getDefinition());
}
// Iterator access to field members. The field iterator only visits
@@ -1787,12 +1825,13 @@ public:
/// completeDefinition - Notes that the definition of this type is
/// now complete.
- void completeDefinition(ASTContext& C);
+ void completeDefinition();
- static bool classof(const Decl *D) {
- return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const RecordDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= RecordFirst && K <= RecordLast;
+ }
};
class FileScopeAsmDecl : public Decl {
@@ -1807,10 +1846,9 @@ public:
StringLiteral *getAsmString() { return AsmString; }
void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
- static bool classof(const Decl *D) {
- return D->getKind() == FileScopeAsm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FileScopeAsmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
/// BlockDecl - This represents a block literal declaration, which is like an
@@ -1869,11 +1907,12 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Block; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const BlockDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Block; }
static DeclContext *castToDeclContext(const BlockDecl *D) {
return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 775bce2a15fc..a407a1627747 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -480,6 +480,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *) { return true; }
+ static bool classofKind(Kind K) { return true; }
static DeclContext *castToDeclContext(const Decl *);
static Decl *castFromDeclContext(const DeclContext *);
@@ -1020,17 +1021,43 @@ inline bool Decl::isTemplateParameter() const {
getKind() == TemplateTemplateParm;
}
+
+// Specialization selected when ToTy is not a known subclass of DeclContext.
+template <class ToTy,
+ bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
+struct cast_convert_decl_context {
+ static const ToTy *doit(const DeclContext *Val) {
+ return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
+ }
+
+ static ToTy *doit(DeclContext *Val) {
+ return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
+ }
+};
+
+// Specialization selected when ToTy is a known subclass of DeclContext.
+template <class ToTy>
+struct cast_convert_decl_context<ToTy, true> {
+ static const ToTy *doit(const DeclContext *Val) {
+ return static_cast<const ToTy*>(Val);
+ }
+
+ static ToTy *doit(DeclContext *Val) {
+ return static_cast<ToTy*>(Val);
+ }
+};
+
+
} // end clang.
namespace llvm {
-/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
-/// a specific Decl.
+/// isa<T>(DeclContext*)
template<class ToTy>
struct isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {
static bool doit(const ::clang::DeclContext &Val) {
- return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
+ return ToTy::classofKind(Val.getDeclKind());
}
};
template<class ToTy>
@@ -1038,6 +1065,34 @@ struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
: public isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {};
+/// cast<T>(DeclContext*)
+template<class ToTy>
+struct cast_convert_val<ToTy,
+ const ::clang::DeclContext,const ::clang::DeclContext> {
+ static const ToTy &doit(const ::clang::DeclContext &Val) {
+ return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+ }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
+ static ToTy &doit(::clang::DeclContext &Val) {
+ return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+ }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy,
+ const ::clang::DeclContext*, const ::clang::DeclContext*> {
+ static const ToTy *doit(const ::clang::DeclContext *Val) {
+ return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+ }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
+ static ToTy *doit(::clang::DeclContext *Val) {
+ return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+ }
+};
+
/// Implement cast_convert_val for Decl -> DeclContext conversions.
template<class FromTy>
struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
@@ -1067,31 +1122,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
}
};
-/// Implement cast_convert_val for DeclContext -> Decl conversions.
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {
- static ToTy &doit(const ::clang::DeclContext &Val) {
- return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
- : public cast_convert_val<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {};
-
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext*, const ::clang::DeclContext*> {
- static ToTy *doit(const ::clang::DeclContext *Val) {
- return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
- : public cast_convert_val<ToTy,
- const ::clang::DeclContext*,const ::clang::DeclContext*> {};
-
} // end namespace llvm
#endif
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 73ebf52d383b..0978c6da9d66 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -145,6 +145,10 @@ public:
/// class (or not).
bool isVirtual() const { return Virtual; }
+ /// \brief Determine whether this base class if a base of a class declared
+ /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
+ bool isBaseOfClass() const { return BaseOfClass; }
+
/// getAccessSpecifier - Returns the access specifier for this base
/// specifier. This is the actual base specifier as used for
/// semantic analysis, so the result can never be AS_none. To
@@ -174,115 +178,137 @@ public:
/// FIXME: This class will disappear once we've properly taught RecordDecl
/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
- /// UserDeclaredConstructor - True when this class has a
- /// user-declared constructor.
- bool UserDeclaredConstructor : 1;
- /// UserDeclaredCopyConstructor - True when this class has a
- /// user-declared copy constructor.
- bool UserDeclaredCopyConstructor : 1;
+ friend void TagDecl::startDefinition();
+
+ struct DefinitionData {
+ DefinitionData(CXXRecordDecl *D);
+
+ /// UserDeclaredConstructor - True when this class has a
+ /// user-declared constructor.
+ bool UserDeclaredConstructor : 1;
+
+ /// UserDeclaredCopyConstructor - True when this class has a
+ /// user-declared copy constructor.
+ bool UserDeclaredCopyConstructor : 1;
+
+ /// UserDeclaredCopyAssignment - True when this class has a
+ /// user-declared copy assignment operator.
+ bool UserDeclaredCopyAssignment : 1;
+
+ /// UserDeclaredDestructor - True when this class has a
+ /// user-declared destructor.
+ bool UserDeclaredDestructor : 1;
+
+ /// Aggregate - True when this class is an aggregate.
+ bool Aggregate : 1;
+
+ /// PlainOldData - True when this class is a POD-type.
+ bool PlainOldData : 1;
+
+ /// Empty - true when this class is empty for traits purposes,
+ /// i.e. has no data members other than 0-width bit-fields, has no
+ /// virtual function/base, and doesn't inherit from a non-empty
+ /// class. Doesn't take union-ness into account.
+ bool Empty : 1;
+
+ /// Polymorphic - True when this class is polymorphic, i.e. has at
+ /// least one virtual member or derives from a polymorphic class.
+ bool Polymorphic : 1;
+
+ /// Abstract - True when this class is abstract, i.e. has at least
+ /// one pure virtual function, (that can come from a base class).
+ bool Abstract : 1;
+
+ /// HasTrivialConstructor - True when this class has a trivial constructor.
+ ///
+ /// C++ [class.ctor]p5. A constructor is trivial if it is an
+ /// implicitly-declared default constructor and if:
+ /// * its class has no virtual functions and no virtual base classes, and
+ /// * all the direct base classes of its class have trivial constructors, and
+ /// * for all the nonstatic data members of its class that are of class type
+ /// (or array thereof), each such class has a trivial constructor.
+ bool HasTrivialConstructor : 1;
+
+ /// HasTrivialCopyConstructor - True when this class has a trivial copy
+ /// constructor.
+ ///
+ /// C++ [class.copy]p6. A copy constructor for class X is trivial
+ /// if it is implicitly declared and if
+ /// * class X has no virtual functions and no virtual base classes, and
+ /// * each direct base class of X has a trivial copy constructor, and
+ /// * for all the nonstatic data members of X that are of class type (or
+ /// array thereof), each such class type has a trivial copy constructor;
+ /// otherwise the copy constructor is non-trivial.
+ bool HasTrivialCopyConstructor : 1;
+
+ /// HasTrivialCopyAssignment - True when this class has a trivial copy
+ /// assignment operator.
+ ///
+ /// C++ [class.copy]p11. A copy assignment operator for class X is
+ /// trivial if it is implicitly declared and if
+ /// * class X has no virtual functions and no virtual base classes, and
+ /// * each direct base class of X has a trivial copy assignment operator, and
+ /// * for all the nonstatic data members of X that are of class type (or
+ /// array thereof), each such class type has a trivial copy assignment
+ /// operator;
+ /// otherwise the copy assignment operator is non-trivial.
+ bool HasTrivialCopyAssignment : 1;
+
+ /// HasTrivialDestructor - True when this class has a trivial destructor.
+ ///
+ /// C++ [class.dtor]p3. A destructor is trivial if it is an
+ /// implicitly-declared destructor and if:
+ /// * all of the direct base classes of its class have trivial destructors
+ /// and
+ /// * for all of the non-static data members of its class that are of class
+ /// type (or array thereof), each such class has a trivial destructor.
+ bool HasTrivialDestructor : 1;
+
+ /// ComputedVisibleConversions - True when visible conversion functions are
+ /// already computed and are available.
+ bool ComputedVisibleConversions : 1;
+
+ /// Bases - Base classes of this class.
+ /// FIXME: This is wasted space for a union.
+ CXXBaseSpecifier *Bases;
- /// UserDeclaredCopyAssignment - True when this class has a
- /// user-declared copy assignment operator.
- bool UserDeclaredCopyAssignment : 1;
+ /// NumBases - The number of base class specifiers in Bases.
+ unsigned NumBases;
- /// UserDeclaredDestructor - True when this class has a
- /// user-declared destructor.
- bool UserDeclaredDestructor : 1;
+ /// VBases - direct and indirect virtual base classes of this class.
+ CXXBaseSpecifier *VBases;
- /// Aggregate - True when this class is an aggregate.
- bool Aggregate : 1;
+ /// NumVBases - The number of virtual base class specifiers in VBases.
+ unsigned NumVBases;
- /// PlainOldData - True when this class is a POD-type.
- bool PlainOldData : 1;
+ /// Conversions - Overload set containing the conversion functions
+ /// of this C++ class (but not its inherited conversion
+ /// functions). Each of the entries in this overload set is a
+ /// CXXConversionDecl.
+ UnresolvedSet<4> Conversions;
- /// Empty - true when this class is empty for traits purposes, i.e. has no
- /// data members other than 0-width bit-fields, has no virtual function/base,
- /// and doesn't inherit from a non-empty class. Doesn't take union-ness into
- /// account.
- bool Empty : 1;
+ /// VisibleConversions - Overload set containing the conversion
+ /// functions of this C++ class and all those inherited conversion
+ /// functions that are visible in this class. Each of the entries
+ /// in this overload set is a CXXConversionDecl or a
+ /// FunctionTemplateDecl.
+ UnresolvedSet<4> VisibleConversions;
- /// Polymorphic - True when this class is polymorphic, i.e. has at least one
- /// virtual member or derives from a polymorphic class.
- bool Polymorphic : 1;
+ /// Definition - The declaration which defines this record.
+ CXXRecordDecl *Definition;
- /// Abstract - True when this class is abstract, i.e. has at least one
- /// pure virtual function, (that can come from a base class).
- bool Abstract : 1;
+ } *DefinitionData;
- /// HasTrivialConstructor - True when this class has a trivial constructor.
- ///
- /// C++ [class.ctor]p5. A constructor is trivial if it is an
- /// implicitly-declared default constructor and if:
- /// * its class has no virtual functions and no virtual base classes, and
- /// * all the direct base classes of its class have trivial constructors, and
- /// * for all the nonstatic data members of its class that are of class type
- /// (or array thereof), each such class has a trivial constructor.
- bool HasTrivialConstructor : 1;
-
- /// HasTrivialCopyConstructor - True when this class has a trivial copy
- /// constructor.
- ///
- /// C++ [class.copy]p6. A copy constructor for class X is trivial
- /// if it is implicitly declared and if
- /// * class X has no virtual functions and no virtual base classes, and
- /// * each direct base class of X has a trivial copy constructor, and
- /// * for all the nonstatic data members of X that are of class type (or
- /// array thereof), each such class type has a trivial copy constructor;
- /// otherwise the copy constructor is non-trivial.
- bool HasTrivialCopyConstructor : 1;
-
- /// HasTrivialCopyAssignment - True when this class has a trivial copy
- /// assignment operator.
- ///
- /// C++ [class.copy]p11. A copy assignment operator for class X is
- /// trivial if it is implicitly declared and if
- /// * class X has no virtual functions and no virtual base classes, and
- /// * each direct base class of X has a trivial copy assignment operator, and
- /// * for all the nonstatic data members of X that are of class type (or
- /// array thereof), each such class type has a trivial copy assignment
- /// operator;
- /// otherwise the copy assignment operator is non-trivial.
- bool HasTrivialCopyAssignment : 1;
-
- /// HasTrivialDestructor - True when this class has a trivial destructor.
- ///
- /// C++ [class.dtor]p3. A destructor is trivial if it is an
- /// implicitly-declared destructor and if:
- /// * all of the direct base classes of its class have trivial destructors
- /// and
- /// * for all of the non-static data members of its class that are of class
- /// type (or array thereof), each such class has a trivial destructor.
- bool HasTrivialDestructor : 1;
-
- /// ComputedVisibleConversions - True when visible conversion functions are
- /// already computed and are available.
- bool ComputedVisibleConversions : 1;
-
- /// Bases - Base classes of this class.
- /// FIXME: This is wasted space for a union.
- CXXBaseSpecifier *Bases;
-
- /// NumBases - The number of base class specifiers in Bases.
- unsigned NumBases;
-
- /// VBases - direct and indirect virtual base classes of this class.
- CXXBaseSpecifier *VBases;
-
- /// NumVBases - The number of virtual base class specifiers in VBases.
- unsigned NumVBases;
-
- /// Conversions - Overload set containing the conversion functions
- /// of this C++ class (but not its inherited conversion
- /// functions). Each of the entries in this overload set is a
- /// CXXConversionDecl.
- UnresolvedSet<4> Conversions;
-
- /// VisibleConversions - Overload set containing the conversion functions
- /// of this C++ class and all those inherited conversion functions that
- /// are visible in this class. Each of the entries in this overload set is
- /// a CXXConversionDecl or a FunctionTemplateDecl.
- UnresolvedSet<4> VisibleConversions;
+ struct DefinitionData &data() {
+ assert(DefinitionData && "queried property of class with no definition");
+ return *DefinitionData;
+ }
+
+ const struct DefinitionData &data() const {
+ assert(DefinitionData && "queried property of class with no definition");
+ return *DefinitionData;
+ }
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@@ -336,6 +362,13 @@ public:
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+ CXXRecordDecl *getDefinition() const {
+ if (!DefinitionData) return 0;
+ return data().Definition;
+ }
+
+ bool hasDefinition() const { return DefinitionData != 0; }
+
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
@@ -345,21 +378,22 @@ public:
virtual void Destroy(ASTContext& C);
bool isDynamicClass() const {
- return Polymorphic || NumVBases != 0;
+ return data().Polymorphic || data().NumVBases != 0;
}
/// setBases - Sets the base classes of this struct or class.
- void setBases(ASTContext &C,
- CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+ void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// getNumBases - Retrieves the number of base classes of this
/// class.
- unsigned getNumBases() const { return NumBases; }
+ unsigned getNumBases() const { return data().NumBases; }
- base_class_iterator bases_begin() { return Bases; }
- base_class_const_iterator bases_begin() const { return Bases; }
- base_class_iterator bases_end() { return Bases + NumBases; }
- base_class_const_iterator bases_end() const { return Bases + NumBases; }
+ base_class_iterator bases_begin() { return data().Bases; }
+ base_class_const_iterator bases_begin() const { return data().Bases; }
+ base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
+ base_class_const_iterator bases_end() const {
+ return bases_begin() + data().NumBases;
+ }
reverse_base_class_iterator bases_rbegin() {
return reverse_base_class_iterator(bases_end());
}
@@ -375,12 +409,14 @@ public:
/// getNumVBases - Retrieves the number of virtual base classes of this
/// class.
- unsigned getNumVBases() const { return NumVBases; }
+ unsigned getNumVBases() const { return data().NumVBases; }
- base_class_iterator vbases_begin() { return VBases; }
- base_class_const_iterator vbases_begin() const { return VBases; }
- base_class_iterator vbases_end() { return VBases + NumVBases; }
- base_class_const_iterator vbases_end() const { return VBases + NumVBases; }
+ base_class_iterator vbases_begin() { return data().VBases; }
+ base_class_const_iterator vbases_begin() const { return data().VBases; }
+ base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
+ base_class_const_iterator vbases_end() const {
+ return vbases_begin() + data().NumVBases;
+ }
reverse_base_class_iterator vbases_rbegin() {
return reverse_base_class_iterator(vbases_end());
}
@@ -445,17 +481,14 @@ public:
/// user-declared constructors. When true, a default constructor
/// will not be implicitly declared.
bool hasUserDeclaredConstructor() const {
- assert((isDefinition() ||
- cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
- "Incomplete record decl!");
- return UserDeclaredConstructor;
+ return data().UserDeclaredConstructor;
}
/// hasUserDeclaredCopyConstructor - Whether this class has a
/// user-declared copy constructor. When false, a copy constructor
/// will be implicitly declared.
bool hasUserDeclaredCopyConstructor() const {
- return UserDeclaredCopyConstructor;
+ return data().UserDeclaredCopyConstructor;
}
/// addedAssignmentOperator - Notify the class that another assignment
@@ -467,45 +500,45 @@ public:
/// user-declared copy assignment operator. When false, a copy
/// assigment operator will be implicitly declared.
bool hasUserDeclaredCopyAssignment() const {
- return UserDeclaredCopyAssignment;
+ return data().UserDeclaredCopyAssignment;
}
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
- bool hasUserDeclaredDestructor() const { return UserDeclaredDestructor; }
+ bool hasUserDeclaredDestructor() const {
+ return data().UserDeclaredDestructor;
+ }
/// setUserDeclaredDestructor - Set whether this class has a
/// user-declared destructor. If not set by the time the class is
/// fully defined, a destructor will be implicitly declared.
void setUserDeclaredDestructor(bool UCD) {
- UserDeclaredDestructor = UCD;
+ data().UserDeclaredDestructor = UCD;
}
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
UnresolvedSetImpl *getConversionFunctions() {
- assert((this->isDefinition() ||
- cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
- "getConversionFunctions() called on incomplete type");
- return &Conversions;
+ return &data().Conversions;
}
const UnresolvedSetImpl *getConversionFunctions() const {
- assert((this->isDefinition() ||
- cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
- "getConversionFunctions() called on incomplete type");
- return &Conversions;
+ return &data().Conversions;
}
typedef UnresolvedSetImpl::iterator conversion_iterator;
- conversion_iterator conversion_begin() const { return Conversions.begin(); }
- conversion_iterator conversion_end() const { return Conversions.end(); }
+ conversion_iterator conversion_begin() const {
+ return getConversionFunctions()->begin();
+ }
+ conversion_iterator conversion_end() const {
+ return getConversionFunctions()->end();
+ }
/// Replaces a conversion function with a new declaration.
///
/// Returns true if the old conversion was found.
bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
- return Conversions.replace(Old, New);
+ return getConversionFunctions()->replace(Old, New);
}
/// getVisibleConversionFunctions - get all conversion functions visible
@@ -532,11 +565,11 @@ public:
/// [dcl.init.aggr]), which is a class with no user-declared
/// constructors, no private or protected non-static data members,
/// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
- bool isAggregate() const { return Aggregate; }
+ bool isAggregate() const { return data().Aggregate; }
/// setAggregate - Set whether this class is an aggregate (C++
/// [dcl.init.aggr]).
- void setAggregate(bool Agg) { Aggregate = Agg; }
+ void setAggregate(bool Agg) { data().Aggregate = Agg; }
/// setMethodAsVirtual - Make input method virtual and set the necesssary
/// special function bits and other bits accordingly.
@@ -546,66 +579,74 @@ public:
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
/// user-defined destructor.
- bool isPOD() const { return PlainOldData; }
+ bool isPOD() const { return data().PlainOldData; }
/// setPOD - Set whether this class is a POD-type (C++ [class]p4).
- void setPOD(bool POD) { PlainOldData = POD; }
+ void setPOD(bool POD) { data().PlainOldData = POD; }
/// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
/// means it has a virtual function, virtual base, data member (other than
/// 0-width bit-field) or inherits from a non-empty class. Does NOT include
/// a check for union-ness.
- bool isEmpty() const { return Empty; }
+ bool isEmpty() const { return data().Empty; }
/// Set whether this class is empty (C++0x [meta.unary.prop])
- void setEmpty(bool Emp) { Empty = Emp; }
+ void setEmpty(bool Emp) { data().Empty = Emp; }
/// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
- bool isPolymorphic() const { return Polymorphic; }
+ bool isPolymorphic() const { return data().Polymorphic; }
/// setPolymorphic - Set whether this class is polymorphic (C++
/// [class.virtual]).
- void setPolymorphic(bool Poly) { Polymorphic = Poly; }
+ void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
/// isAbstract - Whether this class is abstract (C++ [class.abstract]),
/// which means that the class contains or inherits a pure virtual function.
- bool isAbstract() const { return Abstract; }
+ bool isAbstract() const { return data().Abstract; }
/// setAbstract - Set whether this class is abstract (C++ [class.abstract])
- void setAbstract(bool Abs) { Abstract = Abs; }
+ void setAbstract(bool Abs) { data().Abstract = Abs; }
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
- bool hasTrivialConstructor() const { return HasTrivialConstructor; }
+ bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
// setHasTrivialConstructor - Set whether this class has a trivial constructor
// (C++ [class.ctor]p5)
- void setHasTrivialConstructor(bool TC) { HasTrivialConstructor = TC; }
+ void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
- bool hasTrivialCopyConstructor() const { return HasTrivialCopyConstructor; }
+ bool hasTrivialCopyConstructor() const {
+ return data().HasTrivialCopyConstructor;
+ }
// setHasTrivialCopyConstructor - Set whether this class has a trivial
// copy constructor (C++ [class.copy]p6)
- void setHasTrivialCopyConstructor(bool TC) { HasTrivialCopyConstructor = TC; }
+ void setHasTrivialCopyConstructor(bool TC) {
+ data().HasTrivialCopyConstructor = TC;
+ }
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
- bool hasTrivialCopyAssignment() const { return HasTrivialCopyAssignment; }
+ bool hasTrivialCopyAssignment() const {
+ return data().HasTrivialCopyAssignment;
+ }
// setHasTrivialCopyAssignment - Set whether this class has a
// trivial copy assignment operator (C++ [class.copy]p11)
- void setHasTrivialCopyAssignment(bool TC) { HasTrivialCopyAssignment = TC; }
+ void setHasTrivialCopyAssignment(bool TC) {
+ data().HasTrivialCopyAssignment = TC;
+ }
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
- bool hasTrivialDestructor() const { return HasTrivialDestructor; }
+ bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
// setHasTrivialDestructor - Set whether this class has a trivial destructor
// (C++ [class.dtor]p3)
- void setHasTrivialDestructor(bool TC) { HasTrivialDestructor = TC; }
+ void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
@@ -826,10 +867,11 @@ public:
return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
}
- static bool classof(const Decl *D) {
- return D->getKind() == CXXRecord ||
- D->getKind() == ClassTemplateSpecialization ||
- D->getKind() == ClassTemplatePartialSpecialization;
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == CXXRecord ||
+ K == ClassTemplateSpecialization ||
+ K == ClassTemplatePartialSpecialization;
}
static bool classof(const CXXRecordDecl *D) { return true; }
static bool classof(const ClassTemplateSpecializationDecl *D) {
@@ -911,10 +953,11 @@ public:
bool hasInlineBody() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXMethodDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= CXXMethod && K <= CXXConversion;
+ }
};
/// CXXBaseOrMemberInitializer - Represents a C++ base or member
@@ -939,9 +982,9 @@ class CXXBaseOrMemberInitializer {
/// \brief The source location for the field name.
SourceLocation MemberLocation;
- /// Args - The arguments used to initialize the base or member.
- Stmt **Args;
- unsigned NumArgs;
+ /// \brief The argument used to initialize the base or member, which may
+ /// end up constructing an object (when multiple arguments are involved).
+ Stmt *Init;
/// \brief Stores either the constructor to call to initialize this base or
/// member (a CXXConstructorDecl pointer), or stores the anonymous union of
@@ -961,7 +1004,7 @@ class CXXBaseOrMemberInitializer {
/// @endcode
/// In above example, BaseOrMember holds the field decl. for anonymous union
/// and AnonUnionMember holds field decl for au_i1.
- llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
+ FieldDecl *AnonUnionMember;
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@@ -973,30 +1016,22 @@ public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
- TypeSourceInfo *TInfo, CXXConstructorDecl *C,
+ TypeSourceInfo *TInfo,
SourceLocation L,
- Expr **Args, unsigned NumArgs,
+ Expr *Init,
SourceLocation R);
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
FieldDecl *Member, SourceLocation MemberLoc,
- CXXConstructorDecl *C, SourceLocation L,
- Expr **Args, unsigned NumArgs,
+ SourceLocation L,
+ Expr *Init,
SourceLocation R);
/// \brief Destroy the base or member initializer.
void Destroy(ASTContext &Context);
- /// arg_iterator - Iterates through the member initialization
- /// arguments.
- typedef ExprIterator arg_iterator;
-
- /// arg_const_iterator - Iterates through the member initialization
- /// arguments.
- typedef ConstExprIterator const_arg_iterator;
-
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
@@ -1046,32 +1081,16 @@ public:
SourceRange getSourceRange() const;
FieldDecl *getAnonUnionMember() const {
- return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
+ return AnonUnionMember;
}
void setAnonUnionMember(FieldDecl *anonMember) {
- CtorOrAnonUnion = anonMember;
- }
-
- const CXXConstructorDecl *getConstructor() const {
- return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
+ AnonUnionMember = anonMember;
}
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- /// arg_begin() - Retrieve an iterator to the first initializer argument.
- arg_iterator arg_begin() { return Args; }
- /// arg_begin() - Retrieve an iterator to the first initializer argument.
- const_arg_iterator const_arg_begin() const { return Args; }
-
- /// arg_end() - Retrieve an iterator past the last initializer argument.
- arg_iterator arg_end() { return Args + NumArgs; }
- /// arg_end() - Retrieve an iterator past the last initializer argument.
- const_arg_iterator const_arg_end() const { return Args + NumArgs; }
-
- /// getNumArgs - Determine the number of arguments used to
- /// initialize the member or base.
- unsigned getNumArgs() const { return NumArgs; }
+ Expr *getInit() { return static_cast<Expr *>(Init); }
};
/// CXXConstructorDecl - Represents a C++ constructor within a
@@ -1084,8 +1103,9 @@ public:
/// };
/// @endcode
class CXXConstructorDecl : public CXXMethodDecl {
- /// Explicit - Whether this constructor is explicit.
- bool Explicit : 1;
+ /// IsExplicitSpecified - Whether this constructor declaration has the
+ /// 'explicit' keyword specified.
+ bool IsExplicitSpecified : 1;
/// ImplicitlyDefined - Whether this constructor was implicitly
/// defined by the compiler. When false, the constructor was defined
@@ -1103,9 +1123,10 @@ class CXXConstructorDecl : public CXXMethodDecl {
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- bool isExplicit, bool isInline, bool isImplicitlyDeclared)
+ bool isExplicitSpecified, bool isInline,
+ bool isImplicitlyDeclared)
: CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
- Explicit(isExplicit), ImplicitlyDefined(false),
+ IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1118,8 +1139,15 @@ public:
bool isExplicit,
bool isInline, bool isImplicitlyDeclared);
+ /// isExplicitSpecified - Whether this constructor declaration has the
+ /// 'explicit' keyword specified.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
/// isExplicit - Whether this constructor was marked "explicit" or not.
- bool isExplicit() const { return Explicit; }
+ bool isExplicit() const {
+ return cast<CXXConstructorDecl>(getFirstDeclaration())
+ ->isExplicitSpecified();
+ }
/// isImplicitlyDefined - Whether this constructor was implicitly
/// defined. If false, then this constructor was defined by the
@@ -1212,10 +1240,9 @@ public:
bool isCopyConstructorLikeSpecialization() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == CXXConstructor;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConstructorDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXConstructor; }
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1274,10 +1301,9 @@ public:
const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == CXXDestructor;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXDestructorDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXDestructor; }
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1290,16 +1316,16 @@ public:
/// };
/// @endcode
class CXXConversionDecl : public CXXMethodDecl {
- /// Explicit - Whether this conversion function is marked
- /// "explicit", meaning that it can only be applied when the user
+ /// IsExplicitSpecified - Whether this conversion function declaration is
+ /// marked "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
- bool Explicit : 1;
+ bool IsExplicitSpecified : 1;
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicit)
+ bool isInline, bool isExplicitSpecified)
: CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
- Explicit(isExplicit) { }
+ IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@@ -1307,10 +1333,18 @@ public:
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit);
+ /// IsExplicitSpecified - Whether this conversion function declaration is
+ /// marked "explicit", meaning that it can only be applied when the user
+ /// explicitly wrote a cast. This is a C++0x feature.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
/// isExplicit - Whether this is an explicit conversion operator
/// (C++0x only). Explicit conversion operators are only considered
/// when the user has explicitly written a cast.
- bool isExplicit() const { return Explicit; }
+ bool isExplicit() const {
+ return cast<CXXConversionDecl>(getFirstDeclaration())
+ ->isExplicitSpecified();
+ }
/// getConversionType - Returns the type that this conversion
/// function is converting to.
@@ -1319,10 +1353,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == CXXConversion;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConversionDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXConversion; }
};
/// FriendDecl - Represents the declaration of a friend entity,
@@ -1391,10 +1424,9 @@ public:
void setSpecialization(bool WS) { WasSpecialization = WS; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::Friend;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FriendDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::Friend; }
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
@@ -1432,10 +1464,9 @@ public:
/// braces in its syntactic form.
bool hasBraces() const { return HadBraces; }
- static bool classof(const Decl *D) {
- return D->getKind() == LinkageSpec;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == LinkageSpec; }
static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
}
@@ -1537,10 +1568,9 @@ public:
NamedDecl *Nominated,
DeclContext *CommonAncestor);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UsingDirective;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDirectiveDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
// Friend for getUsingDirectiveName.
friend class DeclContext;
@@ -1598,6 +1628,16 @@ public:
return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
}
+ /// Returns the location of the alias name, i.e. 'foo' in
+ /// "namespace foo = ns::bar;".
+ SourceLocation getAliasLoc() const { return AliasLoc; }
+
+ /// Returns the location of the 'namespace' keyword.
+ SourceLocation getNamespaceLoc() const { return getLocation(); }
+
+ /// Returns the location of the identifier in the named namespace.
+ SourceLocation getTargetNameLoc() const { return IdentLoc; }
+
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
@@ -1610,10 +1650,9 @@ public:
SourceLocation IdentLoc,
NamedDecl *Namespace);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::NamespaceAlias;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceAliasDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
};
/// UsingShadowDecl - Represents a shadow declaration introduced into
@@ -1660,10 +1699,9 @@ public:
return Using;
}
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UsingShadow;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
};
/// UsingDecl - Represents a C++ using-declaration. For example:
@@ -1732,10 +1770,9 @@ public:
SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::Using;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::Using; }
};
/// UnresolvedUsingValueDecl - Represents a dependent using
@@ -1784,10 +1821,9 @@ public:
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, DeclarationName TargetName);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsingValue;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
};
/// UnresolvedUsingTypenameDecl - Represents a dependent using
@@ -1843,10 +1879,9 @@ public:
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, DeclarationName TargetName);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsingTypename;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
@@ -1872,10 +1907,9 @@ public:
virtual ~StaticAssertDecl();
virtual void Destroy(ASTContext& C);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::StaticAssert;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
};
/// Insertion operator for diagnostics. This allows sending AccessSpecifier's
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 0fb0db13bb57..e562d352e070 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -193,6 +193,9 @@ public:
ImplementationControl impControl = None);
virtual ObjCMethodDecl *getCanonicalDecl();
+ const ObjCMethodDecl *getCanonicalDecl() const {
+ return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
+ }
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
@@ -277,8 +280,9 @@ public:
bool isThisDeclarationADefinition() const { return Body; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCMethodDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCMethod; }
static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
}
@@ -383,11 +387,12 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= ObjCContainerFirst &&
- D->getKind() <= ObjCContainerLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCContainerDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= ObjCContainerFirst &&
+ K <= ObjCContainerLast;
+ }
static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
@@ -584,8 +589,9 @@ public:
Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(Type *TD) const { TypeForDecl = TD; }
- static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCInterfaceDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCInterface; }
};
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@@ -630,8 +636,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCIvarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCIvar; }
private:
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
@@ -657,8 +664,9 @@ public:
virtual void Destroy(ASTContext& C);
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
};
/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
@@ -749,8 +757,9 @@ public:
SourceLocation getLocEnd() const { return EndLoc; }
void setLocEnd(SourceLocation LE) { EndLoc = LE; }
- static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCProtocolDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCProtocol; }
};
/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
@@ -796,8 +805,9 @@ public:
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 Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCClassDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCClass; }
};
/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
@@ -846,10 +856,9 @@ public:
const SourceLocation *Locs, ASTContext &C) {
ReferencedProtocols.set(List, Num, Locs, C);
}
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCForwardProtocol;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCForwardProtocol; }
};
/// ObjCCategoryDecl - Represents a category declaration. A category allows
@@ -940,6 +949,8 @@ public:
ClassInterface->setCategoryList(this);
}
+ bool IsClassExtension() const { return getIdentifier() == 0; }
+
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation At) { AtLoc = At; }
@@ -950,8 +961,9 @@ public:
return SourceRange(AtLoc, getAtEndRange().getEnd());
}
- static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCategory; }
};
class ObjCImplDecl : public ObjCContainerDecl {
@@ -997,10 +1009,11 @@ public:
return propimpl_iterator(decls_end());
}
- static bool classof(const Decl *D) {
- return D->getKind() >= ObjCImplFirst && D->getKind() <= ObjCImplLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= ObjCImplFirst && K <= ObjCImplLast;
+ }
};
/// ObjCCategoryImplDecl - An object of this class encapsulates a category
@@ -1068,8 +1081,9 @@ public:
return getName();
}
- static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryImplDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
};
/// ObjCImplementationDecl - Represents a class definition - this is where
@@ -1152,10 +1166,9 @@ public:
return ivar_begin() == ivar_end();
}
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCImplementation;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplementationDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCImplementation; }
};
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
@@ -1176,10 +1189,9 @@ public:
ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCCompatibleAlias;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
};
@@ -1294,10 +1306,9 @@ public:
return PropertyIvarDecl;
}
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCProperty;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCProperty; }
};
/// ObjCPropertyImplDecl - Represents implementation declaration of a property
@@ -1354,10 +1365,9 @@ public:
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCPropertyImpl;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyImplDecl *D) { return true; }
+ static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
};
} // end namespace clang
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index d8b004a049ce..ced174716c7a 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -247,13 +247,14 @@ public:
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateDecl *D) { return true; }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= TemplateFirst && K <= TemplateLast;
+ }
protected:
NamedDecl *TemplatedDecl;
@@ -510,10 +511,9 @@ public:
NamedDecl *Decl);
// Implement isa/cast/dyncast support
- static bool classof(const Decl *D)
- { return D->getKind() == FunctionTemplate; }
- static bool classof(const FunctionTemplateDecl *D)
- { return true; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const FunctionTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == FunctionTemplate; }
};
//===----------------------------------------------------------------------===//
@@ -634,10 +634,9 @@ public:
bool isParameterPack() const { return ParameterPack; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == TemplateTypeParm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTypeParmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TemplateTypeParm; }
};
/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
@@ -682,10 +681,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == NonTypeTemplateParm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
};
/// TemplateTemplateParmDecl - Declares a template template parameter,
@@ -735,10 +733,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == TemplateTemplateParm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
};
/// \brief Represents a class template specialization, which refers to
@@ -903,9 +900,10 @@ public:
TemplateArgs[Arg].Profile(ID, Context);
}
- static bool classof(const Decl *D) {
- return D->getKind() == ClassTemplateSpecialization ||
- D->getKind() == ClassTemplatePartialSpecialization;
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == ClassTemplateSpecialization ||
+ K == ClassTemplatePartialSpecialization;
}
static bool classof(const ClassTemplateSpecializationDecl *) {
@@ -1039,8 +1037,9 @@ public:
// FIXME: Add Profile support!
- static bool classof(const Decl *D) {
- return D->getKind() == ClassTemplatePartialSpecialization;
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == ClassTemplatePartialSpecialization;
}
static bool classof(const ClassTemplatePartialSpecializationDecl *) {
@@ -1212,10 +1211,9 @@ public:
}
// Implement isa/cast/dyncast support
- static bool classof(const Decl *D)
- { return D->getKind() == ClassTemplate; }
- static bool classof(const ClassTemplateDecl *D)
- { return true; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const ClassTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ClassTemplate; }
virtual void Destroy(ASTContext& C);
};
@@ -1293,9 +1291,8 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::FriendTemplate;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
static bool classof(const FriendTemplateDecl *D) { return true; }
};
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 59d7e439e570..2254724410d0 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -274,30 +274,34 @@ public:
static DeclarationName getTombstoneMarker() {
return DeclarationName(uintptr_t(-2));
}
+
+ static int compare(DeclarationName LHS, DeclarationName RHS);
void dump() const;
};
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
-bool operator<(DeclarationName LHS, DeclarationName RHS);
+inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
+ return DeclarationName::compare(LHS, RHS) < 0;
+}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
- return RHS < LHS;
+ return DeclarationName::compare(LHS, RHS) > 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
- return !(RHS < LHS);
+ return DeclarationName::compare(LHS, RHS) <= 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
- return !(LHS < RHS);
+ return DeclarationName::compare(LHS, RHS) >= 0;
}
/// DeclarationNameTable - Used to store and retrieve DeclarationName
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 252781767169..114a19800f50 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -149,7 +149,8 @@ public:
LV_DuplicateVectorComponents,
LV_InvalidExpression,
LV_MemberFunction,
- LV_SubObjCPropertySetting
+ LV_SubObjCPropertySetting,
+ LV_SubObjCPropertyGetterSetting
};
isLvalueResult isLvalue(ASTContext &Ctx) const;
@@ -179,7 +180,8 @@ public:
MLV_ReadonlyProperty,
MLV_NoSetterProperty,
MLV_MemberFunction,
- MLV_SubObjCPropertySetting
+ MLV_SubObjCPropertySetting,
+ MLV_SubObjCPropertyGetterSetting
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
@@ -192,6 +194,9 @@ public:
return const_cast<Expr*>(this)->getBitField();
}
+ /// \brief Returns whether this expression refers to a vector element.
+ bool refersToVectorElement() const;
+
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
@@ -563,7 +568,10 @@ public:
enum IdentType {
Func,
Function,
- PrettyFunction
+ PrettyFunction,
+ /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
};
private:
@@ -584,8 +592,7 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- static std::string ComputeName(ASTContext &Context, IdentType IT,
- const Decl *CurrentDecl);
+ static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
@@ -1745,7 +1752,7 @@ public:
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
- if (SC >= ExplicitCastExprClass && SC <= CStyleCastExprClass)
+ if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
return true;
if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6ce95ac5227f..e4bc4b746439 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -241,10 +241,17 @@ public:
CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
Expr(CXXBoolLiteralExprClass, Ty, false, false), Value(val), Loc(l) {}
+ explicit CXXBoolLiteralExpr(EmptyShell Empty)
+ : Expr(CXXBoolLiteralExprClass, Empty) { }
+
bool getValue() const { return Value; }
+ void setValue(bool V) { Value = V; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBoolLiteralExprClass;
}
@@ -262,8 +269,14 @@ public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
Expr(CXXNullPtrLiteralExprClass, Ty, false, false), Loc(l) {}
+ explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
+ : Expr(CXXNullPtrLiteralExprClass, Empty) { }
+
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNullPtrLiteralExprClass;
}
@@ -544,6 +557,68 @@ public:
virtual child_iterator child_end();
};
+/// CXXBindReferenceExpr - Represents binding an expression to a reference.
+/// In the example:
+///
+/// const int &i = 10;
+///
+/// a bind reference expression is inserted to indicate that 10 is bound to
+/// a reference. (Ans also that a temporary needs to be created to hold the
+/// value).
+class CXXBindReferenceExpr : public Expr {
+ // SubExpr - The expression being bound.
+ Stmt *SubExpr;
+
+ // ExtendsLifetime - Whether binding this reference extends the lifetime of
+ // the expression being bound. FIXME: Add C++ reference.
+ bool ExtendsLifetime;
+
+ /// RequiresTemporaryCopy - Whether binding the subexpression requires a
+ /// temporary copy.
+ bool RequiresTemporaryCopy;
+
+ CXXBindReferenceExpr(Expr *subexpr, bool ExtendsLifetime,
+ bool RequiresTemporaryCopy)
+ : Expr(CXXBindReferenceExprClass, subexpr->getType(), false, false),
+ SubExpr(subexpr), ExtendsLifetime(ExtendsLifetime),
+ RequiresTemporaryCopy(RequiresTemporaryCopy) { }
+ ~CXXBindReferenceExpr() { }
+
+protected:
+ virtual void DoDestroy(ASTContext &C);
+
+public:
+ static CXXBindReferenceExpr *Create(ASTContext &C, Expr *SubExpr,
+ bool ExtendsLifetime,
+ bool RequiresTemporaryCopy);
+
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+ void setSubExpr(Expr *E) { SubExpr = E; }
+
+ virtual SourceRange getSourceRange() const {
+ return SubExpr->getSourceRange();
+ }
+
+ /// requiresTemporaryCopy - Whether binding the subexpression requires a
+ /// temporary copy.
+ bool requiresTemporaryCopy() const { return RequiresTemporaryCopy; }
+
+ // extendsLifetime - Whether binding this reference extends the lifetime of
+ // the expression being bound. FIXME: Add C++ reference.
+ bool extendsLifetime() { return ExtendsLifetime; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXBindReferenceExprClass;
+ }
+ static bool classof(const CXXBindReferenceExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
/// CXXConstructExpr - Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
CXXConstructorDecl *Constructor;
@@ -551,6 +626,7 @@ class CXXConstructExpr : public Expr {
SourceLocation Loc;
bool Elidable : 1;
bool ZeroInitialization : 1;
+ bool BaseInitialization : 1;
Stmt **Args;
unsigned NumArgs;
@@ -559,7 +635,8 @@ protected:
SourceLocation Loc,
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
- bool ZeroInitialization = false);
+ bool ZeroInitialization = false,
+ bool BaseInitialization = false);
~CXXConstructExpr() { }
virtual void DoDestroy(ASTContext &C);
@@ -573,7 +650,8 @@ public:
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
- bool ZeroInitialization = false);
+ bool ZeroInitialization = false,
+ bool BaseInitialization = false);
CXXConstructorDecl* getConstructor() const { return Constructor; }
@@ -593,6 +671,11 @@ public:
ZeroInitialization = ZeroInit;
}
+ /// \brief Determines whether this constructor is actually constructing
+ /// a base class (rather than a complete object).
+ bool isBaseInitialization() const { return BaseInitialization; }
+ void setBaseInitialization(bool BI) { BaseInitialization = BI; }
+
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
@@ -779,15 +862,14 @@ class CXXNewExpr : public Expr {
SourceLocation EndLoc;
public:
- CXXNewExpr(bool globalNew, FunctionDecl *operatorNew, Expr **placementArgs,
- unsigned numPlaceArgs, bool ParenTypeId, Expr *arraySize,
- CXXConstructorDecl *constructor, bool initializer,
+ CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+ Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+ Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
SourceLocation startLoc, SourceLocation endLoc);
- ~CXXNewExpr() {
- delete[] SubExprs;
- }
+
+ virtual void DoDestroy(ASTContext &C);
QualType getAllocatedType() const {
assert(getType()->isPointerType());
@@ -1059,33 +1141,123 @@ public:
virtual child_iterator child_end();
};
-/// \brief A reference to a name which we were able to look up during
-/// parsing but could not resolve to a specific declaration. This
-/// arises in several ways:
-/// * we might be waiting for argument-dependent lookup
-/// * the name might resolve to an overloaded function
-/// and eventually:
-/// * the lookup might have included a function template
-/// These never include UnresolvedUsingValueDecls, which are always
-/// class members and therefore appear only in
-/// UnresolvedMemberLookupExprs.
-class UnresolvedLookupExpr : public Expr {
+/// \brief A reference to an overloaded function set, either an
+/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
+class OverloadExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls.
+ /// include UsingShadowDecls. Access is relative to the naming
+ /// class.
UnresolvedSet<4> Results;
- /// The name declared.
+ /// The common name of these declarations.
DeclarationName Name;
- /// The qualifier given, if any.
+ /// The scope specifier, if any.
NestedNameSpecifier *Qualifier;
-
- /// The source range of the nested name specifier.
+
+ /// The source range of the scope specifier.
SourceRange QualifierRange;
/// The location of the name.
SourceLocation NameLoc;
+ /// True if the name was a template-id.
+ bool HasExplicitTemplateArgs;
+
+protected:
+ OverloadExpr(StmtClass K, QualType T, bool Dependent,
+ NestedNameSpecifier *Qualifier, SourceRange QRange,
+ DeclarationName Name, SourceLocation NameLoc,
+ bool HasTemplateArgs)
+ : Expr(K, T, Dependent, Dependent),
+ Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
+ NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
+ {}
+
+public:
+ /// Computes whether an unresolved lookup on the given declarations
+ /// and optional template arguments is type- and value-dependent.
+ static bool ComputeDependence(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End,
+ const TemplateArgumentListInfo *Args);
+
+ /// Finds the overloaded expression in the given expression of
+ /// OverloadTy.
+ ///
+ /// \return the expression (which must be there) and true if it is
+ /// within an address-of operator.
+ static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
+ assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
+
+ bool op = false;
+ E = E->IgnoreParens();
+ if (isa<UnaryOperator>(E))
+ op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+ return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
+ }
+
+ void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
+ Results.append(Begin, End);
+ }
+
+ typedef UnresolvedSetImpl::iterator decls_iterator;
+ decls_iterator decls_begin() const { return Results.begin(); }
+ decls_iterator decls_end() const { return Results.end(); }
+
+ /// Gets the decls as an unresolved set.
+ const UnresolvedSetImpl &getDecls() { return Results; }
+
+ /// Gets the number of declarations in the unresolved set.
+ unsigned getNumDecls() const { return Results.size(); }
+
+ /// Gets the name looked up.
+ DeclarationName getName() const { return Name; }
+ void setName(DeclarationName N) { Name = N; }
+
+ /// Gets the location of the name.
+ SourceLocation getNameLoc() const { return NameLoc; }
+ void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+
+ /// Fetches the nested-name qualifier, if one was given.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// Fetches the range of the nested-name qualifier.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Determines whether this expression had an explicit
+ /// template argument list, e.g. f<int>.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
+
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
+ }
+
+ ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (hasExplicitTemplateArgs())
+ return &getExplicitTemplateArgs();
+ return 0;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass ||
+ T->getStmtClass() == UnresolvedMemberExprClass;
+ }
+ static bool classof(const OverloadExpr *) { return true; }
+};
+
+/// \brief A reference to a name which we were able to look up during
+/// parsing but could not resolve to a specific declaration. This
+/// arises in several ways:
+/// * we might be waiting for argument-dependent lookup
+/// * the name might resolve to an overloaded function
+/// and eventually:
+/// * the lookup might have included a function template
+/// These never include UnresolvedUsingValueDecls, which are always
+/// class members and therefore appear only in
+/// UnresolvedMemberLookupExprs.
+class UnresolvedLookupExpr : public OverloadExpr {
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function
/// call.
@@ -1095,35 +1267,40 @@ class UnresolvedLookupExpr : public Expr {
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded;
- /// True if the name looked up had explicit template arguments.
- /// This requires all the results to be function templates.
- bool HasExplicitTemplateArgs;
+ /// The naming class (C++ [class.access.base]p5) of the lookup, if
+ /// any. This can generally be recalculated from the context chain,
+ /// but that can be fairly expensive for unqualified lookups. If we
+ /// want to improve memory use here, this could go in a union
+ /// against the qualified-lookup bits.
+ CXXRecordDecl *NamingClass;
- UnresolvedLookupExpr(QualType T, bool Dependent,
+ UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
- : Expr(UnresolvedLookupExprClass, T, Dependent, Dependent),
- Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
- NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded),
- HasExplicitTemplateArgs(HasTemplateArgs)
+ : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
+ Name, NameLoc, HasTemplateArgs),
+ RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
public:
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
+ CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
DeclarationName Name,
SourceLocation NameLoc,
bool ADL, bool Overloaded) {
return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
- Dependent, Qualifier, QualifierRange,
+ Dependent, NamingClass,
+ Qualifier, QualifierRange,
Name, NameLoc, ADL, Overloaded, false);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
+ CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
DeclarationName Name,
@@ -1131,20 +1308,6 @@ public:
bool ADL,
const TemplateArgumentListInfo &Args);
- /// Computes whether an unresolved lookup on the given declarations
- /// and optional template arguments is type- and value-dependent.
- static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
- UnresolvedSetImpl::const_iterator End,
- const TemplateArgumentListInfo *Args);
-
- void addDecl(NamedDecl *Decl) {
- Results.addDecl(Decl);
- }
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return Results.begin(); }
- decls_iterator decls_end() const { return Results.end(); }
-
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
@@ -1152,25 +1315,20 @@ public:
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
- /// Fetches the name looked up.
- DeclarationName getName() const { return Name; }
-
- /// Gets the location of the name.
- SourceLocation getNameLoc() const { return NameLoc; }
-
- /// Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
-
- /// Fetches the range of the nested-name qualifier.
- SourceRange getQualifierRange() const { return QualifierRange; }
-
- /// Determines whether this lookup had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+ /// Gets the 'naming class' (in the sense of C++0x
+ /// [class.access.base]p5) of the lookup. This is the scope
+ /// that was looked in to find these results.
+ CXXRecordDecl *getNamingClass() const { return NamingClass; }
// Note that, inconsistently with the explicit-template-argument AST
// nodes, users are *forbidden* from calling these methods on objects
// without explicit template arguments.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+ }
+
/// Gets a reference to the explicit template argument list.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
assert(hasExplicitTemplateArgs());
@@ -1200,8 +1358,8 @@ public:
}
virtual SourceRange getSourceRange() const {
- SourceRange Range(NameLoc);
- if (Qualifier) Range.setBegin(QualifierRange.getBegin());
+ SourceRange Range(getNameLoc());
+ if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
return Range;
}
@@ -1456,11 +1614,24 @@ public:
arg_iterator arg_begin() { return reinterpret_cast<Expr**>(this + 1); }
arg_iterator arg_end() { return arg_begin() + NumArgs; }
+ typedef const Expr* const * const_arg_iterator;
+ const_arg_iterator arg_begin() const {
+ return reinterpret_cast<const Expr* const *>(this + 1);
+ }
+ const_arg_iterator arg_end() const {
+ return arg_begin() + NumArgs;
+ }
+
Expr *getArg(unsigned I) {
assert(I < NumArgs && "Argument index out-of-range");
return *(arg_begin() + I);
}
+ const Expr *getArg(unsigned I) const {
+ assert(I < NumArgs && "Argument index out-of-range");
+ return *(arg_begin() + I);
+ }
+
virtual SourceRange getSourceRange() const {
return SourceRange(TyBeginLoc, RParenLoc);
}
@@ -1713,19 +1884,7 @@ public:
/// In the final AST, an explicit access always becomes a MemberExpr.
/// An implicit access may become either a MemberExpr or a
/// DeclRefExpr, depending on whether the member is static.
-class UnresolvedMemberExpr : public Expr {
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls.
- UnresolvedSet<4> Results;
-
- /// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f. This can be null if this is an 'unbased'
- /// member expression
- Stmt *Base;
-
- /// \brief The type of the base expression; never null.
- QualType BaseType;
-
+class UnresolvedMemberExpr : public OverloadExpr {
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
@@ -1734,39 +1893,17 @@ class UnresolvedMemberExpr : public Expr {
/// declaration.
bool HasUnresolvedUsing : 1;
- /// \brief Whether this member expression has explicitly-specified template
- /// arguments.
- bool HasExplicitTemplateArgs : 1;
+ /// \brief The expression for the base pointer or class reference,
+ /// e.g., the \c x in x.f. This can be null if this is an 'unbased'
+ /// member expression
+ Stmt *Base;
+
+ /// \brief The type of the base expression; never null.
+ QualType BaseType;
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- /// \brief The nested-name-specifier that precedes the member name, if any.
- NestedNameSpecifier *Qualifier;
-
- /// \brief The source range covering the nested name specifier.
- SourceRange QualifierRange;
-
- /// \brief The member to which this member expression refers, which
- /// can be a name or an overloaded operator.
- DeclarationName MemberName;
-
- /// \brief The location of the member name.
- SourceLocation MemberLoc;
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name.
- ExplicitTemplateArgumentList *getExplicitTemplateArgs() {
- assert(HasExplicitTemplateArgs);
- return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
- }
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const {
- return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs();
- }
-
UnresolvedMemberExpr(QualType T, bool Dependent,
bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
@@ -1788,19 +1925,6 @@ public:
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
- /// Adds a declaration to the unresolved set. By assumption, all of
- /// these happen at initialization time and properties like
- /// 'Dependent' and 'HasUnresolvedUsing' take them into account.
- void addDecl(NamedDecl *Decl) {
- Results.addDecl(Decl);
- }
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return Results.begin(); }
- decls_iterator decls_end() const { return Results.end(); }
-
- unsigned getNumDecls() const { return Results.size(); }
-
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
@@ -1812,6 +1936,10 @@ public:
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
+ const Expr *getBase() const {
+ assert(!isImplicitAccess());
+ return cast<Expr>(Base);
+ }
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
@@ -1825,57 +1953,60 @@ public:
SourceLocation getOperatorLoc() const { return OperatorLoc; }
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
- /// \brief Retrieve the nested-name-specifier that qualifies the member
- /// name.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
-
- /// \brief Retrieve the source range covering the nested-name-specifier
- /// that qualifies the member name.
- SourceRange getQualifierRange() const { return QualifierRange; }
+ /// \brief Retrieves the naming class of this lookup.
+ CXXRecordDecl *getNamingClass() const;
/// \brief Retrieve the name of the member that this expression
/// refers to.
- DeclarationName getMemberName() const { return MemberName; }
- void setMemberName(DeclarationName N) { MemberName = N; }
+ DeclarationName getMemberName() const { return getName(); }
+ void setMemberName(DeclarationName N) { setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
- SourceLocation getMemberLoc() const { return MemberLoc; }
- void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+ SourceLocation getMemberLoc() const { return getNameLoc(); }
+ void setMemberLoc(SourceLocation L) { setNameLoc(L); }
- /// \brief Determines whether this member expression actually had a C++
- /// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgs() const {
- return HasExplicitTemplateArgs;
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Copies the template arguments into the given structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- getExplicitTemplateArgs()->copyInto(List);
+ getExplicitTemplateArgs().copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following
/// the member name ('<').
SourceLocation getLAngleLoc() const {
- return getExplicitTemplateArgs()->LAngleLoc;
+ return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
- return getExplicitTemplateArgs()->getTemplateArgs();
+ return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as
/// part of this template-id.
unsigned getNumTemplateArgs() const {
- return getExplicitTemplateArgs()->NumTemplateArgs;
+ return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket
/// following the template arguments ('>').
SourceLocation getRAngleLoc() const {
- return getExplicitTemplateArgs()->RAngleLoc;
+ return getExplicitTemplateArgs().RAngleLoc;
}
virtual SourceRange getSourceRange() const {
@@ -1885,12 +2016,12 @@ public:
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
else
- Range.setBegin(MemberLoc);
+ Range.setBegin(getMemberLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
else
- Range.setEnd(MemberLoc);
+ Range.setEnd(getMemberLoc());
return Range;
}
@@ -1904,6 +2035,13 @@ public:
virtual child_iterator child_end();
};
+inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
+ if (isa<UnresolvedLookupExpr>(this))
+ return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
+ else
+ return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 0b0cd64ad721..df39b535eb3e 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -367,7 +367,7 @@ class ObjCMessageExpr : public Expr {
public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is not known.
- ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -375,13 +375,13 @@ public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is known.
// FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
// constructor for instance messages.
- ObjCMessageExpr(Expr *receiver, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -389,9 +389,7 @@ public:
explicit ObjCMessageExpr(EmptyShell Empty)
: Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
- ~ObjCMessageExpr() {
- delete [] SubExprs;
- }
+ virtual void DoDestroy(ASTContext &C);
/// getReceiver - Returns the receiver of the message expression.
/// This can be NULL if the message is for class methods. For
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index d058f838a008..94caa6faad66 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -102,6 +102,7 @@ public:
#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
+#define ABSTRACT_EXPR(CLASS, PARENT)
#include "clang/AST/StmtNodes.def"
};
private:
@@ -1120,21 +1121,27 @@ class AsmStmt : public Stmt {
unsigned NumOutputs;
unsigned NumInputs;
+ unsigned NumClobbers;
- llvm::SmallVector<std::string, 4> Names;
- llvm::SmallVector<StringLiteral*, 4> Constraints;
- llvm::SmallVector<Stmt*, 4> Exprs;
+ // FIXME: If we wanted to, we could allocate all of these in one big array.
+ IdentifierInfo **Names;
+ StringLiteral **Constraints;
+ Stmt **Exprs;
+ StringLiteral **Clobbers;
- llvm::SmallVector<StringLiteral*, 4> Clobbers;
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+
public:
- AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm,
- unsigned numoutputs, unsigned numinputs,
- std::string *names, StringLiteral **constraints,
+ AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
+ bool msasm, unsigned numoutputs, unsigned numinputs,
+ IdentifierInfo **names, StringLiteral **constraints,
Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
StringLiteral **clobbers, SourceLocation rparenloc);
/// \brief Build an empty inline-assembly statement.
- explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty) { }
+ explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
+ Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@@ -1208,14 +1215,21 @@ public:
unsigned getNumOutputs() const { return NumOutputs; }
- const std::string &getOutputName(unsigned i) const {
+ IdentifierInfo *getOutputIdentifier(unsigned i) const {
return Names[i];
}
+ llvm::StringRef getOutputName(unsigned i) const {
+ if (IdentifierInfo *II = getOutputIdentifier(i))
+ return II->getName();
+
+ return llvm::StringRef();
+ }
+
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
- std::string getOutputConstraint(unsigned i) const;
+ llvm::StringRef getOutputConstraint(unsigned i) const;
const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
return Constraints[i];
@@ -1224,7 +1238,6 @@ public:
return Constraints[i];
}
-
Expr *getOutputExpr(unsigned i);
const Expr *getOutputExpr(unsigned i) const {
@@ -1246,13 +1259,20 @@ public:
unsigned getNumInputs() const { return NumInputs; }
- const std::string &getInputName(unsigned i) const {
+ IdentifierInfo *getInputIdentifier(unsigned i) const {
return Names[i + NumOutputs];
}
+ llvm::StringRef getInputName(unsigned i) const {
+ if (IdentifierInfo *II = getInputIdentifier(i))
+ return II->getName();
+
+ return llvm::StringRef();
+ }
+
/// getInputConstraint - Return the specified input constraint. Unlike output
/// constraints, these can be empty.
- std::string getInputConstraint(unsigned i) const;
+ llvm::StringRef getInputConstraint(unsigned i) const;
const StringLiteral *getInputConstraintLiteral(unsigned i) const {
return Constraints[i + NumOutputs];
@@ -1261,32 +1281,31 @@ public:
return Constraints[i + NumOutputs];
}
-
Expr *getInputExpr(unsigned i);
const Expr *getInputExpr(unsigned i) const {
return const_cast<AsmStmt*>(this)->getInputExpr(i);
}
- void setOutputsAndInputs(unsigned NumOutputs,
- unsigned NumInputs,
- const std::string *Names,
- StringLiteral **Constraints,
- Stmt **Exprs);
+ void setOutputsAndInputsAndClobbers(ASTContext &C,
+ IdentifierInfo **Names,
+ StringLiteral **Constraints,
+ Stmt **Exprs,
+ unsigned NumOutputs,
+ unsigned NumInputs,
+ StringLiteral **Clobbers,
+ unsigned NumClobbers);
//===--- Other ---===//
/// getNamedOperand - Given a symbolic operand reference like %[foo],
/// translate this into a numeric value needed to reference the same operand.
/// This returns -1 if the operand name is invalid.
- int getNamedOperand(const std::string &SymbolicName) const;
-
+ int getNamedOperand(llvm::StringRef SymbolicName) const;
-
- unsigned getNumClobbers() const { return Clobbers.size(); }
+ unsigned getNumClobbers() const { return NumClobbers; }
StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
- void setClobbers(StringLiteral **Clobbers, unsigned NumClobbers);
virtual SourceRange getSourceRange() const {
return SourceRange(AsmLoc, RParenLoc);
@@ -1301,19 +1320,19 @@ public:
typedef ConstExprIterator const_inputs_iterator;
inputs_iterator begin_inputs() {
- return Exprs.data() + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
inputs_iterator end_inputs() {
- return Exprs.data() + NumOutputs + NumInputs;
+ return &Exprs[0] + NumOutputs + NumInputs;
}
const_inputs_iterator begin_inputs() const {
- return Exprs.data() + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
const_inputs_iterator end_inputs() const {
- return Exprs.data() + NumOutputs + NumInputs;
+ return &Exprs[0] + NumOutputs + NumInputs;
}
// Output expr iterators.
@@ -1322,27 +1341,17 @@ public:
typedef ConstExprIterator const_outputs_iterator;
outputs_iterator begin_outputs() {
- return Exprs.data();
+ return &Exprs[0];
}
outputs_iterator end_outputs() {
- return Exprs.data() + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
const_outputs_iterator begin_outputs() const {
- return Exprs.data();
+ return &Exprs[0];
}
const_outputs_iterator end_outputs() const {
- return Exprs.data() + NumOutputs;
- }
-
- // Input name iterator.
-
- const std::string *begin_output_names() const {
- return &Names[0];
- }
-
- const std::string *end_output_names() const {
- return &Names[0] + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
// Child iterators
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 09ea4ca2101b..4e87c2701c26 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -59,31 +59,42 @@ public:
///
class CXXTryStmt : public Stmt {
SourceLocation TryLoc;
- // First place is the guarded CompoundStatement. Subsequent are the handlers.
- // More than three handlers should be rare.
- llvm::SmallVector<Stmt*, 4> Stmts;
+ unsigned NumHandlers;
+
+ CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
+ unsigned numHandlers);
public:
- CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
- Stmt **handlers, unsigned numHandlers);
+ static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
+ Stmt *tryBlock, Stmt **handlers,
+ unsigned numHandlers);
virtual SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const { return Stmts.back()->getLocEnd(); }
+ SourceLocation getEndLoc() const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+ return Stmts[NumHandlers]->getLocEnd();
+ }
- CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
+ CompoundStmt *getTryBlock() {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+ return llvm::cast<CompoundStmt>(Stmts[0]);
+ }
const CompoundStmt *getTryBlock() const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CompoundStmt>(Stmts[0]);
}
- unsigned getNumHandlers() const { return Stmts.size() - 1; }
+ unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
}
const CXXCatchStmt *getHandler(unsigned i) const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
}
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 7102336180cf..ec6149e55f11 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -68,8 +68,7 @@ STMT(CXXTryStmt , Stmt)
LAST_STMT(CXXTryStmt)
// Expressions.
-ABSTRACT_EXPR(Expr , Stmt)
-FIRST_EXPR(Expr)
+ABSTRACT_EXPR(Expr , Stmt)
EXPR(PredefinedExpr , Expr)
EXPR(DeclRefExpr , Expr)
EXPR(IntegerLiteral , Expr)
@@ -83,12 +82,12 @@ EXPR(SizeOfAlignOfExpr , Expr)
EXPR(ArraySubscriptExpr , Expr)
EXPR(CallExpr , Expr)
EXPR(MemberExpr , Expr)
-EXPR(CastExpr , Expr)
+ABSTRACT_EXPR(CastExpr , Expr)
EXPR(BinaryOperator , Expr)
EXPR(CompoundAssignOperator, BinaryOperator)
EXPR(ConditionalOperator , Expr)
EXPR(ImplicitCastExpr , CastExpr)
-EXPR(ExplicitCastExpr , CastExpr)
+ABSTRACT_EXPR(ExplicitCastExpr, CastExpr)
EXPR(CStyleCastExpr , ExplicitCastExpr)
EXPR(CompoundLiteralExpr , Expr)
EXPR(ExtVectorElementExpr , Expr)
@@ -129,6 +128,7 @@ EXPR(UnaryTypeTraitExpr , Expr)
EXPR(DependentScopeDeclRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
+EXPR(CXXBindReferenceExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
EXPR(CXXUnresolvedConstructExpr, Expr)
@@ -152,6 +152,7 @@ EXPR(ShuffleVectorExpr , Expr)
EXPR(BlockExpr , Expr)
EXPR(BlockDeclRefExpr , Expr)
+FIRST_EXPR(PredefinedExpr)
LAST_EXPR(BlockDeclRefExpr)
#undef ABSTRACT_EXPR
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 3a525507dad3..4986f08ac124 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -105,6 +105,7 @@ public:
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
switch (S->getStmtClass()) {
default: assert(0 && "Unknown stmt kind!");
+#define ABSTRACT_EXPR(CLASS, PARENT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
#include "clang/AST/StmtNodes.def"
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index b7b60df5acb4..40e50988e6d2 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -16,6 +16,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Linkage.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "llvm/Support/Casting.h"
@@ -750,24 +751,22 @@ class Type {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
+#define LAST_TYPE(Class) TypeLast = Class,
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
TagFirst = Record, TagLast = Enum
};
-protected:
- enum { TypeClassBitSize = 6 };
-
private:
QualType CanonicalType;
- /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
- bool Dependent : 1;
-
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+ unsigned TC : 8;
+
+ /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
/// Note that this should stay at the end of the ivars for Type so that
/// subclasses can pack their bitfields into the same word.
- unsigned TC : TypeClassBitSize;
+ bool Dependent : 1;
Type(const Type&); // DO NOT IMPLEMENT.
void operator=(const Type&); // DO NOT IMPLEMENT.
@@ -776,7 +775,7 @@ protected:
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool dependent)
: CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
- Dependent(dependent), TC(tc) {}
+ TC(tc), Dependent(dependent) {}
virtual ~Type() {}
virtual void Destroy(ASTContext& C);
friend class ASTContext;
@@ -974,6 +973,9 @@ public:
const char *getTypeClassName() const;
+ /// \brief Determine the linkage of this type.
+ virtual Linkage getLinkage() const;
+
QualType getCanonicalTypeInternal() const { return CanonicalType; }
void dump() const;
static bool classof(const Type *) { return true; }
@@ -1062,6 +1064,8 @@ public:
return TypeKind >= Float && TypeKind <= LongDouble;
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
};
@@ -1089,6 +1093,8 @@ public:
ID.AddPointer(Element.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
static bool classof(const ComplexType *) { return true; }
};
@@ -1116,6 +1122,8 @@ public:
ID.AddPointer(Pointee.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
static bool classof(const PointerType *) { return true; }
};
@@ -1146,6 +1154,8 @@ public:
ID.AddPointer(Pointee.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == BlockPointer;
}
@@ -1183,7 +1193,8 @@ protected:
}
public:
bool isSpelledAsLValue() const { return SpelledAsLValue; }
-
+ bool isInnerRef() const { return InnerRef; }
+
QualType getPointeeTypeAsWritten() const { return PointeeType; }
QualType getPointeeType() const {
// FIXME: this might strip inner qualifiers; okay?
@@ -1203,6 +1214,8 @@ public:
ID.AddBoolean(SpelledAsLValue);
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == LValueReference ||
T->getTypeClass() == RValueReference;
@@ -1277,6 +1290,8 @@ public:
ID.AddPointer(Class);
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
}
@@ -1328,6 +1343,8 @@ public:
}
unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == VariableArray ||
@@ -1576,7 +1593,8 @@ public:
/// VectorType - GCC generic vector type. This type is created using
/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes. Since the constructor takes the number of vector elements, the
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
/// client is responsible for converting the size into the number of elements.
class VectorType : public Type, public llvm::FoldingSetNode {
protected:
@@ -1586,13 +1604,21 @@ protected:
/// NumElements - The number of elements in the vector.
unsigned NumElements;
- VectorType(QualType vecType, unsigned nElements, QualType canonType) :
+ /// AltiVec - True if this is for an Altivec vector.
+ bool AltiVec;
+
+ /// Pixel - True if this is for an Altivec vector pixel.
+ bool Pixel;
+
+ VectorType(QualType vecType, unsigned nElements, QualType canonType,
+ bool isAltiVec, bool isPixel) :
Type(Vector, canonType, vecType->isDependentType()),
- ElementType(vecType), NumElements(nElements) {}
+ ElementType(vecType), NumElements(nElements),
+ AltiVec(isAltiVec), Pixel(isPixel) {}
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType)
+ QualType canonType, bool isAltiVec, bool isPixel)
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
- NumElements(nElements) {}
+ NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
friend class ASTContext; // ASTContext creates these.
public:
@@ -1602,15 +1628,26 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ bool isAltiVec() const { return AltiVec; }
+
+ bool isPixel() const { return Pixel; }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(), getTypeClass());
+ Profile(ID, getElementType(), getNumElements(), getTypeClass(),
+ AltiVec, Pixel);
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
- unsigned NumElements, TypeClass TypeClass) {
+ unsigned NumElements, TypeClass TypeClass,
+ bool isAltiVec, bool isPixel) {
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
+ ID.AddBoolean(isAltiVec);
+ ID.AddBoolean(isPixel);
}
+
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
}
@@ -1624,7 +1661,7 @@ public:
/// points, colors, and textures (modeled after OpenGL Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType) {}
+ VectorType(ExtVector, vecType, nElements, canonType, false, false) {}
friend class ASTContext; // ASTContext creates these.
public:
static int getPointAccessorIdx(char c) {
@@ -1723,6 +1760,8 @@ public:
bool getNoReturnAttr() const { return NoReturn; }
CallingConv getCallConv() const { return (CallingConv)CallConv; }
+ static llvm::StringRef getNameForCallConv(CallingConv CC);
+
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto ||
T->getTypeClass() == FunctionProto;
@@ -1745,14 +1784,17 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getResultType(), getNoReturnAttr());
+ Profile(ID, getResultType(), getNoReturnAttr(), getCallConv());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
- bool NoReturn) {
+ bool NoReturn, CallingConv CallConv) {
+ ID.AddInteger(CallConv);
ID.AddInteger(NoReturn);
ID.AddPointer(ResultType.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
@@ -1856,6 +1898,8 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
@@ -1867,7 +1911,7 @@ public:
bool isVariadic, unsigned TypeQuals,
bool hasExceptionSpec, bool anyExceptionSpec,
unsigned NumExceptions, exception_iterator Exs,
- bool NoReturn);
+ bool NoReturn, CallingConv CallConv);
};
@@ -1878,8 +1922,9 @@ public:
class UnresolvedUsingType : public Type {
UnresolvedUsingTypenameDecl *Decl;
- UnresolvedUsingType(UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true), Decl(D) {}
+ UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
+ : Type(UnresolvedUsing, QualType(), true),
+ Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
public:
@@ -1906,8 +1951,9 @@ public:
class TypedefType : public Type {
TypedefDecl *Decl;
protected:
- TypedefType(TypeClass tc, TypedefDecl *D, QualType can)
- : Type(tc, can, can->isDependentType()), Decl(D) {
+ TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
+ : Type(tc, can, can->isDependentType()),
+ Decl(const_cast<TypedefDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
friend class ASTContext; // ASTContext creates these.
@@ -1950,8 +1996,12 @@ public:
static bool classof(const TypeOfExprType *) { return true; }
};
-/// Subclass of TypeOfExprType that is used for canonical, dependent
+/// \brief Internal representation of canonical, dependent
/// typeof(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via TypeOfExprType nodes.
class DependentTypeOfExprType
: public TypeOfExprType, public llvm::FoldingSetNode {
ASTContext &Context;
@@ -2018,8 +2068,12 @@ public:
static bool classof(const DecltypeType *) { return true; }
};
-/// Subclass of DecltypeType that is used for canonical, dependent
-/// C++0x decltype types.
+/// \brief Internal representation of canonical, dependent
+/// decltype(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via DecltypeType nodes.
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
ASTContext &Context;
@@ -2048,7 +2102,7 @@ class TagType : public Type {
friend class TagDecl;
protected:
- TagType(TypeClass TC, TagDecl *D, QualType can);
+ TagType(TypeClass TC, const TagDecl *D, QualType can);
public:
TagDecl *getDecl() const { return decl.getPointer(); }
@@ -2058,6 +2112,8 @@ public:
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@@ -2070,10 +2126,10 @@ public:
/// to detect TagType objects of structs/unions/classes.
class RecordType : public TagType {
protected:
- explicit RecordType(RecordDecl *D)
- : TagType(Record, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ explicit RecordType(const RecordDecl *D)
+ : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
explicit RecordType(TypeClass TC, RecordDecl *D)
- : TagType(TC, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -2103,8 +2159,8 @@ public:
/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of enums.
class EnumType : public TagType {
- explicit EnumType(EnumDecl *D)
- : TagType(Enum, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ explicit EnumType(const EnumDecl *D)
+ : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -2512,12 +2568,12 @@ public:
class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
ObjCInterfaceDecl *Decl;
- // List of protocols for this protocol conforming object type
- // List is sorted on protocol name. No protocol is enterred more than once.
- ObjCProtocolDecl **Protocols;
+ /// \brief The number of protocols stored after the ObjCInterfaceType node.
+ /// The list of protocols is sorted on protocol name. No protocol is enterred
+ /// more than once.
unsigned NumProtocols;
- ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, ObjCInterfaceDecl *D,
+ ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
ObjCProtocolDecl **Protos, unsigned NumP);
friend class ASTContext; // ASTContext creates these.
public:
@@ -2529,14 +2585,20 @@ public:
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
+ /// \brief Retrieve the Ith protocol.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
/// qual_iterator and friends: this provides access to the (potentially empty)
/// list of protocols qualifying this interface.
typedef ObjCProtocolDecl* const * qual_iterator;
qual_iterator qual_begin() const {
- return Protocols;
+ return reinterpret_cast<qual_iterator>(this + 1);
}
qual_iterator qual_end() const {
- return Protocols ? Protocols + NumProtocols : 0;
+ return qual_begin() + NumProtocols;
}
bool qual_empty() const { return NumProtocols == 0; }
@@ -2546,7 +2608,10 @@ public:
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
+ ObjCProtocolDecl * const *protocols,
+ unsigned NumProtocols);
+
+ virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCInterface;
@@ -2562,12 +2627,14 @@ public:
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType; // A builtin or interface type.
- // List of protocols for this protocol conforming object type
- // List is sorted on protocol name. No protocol is entered more than once.
- ObjCProtocolDecl **Protocols;
+ /// \brief The number of protocols stored after the ObjCObjectPointerType
+ /// node.
+ ///
+ /// The list of protocols is sorted on protocol name. No protocol is enterred
+ /// more than once.
unsigned NumProtocols;
- ObjCObjectPointerType(ASTContext &Ctx, QualType Canonical, QualType T,
+ ObjCObjectPointerType(QualType Canonical, QualType T,
ObjCProtocolDecl **Protos, unsigned NumP);
friend class ASTContext; // ASTContext creates these.
@@ -2614,10 +2681,10 @@ public:
typedef ObjCProtocolDecl* const * qual_iterator;
qual_iterator qual_begin() const {
- return Protocols;
+ return reinterpret_cast<qual_iterator> (this + 1);
}
qual_iterator qual_end() const {
- return Protocols ? Protocols + NumProtocols : NULL;
+ return qual_begin() + NumProtocols;
}
bool qual_empty() const { return NumProtocols == 0; }
@@ -2625,12 +2692,21 @@ public:
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
+ /// \brief Retrieve the Ith protocol.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ virtual Linkage getLinkage() const;
+
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
+ ObjCProtocolDecl *const *protocols,
+ unsigned NumProtocols);
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 575011a8724c..9cf2cb7bd773 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -87,6 +87,11 @@ DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
+#ifdef LAST_TYPE
+LAST_TYPE(ObjCObjectPointer)
+#undef LAST_TYPE
+#endif
+
// These types are always leaves in the type hierarchy.
#ifdef LEAF_TYPE
LEAF_TYPE(Enum)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 055d15264674..9c59229e3134 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -16,7 +16,6 @@
#define LLVM_CLANG_AST_UNRESOLVEDSET_H
#include <iterator>
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "clang/Basic/Specifiers.h"
@@ -24,12 +23,58 @@ namespace clang {
class NamedDecl;
+/// A POD class for pairing a NamedDecl* with an access specifier.
+/// Can be put into unions.
+class DeclAccessPair {
+ NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
+
+ enum { Mask = 0x3 };
+
+public:
+ static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
+ DeclAccessPair p;
+ p.set(D, AS);
+ return p;
+ }
+
+ NamedDecl *getDecl() const {
+ return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
+ }
+ AccessSpecifier getAccess() const {
+ return AccessSpecifier(Mask & (uintptr_t) Ptr);
+ }
+
+ void setDecl(NamedDecl *D) {
+ set(D, getAccess());
+ }
+ void setAccess(AccessSpecifier AS) {
+ set(getDecl(), AS);
+ }
+ void set(NamedDecl *D, AccessSpecifier AS) {
+ Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
+ reinterpret_cast<uintptr_t>(D));
+ }
+
+ operator NamedDecl*() const { return getDecl(); }
+ NamedDecl *operator->() const { return getDecl(); }
+};
+}
+
+// Take a moment to tell SmallVector that this is POD.
+namespace llvm {
+template<typename> struct isPodLike;
+template<> struct isPodLike<clang::DeclAccessPair> {
+ static const bool value = true;
+};
+}
+
+namespace clang {
+
/// The iterator over UnresolvedSets. Serves as both the const and
/// non-const iterator.
class UnresolvedSetIterator {
-
- typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry;
- typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy;
+private:
+ typedef llvm::SmallVectorImpl<DeclAccessPair> DeclsTy;
typedef DeclsTy::iterator IteratorTy;
IteratorTy ir;
@@ -47,8 +92,8 @@ public:
typedef NamedDecl *reference;
typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
- NamedDecl *getDecl() const { return ir->getPointer(); }
- AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); }
+ NamedDecl *getDecl() const { return ir->getDecl(); }
+ AccessSpecifier getAccess() const { return ir->getAccess(); }
NamedDecl *operator*() const { return getDecl(); }
@@ -87,7 +132,6 @@ public:
/// in a lot of places, but isn't really worth breaking into its own
/// header right now.
class UnresolvedSetImpl {
- typedef UnresolvedSetIterator::DeclEntry DeclEntry;
typedef UnresolvedSetIterator::DeclsTy DeclsTy;
// Don't allow direct construction, and only permit subclassing by
@@ -114,7 +158,7 @@ public:
}
void addDecl(NamedDecl *D, AccessSpecifier AS) {
- decls().push_back(DeclEntry(D, AS));
+ decls().push_back(DeclAccessPair::make(D, AS));
}
/// Replaces the given declaration with the new one, once.
@@ -122,19 +166,24 @@ public:
/// \return true if the set changed
bool replace(const NamedDecl* Old, NamedDecl *New) {
for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
- if (I->getPointer() == Old)
- return (I->setPointer(New), true);
+ if (I->getDecl() == Old)
+ return (I->setDecl(New), true);
return false;
}
/// Replaces the declaration at the given iterator with the new one,
/// preserving the original access bits.
void replace(iterator I, NamedDecl *New) {
- I.ir->setPointer(New);
+ I.ir->setDecl(New);
}
void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
- *I.ir = DeclEntry(New, AS);
+ I.ir->set(New, AS);
+ }
+
+ void erase(unsigned I) {
+ decls()[I] = decls().back();
+ decls().pop_back();
}
void erase(iterator I) {
@@ -142,6 +191,10 @@ public:
decls().pop_back();
}
+ void setAccess(iterator I, AccessSpecifier AS) {
+ I.ir->setAccess(AS);
+ }
+
void clear() { decls().clear(); }
void set_size(unsigned N) { decls().set_size(N); }
@@ -152,41 +205,8 @@ public:
decls().append(I.ir, E.ir);
}
- /// A proxy reference for implementing operator[].
- class Proxy {
- DeclEntry &Ref;
-
- friend class UnresolvedSetImpl;
- Proxy(DeclEntry &Ref) : Ref(Ref) {}
-
- public:
- NamedDecl *getDecl() const { return Ref.getPointer(); }
- void setDecl(NamedDecl *D) { Ref.setPointer(D); }
-
- AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
- void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); }
-
- NamedDecl* operator->() const { return getDecl(); }
- operator NamedDecl*() const { return getDecl(); }
- Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; }
- };
- Proxy operator[](unsigned I) { return Proxy(decls()[I]); }
-
- /// A proxy reference for implementing operator[] const.
- class ConstProxy {
- const DeclEntry &Ref;
-
- friend class UnresolvedSetImpl;
- ConstProxy(const DeclEntry &Ref) : Ref(Ref) {}
-
- public:
- NamedDecl *getDecl() const { return Ref.getPointer(); }
- AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
-
- NamedDecl *operator->() const { return getDecl(); }
- operator NamedDecl*() const { return getDecl(); }
- };
- ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); }
+ DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
+ const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
private:
// These work because the only permitted subclass is UnresolvedSetImpl
@@ -202,7 +222,7 @@ private:
/// A set of unresolved declarations
template <unsigned InlineCapacity> class UnresolvedSet :
public UnresolvedSetImpl {
- llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls;
+ llvm::SmallVector<DeclAccessPair, InlineCapacity> Decls;
};
diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h
new file mode 100644
index 000000000000..a4ad0b703708
--- /dev/null
+++ b/include/clang/Analysis/Analyses/PrintfFormatString.h
@@ -0,0 +1,279 @@
+//==- PrintfFormatStrings.h - Analysis of printf format strings --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Handling of format string in printf and friends. The structure of format
+// strings for fprintf() are described in C99 7.19.6.1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FPRINTF_FORMAT_H
+#define LLVM_CLANG_FPRINTF_FORMAT_H
+
+#include "clang/AST/CanonicalType.h"
+
+namespace clang {
+
+class ASTContext;
+
+namespace analyze_printf {
+
+class ArgTypeResult {
+public:
+ enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy,
+ WCStrTy };
+private:
+ const Kind K;
+ QualType T;
+ ArgTypeResult(bool) : K(InvalidTy) {}
+public:
+ ArgTypeResult(Kind k = UnknownTy) : K(k) {}
+ ArgTypeResult(QualType t) : K(SpecificTy), T(t) {}
+ ArgTypeResult(CanQualType t) : K(SpecificTy), T(t) {}
+
+ static ArgTypeResult Invalid() { return ArgTypeResult(true); }
+
+ bool isValid() const { return K != InvalidTy; }
+
+ const QualType *getSpecificType() const {
+ return K == SpecificTy ? &T : 0;
+ }
+
+ bool matchesType(ASTContext &C, QualType argTy) const;
+
+ bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
+
+ QualType getRepresentativeType(ASTContext &C) const;
+};
+
+class ConversionSpecifier {
+public:
+ enum Kind {
+ InvalidSpecifier = 0,
+ // C99 conversion specifiers.
+ dArg, // 'd'
+ iArg, // 'i',
+ oArg, // 'o',
+ uArg, // 'u',
+ xArg, // 'x',
+ XArg, // 'X',
+ fArg, // 'f',
+ FArg, // 'F',
+ eArg, // 'e',
+ EArg, // 'E',
+ gArg, // 'g',
+ GArg, // 'G',
+ aArg, // 'a',
+ AArg, // 'A',
+ IntAsCharArg, // 'c'
+ CStrArg, // 's'
+ VoidPtrArg, // 'p'
+ OutIntPtrArg, // 'n'
+ PercentArg, // '%'
+ // Objective-C specific specifiers.
+ ObjCObjArg, // '@'
+ // GlibC specific specifiers.
+ PrintErrno, // 'm'
+ // Specifier ranges.
+ IntArgBeg = dArg,
+ IntArgEnd = iArg,
+ UIntArgBeg = oArg,
+ UIntArgEnd = XArg,
+ DoubleArgBeg = fArg,
+ DoubleArgEnd = AArg,
+ C99Beg = IntArgBeg,
+ C99End = DoubleArgEnd,
+ ObjCBeg = ObjCObjArg,
+ ObjCEnd = ObjCObjArg
+ };
+
+ ConversionSpecifier()
+ : Position(0), kind(InvalidSpecifier) {}
+
+ ConversionSpecifier(const char *pos, Kind k)
+ : Position(pos), kind(k) {}
+
+ const char *getStart() const {
+ return Position;
+ }
+
+ llvm::StringRef getCharacters() const {
+ return llvm::StringRef(getStart(), getLength());
+ }
+
+ bool consumesDataArgument() const {
+ switch (kind) {
+ case PercentArg:
+ case PrintErrno:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
+ bool isIntArg() const { return kind >= dArg && kind <= iArg; }
+ bool isUIntArg() const { return kind >= oArg && kind <= XArg; }
+ bool isDoubleArg() const { return kind >= fArg && kind <= AArg; }
+ Kind getKind() const { return kind; }
+ unsigned getLength() const {
+ // Conversion specifiers currently only are represented by
+ // single characters, but we be flexible.
+ return 1;
+ }
+
+private:
+ const char *Position;
+ Kind kind;
+};
+
+enum LengthModifier {
+ None,
+ AsChar, // 'hh'
+ AsShort, // 'h'
+ AsLong, // 'l'
+ AsLongLong, // 'll', 'q' (BSD, deprecated)
+ AsIntMax, // 'j'
+ AsSizeT, // 'z'
+ AsPtrDiff, // 't'
+ AsLongDouble, // 'L'
+ AsWideChar = AsLong // for '%ls'
+};
+
+class OptionalAmount {
+public:
+ enum HowSpecified { NotSpecified, Constant, Arg };
+
+ OptionalAmount(HowSpecified h, const char *st)
+ : start(st), hs(h), amt(0) {}
+
+ OptionalAmount()
+ : start(0), hs(NotSpecified), amt(0) {}
+
+ OptionalAmount(unsigned i, const char *st)
+ : start(st), hs(Constant), amt(i) {}
+
+ HowSpecified getHowSpecified() const { return hs; }
+ bool hasDataArgument() const { return hs == Arg; }
+
+ unsigned getConstantAmount() const {
+ assert(hs == Constant);
+ return amt;
+ }
+
+ const char *getStart() const {
+ return start;
+ }
+
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+private:
+ const char *start;
+ HowSpecified hs;
+ unsigned amt;
+};
+
+class FormatSpecifier {
+ LengthModifier LM;
+ unsigned IsLeftJustified : 1;
+ unsigned HasPlusPrefix : 1;
+ unsigned HasSpacePrefix : 1;
+ unsigned HasAlternativeForm : 1;
+ unsigned HasLeadingZeroes : 1;
+ unsigned flags : 5;
+ ConversionSpecifier CS;
+ OptionalAmount FieldWidth;
+ OptionalAmount Precision;
+public:
+ FormatSpecifier() : LM(None),
+ IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
+ HasAlternativeForm(0), HasLeadingZeroes(0) {}
+
+ static FormatSpecifier Parse(const char *beg, const char *end);
+
+ // Methods for incrementally constructing the FormatSpecifier.
+ void setConversionSpecifier(const ConversionSpecifier &cs) {
+ CS = cs;
+ }
+ void setLengthModifier(LengthModifier lm) {
+ LM = lm;
+ }
+ void setIsLeftJustified() { IsLeftJustified = 1; }
+ void setHasPlusPrefix() { HasPlusPrefix = 1; }
+ void setHasSpacePrefix() { HasSpacePrefix = 1; }
+ void setHasAlternativeForm() { HasAlternativeForm = 1; }
+ void setHasLeadingZeros() { HasLeadingZeroes = 1; }
+
+ // Methods for querying the format specifier.
+
+ const ConversionSpecifier &getConversionSpecifier() const {
+ return CS;
+ }
+
+ LengthModifier getLengthModifier() const {
+ return LM;
+ }
+
+ const OptionalAmount &getFieldWidth() const {
+ return FieldWidth;
+ }
+
+ void setFieldWidth(const OptionalAmount &Amt) {
+ FieldWidth = Amt;
+ }
+
+ void setPrecision(const OptionalAmount &Amt) {
+ Precision = Amt;
+ }
+
+ const OptionalAmount &getPrecision() const {
+ return Precision;
+ }
+
+ /// \brief Returns the builtin type that a data argument
+ /// paired with this format specifier should have. This method
+ /// will return null if the format specifier does not have
+ /// a matching data argument or the matching argument matches
+ /// more than one type.
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+ bool isLeftJustified() const { return (bool) IsLeftJustified; }
+ bool hasPlusPrefix() const { return (bool) HasPlusPrefix; }
+ bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
+ bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
+ bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
+};
+
+class FormatStringHandler {
+public:
+ FormatStringHandler() {}
+ virtual ~FormatStringHandler();
+
+ virtual void HandleIncompleteFormatSpecifier(const char *startSpecifier,
+ unsigned specifierLen) {}
+
+ virtual void HandleNullChar(const char *nullCharacter) {}
+
+ virtual void
+ HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {}
+
+ virtual bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {
+ return true;
+ }
+};
+
+bool ParseFormatString(FormatStringHandler &H,
+ const char *beg, const char *end);
+
+} // end printf namespace
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 2b367b7e37f6..cd771acb06a5 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -70,5 +70,8 @@ public:
void InitializeValues(const CFG& cfg);
};
+
+void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
+ bool FullUninitTaint=false);
} // end namespace clang
#endif
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index c82bb962fd18..ea4f5b20669c 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -32,7 +32,6 @@ class LiveVariables;
class ParentMap;
class ImplicitParamDecl;
class LocationContextManager;
-class BlockDataRegion;
class StackFrameContext;
/// AnalysisContext contains the context data for the function or method under
@@ -207,35 +206,23 @@ public:
};
class BlockInvocationContext : public LocationContext {
- llvm::PointerUnion<const BlockDataRegion *, const BlockDecl *> Data;
+ // FIXME: Add back context-sensivity (we don't want libAnalysis to know
+ // about MemRegion).
+ const BlockDecl *BD;
friend class LocationContextManager;
BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
- const BlockDataRegion *br)
- : LocationContext(Block, ctx, parent), Data(br) {}
-
- BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
const BlockDecl *bd)
- : LocationContext(Block, ctx, parent), Data(bd) {}
+ : LocationContext(Block, ctx, parent), BD(bd) {}
public:
~BlockInvocationContext() {}
-
- const BlockDataRegion *getBlockRegion() const {
- return Data.is<const BlockDataRegion*>() ?
- Data.get<const BlockDataRegion*>() : 0;
- }
-
- const BlockDecl *getBlockDecl() const;
-
+
+ const BlockDecl *getBlockDecl() const { return BD; }
+
void Profile(llvm::FoldingSetNodeID &ID);
-
- static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const BlockDataRegion *br){
- ProfileCommon(ID, Block, ctx, parent, br);
- }
-
+
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
const LocationContext *parent, const BlockDecl *bd) {
ProfileCommon(ID, Block, ctx, parent, bd);
@@ -260,10 +247,6 @@ public:
const LocationContext *parent,
const Stmt *s);
- const BlockInvocationContext *
- getBlockInvocation(AnalysisContext *ctx, const LocationContext *parent,
- const BlockDataRegion *BR);
-
/// Discard all previously created LocationContext objects.
void clear();
private:
diff --git a/include/clang/Analysis/Support/Optional.h b/include/clang/Analysis/Support/Optional.h
index 40f38be020a9..a4e6d519a04f 100644
--- a/include/clang/Analysis/Support/Optional.h
+++ b/include/clang/Analysis/Support/Optional.h
@@ -20,19 +20,27 @@ namespace clang {
template<typename T>
class Optional {
- const T x;
+ T x;
unsigned hasVal : 1;
public:
- explicit Optional() : hasVal(false) {}
+ explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
+ Optional &operator=(const T &y) {
+ x = y;
+ hasVal = true;
+ return *this;
+ }
+
const T* getPointer() const { assert(hasVal); return &x; }
+ const T& getValue() const { assert(hasVal); return x; }
operator bool() const { return hasVal; }
+ bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
const T& operator*() const { assert(hasVal); return x; }
};
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 08945635e6c9..3251ec4b1f97 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -12,9 +12,6 @@
//
//===----------------------------------------------------------------------===//
-// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
-// adding stuff on demand.
-//
// FIXME: This should really be a .td file, but that requires modifying tblgen.
// Perhaps tblgen should have plugins.
@@ -52,6 +49,7 @@
// * -> pointer
// & -> reference
// C -> const
+// D -> volatile
// The third value provided to the macro specifies information about attributes
// of the function. These must be kept in sync with the predicates in the
@@ -235,7 +233,7 @@ BUILTIN(__builtin_islessgreater , "i.", "nc")
BUILTIN(__builtin_isunordered , "i.", "nc")
// Unary FP classification
-// BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
+BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
BUILTIN(__builtin_isfinite, "i.", "nc")
BUILTIN(__builtin_isinf, "i.", "nc")
BUILTIN(__builtin_isinf_sign, "i.", "nc")
@@ -277,7 +275,7 @@ BUILTIN(__builtin_va_copy, "vAA", "n")
BUILTIN(__builtin_stdarg_start, "vA.", "n")
BUILTIN(__builtin_bcmp, "iv*v*z", "n")
BUILTIN(__builtin_bcopy, "vv*v*z", "n")
-BUILTIN(__builtin_bzero, "vv*z", "n")
+BUILTIN(__builtin_bzero, "vv*z", "nF")
BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
@@ -308,11 +306,19 @@ BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
BUILTIN(__builtin_frame_address, "v*Ui", "n")
BUILTIN(__builtin_flt_rounds, "i", "nc")
BUILTIN(__builtin_setjmp, "iv**", "")
-BUILTIN(__builtin_longjmp, "vv**i", "")
+BUILTIN(__builtin_longjmp, "vv**i", "r")
BUILTIN(__builtin_unwind_init, "v", "")
BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
+// GCC exception builtins
+BUILTIN(__builtin_eh_return, "vzv*", "") // FIXME: Takes intptr_t, not size_t!
+BUILTIN(__builtin_frob_return_addr, "v*v*", "n")
+BUILTIN(__builtin_dwarf_cfa, "v*", "n")
+BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
+BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
+BUILTIN(__builtin_extend_pointer, "iv*", "n")
+
// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n")
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
@@ -438,18 +444,18 @@ BUILTIN(__sync_nand_and_fetch_16, "LLLiLLLi*LLLi.", "n")
BUILTIN(__sync_bool_compare_and_swap, "v.", "")
-BUILTIN(__sync_bool_compare_and_swap_1, "bc*cc.", "n")
-BUILTIN(__sync_bool_compare_and_swap_2, "bs*ss.", "n")
-BUILTIN(__sync_bool_compare_and_swap_4, "bi*ii.", "n")
-BUILTIN(__sync_bool_compare_and_swap_8, "bLLi*LLi.", "n")
-BUILTIN(__sync_bool_compare_and_swap_16, "bLLLi*LLLiLLLi.", "n")
+BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "n")
+BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "n")
+BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "n")
+BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "n")
+BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "n")
BUILTIN(__sync_val_compare_and_swap, "v.", "")
-BUILTIN(__sync_val_compare_and_swap_1, "cc*cc.", "n")
-BUILTIN(__sync_val_compare_and_swap_2, "ss*ss.", "n")
-BUILTIN(__sync_val_compare_and_swap_4, "ii*ii.", "n")
-BUILTIN(__sync_val_compare_and_swap_8, "LLiLLi*LLi.", "n")
-BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLi*LLLiLLLi.", "n")
+BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "n")
+BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "n")
+BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "n")
+BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "n")
+BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "n")
BUILTIN(__sync_lock_test_and_set, "v.", "")
BUILTIN(__sync_lock_test_and_set_1, "cc*c.", "n")
@@ -527,6 +533,7 @@ LIBBUILTIN(strndup, "c*cC*z", "f", "string.h")
// POSIX strings.h
LIBBUILTIN(index, "c*cC*i", "f", "strings.h")
LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h")
+LIBBUILTIN(bzero, "vv*z", "f", "strings.h")
// POSIX unistd.h
LIBBUILTIN(_exit, "vi", "fr", "unistd.h")
// POSIX setjmp.h
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index c5d6d7c71316..d2516f8695b8 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -23,16 +23,19 @@
namespace llvm {
template <typename T> class SmallVectorImpl;
+ class raw_ostream;
}
namespace clang {
class DeclContext;
class DiagnosticBuilder;
class DiagnosticClient;
+ class FileManager;
class IdentifierInfo;
class LangOptions;
class PartialDiagnostic;
class Preprocessor;
+ class SourceManager;
class SourceRange;
// Import the diagnostic enums themselves.
@@ -400,6 +403,13 @@ public:
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
+ /// Deserialize - Deserialize the first diagnostic within the memory
+ /// [Memory, MemoryEnd), producing a new diagnostic builder describing the
+ /// deserialized diagnostic. If the memory does not contain a
+ /// diagnostic, returns a diagnostic builder with no diagnostic ID.
+ DiagnosticBuilder Deserialize(FileManager &FM, SourceManager &SM,
+ const char *&Memory, const char *MemoryEnd);
+
private:
/// getDiagnosticMappingInfo - Return the mapping info currently set for the
/// specified builtin diagnostic. This returns the high bit encoding, or zero
@@ -472,7 +482,7 @@ private:
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
- const SourceRange *DiagRanges[10];
+ SourceRange DiagRanges[10];
enum { MaxCodeModificationHints = 3 };
@@ -568,6 +578,9 @@ public:
/// been emitted.
~DiagnosticBuilder() { Emit(); }
+ /// isActive - Determine whether this diagnostic is still active.
+ bool isActive() const { return DiagObj != 0; }
+
/// Operator bool: conversion of DiagnosticBuilder to bool always returns
/// true. This allows is to be used in boolean error contexts like:
/// return Diag(...);
@@ -596,7 +609,7 @@ public:
sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
"Too many arguments to diagnostic!");
if (DiagObj)
- DiagObj->DiagRanges[NumRanges++] = &R;
+ DiagObj->DiagRanges[NumRanges++] = R;
}
void AddCodeModificationHint(const CodeModificationHint &Hint) const {
@@ -759,9 +772,9 @@ public:
return DiagObj->NumDiagRanges;
}
- const SourceRange &getRange(unsigned Idx) const {
+ SourceRange getRange(unsigned Idx) const {
assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
- return *DiagObj->DiagRanges[Idx];
+ return DiagObj->DiagRanges[Idx];
}
unsigned getNumCodeModificationHints() const {
@@ -786,6 +799,12 @@ public:
/// output buffer using the arguments stored in this diagnostic.
void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
llvm::SmallVectorImpl<char> &OutStr) const;
+
+ /// Serialize - Serialize the given diagnostic (with its diagnostic
+ /// level) to the given stream. Serialization is a lossy operation,
+ /// since the specific diagnostic ID and any macro-instantiation
+ /// information is lost.
+ void Serialize(Diagnostic::Level DiagLevel, llvm::raw_ostream &OS) const;
};
/// DiagnosticClient - This is an abstract interface implemented by clients of
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index f075aaaf422f..b6c2b13895d6 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -26,4 +26,33 @@ def err_asm_empty_symbolic_operand_name : Error<
def err_asm_invalid_operand_number : Error<
"invalid operand number in inline asm string">;
+// Importing ASTs
+def err_odr_variable_type_inconsistent : Error<
+ "external variable %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">;
+def err_odr_variable_multiple_def : Error<
+ "external variable %0 defined in multiple translation units">;
+def note_odr_value_here : Note<"declared here with type %0">;
+def note_odr_defined_here : Note<"also defined here">;
+def err_odr_function_type_inconsistent : Error<
+ "external function %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">;
+def warn_odr_tag_type_inconsistent : Warning<
+ "type %0 has incompatible definitions in different translation units">;
+def note_odr_tag_kind_here: Note<
+ "%0 is a %select{struct|union|class|enum}1 here">;
+def note_odr_field : Note<"field %0 has type %1 here">;
+def note_odr_missing_field : Note<"no corresponding field here">;
+def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
+def note_odr_not_bit_field : Note<"field %0 is not a bit-field">;
+def note_odr_base : Note<"class has base type %0">;
+def note_odr_virtual_base : Note<
+ "%select{non-virtual|virtual}0 derivation here">;
+def note_odr_missing_base : Note<"no corresponding base class here">;
+def note_odr_number_of_bases : Note<
+ "class has %0 base %plural{1:class|:classes}0">;
+def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
+def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
+
+def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
}
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 7e14a329dcab..66f84dbbbabe 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -31,6 +31,9 @@ def note_also_found : Note<"also found">;
// Parse && Lex
def err_expected_colon : Error<"expected ':'">;
+def err_expected_colon_after_setter_name : Error<
+ "method name referenced in property setter attribute "
+ "must end with ':'">;
// Parse && Sema
def err_no_declarators : Error<"declaration does not declare anything">;
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 8cdf85082b16..dc5ccfdf5202 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -62,6 +62,8 @@ def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_remap_file : Error<
"invalid option '%0' not of the form <from-file>;<to-file>">;
+def err_drv_invalid_gcc_output_type : Error<
+ "invalid output type '%0' for use with gcc tool">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
@@ -85,5 +87,7 @@ def warn_ignoring_ftabstop_value : Warning<
"ignoring invalid -ftabstop value '%0', using default value %1">;
def warn_drv_missing_resource_library : Warning<
"missing resource library '%0', link may fail">;
+def warn_drv_conflicting_deployment_targets : Warning<
+ "conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 66a841a8afae..79147eac5f32 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -19,6 +19,8 @@ def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
DefaultFatal;
+def err_fe_stderr_binary : Error<"unable to change standard error to binary">,
+ DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
"-dependency-file requires at least one -MT option">;
def err_fe_incompatible_options : Error<
@@ -80,6 +82,8 @@ def note_fixit_main_file_unchanged : Note<
def warn_fixit_no_changes : Note<
"FIX-IT detected errors it could not fix; no output will be generated">;
+def err_fe_clang : Error<"error invoking%s: %s">, DefaultFatal;
+
// PCH reader
def err_relocatable_without_without_isysroot : Error<
"must specify system root with -isysroot when building a relocatable "
@@ -105,6 +109,10 @@ def warn_pch_objective_c2 : Error<
def warn_pch_nonfragile_abi : Error<
"PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C "
"ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">;
+def warn_pch_nonfragile_abi2 : Error<
+ "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
+ "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
+ "Objective-C ABI is selected">;
def warn_pch_extensions : Error<
"extensions were %select{enabled|disabled}0 in PCH file but are "
"currently %select{enabled|disabled}1">;
@@ -132,6 +140,9 @@ def warn_pch_elide_constructors : Error<
def warn_pch_exceptions : Error<
"exceptions were %select{disabled|enabled}0 in PCH file but "
"are currently %select{disabled|enabled}1">;
+def warn_pch_sjlj_exceptions : Error<
+ "sjlj-exceptions were %select{disabled|enabled}0 in PCH file but "
+ "are currently %select{disabled|enabled}1">;
def warn_pch_objc_runtime : Error<
"PCH file was compiled with the %select{NeXT|GNU}0 runtime but the "
"%select{NeXT|GNU}1 runtime is selected">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 03aad8606352..82f9eca12960 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -96,7 +96,8 @@ def : DiagGroup<"strict-overflow">;
def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
def : DiagGroup<"strict-prototypes">;
def : DiagGroup<"strict-selector-match">;
-def Switch : DiagGroup<"switch">;
+def SwitchEnum : DiagGroup<"switch-enum">;
+def Switch : DiagGroup<"switch", [SwitchEnum]>;
def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
@@ -118,6 +119,7 @@ def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def : DiagGroup<"write-strings">;
def CharSubscript : DiagGroup<"char-subscripts">;
+def ForceAlignArgPointer : DiagGroup<"force-align-arg-pointer">;
// Aggregation warning settings.
@@ -178,4 +180,4 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
// 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]>;
+ [SignCompare, Conversion, ForceAlignArgPointer]>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index c6d060525285..bc26c3b0dad9 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -14,6 +14,8 @@
let Component = "Parse" in {
def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">;
+def warn_file_asm_volatile : Warning<
+ "meaningless 'volatile' on asm outside function">;
def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
def ext_top_level_semi : Extension<
@@ -158,12 +160,20 @@ def err_typename_invalid_functionspec : Error<
"type name does not allow function specifier to be specified">;
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
+def err_invalid_vector_decl_spec_combination : Error<
+ "cannot combine with previous '%0' declaration specifier. \"__vector\" must be first">;
+def err_invalid_pixel_decl_spec_combination : Error<
+ "\"__pixel\" must be preceded by \"__vector\". '%0' declaration specifier not allowed here">;
+def err_invalid_vector_double_decl_spec_combination : Error<
+ "cannot use \"double\" with \"__vector\"">;
+def warn_vector_long_decl_spec_combination : Warning<
+ "Use of \"long\" with \"__vector\" is deprecated">;
def err_friend_invalid_in_context : Error<
"'friend' used outside of class">;
def err_unknown_typename : Error<
"unknown type name %0">;
def err_use_of_tag_name_without_tag : Error<
- "use of tagged type %0 without '%1' tag">;
+ "must use '%1' tag to refer to type %0%select{| in this scope}2">;
def err_expected_ident_in_using : Error<
"expected an identifier in using directive">;
def err_unexected_colon_in_nested_name_spec : Error<
@@ -303,6 +313,9 @@ def err_out_of_line_type_names_constructor : Error<
def err_expected_qualified_after_typename : Error<
"expected a qualified name after 'typename'">;
+def err_expected_semi_after_tagdecl : Error<
+ "expected ';' after %0">;
+
def err_typename_refers_to_non_type_template : Error<
"typename specifier refers to a non-template">;
def err_expected_type_name_after_typename : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 8d75d2e25722..19b242e86b69 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -85,7 +85,11 @@ def warn_unused_variable : Warning<"unused variable %0">,
InGroup<UnusedVariable>, DefaultIgnore;
def warn_decl_in_param_list : Warning<
"declaration of %0 will not be visible outside of this function">;
-
+def err_array_star_in_function_definition : Error<
+ "variable length array must be bound in function definition">;
+def warn_unused_function : Warning<"unused function %0">,
+ InGroup<UnusedFunction>, DefaultIgnore;
+
def warn_implicit_function_decl : Warning<
"implicit declaration of function %0">,
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
@@ -388,6 +392,11 @@ def err_deleted_non_function : Error<
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
+def warn_weak_vtable : Warning<
+ "%0 has no out-of-line virtual method definitions; its vtable will be "
+ "emitted in every translation unit">,
+ InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
+
// C++ exception specifications
def err_exception_spec_in_typedef : Error<
"exception specifications are not allowed in typedefs">;
@@ -410,17 +419,20 @@ def err_deep_exception_specs_differ : Error<
// C++ access checking
def err_class_redeclared_with_different_access : Error<
"%0 redeclared with '%1' access">;
+def err_access_private : Error<"%0 is a private member of %1">;
+def err_access_ctor_private : Error<"calling a private constructor of %0">;
+// Say something about the context for these?
+def err_access_protected : Error<"%0 is a protected member of %1">;
+def err_access_ctor_protected : Error<"calling a protected constructor of %0">;
def note_previous_access_declaration : Note<
"previously declared '%1' here">;
def err_access_outside_class : Error<
"access to %select{private|protected}0 member outside any class context">;
-def note_access_natural : Note<"declared %select{private|protected}0 here">;
+def note_access_natural : Note<
+ "%select{|implicitly }1declared %select{private|protected}0 here">;
def note_access_constrained_by_path : Note<
- "access to decl constrained by %select{private|protected}0 inheritance">;
-def err_access_protected : Error<
- "access to protected member of %0 from %1, which is not a subclass">;
-def err_access_private : Error<
- "access to private member of %0 from %1">;
+ "constrained by %select{|implicitly }1%select{private|protected}0"
+ " inheritance here">;
// C++ name lookup
def err_incomplete_nested_name_spec : Error<
@@ -446,10 +458,14 @@ def err_mutable_nonmember : Error<
"'mutable' can only be applied to member variables">;
def err_virtual_non_function : Error<
"'virtual' can only appear on non-static member functions">;
-def err_explicit_non_function : Error<
- "'explicit' can only appear on non-static member functions">;
def err_virtual_out_of_class : Error<
"'virtual' can only be specified inside the class definition">;
+def err_explicit_non_function : Error<
+ "'explicit' can only appear on non-static member functions">;
+def err_explicit_out_of_class : Error<
+ "'explicit' can only be specified inside the class definition">;
+def err_explicit_non_ctor_or_conv_function : Error<
+ "'explicit' can only be applied to a constructor or conversion function">;
def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">;
def err_static_out_of_line : Error<
"'static' can only be specified inside the class definition">;
@@ -498,9 +514,8 @@ def note_overridden_virtual_function : Note<
"overridden virtual function is here">;
def err_covariant_return_inaccessible_base : Error<
- "return type of virtual function %2 is not covariant with the return type "
- "of the function it overrides "
- "(conversion from %0 to inaccessible base class %1)">, NoSFINAE;
+ "invalid covariant return for virtual function: %1 is a "
+ "%select{private|protected}2 base class of %0">, NoSFINAE;
def err_covariant_return_ambiguous_derived_to_base_conv : Error<
"return type of virtual function %3 is not covariant with the return type of "
"the function it overrides (ambiguous conversion from derived class "
@@ -547,7 +562,7 @@ def err_destructor_name : Error<
def err_init_conversion_failed : Error<
"cannot initialize %select{a variable|a parameter|return object|an "
"exception object|a member subobject|an array element|a new value|a value|a "
- "base class|an array element}0 of type %1 with an %select{rvalue|lvalue}2 of "
+ "base class|a vector element}0 of type %1 with an %select{rvalue|lvalue}2 of "
"type %3">;
def err_lvalue_to_rvalue_ref : Error<"rvalue reference cannot bind to lvalue">;
@@ -556,14 +571,14 @@ def err_invalid_initialization : Error<
def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
"due to multiple conversion functions">;
def err_not_reference_to_const_init : Error<
- "non-const lvalue reference to type %0 cannot be initialized "
- "with a %select{value|temporary}1 of type %2">;
+ "%select{non-const|volatile}0 lvalue reference to type %1 cannot be "
+ "initialized with a %select{value|temporary}2 of type %3">;
def err_lvalue_reference_bind_to_temporary : Error<
- "non-const lvalue reference to type %0 cannot bind to a temporary of type "
- "%1">;
+ "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+ "temporary of type %2">;
def err_lvalue_reference_bind_to_unrelated : Error<
- "non-const lvalue reference to type %0 cannot bind to a value of unrelated "
- "type %1">;
+ "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+ "value of unrelated type %2">;
def err_reference_bind_drops_quals : Error<
"binding of reference to type %0 to a value of type %1 drops qualifiers">;
def err_reference_bind_failed : Error<
@@ -580,10 +595,14 @@ def err_reference_init_drops_quals : Error<
"qualifiers">;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
+def err_reference_bind_to_vector_element : Error<
+ "%select{non-const|volatile}0 reference cannot bind to vector element">;
def err_reference_var_requires_init : Error<
"declaration of reference variable %0 requires an initializer">;
def err_const_var_requires_init : Error<
"declaration of const variable '%0' requires an initializer">;
+def err_reference_without_init : Error<
+ "reference to type %0 requires an initializer">;
def err_reference_has_multiple_inits : Error<
"reference cannot be initialized with multiple values">;
def err_init_non_aggr_init_list : Error<
@@ -597,13 +616,16 @@ def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
def err_temp_copy_no_viable : Error<
"no viable copy constructor %select{copying variable|copying parameter|"
- "returning object|throwing object}0 of type %1">;
+ "returning object|throwing object|copying member subobject|copying array "
+ "element}0 of type %1">;
def err_temp_copy_ambiguous : Error<
"ambiguous copy constructor call when %select{copying variable|copying "
- "parameter|returning object|throwing object}0 of type %1">;
+ "parameter|returning object|throwing object|copying member subobject|copying "
+ "array element}0 of type %1">;
def err_temp_copy_deleted : Error<
"%select{copying variable|copying parameter|returning object|throwing "
- "object}0 of type %1 invokes deleted copy constructor">;
+ "object|copying member subobject|copying array element}0 of type %1 invokes "
+ "deleted copy constructor">;
// C++0x decltype
def err_cannot_determine_declared_type_of_overloaded_function : Error<
@@ -702,6 +724,9 @@ def err_attribute_aligned_not_power_of_two : Error<
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"'%0' redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
+def warn_faap_attribute_ignored : Warning<
+ "force_align_arg_pointer used on function pointer; attribute ignored">,
+ InGroup<ForceAlignArgPointer>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
def warn_attribute_void_function : Warning<
@@ -728,13 +753,18 @@ def err_attribute_wrong_decl_type : Error<
"parameter or Objective-C method |function, method or block|"
"virtual method or class|function, method, or parameter|class|virtual method"
"|member}1 types">;
+def warn_function_attribute_wrong_type : Warning<
+ "%0 only applies to function types; type here is %1">;
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">;
+def err_cconv_change : Error<
+ "function declared '%0' here was previously declared "
+ "%select{'%2'|without calling convention}1">;
def err_cconv_knr : Error<
- "function with no prototype cannot use '%0' calling convention">;
+ "function with no prototype cannot use %0 calling convention">;
def err_cconv_varargs : Error<
- "variadic function cannot use '%0' calling convention">;
+ "variadic function cannot use %0 calling convention">;
def warn_impcast_vector_scalar : Warning<
"implicit cast turns vector to scalar: %0 to %1">,
@@ -873,10 +903,7 @@ def err_uninitialized_member_for_assign : Error<
"assignment operator">;
def note_first_required_here : Note<
"synthesized method is first required here">;
-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<
+def err_uninitialized_member_in_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{reference|const}2 member %3">;
@@ -915,6 +942,12 @@ def note_ovl_candidate : Note<"candidate "
"is the implicit default constructor|"
"is the implicit copy constructor|"
"is the implicit copy assignment operator}0%1">;
+
+def note_ovl_candidate_bad_deduction : Note<
+ "candidate template ignored: failed template argument deduction">;
+def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
+ "couldn't infer template argument %0">;
+
// Note that we don't treat templates differently for this diagnostic.
def note_ovl_candidate_arity : Note<"candidate "
"%select{function|function|constructor|function|function|constructor|"
@@ -941,6 +974,13 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
"constructor (the implicit copy constructor)|"
"function (the implicit copy assignment operator)}0%1 "
"not viable: cannot convert argument of incomplete type %2 to %3">;
+def note_ovl_candidate_bad_overload : Note<"candidate "
+ "%select{function|function|constructor|"
+ "function |function |constructor |"
+ "constructor (the implicit default constructor)|"
+ "constructor (the implicit copy constructor)|"
+ "function (the implicit copy assignment operator)}0%1"
+ " not viable: no overload of %3 matching %2 for %ordinal4 argument">;
def note_ovl_candidate_bad_conv : Note<"candidate "
"%select{function|function|constructor|"
"function |function |constructor |"
@@ -1068,9 +1108,6 @@ def err_template_tag_noparams : Error<
def err_template_decl_ref : Error<
"cannot refer to class template %0 without a template argument list">;
-def err_typedef_in_def_scope : Error<
- "cannot use typedef %0 in scope specifier for out-of-line declaration">;
-
// C++ Template Argument Lists
def err_template_arg_list_different_arity : Error<
"%select{too few|too many}0 template arguments for "
@@ -1122,6 +1159,8 @@ def err_template_arg_no_ref_bind : Error<
def err_template_arg_ref_bind_ignores_quals : Error<
"reference binding of non-type template parameter of type %0 to template "
"argument of type %1 ignores qualifiers">;
+def err_template_arg_not_decl_ref : Error<
+ "non-type template argument does not refer to any declaration">;
def err_template_arg_not_object_or_func_form : Error<
"non-type template argument does not directly refer to an object or "
"function">;
@@ -1236,6 +1275,8 @@ def err_partial_spec_redeclared : Error<
"class template partial specialization %0 cannot be redeclared">;
def note_prev_partial_spec_here : Note<
"previous declaration of class template partial specialization %0 is here">;
+def err_partial_spec_fully_specialized : Error<
+ "partial specialization of %0 does not use any of its template parameters">;
// C++ Function template specializations
def err_function_template_spec_no_match : Error<
@@ -1442,9 +1483,13 @@ def err_forward_ref_enum : Error<
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
def ext_enum_value_not_int : Extension<
- "ISO C restricts enumerator values to range of 'int' (%0 is too large)">;
+ "ISO C restricts enumerator values to range of 'int' (%0 is too "
+ "%select{small|large}1)">;
def warn_enum_too_large : Warning<
"enumeration values exceed range of largest integer">;
+def warn_enumerator_too_large : Warning<
+ "enumerator value %0 is not representable in the largest integer type">;
+
def warn_illegal_constant_array_size : Extension<
"size of static array must be an integer constant expression">;
def err_vla_decl_in_file_scope : Error<
@@ -1677,6 +1722,8 @@ def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
def err_no_member : Error<"no member named %0 in %1">;
def err_member_redeclared : Error<"class member cannot be redeclared">;
+def err_member_def_undefined_record : Error<
+ "out-of-line definition of %0 from class %1 without definition">;
def err_member_def_does_not_match : Error<
"out-of-line definition of %0 does not match any declaration in %1">;
def err_nonstatic_member_out_of_line : Error<
@@ -1824,7 +1871,11 @@ def ext_integer_complement_complex : Extension<
def error_nosetter_property_assignment : Error<
"setter method is needed to assign to object using property" " assignment syntax">;
def error_no_subobject_property_setting : Error<
- "cannot assign to a sub-structure of an ivar using property" " assignment syntax">;
+ "cannot assign to a sub-structure of an ivar using property"
+ " assignment syntax">;
+def error_no_subobject_property_getter_setting : Error<
+ "cannot assign to a sub-structure returned via a getter using property"
+ " assignment syntax">;
def ext_freestanding_complex : Extension<
"complex numbers are an extension in a freestanding C99 implementation">;
@@ -1915,7 +1966,9 @@ def err_ambiguous_base_to_derived_cast : Error<
def err_static_downcast_via_virtual : Error<
"cannot cast %0 to %1 via virtual base %2">;
def err_downcast_from_inaccessible_base : Error<
- "cannot cast %1 to %0 due to inaccessible conversion path">;
+ "cannot cast %select{private|protected}2 base class %1 to %0">;
+def err_upcast_to_inaccessible_base : Error<
+ "cannot cast %0 to its %select{private|protected}2 base class %1">;
def err_bad_dynamic_cast_not_ref_or_ptr : Error<
"%0 is not a reference or pointer">;
def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
@@ -1942,7 +1995,8 @@ def err_new_paren_array_nonconst : Error<
def err_array_size_not_integral : Error<
"array size expression must have integral or enumerated type, not %0">;
def err_default_init_const : Error<
- "default initialization of an object of const type %0">;
+ "default initialization of an object of const type %0"
+ "%select{| requires a user-provided default constructor}1">;
def err_delete_operand : Error<"cannot delete expression of type %0">;
def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
"expression of type %0 to a pointer">;
@@ -2245,8 +2299,6 @@ def error_multiple_base_initialization : Error <
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
-def err_mem_initializer_mismatch : Error<
- "Too many arguments for member initializer %0">;
def warn_field_initialized : Warning<
"member '%0' will be initialized after">,
@@ -2435,11 +2487,16 @@ def warn_printf_write_back : Warning<
def warn_printf_insufficient_data_args : Warning<
"more '%%' conversions than data arguments">, InGroup<Format>;
def warn_printf_too_many_data_args : Warning<
- "more data arguments than '%%' conversions">, InGroup<FormatExtraArgs>;
+ "more data arguments than format specifiers">, InGroup<FormatExtraArgs>;
def warn_printf_invalid_conversion : Warning<
- "invalid conversion '%0'">, InGroup<Format>;
+ "invalid conversion specifier '%0'">, InGroup<Format>;
+def warn_printf_incomplete_specifier : Warning<
+ "incomplete format specifier">, InGroup<Format>;
def warn_printf_missing_format_string : Warning<
"format string missing">, InGroup<Format>;
+def warn_printf_conversion_argument_type_mismatch : Warning<
+ "conversion specifies type %0 but the argument has type %1">,
+ InGroup<Format>;
def warn_null_arg : Warning<
"null passed to a callee which requires a non-null argument">,
InGroup<NonNull>;
@@ -2454,12 +2511,18 @@ def warn_printf_asterisk_width_missing_arg : Warning<
def warn_printf_asterisk_precision_missing_arg : Warning<
"'.*' specified field precision is missing a matching 'int' argument">;
def warn_printf_asterisk_width_wrong_type : Warning<
- "field width should have type 'int', but argument has type %0">,
+ "field width should have type %0, but argument has type %1">,
InGroup<Format>;
def warn_printf_asterisk_precision_wrong_type : Warning<
- "field precision should have type 'int', but argument has type %0">,
+ "field precision should have type %0, but argument has type %1">,
InGroup<Format>;
-
+def warn_printf_nonsensical_precision: Warning<
+ "precision used in '%0' conversion specifier (where it has no meaning)">,
+ InGroup<Format>;
+def warn_printf_nonsensical_flag: Warning<
+ "flag '%0' results in undefined behavior in '%1' conversion specifier">,
+ InGroup<Format>;
+
// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr : Warning<
"address of stack memory associated with local variable %0 returned">;
@@ -2511,6 +2574,10 @@ def warn_case_value_overflow : Warning<
"overflow converting case value to switch condition type (%0 to %1)">;
def err_duplicate_case : Error<"duplicate case value '%0'">;
def warn_case_empty_range : Warning<"empty case range specified">;
+def warn_missing_cases : Warning<"enumeration value %0 not handled in switch">,
+ InGroup<DiagGroup<"switch-enum"> >;
+def not_in_enum : Warning<"case value not in enumerated type %0">,
+ InGroup<DiagGroup<"switch-enum"> >;
def err_typecheck_statement_requires_scalar : Error<
"statement requires expression of scalar type (%0 invalid)">;
def err_typecheck_statement_requires_integer : Error<
@@ -2679,6 +2746,7 @@ def err_undeclared_protocol_suggest : Error<
"cannot find protocol declaration for %0; did you mean %1?">;
def note_base_class_specified_here : Note<
"base class %0 specified here">;
+
}
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 2b6092dea309..d909f83e74d5 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -40,12 +40,14 @@ public:
unsigned ObjC1 : 1; // Objective-C 1 support enabled.
unsigned ObjC2 : 1; // Objective-C 2 support enabled.
unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
+ unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled
unsigned PascalStrings : 1; // Allow Pascal strings
unsigned WritableStrings : 1; // Allow writable strings
unsigned LaxVectorConversions : 1;
unsigned AltiVec : 1; // Support AltiVec-style vector initializers.
unsigned Exceptions : 1; // Support exception handling.
+ unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling.
unsigned RTTI : 1; // Support RTTI information.
unsigned NeXTRuntime : 1; // Use NeXT runtime.
@@ -95,7 +97,9 @@ public:
// operators
unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
// elided if possible.
- unsigned CatchUndefined :1; // Generate code to check for undefined ops.
+ unsigned CatchUndefined : 1; // Generate code to check for undefined ops.
+ unsigned DumpVtableLayouts : 1; // Dump the layouts of all the emitted
+ // vtables.
private:
unsigned GC : 2; // Objective-C Garbage Collection modes. We
// declare this enum as unsigned because MSVC
@@ -124,10 +128,10 @@ public:
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
GNUMode = ImplicitInt = Digraphs = 0;
HexFloats = 0;
- GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
+ GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = 0;
- Exceptions = Freestanding = NoBuiltin = 0;
+ Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
NeXTRuntime = 1;
RTTI = 1;
LaxVectorConversions = 1;
@@ -136,8 +140,7 @@ public:
SymbolVisibility = (unsigned) Default;
- // FIXME: The default should be 1.
- ThreadsafeStatics = 0;
+ ThreadsafeStatics = 1;
POSIXThreads = 0;
Blocks = 0;
BlockIntrospection = 0;
@@ -167,6 +170,7 @@ public:
CharIsSigned = 1;
ShortWChar = 0;
CatchUndefined = 0;
+ DumpVtableLayouts = 0;
}
GCMode getGCMode() const { return (GCMode) GC; }
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
new file mode 100644
index 000000000000..de0de348d351
--- /dev/null
+++ b/include/clang/Basic/Linkage.h
@@ -0,0 +1,57 @@
+//===--- Linkage.h - Linkage enumeration and utilities ----------*- 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 Linkage enumeration and various utility
+// functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_LINKAGE_H
+#define LLVM_CLANG_BASIC_LINKAGE_H
+
+namespace clang {
+
+/// \brief Describes the different kinds of linkage
+/// (C++ [basic.link], C99 6.2.2) that an entity may have.
+enum Linkage {
+ /// \brief No linkage, which means that the entity is unique and
+ /// can only be referred to from within its scope.
+ NoLinkage = 0,
+
+ /// \brief Internal linkage, which indicates that the entity can
+ /// be referred to from within the translation unit (but not other
+ /// translation units).
+ InternalLinkage,
+
+ /// \brief External linkage within a unique namespace. From the
+ /// langauge perspective, these entities have external
+ /// linkage. However, since they reside in an anonymous namespace,
+ /// their names are unique to this translation unit, which is
+ /// equivalent to having internal linkage from the code-generation
+ /// point of view.
+ UniqueExternalLinkage,
+
+ /// \brief External linkage, which indicates that the entity can
+ /// be referred to from other translation units.
+ ExternalLinkage
+};
+
+/// \brief Determine whether the given linkage is semantically
+/// external.
+inline bool isExternalLinkage(Linkage L) {
+ return L == UniqueExternalLinkage || L == ExternalLinkage;
+}
+
+/// \brief Compute the minimum linkage given two linages.
+static inline Linkage minLinkage(Linkage L1, Linkage L2) {
+ return L1 < L2? L1 : L2;
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_LINKAGE_H
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 0d970123f745..873aaeecb6bf 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -1,4 +1,4 @@
-//===--- PartialDiagnostic.h - Diagnostic "closures" ----------------------===//
+//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index b4cf959dc551..15ece685104c 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -669,12 +669,20 @@ public:
::const_iterator fileinfo_iterator;
fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
+ bool hasFileInfo(const FileEntry *File) const {
+ return FileInfos.find(File) != FileInfos.end();
+ }
/// PrintStats - Print statistics to stderr.
///
void PrintStats() const;
unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
+
+ // FIXME: Exposing this is a little gross; what we want is a good way
+ // to iterate the entries that were not defined in a PCH file (or
+ // any other external source).
+ unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
assert(ID < SLocEntryTable.size() && "Invalid id");
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 4cace86dd18d..9e54762add7d 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -77,6 +77,7 @@ namespace clang {
AS_private,
AS_none
};
-}
+
+} // end namespace clang
#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 97e0495bfbe2..bc2cf198c3f5 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -226,11 +226,11 @@ public:
/// isValidGCCRegisterName - Returns whether the passed in string
/// is a valid register name according to GCC. This is used by Sema for
/// inline asm statements.
- bool isValidGCCRegisterName(const char *Name) const;
+ bool isValidGCCRegisterName(llvm::StringRef Name) const;
// getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
// For example, on x86 it will return "ax" when "eax" is passed in.
- const char *getNormalizedGCCRegisterName(const char *Name) const;
+ llvm::StringRef getNormalizedGCCRegisterName(llvm::StringRef Name) const;
struct ConstraintInfo {
enum {
@@ -246,10 +246,9 @@ public:
std::string ConstraintStr; // constraint: "=rm"
std::string Name; // Operand name: [foo] with no []'s.
public:
- ConstraintInfo(const char *str, unsigned strlen, const std::string &name)
- : Flags(0), TiedOperand(-1), ConstraintStr(str, str+strlen), Name(name) {}
- explicit ConstraintInfo(const std::string &Str, const std::string &name)
- : Flags(0), TiedOperand(-1), ConstraintStr(Str), Name(name) {}
+ ConstraintInfo(llvm::StringRef ConstraintStr, llvm::StringRef Name)
+ : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
+ Name(Name.str()) {}
const std::string &getConstraintStr() const { return ConstraintStr; }
const std::string &getName() const { return Name; }
@@ -321,12 +320,6 @@ public:
virtual bool useGlobalsForAutomaticVariables() const { return false; }
- /// getUnicodeStringSection - Return the section to use for unicode
- /// string literals, or 0 if no special section is used.
- virtual const char *getUnicodeStringSection() const {
- return 0;
- }
-
/// getCFStringSection - Return the section to use for CFString
/// literals, or 0 if no special section is used.
virtual const char *getCFStringSection() const {
@@ -343,7 +336,7 @@ public:
/// and give good diagnostics in cases when the assembler or code generator
/// would otherwise reject the section specifier.
///
- virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
+ virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
return "";
}
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index bb022f11759d..522ac13b4e32 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -227,7 +227,7 @@ KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , BOOLSUPPORT)
+KEYWORD(bool , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@@ -235,7 +235,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
-KEYWORD(false , BOOLSUPPORT)
+KEYWORD(false , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@@ -249,7 +249,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
-KEYWORD(true , BOOLSUPPORT)
+KEYWORD(true , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
@@ -340,6 +340,10 @@ KEYWORD(__ptr64 , KEYALL)
KEYWORD(__w64 , KEYALL)
KEYWORD(__forceinline , KEYALL)
+// Altivec Extension.
+KEYWORD(__vector , KEYALTIVEC)
+KEYWORD(__pixel , KEYALTIVEC)
+
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
ALIAS("__attribute__", __attribute, KEYALL)
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 4710b6b608e6..2728637ba497 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -56,16 +56,16 @@ namespace clang {
/// \brief Retrieves the repository revision number (or identifer) from which
/// this Clang was built.
- llvm::StringRef getClangRevision();
+ std::string getClangRevision();
/// \brief Retrieves the full repository version that is an amalgamation of
/// the information in getClangRepositoryPath() and getClangRevision().
- llvm::StringRef getClangFullRepositoryVersion();
+ std::string getClangFullRepositoryVersion();
/// \brief Retrieves a string representing the complete clang version,
/// which includes the clang version number, the repository version,
/// and the vendor tag.
- const char *getClangFullVersion();
+ std::string getClangFullVersion();
}
#endif // LLVM_CLANG_BASIC_VERSION_H
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h
index 6f6681a3629b..6c41668ccece 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Checker/BugReporter/BugReporter.h
@@ -17,9 +17,9 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/BugType.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/BugReporter/BugType.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
@@ -202,7 +202,7 @@ public:
~RangedBugReport();
// FIXME: Move this out of line.
- void addRange(SourceRange R) {
+ void addRange(SourceRange R) {
assert(R.isValid());
Ranges.push_back(R);
}
@@ -464,6 +464,10 @@ const Stmt *GetRetValExpr(const ExplodedNode *N);
void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
const ExplodedNode* N);
+void registerFindLastStore(BugReporterContext& BRC, const void *memregion,
+ const ExplodedNode *N);
+
+
} // end namespace clang::bugreporter
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Checker/BugReporter/BugType.h
index b75a8189e54c..4f1523a5440d 100644
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ b/include/clang/Checker/BugReporter/BugType.h
@@ -14,7 +14,6 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
#define LLVM_CLANG_ANALYSIS_BUGTYPE
-#include "clang/Analysis/PathSensitive/BugReporter.h"
#include <llvm/ADT/FoldingSet.h>
#include <string>
diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Checker/BugReporter/PathDiagnostic.h
index d380c45480cb..d380c45480cb 100644
--- a/include/clang/Analysis/PathDiagnostic.h
+++ b/include/clang/Checker/BugReporter/PathDiagnostic.h
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Checker/Checkers/DereferenceChecker.h
index a84183e7f27f..a84183e7f27f 100644
--- a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
+++ b/include/clang/Checker/Checkers/DereferenceChecker.h
diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Checker/Checkers/LocalCheckers.h
index 9c343e078641..4a9e381a7c15 100644
--- a/include/clang/Analysis/LocalCheckers.h
+++ b/include/clang/Checker/Checkers/LocalCheckers.h
@@ -31,13 +31,11 @@ class BugReporter;
class ObjCImplementationDecl;
class LangOptions;
class GRExprEngine;
+class TranslationUnitDecl;
void CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &map,
BugReporter& BR);
-void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
- bool FullUninitTaint=false);
-
GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
const LangOptions& lopts);
@@ -53,8 +51,8 @@ void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
void RegisterExperimentalChecks(GRExprEngine &Eng);
void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
+void CheckLLVMConventions(TranslationUnitDecl &TU, BugReporter &BR);
void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
-
void CheckSizeofPointer(const Decl *D, BugReporter &BR);
void RegisterCallInliner(GRExprEngine &Eng);
diff --git a/include/clang/Checker/DomainSpecific/CocoaConventions.h b/include/clang/Checker/DomainSpecific/CocoaConventions.h
new file mode 100644
index 000000000000..ee3d648b8608
--- /dev/null
+++ b/include/clang/Checker/DomainSpecific/CocoaConventions.h
@@ -0,0 +1,40 @@
+//===- CocoaConventions.h - Special handling of Cocoa conventions -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_DS_COCOA
+#define LLVM_CLANG_CHECKER_DS_COCOA
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+namespace cocoa {
+
+ enum NamingConvention { NoConvention, CreateRule, InitRule };
+
+ NamingConvention deriveNamingConvention(Selector S);
+
+ static inline bool followsFundamentalRule(Selector S) {
+ return deriveNamingConvention(S) == CreateRule;
+ }
+
+ bool isRefType(QualType RetTy, llvm::StringRef Prefix,
+ llvm::StringRef Name = llvm::StringRef());
+
+ bool isCFObjectRef(QualType T);
+
+ bool isCocoaObjectRef(QualType T);
+
+}}
+
+#endif
diff --git a/include/clang/Analysis/ManagerRegistry.h b/include/clang/Checker/ManagerRegistry.h
index 972993855c28..ebfd28e10930 100644
--- a/include/clang/Analysis/ManagerRegistry.h
+++ b/include/clang/Checker/ManagerRegistry.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
-#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRState.h"
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h
index 8288864f2b61..fdf52a7dc770 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ b/include/clang/Checker/PathSensitive/AnalysisManager.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/AnalysisContext.h"
-#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/include/clang/Checker/PathSensitive/BasicValueFactory.h
index 12f0ce2d50b7..2f0b6c2a0348 100644
--- a/include/clang/Analysis/PathSensitive/BasicValueFactory.h
+++ b/include/clang/Checker/PathSensitive/BasicValueFactory.h
@@ -16,8 +16,8 @@
#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/APSInt.h"
@@ -46,19 +46,19 @@ public:
};
class LazyCompoundValData : public llvm::FoldingSetNode {
- const GRState *state;
+ const void *store;
const TypedRegion *region;
public:
- LazyCompoundValData(const GRState *st, const TypedRegion *r)
- : state(st), region(r) {}
+ LazyCompoundValData(const void *st, const TypedRegion *r)
+ : store(st), region(r) {}
- const GRState *getState() const { return state; }
+ const void *getStore() const { return store; }
const TypedRegion *getRegion() const { return region; }
- static void Profile(llvm::FoldingSetNodeID& ID, const GRState *state,
+ static void Profile(llvm::FoldingSetNodeID& ID, const void *store,
const TypedRegion *region);
- void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, state, region); }
+ void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
};
class BasicValueFactory {
@@ -169,7 +169,7 @@ public:
const CompoundValData *getCompoundValData(QualType T,
llvm::ImmutableList<SVal> Vals);
- const LazyCompoundValData *getLazyCompoundValData(const GRState *state,
+ const LazyCompoundValData *getLazyCompoundValData(const void *store,
const TypedRegion *region);
llvm::ImmutableList<SVal> getEmptySValList() {
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h
index 924a8b11b098..d498044b82ca 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Checker/PathSensitive/Checker.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_CHECKER
#define LLVM_CLANG_ANALYSIS_CHECKER
#include "clang/Analysis/Support/SaveAndRestore.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtCXX.h"
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Checker/PathSensitive/CheckerVisitor.def
index 7ec27efe5199..2edc4a37b7eb 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.def
+++ b/include/clang/Checker/PathSensitive/CheckerVisitor.def
@@ -22,7 +22,6 @@
PREVISIT(ArraySubscriptExpr, Stmt)
PREVISIT(BinaryOperator, Stmt)
PREVISIT(CallExpr, Stmt)
-PREVISIT(CastExpr, Stmt)
PREVISIT(CXXOperatorCallExpr, CallExpr)
PREVISIT(DeclStmt, Stmt)
PREVISIT(ObjCMessageExpr, Stmt)
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Checker/PathSensitive/CheckerVisitor.h
index 37ec8def50b3..72f0ae1375e8 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.h
+++ b/include/clang/Checker/PathSensitive/CheckerVisitor.h
@@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_ANALYSIS_CHECKERVISITOR
#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR
-#include "clang/Analysis/PathSensitive/Checker.h"
+#include "clang/Checker/PathSensitive/Checker.h"
namespace clang {
@@ -42,7 +42,6 @@ public:
return;
case Stmt::ImplicitCastExprClass:
- case Stmt::ExplicitCastExprClass:
case Stmt::CStyleCastExprClass:
static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
static_cast<const CastExpr*>(S));
@@ -57,7 +56,7 @@ public:
case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
break;
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
}
}
@@ -76,24 +75,26 @@ case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->\
PostVisit ## NAME(C,static_cast<const NAME*>(S));\
break;
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
}
}
void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
+
+ void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
+ static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
+ }
#define PREVISIT(NAME, FALLBACK) \
void PreVisit ## NAME(CheckerContext &C, const NAME* S) {\
- PreVisit ## FALLBACK(C, S);\
+ static_cast<ImplClass*>(this)->PreVisit ## FALLBACK(C, S);\
}
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
-
#define POSTVISIT(NAME, FALLBACK) \
void PostVisit ## NAME(CheckerContext &C, const NAME* S) {\
- PostVisit ## FALLBACK(C, S);\
+ static_cast<ImplClass*>(this)->PostVisit ## FALLBACK(C, S);\
}
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+#include "clang/Checker/PathSensitive/CheckerVisitor.def"
};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Checker/PathSensitive/ConstraintManager.h
index c8292802ae9d..ce7d1b381714 100644
--- a/include/clang/Analysis/PathSensitive/ConstraintManager.h
+++ b/include/clang/Checker/PathSensitive/ConstraintManager.h
@@ -15,7 +15,7 @@
#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place.
-#include "clang/Analysis/PathSensitive/Store.h"
+#include "clang/Checker/PathSensitive/Store.h"
namespace llvm {
class APSInt;
diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h
index 6d5c5678e59b..0852c31faeb6 100644
--- a/include/clang/Analysis/PathSensitive/Environment.h
+++ b/include/clang/Checker/PathSensitive/Environment.h
@@ -16,11 +16,11 @@
// For using typedefs in StoreManager. Should find a better place for these
// typedefs.
-#include "clang/Analysis/PathSensitive/Store.h"
+#include "clang/Checker/PathSensitive/Store.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/SVals.h"
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Checker/PathSensitive/ExplodedGraph.h
index fb5e1b8a415f..d6c4436c594c 100644
--- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h
+++ b/include/clang/Checker/PathSensitive/ExplodedGraph.h
@@ -16,7 +16,7 @@
#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Analysis/PathSensitive/AnalysisContext.h"
+#include "clang/Analysis/AnalysisContext.h"
#include "clang/AST/Decl.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/FoldingSet.h"
diff --git a/include/clang/Analysis/PathSensitive/GRAuditor.h b/include/clang/Checker/PathSensitive/GRAuditor.h
index 015c82e80bb5..015c82e80bb5 100644
--- a/include/clang/Analysis/PathSensitive/GRAuditor.h
+++ b/include/clang/Checker/PathSensitive/GRAuditor.h
diff --git a/include/clang/Analysis/PathSensitive/GRBlockCounter.h b/include/clang/Checker/PathSensitive/GRBlockCounter.h
index 67ed9532db02..67ed9532db02 100644
--- a/include/clang/Analysis/PathSensitive/GRBlockCounter.h
+++ b/include/clang/Checker/PathSensitive/GRBlockCounter.h
diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
index 74f7a147b841..6da45815f996 100644
--- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -16,11 +16,11 @@
#define LLVM_CLANG_ANALYSIS_GRENGINE
#include "clang/AST/Expr.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/GRWorkList.h"
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
-#include "clang/Analysis/PathSensitive/GRAuditor.h"
-#include "clang/Analysis/PathSensitive/GRSubEngine.h"
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/GRWorkList.h"
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
+#include "clang/Checker/PathSensitive/GRAuditor.h"
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
index df90ad9f7f08..90a2cd55972a 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -16,13 +16,13 @@
#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
-#include "clang/Analysis/PathSensitive/AnalysisManager.h"
-#include "clang/Analysis/PathSensitive/GRSubEngine.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
#include "clang/AST/Type.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprCXX.h"
@@ -328,17 +328,6 @@ protected:
void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue);
- void VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
- ObjCMessageExpr::arg_iterator I,
- ObjCMessageExpr::arg_iterator E,
- ExplodedNode* Pred, ExplodedNodeSet& Dst,
- bool asLValue);
-
- void VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
- ExplodedNode* Pred,
- ExplodedNodeSet& Dst,
- bool asLValue);
-
/// VisitReturnStmt - Transfer function logic for return statements.
void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h b/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h
index 60db406cd13d..5503412f7e45 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
#define LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/Support/SaveAndRestore.h"
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
index 978ff0889e64..383463b822cb 100644
--- a/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
+++ b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
@@ -16,8 +16,8 @@
#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS
#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
-#include "clang/Analysis/PathSensitive/GRAuditor.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRAuditor.h"
+#include "clang/Checker/PathSensitive/GRState.h"
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
index 11cdac0e96de..4e44697a272f 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -16,11 +16,11 @@
// FIXME: Reduce the number of includes.
-#include "clang/Analysis/PathSensitive/Environment.h"
-#include "clang/Analysis/PathSensitive/Store.h"
-#include "clang/Analysis/PathSensitive/ConstraintManager.h"
-#include "clang/Analysis/PathSensitive/ValueManager.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/Environment.h"
+#include "clang/Checker/PathSensitive/Store.h"
+#include "clang/Checker/PathSensitive/ConstraintManager.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/ASTContext.h"
@@ -216,7 +216,7 @@ public:
/// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
- const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
+ const GRState *bindCompoundLiteral(const CompoundLiteralExpr* CL,
const LocationContext *LC,
SVal V) const;
@@ -607,19 +607,24 @@ inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
inline const GRState *
GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
const LocationContext *LC, SVal V) const {
- return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, LC, V);
+ Store new_store =
+ getStateManager().StoreMgr->BindCompoundLiteral(St, CL, LC, V);
+ return makeWithStore(new_store);
}
inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
- return getStateManager().StoreMgr->BindDecl(this, VR, IVal);
+ Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal);
+ return makeWithStore(new_store);
}
inline const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
- return getStateManager().StoreMgr->BindDeclWithNoInit(this, VR);
+ Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR);
+ return makeWithStore(new_store);
}
inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
- return getStateManager().StoreMgr->Bind(this, LV, V);
+ Store new_store = getStateManager().StoreMgr->Bind(St, LV, V);
+ return makeWithStore(new_store);
}
inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
@@ -671,11 +676,11 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
}
inline SVal GRState::getSVal(Loc LV, QualType T) const {
- return getStateManager().StoreMgr->Retrieve(this, LV, T).getSVal();
+ return getStateManager().StoreMgr->Retrieve(St, LV, T);
}
inline SVal GRState::getSVal(const MemRegion* R) const {
- return getStateManager().StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
+ return getStateManager().StoreMgr->Retrieve(St, loc::MemRegionVal(R));
}
inline BasicValueFactory &GRState::getBasicVals() const {
diff --git a/include/clang/Analysis/PathSensitive/GRStateTrait.h b/include/clang/Checker/PathSensitive/GRStateTrait.h
index 5189a1f5aa7e..5189a1f5aa7e 100644
--- a/include/clang/Analysis/PathSensitive/GRStateTrait.h
+++ b/include/clang/Checker/PathSensitive/GRStateTrait.h
diff --git a/include/clang/Analysis/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h
index 5b383fae9bd0..ce57c2c68b4b 100644
--- a/include/clang/Analysis/PathSensitive/GRSubEngine.h
+++ b/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
#define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
-#include "clang/Analysis/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/SVals.h"
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
index b058460a4934..04634effd587 100644
--- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_GRTF
#define LLVM_CLANG_ANALYSIS_GRTF
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/GRState.h"
#include <vector>
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/GRWorkList.h b/include/clang/Checker/PathSensitive/GRWorkList.h
index 857fa316911f..b8f90fa1eea1 100644
--- a/include/clang/Analysis/PathSensitive/GRWorkList.h
+++ b/include/clang/Checker/PathSensitive/GRWorkList.h
@@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
#define LLVM_CLANG_ANALYSIS_GRWORKLIST
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+#include "clang/Checker/PathSensitive/GRBlockCounter.h"
#include <cstddef>
namespace clang {
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
index 3bcedbefd65c..12bc0b795685 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -18,8 +18,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/FoldingSet.h"
@@ -249,17 +249,20 @@ public:
class ElementRegion;
-class RegionRawOffset : public std::pair<const MemRegion*, int64_t> {
+class RegionRawOffset {
private:
friend class ElementRegion;
+ const MemRegion *Region;
+ int64_t Offset;
+
RegionRawOffset(const MemRegion* reg, int64_t offset = 0)
- : std::pair<const MemRegion*, int64_t>(reg, offset) {}
+ : Region(reg), Offset(offset) {}
public:
// FIXME: Eventually support symbolic offsets.
- int64_t getByteOffset() const { return second; }
- const MemRegion *getRegion() const { return first; }
+ int64_t getByteOffset() const { return Offset; }
+ const MemRegion *getRegion() const { return Region; }
void dumpToStream(llvm::raw_ostream& os) const;
void dump() const;
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h
index 9206817989db..65a8a2c01df5 100644
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ b/include/clang/Checker/PathSensitive/SVals.h
@@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
#define LLVM_CLANG_ANALYSIS_RVALUE_H
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/ImmutableList.h"
@@ -388,7 +388,7 @@ public:
const LazyCompoundValData *getCVData() const {
return static_cast<const LazyCompoundValData*>(Data);
}
- const GRState *getState() const;
+ const void *getStore() const;
const TypedRegion *getRegion() const;
static bool classof(const SVal *V) {
diff --git a/include/clang/Analysis/PathSensitive/SValuator.h b/include/clang/Checker/PathSensitive/SValuator.h
index 4a4b502c6271..9beb8cb08661 100644
--- a/include/clang/Analysis/PathSensitive/SValuator.h
+++ b/include/clang/Checker/PathSensitive/SValuator.h
@@ -16,7 +16,7 @@
#define LLVM_CLANG_ANALYSIS_SVALUATOR
#include "clang/AST/Expr.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/SVals.h"
namespace clang {
@@ -38,33 +38,8 @@ public:
SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
virtual ~SValuator() {}
- template <typename T>
- class GenericCastResult : public std::pair<const GRState *, T> {
- public:
- const GRState *getState() const { return this->first; }
- T getSVal() const { return this->second; }
- GenericCastResult(const GRState *s, T v)
- : std::pair<const GRState*,T>(s, v) {}
- };
+ SVal EvalCast(SVal V, QualType castTy, QualType originalType);
- class CastResult : public GenericCastResult<SVal> {
- public:
- CastResult(const GRState *s, SVal v) : GenericCastResult<SVal>(s, v) {}
- };
-
- class DefinedOrUnknownCastResult :
- public GenericCastResult<DefinedOrUnknownSVal> {
- public:
- DefinedOrUnknownCastResult(const GRState *s, DefinedOrUnknownSVal v)
- : GenericCastResult<DefinedOrUnknownSVal>(s, v) {}
- };
-
- CastResult EvalCast(SVal V, const GRState *ST,
- QualType castTy, QualType originalType);
-
- DefinedOrUnknownCastResult EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
- QualType castTy, QualType originalType);
-
virtual SVal EvalMinus(NonLoc val) = 0;
virtual SVal EvalComplement(NonLoc val) = 0;
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h
index 5606df0014f0..c660e7b7feee 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Checker/PathSensitive/Store.h
@@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_ANALYSIS_STORE_H
#define LLVM_CLANG_ANALYSIS_STORE_H
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/Analysis/PathSensitive/ValueManager.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
@@ -41,6 +41,7 @@ protected:
/// MRMgr - Manages region objects associated with this StoreManager.
MemRegionManager &MRMgr;
+ ASTContext &Ctx;
StoreManager(GRStateManager &stateMgr);
@@ -54,8 +55,7 @@ public:
/// expected type of the returned value. This is used if the value is
/// lazily computed.
/// \return The value bound to the location \c loc.
- virtual SValuator::CastResult Retrieve(const GRState *state, Loc loc,
- QualType T = QualType()) = 0;
+ virtual SVal Retrieve(Store store, Loc loc, QualType T = QualType()) = 0;
/// Return a state with the specified value bound to the given location.
/// \param[in] state The analysis state.
@@ -64,7 +64,7 @@ public:
/// \return A pointer to a GRState object that contains the same bindings as
/// \c state with the addition of having the value specified by \c val bound
/// to the location given for \c loc.
- virtual const GRState *Bind(const GRState *state, Loc loc, SVal val) = 0;
+ virtual Store Bind(Store store, Loc loc, SVal val) = 0;
virtual Store Remove(Store St, Loc L) = 0;
@@ -72,10 +72,9 @@ public:
/// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
- virtual const GRState *BindCompoundLiteral(const GRState *state,
- const CompoundLiteralExpr* cl,
- const LocationContext *LC,
- SVal v) = 0;
+ virtual Store BindCompoundLiteral(Store store,
+ const CompoundLiteralExpr* cl,
+ const LocationContext *LC, SVal v) = 0;
/// getInitialStore - Returns the initial "empty" store representing the
/// value bindings upon entry to an analyzed function.
@@ -88,20 +87,30 @@ public:
/// getSubRegionMap - Returns an opaque map object that clients can query
/// to get the subregions of a given MemRegion object. It is the
// caller's responsibility to 'delete' the returned map.
- virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0;
+ virtual SubRegionMap *getSubRegionMap(Store store) = 0;
- virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) = 0;
+ virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) {
+ return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
+ }
- virtual SVal getLValueString(const StringLiteral* sl) = 0;
+ virtual SVal getLValueString(const StringLiteral* S) {
+ return ValMgr.makeLoc(MRMgr.getStringRegion(S));
+ }
- SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl,
- const LocationContext *LC);
+ SVal getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC) {
+ return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
+ }
- virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) = 0;
+ virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) {
+ return getLValueFieldOrIvar(decl, base);
+ }
- virtual SVal getLValueField(const FieldDecl* D, SVal Base) = 0;
+ virtual SVal getLValueField(const FieldDecl* D, SVal Base) {
+ return getLValueFieldOrIvar(D, Base);
+ }
- virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
+ virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
// FIXME: Make out-of-line.
virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
@@ -129,33 +138,31 @@ public:
const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
/// EvalBinOp - Perform pointer arithmetic.
- virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,
+ virtual SVal EvalBinOp(BinaryOperator::Opcode Op,
Loc lhs, NonLoc rhs, QualType resultTy) {
return UnknownVal();
}
- virtual void RemoveDeadBindings(GRState &state, Stmt* Loc,
- SymbolReaper& SymReaper,
+ virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
+ SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
- virtual const GRState *BindDecl(const GRState *ST, const VarRegion *VR,
- SVal initVal) = 0;
+ virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0;
- virtual const GRState *BindDeclWithNoInit(const GRState *ST,
- const VarRegion *VR) = 0;
+ virtual Store BindDeclWithNoInit(Store store, const VarRegion *VR) = 0;
typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
- virtual const GRState *InvalidateRegion(const GRState *state,
- const MemRegion *R,
- const Expr *E, unsigned Count,
- InvalidatedSymbols *IS) = 0;
+ virtual Store InvalidateRegion(Store store,
+ const MemRegion *R,
+ const Expr *E, unsigned Count,
+ InvalidatedSymbols *IS) = 0;
- virtual const GRState *InvalidateRegions(const GRState *state,
- const MemRegion * const *Begin,
- const MemRegion * const *End,
- const Expr *E, unsigned Count,
- InvalidatedSymbols *IS);
+ virtual Store InvalidateRegions(Store store,
+ const MemRegion * const *Begin,
+ const MemRegion * const *End,
+ const Expr *E, unsigned Count,
+ InvalidatedSymbols *IS);
// FIXME: Make out-of-line.
virtual const GRState *setExtent(const GRState *state,
@@ -192,6 +199,9 @@ protected:
/// as another region.
SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy,
bool performTestOnly = true);
+
+private:
+ SVal getLValueFieldOrIvar(const Decl* D, SVal Base);
};
// FIXME: Do we still need this?
@@ -214,7 +224,7 @@ public:
StoreManager *CreateBasicStoreManager(GRStateManager& StMgr);
StoreManager *CreateRegionStoreManager(GRStateManager& StMgr);
StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr);
-
+StoreManager *CreateFlatStoreManager(GRStateManager &StMgr);
} // end clang namespace
#endif
diff --git a/include/clang/Checker/PathSensitive/SummaryManager.h b/include/clang/Checker/PathSensitive/SummaryManager.h
new file mode 100644
index 000000000000..fd23189491b3
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/SummaryManager.h
@@ -0,0 +1,57 @@
+//== SummaryManager.h - Generic handling of function summaries --*- 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 SummaryManager and related classes, which provides
+// a generic mechanism for managing function summaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CHECKER_SUMMARY
+#define LLVM_CLANG_CHECKER_SUMMARY
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+namespace summMgr {
+
+
+/* Key kinds:
+
+ - C functions
+ - C++ functions (name + parameter types)
+ - ObjC methods:
+ - Class, selector (class method)
+ - Class, selector (instance method)
+ - Category, selector (instance method)
+ - Protocol, selector (instance method)
+ - C++ methods
+ - Class, function name + parameter types + const
+ */
+
+class SummaryKey {
+
+};
+
+} // end namespace clang::summMgr
+
+class SummaryManagerImpl {
+
+};
+
+
+template <typename T>
+class SummaryManager : SummaryManagerImpl {
+
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h
index 8eb319647953..8eb319647953 100644
--- a/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ b/include/clang/Checker/PathSensitive/SymbolManager.h
diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h
index 9cec3c421fbe..ea3af57ed3e4 100644
--- a/include/clang/Analysis/PathSensitive/ValueManager.h
+++ b/include/clang/Checker/PathSensitive/ValueManager.h
@@ -17,11 +17,11 @@
#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
#include "llvm/ADT/OwningPtr.h"
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/Analysis/PathSensitive/SValuator.h"
+#include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/BasicValueFactory.h"
+#include "clang/Checker/PathSensitive/SymbolManager.h"
+#include "clang/Checker/PathSensitive/SValuator.h"
namespace llvm { class BumpPtrAllocator; }
@@ -115,8 +115,8 @@ public:
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}
- NonLoc makeLazyCompoundVal(const GRState *state, const TypedRegion *R) {
- return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(state, R));
+ NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
+ return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
}
NonLoc makeZeroArrayIndex() {
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
index 8682715ce552..e1d4ad1b1cce 100644
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -41,6 +41,8 @@ public:
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
+ unsigned ObjCLegacyDispatch: 1; /// Use legacy Objective-C dispatch, even with
+ /// 2.0 runtime.
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
unsigned OptimizeSize : 1; /// If -Os is specified.
unsigned SoftFloat : 1; /// -soft-float.
@@ -90,12 +92,13 @@ public:
NoCommon = 0;
NoImplicitFloat = 0;
NoZeroInitializedInBSS = 0;
+ ObjCLegacyDispatch = 0;
OptimizationLevel = 0;
OptimizeSize = 0;
- UnrollLoops = 0;
SoftFloat = 0;
TimePasses = 0;
UnitAtATime = 1;
+ UnrollLoops = 0;
UnwindTables = 0;
VerifyModule = 1;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 2511dfb7677a..047363ea597b 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -38,19 +38,21 @@ def analysis_CFGView : Flag<"-cfg-view">,
HelpText<"View Control-Flow Graphs using GraphViz">;
def analysis_DisplayLiveVariables : Flag<"-dump-live-variables">,
HelpText<"Print results of live variable analysis">;
-def analysis_SecuritySyntacticChecks : Flag<"-warn-security-syntactic">,
+def analysis_LLVMConventionChecker : Flag<"-analyzer-check-llvm-conventions">,
+ HelpText<"Check code for LLVM codebase conventions (domain-specific)">;
+def analysis_SecuritySyntacticChecks : Flag<"-analyzer-check-security-syntactic">,
HelpText<"Perform quick security checks that require no data flow">;
-def analysis_WarnDeadStores : Flag<"-warn-dead-stores">,
+def analysis_WarnDeadStores : Flag<"-analyzer-check-dead-stores">,
HelpText<"Warn about stores to dead variables">;
def analysis_WarnUninitVals : Flag<"-warn-uninit-values">,
HelpText<"Warn about uses of uninitialized variables">;
-def analysis_WarnObjCMethSigs : Flag<"-warn-objc-methodsigs">,
+def analysis_WarnObjCMethSigs : Flag<"-analyzer-check-objc-methodsigs">,
HelpText<"Warn about Objective-C method signatures with type incompatibilities">;
-def analysis_WarnObjCDealloc : Flag<"-warn-objc-missing-dealloc">,
+def analysis_WarnObjCDealloc : Flag<"-analyzer-check-objc-missing-dealloc">,
HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">;
-def analysis_WarnObjCUnusedIvars : Flag<"-warn-objc-unused-ivars">,
+def analysis_WarnObjCUnusedIvars : Flag<"-analyzer-check-objc-unused-ivars">,
HelpText<"Warn about private ivars that are never used">;
-def analysis_CheckerCFRef : Flag<"-checker-cfref">,
+def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">,
HelpText<"Run the [Core] Foundation reference count checker">;
def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
@@ -102,6 +104,8 @@ def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
def disable_llvm_optzns : Flag<"-disable-llvm-optzns">,
HelpText<"Don't run LLVM optimization passes">;
+def disable_llvm_verifier : Flag<"-disable-llvm-verifier">,
+ HelpText<"Don't run the LLVM IR verifier pass">;
def disable_red_zone : Flag<"-disable-red-zone">,
HelpText<"Do not emit code that uses the red zone.">;
def dwarf_debug_flags : Separate<"-dwarf-debug-flags">,
@@ -115,6 +119,10 @@ def no_implicit_float : Flag<"-no-implicit-float">,
HelpText<"Don't generate implicit floating point instructions (x86-only)">;
def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
HelpText<"Disallow merging of constants.">;
+def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
+ HelpText<"Do not emit code to make initialization of local statics thread safe">;
+def fdump_vtable_layouts : Flag<"-fdump-vtable-layouts">,
+ HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
def masm_verbose : Flag<"-masm-verbose">,
HelpText<"Generate verbose assembly output">;
def mcode_model : Separate<"-mcode-model">,
@@ -165,6 +173,7 @@ def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
HelpText<"Do not include source line and caret with diagnostics">;
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
HelpText<"Do not include fixit information in diagnostics">;
+def fdiagnostics_binary : Flag<"-fdiagnostics-binary">;
def w : Flag<"-w">, HelpText<"Suppress all warnings">;
def pedantic : Flag<"-pedantic">;
def pedantic_errors : Flag<"-pedantic-errors">;
@@ -197,6 +206,9 @@ def verify : Flag<"-verify">,
// CompilerInvocation out of a driver-derived argument vector.
def cc1 : Flag<"-cc1">;
+def ast_merge : Separate<"-ast-merge">,
+ MetaVarName<"<ast file>">,
+ HelpText<"Merge the given AST file into the translation unit being compiled.">;
def code_completion_at : Separate<"-code-completion-at">,
MetaVarName<"<file>:<line>:<column>">,
HelpText<"Dump code-completion information at a location">;
@@ -280,6 +292,8 @@ def emit_llvm_bc : Flag<"-emit-llvm-bc">,
HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
def emit_llvm_only : Flag<"-emit-llvm-only">,
HelpText<"Build ASTs and convert to LLVM, discarding output">;
+def emit_obj : Flag<"-emit-obj">,
+ HelpText<"Emit native object files">;
def rewrite_test : Flag<"-rewrite-test">,
HelpText<"Rewriter playground">;
def rewrite_objc : Flag<"-rewrite-objc">,
@@ -319,6 +333,8 @@ def fblocks : Flag<"-fblocks">,
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
def fexceptions : Flag<"-fexceptions">,
HelpText<"Enable support for exception handling">;
+def fsjlj_exceptions : Flag<"-fsjlj-exceptions">,
+ HelpText<"Use SjLj style exceptions">;
def ffreestanding : Flag<"-ffreestanding">,
HelpText<"Assert that the compilation takes place in a freestanding environment">;
def fgnu_runtime : Flag<"-fgnu-runtime">,
@@ -346,10 +362,14 @@ def fobjc_gc : Flag<"-fobjc-gc">,
HelpText<"Enable Objective-C garbage collection">;
def fobjc_gc_only : Flag<"-fobjc-gc-only">,
HelpText<"Use GC exclusively for Objective-C related memory management">;
+def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">,
+ HelpText<"Use legacy dispatch with the Objective-C non-fragile ABI">;
def print_ivar_layout : Flag<"-print-ivar-layout">,
HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
HelpText<"enable objective-c's nonfragile abi">;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">,
+ HelpText<"enable objective-c's enhanced nonfragile abi">;
def ftrapv : Flag<"-ftrapv">,
HelpText<"Trap on integer overflow">;
def pic_level : Separate<"-pic-level">,
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 3186471ce613..64f88ed98318 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -77,32 +77,36 @@ public:
/// Information about the host which can be overriden by the user.
std::string HostBits, HostMachine, HostSystem, HostRelease;
+ /// Name to use when calling the generic gcc.
+ std::string CCCGenericGCCName;
+
/// Whether the driver should follow g++ like behavior.
- bool CCCIsCXX : 1;
+ unsigned CCCIsCXX : 1;
/// Echo commands while executing (in -v style).
- bool CCCEcho : 1;
+ unsigned CCCEcho : 1;
/// Only print tool bindings, don't build any jobs.
- bool CCCPrintBindings : 1;
-
- /// Name to use when calling the generic gcc.
- std::string CCCGenericGCCName;
+ unsigned CCCPrintBindings : 1;
private:
+ /// Whether to check that input files exist when constructing compilation
+ /// jobs.
+ unsigned CheckInputsExist : 1;
+
/// Use the clang compiler where possible.
- bool CCCUseClang : 1;
+ unsigned CCCUseClang : 1;
/// Use clang for handling C++ and Objective-C++ inputs.
- bool CCCUseClangCXX : 1;
+ unsigned CCCUseClangCXX : 1;
/// Use clang as a preprocessor (clang's preprocessor will still be
/// used where an integrated CPP would).
- bool CCCUseClangCPP : 1;
+ unsigned CCCUseClangCPP : 1;
public:
/// Use lazy precompiled headers for PCH support.
- bool CCCUsePCH;
+ unsigned CCCUsePCH : 1;
private:
/// Only use clang for the given architectures (only used when
@@ -129,6 +133,10 @@ public:
const Diagnostic &getDiags() const { return Diags; }
+ bool getCheckInputsExist() const { return CheckInputsExist; }
+
+ void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+
/// @}
/// @name Primary Functionality
/// @{
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 955d98e4e914..4693e5c1433c 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -252,6 +252,7 @@ def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Grou
def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
+def fdiagnostics_binary : Flag<"-fdiagnostics-binary">, Group<f_Group>, Flags<[HelpHidden]>;
def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
@@ -302,6 +303,7 @@ def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_
def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>;
def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>;
def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>;
+def fno_objc_legacy_dispatch : Flag<"-fno-objc-legacy-dispatch">, Group<f_Group>;
def fno_omit_frame_pointer : Flag<"-fno-omit-frame-pointer">, Group<f_Group>;
def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>;
def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>;
@@ -309,6 +311,7 @@ def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>;
def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
+def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>;
def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>;
def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
@@ -317,8 +320,10 @@ def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
+def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>;
def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">, Group<f_Group>;
def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fobjc : Flag<"-fobjc">, Group<f_Group>;
def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
@@ -348,6 +353,7 @@ def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
+def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
@@ -374,6 +380,7 @@ def image__base : Separate<"-image_base">;
def include_ : JoinedOrSeparate<"-include">, Group<clang_i_Group>, EnumName<"include">;
def init : Separate<"-init">;
def install__name : Separate<"-install_name">;
+def integrated_as : Flag<"-integrated-as">, Flags<[DriverOption]>;
def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>;
def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>;
def isysroot : JoinedOrSeparate<"-isysroot">, Group<clang_i_Group>;
@@ -398,10 +405,10 @@ def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>
def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
def mfpu_EQ : Joined<"-mfpu=">, Group<m_Group>;
def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
-def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>;
+def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
def mkernel : Flag<"-mkernel">, Group<m_Group>;
def mllvm : Separate<"-mllvm">;
-def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>;
+def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>;
def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>;
def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>;
@@ -416,7 +423,10 @@ def mno_sse4a : Flag<"-mno-sse4a">, Group<m_x86_Features_Group>;
def mno_sse4 : Flag<"-mno-sse4">, Group<m_x86_Features_Group>;
def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>;
def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>;
+
def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>;
+def marm : Flag<"-marm">, Alias<mno_thumb>;
+
def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
@@ -438,6 +448,7 @@ def m_Joined : Joined<"-m">, Group<m_Group>;
def no_canonical_prefixes : Flag<"-no-canonical-prefixes">, Flags<[DriverOption, HelpHidden]>,
HelpText<"Use relative instead of canonical paths">;
def no_cpp_precomp : Flag<"-no-cpp-precomp">;
+def no_integrated_as : Flag<"-no-integrated-as">, Flags<[DriverOption]>;
def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
def nobuiltininc : Flag<"-nobuiltininc">;
@@ -481,6 +492,8 @@ def pthread : Flag<"-pthread">;
def p : Flag<"-p">;
def read__only__relocs : Separate<"-read_only_relocs">;
def remap : Flag<"-remap">;
+def rewrite_objc : Flag<"-rewrite-objc">, Flags<[DriverOption]>,
+ HelpText<"Rewrite Objective-C source to C++">;
def rpath : Separate<"-rpath">, Flags<[LinkerInput]>;
def r : Flag<"-r">;
def save_temps : Flag<"-save-temps">, Flags<[DriverOption]>,
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index 8a89f01e0f4b..851e4235b00e 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -45,6 +45,7 @@ public:
virtual bool acceptsPipedInput() const = 0;
virtual bool canPipeOutput() const = 0;
+ virtual bool hasIntegratedAssembler() const { return false; }
virtual bool hasIntegratedCPP() const = 0;
/// ConstructJob - Construct jobs to perform the action \arg JA,
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index cc8d438db3e9..9a82973dca27 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -53,9 +53,9 @@ public:
const Driver &getDriver() const;
const llvm::Triple &getTriple() const { return Triple; }
- std::string getArchName() const { return Triple.getArchName(); }
- std::string getPlatform() const { return Triple.getVendorName(); }
- std::string getOS() const { return Triple.getOSName(); }
+ llvm::StringRef getArchName() const { return Triple.getArchName(); }
+ llvm::StringRef getPlatform() const { return Triple.getVendorName(); }
+ llvm::StringRef getOS() const { return Triple.getOSName(); }
std::string getTripleString() const {
return Triple.getTriple();
@@ -90,10 +90,19 @@ public:
/// IsBlocksDefault - Does this tool chain enable -fblocks by default.
virtual bool IsBlocksDefault() const { return false; }
+ /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
+ /// by default.
+ virtual bool IsIntegratedAssemblerDefault() const { return false; }
+
/// IsObjCNonFragileABIDefault - Does this tool chain set
/// -fobjc-nonfragile-abi by default.
virtual bool IsObjCNonFragileABIDefault() const { return false; }
+ /// IsObjCLegacyDispatchDefault - Does this tool chain set
+ /// -fobjc-legacy-dispatch by default (this is only used with the non-fragile
+ /// ABI).
+ virtual bool IsObjCLegacyDispatchDefault() 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; }
@@ -114,6 +123,9 @@ public:
/// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
/// compile unit information.
virtual bool UseDwarfDebugFlags() const { return false; }
+
+ /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
+ virtual bool UseSjLjExceptions() const { return false; }
};
} // end namespace driver
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index d66fe9221a30..61a5043b34fc 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -72,6 +72,7 @@ TYPE("ast", AST, INVALID, "ast", "u")
TYPE("llvm-asm", LLVMAsm, INVALID, "s", "")
TYPE("llvm-bc", LLVMBC, INVALID, "o", "")
TYPE("plist", Plist, INVALID, "plist", "")
+TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")
TYPE("precompiled-header", PCH, INVALID, "gch", "A")
TYPE("object", Object, INVALID, "o", "")
TYPE("treelang", Treelang, INVALID, 0, "u")
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 978b0d2b2aa6..7ec5063b5334 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -73,10 +73,11 @@ ASTConsumer *CreateObjCRewriter(const std::string &InFile,
// assembly. This runs optimizations depending on the CodeGenOptions
// parameter. The output depends on the Action parameter.
enum BackendAction {
- Backend_EmitAssembly, // Emit native assembly
- Backend_EmitBC, // Emit LLVM bitcode file
+ Backend_EmitAssembly, // Emit native assembly files
+ Backend_EmitBC, // Emit LLVM bitcode files
Backend_EmitLL, // Emit human-readable LLVM assembly
- Backend_EmitNothing // Don't emit anything (benchmarking mode)
+ Backend_EmitNothing, // Don't emit anything (benchmarking mode)
+ Backend_EmitObj // Emit native object files
};
ASTConsumer *CreateBackendConsumer(BackendAction Action,
Diagnostic &Diags,
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 2659dbb2a30c..f122dd954d3e 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -53,6 +53,10 @@ class ASTUnit {
llvm::OwningPtr<ASTContext> Ctx;
bool tempFile;
+ /// Optional owned invocation, just used to make the invocation used in
+ /// LoadFromCommandLine available.
+ llvm::OwningPtr<CompilerInvocation> Invocation;
+
// OnlyLocalDecls - when true, walking this AST should only visit declarations
// that come from the AST itself, not from included precompiled headers.
// FIXME: This is temporary; eventually, CIndex will always do this.
@@ -131,7 +135,6 @@ public:
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
bool OnlyLocalDecls = false,
- bool UseBumpAllocator = false,
RemappedFile *RemappedFiles = 0,
unsigned NumRemappedFiles = 0);
@@ -139,14 +142,14 @@ public:
/// CompilerInvocation object.
///
/// \param CI - The compiler invocation to use; it must have exactly one input
- /// source file.
+ /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
///
/// \param Diags - The diagnostics engine to use for reporting errors; its
/// lifetime is expected to extend past that of the returned ASTUnit.
//
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
// shouldn't need to specify them at construction time.
- static ASTUnit *LoadFromCompilerInvocation(const CompilerInvocation &CI,
+ static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
Diagnostic &Diags,
bool OnlyLocalDecls = false);
@@ -169,7 +172,6 @@ public:
Diagnostic &Diags,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls = false,
- bool UseBumpAllocator = false,
RemappedFile *RemappedFiles = 0,
unsigned NumRemappedFiles = 0);
};
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index 7d55673a612f..287c67ebb7ef 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -24,28 +24,32 @@ ANALYSIS(CFGView, "cfg-view",
ANALYSIS(DisplayLiveVariables, "dump-live-variables",
"Print results of live variable analysis", Code)
-ANALYSIS(SecuritySyntacticChecks, "warn-security-syntactic",
+ANALYSIS(SecuritySyntacticChecks, "analyzer-check-security-syntactic",
"Perform quick security checks that require no data flow",
Code)
-ANALYSIS(WarnDeadStores, "warn-dead-stores",
+ANALYSIS(LLVMConventionChecker, "analyzer-check-llvm-conventions",
+ "Check code for LLVM codebase conventions (domain-specific)",
+ TranslationUnit)
+
+ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
"Warn about stores to dead variables", Code)
ANALYSIS(WarnUninitVals, "warn-uninit-values",
"Warn about uses of uninitialized variables", Code)
-ANALYSIS(WarnObjCMethSigs, "warn-objc-methodsigs",
+ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
"Warn about Objective-C method signatures with type incompatibilities",
ObjCImplementation)
-ANALYSIS(WarnObjCDealloc, "warn-objc-missing-dealloc",
+ANALYSIS(WarnObjCDealloc, "analyzer-check-objc-missing-dealloc",
"Warn about Objective-C classes that lack a correct implementation of -dealloc",
ObjCImplementation)
-ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars",
+ANALYSIS(WarnObjCUnusedIvars, "analyzer-check-objc-unused-ivars",
"Warn about private ivars that are never used", ObjCImplementation)
-ANALYSIS(CheckerCFRef, "checker-cfref",
+ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
"Run the [Core] Foundation reference count checker", Code)
ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
@@ -61,6 +65,7 @@ ANALYSIS(InlineCall, "inline-call",
ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store", CreateBasicStoreManager)
ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager)
+ANALYSIS_STORE(FlatStore, "flat", "Use flat analyzer store", CreateFlatStoreManager)
#ifndef ANALYSIS_CONSTRAINTS
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index edafe623a4f6..1be4118e5542 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -58,11 +58,10 @@ class TargetInfo;
/// 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;
+ llvm::OwningPtr<llvm::LLVMContext> LLVMContext;
/// The options used in this compiler instance.
- CompilerInvocation Invocation;
+ llvm::OwningPtr<CompilerInvocation> Invocation;
/// The diagnostics engine instance.
llvm::OwningPtr<Diagnostic> Diagnostics;
@@ -97,11 +96,10 @@ class CompilerInstance {
/// The list of active output files.
std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
+ void operator=(const CompilerInstance &); // DO NOT IMPLEMENT
+ CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
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();
~CompilerInstance();
/// @name High-Level Operations
@@ -150,93 +148,101 @@ public:
return *LLVMContext;
}
+ llvm::LLVMContext *takeLLVMContext() { return LLVMContext.take(); }
+
/// setLLVMContext - Replace the current LLVM context and take ownership of
/// \arg Value.
- void setLLVMContext(llvm::LLVMContext *Value, bool TakeOwnership = true) {
- LLVMContext = Value;
- OwnsLLVMContext = TakeOwnership;
- }
+ void setLLVMContext(llvm::LLVMContext *Value);
/// }
/// @name Compiler Invocation and Options
/// {
- CompilerInvocation &getInvocation() { return Invocation; }
- const CompilerInvocation &getInvocation() const { return Invocation; }
- void setInvocation(const CompilerInvocation &Value) { Invocation = Value; }
+ bool hasInvocation() const { return Invocation != 0; }
+
+ CompilerInvocation &getInvocation() {
+ assert(Invocation && "Compiler instance has no invocation!");
+ return *Invocation;
+ }
+
+ CompilerInvocation *takeInvocation() { return Invocation.take(); }
+
+ /// setInvocation - Replace the current invocation; the compiler instance
+ /// takes ownership of \arg Value.
+ void setInvocation(CompilerInvocation *Value);
/// }
/// @name Forwarding Methods
/// {
AnalyzerOptions &getAnalyzerOpts() {
- return Invocation.getAnalyzerOpts();
+ return Invocation->getAnalyzerOpts();
}
const AnalyzerOptions &getAnalyzerOpts() const {
- return Invocation.getAnalyzerOpts();
+ return Invocation->getAnalyzerOpts();
}
CodeGenOptions &getCodeGenOpts() {
- return Invocation.getCodeGenOpts();
+ return Invocation->getCodeGenOpts();
}
const CodeGenOptions &getCodeGenOpts() const {
- return Invocation.getCodeGenOpts();
+ return Invocation->getCodeGenOpts();
}
DependencyOutputOptions &getDependencyOutputOpts() {
- return Invocation.getDependencyOutputOpts();
+ return Invocation->getDependencyOutputOpts();
}
const DependencyOutputOptions &getDependencyOutputOpts() const {
- return Invocation.getDependencyOutputOpts();
+ return Invocation->getDependencyOutputOpts();
}
DiagnosticOptions &getDiagnosticOpts() {
- return Invocation.getDiagnosticOpts();
+ return Invocation->getDiagnosticOpts();
}
const DiagnosticOptions &getDiagnosticOpts() const {
- return Invocation.getDiagnosticOpts();
+ return Invocation->getDiagnosticOpts();
}
FrontendOptions &getFrontendOpts() {
- return Invocation.getFrontendOpts();
+ return Invocation->getFrontendOpts();
}
const FrontendOptions &getFrontendOpts() const {
- return Invocation.getFrontendOpts();
+ return Invocation->getFrontendOpts();
}
HeaderSearchOptions &getHeaderSearchOpts() {
- return Invocation.getHeaderSearchOpts();
+ return Invocation->getHeaderSearchOpts();
}
const HeaderSearchOptions &getHeaderSearchOpts() const {
- return Invocation.getHeaderSearchOpts();
+ return Invocation->getHeaderSearchOpts();
}
LangOptions &getLangOpts() {
- return Invocation.getLangOpts();
+ return Invocation->getLangOpts();
}
const LangOptions &getLangOpts() const {
- return Invocation.getLangOpts();
+ return Invocation->getLangOpts();
}
PreprocessorOptions &getPreprocessorOpts() {
- return Invocation.getPreprocessorOpts();
+ return Invocation->getPreprocessorOpts();
}
const PreprocessorOptions &getPreprocessorOpts() const {
- return Invocation.getPreprocessorOpts();
+ return Invocation->getPreprocessorOpts();
}
PreprocessorOutputOptions &getPreprocessorOutputOpts() {
- return Invocation.getPreprocessorOutputOpts();
+ return Invocation->getPreprocessorOutputOpts();
}
const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
- return Invocation.getPreprocessorOutputOpts();
+ return Invocation->getPreprocessorOutputOpts();
}
TargetOptions &getTargetOpts() {
- return Invocation.getTargetOpts();
+ return Invocation->getTargetOpts();
}
const TargetOptions &getTargetOpts() const {
- return Invocation.getTargetOpts();
+ return Invocation->getTargetOpts();
}
/// }
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
index 13039bb5063e..b37c18057f0f 100644
--- a/include/clang/Frontend/DiagnosticOptions.h
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -31,9 +31,12 @@ 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
+ unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
/// diagnostics, indicated by markers in the
/// input source file.
+ unsigned BinaryOutput : 1; /// Emit diagnostics via the diagnostic
+ /// binary serialization mechanism, to be
+ /// deserialized by, e.g., the CIndex library.
/// The distance between tab stops.
unsigned TabStop;
@@ -66,6 +69,7 @@ public:
ShowOptionNames = 0;
ShowSourceRanges = 0;
VerifyDiagnostics = 0;
+ BinaryOutput = 0;
}
};
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 3042767af874..7b7db3785cf3 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -18,6 +18,7 @@ namespace clang {
class ASTUnit;
class ASTConsumer;
class CompilerInstance;
+class ASTMergeAction;
/// FrontendAction - Abstract base class for actions which can be performed by
/// the frontend.
@@ -25,6 +26,7 @@ class FrontendAction {
std::string CurrentFile;
llvm::OwningPtr<ASTUnit> CurrentASTUnit;
CompilerInstance *Instance;
+ friend class ASTMergeAction;
protected:
/// @name Implementation Action Interface
@@ -104,6 +106,10 @@ public:
return *CurrentASTUnit;
}
+ ASTUnit *takeCurrentASTUnit() {
+ return CurrentASTUnit.take();
+ }
+
void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
/// @}
@@ -167,7 +173,7 @@ public:
};
/// ASTFrontendAction - Abstract base class to use for AST consumer based
-/// frontend actios.
+/// frontend actions.
class ASTFrontendAction : public FrontendAction {
/// ExecuteAction - Implement the ExecuteAction interface by running Sema on
/// the already initialized AST consumer.
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 33bb8aaf6e1d..cbb3508c8a76 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -11,6 +11,8 @@
#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
#include "clang/Frontend/FrontendAction.h"
+#include <string>
+#include <vector>
namespace clang {
class FixItRewriter;
@@ -119,6 +121,43 @@ public:
virtual bool hasCodeCompletionSupport() const { return true; }
};
+/**
+ * \brief Frontend action adaptor that merges ASTs together.
+ *
+ * This action takes an existing AST file and "merges" it into the AST
+ * context, producing a merged context. This action is an action
+ * adaptor, which forwards most of its calls to another action that
+ * will consume the merged context.
+ */
+class ASTMergeAction : public FrontendAction {
+ /// \brief The action that the merge action adapts.
+ FrontendAction *AdaptedAction;
+
+ /// \brief The set of AST files to merge.
+ std::vector<std::string> ASTFiles;
+
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename);
+
+ virtual void ExecuteAction();
+ virtual void EndSourceFileAction();
+
+public:
+ ASTMergeAction(FrontendAction *AdaptedAction,
+ std::string *ASTFiles, unsigned NumASTFiles);
+ virtual ~ASTMergeAction();
+
+ virtual bool usesPreprocessorOnly() const;
+ virtual bool usesCompleteTranslationUnit();
+ virtual bool hasPCHSupport() const;
+ virtual bool hasASTSupport() const;
+ virtual bool hasCodeCompletionSupport() const;
+};
+
//===----------------------------------------------------------------------===//
// Code Gen AST Actions
//===----------------------------------------------------------------------===//
@@ -154,6 +193,11 @@ public:
EmitLLVMOnlyAction();
};
+class EmitObjAction : public CodeGenAction {
+public:
+ EmitObjAction();
+};
+
//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 735a86a70fcb..80ba77864a5b 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -31,6 +31,7 @@ namespace frontend {
EmitHTML, ///< Translate input source into HTML.
EmitLLVM, ///< Emit a .ll file.
EmitLLVMOnly, ///< Generate LLVM IR, but do not
+ EmitObj, ///< Emit a .o file.
FixIt, ///< Parse and apply any fixits to the source.
GeneratePCH, ///< Generate pre-compiled header.
GeneratePTH, ///< Generate pre-tokenized header.
@@ -109,6 +110,9 @@ public:
/// The list of plugins to load.
std::vector<std::string> Plugins;
+ /// \brief The list of AST files to merge.
+ std::vector<std::string> ASTMergeFiles;
+
public:
FrontendOptions() {
DebugCodeCompletionPrinter = 1;
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 1a9f4ceab933..e22d37ba34f5 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -221,7 +221,11 @@ namespace clang {
/// \brief Record code for the version control branch and revision
/// information of the compiler used to build this PCH file.
- VERSION_CONTROL_BRANCH_REVISION = 21
+ VERSION_CONTROL_BRANCH_REVISION = 21,
+
+ /// \brief Record code for the array of unused static functions.
+ UNUSED_STATIC_FUNCS = 22
+
};
/// \brief Record types used within a source manager block.
@@ -686,7 +690,11 @@ namespace clang {
// \brief A CXXConstCastExpr record.
EXPR_CXX_CONST_CAST,
// \brief A CXXFunctionalCastExpr record.
- EXPR_CXX_FUNCTIONAL_CAST
+ EXPR_CXX_FUNCTIONAL_CAST,
+ // \brief A CXXBoolLiteralExpr record.
+ EXPR_CXX_BOOL_LITERAL,
+ // \brief A CXXNullPtrLiteralExpr record.
+ EXPR_CXX_NULL_PTR_LITERAL
};
/// \brief The kinds of designators that can occur in a
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 9665ce189f4a..065006fce5c4 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -306,6 +306,10 @@ private:
/// \brief The set of tentative definitions stored in the the PCH
/// file.
llvm::SmallVector<uint64_t, 16> TentativeDefinitions;
+
+ /// \brief The set of tentative definitions stored in the the PCH
+ /// file.
+ llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs;
/// \brief The set of locally-scoped external declarations stored in
/// the the PCH file.
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 0f36df43e232..6a6e319463f0 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -199,6 +199,9 @@ public:
/// the current file.
SourceLocation getSourceLocation() { return getSourceLocation(BufferPtr); }
+ /// \brief Return the current location in the buffer.
+ const char *getBufferLocation() const { return BufferPtr; }
+
/// Stringify - Convert the specified string into a C string by escaping '\'
/// and " characters. This does not add surrounding ""'s to the string.
/// If Charify is true, this escapes the ' character instead of ".
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 604eae1027aa..b5dde9a700e8 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -124,6 +124,10 @@ public:
UintData = L.getRawEncoding();
}
+ SourceLocation getLastLoc() const {
+ return isAnnotation() ? getAnnotationEndLoc() : getLocation();
+ }
+
/// getAnnotationRange - SourceRange of the group of tokens that this
/// annotation token represents.
SourceRange getAnnotationRange() const {
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index ff33f5039d5d..ec542f08c303 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -459,6 +459,8 @@ public:
virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D) {
return DeclPtrTy();
}
+ virtual void ActOnObjCCatchParam(DeclPtrTy D) {
+ }
/// AddInitializerToDecl - This action is called immediately after
/// ActOnDeclarator (when an initializer is present). The code is factored
@@ -808,6 +810,11 @@ public:
return StmtEmpty();
}
+ /// ActOnSwitchBodyError - This is called if there is an error parsing the
+ /// body of the switch stmt instead of ActOnFinishSwitchStmt.
+ virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
+ StmtArg Body) {}
+
virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
StmtArg Switch, StmtArg Body) {
return StmtEmpty();
@@ -897,7 +904,7 @@ public:
bool IsVolatile,
unsigned NumOutputs,
unsigned NumInputs,
- std::string *Names,
+ IdentifierInfo **Names,
MultiExprArg Constraints,
MultiExprArg Exprs,
ExprArg AsmString,
@@ -1270,7 +1277,8 @@ public:
/// definition.
virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
IdentifierInfo *Ident,
- SourceLocation LBrace) {
+ SourceLocation LBrace,
+ AttributeList *AttrList) {
return DeclPtrTy();
}
@@ -1649,9 +1657,12 @@ public:
/// a well-formed program), ColonLoc is the location of the ':' that
/// starts the constructor initializer, and MemInit/NumMemInits
/// contains the individual member (and base) initializers.
+ /// AnyErrors will be true if there were any invalid member initializers
+ /// that are not represented in the list.
virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
SourceLocation ColonLoc,
- MemInitTy **MemInits, unsigned NumMemInits){
+ MemInitTy **MemInits, unsigned NumMemInits,
+ bool AnyErrors){
}
virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {}
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index f923b5e910db..4fe81a7eb5c2 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -153,6 +153,8 @@ private:
/*TSC*/unsigned TypeSpecComplex : 2;
/*TSS*/unsigned TypeSpecSign : 2;
/*TST*/unsigned TypeSpecType : 5;
+ bool TypeAltiVecVector : 1;
+ bool TypeAltiVecPixel : 1;
bool TypeSpecOwned : 1;
// type-qualifiers
@@ -193,7 +195,7 @@ private:
SourceRange Range;
SourceLocation StorageClassSpecLoc, SCS_threadLoc;
- SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
+ SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
SourceRange TypeofParensRange;
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
@@ -213,6 +215,8 @@ public:
TypeSpecComplex(TSC_unspecified),
TypeSpecSign(TSS_unspecified),
TypeSpecType(TST_unspecified),
+ TypeAltiVecVector(false),
+ TypeAltiVecPixel(false),
TypeSpecOwned(false),
TypeQualifiers(TSS_unspecified),
FS_inline_specified(false),
@@ -250,6 +254,8 @@ public:
TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; }
TST getTypeSpecType() const { return (TST)TypeSpecType; }
+ bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
+ bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
bool isTypeSpecOwned() const { return TypeSpecOwned; }
void *getTypeRep() const { return TypeRep; }
CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
@@ -260,6 +266,7 @@ public:
SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
+ SourceLocation getAltiVecLoc() const { return AltiVecLoc; }
SourceRange getTypeofParensRange() const { return TypeofParensRange; }
void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
@@ -344,6 +351,10 @@ public:
unsigned &DiagID);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID, void *Rep = 0, bool Owned = false);
+ bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
+ bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
bool SetTypeSpecError();
void UpdateTypeRep(void *Rep) { TypeRep = Rep; }
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index e7cb0a2493d3..f4d3d3e54d51 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -81,6 +81,11 @@ class Parser {
/// Ident_super - IdentifierInfo for "super", to support fast
/// comparison.
IdentifierInfo *Ident_super;
+ /// Ident_vector and Ident_pixel - cached IdentifierInfo's for
+ /// "vector" and "pixel" fast comparison. Only present if
+ /// AltiVec enabled.
+ IdentifierInfo *Ident_vector;
+ IdentifierInfo *Ident_pixel;
llvm::OwningPtr<PragmaHandler> PackHandler;
llvm::OwningPtr<PragmaHandler> UnusedHandler;
@@ -320,6 +325,81 @@ private:
/// annotated.
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+ /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
+ /// replacing them with the non-context-sensitive keywords. This returns
+ /// true if the token was replaced.
+ bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID, bool &isInvalid) {
+ if (getLang().AltiVec) {
+ if (Tok.getIdentifierInfo() == Ident_vector) {
+ const Token nextToken = NextToken();
+ switch (nextToken.getKind()) {
+ case tok::kw_short:
+ case tok::kw_long:
+ case tok::kw_signed:
+ case tok::kw_unsigned:
+ case tok::kw_void:
+ case tok::kw_char:
+ case tok::kw_int:
+ case tok::kw_float:
+ case tok::kw_double:
+ case tok::kw_bool:
+ case tok::kw___pixel:
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ return true;
+ case tok::identifier:
+ if (nextToken.getIdentifierInfo() == Ident_pixel) {
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
+ DS.isTypeAltiVecVector()) {
+ isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
+ /// identifier token, replacing it with the non-context-sensitive __vector.
+ /// This returns true if the token was replaced.
+ bool TryAltiVecVectorToken() {
+ if (getLang().AltiVec) {
+ if (Tok.getIdentifierInfo() == Ident_vector) {
+ const Token nextToken = NextToken();
+ switch (nextToken.getKind()) {
+ case tok::kw_short:
+ case tok::kw_long:
+ case tok::kw_signed:
+ case tok::kw_unsigned:
+ case tok::kw_void:
+ case tok::kw_char:
+ case tok::kw_int:
+ case tok::kw_float:
+ case tok::kw_double:
+ case tok::kw_bool:
+ case tok::kw___pixel:
+ Tok.setKind(tok::kw___vector);
+ return true;
+ case tok::identifier:
+ if (nextToken.getIdentifierInfo() == Ident_pixel) {
+ Tok.setKind(tok::kw___vector);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+ }
+
/// TentativeParsingAction - An object that is used as a kind of "tentative
/// parsing transaction". It gets instantiated to mark the token position and
/// after the token consumption is done, Commit() or Revert() is called to
@@ -1009,9 +1089,9 @@ private:
OwningStmtResult ParseReturnStatement(AttributeList *Attr);
OwningStmtResult ParseAsmStatement(bool &msAsm);
OwningStmtResult FuzzyParseMicrosoftAsmStatement();
- bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
- llvm::SmallVectorImpl<ExprTy*> &Constraints,
- llvm::SmallVectorImpl<ExprTy*> &Exprs);
+ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
+ llvm::SmallVectorImpl<ExprTy *> &Constraints,
+ llvm::SmallVectorImpl<ExprTy *> &Exprs);
//===--------------------------------------------------------------------===//
// C++ 6: Statements and Blocks
@@ -1065,7 +1145,8 @@ private:
bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid,
const char *&PrevSpec,
unsigned &DiagID,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ bool SuppressDeclarations = false);
void ParseSpecifierQualifierList(DeclSpec &DS);
@@ -1311,7 +1392,8 @@ private:
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- AccessSpecifier AS = AS_none);
+ AccessSpecifier AS = AS_none,
+ bool SuppressDeclarations = false);
void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
DeclPtrTy TagDecl);
void ParseCXXClassMemberDeclaration(AccessSpecifier AS,